@contentstack/cli-cm-import 1.2.1 → 1.2.3
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 +2 -2
- package/oclif.manifest.json +1 -1
- package/package.json +5 -5
- package/src/app.js +12 -2
- package/src/commands/cm/stacks/import.js +4 -4
- package/src/config/default.js +3 -0
- package/src/lib/import/content-types.js +2 -2
- package/src/lib/import/custom-roles.js +9 -5
- package/src/lib/import/entries.js +2 -15
- package/src/lib/import/marketplace-apps.js +129 -18
- package/src/lib/util/extensionsUidReplace.js +22 -1
- package/src/lib/util/lookupReplaceAssets.js +63 -12
- package/src/lib/util/marketplace-app-helper.js +16 -15
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.2.
|
|
40
|
+
@contentstack/cli-cm-import/1.2.3 linux-x64 node-v16.18.1
|
|
41
41
|
$ csdx --help [COMMAND]
|
|
42
42
|
USAGE
|
|
43
43
|
$ csdx COMMAND
|
|
@@ -68,7 +68,7 @@ OPTIONS
|
|
|
68
68
|
-k, --stack-api-key=stack-api-key API key of the target stack
|
|
69
69
|
-m, --module=module [optional] specific module name
|
|
70
70
|
-y, --yes [optional] Override marketplace prompts
|
|
71
|
-
--import-webhook-status=disable|current [default: disable] Webhook state
|
|
71
|
+
--import-webhook-status=disable|current [default: disable] [optional] Webhook state
|
|
72
72
|
|
|
73
73
|
DESCRIPTION
|
|
74
74
|
...
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.2.
|
|
1
|
+
{"version":"1.2.3","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> --yes"],"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":"[optional] Webhook state","required":false,"options":["disable","current"],"default":"disable"},"yes":{"name":"yes","type":"boolean","char":"y","description":"[optional] Override marketplace prompts","required":false,"allowNo":false}},"args":[]}}}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-import",
|
|
3
3
|
"description": "Contentstack CLI plugin to import content into stack",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.3",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-command": "^1.0.
|
|
9
|
-
"@contentstack/management": "^1.
|
|
10
|
-
"@contentstack/cli-utilities": "^1.0.
|
|
8
|
+
"@contentstack/cli-command": "^1.0.3",
|
|
9
|
+
"@contentstack/management": "^1.6.0",
|
|
10
|
+
"@contentstack/cli-utilities": "^1.0.4",
|
|
11
11
|
"@oclif/command": "^1.8.16",
|
|
12
12
|
"@oclif/config": "^1.18.3",
|
|
13
13
|
"big-json": "^3.2.0",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"eslint-config-oclif": "^3.1.0",
|
|
30
30
|
"globby": "^10.0.2",
|
|
31
31
|
"mocha": "^10.0.0",
|
|
32
|
-
"nyc": "^
|
|
32
|
+
"nyc": "^15.1.0"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=8.0.0"
|
package/src/app.js
CHANGED
|
@@ -137,14 +137,24 @@ let allImport = async (config, types) => {
|
|
|
137
137
|
);
|
|
138
138
|
addlogs(config, 'The log for this is stored at ' + path.join(config.data, 'logs', 'import'), 'success');
|
|
139
139
|
} else {
|
|
140
|
-
addlogs(
|
|
140
|
+
addlogs(
|
|
141
|
+
config,
|
|
142
|
+
chalk.green(
|
|
143
|
+
'Data has been imported to stack ' + (config.destinationStackName || config.target_stack) + ' succesfully!',
|
|
144
|
+
),
|
|
145
|
+
'success',
|
|
146
|
+
);
|
|
141
147
|
addlogs(config, 'The log for this is stored at ' + path.join(config.oldPath, 'logs', 'import'), 'success');
|
|
142
148
|
}
|
|
143
149
|
return true;
|
|
144
150
|
} catch (error) {
|
|
145
151
|
addlogs(
|
|
146
152
|
config,
|
|
147
|
-
chalk.red(
|
|
153
|
+
chalk.red(
|
|
154
|
+
'Failed to migrate stack: ' +
|
|
155
|
+
(config.destinationStackName || config.target_stack) +
|
|
156
|
+
'. Please check error logs for more info',
|
|
157
|
+
),
|
|
148
158
|
'error',
|
|
149
159
|
);
|
|
150
160
|
addlogs(config, formatError(error), 'error');
|
|
@@ -34,7 +34,7 @@ class ImportCommand extends Command {
|
|
|
34
34
|
defaultConfig.data = data;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
defaultConfig.
|
|
37
|
+
defaultConfig.forceStopMarketplaceAppsPrompt = importCommandFlags.yes;
|
|
38
38
|
|
|
39
39
|
if (alias) {
|
|
40
40
|
let managementTokens = self.getToken(alias);
|
|
@@ -173,7 +173,7 @@ ImportCommand.flags = {
|
|
|
173
173
|
parse: printFlagDeprecation(['-B'], ['--branch']),
|
|
174
174
|
}),
|
|
175
175
|
'import-webhook-status': flags.string({
|
|
176
|
-
description: 'Webhook state',
|
|
176
|
+
description: '[optional] Webhook state',
|
|
177
177
|
options: ['disable', 'current'],
|
|
178
178
|
required: false,
|
|
179
179
|
default: 'disable',
|
|
@@ -181,8 +181,8 @@ ImportCommand.flags = {
|
|
|
181
181
|
yes: flags.boolean({
|
|
182
182
|
char: 'y',
|
|
183
183
|
required: false,
|
|
184
|
-
description: '[optional] Override marketplace prompts'
|
|
185
|
-
})
|
|
184
|
+
description: '[optional] Override marketplace prompts',
|
|
185
|
+
}),
|
|
186
186
|
};
|
|
187
187
|
|
|
188
188
|
ImportCommand.aliases = ['cm:import'];
|
package/src/config/default.js
CHANGED
|
@@ -336,6 +336,9 @@ module.exports = {
|
|
|
336
336
|
importConcurrency: 5,
|
|
337
337
|
fetchConcurrency: 5,
|
|
338
338
|
writeConcurrency: 5,
|
|
339
|
+
developerHubBaseUrl: '',
|
|
340
|
+
marketplaceAppEncryptionKey: 'nF2ejRQcTv',
|
|
341
|
+
getEncryptionKeyMaxRetry: 3,
|
|
339
342
|
// useBackedupDir: '',
|
|
340
343
|
// backupConcurrency: 10,
|
|
341
344
|
};
|
|
@@ -154,11 +154,11 @@ class ContentTypesImport {
|
|
|
154
154
|
addlogs(this.importConfig, contentType.uid + ' updated with references', 'success');
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
async updateGlobalFields(
|
|
157
|
+
async updateGlobalFields(uid) {
|
|
158
158
|
const globalField = find(this.globalFields, { uid });
|
|
159
159
|
if (globalField) {
|
|
160
160
|
supress(globalField.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
|
|
161
|
-
let globalFieldObj = this.stackAPIClient.globalField(globalField);
|
|
161
|
+
let globalFieldObj = this.stackAPIClient.globalField(globalField.uid);
|
|
162
162
|
Object.assign(globalFieldObj, cloneDeep(globalField));
|
|
163
163
|
try {
|
|
164
164
|
const globalFieldResponse = await globalFieldObj.update();
|
|
@@ -103,13 +103,17 @@ module.exports = class ImportCustomRoles {
|
|
|
103
103
|
} catch (error) {
|
|
104
104
|
self.fails.push(customRole);
|
|
105
105
|
|
|
106
|
-
if (error && error.errors && error.errors.name) {
|
|
107
|
-
addlogs(self.config, chalk.red(
|
|
106
|
+
if (((error && error.errors && error.errors.name) || '').includes('is not a unique.')) {
|
|
107
|
+
addlogs(self.config, chalk.red(`${customRole.name} role already exists`), 'info');
|
|
108
108
|
} else {
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
if (!(error && error.errors && error.errors.name)) {
|
|
110
|
+
addlogs(self.config, chalk.red(`custom-role: ${customRole.name} already exists`), 'error');
|
|
111
|
+
} else {
|
|
112
|
+
addlogs(self.config, chalk.red(`custom-role: ${customRole.name} failed`), 'error');
|
|
113
|
+
}
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
addlogs(self.config, formatError(error), 'error');
|
|
116
|
+
}
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
addlogs(self.config, chalk.green('Custom-roles have been imported successfully!'), 'success');
|
|
@@ -780,19 +780,6 @@ EntriesImport.prototype = {
|
|
|
780
780
|
}
|
|
781
781
|
}
|
|
782
782
|
|
|
783
|
-
if (flag.jsonRte) {
|
|
784
|
-
self.ctJsonRte.push(uid);
|
|
785
|
-
if (flag.jsonRteEmbeddedEntries) {
|
|
786
|
-
self.ctJsonRteWithEntryRefs.push(uid);
|
|
787
|
-
// pushing ct uid to refSchemas, because
|
|
788
|
-
// repostEntries uses refSchemas content types for
|
|
789
|
-
// reposting entries
|
|
790
|
-
if (self.refSchemas.indexOf(uid) === -1) {
|
|
791
|
-
self.refSchemas.push(uid);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
783
|
// Replace extensions with new UID
|
|
797
784
|
extension_suppress(contentTypeSchema.schema, config.preserveStackVersion, self.installedExtensions);
|
|
798
785
|
}
|
|
@@ -1356,8 +1343,8 @@ EntriesImport.prototype = {
|
|
|
1356
1343
|
|
|
1357
1344
|
if (entryRefs.length > 0) {
|
|
1358
1345
|
entryRefs.forEach((entryRef) => {
|
|
1359
|
-
if (!_.isEmpty(entry[
|
|
1360
|
-
entry[
|
|
1346
|
+
if (!_.isEmpty(entry[element.uid]) && entry[element.uid].children) {
|
|
1347
|
+
entry[element.uid].children.splice(entryRef.index, 0, entryRef.value);
|
|
1361
1348
|
}
|
|
1362
1349
|
});
|
|
1363
1350
|
}
|
|
@@ -30,7 +30,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
30
30
|
|
|
31
31
|
async start() {
|
|
32
32
|
this.client = sdk.Client(this.config);
|
|
33
|
-
this.developerHubBaseUrl = await getDeveloperHubUrl();
|
|
33
|
+
this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl());
|
|
34
34
|
this.marketplaceAppFolderPath = path.resolve(this.config.data, this.marketplaceAppConfig.dirName);
|
|
35
35
|
this.marketplaceApps = _.uniqBy(
|
|
36
36
|
readFileSync(path.resolve(this.marketplaceAppFolderPath, this.marketplaceAppConfig.fileName)),
|
|
@@ -74,18 +74,68 @@ module.exports = class ImportMarketplaceApps {
|
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
async getEncryptionKeyAndValidate(defaultValue, retry = 1) {
|
|
78
|
+
const appConfig =
|
|
79
|
+
_.find(this.marketplaceApps, 'configuration') ||
|
|
80
|
+
_.find(this.marketplaceApps, 'server_configuration.configuration');
|
|
81
|
+
|
|
82
|
+
if (appConfig) {
|
|
83
|
+
const encryptionKey = await cliux.inquire({
|
|
84
|
+
type: 'input',
|
|
85
|
+
name: 'name',
|
|
86
|
+
default: defaultValue,
|
|
87
|
+
validate: (key) => {
|
|
88
|
+
if (!key) return "Encryption key can't be empty.";
|
|
89
|
+
|
|
90
|
+
return true;
|
|
91
|
+
},
|
|
92
|
+
message: 'Enter marketplace app configurations encryption key',
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const nodeCrypto = new NodeCrypto({ encryptionKey });
|
|
97
|
+
nodeCrypto.decrypt(appConfig.configuration || appConfig.server_configuration);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (retry < this.config.getEncryptionKeyMaxRetry && error.code === 'ERR_OSSL_EVP_BAD_DECRYPT') {
|
|
100
|
+
cliux.print('Provided encryption key is not valid or your data might be corrupted.!', { color: 'red' });
|
|
101
|
+
// NOTE max retry limit is 3
|
|
102
|
+
return this.getEncryptionKeyAndValidate(encryptionKey, retry + 1);
|
|
103
|
+
} else {
|
|
104
|
+
cliux.print('Maximum retry limit exceeded. Closing the process, please try again.!', { color: 'red' });
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return encryptionKey;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return defaultValue;
|
|
113
|
+
}
|
|
114
|
+
|
|
77
115
|
/**
|
|
78
116
|
* @method handleInstallationProcess
|
|
79
117
|
* @returns {Promise<void>}
|
|
80
118
|
*/
|
|
81
119
|
handleInstallationProcess = async () => {
|
|
82
120
|
const self = this;
|
|
121
|
+
const cryptoArgs = {};
|
|
83
122
|
const headers = {
|
|
84
123
|
authtoken: self.config.auth_token,
|
|
85
124
|
organization_uid: self.config.org_uid,
|
|
86
125
|
};
|
|
126
|
+
|
|
127
|
+
if (self.config.marketplaceAppEncryptionKey) {
|
|
128
|
+
cryptoArgs['encryptionKey'] = self.config.marketplaceAppEncryptionKey;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (self.config.forceStopMarketplaceAppsPrompt) {
|
|
132
|
+
cryptoArgs['encryptionKey'] = self.config.marketplaceAppEncryptionKey;
|
|
133
|
+
} else {
|
|
134
|
+
cryptoArgs['encryptionKey'] = await self.getEncryptionKeyAndValidate(self.config.marketplaceAppEncryptionKey);
|
|
135
|
+
}
|
|
136
|
+
|
|
87
137
|
const httpClient = new HttpClient().headers(headers);
|
|
88
|
-
const nodeCrypto = new NodeCrypto();
|
|
138
|
+
const nodeCrypto = new NodeCrypto(cryptoArgs);
|
|
89
139
|
|
|
90
140
|
// NOTE install all private apps which is not available for stack.
|
|
91
141
|
await this.handleAllPrivateAppsCreationProcess({ httpClient });
|
|
@@ -148,7 +198,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
148
198
|
(app) => !_.includes(_.map(installedDeveloperHubApps, 'uid'), app.app_uid),
|
|
149
199
|
);
|
|
150
200
|
|
|
151
|
-
if (!_.isEmpty(listOfNotInstalledPrivateApps) && !self.config.
|
|
201
|
+
if (!_.isEmpty(listOfNotInstalledPrivateApps) && !self.config.forceStopMarketplaceAppsPrompt) {
|
|
152
202
|
const confirmation = await cliux.confirm(
|
|
153
203
|
chalk.yellow(
|
|
154
204
|
`WARNING!!! The listed apps are private apps that are not available in the destination stack: \n\n${_.map(
|
|
@@ -166,7 +216,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
166
216
|
);
|
|
167
217
|
|
|
168
218
|
if (continueProcess) {
|
|
169
|
-
return resolve();
|
|
219
|
+
return Promise.resolve();
|
|
170
220
|
} else {
|
|
171
221
|
process.exit();
|
|
172
222
|
}
|
|
@@ -197,18 +247,55 @@ module.exports = class ImportMarketplaceApps {
|
|
|
197
247
|
});
|
|
198
248
|
};
|
|
199
249
|
|
|
250
|
+
/**
|
|
251
|
+
* @method updateNameInManifestUILocations
|
|
252
|
+
* @param {Array<Object>} locations
|
|
253
|
+
* @returns {Array<Object>}
|
|
254
|
+
*/
|
|
255
|
+
updateNameInManifestUILocations = (locations, appSuffix = 1) => {
|
|
256
|
+
return _.map(locations, (location) => {
|
|
257
|
+
if (location.meta) {
|
|
258
|
+
location.meta = _.map(location.meta, (meta) => {
|
|
259
|
+
meta.name = `${_.first(_.split(meta.name, '◈'))}◈${appSuffix}`;
|
|
260
|
+
|
|
261
|
+
return meta;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return location;
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
getAppName = (name, appSuffix = 1) => {
|
|
270
|
+
if (name.length >= 19) name = name.slice(0, 18);
|
|
271
|
+
|
|
272
|
+
name = `${_.first(_.split(name, '◈'))}◈${appSuffix}`;
|
|
273
|
+
|
|
274
|
+
return name;
|
|
275
|
+
};
|
|
276
|
+
|
|
200
277
|
/**
|
|
201
278
|
* @method createAllPrivateAppsInDeveloperHub
|
|
202
279
|
* @param {Object} options
|
|
203
280
|
* @returns {Promise<void>}
|
|
204
281
|
*/
|
|
205
|
-
createAllPrivateAppsInDeveloperHub = async (options, uidCleaned = false) => {
|
|
282
|
+
createAllPrivateAppsInDeveloperHub = async (options, uidCleaned = false, appSuffix = 1, isRecursive = false) => {
|
|
206
283
|
const self = this;
|
|
207
284
|
const { app, httpClient } = options;
|
|
208
285
|
|
|
209
286
|
return new Promise((resolve) => {
|
|
210
287
|
if (!uidCleaned && app.manifest.ui_location && !_.isEmpty(app.manifest.ui_location.locations)) {
|
|
211
288
|
app.manifest.ui_location.locations = this.removeUidFromManifestUILocations(app.manifest.ui_location.locations);
|
|
289
|
+
} else if (isRecursive && app.manifest.ui_location && !_.isEmpty(app.manifest.ui_location.locations)) {
|
|
290
|
+
app.manifest.ui_location.locations = this.updateNameInManifestUILocations(
|
|
291
|
+
app.manifest.ui_location.locations,
|
|
292
|
+
appSuffix - 1 || 1,
|
|
293
|
+
isRecursive,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (app.manifest.name > 20) {
|
|
298
|
+
app.manifest.name = app.manifest.name.slice(0, 20);
|
|
212
299
|
}
|
|
213
300
|
|
|
214
301
|
httpClient
|
|
@@ -221,20 +308,23 @@ module.exports = class ImportMarketplaceApps {
|
|
|
221
308
|
log(self.config, message, 'error');
|
|
222
309
|
|
|
223
310
|
if (_.toLower(error) === 'conflict') {
|
|
224
|
-
const appName = self.config.
|
|
225
|
-
? self.getAppName(app.manifest.name)
|
|
311
|
+
const appName = self.config.forceStopMarketplaceAppsPrompt
|
|
312
|
+
? self.getAppName(app.manifest.name, appSuffix)
|
|
226
313
|
: await cliux.inquire({
|
|
227
314
|
type: 'input',
|
|
228
315
|
name: 'name',
|
|
229
|
-
default:
|
|
316
|
+
default: self.getAppName(app.manifest.name, appSuffix),
|
|
230
317
|
validate: this.validateAppName,
|
|
231
318
|
message: `${message}. Enter a new name to create an app.?`,
|
|
232
319
|
});
|
|
233
320
|
app.manifest.name = appName;
|
|
234
321
|
|
|
235
|
-
await self
|
|
322
|
+
await self
|
|
323
|
+
.createAllPrivateAppsInDeveloperHub({ app, httpClient }, true, appSuffix + 1, true)
|
|
324
|
+
.then(resolve)
|
|
325
|
+
.catch(resolve);
|
|
236
326
|
} else {
|
|
237
|
-
if (self.config.
|
|
327
|
+
if (self.config.forceStopMarketplaceAppsPrompt) return resolve();
|
|
238
328
|
|
|
239
329
|
const confirmation = await cliux.confirm(
|
|
240
330
|
chalk.yellow(
|
|
@@ -251,7 +341,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
251
341
|
} else if (data) {
|
|
252
342
|
// NOTE new app installation
|
|
253
343
|
log(self.config, `${name} app created successfully.!`, 'success');
|
|
254
|
-
this.updatePrivateAppUid(app, data, app.manifest
|
|
344
|
+
this.updatePrivateAppUid(app, data, app.manifest);
|
|
255
345
|
}
|
|
256
346
|
|
|
257
347
|
resolve();
|
|
@@ -273,7 +363,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
273
363
|
* @param {Object} app
|
|
274
364
|
* @param {Object} data
|
|
275
365
|
*/
|
|
276
|
-
updatePrivateAppUid = (app, data,
|
|
366
|
+
updatePrivateAppUid = (app, data, manifest) => {
|
|
277
367
|
const self = this;
|
|
278
368
|
const allMarketplaceApps = readFileSync(
|
|
279
369
|
path.resolve(self.marketplaceAppFolderPath, self.marketplaceAppConfig.fileName),
|
|
@@ -283,6 +373,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
283
373
|
if (index > -1) {
|
|
284
374
|
allMarketplaceApps[index] = {
|
|
285
375
|
...allMarketplaceApps[index],
|
|
376
|
+
manifest,
|
|
286
377
|
title: data.name,
|
|
287
378
|
app_uid: data.uid,
|
|
288
379
|
old_title: allMarketplaceApps[index].title,
|
|
@@ -292,9 +383,6 @@ module.exports = class ImportMarketplaceApps {
|
|
|
292
383
|
],
|
|
293
384
|
};
|
|
294
385
|
|
|
295
|
-
// NOTE Update app name
|
|
296
|
-
allMarketplaceApps[index].manifest.name = appName;
|
|
297
|
-
|
|
298
386
|
writeFile(path.join(self.marketplaceAppFolderPath, self.marketplaceAppConfig.fileName), allMarketplaceApps);
|
|
299
387
|
}
|
|
300
388
|
};
|
|
@@ -331,7 +419,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
331
419
|
{ color: 'yellow' },
|
|
332
420
|
);
|
|
333
421
|
|
|
334
|
-
const configOption = self.config.
|
|
422
|
+
const configOption = self.config.forceStopMarketplaceAppsPrompt
|
|
335
423
|
? 'Update it with the new configuration.'
|
|
336
424
|
: await cliux.inquire({
|
|
337
425
|
choices: [
|
|
@@ -356,7 +444,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
356
444
|
}
|
|
357
445
|
}
|
|
358
446
|
} else {
|
|
359
|
-
if (!self.config.
|
|
447
|
+
if (!self.config.forceStopMarketplaceAppsPrompt) {
|
|
360
448
|
cliux.print(`WARNING!!! ${message || error_message}`, { color: 'yellow' });
|
|
361
449
|
const confirmation = await cliux.confirm(
|
|
362
450
|
chalk.yellow(
|
|
@@ -393,6 +481,27 @@ module.exports = class ImportMarketplaceApps {
|
|
|
393
481
|
});
|
|
394
482
|
};
|
|
395
483
|
|
|
484
|
+
updateConfigData(config) {
|
|
485
|
+
const configKeyMapper = {};
|
|
486
|
+
const serverConfigKeyMapper = {
|
|
487
|
+
cmsApiKey: this.config.target_stack,
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
if (!_.isEmpty(config.configuration) && !_.isEmpty(configKeyMapper)) {
|
|
491
|
+
_.forEach(_.keys(configKeyMapper), (key) => {
|
|
492
|
+
config.configuration[key] = configKeyMapper[key];
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (!_.isEmpty(config.server_configuration) && !_.isEmpty(serverConfigKeyMapper)) {
|
|
497
|
+
_.forEach(_.keys(serverConfigKeyMapper), (key) => {
|
|
498
|
+
config.server_configuration[key] = serverConfigKeyMapper[key];
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return config;
|
|
503
|
+
}
|
|
504
|
+
|
|
396
505
|
/**
|
|
397
506
|
* @method updateAppsConfig
|
|
398
507
|
* @param {Object<{ data, app, httpClient, nodeCrypto }>} param
|
|
@@ -401,7 +510,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
401
510
|
updateAppsConfig = ({ data, app, httpClient, nodeCrypto }) => {
|
|
402
511
|
const self = this;
|
|
403
512
|
return new Promise((resolve, reject) => {
|
|
404
|
-
|
|
513
|
+
let payload = {};
|
|
405
514
|
const { title, configuration, server_configuration } = app;
|
|
406
515
|
|
|
407
516
|
if (!_.isEmpty(configuration)) {
|
|
@@ -411,6 +520,8 @@ module.exports = class ImportMarketplaceApps {
|
|
|
411
520
|
payload['server_configuration'] = nodeCrypto.decrypt(server_configuration);
|
|
412
521
|
}
|
|
413
522
|
|
|
523
|
+
payload = self.updateConfigData(payload);
|
|
524
|
+
|
|
414
525
|
if (_.isEmpty(data) || _.isEmpty(payload) || !data.installation_uid) {
|
|
415
526
|
resolve();
|
|
416
527
|
} else {
|
|
@@ -55,7 +55,28 @@ let extension_uid_Replace = (module.exports = function (schema, preserveStackVer
|
|
|
55
55
|
const oldExt = _.find(marketplaceApps, { uid: schema[i].extension_uid });
|
|
56
56
|
|
|
57
57
|
if (oldExt) {
|
|
58
|
-
|
|
58
|
+
let ext = _.find(installedExtensions, (ext) => {
|
|
59
|
+
const { type, title, app_uid } = ext;
|
|
60
|
+
|
|
61
|
+
if (type === 'field' && app_uid === oldExt.app_uid) {
|
|
62
|
+
const titles = [
|
|
63
|
+
...(oldExt.manifest
|
|
64
|
+
? _.map(
|
|
65
|
+
_.map(
|
|
66
|
+
oldExt.manifest && oldExt.manifest.ui_location && oldExt.manifest.ui_location.locations,
|
|
67
|
+
'meta',
|
|
68
|
+
).flat(),
|
|
69
|
+
'name',
|
|
70
|
+
)
|
|
71
|
+
: []),
|
|
72
|
+
oldExt.title,
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
return _.includes(titles, title);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return false;
|
|
79
|
+
});
|
|
59
80
|
|
|
60
81
|
if (ext) {
|
|
61
82
|
schema[i].extension_uid = ext.uid;
|
|
@@ -80,10 +80,27 @@ module.exports = function (data, mappedAssetUids, mappedAssetUrls, assetUidMappe
|
|
|
80
80
|
const oldExt = _.find(marketplaceApps, { uid: schema[i].extension_uid });
|
|
81
81
|
|
|
82
82
|
if (oldExt) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
app_uid
|
|
83
|
+
let ext = _.find(installedExtensions, (ext) => {
|
|
84
|
+
const { type, title, app_uid } = ext;
|
|
85
|
+
|
|
86
|
+
if (type === 'field' && app_uid === oldExt.app_uid) {
|
|
87
|
+
const titles = [
|
|
88
|
+
...(oldExt.manifest
|
|
89
|
+
? _.map(
|
|
90
|
+
_.map(
|
|
91
|
+
oldExt.manifest && oldExt.manifest.ui_location && oldExt.manifest.ui_location.locations,
|
|
92
|
+
'meta',
|
|
93
|
+
).flat(),
|
|
94
|
+
'name',
|
|
95
|
+
)
|
|
96
|
+
: []),
|
|
97
|
+
oldExt.title,
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
return _.includes(titles, title);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return false;
|
|
87
104
|
});
|
|
88
105
|
|
|
89
106
|
if (ext) {
|
|
@@ -104,10 +121,27 @@ module.exports = function (data, mappedAssetUids, mappedAssetUrls, assetUidMappe
|
|
|
104
121
|
const oldExt = _.find(marketplaceApps, { uid: row.extension_uid });
|
|
105
122
|
|
|
106
123
|
if (oldExt) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
app_uid
|
|
124
|
+
let ext = _.find(installedExtensions, (ext) => {
|
|
125
|
+
const { type, title, app_uid } = ext;
|
|
126
|
+
|
|
127
|
+
if (type === 'field' && app_uid === oldExt.app_uid) {
|
|
128
|
+
const titles = [
|
|
129
|
+
...(oldExt.manifest
|
|
130
|
+
? _.map(
|
|
131
|
+
_.map(
|
|
132
|
+
oldExt.manifest && oldExt.manifest.ui_location && oldExt.manifest.ui_location.locations,
|
|
133
|
+
'meta',
|
|
134
|
+
).flat(),
|
|
135
|
+
'name',
|
|
136
|
+
)
|
|
137
|
+
: []),
|
|
138
|
+
oldExt.title,
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
return _.includes(titles, title);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return false;
|
|
111
145
|
});
|
|
112
146
|
|
|
113
147
|
if (ext) {
|
|
@@ -121,10 +155,27 @@ module.exports = function (data, mappedAssetUids, mappedAssetUrls, assetUidMappe
|
|
|
121
155
|
const oldExt = _.find(marketplaceApps, { uid: entryObj[row.uid].metadata.extension_uid });
|
|
122
156
|
|
|
123
157
|
if (oldExt) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
app_uid
|
|
158
|
+
let ext = _.find(installedExtensions, (ext) => {
|
|
159
|
+
const { type, title, app_uid } = ext;
|
|
160
|
+
|
|
161
|
+
if (type === 'field' && app_uid === oldExt.app_uid) {
|
|
162
|
+
const titles = [
|
|
163
|
+
...(oldExt.manifest
|
|
164
|
+
? _.map(
|
|
165
|
+
_.map(
|
|
166
|
+
oldExt.manifest && oldExt.manifest.ui_location && oldExt.manifest.ui_location.locations,
|
|
167
|
+
'meta',
|
|
168
|
+
).flat(),
|
|
169
|
+
'name',
|
|
170
|
+
)
|
|
171
|
+
: []),
|
|
172
|
+
oldExt.title,
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
return _.includes(titles, title);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return false;
|
|
128
179
|
});
|
|
129
180
|
|
|
130
181
|
if (ext) {
|
|
@@ -3,13 +3,13 @@ const sdk = require('./contentstack-management-sdk');
|
|
|
3
3
|
const { cliux, HttpClient, configHandler } = require('@contentstack/cli-utilities');
|
|
4
4
|
|
|
5
5
|
const getInstalledExtensions = (config) => {
|
|
6
|
-
const client = sdk.Client(config)
|
|
6
|
+
const client = sdk.Client(config);
|
|
7
7
|
|
|
8
8
|
return new Promise((resolve, reject) => {
|
|
9
9
|
const queryRequestOptions = {
|
|
10
|
-
include_marketplace_extensions: true
|
|
11
|
-
}
|
|
12
|
-
const { target_stack: api_key, management_token, auth_token } = config || {}
|
|
10
|
+
include_marketplace_extensions: true,
|
|
11
|
+
};
|
|
12
|
+
const { target_stack: api_key, management_token, auth_token } = config || {};
|
|
13
13
|
|
|
14
14
|
if (api_key && management_token) {
|
|
15
15
|
return client
|
|
@@ -18,21 +18,22 @@ const getInstalledExtensions = (config) => {
|
|
|
18
18
|
.query(queryRequestOptions)
|
|
19
19
|
.find()
|
|
20
20
|
.then(({ items }) => resolve(items))
|
|
21
|
-
.catch(reject)
|
|
21
|
+
.catch(reject);
|
|
22
22
|
} else if (api_key && auth_token) {
|
|
23
23
|
const { cma } = configHandler.get('region') || {};
|
|
24
24
|
const headers = {
|
|
25
25
|
api_key,
|
|
26
|
-
authtoken: auth_token
|
|
27
|
-
}
|
|
26
|
+
authtoken: auth_token,
|
|
27
|
+
};
|
|
28
28
|
const httpClient = new HttpClient().headers(headers);
|
|
29
|
-
httpClient
|
|
30
|
-
.
|
|
29
|
+
httpClient
|
|
30
|
+
.get(`${cma}/v3/extensions/?include_marketplace_extensions=true`)
|
|
31
|
+
.then(({ data: { extensions } }) => resolve(extensions));
|
|
31
32
|
} else {
|
|
32
|
-
resolve([])
|
|
33
|
+
resolve([]);
|
|
33
34
|
}
|
|
34
|
-
})
|
|
35
|
-
}
|
|
35
|
+
});
|
|
36
|
+
};
|
|
36
37
|
|
|
37
38
|
const getDeveloperHubUrl = async () => {
|
|
38
39
|
const { cma, name } = configHandler.get('region') || {};
|
|
@@ -47,11 +48,11 @@ const getDeveloperHubUrl = async () => {
|
|
|
47
48
|
|
|
48
49
|
return true;
|
|
49
50
|
},
|
|
50
|
-
message: `Enter the developer-hub base URL for the ${name} region
|
|
51
|
+
message: `Enter the developer-hub base URL for the ${name} region -`,
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
return developerHubBaseUrl.startsWith('http') ? developerHubBaseUrl : `https://${developerHubBaseUrl}`;
|
|
55
|
-
}
|
|
56
|
+
};
|
|
56
57
|
|
|
57
|
-
module.exports = { getInstalledExtensions, getDeveloperHubUrl }
|
|
58
|
+
module.exports = { getInstalledExtensions, getDeveloperHubUrl };
|