contensis-cli 1.0.12-beta.1 → 1.0.12-beta.11

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 (61) hide show
  1. package/README.md +9 -9
  2. package/dist/commands/get.js +13 -1
  3. package/dist/commands/get.js.map +2 -2
  4. package/dist/commands/globalOptions.js +9 -10
  5. package/dist/commands/globalOptions.js.map +2 -2
  6. package/dist/commands/import.js +25 -10
  7. package/dist/commands/import.js.map +2 -2
  8. package/dist/commands/index.js +2 -2
  9. package/dist/commands/index.js.map +2 -2
  10. package/dist/commands/list.js +9 -0
  11. package/dist/commands/list.js.map +2 -2
  12. package/dist/commands/remove.js +13 -0
  13. package/dist/commands/remove.js.map +2 -2
  14. package/dist/localisation/en-GB.js +8 -2
  15. package/dist/localisation/en-GB.js.map +2 -2
  16. package/dist/mappers/DevInit-to-CIWorkflow.js +6 -8
  17. package/dist/mappers/DevInit-to-CIWorkflow.js.map +2 -2
  18. package/dist/mappers/DevInit-to-RolePermissions.js.map +2 -2
  19. package/dist/providers/file-provider.js +5 -1
  20. package/dist/providers/file-provider.js.map +2 -2
  21. package/dist/services/ContensisAuthService.js.map +2 -2
  22. package/dist/services/ContensisCliService.js +164 -75
  23. package/dist/services/ContensisCliService.js.map +3 -3
  24. package/dist/services/ContensisDevService.js +48 -53
  25. package/dist/services/ContensisDevService.js.map +3 -3
  26. package/dist/shell.js +5 -0
  27. package/dist/shell.js.map +2 -2
  28. package/dist/util/console.printer.js +111 -10
  29. package/dist/util/console.printer.js.map +2 -2
  30. package/dist/util/error.js +36 -0
  31. package/dist/util/error.js.map +7 -0
  32. package/dist/util/find.js +10 -2
  33. package/dist/util/find.js.map +2 -2
  34. package/dist/util/git.js +1 -0
  35. package/dist/util/git.js.map +2 -2
  36. package/dist/util/logger.js +52 -9
  37. package/dist/util/logger.js.map +3 -3
  38. package/dist/version.js +1 -1
  39. package/dist/version.js.map +1 -1
  40. package/package.json +4 -4
  41. package/src/commands/get.ts +19 -1
  42. package/src/commands/globalOptions.ts +9 -7
  43. package/src/commands/import.ts +41 -13
  44. package/src/commands/index.ts +2 -3
  45. package/src/commands/list.ts +15 -0
  46. package/src/commands/remove.ts +20 -0
  47. package/src/localisation/en-GB.ts +10 -3
  48. package/src/mappers/DevInit-to-CIWorkflow.ts +6 -8
  49. package/src/mappers/DevInit-to-RolePermissions.ts +1 -0
  50. package/src/models/Cache.d.ts +1 -1
  51. package/src/providers/file-provider.ts +5 -1
  52. package/src/services/ContensisAuthService.ts +1 -1
  53. package/src/services/ContensisCliService.ts +206 -101
  54. package/src/services/ContensisDevService.ts +70 -66
  55. package/src/shell.ts +5 -0
  56. package/src/util/console.printer.ts +238 -12
  57. package/src/util/error.ts +7 -0
  58. package/src/util/find.ts +13 -2
  59. package/src/util/git.ts +2 -1
  60. package/src/util/logger.ts +90 -15
  61. package/src/version.ts +1 -1
@@ -29,6 +29,11 @@ class ContensisDev extends ContensisRole {
29
29
  git!: GitHelper;
30
30
  blockId!: string;
31
31
 
32
+ deployCredentials = {
33
+ clientId: '',
34
+ clientSecret: '',
35
+ };
36
+
32
37
  constructor(
33
38
  args: string[],
34
39
  outputOpts?: OutputOptionsConstructorArg,
@@ -49,8 +54,6 @@ class ContensisDev extends ContensisRole {
49
54
  const contensis = await this.ConnectContensis();
50
55
 
51
56
  if (contensis) {
52
- this.devinit = { ...this.devinit, invokedBy: this.invokedBy };
53
-
54
57
  // First we need to get the block id from the user
55
58
  const validateBlockId = (blockId: string) => {
56
59
  const pattern = /^[0-9a-z](-?[0-9a-z])*$/;
@@ -64,6 +67,7 @@ class ContensisDev extends ContensisRole {
64
67
  prefix: '🧱',
65
68
  message: messages.devinit.blockIdQuestion,
66
69
  validate: validateBlockId,
70
+ default: git.name,
67
71
  });
68
72
  // make sure block id is lowercase
69
73
  this.blockId = blockId.toLowerCase();
@@ -93,65 +97,17 @@ class ContensisDev extends ContensisRole {
93
97
  const devKeyDescription = `Created by Contensis to allow API access from the running block`;
94
98
  let existingDevKey = apiKeyExists(devKeyName);
95
99
 
96
- // if dev api key doesn't exisit go and create it (we need this for local development, we will store these details in the .env file).
97
- if (!existingDevKey) {
98
- existingDevKey = await this.CreateOrUpdateApiKey(
99
- existingDevKey,
100
- devKeyName,
101
- devKeyDescription
102
- );
103
- log.success('Successfully created development key');
104
- }
105
-
106
100
  const deployKeyName = `${apiKeyName}-ci`;
107
101
  const deployKeyDescription = `Created by the Contensis CLI for use in continuous integration`;
108
102
 
109
103
  let existingDeployKey = apiKeyExists(deployKeyName);
110
104
 
111
- // if deploy api key doesn't exisit go and create it (we need this for yml file).
112
- if (!existingDeployKey) {
113
- existingDeployKey = await this.CreateOrUpdateApiKey(
114
- existingDeployKey,
115
- deployKeyName,
116
- deployKeyDescription
117
- );
118
- log.success('Successfully created deploy key');
119
- }
120
-
121
- // check we have the deply key so we can assign them to this values
122
- if (existingDeployKey) {
123
- // Add client id and secret to global 'this'
124
- this.devinit = {
125
- ...this.devinit,
126
- credentials: {
127
- clientId: existingDeployKey?.id,
128
- clientSecret: existingDeployKey?.sharedSecret,
129
- },
130
- };
131
- }
132
-
133
- // we need to credentials of the user so that we can create a auth service
134
- const credentials = await this.GetCredentials(this.devinit.invokedBy);
135
-
136
- // create new auth service using creds
137
- let classicToken: string | undefined | null;
138
- const auth = new ContensisAuthService({
139
- username: credentials?.current?.account,
140
- password: credentials?.current?.password,
141
- projectId: currentProject,
142
- rootUrl: `https://cms-${currentEnv}.cloud.contensis.com`,
143
- });
144
-
145
- // once we have auth service, we can go and fetch out classic token
146
- classicToken = await auth.ClassicToken();
147
-
148
105
  // const blockId = git.name;
149
106
  const errors = [] as AppError[];
150
107
 
151
108
  // Start render console output
152
109
  log.raw('');
153
110
  log.success(messages.devinit.intro());
154
- log.raw('');
155
111
  log.raw(
156
112
  log.infoText(
157
113
  messages.devinit.projectDetails(
@@ -193,7 +149,6 @@ class ContensisDev extends ContensisRole {
193
149
 
194
150
  log.raw(log.infoText(messages.devinit.ciDetails(ciFileName)));
195
151
 
196
- let mappedWorkflow;
197
152
  // Location for Client ID / Secret.
198
153
  const { loc } = await inquirer.prompt({
199
154
  name: 'loc',
@@ -213,9 +168,8 @@ class ContensisDev extends ContensisRole {
213
168
  ],
214
169
  });
215
170
 
171
+ log.raw('');
216
172
  log.help(messages.devinit.ciIntro(git, loc));
217
- // Update CI Workflow
218
- mappedWorkflow = await mapCIWorkflowContent(this, loc);
219
173
 
220
174
  if (!dryRun) {
221
175
  // Confirm prompt
@@ -233,7 +187,6 @@ class ContensisDev extends ContensisRole {
233
187
 
234
188
  // Fetching access token
235
189
  let accessToken: string | undefined = undefined;
236
- log.raw('');
237
190
 
238
191
  const spinner = createSpinner(messages.devinit.accessTokenFetch());
239
192
  spinner.start();
@@ -241,9 +194,9 @@ class ContensisDev extends ContensisRole {
241
194
  const token = await this.GetDeliveryApiKey();
242
195
 
243
196
  if (token) {
244
- spinner.success();
245
- this.log.success(messages.devinit.accessTokenSuccess(token));
246
197
  accessToken = token;
198
+ spinner.success({ text: messages.devinit.accessTokenSuccess(token) });
199
+ log.raw('');
247
200
  } else {
248
201
  spinner.error();
249
202
  this.log.error(messages.devinit.accessTokenFailed());
@@ -261,9 +214,48 @@ class ContensisDev extends ContensisRole {
261
214
  const [getRolesErr, roles] = await to(contensis.roles.GetRoles());
262
215
  if (!roles && getRolesErr) errors.push(getRolesErr);
263
216
  checkpoint(`fetched ${roles?.length} roles`);
217
+
264
218
  if (dryRun) {
265
219
  checkpoint(`skip api key creation (dry-run)`);
266
220
  } else {
221
+ // if dev api key doesn't exist go and create it (we need this for local development, we will store these details in the .env file).
222
+ const devKeyExisted = !!existingDevKey;
223
+ if (!existingDevKey) {
224
+ existingDevKey = await this.CreateOrUpdateApiKey(
225
+ existingDevKey,
226
+ devKeyName,
227
+ devKeyDescription
228
+ );
229
+ log.success(messages.devinit.createDevKey(devKeyName, devKeyExisted));
230
+ }
231
+ // NF 24/11/23 Added this commented code back in as we are not assigning the dev key to any role here
232
+ // // Ensure dev API key is assigned to a role
233
+ // let existingDevRole = findByIdOrName(roles || [], devKeyName, true) as
234
+ // | Role
235
+ // | undefined;
236
+ // existingDevRole = await this.CreateOrUpdateRole(
237
+ // existingDevRole,
238
+ // devKeyRole(devKeyName, devKeyDescription)
239
+ // );
240
+ // checkpoint('dev key role assigned');
241
+
242
+ // if deploy api key doesn't exist go and create it (we need this for yml file).
243
+ const deployKeyExisted = !!existingDeployKey;
244
+ if (!existingDeployKey) {
245
+ existingDeployKey = await this.CreateOrUpdateApiKey(
246
+ existingDeployKey,
247
+ deployKeyName,
248
+ deployKeyDescription
249
+ );
250
+ }
251
+
252
+ // check we have the deploy key so we can assign them to this values
253
+ if (existingDeployKey) {
254
+ // Add client id and secret to credentials
255
+ this.deployCredentials.clientId = existingDeployKey?.id;
256
+ this.deployCredentials.clientSecret = existingDeployKey?.sharedSecret;
257
+ }
258
+
267
259
  // Ensure deploy API key is assigned to a role with the right permissions
268
260
  const deployRoleName = `Role for CI push of block '${blockId}'`;
269
261
  const deplyRoleDescription = `Created by the Contensis CLI for use in continuous integration`;
@@ -274,11 +266,13 @@ class ContensisDev extends ContensisRole {
274
266
  ) as Role | undefined;
275
267
  existingDeployRole = await this.CreateOrUpdateRole(
276
268
  existingDeployRole,
277
- deployKeyRole(deployKeyName, deplyRoleDescription)
269
+ deployKeyRole(deployRoleName, deplyRoleDescription)
278
270
  );
279
271
 
280
272
  checkpoint('deploy key role assigned');
281
- log.success(messages.devinit.createDeployKey(deployRoleName, true));
273
+ log.success(
274
+ messages.devinit.createDeployKey(deployRoleName, deployKeyExisted)
275
+ );
282
276
  checkpoint('api keys done');
283
277
  }
284
278
 
@@ -339,7 +333,7 @@ class ContensisDev extends ContensisRole {
339
333
  }
340
334
  checkpoint('skip .env file update (dry-run)');
341
335
  } else {
342
- if (envDiff) log.info(`updating .env file ${winSlash(envFilePath)}`);
336
+ if (envDiff) log.info(`Updating .env file ${winSlash(envFilePath)}`);
343
337
  writeFile(envFilePath, envFileLines.join('\n'));
344
338
  checkpoint('.env file updated');
345
339
  log.success(messages.devinit.writeEnvFile());
@@ -347,16 +341,21 @@ class ContensisDev extends ContensisRole {
347
341
  }
348
342
 
349
343
  // Update git ignore
350
- const gitIgnorePath = `${projectHome}/.gitignore`;
351
- const gitIgnoreContentsToAdd = ['.env'];
352
- mergeContentsToAddWithGitignore(gitIgnorePath, gitIgnoreContentsToAdd);
344
+ if (dryRun) {
345
+ checkpoint('skip .gitignore file update (dry-run)');
346
+ } else {
347
+ mergeContentsToAddWithGitignore(`${projectHome}/.gitignore`, ['.env']);
348
+ log.raw('');
349
+ }
350
+
351
+ // Update CI Workflow
352
+ const mappedWorkflow = await mapCIWorkflowContent(this, loc);
353
353
 
354
354
  // Update CI file -- different for GH/GL
355
355
  if (mappedWorkflow?.diff) {
356
356
  log.info(
357
357
  `Updating ${winSlash(ciFileName)} file:\n${mappedWorkflow.diff}`
358
358
  );
359
- log.raw('');
360
359
  }
361
360
  if (dryRun) {
362
361
  checkpoint('skip CI file update (dry-run)');
@@ -372,18 +371,20 @@ class ContensisDev extends ContensisRole {
372
371
  } else {
373
372
  log.info(messages.devinit.ciFileNoChanges(`./${ciFileName}`));
374
373
  }
374
+ log.raw('');
375
375
  checkpoint('CI file updated');
376
376
  }
377
377
  }
378
378
 
379
379
  if (loc === 'git') {
380
380
  // Echo Deployment API key to console, ask user to add secrets to repo
381
+ const dryRunKeyMessage = dryRun ? 'not created in dry-run' : undefined;
381
382
  log.warning(messages.devinit.addGitSecretsIntro());
382
383
  log.help(
383
384
  messages.devinit.addGitSecretsHelp(
384
385
  git,
385
- existingDeployKey?.id,
386
- existingDeployKey?.sharedSecret
386
+ existingDeployKey?.id || dryRunKeyMessage,
387
+ existingDeployKey?.sharedSecret || dryRunKeyMessage
387
388
  )
388
389
  );
389
390
  }
@@ -395,10 +396,13 @@ class ContensisDev extends ContensisRole {
395
396
  log.success(messages.devinit.success());
396
397
  log.help(messages.devinit.startProjectTip());
397
398
  // open the cms link -- if no classic token just return the cms url
399
+
400
+ // go and fetch the classic token from auth service
401
+ const classicToken = await this.auth?.ClassicToken();
398
402
  log.help(
399
403
  ansiEscapes.link(
400
404
  `Open Contensis`,
401
- `https://cms-${currentEnv}.cloud.contensis.com${
405
+ `${this.urls?.cms}${
402
406
  classicToken ? `?SecurityToken=${classicToken}` : ''
403
407
  }`
404
408
  )
package/src/shell.ts CHANGED
@@ -143,6 +143,7 @@ class ContensisShell {
143
143
  'execute block action makelive',
144
144
  'execute block action rollback',
145
145
  'execute block action markasbroken',
146
+ 'get assets',
146
147
  'get block',
147
148
  'get block logs',
148
149
  'get contenttype',
@@ -155,10 +156,12 @@ class ContensisShell {
155
156
  'get token',
156
157
  'get version',
157
158
  'get webhook',
159
+ 'get workflow',
158
160
  'import contenttypes',
159
161
  'import components',
160
162
  'import entries',
161
163
  'import models',
164
+ 'import nodes',
162
165
  'list blocks',
163
166
  'list contenttypes',
164
167
  'list components',
@@ -168,11 +171,13 @@ class ContensisShell {
168
171
  'list renderers',
169
172
  'list roles',
170
173
  'list webhooks',
174
+ 'list workflows',
171
175
  'push block',
172
176
  'remove components',
173
177
  'remove contenttypes',
174
178
  'remove key',
175
179
  'remove entries',
180
+ 'remove nodes',
176
181
  'remove role',
177
182
  'set project name',
178
183
  'set project description',
@@ -1,7 +1,17 @@
1
+ import { Node } from 'contensis-delivery-api/lib/models';
1
2
  import dayjs from 'dayjs';
2
- import { BlockVersion, MigrateModelsResult, MigrateStatus } from 'migratortron';
3
+ import { deconstructApiError } from './error';
4
+ import { Logger, addNewLines } from './logger';
5
+ import {
6
+ BlockVersion,
7
+ EntriesResult,
8
+ MigrateModelsResult,
9
+ MigrateNodesTree,
10
+ MigrateStatus,
11
+ NodesResult,
12
+ ProjectNodesToMigrate,
13
+ } from 'migratortron';
3
14
  import ContensisCli from '~/services/ContensisCliService';
4
- import { Logger } from './logger';
5
15
 
6
16
  const formatDate = (date: Date | string, format = 'DD/MM/YYYY HH:mm') =>
7
17
  dayjs(date).format(format);
@@ -104,19 +114,19 @@ export const printBlockVersion = (
104
114
  console.log('');
105
115
  };
106
116
 
107
- export const printMigrateResult = (
117
+ export const printEntriesMigrateResult = (
108
118
  { log, messages, currentProject }: ContensisCli,
109
- migrateResult: any,
119
+ migrateResult: EntriesResult,
110
120
  {
111
121
  action = 'import',
112
122
  showDiff = false,
113
- showAllEntries = false,
114
- showChangedEntries = false,
123
+ showAll = false,
124
+ showChanged = false,
115
125
  }: {
116
126
  action?: 'import' | 'delete';
117
127
  showDiff?: boolean;
118
- showAllEntries?: boolean;
119
- showChangedEntries?: boolean;
128
+ showAll?: boolean;
129
+ showChanged?: boolean;
120
130
  } = {}
121
131
  ) => {
122
132
  console.log(``);
@@ -129,8 +139,8 @@ export const printMigrateResult = (
129
139
  any
130
140
  ][]) {
131
141
  if (
132
- showAllEntries ||
133
- (showChangedEntries &&
142
+ showAll ||
143
+ (showChanged &&
134
144
  (
135
145
  Object.entries(
136
146
  Object.entries(entryStatus[currentProject])[0]
@@ -173,7 +183,7 @@ export const printMigrateResult = (
173
183
  }
174
184
  }
175
185
  }
176
- if (showAllEntries || showChangedEntries) console.log(``);
186
+ if (showAll || showChanged) console.log(``);
177
187
 
178
188
  for (const [projectId, contentTypeCounts] of Object.entries(
179
189
  migrateResult.entries || {}
@@ -250,7 +260,98 @@ export const printMigrateResult = (
250
260
  ` - ${log.errorText(`errors: ${migrateResult.errors.length}`)}\n`
251
261
  );
252
262
  for (const error of migrateResult.errors)
253
- log.error(error.message || error, null, '');
263
+ log.error(error.message, null, '');
264
+ }
265
+ };
266
+
267
+ export const printNodesMigrateResult = (
268
+ { log, currentProject }: ContensisCli,
269
+ migrateResult: NodesResult,
270
+ {
271
+ action = 'import',
272
+ logLimit = 50,
273
+ showDiff = false,
274
+ showAll = false,
275
+ showChanged = false,
276
+ }: {
277
+ action?: 'import' | 'delete';
278
+ logLimit?: number;
279
+ showDiff?: boolean;
280
+ showAll?: boolean;
281
+ showChanged?: boolean;
282
+ } = {}
283
+ ) => {
284
+ log.raw(``);
285
+ for (const [projectId, counts] of Object.entries(migrateResult.nodes || {})) {
286
+ const importTitle =
287
+ action === 'delete'
288
+ ? `Delete from project ${log.warningText(currentProject)}`
289
+ : `Import ${
290
+ projectId && projectId !== 'null'
291
+ ? `from project ${log.highlightText(projectId)} `
292
+ : ''
293
+ }to ${log.boldText(log.warningText(currentProject))}`;
294
+ log.help(importTitle);
295
+
296
+ const migrateStatusAndCount = migrateResult.nodesToMigrate[
297
+ currentProject
298
+ ] as ProjectNodesToMigrate;
299
+
300
+ const existingCount =
301
+ migrateResult.existing?.[currentProject]?.totalCount || 0;
302
+
303
+ const totalCount = Object.keys(migrateResult.nodesToMigrate.nodeIds).length;
304
+ const existingPercent = counts.totalCount
305
+ ? ((existingCount / totalCount) * 100).toFixed(0)
306
+ : '0';
307
+
308
+ const noChangeCount = migrateStatusAndCount?.['no change'] || 0;
309
+
310
+ const changedPercentage = counts.totalCount
311
+ ? ((noChangeCount / totalCount) * 100).toFixed(0)
312
+ : '0';
313
+
314
+ const existingColor =
315
+ existingPercent === '0' || action === 'delete'
316
+ ? log.warningText
317
+ : log.infoText;
318
+
319
+ const changedColor =
320
+ changedPercentage === '100' ? log.successText : log.warningText;
321
+
322
+ console.log(
323
+ ` - ${log.highlightText(
324
+ `totalCount: ${migrateStatusAndCount.totalCount}`
325
+ )}${
326
+ changedPercentage === '100'
327
+ ? ''
328
+ : existingColor(` [existing: ${`${existingPercent}%`}]`)
329
+ }${
330
+ existingPercent === '0'
331
+ ? ''
332
+ : changedColor(
333
+ ` ${
334
+ changedPercentage === '100'
335
+ ? 'up to date'
336
+ : `[needs update: ${100 - Number(changedPercentage)}%]`
337
+ }`
338
+ )
339
+ }`
340
+ );
341
+ }
342
+ if (migrateResult.errors?.length) {
343
+ console.log(
344
+ ` - ${log.errorText(`errors: ${migrateResult.errors.length}`)}\n`
345
+ );
346
+
347
+ log.limits(
348
+ migrateResult.errors
349
+ .map(error => {
350
+ return log.errorText(deconstructApiError(error));
351
+ })
352
+ .join('\n'),
353
+ logLimit
354
+ );
254
355
  }
255
356
  };
256
357
 
@@ -363,3 +464,128 @@ export const printModelMigrationResult = (
363
464
  }
364
465
  }
365
466
  };
467
+
468
+ export const printNodeTreeOutput = (
469
+ { log, messages }: ContensisCli,
470
+ root: Node | MigrateNodesTree | undefined,
471
+ logDetail = 'errors',
472
+ logLimit = 1000
473
+ ) => {
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
+ );
487
+ log.info(
488
+ `Node properties: ${log.highlightText(
489
+ 'e'
490
+ )} = has entry; ${log.highlightText('c')} = canonical; ${log.highlightText(
491
+ 'm'
492
+ )} = include in menu`
493
+ );
494
+
495
+ log.line();
496
+
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('-')
525
+ }${
526
+ node.includeInMenu ? log.highlightText('m') : log.infoText('-')
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)}` : ''}${
538
+ node.childCount ? ` +${node.childCount}` : ``
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
+ };
576
+
577
+ const outputChildren = (node: Node | undefined, depth = 2) => {
578
+ let str = '';
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);
582
+ }
583
+ return str;
584
+ };
585
+
586
+ const children = outputChildren(root);
587
+ log.limits(
588
+ `${outputNode(root || {}, ' ', true)}${children ? `\n${children}` : ''}`,
589
+ logLimit
590
+ );
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
+ ));
package/src/util/git.ts CHANGED
@@ -75,7 +75,7 @@ export class GitHelper {
75
75
  }
76
76
  gitcwd = () => path.join(this.gitRepoPath);
77
77
  gitInfo = (url: string = this.originUrl) => hostedGitInfo.fromUrl(url);
78
- hostType = (url: string = this.originUrl): GitTypes => {
78
+ hostType = (url: string = this.originUrl): GitTypes | undefined => {
79
79
  if (url) {
80
80
  if (url.includes('github.com')) return 'github';
81
81
  else return 'gitlab';
@@ -87,6 +87,7 @@ export class GitHelper {
87
87
  gitConfig = (cwd = this.gitRepoPath) => {
88
88
  // Find .git/config in project cwd
89
89
  const config = parseGitConfig.sync({
90
+ cwd,
90
91
  path: '.git/config',
91
92
  expandKeys: true,
92
93
  });