@contentstack/cli-cm-import 1.3.0 → 1.4.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Contentstack
3
+ Copyright (c) 2023 Contentstack
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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 (--version)
40
- @contentstack/cli-cm-import/1.3.0 linux-x64 node-v16.19.0
40
+ @contentstack/cli-cm-import/1.4.0 linux-x64 node-v16.19.1
41
41
  $ csdx --help [COMMAND]
42
42
  USAGE
43
43
  $ csdx COMMAND
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.0",
2
+ "version": "1.4.0",
3
3
  "commands": {
4
4
  "cm:stacks:import": {
5
5
  "id": "cm:stacks:import",
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-import",
3
3
  "description": "Contentstack CLI plugin to import content into stack",
4
- "version": "1.3.0",
4
+ "version": "1.4.0",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-command": "^1.1.0",
9
- "@contentstack/cli-utilities": "^1.1.0",
8
+ "@contentstack/cli-command": "^1.2.0",
9
+ "@contentstack/cli-utilities": "^1.2.0",
10
10
  "@oclif/config": "^1.18.3",
11
11
  "big-json": "^3.2.0",
12
12
  "bluebird": "^3.7.2",
13
+ "chalk": "^4.1.2",
13
14
  "debug": "^4.1.0",
14
15
  "lodash": "^4.17.20",
15
16
  "marked": "^4.0.17",
@@ -19,17 +20,17 @@
19
20
  "winston": "^3.7.2"
20
21
  },
21
22
  "devDependencies": {
22
- "oclif": "^3.1.2",
23
23
  "@oclif/test": "^1.2.6",
24
24
  "chai": "^4.2.0",
25
25
  "eslint": "^8.18.0",
26
- "eslint-config-oclif": "^3.1.0",
26
+ "eslint-config-oclif": "^4.0.0",
27
27
  "globby": "^10.0.2",
28
28
  "mocha": "^10.0.0",
29
- "nyc": "^15.1.0"
29
+ "nyc": "^15.1.0",
30
+ "oclif": "^3.1.2"
30
31
  },
31
32
  "engines": {
32
- "node": ">=8.0.0"
33
+ "node": ">=14.0.0"
33
34
  },
34
35
  "files": [
35
36
  "/npm-shrinkwrap.json",
@@ -48,7 +49,8 @@
48
49
  "postpack": "rm -f oclif.manifest.json",
49
50
  "prepack": "oclif manifest && oclif readme",
50
51
  "test": "nyc mocha --forbid-only \"test/**/*.test.js\"",
51
- "version": "oclif readme && git add README.md"
52
+ "version": "oclif readme && git add README.md",
53
+ "clean": "rm -rf ./node_modules tsconfig.build.tsbuildinfo"
52
54
  },
53
55
  "csdxConfig": {
54
56
  "expiredCommands": {
package/src/app.js CHANGED
@@ -48,7 +48,7 @@ exports.initial = (configData) => {
48
48
  })
49
49
  .catch((error) => {
50
50
  addlogs(config, `Failed to import contents ${util.formatError(error)}`, 'error');
51
- reject(e);
51
+ reject(error);
52
52
  process.exit(1);
53
53
  });
54
54
  } else {
@@ -1,7 +1,7 @@
1
1
  const _ = require('lodash');
2
2
  const defaultConfig = require('../../../config/default');
3
- const { Command, flags } = require('@contentstack/cli-command');
4
- const { configHandler } = require('@contentstack/cli-utilities');
3
+ const { Command } = require('@contentstack/cli-command');
4
+ const { configHandler, flags, printFlagDeprecation } = require('@contentstack/cli-utilities');
5
5
  const {
6
6
  configWithMToken,
7
7
  parameterWithMToken,
@@ -10,7 +10,6 @@ const {
10
10
  parametersWithAuthToken,
11
11
  withoutParametersWithAuthToken,
12
12
  } = require('../../../lib/util/import-flags');
13
- const { printFlagDeprecation } = require('@contentstack/cli-utilities');
14
13
 
15
14
  class ImportCommand extends Command {
16
15
  async run() {
@@ -35,6 +35,11 @@ module.exports = {
35
35
  fileName: 'locales.json',
36
36
  requiredKeys: ['code', 'uid', 'name', 'fallback_locale'],
37
37
  },
38
+ masterLocale: {
39
+ dirName: 'locales',
40
+ fileName: 'master-locale.json',
41
+ requiredKeys: ['code', 'uid', 'name'],
42
+ },
38
43
  customRoles: {
39
44
  dirName: 'custom-roles',
40
45
  fileName: 'custom-roles.json',
@@ -11,6 +11,7 @@ let chalk = require('chalk');
11
11
  let mkdirp = require('mkdirp');
12
12
  let Promise = require('bluebird');
13
13
  let { isEmpty, merge, cloneDeep } = require('lodash');
14
+ const { cliux } = require('@contentstack/cli-utilities');
14
15
 
15
16
  let helper = require('../util/fs');
16
17
  let { addlogs } = require('../util/log');
@@ -23,6 +24,7 @@ module.exports = class ImportLanguages {
23
24
  langUidMapper = {};
24
25
  masterLanguage = config.master_locale;
25
26
  langConfig = config.modules.locales;
27
+ sourceMasterLangConfig = config.modules.masterLocale;
26
28
  reqConcurrency = config.concurrency || config.fetchConcurrency || 1;
27
29
 
28
30
  constructor(importConfig, stackAPIClient) {
@@ -37,9 +39,10 @@ module.exports = class ImportLanguages {
37
39
  let langMapperPath = path.resolve(this.config.data, 'mapper', 'languages');
38
40
  let langFolderPath = path.resolve(this.config.data, this.langConfig.dirName);
39
41
  let langFailsPath = path.resolve(this.config.data, 'mapper', 'languages', 'fails.json');
40
- let langSuccessPath = path.resolve(this.config.data, 'mapper', 'languages', 'success.json');
41
42
  let langUidMapperPath = path.resolve(this.config.data, 'mapper', 'languages', 'uid-mapper.json');
43
+ self.langSuccessPath = path.resolve(this.config.data, 'mapper', 'languages', 'success.json');
42
44
  self.languages = helper.readFileSync(path.resolve(langFolderPath, this.langConfig.fileName));
45
+ self.sourceMasterLanguages = helper.readFileSync(path.resolve(langFolderPath, this.sourceMasterLangConfig.fileName));
43
46
 
44
47
  mkdirp.sync(langMapperPath);
45
48
 
@@ -48,11 +51,22 @@ module.exports = class ImportLanguages {
48
51
  self.langUidMapper = self.langUidMapper || {};
49
52
  }
50
53
 
51
- return new Promise(function (resolve, reject) {
54
+ return new Promise(async function (resolve, reject) {
52
55
  if (self.languages === undefined || isEmpty(self.languages)) {
53
56
  addlogs(self.config, chalk.white('No Languages Found'), 'success');
54
57
  return resolve({ empty: true });
55
58
  }
59
+
60
+ let sourceMasterLangDetails = self.sourceMasterLanguages && Object.values(self.sourceMasterLanguages);
61
+ if (sourceMasterLangDetails &&
62
+ sourceMasterLangDetails[0] &&
63
+ sourceMasterLangDetails[0]["code"] &&
64
+ self.masterLanguage["code"] === sourceMasterLangDetails[0]["code"]) {
65
+ await self.checkAndUpdateMasterLocaleName(sourceMasterLangDetails).catch((error) => {
66
+ addlogs(self.config, formatError(error), 'warn');
67
+ })
68
+ }
69
+
56
70
  let langUids = Object.keys(self.languages);
57
71
  return Promise.map(
58
72
  langUids,
@@ -98,7 +112,7 @@ module.exports = class ImportLanguages {
98
112
  self
99
113
  .updateLocales(langUids)
100
114
  .then(() => {
101
- helper.writeFileSync(langSuccessPath, self.success);
115
+ helper.writeFileSync(self.langSuccessPath, self.success);
102
116
  addlogs(self.config, chalk.green('Languages have been imported successfully!'), 'success');
103
117
  resolve();
104
118
  })
@@ -142,4 +156,58 @@ module.exports = class ImportLanguages {
142
156
  });
143
157
  });
144
158
  }
159
+
160
+ checkAndUpdateMasterLocaleName(sourceMasterLangDetails) {
161
+ let self = this;
162
+ return new Promise(async function (resolve, reject) {
163
+ let masterLangDetails = await self.stackAPIClient.locale(self.masterLanguage["code"]).fetch()
164
+ .catch((error) => {
165
+ addlogs(self.config, formatError(error), 'warn');
166
+ })
167
+ if (masterLangDetails &&
168
+ masterLangDetails["name"] &&
169
+ sourceMasterLangDetails[0]["name"] &&
170
+ masterLangDetails["name"].toString().toUpperCase() !== sourceMasterLangDetails[0]["name"].toString().toUpperCase()
171
+ ) {
172
+ cliux.print(
173
+ 'WARNING!!! The master language name for the source and destination is different.',
174
+ { color: 'yellow' },
175
+ );
176
+ cliux.print(
177
+ `Old Master language name: ${masterLangDetails["name"]}`,
178
+ { color: 'red' },
179
+ );
180
+ cliux.print(
181
+ `New Master language name: ${sourceMasterLangDetails[0]["name"]}`,
182
+ { color: 'green' },
183
+ );
184
+ let confirm = await cliux.inquire({
185
+ type: 'confirm',
186
+ message: 'Are you sure you want to update name of master language?',
187
+ name: 'confirmation',
188
+ })
189
+
190
+ if (confirm) {
191
+ let languid = sourceMasterLangDetails[0] && sourceMasterLangDetails[0]["uid"];
192
+ let lang = self.sourceMasterLanguages[languid];
193
+ if (!lang) return reject('Locale not found.!');
194
+ const langObj = self.stackAPIClient.locale(lang.code);
195
+ Object.assign(langObj, { name: lang.name });
196
+ langObj.update()
197
+ .then(() => {
198
+ helper.writeFileSync(self.langSuccessPath, self.success);
199
+ addlogs(self.config, chalk.green('Master Languages name have been updated successfully!'), 'success');
200
+ resolve();
201
+ })
202
+ .catch(function (error) {
203
+ reject(error);
204
+ });
205
+ } else {
206
+ resolve();
207
+ }
208
+ } else {
209
+ resolve();
210
+ }
211
+ });
212
+ }
145
213
  };
@@ -35,8 +35,6 @@ module.exports = class ImportMarketplaceApps {
35
35
  }
36
36
 
37
37
  async start() {
38
- this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl(this.config));
39
- this.client = contentstack.client({ authtoken: this.config.auth_token, endpoint: this.developerHubBaseUrl });
40
38
  this.mapperDirPath = path.resolve(this.config.data, 'mapper', 'marketplace_apps');
41
39
  this.uidMapperPath = path.join(this.mapperDirPath, 'uid-mapping.json');
42
40
  this.marketplaceAppFolderPath = path.resolve(this.config.data, this.marketplaceAppConfig.dirName);
@@ -54,6 +52,9 @@ module.exports = class ImportMarketplaceApps {
54
52
  return Promise.resolve();
55
53
  }
56
54
 
55
+ this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl(this.config));
56
+ this.client = contentstack.client({ authtoken: this.config.auth_token, endpoint: this.developerHubBaseUrl });
57
+
57
58
  await this.getOrgUid();
58
59
 
59
60
  this.httpClient = new HttpClient({
@@ -210,18 +211,14 @@ module.exports = class ImportMarketplaceApps {
210
211
 
211
212
  for (let app of privateApps) {
212
213
  // NOTE keys can be passed to install new app in the developer hub
213
- app.manifest = _.pick(app.manifest, [
214
- 'uid',
215
- 'name',
216
- 'description',
217
- 'icon',
218
- 'target_type',
219
- 'ui_location',
220
- 'webhook',
221
- 'oauth',
222
- ]);
214
+ app.manifest = _.pick(app.manifest, ['uid', 'name', 'description', 'icon', 'target_type', 'webhook', 'oauth']);
223
215
  this.appOrginalName = app.manifest.name;
224
- await this.createPrivateApps(app.manifest);
216
+ await this.createPrivateApps({
217
+ oauth: app.oauth,
218
+ webhook: app.webhook,
219
+ ui_location: app.ui_location,
220
+ ...app.manifest,
221
+ });
225
222
  }
226
223
 
227
224
  this.appOrginalName = undefined;
@@ -264,9 +261,9 @@ module.exports = class ImportMarketplaceApps {
264
261
  let locations = app.ui_location && app.ui_location.locations;
265
262
 
266
263
  if (!uidCleaned && !_.isEmpty(locations)) {
267
- app.ui_location.locations = this.uodateManifestUILocations(locations, 'uid');
264
+ app.ui_location.locations = this.updateManifestUILocations(locations, 'uid');
268
265
  } else if (uidCleaned && !_.isEmpty(locations)) {
269
- app.ui_location.locations = this.uodateManifestUILocations(locations, 'name', appSuffix);
266
+ app.ui_location.locations = this.updateManifestUILocations(locations, 'name', appSuffix);
270
267
  }
271
268
 
272
269
  if (app.name > 20) {
@@ -328,7 +325,7 @@ module.exports = class ImportMarketplaceApps {
328
325
  return this.createPrivateApps(app, true, appSuffix + 1);
329
326
  }
330
327
 
331
- uodateManifestUILocations(locations, type = 'uid', appSuffix = 1) {
328
+ updateManifestUILocations(locations, type = 'uid', appSuffix = 1) {
332
329
  switch (type) {
333
330
  case 'uid':
334
331
  return _.map(locations, (location) => {
@@ -389,7 +386,10 @@ module.exports = class ImportMarketplaceApps {
389
386
  .catch((error) => error);
390
387
 
391
388
  if (installation.installation_uid) {
392
- log(this.config, `${app.manifest.name} app installed successfully.!`, 'success');
389
+ let appName = (this.appNameMapping[app.manifest.name]) ?
390
+ this.appNameMapping[app.manifest.name] :
391
+ app.manifest.name ;
392
+ log(this.config, `${appName} app installed successfully.!`, 'success');
393
393
  await this.makeRedirectUrlCall(installation, app.manifest.name);
394
394
  this.installationUidMapping[app.uid] = installation.installation_uid;
395
395
  updateParam = { manifest: app.manifest, ...installation, configuration, server_configuration };
@@ -118,3 +118,7 @@ exports.readdirSync = function (dirPath) {
118
118
  return [];
119
119
  }
120
120
  };
121
+
122
+ exports.fileExistsSync = function (path) {
123
+ return fs.existsSync(path);
124
+ };
@@ -219,7 +219,9 @@ module.exports = function (data, mappedAssetUids, mappedAssetUrls, assetUidMappe
219
219
  [data.entry.uid]: matchedUids,
220
220
  };
221
221
  }
222
- helper.writeFile(path.join(assetUidMapperPath, 'matched-asset-uids.json'));
222
+ if (!helper.fileExistsSync(path.join(assetUidMapperPath, 'matched-asset-uids.json'))) {
223
+ helper.writeFile(path.join(assetUidMapperPath, 'matched-asset-uids.json'));
224
+ }
223
225
  }
224
226
 
225
227
  if (unmatchedUids.length) {