contensis-cli 1.0.12-beta.6 → 1.0.12-beta.8

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 (40) hide show
  1. package/dist/commands/get.js +12 -0
  2. package/dist/commands/get.js.map +2 -2
  3. package/dist/commands/import.js +12 -7
  4. package/dist/commands/import.js.map +2 -2
  5. package/dist/commands/list.js +9 -0
  6. package/dist/commands/list.js.map +2 -2
  7. package/dist/commands/remove.js +13 -0
  8. package/dist/commands/remove.js.map +2 -2
  9. package/dist/localisation/en-GB.js +7 -1
  10. package/dist/localisation/en-GB.js.map +2 -2
  11. package/dist/providers/file-provider.js +5 -1
  12. package/dist/providers/file-provider.js.map +2 -2
  13. package/dist/services/ContensisCliService.js +124 -10
  14. package/dist/services/ContensisCliService.js.map +2 -2
  15. package/dist/shell.js +3 -0
  16. package/dist/shell.js.map +2 -2
  17. package/dist/util/console.printer.js +52 -45
  18. package/dist/util/console.printer.js.map +3 -3
  19. package/dist/util/error.js +36 -0
  20. package/dist/util/error.js.map +7 -0
  21. package/dist/util/find.js +10 -2
  22. package/dist/util/find.js.map +2 -2
  23. package/dist/util/logger.js +52 -9
  24. package/dist/util/logger.js.map +3 -3
  25. package/dist/version.js +1 -1
  26. package/dist/version.js.map +1 -1
  27. package/package.json +2 -2
  28. package/src/commands/get.ts +18 -0
  29. package/src/commands/import.ts +12 -6
  30. package/src/commands/list.ts +15 -0
  31. package/src/commands/remove.ts +20 -0
  32. package/src/localisation/en-GB.ts +9 -2
  33. package/src/providers/file-provider.ts +5 -1
  34. package/src/services/ContensisCliService.ts +161 -13
  35. package/src/shell.ts +3 -0
  36. package/src/util/console.printer.ts +121 -54
  37. package/src/util/error.ts +7 -0
  38. package/src/util/find.ts +13 -2
  39. package/src/util/logger.ts +90 -15
  40. package/src/version.ts +1 -1
@@ -1,15 +1,17 @@
1
1
  import { Node } from 'contensis-delivery-api/lib/models';
2
2
  import dayjs from 'dayjs';
3
+ import { deconstructApiError } from './error';
4
+ import { Logger, addNewLines } from './logger';
3
5
  import {
4
6
  BlockVersion,
5
7
  EntriesResult,
6
8
  MigrateModelsResult,
9
+ MigrateNodesTree,
7
10
  MigrateStatus,
8
11
  NodesResult,
9
12
  ProjectNodesToMigrate,
10
13
  } from 'migratortron';
11
14
  import ContensisCli from '~/services/ContensisCliService';
12
- import { Logger } from './logger';
13
15
 
14
16
  const formatDate = (date: Date | string, format = 'DD/MM/YYYY HH:mm') =>
15
17
  dayjs(date).format(format);
@@ -263,46 +265,23 @@ export const printEntriesMigrateResult = (
263
265
  };
264
266
 
265
267
  export const printNodesMigrateResult = (
266
- { log, messages, currentProject }: ContensisCli,
268
+ { log, currentProject }: ContensisCli,
267
269
  migrateResult: NodesResult,
268
270
  {
269
271
  action = 'import',
272
+ logLimit = 50,
270
273
  showDiff = false,
271
274
  showAll = false,
272
275
  showChanged = false,
273
276
  }: {
274
277
  action?: 'import' | 'delete';
278
+ logLimit?: number;
275
279
  showDiff?: boolean;
276
280
  showAll?: boolean;
277
281
  showChanged?: boolean;
278
282
  } = {}
279
283
  ) => {
280
- console.log(``);
281
-
282
- for (const [originalId, migrateNodeId] of Object.entries(
283
- migrateResult.nodesToMigrate.nodeIds
284
- )) {
285
- if (showAll || (showChanged && migrateNodeId.status !== 'no change')) {
286
- console.log(
287
- log.infoText(
288
- `${originalId} ${`${messages.migrate.status(migrateNodeId.status)(
289
- `${migrateNodeId.status}`
290
- )}${
291
- migrateNodeId.id !== originalId ? `-> ${migrateNodeId.id}` : ''
292
- }`}`
293
- ) + ` ${log.helpText(migrateNodeId.path)} ${migrateNodeId.displayName}`
294
- );
295
-
296
- if (migrateNodeId.diff && showDiff)
297
- console.log(
298
- ` ${log.highlightText(`diff:`)} ${log.infoText(
299
- highlightDiffText(migrateNodeId.diff)
300
- )}\n`
301
- );
302
- }
303
- }
304
- if (showAll || showChanged) console.log(``);
305
-
284
+ log.raw(``);
306
285
  for (const [projectId, counts] of Object.entries(migrateResult.nodes || {})) {
307
286
  const importTitle =
308
287
  action === 'delete'
@@ -364,15 +343,18 @@ export const printNodesMigrateResult = (
364
343
  console.log(
365
344
  ` - ${log.errorText(`errors: ${migrateResult.errors.length}`)}\n`
366
345
  );
367
- for (const error of migrateResult.errors) {
368
- let inner = '';
369
- if (error.data?.[0]) {
370
- inner = `${error.data?.[0].Field}: ${error.data?.[0].Message}`;
371
- }
372
- log.error(`${error.message} ${inner}`, null, '');
373
- }
346
+
347
+ log.limits(
348
+ migrateResult.errors
349
+ .map(error => {
350
+ return log.errorText(deconstructApiError(error));
351
+ })
352
+ .join('\n'),
353
+ logLimit
354
+ );
374
355
  }
375
356
  };
357
+
376
358
  const highlightDiffText = (str: string) => {
377
359
  const addedRegex = new RegExp(/<<\+>>(.*?)<<\/\+>>/, 'g');
378
360
  const removedRegex = new RegExp(/<<->>(.*?)<<\/->>/, 'g');
@@ -484,41 +466,126 @@ export const printModelMigrationResult = (
484
466
  };
485
467
 
486
468
  export const printNodeTreeOutput = (
487
- { log }: ContensisCli,
488
- root: Node | undefined
469
+ { log, messages }: ContensisCli,
470
+ root: Node | MigrateNodesTree | undefined,
471
+ logDetail = 'errors',
472
+ logLimit = 1000
489
473
  ) => {
490
- log.object({ ...root, children: undefined });
491
474
  log.raw('');
475
+ const statusColour = messages.migrate.status;
476
+
477
+ if (root && 'status' in root)
478
+ log.info(
479
+ `Migrate status: ${statusColour('no change')(
480
+ 'N'
481
+ )} [no change]; ${statusColour('create')('C')} [create]; ${statusColour(
482
+ 'update'
483
+ )('U')} [update]; ${statusColour('delete')('D')} [delete]; ${statusColour(
484
+ 'error'
485
+ )('E')} [error];`
486
+ );
492
487
  log.info(
493
- `${log.highlightText('e')} = has entry; ${log.highlightText(
494
- 'c'
495
- )} = canonical; ${log.highlightText('m')} = include in menu`
488
+ `Node properties: ${log.highlightText(
489
+ 'e'
490
+ )} = has entry; ${log.highlightText('c')} = canonical; ${log.highlightText(
491
+ 'm'
492
+ )} = include in menu`
496
493
  );
494
+
497
495
  log.line();
498
496
 
499
- const outputNode = (node: Node | any, spaces: string) =>
500
- `${node.entry ? log.highlightText('e') : log.infoText('-')}${
501
- node.isCanonical ? log.highlightText('c') : log.infoText('-')
497
+ const outputNode = (
498
+ node: Node | MigrateNodesTree,
499
+ spaces: string,
500
+ isRoot = false
501
+ ) => {
502
+ const errorOutput =
503
+ 'error' in node && node.error && deconstructApiError(node.error);
504
+ const fullOutput = logDetail === 'all';
505
+ const changesOutput =
506
+ logDetail === 'changes' &&
507
+ 'status' in node &&
508
+ ['create', 'update'].includes(node.status);
509
+
510
+ const diffOutput =
511
+ (fullOutput || changesOutput || errorOutput) &&
512
+ 'diff' in node &&
513
+ node.diff?.replaceAll('\n', '');
514
+
515
+ return `${
516
+ 'status' in node
517
+ ? `${statusColour(node.status)(
518
+ node.status.substring(0, 1).toUpperCase()
519
+ )} `
520
+ : ''
521
+ }${node.entry ? log.highlightText('e') : log.infoText('-')}${
522
+ 'isCanonical' in node && node.isCanonical
523
+ ? log.highlightText('c')
524
+ : log.infoText('-')
502
525
  }${
503
526
  node.includeInMenu ? log.highlightText('m') : log.infoText('-')
504
- }${spaces}${
505
- node.isCanonical ? log.boldText(`/${node.slug}`) : `/${node.slug}`
506
- }${node.entry ? ` ${log.helpText(node.entry.sys.contentTypeId)}` : ''}${
527
+ }${spaces}${log[
528
+ 'status' in node && node.status === 'no change'
529
+ ? 'infoText'
530
+ : 'standardText'
531
+ ](
532
+ 'isCanonical' in node && node.isCanonical
533
+ ? log.boldText(fullOutput || isRoot ? node.path : `/${node.slug}`)
534
+ : fullOutput || isRoot
535
+ ? node.path
536
+ : `/${node.slug}`
537
+ )}${node.entry ? ` ${log.helpText(node.entry.sys.contentTypeId)}` : ''}${
507
538
  node.childCount ? ` +${node.childCount}` : ``
508
- } ${log.infoText(node.displayName)}`;
539
+ } ${'displayName' in node ? log.infoText(node.displayName) : ''}${
540
+ fullOutput || (changesOutput && node.id !== node.originalId)
541
+ ? `~n ${log.infoText(`id:`)} ${
542
+ node.id === node.originalId
543
+ ? node.id
544
+ : `${node.id} ${log.infoText(`<= ${node.originalId}`)}`
545
+ }`
546
+ : ''
547
+ }${
548
+ (fullOutput ||
549
+ (changesOutput && node.parentId !== node.originalParentId)) &&
550
+ node.parentId
551
+ ? `~n ${log.infoText(
552
+ `parentId: ${
553
+ node.parentId === node.originalParentId
554
+ ? node.parentId
555
+ : `${node.parentId} <= ${node.originalParentId}`
556
+ }`
557
+ )}`
558
+ : ''
559
+ }${
560
+ fullOutput && node.entry?.sys.id
561
+ ? `~n ${log.infoText(`entryId: ${node.entry.sys.id}`)}`
562
+ : ''
563
+ }${
564
+ errorOutput
565
+ ? `~n${addNewLines(` ${log.errorText(errorOutput)}`, '~n')}`
566
+ : ''
567
+ }${
568
+ diffOutput
569
+ ? `~n${addNewLines(
570
+ ` ${log.infoText(`diff: ${highlightDiffText(diffOutput)}`)}`,
571
+ '~n'
572
+ )}`
573
+ : ''
574
+ }`;
575
+ };
509
576
 
510
- const outputChildren = (root: Node | undefined, depth = 2) => {
577
+ const outputChildren = (node: Node | undefined, depth = 2) => {
511
578
  let str = '';
512
- for (const node of (root as any)?.children as Node[]) {
513
- str += `${outputNode(node, Array(depth + 1).join(' '))}\n`;
514
- if ('children' in node) str += outputChildren(node, depth + 1);
579
+ for (const child of ((node as any)?.children || []) as Node[]) {
580
+ str += `${outputNode(child, Array(depth + 1).join(' '))}\n`;
581
+ if ('children' in child) str += outputChildren(child, depth + 1);
515
582
  }
516
583
  return str;
517
584
  };
518
585
 
519
586
  const children = outputChildren(root);
520
587
  log.limits(
521
- `${outputNode(root, ' ')}${children ? `\n${children}` : ''}`,
522
- 100
588
+ `${outputNode(root || {}, ' ', true)}${children ? `\n${children}` : ''}`,
589
+ logLimit
523
590
  );
524
591
  };
@@ -0,0 +1,7 @@
1
+ export const deconstructApiError = (error: MappedError) => {
2
+ let inner = '';
3
+ if (error.data?.[0]) {
4
+ inner = `${error.data?.[0].Field}: ${error.data?.[0].Message}`;
5
+ }
6
+ return `${error.message} ${inner}`;
7
+ };
package/src/util/find.ts CHANGED
@@ -2,7 +2,18 @@ export const findByIdOrName = (arr: any[], idOrName: string, exact = false) =>
2
2
  arr.find(
3
3
  r =>
4
4
  r.id === idOrName ||
5
- r.name.toLowerCase() === idOrName.toLowerCase()
5
+ (typeof r.name === 'string' &&
6
+ r.name.toLowerCase() === idOrName.toLowerCase()) ||
7
+ (typeof r.name === 'object' &&
8
+ Object.values<string>(r.name || {})?.[0].toLowerCase() ===
9
+ idOrName.toLowerCase())
6
10
  ) ||
7
11
  (!exact &&
8
- arr.find(r => r.name.toLowerCase().includes(idOrName.toLowerCase())));
12
+ arr.find(
13
+ r =>
14
+ (typeof r.name === 'string' &&
15
+ r.name.toLowerCase().includes(idOrName.toLowerCase())) ||
16
+ (typeof r.name === 'object' &&
17
+ Object.values<string>(r.name || {})?.[0].toLowerCase() ===
18
+ idOrName.toLowerCase())
19
+ ));
@@ -2,7 +2,12 @@
2
2
  import chalk from 'chalk';
3
3
  import dateFormat from 'dateformat';
4
4
  import deepCleaner from 'deep-cleaner';
5
- import { ansiEscapeCodes, first, strlen } from 'printable-characters';
5
+ import {
6
+ ansiEscapeCodes,
7
+ first,
8
+ partition,
9
+ strlen,
10
+ } from 'printable-characters';
6
11
  // import ProgressBar from 'progress';
7
12
  import { isSysError, tryStringify } from '.';
8
13
 
@@ -225,24 +230,41 @@ export class Logger {
225
230
  else console.log(content);
226
231
  };
227
232
 
228
- static limits = (content: string, displayLength = 30) => {
229
- const consoleWidth = process.stdout.columns;
230
- console.info(
231
- consoleWidth
232
- ? content
233
- .split('\n')
234
- .slice(0, consoleWidth ? displayLength : undefined)
235
- .map((line: string) =>
236
- consoleWidth && strlen(line) > consoleWidth
237
- ? first(line, consoleWidth)
238
- : line
233
+ static limits = (
234
+ content: string,
235
+ displayLength = 30,
236
+ consoleWidth = process.stdout.columns,
237
+ logMethod: Function = console.info
238
+ ) => {
239
+ if (consoleWidth) {
240
+ const contentArray = content.endsWith('\n')
241
+ ? content.split('\n').slice(0, -1)
242
+ : content.split('\n');
243
+ const contentLines = contentArray.slice(
244
+ 0,
245
+ consoleWidth ? displayLength : undefined
246
+ );
247
+ for (const line of contentLines)
248
+ logMethod(
249
+ line
250
+ .split('~n')
251
+ .map(l =>
252
+ consoleWidth && strlen(l) > consoleWidth
253
+ ? first(l, consoleWidth)
254
+ : l
239
255
  )
240
256
  .join('\n')
241
- : content.replace(ansiEscapeCodes, '')
242
- );
257
+ );
258
+ } else {
259
+ logMethod(content.replace(ansiEscapeCodes, '').replaceAll('~n', '\n'));
260
+ }
261
+
243
262
  const tableArray = content.split('\n');
244
263
  if (consoleWidth && tableArray.length > displayLength)
245
- console.info(`\n`, `- and ${tableArray.length - displayLength} more...`);
264
+ console.info(
265
+ `\n`,
266
+ `- and ${tableArray.length - displayLength} more...\n`
267
+ );
246
268
  };
247
269
  }
248
270
 
@@ -265,6 +287,59 @@ export const logError: LogErrorFunc = (
265
287
  return null;
266
288
  };
267
289
 
290
+ export const addNewLines = (
291
+ message = '',
292
+ newLineSeparater = '\n',
293
+ atPosition = process.stdout.columns
294
+ ) => {
295
+ if (message === '' || atPosition === 0) {
296
+ return '';
297
+ }
298
+
299
+ let result = '';
300
+ let lengthCounter = 0;
301
+
302
+ // Partition the message string into an array of
303
+ // [nonPrintable, printable][]
304
+ const partitioned = partition(message);
305
+ const addSeparater = () => {
306
+ // If line length counter has exceeded the console width
307
+ // add a new line separater and reset the line length counter
308
+ if (lengthCounter >= atPosition) {
309
+ result += newLineSeparater;
310
+ lengthCounter = 0;
311
+ }
312
+ };
313
+
314
+ // Loop through the partitioned message parts
315
+ for (const [nonPrintable, printable] of partitioned) {
316
+ // Convert string to array as this will provide accurate
317
+ // lengths and splicing methods with all unicode chars
318
+ const textParts = Array.from(printable);
319
+ // Splice the remaining allowable line length from the text parts array
320
+ const text = textParts.splice(0, atPosition - lengthCounter);
321
+ // In the first iteration append the non printable unicode chars
322
+ // to the beginning of the spliced text
323
+ result += nonPrintable + text.join('');
324
+ // Keep a count of the current line length
325
+ // as one line of output could span multiple "partitions"
326
+ lengthCounter += text.length;
327
+ addSeparater();
328
+
329
+ // Handle any remaining text in this "partition"
330
+ while (textParts.length) {
331
+ // Splice the remaining allowable line length from the text parts array
332
+ const text = textParts.splice(0, atPosition - lengthCounter);
333
+ // Append the spliced text to the result
334
+ result += text.join('');
335
+ // Increase line length counter
336
+ lengthCounter += text.length;
337
+ addSeparater();
338
+ }
339
+ }
340
+ return result;
341
+ };
342
+
268
343
  export const progress = {
269
344
  current: { interrupt: (x: string) => {} },
270
345
  active: false,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const LIB_VERSION = "1.0.12-beta.6";
1
+ export const LIB_VERSION = "1.0.12-beta.8";