contensis-cli 1.5.1-beta.5 → 1.5.1-beta.7

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.
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var util_exports = {};
30
30
  __export(util_exports, {
31
31
  Logging: () => Logging,
32
+ splitTagGroupsInModels: () => splitTagGroupsInModels,
32
33
  splitTagsAndGroups: () => splitTagsAndGroups,
33
34
  url: () => url
34
35
  });
@@ -70,9 +71,18 @@ const splitTagsAndGroups = (tagsAndGroups = [], tags = [], groups = []) => {
70
71
  }
71
72
  }
72
73
  };
74
+ const splitTagGroupsInModels = (mixedData = [], models = [], groups = []) => {
75
+ for (const item of mixedData) {
76
+ if ((0, import_lodash.isObject)(item) && "id" in item) {
77
+ if (!("dataFormat" in item)) groups.push(item);
78
+ else models.push(item);
79
+ }
80
+ }
81
+ };
73
82
  // Annotate the CommonJS export names for ESM import in node:
74
83
  0 && (module.exports = {
75
84
  Logging,
85
+ splitTagGroupsInModels,
76
86
  splitTagsAndGroups,
77
87
  url
78
88
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/util/index.ts"],
4
- "sourcesContent": ["import { ICreateTag, ICreateTagGroup } from 'contensis-management-api';\nimport mergeWith from 'lodash/mergeWith';\nimport { Logger } from './logger';\nimport { LogMessages as enGB } from '../localisation/en-GB.js';\nimport { isObject } from 'lodash';\n\nexport const url = (alias: string, project: string) => {\n const projectAndAlias =\n project && project.toLowerCase() !== 'website'\n ? `${project.toLowerCase()}-${alias}`\n : alias;\n return {\n api: `https://api-${alias}.cloud.contensis.com`,\n cms: `https://cms-${alias}.cloud.contensis.com`,\n liveWeb: `https://live-${projectAndAlias}.cloud.contensis.com`,\n previewWeb: `https://preview-${projectAndAlias}.cloud.contensis.com`,\n iisWeb: `https://iis-live-${projectAndAlias}.cloud.contensis.com`,\n iisPreviewWeb: `https://iis-preview-${projectAndAlias}.cloud.contensis.com`,\n };\n};\n\nexport const Logging = async (language = 'en-GB') => {\n const defaultMessages = enGB;\n // const { LogMessages: defaultMessages } = await import(\n // `../localisation/en-GB.js`\n // );\n const localisedMessages = defaultMessages;\n\n if (language === 'en-GB') {\n // Using a variable import e.g. `import(`../localisation/${language}.js`);`\n // does not play well with packaged executables\n // So we have to hard code the import for each language individually\n }\n return {\n messages: mergeWith(\n localisedMessages,\n defaultMessages,\n (v, s) => v || s\n ) as typeof defaultMessages,\n Log: Logger,\n };\n};\n\nexport const splitTagsAndGroups = (\n tagsAndGroups: unknown[] = [],\n tags: ICreateTag[] = [],\n groups: ICreateTagGroup[] = []\n) => {\n for (const item of tagsAndGroups) {\n if (isObject(item) && 'id' in item) {\n if ('name' in item) groups.push(item as ICreateTagGroup);\n else tags.push(item as ICreateTag);\n }\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAsB;AACtB,oBAAuB;AACvB,mBAAoC;AACpC,oBAAyB;AAElB,MAAM,MAAM,CAAC,OAAe,YAAoB;AACrD,QAAM,kBACJ,WAAW,QAAQ,YAAY,MAAM,YACjC,GAAG,QAAQ,YAAY,CAAC,IAAI,KAAK,KACjC;AACN,SAAO;AAAA,IACL,KAAK,eAAe,KAAK;AAAA,IACzB,KAAK,eAAe,KAAK;AAAA,IACzB,SAAS,gBAAgB,eAAe;AAAA,IACxC,YAAY,mBAAmB,eAAe;AAAA,IAC9C,QAAQ,oBAAoB,eAAe;AAAA,IAC3C,eAAe,uBAAuB,eAAe;AAAA,EACvD;AACF;AAEO,MAAM,UAAU,OAAO,WAAW,YAAY;AACnD,QAAM,kBAAkB,aAAAA;AAIxB,QAAM,oBAAoB;AAE1B,MAAI,aAAa,SAAS;AAAA,EAI1B;AACA,SAAO;AAAA,IACL,cAAU,iBAAAC;AAAA,MACR;AAAA,MACA;AAAA,MACA,CAAC,GAAG,MAAM,KAAK;AAAA,IACjB;AAAA,IACA,KAAK;AAAA,EACP;AACF;AAEO,MAAM,qBAAqB,CAChC,gBAA2B,CAAC,GAC5B,OAAqB,CAAC,GACtB,SAA4B,CAAC,MAC1B;AACH,aAAW,QAAQ,eAAe;AAChC,YAAI,wBAAS,IAAI,KAAK,QAAQ,MAAM;AAClC,UAAI,UAAU,KAAM,QAAO,KAAK,IAAuB;AAAA,UAClD,MAAK,KAAK,IAAkB;AAAA,IACnC;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { ContentType, Component } from 'contensis-core-api';\nimport { ICreateTag, ICreateTagGroup } from 'contensis-management-api';\nimport mergeWith from 'lodash/mergeWith';\nimport { Logger } from './logger';\nimport { LogMessages as enGB } from '../localisation/en-GB.js';\nimport { isObject } from 'lodash';\n\nexport const url = (alias: string, project: string) => {\n const projectAndAlias =\n project && project.toLowerCase() !== 'website'\n ? `${project.toLowerCase()}-${alias}`\n : alias;\n return {\n api: `https://api-${alias}.cloud.contensis.com`,\n cms: `https://cms-${alias}.cloud.contensis.com`,\n liveWeb: `https://live-${projectAndAlias}.cloud.contensis.com`,\n previewWeb: `https://preview-${projectAndAlias}.cloud.contensis.com`,\n iisWeb: `https://iis-live-${projectAndAlias}.cloud.contensis.com`,\n iisPreviewWeb: `https://iis-preview-${projectAndAlias}.cloud.contensis.com`,\n };\n};\n\nexport const Logging = async (language = 'en-GB') => {\n const defaultMessages = enGB;\n // const { LogMessages: defaultMessages } = await import(\n // `../localisation/en-GB.js`\n // );\n const localisedMessages = defaultMessages;\n\n if (language === 'en-GB') {\n // Using a variable import e.g. `import(`../localisation/${language}.js`);`\n // does not play well with packaged executables\n // So we have to hard code the import for each language individually\n }\n return {\n messages: mergeWith(\n localisedMessages,\n defaultMessages,\n (v, s) => v || s\n ) as typeof defaultMessages,\n Log: Logger,\n };\n};\n\nexport const splitTagsAndGroups = (\n tagsAndGroups: unknown[] = [],\n tags: ICreateTag[] = [],\n groups: ICreateTagGroup[] = []\n) => {\n for (const item of tagsAndGroups) {\n if (isObject(item) && 'id' in item) {\n if ('name' in item) groups.push(item as ICreateTagGroup);\n else tags.push(item as ICreateTag);\n }\n }\n};\n\nexport const splitTagGroupsInModels = (\n mixedData: unknown[] = [],\n models: (ContentType | Component)[] = [],\n groups: ICreateTagGroup[] = []\n) => {\n for (const item of mixedData) {\n if (isObject(item) && 'id' in item) {\n if (!('dataFormat' in item)) groups.push(item as ICreateTagGroup);\n else models.push(item as ContentType | Component);\n }\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAAsB;AACtB,oBAAuB;AACvB,mBAAoC;AACpC,oBAAyB;AAElB,MAAM,MAAM,CAAC,OAAe,YAAoB;AACrD,QAAM,kBACJ,WAAW,QAAQ,YAAY,MAAM,YACjC,GAAG,QAAQ,YAAY,CAAC,IAAI,KAAK,KACjC;AACN,SAAO;AAAA,IACL,KAAK,eAAe,KAAK;AAAA,IACzB,KAAK,eAAe,KAAK;AAAA,IACzB,SAAS,gBAAgB,eAAe;AAAA,IACxC,YAAY,mBAAmB,eAAe;AAAA,IAC9C,QAAQ,oBAAoB,eAAe;AAAA,IAC3C,eAAe,uBAAuB,eAAe;AAAA,EACvD;AACF;AAEO,MAAM,UAAU,OAAO,WAAW,YAAY;AACnD,QAAM,kBAAkB,aAAAA;AAIxB,QAAM,oBAAoB;AAE1B,MAAI,aAAa,SAAS;AAAA,EAI1B;AACA,SAAO;AAAA,IACL,cAAU,iBAAAC;AAAA,MACR;AAAA,MACA;AAAA,MACA,CAAC,GAAG,MAAM,KAAK;AAAA,IACjB;AAAA,IACA,KAAK;AAAA,EACP;AACF;AAEO,MAAM,qBAAqB,CAChC,gBAA2B,CAAC,GAC5B,OAAqB,CAAC,GACtB,SAA4B,CAAC,MAC1B;AACH,aAAW,QAAQ,eAAe;AAChC,YAAI,wBAAS,IAAI,KAAK,QAAQ,MAAM;AAClC,UAAI,UAAU,KAAM,QAAO,KAAK,IAAuB;AAAA,UAClD,MAAK,KAAK,IAAkB;AAAA,IACnC;AAAA,EACF;AACF;AAEO,MAAM,yBAAyB,CACpC,YAAuB,CAAC,GACxB,SAAsC,CAAC,GACvC,SAA4B,CAAC,MAC1B;AACH,aAAW,QAAQ,WAAW;AAC5B,YAAI,wBAAS,IAAI,KAAK,QAAQ,MAAM;AAClC,UAAI,EAAE,gBAAgB,MAAO,QAAO,KAAK,IAAuB;AAAA,UAC3D,QAAO,KAAK,IAA+B;AAAA,IAClD;AAAA,EACF;AACF;",
6
6
  "names": ["enGB", "mergeWith"]
7
7
  }
package/dist/version.js CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  LIB_VERSION: () => LIB_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const LIB_VERSION = "1.5.1-beta.5";
24
+ const LIB_VERSION = "1.5.1-beta.7";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  LIB_VERSION
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["export const LIB_VERSION = \"1.5.1-beta.5\";\n"],
4
+ "sourcesContent": ["export const LIB_VERSION = \"1.5.1-beta.7\";\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contensis-cli",
3
- "version": "1.5.1-beta.5",
3
+ "version": "1.5.1-beta.7",
4
4
  "description": "A fully featured Contensis command line interface with a shell UI provides simple and intuitive ways to manage or profile your content in any NodeJS terminal.",
5
5
  "repository": "https://github.com/contensis/cli",
6
6
  "homepage": "https://github.com/contensis/cli/tree/main/packages/contensis-cli#readme",
@@ -39,7 +39,7 @@
39
39
  "inquirer-command-prompt": "^0.1.0",
40
40
  "keytar": "^7.9.0",
41
41
  "lodash": "^4.17.21",
42
- "migratortron": "^1.0.0-beta.77",
42
+ "migratortron": "^1.0.0-beta.78",
43
43
  "nanospinner": "^1.2.0",
44
44
  "node-fetch": "^2.6.7",
45
45
  "parse-git-config": "^3.0.0",
@@ -315,9 +315,16 @@ Example call:
315
315
  'get entries with the search phrase, use quotes for multiple words'
316
316
  )
317
317
  .addOption(contentTypes)
318
- .option(
319
- '-d --dependents',
320
- 'find and return any dependencies of all found entries'
318
+ .addOption(
319
+ new Option(
320
+ '-d --dependents [depth]',
321
+ 'find and return any dependencies of all found entries (optionally limit the number of dependency levels)'
322
+ ).argParser(value => {
323
+ // If value is undefined, treat as boolean true
324
+ if (value === undefined) return true;
325
+ const num = Number(value);
326
+ return isNaN(num) ? true : num;
327
+ })
321
328
  )
322
329
  )
323
330
  .addOption(
@@ -52,6 +52,12 @@ export const mapContensisOpts = (opts: any = {}): MigrateRequest => ({
52
52
  concurrency: opts.concurrency ? Number(opts.concurrency) : undefined,
53
53
  noPublish: !opts.publish, // arg is inverted automatically from `--no-publish` to `publish: false`
54
54
  outputLogs: opts.logLevel,
55
+ stopLevel:
56
+ typeof opts.stopLevel === 'number'
57
+ ? Number(opts.stopLevel)
58
+ : typeof opts.dependents === 'number'
59
+ ? Number(opts.dependents)
60
+ : undefined,
55
61
  });
56
62
 
57
63
  /* Output options */
@@ -195,6 +201,11 @@ export const noPublish = new Option(
195
201
  "don't publish created or updated entries"
196
202
  );
197
203
 
204
+ export const stopLevel = new Option(
205
+ '-d --stop-level <stopLevel>',
206
+ 'the level at which to stop resolving dependent entries (may result in incomplete entries)'
207
+ ).argParser(parseInt);
208
+
198
209
  export const addConnectOptions = (program: Command) =>
199
210
  program.addOption(alias.hideHelp()).addOption(project.hideHelp());
200
211
 
@@ -13,6 +13,7 @@ import {
13
13
  noPublish,
14
14
  outputDetail,
15
15
  saveEntries,
16
+ stopLevel,
16
17
  versionStatus,
17
18
  zenql,
18
19
  } from './globalOptions';
@@ -39,6 +40,7 @@ export const makeImportCommand = () => {
39
40
  '-preserve --preserve-guids',
40
41
  'import any default entries or nodes using the same id as the source'
41
42
  )
43
+ .addOption(ignoreErrors)
42
44
  .addHelpText(
43
45
  'after',
44
46
  `
@@ -131,6 +133,7 @@ Example call:
131
133
  .addOption(assetTypes)
132
134
  .addOption(latest)
133
135
  .addOption(versionStatus)
136
+ .addOption(stopLevel)
134
137
  .addOption(commit)
135
138
  .option(
136
139
  '-preserve --preserve-guids',
@@ -275,7 +278,7 @@ Example call:
275
278
  > import tags --from-file myImportData.json --preserve-guids
276
279
  `
277
280
  )
278
- .action(async (opts) => {
281
+ .action(async opts => {
279
282
  await cliCommand(
280
283
  ['import', 'tags'],
281
284
  opts,
@@ -246,6 +246,7 @@ export const LogMessages = {
246
246
  `[${env}] ${commit ? `Deleted` : `Will delete`} entries`,
247
247
  failedRemove: (env: string) => `[${env}] Unable to delete entries`,
248
248
  notFound: (env: string) => `[${env}] Entries were not found`,
249
+ noChange: (env: string) => `[${env}] No changes to be made`,
249
250
  },
250
251
  keys: {
251
252
  list: (env: string) => `[${env}] API keys:`,
@@ -396,6 +397,7 @@ export const LogMessages = {
396
397
  }`,
397
398
  failedRemove: (env: string, length: number) =>
398
399
  `[${env}] Unable to delete tags with ${pl('error', length)}`,
400
+ noChange: (env: string) => `[${env}] No changes to be made`,
399
401
  },
400
402
  blocks: {
401
403
  runningStatus: (status: BlockRunningStatus | 'broken') => {
@@ -38,7 +38,7 @@ import { readFileAsJSON } from '~/providers/file-provider';
38
38
  import SessionCacheProvider from '../providers/SessionCacheProvider';
39
39
  import CredentialProvider from '~/providers/CredentialProvider';
40
40
 
41
- import { splitTagsAndGroups, url } from '~/util';
41
+ import { splitTagGroupsInModels, splitTagsAndGroups, url } from '~/util';
42
42
  import { sanitiseIds } from '~/util/api-ids';
43
43
  import {
44
44
  isPassword,
@@ -167,8 +167,11 @@ class ContensisCli {
167
167
  }
168
168
 
169
169
  this.format = outputOpts?.format;
170
- this.output =
171
- outputOpts?.output && path.join(process.cwd(), outputOpts.output);
170
+ this.output = outputOpts?.output
171
+ ? path.isAbsolute(outputOpts.output)
172
+ ? outputOpts.output
173
+ : path.join(process.cwd(), outputOpts.output)
174
+ : undefined;
172
175
 
173
176
  const currentEnvironment = outputOpts?.alias || this.currentEnv;
174
177
  const environments = this.cache.environments || {};
@@ -1460,13 +1463,22 @@ class ContensisCli {
1460
1463
  log.help(messages.migrate.commitTip());
1461
1464
  }
1462
1465
  } else {
1463
- log.error(
1464
- messages.tags.failedCreate(
1465
- currentEnv,
1466
- data?.length === 1 ? data?.[0].label['en-GB'] : undefined
1467
- ),
1468
- err
1469
- );
1466
+ const noChanges =
1467
+ result?.tagsToMigrate?.[currentProject]?.['no change'] &&
1468
+ result.tagsToMigrate[currentProject].totalCount === 0 &&
1469
+ result.groupsToMigrate[currentProject].totalCount === 0;
1470
+
1471
+ if (noChanges && !err && !result.errors?.length) {
1472
+ log.help(messages.tags.noChange(currentEnv));
1473
+ } else {
1474
+ log.error(
1475
+ messages.tags.failedCreate(
1476
+ currentEnv,
1477
+ data?.length === 1 ? data?.[0].label['en-GB'] : undefined
1478
+ ),
1479
+ err
1480
+ );
1481
+ }
1470
1482
  }
1471
1483
  } else {
1472
1484
  log.warning(messages.models.noList(currentProject));
@@ -1681,6 +1693,7 @@ class ContensisCli {
1681
1693
  const models = await contensis.models.contentModels();
1682
1694
  const contentTypes = await contensis.models.contentTypes();
1683
1695
  const components = await contensis.models.components();
1696
+ const tagGroups = await contensis.models.tagGroups();
1684
1697
 
1685
1698
  // Models to output to console
1686
1699
  const returnModels = modelIds?.length
@@ -1688,11 +1701,11 @@ class ContensisCli {
1688
1701
  modelIds.some(id => id.toLowerCase() === m.id.toLowerCase())
1689
1702
  )
1690
1703
  : undefined;
1691
- const exportResources: (ContentType | Component)[] = [];
1704
+ const exportResources: (ContentType | Component | TagGroup)[] = [];
1692
1705
 
1693
1706
  if (opts.export) {
1694
- // Generate a list of contentTypeIds and componentIds from all models
1695
- // and dependencies
1707
+ // Generate a list of contentTypeIds, componentIds and tagGroupIds from all models
1708
+ // and their dependencies
1696
1709
  const contentTypeIds = Array.from(
1697
1710
  new Set([
1698
1711
  ...(returnModels || models || []).map(m => m.id),
@@ -1708,9 +1721,16 @@ class ContensisCli {
1708
1721
  .flat()
1709
1722
  )
1710
1723
  );
1724
+ const tagGroupIds = Array.from(
1725
+ new Set(
1726
+ (returnModels || models || [])
1727
+ .map(m => m.dependencies?.tagGroups?.map(g => g[0]) || [])
1728
+ .flat()
1729
+ )
1730
+ );
1711
1731
 
1712
- // Create an array of all the content types and component definitions
1713
- // we will use this when outputting to a file
1732
+ // Create an array of all the content types, component and tag group
1733
+ // definitions, we will use this when outputting to a file
1714
1734
  exportResources.push(
1715
1735
  ...contentTypes.filter(c =>
1716
1736
  contentTypeIds
@@ -1719,6 +1739,9 @@ class ContensisCli {
1719
1739
  ),
1720
1740
  ...components.filter(c =>
1721
1741
  componentIds.map(i => i.toLowerCase()).includes(c.id.toLowerCase())
1742
+ ),
1743
+ ...tagGroups.filter(g =>
1744
+ tagGroupIds.map(i => i.toLowerCase()).includes(g.id.toLowerCase())
1722
1745
  )
1723
1746
  );
1724
1747
  }
@@ -1760,17 +1783,23 @@ class ContensisCli {
1760
1783
  for (const model of models) {
1761
1784
  const components = model.components?.length || 0;
1762
1785
  const contentTypes = model.contentTypes?.length || 0;
1786
+ const tagGroups = model.tagGroups?.length || 0;
1763
1787
  const defaults =
1764
1788
  (model.defaults?.length || 0) + (model.nodes?.length || 0);
1765
1789
  const dependencies =
1766
1790
  (model.dependencies?.components?.length || 0) +
1767
- (model.dependencies?.contentTypes?.length || 0);
1791
+ (model.dependencies?.contentTypes?.length || 0) +
1792
+ (model.dependencies?.tagGroups?.length || 0);
1768
1793
  const dependencyOf =
1769
1794
  (model.dependencyOf?.components?.length || 0) +
1770
1795
  (model.dependencyOf?.contentTypes?.length || 0);
1771
1796
 
1772
1797
  const hasAny =
1773
- components + contentTypes + dependencies + dependencyOf;
1798
+ components +
1799
+ contentTypes +
1800
+ tagGroups +
1801
+ dependencies +
1802
+ dependencyOf;
1774
1803
  log.raw(
1775
1804
  ` - ${log.highlightText(log.boldText(model.id))} ${
1776
1805
  hasAny
@@ -1781,6 +1810,8 @@ class ContensisCli {
1781
1810
  contentTypes
1782
1811
  ? `contentTypes: ${contentTypes}, `
1783
1812
  : ''
1813
+ }${
1814
+ tagGroups ? `tagGroups: ${tagGroups}, ` : ''
1784
1815
  }${defaults ? `defaults: ${defaults}, ` : ''}${
1785
1816
  dependencies ? `references: ${dependencies}, ` : ''
1786
1817
  }${
@@ -1808,16 +1839,25 @@ class ContensisCli {
1808
1839
  }) => {
1809
1840
  const { currentProject, log, messages } = this;
1810
1841
 
1811
- const fileData = fromFile
1812
- ? (await readFileAsJSON<(ContentType | Component)[]>(fromFile)) || []
1813
- : [];
1814
- if (typeof fileData === 'string')
1815
- throw new Error(`Import file format must be of type JSON`);
1842
+ const mixedData: {
1843
+ models: (ContentType | Component)[];
1844
+ tagGroups: ICreateTagGroup[];
1845
+ } = { models: [], tagGroups: [] };
1846
+
1847
+ if (fromFile) {
1848
+ // File may contain mix of content types, components and tag groups, separate those here
1849
+ const fileData = fromFile ? (await readFileAsJSON(fromFile)) || [] : [];
1850
+ splitTagGroupsInModels(fileData, mixedData.models, mixedData.tagGroups);
1851
+ }
1852
+ // const fileData = fromFile
1853
+ // ? (await readFileAsJSON<(ContentType | Component | TagGroup)[]>(fromFile)) || []
1854
+ // : [];
1855
+ // if (typeof fileData === 'string')
1856
+ // throw new Error(`Import file format must be of type JSON`);
1816
1857
 
1817
1858
  const contensis = await this.ConnectContensisImport({
1818
1859
  commit,
1819
- fromFile,
1820
- importDataType: 'models',
1860
+ mixedData: mixedData.models.length ? mixedData : undefined,
1821
1861
  });
1822
1862
 
1823
1863
  if (contensis) {
@@ -1843,6 +1883,10 @@ class ContensisCli {
1843
1883
  if (!result.components) log.info(`- None returned\n`);
1844
1884
  else printModelMigrationAnalysis(this, result.components);
1845
1885
 
1886
+ if (result.tagGroups && Object.keys(result.tagGroups).length) {
1887
+ log.raw(log.boldText(`\nTag Groups:`));
1888
+ printModelMigrationAnalysis(this, result.tagGroups);
1889
+ }
1846
1890
  if (result.defaults && Object.keys(result.defaults).length) {
1847
1891
  log.raw(log.boldText(`\nDefaults:`));
1848
1892
  printModelMigrationAnalysis(this, result.defaults);
@@ -1874,6 +1918,17 @@ class ContensisCli {
1874
1918
  modelsResult[currentProject].components
1875
1919
  );
1876
1920
  }
1921
+ if (
1922
+ Object.values(modelsResult[currentProject].tagGroups || {}).some(
1923
+ r => r.length > 0
1924
+ )
1925
+ ) {
1926
+ log.raw(log.boldText(`\nTag Groups:`));
1927
+ printModelMigrationResult(
1928
+ this,
1929
+ modelsResult[currentProject].tagGroups
1930
+ );
1931
+ }
1877
1932
  if (
1878
1933
  Object.values(modelsResult[currentProject].defaults || {}).some(
1879
1934
  r => r.length > 0
@@ -1981,6 +2036,7 @@ class ContensisCli {
1981
2036
  );
1982
2037
  // print the results to console
1983
2038
  await this.HandleFormattingAndOutput(result, log.object);
2039
+ if (!commit) log.help(messages.migrate.commitTip());
1984
2040
  }
1985
2041
  }
1986
2042
  };
@@ -2042,6 +2098,7 @@ class ContensisCli {
2042
2098
  );
2043
2099
  await this.HandleFormattingAndOutput(result, log.object);
2044
2100
  }
2101
+ if (!commit) log.help(messages.migrate.commitTip());
2045
2102
  }
2046
2103
  };
2047
2104
 
@@ -2172,6 +2229,8 @@ class ContensisCli {
2172
2229
  );
2173
2230
  // print the results to console
2174
2231
  await this.HandleFormattingAndOutput(result, log.object);
2232
+
2233
+ if (!commit) log.help(messages.migrate.commitTip());
2175
2234
  }
2176
2235
  }
2177
2236
  };
@@ -2233,6 +2292,7 @@ class ContensisCli {
2233
2292
  );
2234
2293
  await this.HandleFormattingAndOutput(result, log.object);
2235
2294
  }
2295
+ if (!commit) log.help(messages.migrate.commitTip());
2236
2296
  }
2237
2297
  };
2238
2298
 
@@ -2409,9 +2469,24 @@ class ContensisCli {
2409
2469
  log.help(messages.migrate.commitTip());
2410
2470
  }
2411
2471
  } else {
2412
- log.error(messages.entries.failedImport(currentEnv), err);
2413
- if (!result?.entriesToMigrate?.[currentProject]?.totalCount)
2414
- log.help(messages.entries.notFound(currentEnv));
2472
+ const noChanges =
2473
+ Object.values(result?.entriesToMigrate?.[currentProject]).every(
2474
+ status =>
2475
+ typeof status === 'number' || (status['no change'] || 0) > 0
2476
+ ) && result.entriesToMigrate[currentProject].totalCount === 0;
2477
+
2478
+ if (
2479
+ noChanges &&
2480
+ !err &&
2481
+ !result?.migrateResult?.errors &&
2482
+ !result?.nodesResult?.errors
2483
+ ) {
2484
+ log.help(messages.entries.noChange(currentEnv));
2485
+ } else {
2486
+ log.error(messages.entries.failedImport(currentEnv), err);
2487
+ if (!result?.entriesToMigrate?.[currentProject]?.totalCount)
2488
+ log.help(messages.entries.notFound(currentEnv));
2489
+ }
2415
2490
  }
2416
2491
  } else {
2417
2492
  log.warning(messages.models.noList(currentProject));
package/src/util/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ContentType, Component } from 'contensis-core-api';
1
2
  import { ICreateTag, ICreateTagGroup } from 'contensis-management-api';
2
3
  import mergeWith from 'lodash/mergeWith';
3
4
  import { Logger } from './logger';
@@ -53,3 +54,16 @@ export const splitTagsAndGroups = (
53
54
  }
54
55
  }
55
56
  };
57
+
58
+ export const splitTagGroupsInModels = (
59
+ mixedData: unknown[] = [],
60
+ models: (ContentType | Component)[] = [],
61
+ groups: ICreateTagGroup[] = []
62
+ ) => {
63
+ for (const item of mixedData) {
64
+ if (isObject(item) && 'id' in item) {
65
+ if (!('dataFormat' in item)) groups.push(item as ICreateTagGroup);
66
+ else models.push(item as ContentType | Component);
67
+ }
68
+ }
69
+ };
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const LIB_VERSION = "1.5.1-beta.5";
1
+ export const LIB_VERSION = "1.5.1-beta.7";