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

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.
@@ -28,17 +28,17 @@ import {
28
28
  import ContensisAuthService from './ContensisAuthService';
29
29
 
30
30
  import { LogMessages } from '~/localisation/en-GB';
31
+ import { MixedFileData } from '~/mappers/MixedFileData';
31
32
  import {
32
33
  CliUrls,
33
34
  OutputFormat,
34
35
  OutputOptionsConstructorArg,
35
36
  } from '~/models/CliService';
36
37
 
37
- import { readFileAsJSON } from '~/providers/file-provider';
38
38
  import SessionCacheProvider from '../providers/SessionCacheProvider';
39
39
  import CredentialProvider from '~/providers/CredentialProvider';
40
40
 
41
- import { splitTagGroupsInModels, splitTagsAndGroups, url } from '~/util';
41
+ import { url } from '~/util';
42
42
  import { sanitiseIds } from '~/util/api-ids';
43
43
  import {
44
44
  isPassword,
@@ -67,16 +67,6 @@ import { promiseDelay } from '~/util/timers';
67
67
  import { GetTagsArgs } from 'migratortron/dist/services/TagsMigrationService';
68
68
  import { GetTagGroupsArgs } from 'migratortron/dist/services/TagGroupsMigrationService';
69
69
 
70
- type ImportDataType =
71
- | 'entries'
72
- | 'contentTypes'
73
- | 'components'
74
- | 'models'
75
- | 'nodes'
76
- | 'tagGroups'
77
- | 'tags'
78
- | 'user-input';
79
-
80
70
  let insecurePasswordWarningShown = false;
81
71
 
82
72
  class ContensisCli {
@@ -344,27 +334,21 @@ class ContensisCli {
344
334
 
345
335
  ConnectContensisImport = async ({
346
336
  commit = false,
337
+ noSource = false,
347
338
  fromFile,
348
- importDataType,
349
339
  importData,
350
- mixedData,
351
340
  }: {
352
341
  commit?: boolean;
342
+ noSource?: boolean;
353
343
  fromFile?: string;
354
- importDataType?: ImportDataType;
355
- importData?: any[];
356
- mixedData?: {
357
- [K in ImportDataType]?: any[];
358
- };
344
+ importData?: MixedFileData;
359
345
  }) => {
360
- const source: 'contensis' | 'file' =
361
- fromFile || importData || mixedData ? 'file' : 'contensis';
362
-
363
- const fileData =
364
- importData || (fromFile ? (await readFileAsJSON(fromFile)) || [] : []);
346
+ const source: 'contensis' | 'user-input' =
347
+ fromFile || importData || noSource ? 'user-input' : 'contensis';
365
348
 
366
- if (typeof fileData === 'string')
367
- throw new Error(`Import file format must be of type JSON`);
349
+ const mixedData = fromFile
350
+ ? await new MixedFileData().readFile(fromFile)
351
+ : importData;
368
352
 
369
353
  const { contensisOpts, currentEnv, env, log, messages, sourceAlias } = this;
370
354
  const environments = this.cache.environments || {};
@@ -405,7 +389,7 @@ class ContensisCli {
405
389
  const cachedTargetPassword = targetCredentials?.current?.password;
406
390
 
407
391
  if (cachedSourcePassword && cachedTargetPassword) {
408
- if (source === 'file' || importDataType === 'user-input') {
392
+ if (source === 'user-input') {
409
393
  this.contensis = new ContensisMigrationService(
410
394
  {
411
395
  concurrency: 2,
@@ -420,7 +404,6 @@ class ContensisCli {
420
404
  targetProjects: [env.currentProject || ''],
421
405
  assetHostname: this.urls?.previewWeb,
422
406
  },
423
- ...(importDataType ? { [importDataType]: fileData } : {}),
424
407
  ...(mixedData || {}),
425
408
  },
426
409
  !commit
@@ -1175,14 +1158,17 @@ class ContensisCli {
1175
1158
  }) => {
1176
1159
  const { currentEnv, currentProject, log, messages } = this;
1177
1160
 
1161
+ let importData;
1162
+ if (tags) {
1163
+ importData = new MixedFileData();
1164
+ importData.tags = tags;
1165
+ importData.tagGroups = data || [];
1166
+ }
1167
+
1178
1168
  const contensis = await this.ConnectContensisImport({
1179
1169
  commit,
1180
1170
  fromFile,
1181
- importDataType: tags ? 'user-input' : 'tagGroups',
1182
- mixedData: {
1183
- tagGroups: data,
1184
- tags: tags,
1185
- },
1171
+ importData,
1186
1172
  });
1187
1173
 
1188
1174
  if (contensis) {
@@ -1304,10 +1290,7 @@ class ContensisCli {
1304
1290
  });
1305
1291
 
1306
1292
  if (Array.isArray(result)) {
1307
- let tags: ICreateTag[] = [];
1308
- const groups: ICreateTagGroup[] = [];
1309
- if (withDependents) splitTagsAndGroups(result, tags, groups);
1310
- else tags = result;
1293
+ const { tags, tagGroups } = new MixedFileData(result);
1311
1294
 
1312
1295
  log.success(messages.tags.list(currentEnv, tags.length));
1313
1296
 
@@ -1318,11 +1301,13 @@ class ContensisCli {
1318
1301
  log.raw('');
1319
1302
  log.object(tag);
1320
1303
  }
1321
- if (groups.length) {
1304
+ if (tagGroups.length) {
1322
1305
  log.raw('');
1323
- log.success(messages.taggroups.list(currentEnv, groups.length));
1306
+ log.success(
1307
+ messages.taggroups.list(currentEnv, tagGroups.length)
1308
+ );
1324
1309
 
1325
- for (const group of groups) {
1310
+ for (const group of tagGroups) {
1326
1311
  log.raw('');
1327
1312
  log.object(group);
1328
1313
  }
@@ -1346,25 +1331,22 @@ class ContensisCli {
1346
1331
  });
1347
1332
 
1348
1333
  if (Array.isArray(result)) {
1349
- let tags: Tag[] = [];
1350
- const groups: TagGroup[] = [];
1351
- if (withDependents) splitTagsAndGroups(result, tags, groups);
1352
- else tags = result;
1334
+ const { tags, tagGroups } = new MixedFileData(result);
1353
1335
  log.success(messages.tags.list(currentEnv, tags.length));
1354
1336
 
1355
1337
  if (!tags.length) log.help(messages.tags.noneExist());
1356
1338
 
1357
1339
  await this.HandleFormattingAndOutput(result, () => {
1358
1340
  // print the tags to console
1359
- for (const { version, ...tag } of tags) {
1341
+ for (const { version, ...tag } of tags as Tag[]) {
1360
1342
  log.raw('');
1361
1343
  log.object(tag);
1362
1344
  }
1363
- if (groups.length) {
1345
+ if (tagGroups.length) {
1364
1346
  log.raw('');
1365
- log.success(messages.taggroups.list(currentEnv, groups.length));
1347
+ log.success(messages.taggroups.list(currentEnv, tagGroups.length));
1366
1348
 
1367
- for (const { version, ...group } of groups) {
1349
+ for (const { version, ...group } of tagGroups as TagGroup[]) {
1368
1350
  log.raw('');
1369
1351
  log.object(group);
1370
1352
  }
@@ -1391,30 +1373,23 @@ class ContensisCli {
1391
1373
  }) => {
1392
1374
  const { currentEnv, currentProject, log, messages } = this;
1393
1375
 
1394
- const mixedData: {
1395
- tags: ICreateTag[];
1396
- tagGroups: ICreateTagGroup[];
1397
- } = { tags: [], tagGroups: [] };
1376
+ let importData;
1398
1377
 
1399
1378
  if (data) {
1400
- mixedData.tags = data;
1401
- mixedData.tagGroups = [...new Set(data.map(t => t.groupId))].map(
1379
+ importData = new MixedFileData();
1380
+ importData.tags = data;
1381
+ importData.tagGroups = [...new Set(data.map(t => t.groupId))].map(
1402
1382
  id =>
1403
1383
  ({
1404
1384
  id,
1405
1385
  }) as ICreateTagGroup
1406
1386
  );
1407
1387
  }
1408
- if (fromFile) {
1409
- // File may contain mix of tags and tag groups, separate those here
1410
- const fileData = fromFile ? (await readFileAsJSON(fromFile)) || [] : [];
1411
- splitTagsAndGroups(fileData, mixedData.tags, mixedData.tagGroups);
1412
- }
1413
1388
 
1414
1389
  const contensis = await this.ConnectContensisImport({
1415
1390
  commit,
1416
- importDataType: 'tags',
1417
- mixedData,
1391
+ fromFile,
1392
+ importData,
1418
1393
  });
1419
1394
 
1420
1395
  if (contensis) {
@@ -1492,7 +1467,7 @@ class ContensisCli {
1492
1467
  this.contensisOpts.concurrency = 1;
1493
1468
  const contensis = await this.ConnectContensisImport({
1494
1469
  commit,
1495
- importDataType: 'user-input', // 'user-input' import type does not require a source cms
1470
+ noSource: true,
1496
1471
  });
1497
1472
  if (contensis) {
1498
1473
  log.line();
@@ -1839,25 +1814,9 @@ class ContensisCli {
1839
1814
  }) => {
1840
1815
  const { currentProject, log, messages } = this;
1841
1816
 
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`);
1857
-
1858
1817
  const contensis = await this.ConnectContensisImport({
1859
1818
  commit,
1860
- mixedData: mixedData.models.length ? mixedData : undefined,
1819
+ fromFile,
1861
1820
  });
1862
1821
 
1863
1822
  if (contensis) {
@@ -2013,7 +1972,7 @@ class ContensisCli {
2013
1972
  const { currentProject, log, messages } = this;
2014
1973
  const contensis = await this.ConnectContensisImport({
2015
1974
  commit,
2016
- importDataType: 'user-input', // 'user-input' import type does not require a source cms
1975
+ noSource: true,
2017
1976
  });
2018
1977
  if (contensis) {
2019
1978
  const [err, result] = await contensis.DeleteContentTypes(contentTypeIds);
@@ -2053,23 +2012,18 @@ class ContensisCli {
2053
2012
  ) => {
2054
2013
  const { currentProject, log, messages } = this;
2055
2014
 
2056
- let fileData = fromFile
2057
- ? (await readFileAsJSON<ContentType[]>(fromFile)) || []
2058
- : [];
2059
- if (typeof fileData === 'string')
2060
- throw new Error(`Import file format must be of type JSON`);
2061
-
2062
- if (!Array.isArray(fileData)) fileData = [fileData];
2015
+ let importData;
2016
+ if (fromFile) importData = await new MixedFileData().readFile(fromFile);
2063
2017
 
2064
2018
  const contensis = await this.ConnectContensisImport({
2065
2019
  commit,
2066
- importDataType: fromFile ? 'user-input' : undefined,
2020
+ noSource: !!fromFile,
2067
2021
  });
2068
2022
 
2069
2023
  if (contensis) {
2070
2024
  if (fromFile)
2071
2025
  // Pass each content type to the target repo
2072
- for (const contentType of fileData) {
2026
+ for (const contentType of importData.models) {
2073
2027
  // Fix invalid data
2074
2028
  contentType.projectId = currentProject;
2075
2029
  delete contentType.uuid;
@@ -2112,22 +2066,16 @@ class ContensisCli {
2112
2066
  ) => {
2113
2067
  const { log } = this;
2114
2068
 
2115
- let fileData = fromFile
2116
- ? (await readFileAsJSON<ContentType[]>(fromFile)) || []
2117
- : [];
2118
- if (typeof fileData === 'string')
2119
- throw new Error(`Import file format must be of type JSON`);
2120
-
2121
- if (!Array.isArray(fileData)) fileData = [fileData];
2069
+ let importData;
2070
+ if (fromFile) importData = await new MixedFileData().readFile(fromFile);
2122
2071
 
2123
- const contensis = await this.ConnectContensisImport({
2124
- fromFile,
2125
- importDataType: 'models',
2126
- });
2072
+ const contensis = await this.ConnectContensisImport({ fromFile });
2127
2073
 
2128
2074
  if (contensis) {
2129
2075
  const [err, result] = (await to(
2130
- contensis.models.Diff(fileData.length ? fileData : modelIds)
2076
+ contensis.models.Diff(
2077
+ importData.models.length ? importData.models : modelIds
2078
+ )
2131
2079
  )) as [Error | null, ContentTypesResult | undefined];
2132
2080
 
2133
2081
  if (err) log.error(err.message, err);
@@ -2201,10 +2149,12 @@ class ContensisCli {
2201
2149
 
2202
2150
  RemoveComponents = async (componentIds: string[], commit = false) => {
2203
2151
  const { currentProject, log, messages } = this;
2152
+
2204
2153
  const contensis = await this.ConnectContensisImport({
2205
2154
  commit,
2206
- importDataType: 'user-input', // 'user-input' import type does not require a source cms
2155
+ noSource: true,
2207
2156
  });
2157
+
2208
2158
  if (contensis) {
2209
2159
  const [err, result] = await contensis.DeleteContentTypes(
2210
2160
  undefined,
@@ -2247,23 +2197,18 @@ class ContensisCli {
2247
2197
  ) => {
2248
2198
  const { currentProject, log, messages } = this;
2249
2199
 
2250
- let fileData = fromFile
2251
- ? (await readFileAsJSON<Component[]>(fromFile)) || []
2252
- : [];
2253
- if (typeof fileData === 'string')
2254
- throw new Error(`Import file format must be of type JSON`);
2255
-
2256
- if (!Array.isArray(fileData)) fileData = [fileData];
2200
+ let importData;
2201
+ if (fromFile) importData = await new MixedFileData().readFile(fromFile);
2257
2202
 
2258
2203
  const contensis = await this.ConnectContensisImport({
2259
2204
  commit,
2260
- importDataType: fromFile ? 'user-input' : undefined,
2205
+ noSource: !!fromFile,
2261
2206
  });
2262
2207
 
2263
2208
  if (contensis) {
2264
2209
  // Pass each component to the target repo
2265
2210
  if (fromFile)
2266
- for (const component of fileData) {
2211
+ for (const component of importData.models) {
2267
2212
  // Fix invalid data
2268
2213
  component.projectId = currentProject;
2269
2214
  delete component.uuid;
@@ -2302,7 +2247,7 @@ class ContensisCli {
2302
2247
  this.contensisOpts.concurrency = 1;
2303
2248
  const contensis = await this.ConnectContensisImport({
2304
2249
  commit,
2305
- importDataType: 'user-input', // 'user-input' import type does not require a source cms
2250
+ noSource: true,
2306
2251
  });
2307
2252
 
2308
2253
  if (contensis) {
@@ -2392,11 +2337,13 @@ class ContensisCli {
2392
2337
  }) => {
2393
2338
  const { currentEnv, currentProject, log, messages } = this;
2394
2339
 
2340
+ let importData;
2341
+ if (data) importData = new MixedFileData(data);
2342
+
2395
2343
  const contensis = await this.ConnectContensisImport({
2396
2344
  commit,
2397
2345
  fromFile,
2398
- importDataType: 'entries',
2399
- importData: data,
2346
+ importData,
2400
2347
  });
2401
2348
 
2402
2349
  if (contensis) {
@@ -2411,13 +2358,16 @@ class ContensisCli {
2411
2358
 
2412
2359
  if (err) logError(err);
2413
2360
  else {
2414
- const { entries, nodes } = contensis.content.targets[currentProject];
2361
+ const { entries, nodes, tags } =
2362
+ contensis.content.targets[currentProject];
2415
2363
 
2416
2364
  const output = saveEntries
2417
- ? // include entries and dependent nodes when saving entries
2365
+ ? // include entries and dependent nodes (or tags) when saving entries
2418
2366
  [
2419
2367
  entries.migrate?.map(me => me.toJSON()) || [],
2420
2368
  nodes.migrateNodes.map(mn => mn.node),
2369
+ tags.migrateTags.map(mt => mt.toJSON()),
2370
+ tags.migrateGroups.map(mg => mg.toJSON()),
2421
2371
  ].flat()
2422
2372
  : result;
2423
2373
  await this.HandleFormattingAndOutput(output, () => {
@@ -2461,7 +2411,12 @@ class ContensisCli {
2461
2411
  ? (result.nodesResult?.created || 0) +
2462
2412
  (result.nodesResult?.updated || 0)
2463
2413
  : (result.nodesToMigrate?.[currentProject]
2464
- .totalCount as number) || 0
2414
+ .totalCount as number) || 0,
2415
+ commit
2416
+ ? (result.tagsResult?.created || 0) +
2417
+ (result.tagsResult?.updated || 0)
2418
+ : (result.tagsToMigrate?.[currentProject].totalCount as number) ||
2419
+ 0
2465
2420
  )
2466
2421
  );
2467
2422
  if (!commit) {
@@ -2479,7 +2434,8 @@ class ContensisCli {
2479
2434
  noChanges &&
2480
2435
  !err &&
2481
2436
  !result?.migrateResult?.errors &&
2482
- !result?.nodesResult?.errors
2437
+ !result?.nodesResult?.errors &&
2438
+ !result?.tagsResult?.errors
2483
2439
  ) {
2484
2440
  log.help(messages.entries.noChange(currentEnv));
2485
2441
  } else {
@@ -2510,7 +2466,6 @@ class ContensisCli {
2510
2466
  const contensis = await this.ConnectContensisImport({
2511
2467
  commit,
2512
2468
  fromFile,
2513
- importDataType: 'entries',
2514
2469
  });
2515
2470
 
2516
2471
  if (contensis) {
@@ -2591,7 +2546,6 @@ class ContensisCli {
2591
2546
  const contensis = await this.ConnectContensisImport({
2592
2547
  commit,
2593
2548
  fromFile,
2594
- importDataType: 'entries',
2595
2549
  });
2596
2550
 
2597
2551
  if (contensis) {
@@ -2698,7 +2652,6 @@ class ContensisCli {
2698
2652
  const contensis = await this.ConnectContensisImport({
2699
2653
  commit,
2700
2654
  fromFile,
2701
- importDataType: 'nodes',
2702
2655
  });
2703
2656
 
2704
2657
  if (contensis) {
@@ -2773,7 +2726,7 @@ class ContensisCli {
2773
2726
  const { currentEnv, currentProject, log, messages } = this;
2774
2727
  const contensis = await this.ConnectContensisImport({
2775
2728
  commit,
2776
- importDataType: 'user-input', // 'user-input' import type does not require a source cms
2729
+ noSource: true,
2777
2730
  });
2778
2731
 
2779
2732
  if (contensis) {
@@ -140,14 +140,14 @@ export const printEntriesMigrateResult = (
140
140
  string,
141
141
  any,
142
142
  ][]) {
143
+ const projectStatus = Object.entries(
144
+ Object.entries(entryStatus[currentProject])[0]
145
+ )[1][1] as any;
143
146
  if (
144
147
  showAll ||
145
148
  (showChanged &&
146
- (
147
- Object.entries(
148
- Object.entries(entryStatus[currentProject])[0]
149
- )[1][1] as any
150
- ).status !== 'no change')
149
+ projectStatus.status !== 'no change' &&
150
+ projectStatus.status !== 'ignore')
151
151
  ) {
152
152
  console.log(
153
153
  log.infoText(
@@ -215,7 +215,8 @@ export const printEntriesMigrateResult = (
215
215
  const existingPercent = ((existingCount / count) * 100).toFixed(0);
216
216
  const noChangeOrTotalEntriesCount =
217
217
  typeof migrateStatusAndCount !== 'number'
218
- ? migrateStatusAndCount?.['no change'] || 0
218
+ ? (migrateStatusAndCount?.['no change'] || 0) +
219
+ (migrateStatusAndCount?.['ignore'] || 0)
219
220
  : migrateStatusAndCount;
220
221
 
221
222
  const changedPercentage = (
@@ -434,7 +435,7 @@ export const printModelMigrationAnalysis = (
434
435
  )}`;
435
436
  if (projectDetails.error)
436
437
  errorOutput += ` ${log.highlightText(
437
- `error::`
438
+ `error:`
438
439
  )} ${log.errorText(projectDetails.error)}`;
439
440
  }
440
441
  }
package/src/util/index.ts CHANGED
@@ -41,29 +41,3 @@ export const Logging = async (language = 'en-GB') => {
41
41
  Log: Logger,
42
42
  };
43
43
  };
44
-
45
- export const splitTagsAndGroups = (
46
- tagsAndGroups: unknown[] = [],
47
- tags: ICreateTag[] = [],
48
- groups: ICreateTagGroup[] = []
49
- ) => {
50
- for (const item of tagsAndGroups) {
51
- if (isObject(item) && 'id' in item) {
52
- if ('name' in item) groups.push(item as ICreateTagGroup);
53
- else tags.push(item as ICreateTag);
54
- }
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.7";
1
+ export const LIB_VERSION = "1.5.1-beta.9";