@cyberismo/data-handler 0.0.2

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 (306) hide show
  1. package/LICENSE +702 -0
  2. package/dist/card-metadata-updater.d.ts +33 -0
  3. package/dist/card-metadata-updater.js +121 -0
  4. package/dist/card-metadata-updater.js.map +1 -0
  5. package/dist/command-handler.d.ts +96 -0
  6. package/dist/command-handler.js +557 -0
  7. package/dist/command-handler.js.map +1 -0
  8. package/dist/command-manager.d.ts +43 -0
  9. package/dist/command-manager.js +73 -0
  10. package/dist/command-manager.js.map +1 -0
  11. package/dist/commands/calculate.d.ts +86 -0
  12. package/dist/commands/calculate.js +444 -0
  13. package/dist/commands/calculate.js.map +1 -0
  14. package/dist/commands/create.d.ts +114 -0
  15. package/dist/commands/create.js +389 -0
  16. package/dist/commands/create.js.map +1 -0
  17. package/dist/commands/edit.d.ts +37 -0
  18. package/dist/commands/edit.js +99 -0
  19. package/dist/commands/edit.js.map +1 -0
  20. package/dist/commands/export-site.d.ts +45 -0
  21. package/dist/commands/export-site.js +301 -0
  22. package/dist/commands/export-site.js.map +1 -0
  23. package/dist/commands/export.d.ts +53 -0
  24. package/dist/commands/export.js +251 -0
  25. package/dist/commands/export.js.map +1 -0
  26. package/dist/commands/import.d.ts +53 -0
  27. package/dist/commands/import.js +133 -0
  28. package/dist/commands/import.js.map +1 -0
  29. package/dist/commands/index.d.ts +26 -0
  30. package/dist/commands/index.js +27 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/move.d.ts +55 -0
  33. package/dist/commands/move.js +341 -0
  34. package/dist/commands/move.js.map +1 -0
  35. package/dist/commands/remove.d.ts +38 -0
  36. package/dist/commands/remove.js +192 -0
  37. package/dist/commands/remove.js.map +1 -0
  38. package/dist/commands/rename.d.ts +46 -0
  39. package/dist/commands/rename.js +289 -0
  40. package/dist/commands/rename.js.map +1 -0
  41. package/dist/commands/show.d.ts +124 -0
  42. package/dist/commands/show.js +345 -0
  43. package/dist/commands/show.js.map +1 -0
  44. package/dist/commands/transition.d.ts +27 -0
  45. package/dist/commands/transition.js +92 -0
  46. package/dist/commands/transition.js.map +1 -0
  47. package/dist/commands/update.d.ts +29 -0
  48. package/dist/commands/update.js +64 -0
  49. package/dist/commands/update.js.map +1 -0
  50. package/dist/commands/validate.d.ts +143 -0
  51. package/dist/commands/validate.js +689 -0
  52. package/dist/commands/validate.js.map +1 -0
  53. package/dist/containers/card-container.d.ts +44 -0
  54. package/dist/containers/card-container.js +282 -0
  55. package/dist/containers/card-container.js.map +1 -0
  56. package/dist/containers/project/project-paths.d.ts +46 -0
  57. package/dist/containers/project/project-paths.js +105 -0
  58. package/dist/containers/project/project-paths.js.map +1 -0
  59. package/dist/containers/project/resource-collector.d.ts +86 -0
  60. package/dist/containers/project/resource-collector.js +331 -0
  61. package/dist/containers/project/resource-collector.js.map +1 -0
  62. package/dist/containers/project.d.ts +351 -0
  63. package/dist/containers/project.js +896 -0
  64. package/dist/containers/project.js.map +1 -0
  65. package/dist/containers/template.d.ts +108 -0
  66. package/dist/containers/template.js +433 -0
  67. package/dist/containers/template.js.map +1 -0
  68. package/dist/exceptions/index.d.ts +19 -0
  69. package/dist/exceptions/index.js +26 -0
  70. package/dist/exceptions/index.js.map +1 -0
  71. package/dist/index.d.ts +16 -0
  72. package/dist/index.js +15 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/interfaces/adoc.d.ts +12 -0
  75. package/dist/interfaces/adoc.js +13 -0
  76. package/dist/interfaces/adoc.js.map +1 -0
  77. package/dist/interfaces/macros.d.ts +45 -0
  78. package/dist/interfaces/macros.js +13 -0
  79. package/dist/interfaces/macros.js.map +1 -0
  80. package/dist/interfaces/project-interfaces.d.ts +121 -0
  81. package/dist/interfaces/project-interfaces.js +21 -0
  82. package/dist/interfaces/project-interfaces.js.map +1 -0
  83. package/dist/interfaces/request-status-interfaces.d.ts +28 -0
  84. package/dist/interfaces/request-status-interfaces.js +20 -0
  85. package/dist/interfaces/request-status-interfaces.js.map +1 -0
  86. package/dist/interfaces/resource-interfaces.d.ts +117 -0
  87. package/dist/interfaces/resource-interfaces.js +20 -0
  88. package/dist/interfaces/resource-interfaces.js.map +1 -0
  89. package/dist/macros/base-macro.d.ts +31 -0
  90. package/dist/macros/base-macro.js +126 -0
  91. package/dist/macros/base-macro.js.map +1 -0
  92. package/dist/macros/common.d.ts +17 -0
  93. package/dist/macros/common.js +23 -0
  94. package/dist/macros/common.js.map +1 -0
  95. package/dist/macros/createCards/index.d.ts +36 -0
  96. package/dist/macros/createCards/index.js +35 -0
  97. package/dist/macros/createCards/index.js.map +1 -0
  98. package/dist/macros/createCards/metadata.d.ts +14 -0
  99. package/dist/macros/createCards/metadata.js +18 -0
  100. package/dist/macros/createCards/metadata.js.map +1 -0
  101. package/dist/macros/graph/index.d.ts +29 -0
  102. package/dist/macros/graph/index.js +91 -0
  103. package/dist/macros/graph/index.js.map +1 -0
  104. package/dist/macros/graph/metadata.d.ts +14 -0
  105. package/dist/macros/graph/metadata.js +18 -0
  106. package/dist/macros/graph/metadata.js.map +1 -0
  107. package/dist/macros/index.d.ts +93 -0
  108. package/dist/macros/index.js +237 -0
  109. package/dist/macros/index.js.map +1 -0
  110. package/dist/macros/report/index.d.ts +26 -0
  111. package/dist/macros/report/index.js +70 -0
  112. package/dist/macros/report/index.js.map +1 -0
  113. package/dist/macros/report/metadata.d.ts +14 -0
  114. package/dist/macros/report/metadata.js +18 -0
  115. package/dist/macros/report/metadata.js.map +1 -0
  116. package/dist/macros/scoreCard/index.d.ts +30 -0
  117. package/dist/macros/scoreCard/index.js +38 -0
  118. package/dist/macros/scoreCard/index.js.map +1 -0
  119. package/dist/macros/scoreCard/metadata.d.ts +14 -0
  120. package/dist/macros/scoreCard/metadata.js +18 -0
  121. package/dist/macros/scoreCard/metadata.js.map +1 -0
  122. package/dist/macros/task-queue.d.ts +46 -0
  123. package/dist/macros/task-queue.js +69 -0
  124. package/dist/macros/task-queue.js.map +1 -0
  125. package/dist/module-manager.d.ts +62 -0
  126. package/dist/module-manager.js +350 -0
  127. package/dist/module-manager.js.map +1 -0
  128. package/dist/permissions/action-guard.d.ts +28 -0
  129. package/dist/permissions/action-guard.js +61 -0
  130. package/dist/permissions/action-guard.js.map +1 -0
  131. package/dist/project-settings.d.ts +42 -0
  132. package/dist/project-settings.js +120 -0
  133. package/dist/project-settings.js.map +1 -0
  134. package/dist/resources/array-handler.d.ts +28 -0
  135. package/dist/resources/array-handler.js +116 -0
  136. package/dist/resources/array-handler.js.map +1 -0
  137. package/dist/resources/card-type-resource.d.ts +72 -0
  138. package/dist/resources/card-type-resource.js +334 -0
  139. package/dist/resources/card-type-resource.js.map +1 -0
  140. package/dist/resources/create-defaults.d.ts +81 -0
  141. package/dist/resources/create-defaults.js +184 -0
  142. package/dist/resources/create-defaults.js.map +1 -0
  143. package/dist/resources/field-type-resource.d.ts +88 -0
  144. package/dist/resources/field-type-resource.js +411 -0
  145. package/dist/resources/field-type-resource.js.map +1 -0
  146. package/dist/resources/file-resource.d.ts +50 -0
  147. package/dist/resources/file-resource.js +301 -0
  148. package/dist/resources/file-resource.js.map +1 -0
  149. package/dist/resources/folder-resource.d.ts +66 -0
  150. package/dist/resources/folder-resource.js +100 -0
  151. package/dist/resources/folder-resource.js.map +1 -0
  152. package/dist/resources/graph-model-resource.d.ts +78 -0
  153. package/dist/resources/graph-model-resource.js +164 -0
  154. package/dist/resources/graph-model-resource.js.map +1 -0
  155. package/dist/resources/graph-view-resource.d.ts +78 -0
  156. package/dist/resources/graph-view-resource.js +163 -0
  157. package/dist/resources/graph-view-resource.js.map +1 -0
  158. package/dist/resources/link-type-resource.d.ts +62 -0
  159. package/dist/resources/link-type-resource.js +150 -0
  160. package/dist/resources/link-type-resource.js.map +1 -0
  161. package/dist/resources/report-resource.d.ts +77 -0
  162. package/dist/resources/report-resource.js +171 -0
  163. package/dist/resources/report-resource.js.map +1 -0
  164. package/dist/resources/resource-object.d.ts +108 -0
  165. package/dist/resources/resource-object.js +147 -0
  166. package/dist/resources/resource-object.js.map +1 -0
  167. package/dist/resources/template-resource.d.ts +82 -0
  168. package/dist/resources/template-resource.js +173 -0
  169. package/dist/resources/template-resource.js.map +1 -0
  170. package/dist/resources/workflow-resource.d.ts +67 -0
  171. package/dist/resources/workflow-resource.js +156 -0
  172. package/dist/resources/workflow-resource.js.map +1 -0
  173. package/dist/types/queries.d.ts +142 -0
  174. package/dist/types/queries.js +16 -0
  175. package/dist/types/queries.js.map +1 -0
  176. package/dist/utils/card-utils.d.ts +34 -0
  177. package/dist/utils/card-utils.js +78 -0
  178. package/dist/utils/card-utils.js.map +1 -0
  179. package/dist/utils/clingo-fact-builder.d.ts +58 -0
  180. package/dist/utils/clingo-fact-builder.js +126 -0
  181. package/dist/utils/clingo-fact-builder.js.map +1 -0
  182. package/dist/utils/clingo-facts.d.ts +97 -0
  183. package/dist/utils/clingo-facts.js +352 -0
  184. package/dist/utils/clingo-facts.js.map +1 -0
  185. package/dist/utils/clingo-parser.d.ts +59 -0
  186. package/dist/utils/clingo-parser.js +403 -0
  187. package/dist/utils/clingo-parser.js.map +1 -0
  188. package/dist/utils/clingo-program-builder.d.ts +39 -0
  189. package/dist/utils/clingo-program-builder.js +57 -0
  190. package/dist/utils/clingo-program-builder.js.map +1 -0
  191. package/dist/utils/common-utils.d.ts +24 -0
  192. package/dist/utils/common-utils.js +47 -0
  193. package/dist/utils/common-utils.js.map +1 -0
  194. package/dist/utils/constants.d.ts +18 -0
  195. package/dist/utils/constants.js +27 -0
  196. package/dist/utils/constants.js.map +1 -0
  197. package/dist/utils/csv.d.ts +18 -0
  198. package/dist/utils/csv.js +45 -0
  199. package/dist/utils/csv.js.map +1 -0
  200. package/dist/utils/file-utils.d.ts +69 -0
  201. package/dist/utils/file-utils.js +158 -0
  202. package/dist/utils/file-utils.js.map +1 -0
  203. package/dist/utils/json.d.ts +61 -0
  204. package/dist/utils/json.js +108 -0
  205. package/dist/utils/json.js.map +1 -0
  206. package/dist/utils/lexorank.d.ts +59 -0
  207. package/dist/utils/lexorank.js +159 -0
  208. package/dist/utils/lexorank.js.map +1 -0
  209. package/dist/utils/log-utils.d.ts +40 -0
  210. package/dist/utils/log-utils.js +109 -0
  211. package/dist/utils/log-utils.js.map +1 -0
  212. package/dist/utils/random.d.ts +19 -0
  213. package/dist/utils/random.js +34 -0
  214. package/dist/utils/random.js.map +1 -0
  215. package/dist/utils/resource-utils.d.ts +45 -0
  216. package/dist/utils/resource-utils.js +137 -0
  217. package/dist/utils/resource-utils.js.map +1 -0
  218. package/dist/utils/sanitize-svg.d.ts +18 -0
  219. package/dist/utils/sanitize-svg.js +38 -0
  220. package/dist/utils/sanitize-svg.js.map +1 -0
  221. package/dist/utils/user-preferences.d.ts +64 -0
  222. package/dist/utils/user-preferences.js +106 -0
  223. package/dist/utils/user-preferences.js.map +1 -0
  224. package/dist/utils/validate.d.ts +26 -0
  225. package/dist/utils/validate.js +53 -0
  226. package/dist/utils/validate.js.map +1 -0
  227. package/dist/utils/value-utils.d.ts +58 -0
  228. package/dist/utils/value-utils.js +181 -0
  229. package/dist/utils/value-utils.js.map +1 -0
  230. package/package.json +67 -0
  231. package/src/card-metadata-updater.ts +182 -0
  232. package/src/command-handler.ts +686 -0
  233. package/src/command-manager.ts +99 -0
  234. package/src/commands/calculate.ts +591 -0
  235. package/src/commands/create.ts +559 -0
  236. package/src/commands/edit.ts +123 -0
  237. package/src/commands/export-site.ts +356 -0
  238. package/src/commands/export.ts +315 -0
  239. package/src/commands/import.ts +169 -0
  240. package/src/commands/index.ts +42 -0
  241. package/src/commands/move.ts +451 -0
  242. package/src/commands/remove.ts +244 -0
  243. package/src/commands/rename.ts +378 -0
  244. package/src/commands/show.ts +442 -0
  245. package/src/commands/transition.ts +127 -0
  246. package/src/commands/update.ts +76 -0
  247. package/src/commands/validate.ts +962 -0
  248. package/src/containers/card-container.ts +378 -0
  249. package/src/containers/project/project-paths.ts +127 -0
  250. package/src/containers/project/resource-collector.ts +379 -0
  251. package/src/containers/project.ts +1135 -0
  252. package/src/containers/template.ts +573 -0
  253. package/src/exceptions/index.ts +29 -0
  254. package/src/index.ts +33 -0
  255. package/src/interfaces/adoc.ts +18 -0
  256. package/src/interfaces/macros.ts +54 -0
  257. package/src/interfaces/project-interfaces.ts +208 -0
  258. package/src/interfaces/request-status-interfaces.ts +30 -0
  259. package/src/interfaces/resource-interfaces.ts +179 -0
  260. package/src/macros/base-macro.ts +176 -0
  261. package/src/macros/common.ts +24 -0
  262. package/src/macros/createCards/index.ts +57 -0
  263. package/src/macros/createCards/metadata.ts +21 -0
  264. package/src/macros/graph/index.ts +130 -0
  265. package/src/macros/graph/metadata.ts +21 -0
  266. package/src/macros/index.ts +321 -0
  267. package/src/macros/report/index.ts +88 -0
  268. package/src/macros/report/metadata.ts +21 -0
  269. package/src/macros/scoreCard/index.ts +55 -0
  270. package/src/macros/scoreCard/metadata.ts +21 -0
  271. package/src/macros/task-queue.ts +79 -0
  272. package/src/module-manager.ts +443 -0
  273. package/src/permissions/action-guard.ts +77 -0
  274. package/src/project-settings.ts +140 -0
  275. package/src/resources/array-handler.ts +141 -0
  276. package/src/resources/card-type-resource.ts +455 -0
  277. package/src/resources/create-defaults.ts +216 -0
  278. package/src/resources/field-type-resource.ts +533 -0
  279. package/src/resources/file-resource.ts +433 -0
  280. package/src/resources/folder-resource.ts +140 -0
  281. package/src/resources/graph-model-resource.ts +205 -0
  282. package/src/resources/graph-view-resource.ts +199 -0
  283. package/src/resources/link-type-resource.ts +191 -0
  284. package/src/resources/report-resource.ts +224 -0
  285. package/src/resources/resource-object.ts +246 -0
  286. package/src/resources/template-resource.ts +210 -0
  287. package/src/resources/workflow-resource.ts +205 -0
  288. package/src/types/queries.ts +149 -0
  289. package/src/utils/card-utils.ts +83 -0
  290. package/src/utils/clingo-fact-builder.ts +167 -0
  291. package/src/utils/clingo-facts.ts +550 -0
  292. package/src/utils/clingo-parser.ts +519 -0
  293. package/src/utils/clingo-program-builder.ts +71 -0
  294. package/src/utils/common-utils.ts +54 -0
  295. package/src/utils/constants.ts +32 -0
  296. package/src/utils/csv.ts +53 -0
  297. package/src/utils/file-utils.ts +182 -0
  298. package/src/utils/json.ts +118 -0
  299. package/src/utils/lexorank.ts +180 -0
  300. package/src/utils/log-utils.ts +127 -0
  301. package/src/utils/random.ts +37 -0
  302. package/src/utils/resource-utils.ts +180 -0
  303. package/src/utils/sanitize-svg.ts +46 -0
  304. package/src/utils/user-preferences.ts +126 -0
  305. package/src/utils/validate.ts +66 -0
  306. package/src/utils/value-utils.ts +189 -0
@@ -0,0 +1,205 @@
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/>.
11
+ */
12
+
13
+ import type {
14
+ CardType,
15
+ Workflow,
16
+ WorkflowState,
17
+ WorkflowTransition,
18
+ } from '../interfaces/resource-interfaces.js';
19
+ import { CardTypeResource } from './card-type-resource.js';
20
+ import type {
21
+ Card,
22
+ ChangeOperation,
23
+ Operation,
24
+ Project,
25
+ ResourceName,
26
+ } from './file-resource.js';
27
+ import {
28
+ DefaultContent,
29
+ FileResource,
30
+ resourceNameToString,
31
+ sortCards,
32
+ } from './folder-resource.js';
33
+ import { ResourcesFrom } from '../containers/project.js';
34
+ import { resourceName } from './file-resource.js';
35
+
36
+ /**
37
+ * Workflow resource class.
38
+ */
39
+ export class WorkflowResource extends FileResource {
40
+ constructor(project: Project, name: ResourceName) {
41
+ super(project, name, 'workflows');
42
+
43
+ this.contentSchemaId = 'workflowSchema';
44
+ this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
45
+
46
+ this.initialize();
47
+ }
48
+
49
+ // When resource name changes.
50
+ private async handleNameChange(existingName: string) {
51
+ await Promise.all([
52
+ super.updateHandleBars(existingName, this.content.name),
53
+ super.updateCalculations(existingName, this.content.name),
54
+ ]);
55
+ // Finally, write updated content.
56
+ await this.write();
57
+ }
58
+
59
+ // Update dependant card types.
60
+ private async updateCardTypes(oldName: string) {
61
+ const cardTypes = await this.project.cardTypes(ResourcesFrom.localOnly);
62
+ const op = {
63
+ name: 'change',
64
+ target: oldName,
65
+ to: this.content.name,
66
+ } as ChangeOperation<string>;
67
+ for (const cardType of cardTypes) {
68
+ const object = new CardTypeResource(
69
+ this.project,
70
+ resourceName(cardType.name),
71
+ );
72
+ if (object.data && (object.data as CardType).workflow === oldName) {
73
+ await object.update('workflow', op);
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Sets new metadata into the workflow object.
80
+ * @param newContent metadata content for the workflow.
81
+ * @throws if 'newContent' is not valid.
82
+ */
83
+ public async create(newContent?: Workflow) {
84
+ if (!newContent) {
85
+ newContent = DefaultContent.workflow(
86
+ resourceNameToString(this.resourceName),
87
+ );
88
+ } else {
89
+ await this.validate(newContent);
90
+ }
91
+ return super.create(newContent);
92
+ }
93
+
94
+ /**
95
+ * Returns content data.
96
+ */
97
+ public get data(): Workflow {
98
+ return super.data as Workflow;
99
+ }
100
+
101
+ /**
102
+ * Deletes file that this object is based on.
103
+ * If there are card types that depended on this workflow, they are now invalid.
104
+ */
105
+ public async delete() {
106
+ return super.delete();
107
+ }
108
+
109
+ /**
110
+ * Renames the object and the file.
111
+ * @param newName New name for the resource.
112
+ */
113
+ public async rename(newName: ResourceName) {
114
+ const existingName = this.content.name;
115
+ await super.rename(newName);
116
+ return this.handleNameChange(existingName);
117
+ }
118
+
119
+ /**
120
+ * Shows metadata of the resource.
121
+ * @returns workflow metadata.
122
+ */
123
+ public async show(): Promise<Workflow> {
124
+ return super.show() as Promise<Workflow>;
125
+ }
126
+
127
+ /**
128
+ * Updates workflow resource.
129
+ * @param key Key to modify
130
+ * @param op Operation to perform on 'key'
131
+ * @throws if key is unknown.
132
+ */
133
+ public async update<Type>(key: string, op: Operation<Type>) {
134
+ const nameChange = key === 'name';
135
+ const existingName = this.content.name;
136
+
137
+ await super.update(key, op);
138
+
139
+ const content = { ...(this.content as Workflow) };
140
+
141
+ if (key === 'name') {
142
+ content.name = super.handleScalar(op) as string;
143
+ } else if (key === 'states') {
144
+ content.states = super.handleArray(
145
+ op,
146
+ key,
147
+ content.states as Type[],
148
+ ) as WorkflowState[];
149
+ } else if (key === 'transitions') {
150
+ content.transitions = super.handleArray(
151
+ op,
152
+ key,
153
+ content.transitions as WorkflowTransition[] as Type[],
154
+ ) as WorkflowTransition[];
155
+ } else {
156
+ throw new Error(`Unknown property '${key}' for Workflow`);
157
+ }
158
+
159
+ await super.postUpdate(content, key, op);
160
+
161
+ // Renaming this workflow causes that references to its name must be updated.
162
+ if (nameChange) {
163
+ await this.handleNameChange(existingName);
164
+ await this.updateCardTypes(existingName);
165
+ }
166
+ }
167
+
168
+ /**
169
+ * List where workflow is used.
170
+ * Always returns card key references first, then any resource references and finally calculation references.
171
+ *
172
+ * @param cards Optional. Check these cards for usage of this resource. If undefined, will check all cards.
173
+ * @returns array of card keys, resource names and calculation filenames that refer this resource.
174
+ */
175
+ public async usage(cards?: Card[]): Promise<string[]> {
176
+ const resourceName = resourceNameToString(this.resourceName);
177
+ const allCards = cards ?? (await super.cards());
178
+ const cardTypes = await this.project.cardTypes(ResourcesFrom.all);
179
+ const cardTypeReferences = await Promise.all(
180
+ cardTypes.map(async (cardType) => {
181
+ const metadata = await this.project.resource<CardType>(cardType.name);
182
+ return metadata?.workflow === resourceName ? cardType.name : null;
183
+ }),
184
+ );
185
+
186
+ const [relevantCards, calculations] = await Promise.all([
187
+ super.usage(allCards),
188
+ super.calculations(),
189
+ ]);
190
+
191
+ return [
192
+ ...relevantCards.sort(sortCards),
193
+ ...cardTypeReferences.filter((name): name is string => name !== null),
194
+ ...calculations,
195
+ ];
196
+ }
197
+
198
+ /**
199
+ * Validates workflow.
200
+ * @throws when there are validation errors.
201
+ */
202
+ public validate(content?: object): Promise<void> {
203
+ return super.validate(content);
204
+ }
205
+ }
@@ -0,0 +1,149 @@
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/>.
11
+ */
12
+
13
+ /**
14
+ * Types for query result
15
+ */
16
+
17
+ import type {
18
+ DataType,
19
+ WorkflowCategory,
20
+ } from '../interfaces/resource-interfaces.js';
21
+
22
+ export type LinkDirection = 'inbound' | 'outbound';
23
+
24
+ export type StatusIndicator = WorkflowCategory | 'error';
25
+
26
+ export interface CalculationLink {
27
+ displayName: string;
28
+ key: string;
29
+ linkType: string;
30
+ title: string; // title of the other card
31
+ linkDescription?: string;
32
+ direction: LinkDirection;
33
+ linkSource: 'user' | 'calculated';
34
+ }
35
+
36
+ export interface Notification {
37
+ key: string;
38
+ category: string;
39
+ title: string;
40
+ message: string;
41
+ }
42
+
43
+ export interface PolicyCheckCollection {
44
+ successes: { category: string; title: string }[];
45
+ failures: {
46
+ category: string;
47
+ title: string;
48
+ errorMessage: string;
49
+ fieldName?: string;
50
+ }[];
51
+ }
52
+
53
+ export interface DeniedOperationCollection {
54
+ transition: { transitionName: string; errorMessage: string }[];
55
+ move: { errorMessage: string }[];
56
+ delete: { errorMessage: string }[];
57
+ editField: { fieldName: string; errorMessage: string }[];
58
+ editContent: { errorMessage: string }[];
59
+ }
60
+
61
+ export interface BaseResult extends Record<string, unknown> {
62
+ key: string;
63
+ labels: string[];
64
+ links: CalculationLink[];
65
+ notifications: Notification[];
66
+ policyChecks: PolicyCheckCollection;
67
+ deniedOperations: DeniedOperationCollection;
68
+ }
69
+
70
+ export interface ParseResult<T extends BaseResult> {
71
+ results: T[];
72
+ error: string | null;
73
+ }
74
+
75
+ /**
76
+ * Generic types for named queries
77
+ */
78
+
79
+ export const queries = ['card', 'onCreation', 'onTransition', 'tree'] as const;
80
+
81
+ export type QueryName = (typeof queries)[number];
82
+
83
+ export type QueryMap = {
84
+ card: CardQueryResult;
85
+ onCreation: FieldsToUpdateQueryResult;
86
+ onTransition: FieldsToUpdateQueryResult;
87
+ tree: TreeQueryResult;
88
+ };
89
+ export type QueryResult<T extends QueryName> = QueryMap[T];
90
+
91
+ /**
92
+ * Define all the queries below
93
+ */
94
+ interface CardQueryResult extends BaseResult {
95
+ progress?: string;
96
+ rank: string;
97
+ title: string;
98
+ cardType: string;
99
+ workflowState: string;
100
+ lastUpdated: string;
101
+ fields?: CardQueryField[];
102
+ }
103
+ interface FieldsToUpdateQueryResult extends BaseResult {
104
+ updateFields: UpdateField[];
105
+ }
106
+ interface TreeQueryResult extends BaseResult {
107
+ progress?: string;
108
+ rank: string;
109
+ title: string;
110
+ cardType: string;
111
+ statusIndicator?: StatusIndicator;
112
+ children?: TreeQueryResult[];
113
+ }
114
+
115
+ export interface UpdateField {
116
+ card: string;
117
+ field: string;
118
+ newValue: string;
119
+ }
120
+
121
+ interface EnumValue {
122
+ index?: number;
123
+ displayValue?: string;
124
+ value: string;
125
+ }
126
+
127
+ interface ListValueItem {
128
+ index?: number;
129
+ displayValue?: string;
130
+ value: string;
131
+ }
132
+
133
+ interface CardQueryField extends BaseResult {
134
+ visibility: 'always' | 'optional';
135
+ index: number;
136
+ fieldDisplayName: string;
137
+ fieldDescription: string;
138
+ dataType: DataType;
139
+ isCalculated: boolean;
140
+ value: string | number | boolean | null | EnumValue | ListValueItem[];
141
+ enumValues: EnumDefinition[];
142
+ }
143
+
144
+ export interface EnumDefinition extends BaseResult {
145
+ index: number;
146
+ enumDisplayValue: string;
147
+ enumDescription: string;
148
+ enumValue: string;
149
+ }
@@ -0,0 +1,83 @@
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/>.
11
+ */
12
+
13
+ import { sep } from 'node:path';
14
+
15
+ import type { Card } from '../interfaces/project-interfaces.js';
16
+
17
+ // Helper function to find the parent path from a card path
18
+ export const findParentPath = (cardPath: string): string | null => {
19
+ const pathParts = cardPath.split(sep);
20
+ const hasChildren = pathParts.lastIndexOf('c');
21
+
22
+ if (hasChildren <= 0) return null;
23
+
24
+ const parentPathParts = [...pathParts];
25
+ parentPathParts.splice(hasChildren, 1);
26
+ return parentPathParts.slice(0, hasChildren).join(sep);
27
+ };
28
+
29
+ /**
30
+ * Flattens card tree so that children are shown on same level regardless of nesting level.
31
+ * @param array card tree
32
+ * @returns flattened card tree.
33
+ */
34
+ export const flattenCardArray = (array: Card[]) => {
35
+ const result: Card[] = [];
36
+ array.forEach((item) => {
37
+ const { key, path, children, attachments, metadata } = item;
38
+ result.push({ key, path, children, attachments, metadata });
39
+ if (children) {
40
+ result.push(...flattenCardArray(children));
41
+ }
42
+ });
43
+ return result;
44
+ };
45
+
46
+ /**
47
+ * Checks if given card is in some template.
48
+ * @param card card object to check
49
+ * @returns true if card exists in a template; false otherwise
50
+ */
51
+ export const isTemplateCard = (card: Card) => {
52
+ return (
53
+ card.path.includes(`${sep}templates${sep}`) ||
54
+ card.path.includes(`${sep}modules${sep}`)
55
+ );
56
+ };
57
+
58
+ /**
59
+ * Sorts array of cards first using prefix and then using ID.
60
+ * Prefixes are returned in alphabetical order, and then in numeric order within same prefix.
61
+ * For example, test_za1, test_aa7 and demo_aaa are sorted to: demo_aaa, test_aa7, test_za1.
62
+ * @param a First card to be sorted
63
+ * @param b Second card to be sorted
64
+ * @returns Cards ordered; first by prefixes, then by ID.
65
+ */
66
+ export const sortCards = (a: string, b: string) => {
67
+ const aParts = a.split('_');
68
+ const bParts = b.split('_');
69
+ if (aParts[0] !== bParts[0]) {
70
+ if (aParts[0] > bParts[0]) return 1;
71
+ if (aParts[0] < bParts[0]) return -1;
72
+ return 0;
73
+ }
74
+ if (a.length > b.length) {
75
+ return 1;
76
+ }
77
+ if (a.length < b.length) {
78
+ return -1;
79
+ }
80
+ if (aParts[1] > bParts[1]) return 1;
81
+ if (aParts[1] < bParts[1]) return -1;
82
+ return 0;
83
+ };
@@ -0,0 +1,167 @@
1
+ import { INT32_MAX } from './constants.js';
2
+ import { logger } from './log-utils.js';
3
+
4
+ /**
5
+ Cyberismo
6
+ Copyright © Cyberismo Ltd and contributors 2024
7
+
8
+ 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.
9
+
10
+ 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.
11
+
12
+ You should have received a copy of the GNU Affero General Public
13
+ License along with this program. If not, see <https://www.gnu.org/licenses/>.
14
+ */
15
+ export type AllowedClingoType = string | number | boolean;
16
+
17
+ export type NestedBuilder = (builder: ClingoFactBuilder) => ClingoFactBuilder;
18
+
19
+ type ClingoArgumentInternal =
20
+ | AllowedClingoType
21
+ | AllowedClingoType[]
22
+ | ClingoFactBuilder;
23
+
24
+ export type ClingoArgument = ClingoArgumentInternal | NestedBuilder;
25
+
26
+ /**
27
+ * This function takes care of encoding chars, which might produce issues in clingo
28
+ * This should be done for user provided values
29
+ */
30
+ export function encodeClingoValue(value: string) {
31
+ return value.replace(/[\n\\"]/g, (char) => {
32
+ if (char === '\n') {
33
+ return '\\n';
34
+ }
35
+ return `\\${char}`;
36
+ });
37
+ }
38
+
39
+ export class ClingoFactBuilder {
40
+ protected predicate: string;
41
+ private end: string;
42
+ private arguments: ClingoArgumentInternal[] = [];
43
+
44
+ constructor(predicate: string, end: string = '.') {
45
+ this.predicate = predicate;
46
+ this.end = end;
47
+ }
48
+
49
+ /**
50
+ * Adds an argument to the fact
51
+ * @param arg Argument to add. If null, skipped
52
+ * @returns this for chaining
53
+ */
54
+ addArgument(arg: ClingoArgument | null): ClingoFactBuilder {
55
+ if (arg === null) {
56
+ return this;
57
+ }
58
+ if (typeof arg === 'function') {
59
+ const nestedBuilder = new ClingoFactBuilder('', '');
60
+ this.arguments.push(arg(nestedBuilder));
61
+ } else {
62
+ this.arguments.push(arg);
63
+ }
64
+ return this;
65
+ }
66
+
67
+ /**
68
+ * Helper for adding multiple arguments, because it's common
69
+ * @param args
70
+ * @returns this for chaining
71
+ */
72
+ addArguments(...args: (ClingoArgument | null)[]): ClingoFactBuilder {
73
+ args.forEach((arg) => this.addArgument(arg));
74
+ return this;
75
+ }
76
+
77
+ /**
78
+ * Adds a literal argument, which means that it will not have quotes
79
+ * @param literal The literal argument to add
80
+ * @returns this for chaining
81
+ */
82
+ addLiteralArgument(literal: string): ClingoFactBuilder {
83
+ this.arguments.push(new LiteralBuilder(literal));
84
+ return this;
85
+ }
86
+
87
+ /**
88
+ * Helper for adding multiple literal arguments, because it's common
89
+ * @param literal
90
+ * @returns this for chaining
91
+ */
92
+ addLiteralArguments(...literals: string[]): ClingoFactBuilder {
93
+ literals.forEach((literal) => this.addLiteralArgument(literal));
94
+ return this;
95
+ }
96
+
97
+ /**
98
+ * Builds the clingo fact
99
+ * @returns The clingo fact as a string
100
+ */
101
+ build(): string {
102
+ const encodedArguments = this.arguments
103
+ .map((arg) =>
104
+ arg instanceof ClingoFactBuilder
105
+ ? arg.build()
106
+ : this.encodeArgument(arg),
107
+ )
108
+ .join(', ');
109
+
110
+ return `${this.predicate}(${encodedArguments})${this.end}`;
111
+ }
112
+
113
+ // Function to get the raw value of the argument without encoding or quoting
114
+ private getValue(value: AllowedClingoType | AllowedClingoType[]): string {
115
+ if (typeof value === 'boolean') {
116
+ return value ? 'true' : 'false';
117
+ } else if (Array.isArray(value)) {
118
+ // Array case, call getValue on each item without quotes
119
+ return value.map((item) => this.getValue(item)).join(',');
120
+ } else if (typeof value === 'number') {
121
+ let floored = Math.floor(value);
122
+ if (floored !== value) {
123
+ logger.warn(
124
+ {
125
+ value,
126
+ },
127
+ 'Expected a whole number, when transforming a number value to a clingo equivalent. Decimal part removed.',
128
+ );
129
+ }
130
+
131
+ const exceedsInt32Max = floored > INT32_MAX;
132
+ if (exceedsInt32Max || floored < -INT32_MAX) {
133
+ logger.warn(
134
+ {
135
+ value,
136
+ },
137
+ `Value exceeds the 32-bit signed integer range. The value is too ${exceedsInt32Max ? 'large' : 'small'} to be represented as a 32-bit integer. Using ${exceedsInt32Max ? INT32_MAX : -INT32_MAX} instead.`,
138
+ );
139
+ floored = exceedsInt32Max ? INT32_MAX : -INT32_MAX;
140
+ }
141
+ return floored.toString();
142
+ } else {
143
+ return value;
144
+ }
145
+ }
146
+
147
+ // Main encoding function, handling encoding and adding quotes if necessary
148
+ private encodeArgument(arg: AllowedClingoType | AllowedClingoType[]): string {
149
+ let processedValue = this.getValue(arg);
150
+
151
+ if (typeof arg === 'string') {
152
+ processedValue = encodeClingoValue(processedValue);
153
+ }
154
+
155
+ if (typeof arg === 'boolean' || typeof arg === 'number') {
156
+ return processedValue;
157
+ }
158
+
159
+ return `"${processedValue}"`;
160
+ }
161
+ }
162
+
163
+ class LiteralBuilder extends ClingoFactBuilder {
164
+ build() {
165
+ return this.predicate;
166
+ }
167
+ }