@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.
- package/dist/command-handler.js +13 -24
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +21 -6
- package/dist/command-manager.js +34 -32
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/calculate.js +101 -46
- package/dist/commands/calculate.js.map +1 -1
- package/dist/commands/create.js +420 -320
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/edit.js +117 -68
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/export.js +301 -252
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/fetch.js +205 -156
- package/dist/commands/fetch.js.map +1 -1
- package/dist/commands/import.js +189 -134
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/migrate.js +91 -45
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/move.js +347 -267
- package/dist/commands/move.js.map +1 -1
- package/dist/commands/remove.d.ts +1 -0
- package/dist/commands/remove.js +202 -135
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.js +233 -187
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +8 -8
- package/dist/commands/show.js +477 -372
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/transition.js +119 -73
- package/dist/commands/transition.js.map +1 -1
- package/dist/commands/update.js +8 -3
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +1 -1
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/project/calculation-engine.js +0 -1
- package/dist/containers/project/calculation-engine.js.map +1 -1
- package/dist/containers/project/card-cache.js +1 -1
- package/dist/containers/project/card-cache.js.map +1 -1
- package/dist/containers/project.d.ts +16 -0
- package/dist/containers/project.js +59 -1
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.js +1 -1
- package/dist/containers/template.js.map +1 -1
- package/dist/interfaces/command-options.d.ts +1 -0
- package/dist/interfaces/resource-interfaces.d.ts +5 -12
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/base-macro.js +1 -1
- package/dist/macros/base-macro.js.map +1 -1
- package/dist/macros/graph/index.js +3 -1
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/include/index.js +16 -1
- package/dist/macros/include/index.js.map +1 -1
- package/dist/macros/include/types.d.ts +15 -12
- package/dist/macros/index.js +4 -1
- package/dist/macros/index.js.map +1 -1
- package/dist/macros/report/index.js +1 -1
- package/dist/macros/report/index.js.map +1 -1
- package/dist/module-manager.js +5 -3
- package/dist/module-manager.js.map +1 -1
- package/dist/project-settings.js +2 -2
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/card-type-resource.js +1 -1
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/create-defaults.js +0 -1
- package/dist/resources/create-defaults.js.map +1 -1
- package/dist/resources/field-type-resource.js +2 -5
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.js +4 -1
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +1 -1
- package/dist/resources/folder-resource.js +4 -1
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/graph-model-resource.d.ts +1 -8
- package/dist/resources/graph-model-resource.js +0 -14
- package/dist/resources/graph-model-resource.js.map +1 -1
- package/dist/resources/graph-view-resource.d.ts +1 -8
- package/dist/resources/graph-view-resource.js +0 -14
- package/dist/resources/graph-view-resource.js.map +1 -1
- package/dist/resources/link-type-resource.js +1 -1
- package/dist/resources/link-type-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +1 -8
- package/dist/resources/report-resource.js +0 -14
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/resource-object.d.ts +11 -1
- package/dist/resources/resource-object.js +19 -2
- package/dist/resources/resource-object.js.map +1 -1
- package/dist/resources/template-resource.d.ts +1 -9
- package/dist/resources/template-resource.js +0 -15
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +6 -0
- package/dist/resources/workflow-resource.js +29 -13
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/utils/card-utils.js +1 -1
- package/dist/utils/card-utils.js.map +1 -1
- package/dist/utils/commit-context.d.ts +23 -0
- package/dist/utils/commit-context.js +30 -0
- package/dist/utils/commit-context.js.map +1 -0
- package/dist/utils/csv.d.ts +8 -0
- package/dist/utils/csv.js +11 -0
- package/dist/utils/csv.js.map +1 -1
- package/dist/utils/file-utils.js +3 -1
- package/dist/utils/file-utils.js.map +1 -1
- package/dist/utils/git-manager.d.ts +29 -0
- package/dist/utils/git-manager.js +76 -0
- package/dist/utils/git-manager.js.map +1 -0
- package/dist/utils/handlebars-helpers.d.ts +22 -0
- package/dist/utils/handlebars-helpers.js +78 -0
- package/dist/utils/handlebars-helpers.js.map +1 -0
- package/dist/utils/json.d.ts +17 -10
- package/dist/utils/json.js +27 -14
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/log-utils.d.ts +7 -2
- package/dist/utils/log-utils.js +28 -3
- package/dist/utils/log-utils.js.map +1 -1
- package/dist/utils/report.d.ts +0 -19
- package/dist/utils/report.js +4 -63
- package/dist/utils/report.js.map +1 -1
- package/dist/utils/rw-lock.d.ts +71 -0
- package/dist/utils/rw-lock.js +220 -0
- package/dist/utils/rw-lock.js.map +1 -0
- package/dist/utils/user-preferences.js +3 -3
- package/dist/utils/user-preferences.js.map +1 -1
- package/package.json +10 -10
- package/src/command-handler.ts +14 -22
- package/src/command-manager.ts +43 -37
- package/src/commands/calculate.ts +8 -1
- package/src/commands/create.ts +39 -6
- package/src/commands/edit.ts +3 -0
- package/src/commands/export.ts +8 -2
- package/src/commands/fetch.ts +3 -0
- package/src/commands/import.ts +5 -0
- package/src/commands/migrate.ts +2 -0
- package/src/commands/move.ts +34 -0
- package/src/commands/remove.ts +24 -2
- package/src/commands/rename.ts +2 -0
- package/src/commands/show.ts +63 -34
- package/src/commands/transition.ts +2 -0
- package/src/commands/update.ts +9 -3
- package/src/commands/validate.ts +1 -1
- package/src/containers/project/calculation-engine.ts +0 -1
- package/src/containers/project/card-cache.ts +1 -0
- package/src/containers/project.ts +75 -1
- package/src/containers/template.ts +1 -1
- package/src/interfaces/command-options.ts +1 -0
- package/src/interfaces/resource-interfaces.ts +5 -12
- package/src/macros/base-macro.ts +1 -1
- package/src/macros/graph/index.ts +3 -0
- package/src/macros/include/index.ts +19 -1
- package/src/macros/include/types.ts +15 -12
- package/src/macros/index.ts +4 -1
- package/src/macros/report/index.ts +1 -0
- package/src/module-manager.ts +5 -2
- package/src/project-settings.ts +2 -1
- package/src/resources/card-type-resource.ts +1 -1
- package/src/resources/create-defaults.ts +0 -1
- package/src/resources/field-type-resource.ts +2 -4
- package/src/resources/file-resource.ts +3 -1
- package/src/resources/folder-resource.ts +7 -2
- package/src/resources/graph-model-resource.ts +1 -25
- package/src/resources/graph-view-resource.ts +1 -25
- package/src/resources/link-type-resource.ts +1 -1
- package/src/resources/report-resource.ts +1 -25
- package/src/resources/resource-object.ts +22 -1
- package/src/resources/template-resource.ts +0 -23
- package/src/resources/workflow-resource.ts +45 -16
- package/src/utils/card-utils.ts +1 -1
- package/src/utils/commit-context.ts +45 -0
- package/src/utils/csv.ts +12 -0
- package/src/utils/file-utils.ts +3 -1
- package/src/utils/git-manager.ts +87 -0
- package/src/utils/handlebars-helpers.ts +95 -0
- package/src/utils/json.ts +29 -15
- package/src/utils/log-utils.ts +33 -4
- package/src/utils/report.ts +8 -74
- package/src/utils/rw-lock.ts +279 -0
- package/src/utils/user-preferences.ts +3 -0
package/src/commands/create.ts
CHANGED
|
@@ -21,10 +21,12 @@ import { Project } from '../containers/project.js';
|
|
|
21
21
|
import { Validate } from './validate.js';
|
|
22
22
|
|
|
23
23
|
import { EMPTY_RANK, sortItems } from '../utils/lexorank.js';
|
|
24
|
+
import { ROOT } from '../utils/constants.js';
|
|
24
25
|
import { isModulePath } from '../utils/card-utils.js';
|
|
25
26
|
import type { DataType } from '../interfaces/resource-interfaces.js';
|
|
26
27
|
import type { Card, ProjectFile } from '../interfaces/project-interfaces.js';
|
|
27
28
|
import { resourceName, resourceNameToString } from '../utils/resource-utils.js';
|
|
29
|
+
import { write } from '../utils/rw-lock.js';
|
|
28
30
|
import { writeJsonFile } from '../utils/json.js';
|
|
29
31
|
|
|
30
32
|
// todo: Is there a easy to way to make JSON schema into a TypeScript interface/type?
|
|
@@ -79,6 +81,10 @@ export class Create {
|
|
|
79
81
|
* @param count How many cards to add. By default one.
|
|
80
82
|
* @returns non-empty string array with ids of added cards
|
|
81
83
|
*/
|
|
84
|
+
@write(
|
|
85
|
+
(cardTypeName, templateName) =>
|
|
86
|
+
`Add cards of type ${cardTypeName} to template ${templateName}`,
|
|
87
|
+
)
|
|
82
88
|
public async addCards(
|
|
83
89
|
cardTypeName: string,
|
|
84
90
|
templateName: string,
|
|
@@ -139,6 +145,7 @@ export class Create {
|
|
|
139
145
|
* Adds a new hub location.
|
|
140
146
|
* @param hubUrl URL of the hub
|
|
141
147
|
*/
|
|
148
|
+
@write((hubUrl) => `Add hub ${hubUrl}`)
|
|
142
149
|
public async addHubLocation(hubUrl: string) {
|
|
143
150
|
return this.project.configuration.addHub(hubUrl);
|
|
144
151
|
}
|
|
@@ -149,6 +156,7 @@ export class Create {
|
|
|
149
156
|
* @param attachment path to an attachment file or attachment name if buffer is defined
|
|
150
157
|
* @param buffer (Optional) attachment buffer
|
|
151
158
|
*/
|
|
159
|
+
@write((cardKey, attachment) => `Add attachment ${attachment} to ${cardKey}`)
|
|
152
160
|
public async createAttachment(
|
|
153
161
|
cardKey: string,
|
|
154
162
|
attachment: string,
|
|
@@ -161,7 +169,7 @@ export class Create {
|
|
|
161
169
|
buffer || attachment,
|
|
162
170
|
);
|
|
163
171
|
} catch (error) {
|
|
164
|
-
throw new Error(errorFunction(error));
|
|
172
|
+
throw new Error(errorFunction(error), { cause: error });
|
|
165
173
|
}
|
|
166
174
|
}
|
|
167
175
|
|
|
@@ -169,6 +177,7 @@ export class Create {
|
|
|
169
177
|
* Creates a calculation resource.
|
|
170
178
|
* @param calculationName name for the calculation resource
|
|
171
179
|
*/
|
|
180
|
+
@write((calculationName) => `Create calculation ${calculationName}`)
|
|
172
181
|
public async createCalculation(calculationName: string) {
|
|
173
182
|
return this.project.resources
|
|
174
183
|
.byType(calculationName, 'calculations')
|
|
@@ -181,6 +190,7 @@ export class Create {
|
|
|
181
190
|
* @param parentCardKey (Optional) card-key of a parent card. If missing, cards are added to the card root.
|
|
182
191
|
* @returns array of card keys that were created. Cards are sorted by their parent key and rank. Template root cards are first but the order between other card groups is not guaranteed. However, the order of cards within a group is guaranteed to be ordered by rank.
|
|
183
192
|
*/
|
|
193
|
+
@write((templateName) => `Create card from template ${templateName}`)
|
|
184
194
|
public async createCard(
|
|
185
195
|
templateName: string,
|
|
186
196
|
parentCardKey?: string,
|
|
@@ -208,11 +218,20 @@ export class Create {
|
|
|
208
218
|
|
|
209
219
|
const createdCards = await templateObject.createCards(specificCard);
|
|
210
220
|
if (createdCards.length > 0) {
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
221
|
+
const rootParent = specificCard?.key ?? ROOT;
|
|
222
|
+
const rootCards: Card[] = [];
|
|
223
|
+
const childCards: Card[] = [];
|
|
224
|
+
for (const card of createdCards) {
|
|
225
|
+
if (card.parent === rootParent) {
|
|
226
|
+
rootCards.push(card);
|
|
227
|
+
} else {
|
|
228
|
+
childCards.push(card);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return [
|
|
232
|
+
...sortItems(rootCards, (item) => item.metadata?.rank || EMPTY_RANK),
|
|
233
|
+
...childCards,
|
|
234
|
+
];
|
|
216
235
|
}
|
|
217
236
|
return [];
|
|
218
237
|
}
|
|
@@ -222,6 +241,7 @@ export class Create {
|
|
|
222
241
|
* @param cardTypeName name for the card type.
|
|
223
242
|
* @param workflowName workflow name to use in the card type.
|
|
224
243
|
*/
|
|
244
|
+
@write((cardTypeName) => `Create card type ${cardTypeName}`)
|
|
225
245
|
public async createCardType(cardTypeName: string, workflowName: string) {
|
|
226
246
|
return this.project.resources
|
|
227
247
|
.byType(cardTypeName, 'cardTypes')
|
|
@@ -233,6 +253,7 @@ export class Create {
|
|
|
233
253
|
* @param fieldTypeName name for the field type.
|
|
234
254
|
* @param dataType data type for the field type
|
|
235
255
|
*/
|
|
256
|
+
@write((fieldTypeName) => `Create field type ${fieldTypeName}`)
|
|
236
257
|
public async createFieldType(fieldTypeName: string, dataType: DataType) {
|
|
237
258
|
return this.project.resources
|
|
238
259
|
.byType(fieldTypeName, 'fieldTypes')
|
|
@@ -243,6 +264,7 @@ export class Create {
|
|
|
243
264
|
* Creates a new graph model.
|
|
244
265
|
* @param graphModelName name for the graph model.
|
|
245
266
|
*/
|
|
267
|
+
@write((graphModelName) => `Create graph model ${graphModelName}`)
|
|
246
268
|
public async createGraphModel(graphModelName: string) {
|
|
247
269
|
return this.project.resources
|
|
248
270
|
.byType(graphModelName, 'graphModels')
|
|
@@ -253,6 +275,7 @@ export class Create {
|
|
|
253
275
|
* Creates a new graph view.
|
|
254
276
|
* @param graphViewName name for the graph view.
|
|
255
277
|
*/
|
|
278
|
+
@write((graphViewName) => `Create graph view ${graphViewName}`)
|
|
256
279
|
public async createGraphView(graphViewName: string) {
|
|
257
280
|
return this.project.resources.byType(graphViewName, 'graphViews').create();
|
|
258
281
|
}
|
|
@@ -262,6 +285,7 @@ export class Create {
|
|
|
262
285
|
* @param cardKey The card to which the label is added to
|
|
263
286
|
* @param label The label being added
|
|
264
287
|
*/
|
|
288
|
+
@write((cardKey, label) => `Add label ${label} to ${cardKey}`)
|
|
265
289
|
public async createLabel(cardKey: string, label: string) {
|
|
266
290
|
if (!Validate.isValidLabelName(label)) {
|
|
267
291
|
throw new Error(`Not a valid label name'`);
|
|
@@ -282,6 +306,7 @@ export class Create {
|
|
|
282
306
|
* Creates a new link type.
|
|
283
307
|
* @param linkTypeName name for the link type.
|
|
284
308
|
*/
|
|
309
|
+
@write((linkTypeName) => `Create link type ${linkTypeName}`)
|
|
285
310
|
public async createLinkType(linkTypeName: string) {
|
|
286
311
|
return this.project.resources.byType(linkTypeName, 'linkTypes').create();
|
|
287
312
|
}
|
|
@@ -293,6 +318,10 @@ export class Create {
|
|
|
293
318
|
* @param linkType The type of link to add
|
|
294
319
|
* @param linkDescription Optional description of the link
|
|
295
320
|
*/
|
|
321
|
+
@write(
|
|
322
|
+
(cardKey, destinationCardKey, linkType) =>
|
|
323
|
+
`Create ${linkType} link from ${cardKey} to ${destinationCardKey}`,
|
|
324
|
+
)
|
|
296
325
|
public async createLink(
|
|
297
326
|
cardKey: string,
|
|
298
327
|
destinationCardKey: string,
|
|
@@ -383,6 +412,7 @@ export class Create {
|
|
|
383
412
|
projectCategory: string,
|
|
384
413
|
projectDescription: string,
|
|
385
414
|
) {
|
|
415
|
+
// No lock required, since we are creating a new project
|
|
386
416
|
projectPath = resolve(projectPath);
|
|
387
417
|
|
|
388
418
|
if (!projectPath) {
|
|
@@ -472,6 +502,7 @@ export class Create {
|
|
|
472
502
|
* Creates a report
|
|
473
503
|
* @param name name of the report
|
|
474
504
|
*/
|
|
505
|
+
@write((name) => `Create report ${name}`)
|
|
475
506
|
public async createReport(name: string) {
|
|
476
507
|
return this.project.resources.byType(name, 'reports').createReport();
|
|
477
508
|
}
|
|
@@ -481,6 +512,7 @@ export class Create {
|
|
|
481
512
|
* @param templateName Name of the template.
|
|
482
513
|
* @param templateContent JSON content for the template file.
|
|
483
514
|
*/
|
|
515
|
+
@write((templateName) => `Create template ${templateName}`)
|
|
484
516
|
public async createTemplate(templateName: string, templateContent: string) {
|
|
485
517
|
return this.project.resources
|
|
486
518
|
.byType(templateName, 'templates')
|
|
@@ -492,6 +524,7 @@ export class Create {
|
|
|
492
524
|
* @param workflowName workflow name
|
|
493
525
|
* @param workflowContent workflow content JSON
|
|
494
526
|
*/
|
|
527
|
+
@write((workflowName) => `Create workflow ${workflowName}`)
|
|
495
528
|
public async createWorkflow(workflowName: string, workflowContent: string) {
|
|
496
529
|
return this.project.resources
|
|
497
530
|
.byType(workflowName, 'workflows')
|
package/src/commands/edit.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
19
19
|
import { ActionGuard } from '../permissions/action-guard.js';
|
|
20
20
|
import { Project } from '../containers/project.js';
|
|
21
21
|
import { UserPreferences } from '../utils/user-preferences.js';
|
|
22
|
+
import { write } from '../utils/rw-lock.js';
|
|
22
23
|
|
|
23
24
|
import type { MetadataContent } from '../interfaces/project-interfaces.js';
|
|
24
25
|
|
|
@@ -76,6 +77,7 @@ export class Edit {
|
|
|
76
77
|
* @param cardKey The card to update.
|
|
77
78
|
* @param changedContent New content for the card.
|
|
78
79
|
*/
|
|
80
|
+
@write((cardKey) => `Edit content of ${cardKey}`)
|
|
79
81
|
public async editCardContent(cardKey: string, changedContent: string) {
|
|
80
82
|
if (this.project.hasTemplateCard(cardKey)) {
|
|
81
83
|
return this.project.updateCardContent(cardKey, changedContent);
|
|
@@ -93,6 +95,7 @@ export class Edit {
|
|
|
93
95
|
* @param changedKey Which metadata property was changed
|
|
94
96
|
* @param newValue New value for the metadata property
|
|
95
97
|
*/
|
|
98
|
+
@write((cardKey) => `Edit metadata of ${cardKey}`)
|
|
96
99
|
public async editCardMetadata(
|
|
97
100
|
cardKey: string,
|
|
98
101
|
changedKey: string,
|
package/src/commands/export.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { generateReportContent } from '../utils/report.js';
|
|
|
31
31
|
import { getStaticDirectoryPath, pdfReport } from '@cyberismo/assets';
|
|
32
32
|
import { Project } from '../containers/project.js';
|
|
33
33
|
import type { QueryResult } from '../types/queries.js';
|
|
34
|
+
import { read } from '../utils/rw-lock.js';
|
|
34
35
|
import type { Show } from './show.js';
|
|
35
36
|
import { sortItems } from '../utils/lexorank.js';
|
|
36
37
|
|
|
@@ -246,7 +247,10 @@ export class Export {
|
|
|
246
247
|
children: [],
|
|
247
248
|
attachments: [],
|
|
248
249
|
};
|
|
249
|
-
const cardDetailsResponse = this.showCmd.showCardDetails(
|
|
250
|
+
const cardDetailsResponse = await this.showCmd.showCardDetails(
|
|
251
|
+
card.key,
|
|
252
|
+
'adoc',
|
|
253
|
+
);
|
|
250
254
|
let asciiDocContent = '';
|
|
251
255
|
const project = this.project;
|
|
252
256
|
try {
|
|
@@ -283,6 +287,7 @@ export class Export {
|
|
|
283
287
|
* @param options Export options.
|
|
284
288
|
* @returns status message
|
|
285
289
|
*/
|
|
290
|
+
@read
|
|
286
291
|
public async exportPdf(
|
|
287
292
|
destination: string,
|
|
288
293
|
options: ExportPdfOptions,
|
|
@@ -320,6 +325,7 @@ export class Export {
|
|
|
320
325
|
* @param cardKey If not exporting the whole card tree, card key of parent card.
|
|
321
326
|
* @returns status message
|
|
322
327
|
*/
|
|
328
|
+
@read
|
|
323
329
|
public async exportToADoc(
|
|
324
330
|
destination: string,
|
|
325
331
|
cardKey?: string,
|
|
@@ -365,7 +371,7 @@ export class Export {
|
|
|
365
371
|
destination,
|
|
366
372
|
Project.cardContentFile,
|
|
367
373
|
);
|
|
368
|
-
let message
|
|
374
|
+
let message: string;
|
|
369
375
|
try {
|
|
370
376
|
await truncate(resultDocumentPath, 0);
|
|
371
377
|
message = `Using existing output file '${resultDocumentPath}'`;
|
package/src/commands/fetch.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { resolve, sep } from 'node:path';
|
|
|
17
17
|
import { getChildLogger } from '../utils/log-utils.js';
|
|
18
18
|
import { readJsonFile, writeJsonFile } from '../utils/json.js';
|
|
19
19
|
import { validateJson } from '../utils/validate.js';
|
|
20
|
+
import { write } from '../utils/rw-lock.js';
|
|
20
21
|
|
|
21
22
|
import type { ModuleSetting } from '../interfaces/project-interfaces.js';
|
|
22
23
|
import type { Project } from '../containers/project.js';
|
|
@@ -203,6 +204,7 @@ export class Fetch {
|
|
|
203
204
|
/**
|
|
204
205
|
* Ensures the module list is up to date by fetching if needed.
|
|
205
206
|
*/
|
|
207
|
+
@write()
|
|
206
208
|
public async ensureModuleListUpToDate() {
|
|
207
209
|
await this.fetchHubs();
|
|
208
210
|
}
|
|
@@ -211,6 +213,7 @@ export class Fetch {
|
|
|
211
213
|
* Fetches modules from modules hub(s) and writes them to a file.
|
|
212
214
|
* Only fetches if the remote version is newer than the local version.
|
|
213
215
|
*/
|
|
216
|
+
@write(() => 'Fetch hubs')
|
|
214
217
|
public async fetchHubs() {
|
|
215
218
|
const needsFetch = await this.fetchModuleList();
|
|
216
219
|
if (!needsFetch) {
|
package/src/commands/import.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { ModuleManager } from '../module-manager.js';
|
|
15
15
|
import { readCsvFile } from '../utils/csv.js';
|
|
16
16
|
import { Validate } from './validate.js';
|
|
17
|
+
import { write } from '../utils/rw-lock.js';
|
|
17
18
|
|
|
18
19
|
import type { Create } from './create.js';
|
|
19
20
|
import type {
|
|
@@ -48,6 +49,7 @@ export class Import {
|
|
|
48
49
|
* @param parentCardKey the cards in the csv file will be created under this card
|
|
49
50
|
* @returns card keys of the imported cards
|
|
50
51
|
*/
|
|
52
|
+
@write((csvFilePath) => `Import cards from CSV ${csvFilePath}`)
|
|
51
53
|
public async importCsv(
|
|
52
54
|
csvFilePath: string,
|
|
53
55
|
parentCardKey?: string,
|
|
@@ -137,6 +139,7 @@ export class Import {
|
|
|
137
139
|
* private: If true, uses credentials to clone the repository
|
|
138
140
|
* @param skipMigrationLog If true, skip logging to migration log (used during project creation)
|
|
139
141
|
*/
|
|
142
|
+
@write((source) => `Import module ${source}`)
|
|
140
143
|
public async importModule(
|
|
141
144
|
source: string,
|
|
142
145
|
destination?: string,
|
|
@@ -195,6 +198,7 @@ export class Import {
|
|
|
195
198
|
* @param credentials Optional credentials for a private module.
|
|
196
199
|
* @throws if module is not part of the project
|
|
197
200
|
*/
|
|
201
|
+
@write((moduleName) => `Update module ${moduleName}`)
|
|
198
202
|
public async updateModule(moduleName: string, credentials?: Credentials) {
|
|
199
203
|
// Ensure module list is up to date before updating
|
|
200
204
|
await this.fetchCmd.ensureModuleListUpToDate();
|
|
@@ -212,6 +216,7 @@ export class Import {
|
|
|
212
216
|
* Updates all imported modules.
|
|
213
217
|
* @param credentials Optional credentials for private modules.
|
|
214
218
|
*/
|
|
219
|
+
@write(() => 'Update all modules')
|
|
215
220
|
public async updateAllModules(credentials?: Credentials) {
|
|
216
221
|
// Ensure module list is up to date before updating all modules
|
|
217
222
|
await this.fetchCmd.ensureModuleListUpToDate();
|
package/src/commands/migrate.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { SCHEMA_VERSION } from '@cyberismo/assets';
|
|
15
15
|
import type { MigrationResult } from '@cyberismo/migrations';
|
|
16
16
|
import type { Project } from '../containers/project.js';
|
|
17
|
+
import { write } from '../utils/rw-lock.js';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Command that handles schema migration operations.
|
|
@@ -32,6 +33,7 @@ export class Migrate {
|
|
|
32
33
|
* @param timeoutMilliSeconds Optional timeout in milliseconds (defaults to 2 minutes)
|
|
33
34
|
* @returns Migration result
|
|
34
35
|
*/
|
|
36
|
+
@write(() => 'Migrate project')
|
|
35
37
|
public async migrate(
|
|
36
38
|
toVersion?: number,
|
|
37
39
|
backupDir?: string,
|
package/src/commands/move.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { ActionGuard } from '../permissions/action-guard.js';
|
|
|
18
18
|
import { copyDir, deleteDir } from '../utils/file-utils.js';
|
|
19
19
|
import type { Card } from '../interfaces/project-interfaces.js';
|
|
20
20
|
import type { Project } from '../containers/project.js';
|
|
21
|
+
import { write } from '../utils/rw-lock.js';
|
|
21
22
|
import {
|
|
22
23
|
EMPTY_RANK,
|
|
23
24
|
FIRST_RANK,
|
|
@@ -100,6 +101,7 @@ export class Move {
|
|
|
100
101
|
* @param source source card to move
|
|
101
102
|
* @param destination destination card where source card will be moved to; or to root
|
|
102
103
|
*/
|
|
104
|
+
@write((source, destination) => `Move card ${source} to ${destination}`)
|
|
103
105
|
public async moveCard(source: string, destination: string) {
|
|
104
106
|
if (source === ROOT) {
|
|
105
107
|
throw new Error('Cannot move "root"');
|
|
@@ -188,6 +190,9 @@ export class Move {
|
|
|
188
190
|
? getRankAfter(lastChild.metadata.rank)
|
|
189
191
|
: FIRST_RANK;
|
|
190
192
|
|
|
193
|
+
// Save old path before moving (needed to update descendant paths)
|
|
194
|
+
const oldPath = sourceCard.path;
|
|
195
|
+
|
|
191
196
|
// First do the file operations, then update metadata
|
|
192
197
|
await copyDir(sourceCard.path, destinationPath);
|
|
193
198
|
await deleteDir(sourceCard.path);
|
|
@@ -199,8 +204,32 @@ export class Move {
|
|
|
199
204
|
sourceCard.metadata.rank = rank;
|
|
200
205
|
}
|
|
201
206
|
|
|
207
|
+
// Update attachment paths for the moved card
|
|
208
|
+
if (sourceCard.attachments && sourceCard.attachments.length > 0) {
|
|
209
|
+
for (const attachment of sourceCard.attachments) {
|
|
210
|
+
if (attachment.path.startsWith(oldPath)) {
|
|
211
|
+
attachment.path = attachment.path.replace(oldPath, destinationPath);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
202
216
|
// Handle cache update and persistence
|
|
203
217
|
await this.project.updateCard(sourceCard);
|
|
218
|
+
|
|
219
|
+
// Update all descendant card paths in the cache to reflect the new filesystem location.
|
|
220
|
+
// This is critical: files have been moved on disk, but children's cached paths
|
|
221
|
+
// still point to the old location. Without this, operations on children
|
|
222
|
+
// (like edit or delete) would target non-existent paths, leaving orphaned files.
|
|
223
|
+
if (sourceCard.children && sourceCard.children.length > 0) {
|
|
224
|
+
for (const childKey of sourceCard.children) {
|
|
225
|
+
this.project.updateDescendantPathsAfterMove(
|
|
226
|
+
childKey,
|
|
227
|
+
oldPath,
|
|
228
|
+
destinationPath,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
204
233
|
const updatedCard: Card = {
|
|
205
234
|
...sourceCard,
|
|
206
235
|
path: destinationPath,
|
|
@@ -238,6 +267,7 @@ export class Move {
|
|
|
238
267
|
* @param cardKey card key
|
|
239
268
|
* @param index to which position should card be ranked to
|
|
240
269
|
*/
|
|
270
|
+
@write((cardKey) => `Reorder card ${cardKey}`)
|
|
241
271
|
public async rankByIndex(cardKey: string, index: number) {
|
|
242
272
|
if (index < 0) {
|
|
243
273
|
throw new Error(`Index must be greater than 0`);
|
|
@@ -272,6 +302,7 @@ export class Move {
|
|
|
272
302
|
* @param cardKey Card to rank
|
|
273
303
|
* @param beforeCardKey Card key after which the card will be ranked
|
|
274
304
|
*/
|
|
305
|
+
@write((cardKey) => `Reorder card ${cardKey}`)
|
|
275
306
|
public async rankCard(cardKey: string, beforeCardKey: string) {
|
|
276
307
|
const card = this.project.findCard(cardKey);
|
|
277
308
|
const beforeCard = this.project.findCard(beforeCardKey);
|
|
@@ -325,6 +356,7 @@ export class Move {
|
|
|
325
356
|
* Ranks card first.
|
|
326
357
|
* @param cardKey card key
|
|
327
358
|
*/
|
|
359
|
+
@write((cardKey) => `Rank card ${cardKey} first`)
|
|
328
360
|
public async rankFirst(cardKey: string) {
|
|
329
361
|
const card = this.project.findCard(cardKey);
|
|
330
362
|
const children = sortItems(
|
|
@@ -370,6 +402,7 @@ export class Move {
|
|
|
370
402
|
* Rebalances the ranks of the children of a card.
|
|
371
403
|
* @param parentCardKey parent card key
|
|
372
404
|
*/
|
|
405
|
+
@write((parentCardKey) => `Rebalance children of ${parentCardKey}`)
|
|
373
406
|
public async rebalanceChildren(parentCardKey: string) {
|
|
374
407
|
const parentCard = this.project.findCard(parentCardKey);
|
|
375
408
|
if (!parentCard || !parentCard.children) {
|
|
@@ -384,6 +417,7 @@ export class Move {
|
|
|
384
417
|
* Rebalances the ranks of the cards in the whole project, including templates
|
|
385
418
|
* Can be used even if the ranks do not exist
|
|
386
419
|
*/
|
|
420
|
+
@write(() => 'Rebalance project')
|
|
387
421
|
public async rebalanceProject() {
|
|
388
422
|
const cards = this.project.showProjectCards();
|
|
389
423
|
|
package/src/commands/remove.ts
CHANGED
|
@@ -13,16 +13,21 @@
|
|
|
13
13
|
|
|
14
14
|
import { ActionGuard } from '../permissions/action-guard.js';
|
|
15
15
|
import { isModuleCard } from '../utils/card-utils.js';
|
|
16
|
+
import { getChildLogger } from '../utils/log-utils.js';
|
|
16
17
|
import { ModuleManager } from '../module-manager.js';
|
|
17
18
|
import type { Fetch } from './fetch.js';
|
|
18
19
|
import type { Project } from '../containers/project.js';
|
|
19
20
|
import type { RemovableResourceTypes } from '../interfaces/project-interfaces.js';
|
|
21
|
+
import { write } from '../utils/rw-lock.js';
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* Remove command.
|
|
23
25
|
*/
|
|
24
26
|
export class Remove {
|
|
25
27
|
private moduleManager: ModuleManager;
|
|
28
|
+
private get logger() {
|
|
29
|
+
return getChildLogger({ module: 'remove' });
|
|
30
|
+
}
|
|
26
31
|
/**
|
|
27
32
|
* Creates a new instance of Remove command.
|
|
28
33
|
* @param project Project instance to use
|
|
@@ -73,14 +78,30 @@ export class Remove {
|
|
|
73
78
|
await actionGuard.checkPermission('delete', cardKey);
|
|
74
79
|
}
|
|
75
80
|
|
|
76
|
-
//
|
|
81
|
+
// Collect all card keys that will be deleted (the card itself and all descendants).
|
|
82
|
+
const cardsToDelete = new Set<string>();
|
|
83
|
+
const collectDescendants = (c: typeof card) => {
|
|
84
|
+
cardsToDelete.add(c.key);
|
|
85
|
+
for (const childKey of c.children) {
|
|
86
|
+
try {
|
|
87
|
+
const childCard = this.project.findCard(childKey);
|
|
88
|
+
collectDescendants(childCard);
|
|
89
|
+
} catch {
|
|
90
|
+
this.logger.debug({ childKey }, 'Child card not found, skipping');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
collectDescendants(card);
|
|
95
|
+
|
|
96
|
+
// If any of the cards to be deleted is a destination of a link, remove the link.
|
|
77
97
|
const allCards = this.project.cards(this.project.paths.cardRootFolder);
|
|
78
98
|
const promiseContainer: Promise<void>[] = [];
|
|
79
99
|
|
|
80
100
|
for (const item of allCards) {
|
|
101
|
+
if (cardsToDelete.has(item.key)) continue;
|
|
81
102
|
const links = item.metadata?.links ?? [];
|
|
82
103
|
for (const link of links) {
|
|
83
|
-
if (link.cardKey
|
|
104
|
+
if (cardsToDelete.has(link.cardKey)) {
|
|
84
105
|
promiseContainer.push(this.removeLink(item.key, link.cardKey));
|
|
85
106
|
}
|
|
86
107
|
}
|
|
@@ -163,6 +184,7 @@ export class Remove {
|
|
|
163
184
|
* when removing link, some of the mandatory parameters are missing, or
|
|
164
185
|
* when trying to remove unknown type
|
|
165
186
|
*/
|
|
187
|
+
@write((type, targetName) => `Remove ${type} ${targetName}`)
|
|
166
188
|
public async remove(
|
|
167
189
|
type: RemovableResourceTypes,
|
|
168
190
|
targetName: string,
|
package/src/commands/rename.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import { isTemplateCard } from '../utils/card-utils.js';
|
|
25
25
|
import { type Project, ResourcesFrom } from '../containers/project.js';
|
|
26
26
|
import { resourceName } from '../utils/resource-utils.js';
|
|
27
|
+
import { write } from '../utils/rw-lock.js';
|
|
27
28
|
|
|
28
29
|
const FILE_TYPES_WITH_PREFIX_REFERENCES = ['adoc', 'hbs', 'json', 'lp'];
|
|
29
30
|
|
|
@@ -186,6 +187,7 @@ export class Rename {
|
|
|
186
187
|
* @throws if trying to rename with current name
|
|
187
188
|
* @param to Card id, or template name
|
|
188
189
|
*/
|
|
190
|
+
@write((to) => `Rename project prefix to ${to}`)
|
|
189
191
|
public async rename(to: string) {
|
|
190
192
|
if (!to) {
|
|
191
193
|
throw new Error(`Input validation error: empty 'to' is not allowed`);
|