contensis-cli 1.2.2-beta.9 → 1.3.0

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.
@@ -30,6 +30,14 @@ export const makeImportCommand = () => {
30
30
  .argument('[modelIds...]', 'ids of the content models to import (optional)')
31
31
  .addOption(noCache)
32
32
  .addOption(commit)
33
+ .option(
34
+ '-nod --no-defaults',
35
+ 'ignore any default entries or nodes attached to content types or fields'
36
+ )
37
+ .option(
38
+ '-preserve --preserve-guids',
39
+ 'import any default entries or nodes using the same id as the source'
40
+ )
33
41
  .addHelpText(
34
42
  'after',
35
43
  `
@@ -1,6 +1,6 @@
1
1
  import { Command } from 'commander';
2
2
  import { cliCommand } from '~/services/ContensisCliService';
3
- import { mapContensisOpts, noCache } from './globalOptions';
3
+ import { exportOption, mapContensisOpts, noCache } from './globalOptions';
4
4
 
5
5
  export const makeListCommand = () => {
6
6
  const list = new Command()
@@ -41,6 +41,7 @@ Example call:
41
41
  list
42
42
  .command('models')
43
43
  .description('print list of content models')
44
+ .addOption(exportOption)
44
45
  .addOption(noCache)
45
46
  .addHelpText(
46
47
  'after',
@@ -54,7 +55,7 @@ Example call:
54
55
  ['list', 'models'],
55
56
  opts,
56
57
  mapContensisOpts(opts)
57
- ).PrintContentModels();
58
+ ).PrintContentModels([], opts);
58
59
  });
59
60
 
60
61
  list
@@ -51,7 +51,7 @@ export const makePushCommand = () => {
51
51
  )
52
52
  .option(
53
53
  '-pr --provider <sourceProvider>',
54
- 'the url of the source repository for the supplied image uri'
54
+ 'the source repository provider of the supplied image uri'
55
55
  )
56
56
  .usage('<block-id> <image uri> [branch] [options]')
57
57
  .addHelpText(
@@ -4,6 +4,7 @@ import fs from 'fs';
4
4
  import inquirer from 'inquirer';
5
5
  import fetch from 'node-fetch';
6
6
  import path from 'path';
7
+ import clone from 'rfdc';
7
8
 
8
9
  import { Component, ContentType, Project } from 'contensis-core-api';
9
10
  import { Role } from 'contensis-management-api/lib/models';
@@ -1178,7 +1179,7 @@ class ContensisCli {
1178
1179
 
1179
1180
  PrintContentModels = async (
1180
1181
  modelIds: string[] = [],
1181
- printRequiredBy?: boolean
1182
+ opts: { export?: boolean; requiredBy?: boolean }
1182
1183
  ) => {
1183
1184
  const { currentProject, log, messages } = this;
1184
1185
  const contensis = await this.ConnectContensis();
@@ -1194,93 +1195,112 @@ class ContensisCli {
1194
1195
  modelIds.some(id => id.toLowerCase() === m.id.toLowerCase())
1195
1196
  )
1196
1197
  : undefined;
1198
+ const exportResources: (ContentType | Component)[] = [];
1199
+
1200
+ if (opts.export) {
1201
+ // Generate a list of contentTypeIds and componentIds from all models
1202
+ // and dependencies
1203
+ const contentTypeIds = Array.from(
1204
+ new Set([
1205
+ ...(returnModels || models || []).map(m => m.id),
1206
+ ...(returnModels || models || [])
1207
+ .map(m => m.dependencies?.contentTypes?.map(c => c[0]) || [])
1208
+ .flat(),
1209
+ ])
1210
+ );
1211
+ const componentIds = Array.from(
1212
+ new Set(
1213
+ (returnModels || models || [])
1214
+ .map(m => m.dependencies?.components?.map(c => c[0]) || [])
1215
+ .flat()
1216
+ )
1217
+ );
1197
1218
 
1198
- // Generate a list of contentTypeIds and componentIds from all models
1199
- // and dependencies
1200
- const contentTypeIds = Array.from(
1201
- new Set([
1202
- ...(returnModels || models || []).map(m => m.id),
1203
- ...(returnModels || models || [])
1204
- .map(m => m.dependencies?.contentTypes?.map(c => c[0]) || [])
1205
- .flat(),
1206
- ])
1207
- );
1208
- const componentIds = Array.from(
1209
- new Set(
1210
- (returnModels || models || [])
1211
- .map(m => m.dependencies?.components?.map(c => c[0]) || [])
1212
- .flat()
1213
- )
1214
- );
1215
-
1216
- // Create an array of all the content types and component definitions
1217
- // we will use this when outputting to a file
1218
- const contentModelBackup = [
1219
- ...contentTypes.filter(c =>
1220
- contentTypeIds.map(i => i.toLowerCase()).includes(c.id.toLowerCase())
1221
- ),
1222
- ...components.filter(c =>
1223
- componentIds.map(i => i.toLowerCase()).includes(c.id.toLowerCase())
1224
- ),
1225
- ];
1219
+ // Create an array of all the content types and component definitions
1220
+ // we will use this when outputting to a file
1221
+ exportResources.push(
1222
+ ...contentTypes.filter(c =>
1223
+ contentTypeIds
1224
+ .map(i => i.toLowerCase())
1225
+ .includes(c.id.toLowerCase())
1226
+ ),
1227
+ ...components.filter(c =>
1228
+ componentIds.map(i => i.toLowerCase()).includes(c.id.toLowerCase())
1229
+ )
1230
+ );
1231
+ }
1226
1232
 
1227
1233
  if (Array.isArray(returnModels)) {
1228
1234
  log.success(messages.models.list(currentProject));
1229
- await this.HandleFormattingAndOutput(contentModelBackup, () => {
1230
- // print the content models to console
1231
- for (const model of returnModels) {
1232
- if (!printRequiredBy) {
1233
- // truncate parts of the output
1234
- delete model.dependencyOf;
1235
- if (model.dependencies?.contentTypes)
1236
- model.dependencies.contentTypes.forEach(id => (id[1] = []));
1237
- if (model.dependencies?.components)
1238
- model.dependencies.components.forEach(id => (id[1] = []));
1239
- }
1235
+ await this.HandleFormattingAndOutput(
1236
+ opts.export ? exportResources : returnModels,
1237
+ () => {
1238
+ // print the content models to console
1239
+ for (const model of returnModels) {
1240
+ // create a clone of each model to safely modify
1241
+ const draft = clone()(model);
1242
+ if (!opts.requiredBy) {
1243
+ // truncate parts of the output
1244
+ delete draft.dependencyOf;
1245
+ if (draft.dependencies?.contentTypes)
1246
+ draft.dependencies.contentTypes.forEach(id => id.pop());
1247
+ if (draft.dependencies?.components)
1248
+ draft.dependencies.components.forEach(id => id.pop());
1249
+ }
1240
1250
 
1251
+ log.raw('');
1252
+ log.object(draft);
1253
+ }
1241
1254
  log.raw('');
1242
- log.object(model);
1243
1255
  }
1244
- log.raw('');
1245
- });
1256
+ );
1246
1257
  } else {
1247
1258
  log.success(
1248
1259
  messages.models.get(currentProject, models?.length.toString() || '0')
1249
1260
  );
1250
1261
  log.raw('');
1251
1262
  if (models?.length) {
1252
- await this.HandleFormattingAndOutput(contentModelBackup, () => {
1253
- // print the content models to console
1254
- for (const model of models) {
1255
- const components = model.components?.length || 0;
1256
- const contentTypes = model.contentTypes?.length || 0;
1257
- const dependencies =
1258
- (model.dependencies?.components?.length || 0) +
1259
- (model.dependencies?.contentTypes?.length || 0);
1260
- const dependencyOf =
1261
- (model.dependencyOf?.components?.length || 0) +
1262
- (model.dependencyOf?.contentTypes?.length || 0);
1263
-
1264
- const hasAny =
1265
- components + contentTypes + dependencies + dependencyOf;
1266
- log.raw(
1267
- ` - ${log.highlightText(log.boldText(model.id))} ${
1268
- hasAny
1269
- ? log.infoText(
1270
- `{ ${components ? `components: ${components}, ` : ''}${
1271
- contentTypes ? `contentTypes: ${contentTypes}, ` : ''
1272
- }${
1273
- dependencies ? `references: ${dependencies}, ` : ''
1274
- }${
1275
- dependencyOf ? `required by: ${dependencyOf}` : ''
1276
- } }`
1277
- )
1278
- : ''
1279
- }`
1280
- );
1263
+ await this.HandleFormattingAndOutput(
1264
+ opts.export ? exportResources : models,
1265
+ () => {
1266
+ // print the content models to console
1267
+ for (const model of models) {
1268
+ const components = model.components?.length || 0;
1269
+ const contentTypes = model.contentTypes?.length || 0;
1270
+ const defaults =
1271
+ (model.defaults?.length || 0) + (model.nodes?.length || 0);
1272
+ const dependencies =
1273
+ (model.dependencies?.components?.length || 0) +
1274
+ (model.dependencies?.contentTypes?.length || 0);
1275
+ const dependencyOf =
1276
+ (model.dependencyOf?.components?.length || 0) +
1277
+ (model.dependencyOf?.contentTypes?.length || 0);
1278
+
1279
+ const hasAny =
1280
+ components + contentTypes + dependencies + dependencyOf;
1281
+ log.raw(
1282
+ ` - ${log.highlightText(log.boldText(model.id))} ${
1283
+ hasAny
1284
+ ? log.infoText(
1285
+ `{ ${
1286
+ components ? `components: ${components}, ` : ''
1287
+ }${
1288
+ contentTypes
1289
+ ? `contentTypes: ${contentTypes}, `
1290
+ : ''
1291
+ }${defaults ? `defaults: ${defaults}, ` : ''}${
1292
+ dependencies ? `references: ${dependencies}, ` : ''
1293
+ }${
1294
+ dependencyOf ? `required by: ${dependencyOf}` : ''
1295
+ } }`
1296
+ )
1297
+ : ''
1298
+ }`
1299
+ );
1300
+ }
1301
+ log.raw('');
1281
1302
  }
1282
- log.raw('');
1283
- });
1303
+ );
1284
1304
  }
1285
1305
  }
1286
1306
  }
@@ -1321,7 +1341,7 @@ class ContensisCli {
1321
1341
  else
1322
1342
  await this.HandleFormattingAndOutput(result, () => {
1323
1343
  // print the results to console
1324
- if (!commit) {
1344
+ if (!result.committed) {
1325
1345
  log.raw(log.boldText(`\nContent types:`));
1326
1346
  if (!result.contentTypes) log.info(`- None returned\n`);
1327
1347
  else printModelMigrationAnalysis(this, result.contentTypes);
@@ -1329,19 +1349,60 @@ class ContensisCli {
1329
1349
  log.raw(log.boldText(`\nComponents:`));
1330
1350
  if (!result.components) log.info(`- None returned\n`);
1331
1351
  else printModelMigrationAnalysis(this, result.components);
1352
+
1353
+ if (Object.keys(result.defaults).length) {
1354
+ log.raw(log.boldText(`\nDefaults:`));
1355
+ printModelMigrationAnalysis(this, result.defaults);
1356
+ }
1357
+ if (Object.keys(result.nodes).length) {
1358
+ log.raw(log.boldText(`\nNodes:`));
1359
+ printModelMigrationAnalysis(this, result.nodes);
1360
+ }
1361
+ if (result.errors) {
1362
+ log.raw(log.boldText(`\nErrors:`));
1363
+ log.object(result.errors);
1364
+ }
1332
1365
  } else {
1333
- const migrateResult = result as MigrateModelsResult;
1366
+ const { modelsResult = {} } = result;
1334
1367
  log.raw(log.boldText(`\nContent types:`));
1335
1368
  printModelMigrationResult(
1336
1369
  this,
1337
- migrateResult[currentProject].contentTypes
1338
- );
1339
-
1340
- log.raw(log.boldText(`\nComponents:`));
1341
- printModelMigrationResult(
1342
- this,
1343
- migrateResult[currentProject].components
1370
+ modelsResult[currentProject].contentTypes
1344
1371
  );
1372
+ // Only output for components if any status has any results
1373
+ if (
1374
+ Object.values(modelsResult[currentProject].components).some(
1375
+ r => r.length > 0
1376
+ )
1377
+ ) {
1378
+ log.raw(log.boldText(`\nComponents:`));
1379
+ printModelMigrationResult(
1380
+ this,
1381
+ modelsResult[currentProject].components
1382
+ );
1383
+ }
1384
+ if (
1385
+ Object.values(modelsResult[currentProject].defaults).some(
1386
+ r => r.length > 0
1387
+ )
1388
+ ) {
1389
+ log.raw(log.boldText(`\nDefaults:`));
1390
+ printModelMigrationResult(
1391
+ this,
1392
+ modelsResult[currentProject].defaults
1393
+ );
1394
+ }
1395
+ if (
1396
+ Object.values(modelsResult[currentProject].nodes).some(
1397
+ r => r.length > 0
1398
+ )
1399
+ ) {
1400
+ log.raw(log.boldText(`\nNodes:`));
1401
+ printModelMigrationResult(
1402
+ this,
1403
+ modelsResult[currentProject].nodes
1404
+ );
1405
+ }
1345
1406
  }
1346
1407
  });
1347
1408
  } else {
@@ -1529,14 +1590,15 @@ class ContensisCli {
1529
1590
  `"${result.query.modelIds?.join(', ')}"`
1530
1591
  )}\n`
1531
1592
  );
1593
+ if (result.committed === false) {
1594
+ log.raw(log.boldText(`Content types:`));
1595
+ if (!result.contentTypes) log.info(`- None returned\n`);
1596
+ else printModelMigrationAnalysis(this, result.contentTypes);
1532
1597
 
1533
- log.raw(log.boldText(`Content types:`));
1534
- if (!result.contentTypes) log.info(`- None returned\n`);
1535
- else printModelMigrationAnalysis(this, result.contentTypes);
1536
-
1537
- log.raw(log.boldText(`Components:`));
1538
- if (!result.components) log.info(`- None returned\n`);
1539
- else printModelMigrationAnalysis(this, result.components);
1598
+ log.raw(log.boldText(`\nComponents:`));
1599
+ if (!result.components) log.info(`- None returned\n`);
1600
+ else printModelMigrationAnalysis(this, result.components);
1601
+ }
1540
1602
  });
1541
1603
  }
1542
1604
  };
@@ -1727,13 +1789,19 @@ class ContensisCli {
1727
1789
  withDependents = false,
1728
1790
  }: {
1729
1791
  withDependents?: boolean;
1730
- }) => {
1792
+ } = {}) => {
1731
1793
  const { currentProject, log, messages } = this;
1732
1794
  const contensis = await this.ConnectContensis();
1733
1795
 
1734
1796
  if (contensis) {
1735
1797
  log.line();
1736
1798
  const entries = await contensis.GetEntries({ withDependents });
1799
+ // TODO: iterate entries and add some extra details to help
1800
+ // with importing later
1801
+ // Add a full sys.uri to asset entries
1802
+ // Add sys.metadata.exportCms
1803
+ // Add sys.metadata.exportProjectId
1804
+
1737
1805
  await this.HandleFormattingAndOutput(entries, () =>
1738
1806
  // print the entries to console
1739
1807
  logEntitiesTable({
@@ -1779,11 +1847,10 @@ class ContensisCli {
1779
1847
 
1780
1848
  if (err) logError(err);
1781
1849
  else {
1782
- const { migrateEntries, nodes } =
1783
- contensis.content.targets[currentProject];
1850
+ const { entries, nodes } = contensis.content.targets[currentProject];
1784
1851
 
1785
1852
  const output = saveEntries
1786
- ? migrateEntries?.map(me => me.finalEntry)
1853
+ ? entries.migrate?.map(me => me.toJSON())
1787
1854
  : result;
1788
1855
  await this.HandleFormattingAndOutput(output, () => {
1789
1856
  // print the migrateResult to console
@@ -1875,8 +1942,8 @@ class ContensisCli {
1875
1942
  if (err) logError(err);
1876
1943
  if (result) {
1877
1944
  const output = saveEntries
1878
- ? contensis.content.copy.targets[currentProject].migrateEntries?.map(
1879
- me => me.finalEntry
1945
+ ? contensis.content.copy.targets[currentProject].entries.migrate?.map(
1946
+ me => me.toJSON()
1880
1947
  )
1881
1948
  : result;
1882
1949
  await this.HandleFormattingAndOutput(output, () => {
package/src/shell.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import figlet from 'figlet';
2
2
  import inquirer from 'inquirer';
3
3
  import inquirerPrompt from 'inquirer-command-prompt';
4
+ import { split } from 'split-cmd';
4
5
  import commands from './commands';
5
6
  import { LogMessages } from './localisation/en-GB';
6
7
  import CredentialProvider from './providers/CredentialProvider';
@@ -222,9 +223,10 @@ class ContensisShell {
222
223
  if (answers.cmd) {
223
224
  const program = commands();
224
225
  await program.parseAsync(
225
- answers.cmd
226
- .match(/"[^"]+"|[^\s]+/g)
227
- ?.map(e => e.replace(/"(.+)"/, '$1')),
226
+ split(answers.cmd).map(e => e.replace(/\\"/g, '"')),
227
+ // answers.cmd
228
+ // .match(/"[^"]+"|[^\s]+/g)
229
+ // ?.map(e => e.replace(/"(.+)"/, '$1')),
228
230
  {
229
231
  from: 'user',
230
232
  }
@@ -393,7 +393,11 @@ export const printModelMigrationAnalysis = (
393
393
  string,
394
394
  any
395
395
  ][]) {
396
- let mainOutput = log.standardText(` - ${contentTypeId}`);
396
+ let mainOutput = log.standardText(
397
+ ` - ${contentTypeId}${
398
+ model.contentTypeId ? ` ${log.helpText(model.contentTypeId)}` : ''
399
+ }`
400
+ );
397
401
  let extraOutput = '';
398
402
  let errorOutput = '';
399
403
  let diffOutput = '';
@@ -416,12 +420,14 @@ export const printModelMigrationAnalysis = (
416
420
  mainOutput += log.infoText(
417
421
  ` [${messages.migrate.status(projectDetails.status)(
418
422
  `${projectId}: ${projectDetails.status}`
419
- )}] v${projectDetails.versionNo}`
423
+ )}]${
424
+ projectDetails.versionNo ? ` v${projectDetails.versionNo}` : ''
425
+ }`
420
426
  );
421
427
  if (projectDetails.diff)
422
428
  diffOutput += ` ${log.highlightText(`diff:`)} ${log.infoText(
423
429
  highlightDiffText(projectDetails.diff)
424
- )}\n`;
430
+ )}`;
425
431
  if (projectDetails.error)
426
432
  errorOutput += ` ${log.highlightText(
427
433
  `error::`
@@ -140,6 +140,14 @@ export class Logger {
140
140
  ' | '
141
141
  )}`
142
142
  : ''
143
+ }${
144
+ field.dataFormat === 'contenttype'
145
+ ? `[${field.validations?.allowedDataFormats.dataFormats.join(
146
+ ' | '
147
+ )}], ${(
148
+ field.validations?.allowedIds?.ids || ['*']
149
+ ).join(' | ')}`
150
+ : ''
143
151
  }>`
144
152
  : ''
145
153
  }${
@@ -195,11 +203,22 @@ export class Logger {
195
203
  if (item.length)
196
204
  Logger.raw(chalk.grey(`${indent} [${item.join(', ')}]`));
197
205
  else Logger.objectRecurse(item, depth + 1, `${indent} `);
206
+ else
207
+ Array.isArray(item)
208
+ ? Logger.raw(
209
+ `${indent}${chalk.grey(`[`)}${item.join(', ')}${chalk.grey(
210
+ `]`
211
+ )}`
212
+ )
213
+ : typeof item === 'object' && item
214
+ ? Logger.objectRecurse(item, depth + 1, `${indent} `)
215
+ : Logger.raw(`${indent}${item}`);
198
216
  } else Logger.raw(`${indent}${item}`);
199
217
  }
200
218
  } else {
201
219
  let pos = 0;
202
220
  for (const [key, value] of Object.entries(content)) {
221
+ if (key === 'stack') continue; // skip stack output for errors
203
222
  const thisIndent =
204
223
  pos === 0 ? `${indent.substring(0, indent.length - 2)}- ` : indent;
205
224
  if (Array.isArray(value)) {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const LIB_VERSION = "1.2.2-beta.9";
1
+ export const LIB_VERSION = "1.3.0";