@contentstack/cli-cm-import 1.16.6 → 1.17.1

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
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import
47
47
  $ csdx COMMAND
48
48
  running command...
49
49
  $ csdx (--version)
50
- @contentstack/cli-cm-import/1.16.6 linux-x64 node-v18.20.4
50
+ @contentstack/cli-cm-import/1.17.1 linux-x64 node-v18.20.4
51
51
  $ csdx --help [COMMAND]
52
52
  USAGE
53
53
  $ csdx COMMAND
@@ -71,21 +71,22 @@ USAGE
71
71
  [--branch <value>] [--import-webhook-status disable|current]
72
72
 
73
73
  FLAGS
74
- -B, --branch=<value> [optional] branch name
75
- -a, --alias=<value> alias of the management token
76
- -b, --backup-dir=<value> [optional] backup directory name when using specific module
77
- -c, --config=<value> [optional] path of config file
78
- -d, --data-dir=<value> path and location where data is stored
79
- -k, --stack-api-key=<value> API key of the target stack
80
- -m, --module=<value> [optional] specific module name
81
- -y, --yes [optional] Override marketplace prompts
82
- --exclude-global-modules Excludes the branch-independent module from the import operation
83
- --import-webhook-status=<option> [default: disable] [optional] Webhook state
84
- <options: disable|current>
85
- --replace-existing Replaces the existing module in the target stack.
86
- --skip-app-recreation [optional] Skip private apps recreation if already exist
87
- --skip-audit Skips the audit fix.
88
- --skip-existing Skips the module exists warning messages.
74
+ -B, --branch=<value> [optional] branch name
75
+ -a, --alias=<value> alias of the management token
76
+ -b, --backup-dir=<value> [optional] backup directory name when using specific module
77
+ -c, --config=<value> [optional] path of config file
78
+ -d, --data-dir=<value> path and location where data is stored
79
+ -k, --stack-api-key=<value> API key of the target stack
80
+ -m, --module=<value> [optional] specific module name
81
+ -y, --yes [optional] Override marketplace prompts
82
+ --exclude-global-modules Excludes the branch-independent module from the import operation
83
+ --import-webhook-status=<option> [default: disable] [optional] Webhook state
84
+ <options: disable|current>
85
+ --personalize-project-name=<value> Personalize project name.
86
+ --replace-existing Replaces the existing module in the target stack.
87
+ --skip-app-recreation [optional] Skip private apps recreation if already exist
88
+ --skip-audit Skips the audit fix.
89
+ --skip-existing Skips the module exists warning messages.
89
90
 
90
91
  DESCRIPTION
91
92
  Import content from a stack
@@ -121,21 +122,22 @@ USAGE
121
122
  [--branch <value>] [--import-webhook-status disable|current]
122
123
 
123
124
  FLAGS
124
- -B, --branch=<value> [optional] branch name
125
- -a, --alias=<value> alias of the management token
126
- -b, --backup-dir=<value> [optional] backup directory name when using specific module
127
- -c, --config=<value> [optional] path of config file
128
- -d, --data-dir=<value> path and location where data is stored
129
- -k, --stack-api-key=<value> API key of the target stack
130
- -m, --module=<value> [optional] specific module name
131
- -y, --yes [optional] Override marketplace prompts
132
- --exclude-global-modules Excludes the branch-independent module from the import operation
133
- --import-webhook-status=<option> [default: disable] [optional] Webhook state
134
- <options: disable|current>
135
- --replace-existing Replaces the existing module in the target stack.
136
- --skip-app-recreation [optional] Skip private apps recreation if already exist
137
- --skip-audit Skips the audit fix.
138
- --skip-existing Skips the module exists warning messages.
125
+ -B, --branch=<value> [optional] branch name
126
+ -a, --alias=<value> alias of the management token
127
+ -b, --backup-dir=<value> [optional] backup directory name when using specific module
128
+ -c, --config=<value> [optional] path of config file
129
+ -d, --data-dir=<value> path and location where data is stored
130
+ -k, --stack-api-key=<value> API key of the target stack
131
+ -m, --module=<value> [optional] specific module name
132
+ -y, --yes [optional] Override marketplace prompts
133
+ --exclude-global-modules Excludes the branch-independent module from the import operation
134
+ --import-webhook-status=<option> [default: disable] [optional] Webhook state
135
+ <options: disable|current>
136
+ --personalize-project-name=<value> Personalize project name.
137
+ --replace-existing Replaces the existing module in the target stack.
138
+ --skip-app-recreation [optional] Skip private apps recreation if already exist
139
+ --skip-audit Skips the audit fix.
140
+ --skip-existing Skips the module exists warning messages.
139
141
 
140
142
  DESCRIPTION
141
143
  Import content from a stack
@@ -17,6 +17,7 @@ class ImportCommand extends cli_command_1.Command {
17
17
  let importConfig = await (0, utils_1.setupImportConfig)(flags);
18
18
  // Note setting host to create cma client
19
19
  importConfig.host = this.cmaHost;
20
+ importConfig.region = this.region;
20
21
  importConfig.developerHubBaseUrl = this.developerHubUrl;
21
22
  backupDir = importConfig.cliLogsPath || importConfig.backupDir;
22
23
  const managementAPIClient = await (0, cli_utilities_1.managementSDKClient)(importConfig);
@@ -127,12 +128,16 @@ ImportCommand.flags = {
127
128
  default: false,
128
129
  description: 'Skips the module exists warning messages.',
129
130
  }),
131
+ 'personalize-project-name': cli_utilities_1.flags.string({
132
+ required: false,
133
+ description: 'Personalize project name.',
134
+ }),
130
135
  'skip-audit': cli_utilities_1.flags.boolean({
131
136
  description: 'Skips the audit fix.',
132
137
  }),
133
138
  'exclude-global-modules': cli_utilities_1.flags.boolean({
134
139
  description: 'Excludes the branch-independent module from the import operation',
135
- default: false
140
+ default: false,
136
141
  }),
137
142
  };
138
143
  ImportCommand.aliases = ['cm:import'];
@@ -33,9 +33,11 @@ const config = {
33
33
  'marketplace-apps',
34
34
  'global-fields',
35
35
  'content-types',
36
+ 'personalization',
36
37
  'custom-roles',
37
38
  'workflows',
38
39
  'entries',
40
+ 'variant-entries',
39
41
  'labels',
40
42
  'webhooks',
41
43
  ],
@@ -149,6 +151,45 @@ const config = {
149
151
  dirName: 'taxonomies',
150
152
  fileName: 'taxonomies.json',
151
153
  },
154
+ personalization: {
155
+ baseURL: {
156
+ NA: 'https://personalization-api.contentstack.com',
157
+ },
158
+ importData: true,
159
+ dirName: 'personalization',
160
+ importOrder: ['attributes', 'audiences', 'events', 'experiences'],
161
+ project_id: '',
162
+ projects: {
163
+ dirName: 'projects',
164
+ fileName: 'projects.json',
165
+ },
166
+ attributes: {
167
+ dirName: 'attributes',
168
+ fileName: 'attributes.json',
169
+ },
170
+ audiences: {
171
+ dirName: 'audiences',
172
+ fileName: 'audiences.json',
173
+ },
174
+ events: {
175
+ dirName: 'events',
176
+ fileName: 'events.json',
177
+ },
178
+ experiences: {
179
+ dirName: 'experiences',
180
+ fileName: 'experiences.json',
181
+ thresholdTimer: 60000,
182
+ checkIntervalDuration: 10000,
183
+ },
184
+ },
185
+ variantEntry: {
186
+ dirName: 'variants',
187
+ fileName: 'index.json',
188
+ apiConcurrency: 5,
189
+ query: {
190
+ locale: 'en-us',
191
+ },
192
+ },
152
193
  },
153
194
  languagesCode: [
154
195
  'af-za',
@@ -19,8 +19,9 @@ class ModuleImporter {
19
19
  }
20
20
  async start() {
21
21
  if (!this.importConfig.management_token) {
22
- const stackName = await this.stackAPIClient.fetch();
23
- this.importConfig.stackName = stackName.name;
22
+ const stackDetails = await this.stackAPIClient.fetch();
23
+ this.importConfig.stackName = stackDetails.name;
24
+ this.importConfig.org_uid = stackDetails.org_uid;
24
25
  }
25
26
  if (this.importConfig.branchName) {
26
27
  await (0, utils_1.validateBranch)(this.stackAPIClient, this.importConfig, this.importConfig.branchName);
@@ -39,7 +40,7 @@ class ModuleImporter {
39
40
  // NOTE audit and fix the import content.
40
41
  if (!this.importConfig.skipAudit &&
41
42
  (!this.importConfig.moduleName ||
42
- ['content-types', 'global-fields', 'entries', 'extensions', 'workflows'].includes(this.importConfig.moduleName))) {
43
+ ['content-types', 'global-fields', 'entries', 'extensions', 'workflows', 'custom-roles'].includes(this.importConfig.moduleName))) {
43
44
  if (!(await this.auditImportData(logger))) {
44
45
  return { noSuccessMsg: true };
45
46
  }
@@ -118,7 +119,7 @@ class ModuleImporter {
118
119
  }
119
120
  else if (this.importConfig.modules.types.length) {
120
121
  this.importConfig.modules.types
121
- .filter((val) => ['content-types', 'global-fields', 'entries', 'extensions', 'workflows'].includes(val))
122
+ .filter((val) => ['content-types', 'global-fields', 'entries', 'extensions', 'workflows', 'custom-roles'].includes(val))
122
123
  .forEach((val) => {
123
124
  args.push('--modules', val);
124
125
  });
@@ -44,6 +44,7 @@ class ContentTypesImport extends base_class_1.default {
44
44
  this.extPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'extensions', 'pending_extensions.js');
45
45
  }
46
46
  async start() {
47
+ var _a;
47
48
  /**
48
49
  * read content type, check if it is necessary to read the entire dir
49
50
  * Seed content types
@@ -60,11 +61,13 @@ class ContentTypesImport extends base_class_1.default {
60
61
  this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
61
62
  this.taxonomies = utils_1.fsUtil.readFile(this.taxonomiesPath);
62
63
  await this.seedCTs();
64
+ if ((_a = this.createdCTs) === null || _a === void 0 ? void 0 : _a.length)
65
+ utils_1.fsUtil.writeFile(this.cTsSuccessPath, this.createdCTs);
63
66
  (0, utils_1.log)(this.importConfig, 'Created content types', 'success');
64
67
  await this.updateCTs();
65
68
  (0, utils_1.log)(this.importConfig, 'Updated content types with references', 'success');
66
69
  if (this.fieldRules.length > 0) {
67
- await utils_1.fsUtil.writeFile(path.join(this.cTsFolderPath, 'field_rules_uid.json'), this.fieldRules);
70
+ utils_1.fsUtil.writeFile(path.join(this.cTsFolderPath, 'field_rules_uid.json'), this.fieldRules);
68
71
  }
69
72
  (0, utils_1.log)(this.importConfig, 'Updating the extensions...', 'success');
70
73
  await this.updatePendingExtensions();
@@ -79,6 +82,7 @@ class ContentTypesImport extends base_class_1.default {
79
82
  }
80
83
  async seedCTs() {
81
84
  const onSuccess = ({ response: globalField, apiData: { content_type: { uid = null } = {} } = {} }) => {
85
+ this.createdCTs.push(uid);
82
86
  (0, utils_1.log)(this.importConfig, `${uid} content type seeded`, 'info');
83
87
  };
84
88
  const onReject = ({ error, apiData: { content_type: { uid = null } = {} } = {} }) => {
@@ -1,8 +1,3 @@
1
- /*!
2
- * Contentstack Import
3
- * Copyright (c) 2024 Contentstack LLC
4
- * MIT Licensed
5
- */
6
1
  import { ModuleClassParams } from '../../types';
7
2
  import BaseClass, { ApiOptions } from './base-class';
8
3
  export default class EntriesImport extends BaseClass {
@@ -38,8 +33,18 @@ export default class EntriesImport extends BaseClass {
38
33
  taxonomies: Record<string, unknown>;
39
34
  rteCTs: any;
40
35
  rteCTsWithRef: any;
36
+ entriesForVariant: {
37
+ content_type: string;
38
+ locale: string;
39
+ entry_uid: string;
40
+ }[];
41
41
  constructor({ importConfig, stackAPIClient }: ModuleClassParams);
42
42
  start(): Promise<any>;
43
+ /**
44
+ * The function `createEntryDataForVariantEntry` writes the `entriesForVariant` data to a JSON file
45
+ * named `data-for-variant-entry.json`.
46
+ */
47
+ createEntryDataForVariantEntry(): void;
43
48
  disableMandatoryCTReferences(): Promise<void>;
44
49
  /**
45
50
  * @method serializeUpdateCTs
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
2
4
  /* eslint-disable no-prototype-builtins */
3
5
  /*!
4
6
  * Contentstack Import
5
7
  * Copyright (c) 2024 Contentstack LLC
6
8
  * MIT Licensed
7
9
  */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const tslib_1 = require("tslib");
10
10
  const path = tslib_1.__importStar(require("path"));
11
+ const fs_1 = require("fs");
11
12
  const lodash_1 = require("lodash");
12
13
  const cli_utilities_1 = require("@contentstack/cli-utilities");
13
14
  const utils_1 = require("../../utils");
@@ -15,6 +16,7 @@ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
15
16
  class EntriesImport extends base_class_1.default {
16
17
  constructor({ importConfig, stackAPIClient }) {
17
18
  super({ importConfig, stackAPIClient });
19
+ this.entriesForVariant = [];
18
20
  this.assetUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'assets', 'uid-mapping.json');
19
21
  this.assetUrlMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'assets', 'url-mapping.json');
20
22
  this.entriesMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'entries');
@@ -107,12 +109,24 @@ class EntriesImport extends base_class_1.default {
107
109
  }
108
110
  (0, utils_1.log)(this.importConfig, 'All the entries have been published successfully', 'success');
109
111
  }
112
+ this.createEntryDataForVariantEntry();
110
113
  }
111
114
  catch (error) {
115
+ this.createEntryDataForVariantEntry();
112
116
  (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
113
117
  throw new Error('Error while importing entries');
114
118
  }
115
119
  }
120
+ /**
121
+ * The function `createEntryDataForVariantEntry` writes the `entriesForVariant` data to a JSON file
122
+ * named `data-for-variant-entry.json`.
123
+ */
124
+ createEntryDataForVariantEntry() {
125
+ const filePath = path.join(this.entriesMapperPath, 'data-for-variant-entry.json');
126
+ if (!(0, lodash_1.isEmpty)(this.entriesForVariant)) {
127
+ (0, fs_1.writeFileSync)(filePath, JSON.stringify(this.entriesForVariant), { encoding: 'utf8' });
128
+ }
129
+ }
116
130
  async disableMandatoryCTReferences() {
117
131
  const onSuccess = ({ response: contentType, apiData: { uid } }) => {
118
132
  (0, utils_1.log)(this.importConfig, `${uid} content type references removed temporarily`, 'success');
@@ -238,6 +252,7 @@ class EntriesImport extends base_class_1.default {
238
252
  const contentType = (0, lodash_1.find)(this.cTs, { uid: cTUid });
239
253
  const onSuccess = ({ response, apiData: entry, additionalInfo }) => {
240
254
  var _a, _b;
255
+ this.entriesForVariant.push({ content_type: cTUid, entry_uid: entry.uid, locale });
241
256
  if ((_a = additionalInfo[entry.uid]) === null || _a === void 0 ? void 0 : _a.isLocalized) {
242
257
  let oldUid = additionalInfo[entry.uid].entryOldUid;
243
258
  (0, utils_1.log)(this.importConfig, `Localized entry: '${entry.title}' of content type ${cTUid} in locale ${locale}`, 'info');
@@ -264,7 +279,9 @@ class EntriesImport extends base_class_1.default {
264
279
  const onReject = ({ error, apiData: entry, additionalInfo }) => {
265
280
  var _a, _b;
266
281
  const { title, uid } = entry;
267
- //Note: write existing entries into files to handler later
282
+ // NOTE Remove from list if any entry import failed
283
+ (0, lodash_1.remove)(this.entriesForVariant, { locale, entry_uid: uid });
284
+ // NOTE: write existing entries into files to handler later
268
285
  if (error.errorCode === 119) {
269
286
  if (((_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.title) || ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.uid)) {
270
287
  if (this.importConfig.replaceExisting) {
@@ -391,6 +408,8 @@ class EntriesImport extends base_class_1.default {
391
408
  entriesReplaceFileHelper.writeIntoFile({ [entry.uid]: entry }, { mapKeyVal: true });
392
409
  };
393
410
  const onReject = ({ error, apiData: { uid, title } }) => {
411
+ // NOTE Remove from list if any entry import failed
412
+ (0, lodash_1.remove)(this.entriesForVariant, { locale, entry_uid: uid });
394
413
  (0, utils_1.log)(this.importConfig, `${title} entry of content type ${cTUid} in locale ${locale} failed to replace`, 'error');
395
414
  (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
396
415
  this.failedEntries.push({
@@ -503,6 +522,8 @@ class EntriesImport extends base_class_1.default {
503
522
  (0, utils_1.log)(this.importConfig, `Updated entry: '${title}' of content type ${cTUid} in locale ${locale}`, 'info');
504
523
  };
505
524
  const onReject = ({ error, apiData: { uid, title } }) => {
525
+ // NOTE Remove from list if any entry import failed
526
+ (0, lodash_1.remove)(this.entriesForVariant, { locale, entry_uid: uid });
506
527
  (0, utils_1.log)(this.importConfig, `${title} entry of content type ${cTUid} in locale ${locale} failed to update`, 'error');
507
528
  (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
508
529
  this.failedEntries.push({
@@ -621,9 +642,21 @@ class EntriesImport extends base_class_1.default {
621
642
  async removeAutoCreatedEntries() {
622
643
  var _a, _b;
623
644
  const onSuccess = ({ response, apiData: { entryUid } }) => {
645
+ var _a, _b;
646
+ // NOTE Remove entry from list
647
+ (0, lodash_1.remove)(this.entriesForVariant, {
648
+ entry_uid: entryUid,
649
+ locale: (_b = (_a = this.importConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code,
650
+ });
624
651
  (0, utils_1.log)(this.importConfig, `Auto created entry in master locale removed - entry uid ${entryUid} `, 'success');
625
652
  };
626
653
  const onReject = ({ error, apiData: { entryUid } }) => {
654
+ var _a, _b;
655
+ // NOTE Remove entry from list
656
+ (0, lodash_1.remove)(this.entriesForVariant, {
657
+ entry_uid: entryUid,
658
+ locale: (_b = (_a = this.importConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code,
659
+ });
627
660
  (0, utils_1.log)(this.importConfig, `Failed to remove auto created entry in master locale - entry uid ${entryUid} \n ${(0, utils_1.formatError)(error)}`, 'error');
628
661
  };
629
662
  return await this.makeConcurrentCall({
@@ -774,6 +807,10 @@ class EntriesImport extends base_class_1.default {
774
807
  apiOptions.apiData = null;
775
808
  return apiOptions;
776
809
  }
810
+ if (requestObject.environments.length === 0 || requestObject.locales.length === 0) {
811
+ apiOptions.apiData = null;
812
+ return apiOptions;
813
+ }
777
814
  apiOptions.apiData = requestObject;
778
815
  return apiOptions;
779
816
  }
@@ -0,0 +1,11 @@
1
+ import { ImportConfig, ModuleClassParams } from '../../types';
2
+ export default class ImportPersonalization {
3
+ private config;
4
+ personalizeConfig: ImportConfig['modules']['personalization'];
5
+ constructor({ importConfig }: ModuleClassParams);
6
+ /**
7
+ * The `start` function in TypeScript asynchronously imports data based on a specified order using a
8
+ * module mapper.
9
+ */
10
+ start(): Promise<void>;
11
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cli_variants_1 = require("@contentstack/cli-variants");
4
+ const utils_1 = require("../../utils");
5
+ class ImportPersonalization {
6
+ constructor({ importConfig }) {
7
+ this.config = importConfig;
8
+ this.personalizeConfig = importConfig.modules.personalization;
9
+ }
10
+ /**
11
+ * The `start` function in TypeScript asynchronously imports data based on a specified order using a
12
+ * module mapper.
13
+ */
14
+ async start() {
15
+ try {
16
+ if (!this.personalizeConfig.baseURL[this.config.region.name]) {
17
+ (0, utils_1.log)(this.config, 'Skipping Personalize project import, personalize url is not set', 'info');
18
+ this.personalizeConfig.importData = false;
19
+ return;
20
+ }
21
+ if (this.config.management_token) {
22
+ (0, utils_1.log)(this.config, 'Skipping Personalize project import when using management token', 'info');
23
+ return;
24
+ }
25
+ await new cli_variants_1.Import.Project(this.config, utils_1.log).import();
26
+ if (this.personalizeConfig.importData) {
27
+ const moduleMapper = {
28
+ events: cli_variants_1.Import.Events,
29
+ audiences: cli_variants_1.Import.Audiences,
30
+ attributes: cli_variants_1.Import.Attribute,
31
+ experiences: cli_variants_1.Import.Experiences,
32
+ };
33
+ const order = this.personalizeConfig
34
+ .importOrder;
35
+ for (const module of order) {
36
+ const Module = moduleMapper[module];
37
+ await new Module(this.config, utils_1.log).import();
38
+ }
39
+ }
40
+ }
41
+ catch (error) {
42
+ this.personalizeConfig.importData = false; // Stop personalization import if project creation fails
43
+ (0, utils_1.log)(this.config, error, 'error');
44
+ if (!this.personalizeConfig.importData) {
45
+ (0, utils_1.log)(this.config, 'Skipping personalization migration...', 'warn');
46
+ }
47
+ }
48
+ }
49
+ }
50
+ exports.default = ImportPersonalization;
@@ -0,0 +1,12 @@
1
+ import { ImportConfig, ModuleClassParams } from '../../types';
2
+ export default class ImportVarientEntries {
3
+ private config;
4
+ personalization: ImportConfig['modules']['personalization'];
5
+ private projectMapperFilePath;
6
+ constructor({ importConfig }: ModuleClassParams);
7
+ /**
8
+ * The `start` function in TypeScript is an asynchronous method that conditionally imports data using
9
+ * helper methods and logs any errors encountered.
10
+ */
11
+ start(): Promise<void>;
12
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const path_1 = tslib_1.__importDefault(require("path"));
5
+ const cli_variants_1 = require("@contentstack/cli-variants");
6
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
7
+ const utils_1 = require("../../utils");
8
+ class ImportVarientEntries {
9
+ constructor({ importConfig }) {
10
+ this.config = importConfig;
11
+ this.personalization = importConfig.modules.personalization;
12
+ this.projectMapperFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', (0, cli_utilities_1.sanitizePath)(this.personalization.dirName), 'projects', 'projects.json');
13
+ }
14
+ /**
15
+ * The `start` function in TypeScript is an asynchronous method that conditionally imports data using
16
+ * helper methods and logs any errors encountered.
17
+ */
18
+ async start() {
19
+ try {
20
+ const project = utils_1.fsUtil.readFile(this.projectMapperFilePath);
21
+ if (project && project.uid && this.personalization.importData) {
22
+ this.config.modules.personalization.project_id = project.uid;
23
+ const helpers = {
24
+ lookUpTerms: utils_1.lookUpTerms,
25
+ lookupAssets: utils_1.lookupAssets,
26
+ lookupEntries: utils_1.lookupEntries,
27
+ lookupExtension: utils_1.lookupExtension,
28
+ restoreJsonRteEntryRefs: utils_1.restoreJsonRteEntryRefs,
29
+ };
30
+ await new cli_variants_1.Import.VariantEntries(Object.assign(this.config, { helpers })).import();
31
+ }
32
+ else {
33
+ (0, utils_1.log)(this.config, 'Skipping entry variants import because no personalize project is linked.', 'info');
34
+ }
35
+ }
36
+ catch (error) {
37
+ (0, utils_1.log)(this.config, error, 'error');
38
+ }
39
+ }
40
+ }
41
+ exports.default = ImportVarientEntries;
@@ -1,4 +1,7 @@
1
1
  import { Modules } from '.';
2
+ export interface AnyProperty {
3
+ [propName: string]: any;
4
+ }
2
5
  export default interface DefaultConfig {
3
6
  versioning: boolean;
4
7
  host: string;
@@ -117,6 +120,43 @@ export default interface DefaultConfig {
117
120
  fileName: string;
118
121
  dependencies?: Modules[];
119
122
  };
123
+ personalization: {
124
+ baseURL: Record<string, string>;
125
+ dirName: string;
126
+ importData: boolean;
127
+ importOrder: string[];
128
+ project_id?: string;
129
+ projects: {
130
+ dirName: string;
131
+ fileName: string;
132
+ };
133
+ attributes: {
134
+ dirName: string;
135
+ fileName: string;
136
+ };
137
+ audiences: {
138
+ dirName: string;
139
+ fileName: string;
140
+ };
141
+ events: {
142
+ dirName: string;
143
+ fileName: string;
144
+ };
145
+ experiences: {
146
+ dirName: string;
147
+ fileName: string;
148
+ thresholdTimer: number;
149
+ checkIntervalDuration: number;
150
+ };
151
+ };
152
+ variantEntry: {
153
+ dirName: string;
154
+ fileName: string;
155
+ apiConcurrency: number;
156
+ query: {
157
+ locale: string;
158
+ } & AnyProperty;
159
+ } & AnyProperty;
120
160
  };
121
161
  languagesCode: string[];
122
162
  apis: {
@@ -1,4 +1,4 @@
1
- import { Modules } from '.';
1
+ import { Modules, Region } from '.';
2
2
  import DefaultConfig from './default-config';
3
3
  export interface ExternalConfig {
4
4
  source_stack?: string;
@@ -49,6 +49,8 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
49
49
  skipExisting?: boolean;
50
50
  skipAudit?: boolean;
51
51
  stackName?: string;
52
+ region: Region;
53
+ personalizeProjectName?: string;
52
54
  'exclude-global-modules': false;
53
55
  }
54
56
  type branch = {
@@ -9,6 +9,12 @@ export interface ContentStackManagementClient {
9
9
  export interface PrintOptions {
10
10
  color?: string;
11
11
  }
12
+ export interface Region {
13
+ name: string;
14
+ cma: string;
15
+ cda: string;
16
+ uiHost: string;
17
+ }
12
18
  export interface InquirePayload {
13
19
  type: string;
14
20
  name: string;
@@ -20,7 +26,7 @@ export interface User {
20
26
  email: string;
21
27
  authtoken: string;
22
28
  }
23
- export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies';
29
+ export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalization' | 'variant-entries';
24
30
  export type ModuleClassParams = {
25
31
  stackAPIClient: ReturnType<ContentstackClient['stack']>;
26
32
  importConfig: ImportConfig;
@@ -1,3 +1,4 @@
1
+ import { AnyProperty } from "./default-config";
1
2
  type AppLocation = 'cs.cm.stack.config' | 'cs.cm.stack.dashboard' | 'cs.cm.stack.sidebar' | 'cs.cm.stack.custom_field' | 'cs.cm.stack.rte' | 'cs.cm.stack.asset_sidebar' | 'cs.org.config';
2
3
  interface ExtensionMeta {
3
4
  uid?: string;
@@ -21,9 +22,6 @@ interface LocationConfiguration {
21
22
  base_url: string;
22
23
  locations: Extension[];
23
24
  }
24
- interface AnyProperty {
25
- [propName: string]: any;
26
- }
27
25
  type Manifest = {
28
26
  uid: string;
29
27
  name: string;
@@ -67,6 +67,7 @@ const setupConfig = async (importCmdFlags) => {
67
67
  }
68
68
  }
69
69
  config.isAuthenticated = (0, cli_utilities_1.isAuthenticated)();
70
+ config.auth_token = cli_utilities_1.configHandler.get('authtoken'); // TBD handle auth token in httpClient & sdk
70
71
  //Note to support the old key
71
72
  config.source_stack = config.apiKey;
72
73
  config.skipAudit = importCmdFlags['skip-audit'];
@@ -75,7 +76,7 @@ const setupConfig = async (importCmdFlags) => {
75
76
  config.skipPrivateAppRecreationIfExist = importCmdFlags['skip-app-recreation'];
76
77
  if (importCmdFlags['branch']) {
77
78
  config.branchName = importCmdFlags['branch'];
78
- config.branchDir = path.join((0, cli_utilities_1.sanitizePath)(config.contentDir), (0, cli_utilities_1.sanitizePath)(config.branchName));
79
+ config.branchDir = config.contentDir;
79
80
  }
80
81
  if (importCmdFlags['module']) {
81
82
  config.moduleName = importCmdFlags['module'];
@@ -88,6 +89,7 @@ const setupConfig = async (importCmdFlags) => {
88
89
  config.target_stack = config.apiKey;
89
90
  config.replaceExisting = importCmdFlags['replace-existing'];
90
91
  config.skipExisting = importCmdFlags['skip-existing'];
92
+ config.personalizeProjectName = importCmdFlags['personalize-project-name'];
91
93
  if (importCmdFlags['exclude-global-modules']) {
92
94
  config['exclude-global-modules'] = importCmdFlags['exclude-global-modules'];
93
95
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.16.6",
2
+ "version": "1.17.1",
3
3
  "commands": {
4
4
  "cm:stacks:import": {
5
5
  "id": "cm:stacks:import",
@@ -144,6 +144,13 @@
144
144
  "required": false,
145
145
  "allowNo": false
146
146
  },
147
+ "personalize-project-name": {
148
+ "name": "personalize-project-name",
149
+ "type": "option",
150
+ "description": "Personalize project name.",
151
+ "required": false,
152
+ "multiple": false
153
+ },
147
154
  "skip-audit": {
148
155
  "name": "skip-audit",
149
156
  "type": "boolean",
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-import",
3
3
  "description": "Contentstack CLI plugin to import content into stack",
4
- "version": "1.16.6",
4
+ "version": "1.17.1",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-audit": "~1.6.5",
8
+ "@contentstack/cli-audit": "~1.7.0",
9
9
  "@contentstack/cli-command": "~1.3.0",
10
- "@contentstack/cli-utilities": "~1.7.1",
10
+ "@contentstack/cli-utilities": "~1.7.2",
11
11
  "@contentstack/management": "~1.17.0",
12
+ "@contentstack/cli-variants": "0.0.1-alpha",
12
13
  "@oclif/core": "^3.26.5",
13
14
  "big-json": "^3.2.0",
14
15
  "bluebird": "^3.7.2",
@@ -45,7 +46,7 @@
45
46
  "nyc": "^15.1.0",
46
47
  "oclif": "^3.8.1",
47
48
  "rimraf": "^2.7.1",
48
- "sinon": "^11.1.1",
49
+ "sinon": "^19.0.0",
49
50
  "tmp": "^0.2.2",
50
51
  "ts-node": "^10.9.1",
51
52
  "typescript": "^4.9.3"