@contentstack/cli-cm-import 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-import
37
37
  $ csdx COMMAND
38
38
  running command...
39
39
  $ csdx (-v|--version|version)
40
- @contentstack/cli-cm-import/1.0.0 linux-x64 node-v16.14.2
40
+ @contentstack/cli-cm-import/1.1.0 darwin-arm64 node-v16.17.0
41
41
  $ csdx --help [COMMAND]
42
42
  USAGE
43
43
  $ csdx COMMAND
@@ -88,5 +88,5 @@ EXAMPLES
88
88
  csdx cm:stacks:import --branch <branch name>
89
89
  ```
90
90
 
91
- _See code: [src/commands/cm/stacks/import.js](https://github.com/contentstack/cli/blob/v1.0.0/packages/contentstack-import/src/commands/cm/stacks/import.js)_
91
+ _See code: [src/commands/cm/stacks/import.js](https://github.com/contentstack/cli/blob/v1.1.0/packages/contentstack-import/src/commands/cm/stacks/import.js)_
92
92
  <!-- commandsstop -->
@@ -1 +1 @@
1
- {"version":"1.0.0","commands":{"cm:stacks:import":{"id":"cm:stacks:import","description":"Import script for importing the content into the new stack\n...\nOnce you export content from the source stack, import it to your destination stack by using the cm:stacks:import command.\n","usage":"cm:stacks:import [-c <value>] [-k <value>] [-d <value>] [-a <value>] [--module <value>] [--backup-dir <value>] [--branch <value>] [--import-webhook-status disable|current]","pluginName":"@contentstack/cli-cm-import","pluginType":"core","aliases":["cm:import"],"examples":["csdx cm:stacks:import --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir>","csdx cm:stacks:import --config <path/of/config/dir>","csdx cm:stacks:import --module <single module name>","csdx cm:stacks:import --module <single module name> --backup-dir <backup dir>","csdx cm:stacks:import --alias <management_token_alias>","csdx cm:stacks:import --alias <management_token_alias> --data-dir <path/of/export/destination/dir>","csdx cm:stacks:import --alias <management_token_alias> --config <path/of/config/file>","csdx cm:stacks:import --branch <branch name>"],"flags":{"config":{"name":"config","type":"option","char":"c","description":"[optional] path of config file"},"stack-uid":{"name":"stack-uid","type":"option","char":"s","description":"API key of the target stack","hidden":true},"stack-api-key":{"name":"stack-api-key","type":"option","char":"k","description":"API key of the target stack"},"data":{"name":"data","type":"option","description":"path and location where data is stored","hidden":true},"data-dir":{"name":"data-dir","type":"option","char":"d","description":"path and location where data is stored"},"alias":{"name":"alias","type":"option","char":"a","description":"alias of the management token"},"management-token-alias":{"name":"management-token-alias","type":"option","description":"alias of the management token","hidden":true},"auth-token":{"name":"auth-token","type":"boolean","char":"A","description":"to use auth token","hidden":true,"allowNo":false},"module":{"name":"module","type":"option","char":"m","description":"[optional] specific module name"},"backup-dir":{"name":"backup-dir","type":"option","char":"b","description":"[optional] backup directory name when using specific module"},"branch":{"name":"branch","type":"option","char":"B","description":"[optional] branch name"},"import-webhook-status":{"name":"import-webhook-status","type":"option","description":"Webhook state","required":false,"options":["disable","current"],"default":"disable"}},"args":[]}}}
1
+ {"version":"1.1.0","commands":{"cm:stacks:import":{"id":"cm:stacks:import","description":"Import script for importing the content into the new stack\n...\nOnce you export content from the source stack, import it to your destination stack by using the cm:stacks:import command.\n","usage":"cm:stacks:import [-c <value>] [-k <value>] [-d <value>] [-a <value>] [--module <value>] [--backup-dir <value>] [--branch <value>] [--import-webhook-status disable|current]","pluginName":"@contentstack/cli-cm-import","pluginType":"core","aliases":["cm:import"],"examples":["csdx cm:stacks:import --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir>","csdx cm:stacks:import --config <path/of/config/dir>","csdx cm:stacks:import --module <single module name>","csdx cm:stacks:import --module <single module name> --backup-dir <backup dir>","csdx cm:stacks:import --alias <management_token_alias>","csdx cm:stacks:import --alias <management_token_alias> --data-dir <path/of/export/destination/dir>","csdx cm:stacks:import --alias <management_token_alias> --config <path/of/config/file>","csdx cm:stacks:import --branch <branch name>"],"flags":{"config":{"name":"config","type":"option","char":"c","description":"[optional] path of config file"},"stack-uid":{"name":"stack-uid","type":"option","char":"s","description":"API key of the target stack","hidden":true},"stack-api-key":{"name":"stack-api-key","type":"option","char":"k","description":"API key of the target stack"},"data":{"name":"data","type":"option","description":"path and location where data is stored","hidden":true},"data-dir":{"name":"data-dir","type":"option","char":"d","description":"path and location where data is stored"},"alias":{"name":"alias","type":"option","char":"a","description":"alias of the management token"},"management-token-alias":{"name":"management-token-alias","type":"option","description":"alias of the management token","hidden":true},"auth-token":{"name":"auth-token","type":"boolean","char":"A","description":"to use auth token","hidden":true,"allowNo":false},"module":{"name":"module","type":"option","char":"m","description":"[optional] specific module name"},"backup-dir":{"name":"backup-dir","type":"option","char":"b","description":"[optional] backup directory name when using specific module"},"branch":{"name":"branch","type":"option","char":"B","description":"[optional] branch name"},"import-webhook-status":{"name":"import-webhook-status","type":"option","description":"Webhook state","required":false,"options":["disable","current"],"default":"disable"}},"args":[]}}}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-import",
3
3
  "description": "Contentstack CLI plugin to import content into stack",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-command": "^1.0.0",
8
+ "@contentstack/cli-command": "^1.0.1",
9
9
  "@contentstack/management": "^1.3.0",
10
- "@contentstack/cli-utilities": "^1.0.0",
11
- "@contentstack/cli-cm-export": "^1.0.0",
10
+ "@contentstack/cli-utilities": "^1.0.2",
11
+ "@contentstack/cli-cm-export": "^1.1.0",
12
12
  "@oclif/command": "^1.8.16",
13
13
  "@oclif/config": "^1.18.3",
14
14
  "bluebird": "3.5.1",
package/src/app.js CHANGED
@@ -91,7 +91,7 @@ let singleImport = async (moduleName, types, config) => {
91
91
  if (moduleName === 'content-types') {
92
92
  let ctPath = path.resolve(config.data, config.modules.content_types.dirName);
93
93
  let fieldPath = path.join(ctPath + '/field_rules_uid.json');
94
- if (fieldPath && fieldPath !== undefined) {
94
+ if (fieldPath) {
95
95
  await util.field_rules_update(config, ctPath);
96
96
  }
97
97
  }
@@ -139,9 +139,9 @@ let allImport = async (config, types) => {
139
139
  config,
140
140
  chalk.green(
141
141
  'The data of the ' +
142
- config.sourceStackName +
142
+ (config.sourceStackName || config.source_stack) +
143
143
  ' stack has been imported into ' +
144
- config.destinationStackName +
144
+ (config.destinationStackName || config.target_stack) +
145
145
  ' stack successfully!',
146
146
  ),
147
147
  'success',
@@ -8,24 +8,38 @@ module.exports = {
8
8
  // not passing `locale` will migrate all the locales present
9
9
  // locales: ['fr-fr'],
10
10
  host: 'https://api.contentstack.io/v3',
11
+ extensionHost: 'https://app.contentstack.com',
12
+ developerHubUrls: {
13
+ 'https://api.contentstack.io': 'https://developerhub-api.contentstack.com',
14
+ 'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com',
15
+ 'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com',
16
+ 'https://stag-api.csnonprod.com': 'https://stag-developerhub-api.csnonprod.com'
17
+ },
11
18
  modules: {
12
19
  types: [
13
20
  'locales',
14
21
  'environments',
15
22
  'assets',
16
23
  'extensions',
24
+ 'marketplace-apps',
17
25
  'global-fields',
18
26
  'content-types',
19
27
  'workflows',
20
28
  'entries',
21
29
  'labels',
22
30
  'webhooks',
31
+ 'custom-roles',
23
32
  ],
24
33
  locales: {
25
34
  dirName: 'locales',
26
35
  fileName: 'locales.json',
27
36
  requiredKeys: ['code', 'uid', 'name', 'fallback_locale'],
28
37
  },
38
+ customRoles: {
39
+ dirName: 'custom-roles',
40
+ fileName: 'custom-roles.json',
41
+ customRolesLocalesFileName: 'custom-roles-locales.json',
42
+ },
29
43
  environments: {
30
44
  dirName: 'environments',
31
45
  fileName: 'environments.json',
@@ -74,7 +88,6 @@ module.exports = {
74
88
  limit: 50,
75
89
  assetBatchLimit: 5,
76
90
  },
77
-
78
91
  globalfields: {
79
92
  dirName: 'global_fields',
80
93
  fileName: 'globalfields.json',
@@ -85,6 +98,10 @@ module.exports = {
85
98
  dirName: 'stack',
86
99
  fileName: 'stack.json',
87
100
  },
101
+ marketplace_apps: {
102
+ dirName: 'marketplace_apps',
103
+ fileName: 'marketplace_apps.json'
104
+ }
88
105
  },
89
106
  languagesCode: [
90
107
  'af-za',
@@ -296,7 +313,6 @@ module.exports = {
296
313
  'xh',
297
314
  'zu',
298
315
  ],
299
-
300
316
  apis: {
301
317
  userSession: '/user-session/',
302
318
  locales: '/locales/',
@@ -418,22 +418,20 @@ importAssets.prototype = {
418
418
  i--;
419
419
  }
420
420
  }
421
- this.findBranches(tree, coll);
421
+ this.findBranches(tree, _.keys(tree), coll);
422
422
  return tree;
423
423
  },
424
- findBranches: function (branch, coll) {
424
+ findBranches: function (tree, branches, coll) {
425
425
  let self = this;
426
- _.forEach(_.keys(branch), () => {
426
+ _.forEach(branches, (branch) => {
427
427
  for (let j = 0; j < coll.length; j++) {
428
- let parent_uid = coll[j].parent_uid;
429
- if (branch.hasOwnProperty(parent_uid)) {
430
- branch[parent_uid][coll[j].uid] = {};
431
- coll.splice(j, 1);
432
- self.findBranches(branch[parent_uid], coll);
433
- --j;
428
+ if (branch === coll[j].parent_uid) {
429
+ let childUid = coll[j].uid;
430
+ tree[branch][childUid] = {};
431
+ self.findBranches(tree[branch], [childUid], coll);
434
432
  }
435
433
  }
436
- })
434
+ });
437
435
  },
438
436
  publish: function (assetUid, assetObject) {
439
437
  let self = this;
@@ -14,10 +14,11 @@ let chalk = require('chalk');
14
14
 
15
15
  let helper = require('../util/fs');
16
16
  let { addlogs } = require('../util/log');
17
+ let config = require('../../config/default');
17
18
  let supress = require('../util/extensionsUidReplace');
18
19
  let sdkInstance = require('../util/contentstack-management-sdk');
20
+ const { getInstalledExtensions } = require('../util/marketplace-app-helper')
19
21
 
20
- let config = require('../../config/default');
21
22
  let reqConcurrency = config.concurrency;
22
23
  let requestLimit = config.rateLimit;
23
24
  let contentTypeConfig = config.modules.content_types;
@@ -40,10 +41,11 @@ function importContentTypes() {
40
41
  this.requestOptions = {
41
42
  json: {},
42
43
  };
44
+ this.installedExtensions = []
43
45
  }
44
46
 
45
47
  importContentTypes.prototype = {
46
- start: function (credentialConfig) {
48
+ start: async function (credentialConfig) {
47
49
  addlogs(config, 'Migrating contenttypes', 'success');
48
50
  let self = this;
49
51
  config = credentialConfig;
@@ -52,6 +54,7 @@ importContentTypes.prototype = {
52
54
  globalFieldsFolderPath = path.resolve(config.data, globalFieldConfig.dirName);
53
55
  contentTypesFolderPath = path.resolve(config.data, contentTypeConfig.dirName);
54
56
  mapperFolderPath = path.join(config.data, 'mapper', 'content_types');
57
+ const appMapperFolderPath = path.join(config.data, 'mapper', 'marketplace_apps');
55
58
  globalFieldMapperFolderPath = helper.readFile(path.join(config.data, 'mapper', 'global_fields', 'success.json'));
56
59
  globalFieldPendingPath = helper.readFile(
57
60
  path.join(config.data, 'mapper', 'global_fields', 'pending_global_fields.js'),
@@ -59,6 +62,7 @@ importContentTypes.prototype = {
59
62
  globalFieldUpdateFile = path.join(config.data, 'mapper', 'global_fields', 'success.json');
60
63
  fileNames = fs.readdirSync(path.join(contentTypesFolderPath));
61
64
  self.globalfields = helper.readFile(path.resolve(globalFieldsFolderPath, globalFieldConfig.fileName));
65
+
62
66
  for (let index in fileNames) {
63
67
  if (skipFiles.indexOf(fileNames[index]) === -1) {
64
68
  self.contentTypes.push(helper.readFile(path.join(contentTypesFolderPath, fileNames[index])));
@@ -74,6 +78,15 @@ importContentTypes.prototype = {
74
78
  if (fs.existsSync(path.join(mapperFolderPath, 'success.json'))) {
75
79
  self.createdContentTypeUids = helper.readFile(path.join(mapperFolderPath, 'success.json')) || [];
76
80
  }
81
+
82
+ if (fs.existsSync(path.join(appMapperFolderPath, 'marketplace-apps.json'))) {
83
+ self.installedExtensions = helper.readFile(path.join(appMapperFolderPath, 'marketplace-apps.json')) || {};
84
+ }
85
+
86
+ if (_.isEmpty(self.installedExtensions)) {
87
+ self.installedExtensions = await getInstalledExtensions(config)
88
+ }
89
+
77
90
  self.contentTypeUids = _.difference(self.contentTypeUids, self.createdContentTypeUids);
78
91
  self.uidToTitleMap = self.mapUidToTitle(self.contentTypes);
79
92
  // remove content types, already created
@@ -182,13 +195,14 @@ importContentTypes.prototype = {
182
195
  updateContentTypes: function (contentType) {
183
196
  let self = this;
184
197
  return new Promise(function (resolve, reject) {
185
- setTimeout(function () {
198
+ setTimeout(async function () {
186
199
  let requestObject = _.cloneDeep(self.requestOptions);
187
200
  if (contentType.field_rules) {
188
201
  field_rules_ct.push(contentType.uid);
189
202
  delete contentType.field_rules;
190
203
  }
191
- supress(contentType.schema);
204
+
205
+ supress(contentType.schema, config.preserveStackVersion, self.installedExtensions);
192
206
  requestObject.json.content_type = contentType;
193
207
  let contentTypeResponse = stack.contentType(contentType.uid);
194
208
  Object.assign(contentTypeResponse, _.cloneDeep(contentType));
@@ -209,9 +223,10 @@ importContentTypes.prototype = {
209
223
  let self = this;
210
224
  return new Promise(function (resolve, reject) {
211
225
  // eslint-disable-next-line no-undef
212
- return Promise.map(globalFieldPendingPath, function (globalfield) {
226
+ return Promise.map(globalFieldPendingPath, async function (globalfield) {
213
227
  let Obj = _.find(self.globalfields, { uid: globalfield });
214
- supress(Obj.schema);
228
+
229
+ supress(Obj.schema, config.preserveStackVersion, self.installedExtensions);
215
230
  let globalFieldObj = stack.globalField(globalfield);
216
231
  Object.assign(globalFieldObj, _.cloneDeep(Obj));
217
232
  return globalFieldObj
@@ -245,7 +260,7 @@ importContentTypes.prototype = {
245
260
  result[ct.uid] = ct.title;
246
261
  });
247
262
  return result;
248
- },
263
+ }
249
264
  };
250
265
 
251
266
  module.exports = new importContentTypes();
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ const mkdirp = require('mkdirp');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const chalk = require('chalk');
7
+
8
+ const helper = require('../util/fs');
9
+ const { addlogs } = require('../util/log');
10
+ const stack = require('../util/contentstack-management-sdk');
11
+ let config = require('../../config/default');
12
+
13
+ const customRolesConfig = config.modules.customRoles;
14
+ let customRolesFolderPath;
15
+ // Mapper file paths variables.
16
+ let customRolesMapperPath;
17
+ let customRolesUidMapperPath;
18
+ let customRolesSuccessPath;
19
+ let customRolesFailsPath;
20
+ let environmentsUidMapperFolderPath;
21
+ let entriesUidMapperFolderPath;
22
+ let customRolesLocalesFilePath;
23
+
24
+ function ImportCustomRoles() {
25
+ this.fails = [];
26
+ this.customRolesUidMapper = {};
27
+ this.labelUids = [];
28
+ this.client = null;
29
+ if (fs.existsSync(customRolesMapperPath)) {
30
+ this.customRolesUidMapper = helper.readFile(customRolesUidMapperPath) || {};
31
+ }
32
+ }
33
+
34
+ ImportCustomRoles.prototype.start = async function(credentialConfig) {
35
+ let self = this;
36
+ try {
37
+ config = credentialConfig;
38
+ this.client = stack.Client(config);
39
+ addlogs(config, chalk.white('Migrating custom-roles'), 'success');
40
+ customRolesFolderPath = path.resolve(config.data, customRolesConfig.dirName);
41
+ self.customRoles = helper.readFile(path.resolve(customRolesFolderPath, customRolesConfig.fileName));
42
+ customRolesLocalesFilePath = path.resolve(customRolesFolderPath, customRolesConfig.customRolesLocalesFileName);
43
+ self.customRolesLocales = helper.readFile(customRolesLocalesFilePath);
44
+ // Mapper file paths.
45
+ customRolesMapperPath = path.resolve(config.data, 'mapper', 'custom-roles');
46
+ customRolesUidMapperPath = path.resolve(config.data, 'mapper', 'custom-roles', 'uid-mapping.json');
47
+ customRolesSuccessPath = path.resolve(config.data, 'custom-roles', 'success.json');
48
+ customRolesFailsPath = path.resolve(config.data, 'custom-roles', 'fails.json');
49
+ environmentsUidMapperFolderPath = path.resolve(config.data, 'mapper', 'environments');
50
+ entriesUidMapperFolderPath = path.resolve(config.data, 'mapper', 'entries');
51
+ mkdirp.sync(customRolesMapperPath);
52
+
53
+ if (!self.customRoles) {
54
+ addlogs(config, chalk.white('No custom-roles found'), 'error');
55
+ return;
56
+ }
57
+ self.customRolesUids = Object.keys(self.customRoles);
58
+
59
+ self.localesUidMap = await getLocalesUidMap(this.client, config, self.customRolesLocales);
60
+
61
+ if (fs.existsSync(environmentsUidMapperFolderPath)) {
62
+ self.environmentsUidMap = helper.readFile(path.resolve(environmentsUidMapperFolderPath, 'uid-mapping.json'));
63
+ }
64
+ if (fs.existsSync(entriesUidMapperFolderPath)) {
65
+ self.entriesUidMap = helper.readFile(path.resolve(entriesUidMapperFolderPath, 'uid-mapping.json'));
66
+ }
67
+
68
+ for (const uid of self.customRolesUids) {
69
+ const customRole = self.customRoles[uid];
70
+
71
+ if (uid in self.customRolesUidMapper) {
72
+ addlogs(config, chalk.white(`The custom-role ${customRole.name} already exists. Skipping it to avoid duplicates!`), 'success');
73
+ continue;
74
+ }
75
+
76
+ try {
77
+ customRole.rules.forEach(rule => {
78
+ const transformUids = getTransformUidsFactory(rule);
79
+ rule = transformUids(rule, self.environmentsUidMap, self.localesUidMap, self.entriesUidMap);
80
+ });
81
+ // rules.branch is required to create custom roles.
82
+ const branchRuleExists = customRole.rules.find(rule => rule.module === 'branch');
83
+ if (!branchRuleExists) {
84
+ customRole.rules.push({
85
+ module: 'branch',
86
+ branches: ['main'],
87
+ acl: { read: true }
88
+ });
89
+ }
90
+ const role = await this.client.stack({ api_key: config.target_stack, management_token: config.management_token })
91
+ .role().create({ role: customRole });
92
+
93
+ self.customRolesUidMapper[uid] = role;
94
+ helper.writeFile(customRolesUidMapperPath, self.customRolesUidMapper);
95
+ } catch (error) {
96
+ self.fails.push(customRole);
97
+ if (error && error.errors && error.errors.name) {
98
+ addlogs(config, chalk.red(`custom-role: ${customRole.name} already exists`), 'error');
99
+ } else {
100
+ addlogs(config, chalk.red(`custom-role: ${customRole.name} failed`), 'error');
101
+ }
102
+ }
103
+ }
104
+ addlogs(config, chalk.green('Custom-roles have been imported successfully!'), 'success');
105
+ } catch (error) {
106
+ helper.writeFile(customRolesFailsPath, self.fails);
107
+ addlogs(config, chalk.red('Custom-roles import failed'), 'error');
108
+ throw error;
109
+ }
110
+ };
111
+
112
+ const getTransformUidsFactory = (rule) => {
113
+ if (rule.module === 'environment') {
114
+ return environmentUidTransformer;
115
+ } else if (rule.module === 'locale') {
116
+ return localeUidTransformer;
117
+ } else if (rule.module === 'entry') {
118
+ return entryUidTransformer;
119
+ } else {
120
+ return noopTransformer;
121
+ }
122
+ };
123
+
124
+ const environmentUidTransformer = (rule, environmentsUidMap) => {
125
+ rule.environments = rule.environments.map(env => environmentsUidMap[env]);
126
+ return rule;
127
+ };
128
+
129
+ const localeUidTransformer = (rule, environmentsUidMap, localesUidMap) => {
130
+ rule.locales = rule.locales.map(locale => localesUidMap[locale]);
131
+ return rule;
132
+ };
133
+
134
+ const entryUidTransformer = (rule, environmentsUidMap, localesUidMap, entriesUidMap) => {
135
+ rule.entries = rule.entries.map(entry => entriesUidMap[entry]);
136
+ return rule;
137
+ };
138
+
139
+ const noopTransformer = (rule) => {
140
+ return rule;
141
+ };
142
+
143
+ const getLocalesUidMap = async (client, config, sourceLocales) => {
144
+ const { items } = await client.stack({ api_key: config.target_stack, management_token: config.management_token }).locale().query().find();
145
+ const [targetLocalesMap, sourceLocalesMap] = [{}, {}];
146
+
147
+ items.forEach(locale => {
148
+ targetLocalesMap[locale.code] = locale.uid;
149
+ });
150
+ for (const key in sourceLocales) {
151
+ sourceLocalesMap[sourceLocales[key].code] = key;
152
+ }
153
+ const localesUidMap = {};
154
+ for (const key in sourceLocalesMap) {
155
+ localesUidMap[sourceLocalesMap[key]] = targetLocalesMap[key];
156
+ }
157
+ return localesUidMap;
158
+ }
159
+ module.exports = new ImportCustomRoles();
@@ -10,16 +10,18 @@ const _ = require('lodash');
10
10
  const mkdirp = require('mkdirp');
11
11
  const chalk = require('chalk');
12
12
 
13
+ const util = require('../util');
13
14
  const helper = require('../util/fs');
14
15
  const { addlogs } = require('../util/log');
15
- const lookupReplaceAssets = require('../util/lookupReplaceAssets');
16
- const lookupReplaceEntries = require('../util/lookupReplaceEntries');
17
16
  const suppress = require('../util/supress-mandatory-fields');
18
- const extension_suppress = require('../util/extensionsUidReplace');
19
- const util = require('../util');
20
- let config = util.getConfig();
21
17
  const stack = require('../util/contentstack-management-sdk');
18
+ const extension_suppress = require('../util/extensionsUidReplace');
19
+ const lookupReplaceAssets = require('../util/lookupReplaceAssets');
20
+ const lookupReplaceEntries = require('../util/lookupReplaceEntries');
21
+ const { getInstalledExtensions } = require('../util/marketplace-app-helper')
22
+
22
23
  let client;
24
+ let config = util.getConfig();
23
25
 
24
26
  let reqConcurrency = config.concurrency;
25
27
  let eConfig = config.modules.entries;
@@ -56,6 +58,7 @@ function importEntries() {
56
58
 
57
59
  createdEntriesWOUidPath = path.join(entryMapperPath, 'created-entries-wo-uid.json');
58
60
  failedWOPath = path.join(entryMapperPath, 'failedWO.json');
61
+
59
62
  // Object of Schemas, referred to by their content type uid
60
63
  this.ctSchemas = {};
61
64
  // Array of content type uids, that have reference fields
@@ -76,6 +79,8 @@ function importEntries() {
76
79
  this.success = [];
77
80
  // Entries that failed to get created OR updated
78
81
  this.fails = [];
82
+ // List of installed extensions to replace uid
83
+ this.installedExtensions = []
79
84
 
80
85
  let files = fs.readdirSync(ctPath);
81
86
  this.environment = helper.readFile(environmentPath);
@@ -108,6 +113,16 @@ importEntries.prototype = {
108
113
  masterLanguage = config.master_locale;
109
114
  addlogs(config, 'Migrating entries', 'success');
110
115
  let languages = helper.readFile(lPath);
116
+ const appMapperFolderPath = path.join(config.data, 'mapper', 'marketplace_apps');
117
+
118
+ if (fs.existsSync(path.join(appMapperFolderPath, 'marketplace-apps.json'))) {
119
+ self.installedExtensions = helper.readFile(path.join(appMapperFolderPath, 'marketplace-apps.json')) || {};
120
+ }
121
+
122
+ if (_.isEmpty(self.installedExtensions)) {
123
+ self.installedExtensions = await getInstalledExtensions(config)
124
+ }
125
+
111
126
  return new Promise(function (resolve, reject) {
112
127
  let langs = [masterLanguage.code];
113
128
  for (let i in languages) {
@@ -248,6 +263,7 @@ importEntries.prototype = {
248
263
  mappedAssetUids,
249
264
  mappedAssetUrls,
250
265
  eLangFolderPath,
266
+ self.installedExtensions
251
267
  );
252
268
  }
253
269
  }
@@ -694,7 +710,7 @@ importEntries.prototype = {
694
710
  // it should be spelled as suppressFields
695
711
  addlogs(config, chalk.white('Suppressing content type fields...'), 'success');
696
712
  let self = this;
697
- return new Promise(function (resolve, reject) {
713
+ return new Promise(async function (resolve, reject) {
698
714
  let modifiedSchemas = [];
699
715
  let suppressedSchemas = [];
700
716
 
@@ -750,7 +766,7 @@ importEntries.prototype = {
750
766
  }
751
767
 
752
768
  // Replace extensions with new UID
753
- extension_suppress(contentTypeSchema.schema, config.preserveStackVersion);
769
+ extension_suppress(contentTypeSchema.schema, config.preserveStackVersion, self.installedExtensions);
754
770
  }
755
771
  }
756
772
 
@@ -834,7 +850,8 @@ importEntries.prototype = {
834
850
  });
835
851
  },
836
852
  unSuppressFields: function () {
837
- return new Promise(function (resolve, reject) {
853
+ let self = this;
854
+ return new Promise(async function (resolve, reject) {
838
855
  let modifiedSchemas = helper.readFile(modifiedSchemaPath);
839
856
  let modifiedSchemasUids = [];
840
857
  let updatedExtensionUidsSchemas = [];
@@ -844,7 +861,8 @@ importEntries.prototype = {
844
861
  if (_contentTypeSchema.field_rules) {
845
862
  delete _contentTypeSchema.field_rules;
846
863
  }
847
- extension_suppress(_contentTypeSchema.schema, config.preserveStackVersion);
864
+
865
+ extension_suppress(_contentTypeSchema.schema, config.preserveStackVersion, self.installedExtensions);
848
866
  updatedExtensionUidsSchemas.push(_contentTypeSchema);
849
867
  }
850
868
  }
@@ -1314,7 +1332,9 @@ importEntries.prototype = {
1314
1332
 
1315
1333
  if (entryRefs.length > 0) {
1316
1334
  entryRefs.forEach((entryRef) => {
1317
- entry[entryRef.uid].children.splice(entryRef.index, 0, entryRef.value);
1335
+ if (!_.isEmpty(entry[entryRef.uid]) && entry[entryRef.uid].children) {
1336
+ entry[entryRef.uid].children.splice(entryRef.index, 0, entryRef.value);
1337
+ }
1318
1338
  });
1319
1339
  }
1320
1340
  }
@@ -1447,7 +1467,7 @@ importEntries.prototype = {
1447
1467
  }
1448
1468
 
1449
1469
  return jsonRteChild;
1450
- },
1470
+ }
1451
1471
  };
1452
1472
 
1453
1473
  module.exports = new importEntries();
@@ -9,13 +9,14 @@ let fs = require('fs');
9
9
  let path = require('path');
10
10
  let Promise = require('bluebird');
11
11
  let chalk = require('chalk');
12
- const {isEmpty} = require('lodash');
12
+ const { isEmpty } = require('lodash');
13
13
 
14
14
  let helper = require('../util/fs');
15
15
  let { addlogs } = require('../util/log');
16
16
  let extension_supress = require('../util/extensionsUidReplace');
17
17
  let removeReferenceFields = require('../util/removeReferenceFields');
18
18
  const stack = require('../util/contentstack-management-sdk');
19
+ const { getInstalledExtensions } = require('../util/marketplace-app-helper');
19
20
 
20
21
  let config = require('../../config/default');
21
22
  let reqConcurrency = config.concurrency;
@@ -39,10 +40,11 @@ function importGlobalFields() {
39
40
  headers: config.headers,
40
41
  method: 'POST',
41
42
  };
43
+ this.installedExtensions = [];
42
44
  }
43
45
 
44
46
  importGlobalFields.prototype = {
45
- start: function (credential) {
47
+ start: async function (credential) {
46
48
  addlogs(config, chalk.white('Migrating global-fields'), 'success');
47
49
  let self = this;
48
50
  config = credential;
@@ -53,6 +55,8 @@ importGlobalFields.prototype = {
53
55
  globalFieldsPending = path.resolve(config.data, 'mapper', 'global_fields', 'pending_global_fields.js');
54
56
  globalfieldsFailsPath = path.resolve(config.data, 'mapper', 'global_fields', 'fails.json');
55
57
  self.globalfields = helper.readFile(path.resolve(globalfieldsFolderPath, globalfieldsConfig.fileName));
58
+ const appMapperFolderPath = path.join(config.data, 'mapper', 'marketplace_apps');
59
+
56
60
  if (fs.existsSync(globalfieldsUidMapperPath)) {
57
61
  self.snipUidMapper = helper.readFile(globalfieldsUidMapperPath);
58
62
  self.snipUidMapper = this.snipUidMapper || {};
@@ -61,6 +65,15 @@ importGlobalFields.prototype = {
61
65
  if (!fs.existsSync(globalfieldsMapperPath)) {
62
66
  mkdirp.sync(globalfieldsMapperPath);
63
67
  }
68
+
69
+ if (fs.existsSync(path.join(appMapperFolderPath, 'marketplace-apps.json'))) {
70
+ self.installedExtensions = helper.readFile(path.join(appMapperFolderPath, 'marketplace-apps.json')) || {};
71
+ }
72
+
73
+ if (isEmpty(self.installedExtensions)) {
74
+ self.installedExtensions = await getInstalledExtensions(config);
75
+ }
76
+
64
77
  client = stack.Client(config);
65
78
  return new Promise(function (resolve, reject) {
66
79
  if (self.globalfields === undefined || isEmpty(self.globalfields)) {
@@ -76,7 +89,7 @@ importGlobalFields.prototype = {
76
89
  supressed: false,
77
90
  };
78
91
  let snip = self.globalfields[snipUid];
79
- extension_supress(snip.schema);
92
+ extension_supress(snip.schema, config.preserveStackVersion, self.installedExtensions);
80
93
  removeReferenceFields(snip.schema, flag);
81
94
 
82
95
  if (flag.supressed) {
@@ -46,6 +46,7 @@ importLanguages.prototype = {
46
46
  langFailsPath = path.resolve(config.data, 'mapper', 'languages', 'fails.json');
47
47
  mkdirp.sync(langMapperPath);
48
48
  self.languages = helper.readFile(path.resolve(langFolderPath, langConfig.fileName));
49
+
49
50
  if (fs.existsSync(langUidMapperPath)) {
50
51
  self.langUidMapper = helper.readFile(langUidMapperPath);
51
52
  self.langUidMapper = self.langUidMapper || {};