@contentstack/cli-cm-import 1.15.5 → 1.15.6

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.
Files changed (37) hide show
  1. package/README.md +1 -1
  2. package/lib/import/modules/content-types.d.ts +1 -1
  3. package/lib/import/modules/content-types.js +11 -10
  4. package/lib/import/modules/entries.d.ts +1 -1
  5. package/lib/import/modules/entries.js +16 -16
  6. package/lib/import/modules/global-fields.d.ts +1 -1
  7. package/lib/import/modules/global-fields.js +9 -8
  8. package/lib/import/modules/locales.d.ts +1 -1
  9. package/lib/import/modules/locales.js +6 -6
  10. package/lib/import/modules-js/assets.js +18 -5
  11. package/lib/import/modules-js/content-types.js +7 -6
  12. package/lib/import/modules-js/entries.js +3 -2
  13. package/lib/import/modules-js/environments.js +1 -1
  14. package/lib/import/modules-js/extensions.js +1 -1
  15. package/lib/import/modules-js/global-fields.js +1 -1
  16. package/lib/import/modules-js/labels.js +1 -1
  17. package/lib/import/modules-js/locales.js +1 -1
  18. package/lib/import/modules-js/marketplace-apps.js +1 -1
  19. package/lib/import/modules-js/webhooks.js +1 -1
  20. package/lib/import/modules-js/workflows.js +1 -1
  21. package/lib/utils/asset-helper.js +6 -2
  22. package/lib/utils/backup-handler.js +1 -1
  23. package/lib/utils/common-helper.d.ts +1 -1
  24. package/lib/utils/common-helper.js +2 -2
  25. package/lib/utils/content-type-helper.d.ts +1 -1
  26. package/lib/utils/content-type-helper.js +1 -1
  27. package/lib/utils/entries-helper.js +22 -11
  28. package/lib/utils/extension-helper.js +1 -1
  29. package/lib/utils/file-helper.js +5 -5
  30. package/lib/utils/import-config-handler.js +1 -1
  31. package/lib/utils/log.js +1 -1
  32. package/lib/utils/logger.d.ts +1 -1
  33. package/lib/utils/logger.js +5 -4
  34. package/lib/utils/login-handler.d.ts +1 -1
  35. package/lib/utils/login-handler.js +1 -1
  36. package/oclif.manifest.json +1 -1
  37. package/package.json +3 -3
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.15.5 linux-x64 node-v18.20.2
50
+ @contentstack/cli-cm-import/1.15.6 linux-x64 node-v18.20.3
51
51
  $ csdx --help [COMMAND]
52
52
  USAGE
53
53
  $ csdx COMMAND
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ModuleClassParams } from '../../types';
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable no-prototype-builtins */
3
3
  /*!
4
4
  * Contentstack Import
5
- * Copyright (c) 2019 Contentstack LLC
5
+ * Copyright (c) 2024 Contentstack LLC
6
6
  * MIT Licensed
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -12,6 +12,7 @@ const lodash_1 = require("lodash");
12
12
  const utils_1 = require("../../utils");
13
13
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
14
14
  const content_type_helper_1 = require("../../utils/content-type-helper");
15
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
15
16
  class ContentTypesImport extends base_class_1.default {
16
17
  constructor({ importConfig, stackAPIClient }) {
17
18
  super({ importConfig, stackAPIClient });
@@ -19,13 +20,13 @@ class ContentTypesImport extends base_class_1.default {
19
20
  this.cTsConfig = importConfig.modules['content-types'];
20
21
  this.gFsConfig = importConfig.modules['global-fields'];
21
22
  this.reqConcurrency = this.cTsConfig.writeConcurrency || this.importConfig.writeConcurrency;
22
- this.cTsFolderPath = path.join(this.importConfig.data, this.cTsConfig.dirName);
23
- this.cTsMapperPath = path.join(this.importConfig.data, 'mapper', 'content_types');
24
- this.cTsSuccessPath = path.join(this.cTsMapperPath, 'success.json');
25
- this.gFsFolderPath = path.resolve(this.importConfig.data, this.gFsConfig.dirName);
26
- this.gFsMapperFolderPath = path.join(importConfig.data, 'mapper', 'global_fields', 'success.json');
27
- this.gFsPendingPath = path.join(importConfig.data, 'mapper', 'global_fields', 'pending_global_fields.js');
28
- this.marketplaceAppMapperPath = path.join(this.importConfig.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
23
+ this.cTsFolderPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), (0, cli_utilities_1.sanitizePath)(this.cTsConfig.dirName));
24
+ this.cTsMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', 'content_types');
25
+ this.cTsSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.cTsMapperPath), 'success.json');
26
+ this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.importConfig.data), (0, cli_utilities_1.sanitizePath)(this.gFsConfig.dirName));
27
+ this.gFsMapperFolderPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'global_fields', 'success.json');
28
+ this.gFsPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'global_fields', 'pending_global_fields.js');
29
+ this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', 'marketplace_apps', 'uid-mapping.json');
29
30
  this.ignoredFilesInContentTypesFolder = new Map([
30
31
  ['__master.json', 'true'],
31
32
  ['__priority.json', 'true'],
@@ -39,8 +40,8 @@ class ContentTypesImport extends base_class_1.default {
39
40
  this.gFs = [];
40
41
  this.createdGFs = [];
41
42
  this.pendingGFs = [];
42
- this.taxonomiesPath = path.join(importConfig.data, 'mapper/taxonomies', 'success.json');
43
- this.extPendingPath = path.join(importConfig.data, 'mapper', 'extensions', 'pending_extensions.js');
43
+ this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper/taxonomies', 'success.json');
44
+ this.extPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'extensions', 'pending_extensions.js');
44
45
  }
45
46
  async start() {
46
47
  /**
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ModuleClassParams } from '../../types';
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable no-prototype-builtins */
3
3
  /*!
4
4
  * Contentstack Import
5
- * Copyright (c) 2019 Contentstack LLC
5
+ * Copyright (c) 2024 Contentstack LLC
6
6
  * MIT Licensed
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -15,19 +15,19 @@ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
15
15
  class EntriesImport extends base_class_1.default {
16
16
  constructor({ importConfig, stackAPIClient }) {
17
17
  super({ importConfig, stackAPIClient });
18
- this.assetUidMapperPath = path.resolve(importConfig.data, 'mapper', 'assets', 'uid-mapping.json');
19
- this.assetUrlMapperPath = path.resolve(importConfig.data, 'mapper', 'assets', 'url-mapping.json');
20
- this.entriesMapperPath = path.resolve(importConfig.data, 'mapper', 'entries');
21
- this.envPath = path.resolve(importConfig.data, 'environments', 'environments.json');
22
- this.entriesUIDMapperPath = path.join(this.entriesMapperPath, 'uid-mapping.json');
23
- this.uniqueUidMapperPath = path.join(this.entriesMapperPath, 'unique-mapping.json');
24
- this.modifiedCTsPath = path.join(this.entriesMapperPath, 'modified-schemas.json');
25
- this.marketplaceAppMapperPath = path.join(this.importConfig.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
26
- this.taxonomiesPath = path.join(this.importConfig.data, 'mapper', 'taxonomies', 'terms', 'success.json');
18
+ this.assetUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'assets', 'uid-mapping.json');
19
+ this.assetUrlMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'assets', 'url-mapping.json');
20
+ this.entriesMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'entries');
21
+ this.envPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), 'environments', 'environments.json');
22
+ this.entriesUIDMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'uid-mapping.json');
23
+ this.uniqueUidMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'unique-mapping.json');
24
+ this.modifiedCTsPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'modified-schemas.json');
25
+ this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', 'marketplace_apps', 'uid-mapping.json');
26
+ this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', 'taxonomies', 'terms', 'success.json');
27
27
  this.entriesConfig = importConfig.modules.entries;
28
- this.entriesPath = path.resolve(importConfig.data, this.entriesConfig.dirName);
29
- this.cTsPath = path.resolve(importConfig.data, importConfig.modules['content-types'].dirName);
30
- this.localesPath = path.resolve(importConfig.data, importConfig.modules.locales.dirName, importConfig.modules.locales.fileName);
28
+ this.entriesPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), (0, cli_utilities_1.sanitizePath)(this.entriesConfig.dirName));
29
+ this.cTsPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), (0, cli_utilities_1.sanitizePath)(importConfig.modules['content-types'].dirName));
30
+ this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.data), (0, cli_utilities_1.sanitizePath)(importConfig.modules.locales.dirName), (0, cli_utilities_1.sanitizePath)(importConfig.modules.locales.fileName));
31
31
  this.importConcurrency = this.entriesConfig.importConcurrency || importConfig.importConcurrency;
32
32
  this.entriesUidMapper = {};
33
33
  this.modifiedCTs = [];
@@ -243,7 +243,7 @@ class EntriesImport extends base_class_1.default {
243
243
  (0, utils_1.log)(this.importConfig, `Localized entry: '${entry.title}' of content type ${cTUid} in locale ${locale}`, 'info');
244
244
  entry.uid = oldUid;
245
245
  entry.entryOldUid = oldUid;
246
- entry.sourceEntryFilePath = path.join(basePath, additionalInfo.entryFileName); // stores source file path temporarily
246
+ entry.sourceEntryFilePath = path.join((0, cli_utilities_1.sanitizePath)(basePath), (0, cli_utilities_1.sanitizePath)(additionalInfo.entryFileName)); // stores source file path temporarily
247
247
  entriesCreateFileHelper.writeIntoFile({ [oldUid]: entry }, { mapKeyVal: true });
248
248
  }
249
249
  else {
@@ -256,7 +256,7 @@ class EntriesImport extends base_class_1.default {
256
256
  this.autoCreatedEntries.push({ cTUid, locale, entryUid: response.uid });
257
257
  }
258
258
  this.entriesUidMapper[entry.uid] = response.uid;
259
- entry.sourceEntryFilePath = path.join(basePath, additionalInfo.entryFileName); // stores source file path temporarily
259
+ entry.sourceEntryFilePath = path.join((0, cli_utilities_1.sanitizePath)(basePath), (0, cli_utilities_1.sanitizePath)(additionalInfo.entryFileName)); // stores source file path temporarily
260
260
  entry.entryOldUid = entry.uid; // stores old uid temporarily
261
261
  entriesCreateFileHelper.writeIntoFile({ [entry.uid]: entry }, { mapKeyVal: true });
262
262
  }
@@ -269,7 +269,7 @@ class EntriesImport extends base_class_1.default {
269
269
  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
270
  if (this.importConfig.replaceExisting) {
271
271
  entry.entryOldUid = uid;
272
- entry.sourceEntryFilePath = path.join(basePath, additionalInfo.entryFileName); // stores source file path temporarily
272
+ entry.sourceEntryFilePath = path.join((0, cli_utilities_1.sanitizePath)(basePath), (0, cli_utilities_1.sanitizePath)(additionalInfo.entryFileName)); // stores source file path temporarily
273
273
  existingEntriesFileHelper.writeIntoFile({ [uid]: entry }, { mapKeyVal: true });
274
274
  }
275
275
  if (!this.importConfig.skipExisting) {
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ModuleClassParams } from '../../types';
@@ -2,13 +2,14 @@
2
2
  /* eslint-disable no-prototype-builtins */
3
3
  /*!
4
4
  * Contentstack Import
5
- * Copyright (c) 2019 Contentstack LLC
5
+ * Copyright (c) 2024 Contentstack LLC
6
6
  * MIT Licensed
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const tslib_1 = require("tslib");
10
10
  const path = tslib_1.__importStar(require("path"));
11
11
  const lodash_1 = require("lodash");
12
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
12
13
  const utils_1 = require("../../utils");
13
14
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
14
15
  class ImportGlobalFields extends base_class_1.default {
@@ -23,13 +24,13 @@ class ImportGlobalFields extends base_class_1.default {
23
24
  this.pendingGFs = [];
24
25
  this.existingGFs = [];
25
26
  this.reqConcurrency = this.gFsConfig.writeConcurrency || this.config.writeConcurrency;
26
- this.gFsMapperPath = path.resolve(this.config.data, 'mapper', 'global_fields');
27
- this.gFsFolderPath = path.resolve(this.config.data, this.gFsConfig.dirName);
28
- this.gFsFailsPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'fails.json');
29
- this.gFsSuccessPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'success.json');
30
- this.gFsUidMapperPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'uid-mapping.json');
31
- this.gFsPendingPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'pending_global_fields.js');
32
- this.marketplaceAppMapperPath = path.join(this.config.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
27
+ this.gFsMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'global_fields');
28
+ this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(this.gFsConfig.dirName));
29
+ this.gFsFailsPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'global_fields', 'fails.json');
30
+ this.gFsSuccessPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'global_fields', 'success.json');
31
+ this.gFsUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'global_fields', 'uid-mapping.json');
32
+ this.gFsPendingPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'global_fields', 'pending_global_fields.js');
33
+ this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'marketplace_apps', 'uid-mapping.json');
33
34
  }
34
35
  async start() {
35
36
  this.gFs = utils_1.fsUtil.readFile(path.join(this.gFsFolderPath, this.gFsConfig.fileName));
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ModuleClassParams } from '../../types';
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable no-prototype-builtins */
3
3
  /*!
4
4
  * Contentstack Import
5
- * Copyright (c) 2019 Contentstack LLC
5
+ * Copyright (c) 2024 Contentstack LLC
6
6
  * MIT Licensed
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -25,11 +25,11 @@ class ImportLocales extends base_class_1.default {
25
25
  this.createdLocales = [];
26
26
  this.failedLocales = [];
27
27
  this.reqConcurrency = this.localeConfig.writeConcurrency || this.config.writeConcurrency;
28
- this.langMapperPath = path.resolve(this.config.data, 'mapper', 'languages');
29
- this.langFolderPath = path.resolve(this.config.data, this.localeConfig.dirName);
30
- this.langFailsPath = path.resolve(this.config.data, 'mapper', 'languages', 'fails.json');
31
- this.langSuccessPath = path.resolve(this.config.data, 'mapper', 'languages', 'success.json');
32
- this.langUidMapperPath = path.resolve(this.config.data, 'mapper', 'languages', 'uid-mapper.json');
28
+ this.langMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'languages');
29
+ this.langFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(this.localeConfig.dirName));
30
+ this.langFailsPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'languages', 'fails.json');
31
+ this.langSuccessPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'languages', 'success.json');
32
+ this.langUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'languages', 'uid-mapper.json');
33
33
  }
34
34
  async start() {
35
35
  this.languages = utils_1.fsUtil.readFile(path.join(this.langFolderPath, this.localeConfig.fileName));
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const fs = require('fs');
@@ -11,6 +11,7 @@ const mkdirp = require('mkdirp');
11
11
  const Promise = require('bluebird');
12
12
  let { default: config } = require('../../config');
13
13
  const { fileHelper, log, uploadAssetHelper } = require('../../utils');
14
+ const { sanitizePath, validateUids, validateFileName } = require('@contentstack/cli-utilities');
14
15
  module.exports = class ImportAssets {
15
16
  constructor(importConfig, stackAPIClient) {
16
17
  this.fails = [];
@@ -66,7 +67,10 @@ module.exports = class ImportAssets {
66
67
  // the asset has been already imported
67
68
  return void 0;
68
69
  }
69
- let currentAssetFolderPath = path.join(self.assetsFolderPath, assetUid);
70
+ if (!validateUids(assetUid)) {
71
+ reject(`UID Not Valid`);
72
+ }
73
+ let currentAssetFolderPath = path.join(sanitizePath(self.assetsFolderPath), sanitizePath(assetUid));
70
74
  if (fs.existsSync(currentAssetFolderPath)) {
71
75
  // if this is true, means, the exported asset data is versioned
72
76
  // hence, upload each asset with its version
@@ -77,7 +81,10 @@ module.exports = class ImportAssets {
77
81
  }
78
82
  let uidContainer = {};
79
83
  let urlContainer = {};
80
- let assetPath = path.resolve(currentAssetFolderPath, self.assets[assetUid].filename);
84
+ if (!validateFileName(self.assets[assetUid].filename)) {
85
+ reject(`File Name Not Valid`);
86
+ }
87
+ let assetPath = path.resolve(sanitizePath(currentAssetFolderPath), sanitizePath(self.assets[assetUid].filename));
81
88
  if (self.assets[assetUid].parent_uid && typeof self.assets[assetUid].parent_uid === 'string') {
82
89
  if (self.mappedFolderUids.hasOwnProperty(self.assets[assetUid].parent_uid)) {
83
90
  self.assets[assetUid].parent_uid = self.mappedFolderUids[self.assets[assetUid].parent_uid];
@@ -142,7 +149,10 @@ module.exports = class ImportAssets {
142
149
  uploadVersionedAssets(uid, assetFolderPath) {
143
150
  let self = this;
144
151
  return new Promise(function (resolve, reject) {
145
- let versionedAssetMetadata = fileHelper.readFileSync(path.join(assetFolderPath, '_contentstack_' + uid + '.json'));
152
+ if (!validateUids(uid)) {
153
+ reject(`UID not valid`);
154
+ }
155
+ let versionedAssetMetadata = fileHelper.readFileSync(path.join(sanitizePath(assetFolderPath), '_contentstack_' + sanitizePath(uid) + '.json'));
146
156
  // using last version, find asset's parent
147
157
  let lastVersion = versionedAssetMetadata[versionedAssetMetadata.length - 1];
148
158
  if (typeof lastVersion.parent_uid === 'string') {
@@ -165,7 +175,10 @@ module.exports = class ImportAssets {
165
175
  let filesStreamed = [];
166
176
  return Promise.map(versionedAssetMetadata, function () {
167
177
  let assetMetadata = versionedAssetMetadata[counter];
168
- let assetPath = path.join(assetFolderPath, assetMetadata.filename);
178
+ if (!validateFileName(assetMetadata.filename)) {
179
+ reject(`File Name not valid`);
180
+ }
181
+ let assetPath = path.join(sanitizePath(assetFolderPath), sanitizePath(assetMetadata.filename));
169
182
  if (++counter === 1) {
170
183
  return self
171
184
  .uploadAsset(assetPath, assetMetadata, uidContainer, urlContainer)
@@ -3,6 +3,7 @@ const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const { cloneDeep, find, findIndex } = require('lodash');
5
5
  const { fileHelper, log, executeTask, formatError, schemaTemplate, lookupExtension } = require('../../utils');
6
+ const { sanitizePath } = require('@contentstack/cli-utilities');
6
7
  class ContentTypesImport {
7
8
  constructor(importConfig, stackAPIClient) {
8
9
  this.stackAPIClient = stackAPIClient;
@@ -11,12 +12,12 @@ class ContentTypesImport {
11
12
  this.globalFieldConfig = importConfig.modules.globalfields;
12
13
  this.importConcurrency = this.contentTypeConfig.importConcurrency || this.importConfig.importConcurrency;
13
14
  this.writeConcurrency = this.contentTypeConfig.writeConcurrency || this.importConfig.writeConcurrency;
14
- this.contentTypesFolderPath = path.join(this.importConfig.data, this.contentTypeConfig.dirName);
15
- this.mapperFolderPath = path.join(this.importConfig.data, 'mapper', 'content_types');
16
- this.existingContentTypesPath = path.join(this.mapperFolderPath, 'success.json');
17
- this.globalFieldsFolderPath = path.resolve(this.importConfig.data, this.globalFieldConfig.dirName);
18
- this.globalFieldMapperFolderPath = path.join(importConfig.data, 'mapper', 'global_fields', 'success.json');
19
- this.globalFieldPendingPath = path.join(importConfig.data, 'mapper', 'global_fields', 'pending_global_fields.js');
15
+ this.contentTypesFolderPath = path.join(sanitizePath(this.importConfig.data), sanitizePath(this.contentTypeConfig.dirName));
16
+ this.mapperFolderPath = path.join(sanitizePath(this.importConfig.data), 'mapper', 'content_types');
17
+ this.existingContentTypesPath = path.join(sanitizePath(this.mapperFolderPath), 'success.json');
18
+ this.globalFieldsFolderPath = path.resolve(sanitizePath(this.importConfig.data), sanitizePath(this.globalFieldConfig.dirName));
19
+ this.globalFieldMapperFolderPath = path.join(sanitizePath(importConfig.data), 'mapper', 'global_fields', 'success.json');
20
+ this.globalFieldPendingPath = path.join(sanitizePath(importConfig.data), 'mapper', 'global_fields', 'pending_global_fields.js');
20
21
  this.ignoredFilesInContentTypesFolder = new Map([
21
22
  ['__master.json', 'true'],
22
23
  ['__priority.json', 'true'],
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const Promise = require('bluebird');
@@ -11,6 +11,7 @@ const mkdirp = require('mkdirp');
11
11
  const chalk = require('chalk');
12
12
  const { fileHelper, log, formatError, lookupExtension, suppressSchemaReference, lookupAssets, lookupEntries, } = require('../../utils');
13
13
  const { default: config } = require('../../config');
14
+ const { sanitizePath } = require('@contentstack/cli-utilities');
14
15
  const addlogs = log;
15
16
  module.exports = class ImportEntries {
16
17
  constructor(importConfig, stackAPIClient) {
@@ -665,7 +666,7 @@ module.exports = class ImportEntries {
665
666
  return resolve();
666
667
  }
667
668
  self.mappedUids[query.entry.uid] = response.body.entries[0].uid;
668
- let _ePath = path.join(this.entryMapperPath, query.locale, query.content_type, 'success.json');
669
+ let _ePath = path.join(sanitizePath(this.entryMapperPath), sanitizePath(query.locale), sanitizePath(query.content_type), 'success.json');
669
670
  let entries = fileHelper.readFileSync(_ePath);
670
671
  entries.push(query.entry);
671
672
  fileHelper.writeFileSync(_ePath, entries);
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const fs = require('fs');
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const mkdirp = require('mkdirp');
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  let fs = require('fs');
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const path = require('path');
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-prototype-builtins */
2
2
  /*!
3
3
  * Contentstack Import
4
- * Copyright (c) 2019 Contentstack LLC
4
+ * Copyright (c) 2024 Contentstack LLC
5
5
  * MIT Licensed
6
6
  */
7
7
  let fs = require('fs');
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Export
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const fs = require('fs');
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const mkdirp = require('mkdirp');
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  const fs = require('fs');
@@ -250,8 +250,12 @@ const lookupAssets = function (data, mappedAssetUids, mappedAssetUrls, assetUidM
250
250
  let uid = mappedAssetUids[assetUid];
251
251
  if (typeof uid !== 'undefined') {
252
252
  const escapedAssetUid = assetUid.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
253
- entry = entry.replace(new RegExp(escapedAssetUid, 'img'), uid);
254
- matchedUids.push(assetUid);
253
+ const regex = new RegExp(`\\b${escapedAssetUid}\\b`, 'img');
254
+ let { status } = (0, cli_utilities_1.validateRegex)(new RegExp(regex, 'img'));
255
+ if (status === 'safe') {
256
+ entry = entry.replace(regex, uid);
257
+ matchedUids.push(assetUid);
258
+ }
255
259
  }
256
260
  else {
257
261
  unmatchedUids.push(assetUid);
@@ -12,7 +12,7 @@ async function backupHandler(importConfig) {
12
12
  let backupDirPath;
13
13
  const subDir = isSubDirectory(importConfig);
14
14
  if (subDir) {
15
- backupDirPath = path.resolve(importConfig.contentDir, '..', '_backup_' + Math.floor(Math.random() * 1000));
15
+ backupDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), '..', '_backup_' + Math.floor(Math.random() * 1000));
16
16
  if (importConfig.createBackupDir) {
17
17
  cli_utilities_1.cliux.print(`Warning!!! Provided backup directory path is a sub directory of the content directory, Cannot copy to a sub directory. Hence new backup directory created - ${backupDirPath}`, {
18
18
  color: 'yellow',
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ImportConfig } from '../types';
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable no-console */
3
3
  /*!
4
4
  * Contentstack Import
5
- * Copyright (c) 2019 Contentstack LLC
5
+ * Copyright (c) 2024 Contentstack LLC
6
6
  * MIT Licensed
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -65,7 +65,7 @@ const sanitizeStack = (importConfig) => {
65
65
  if (stackDetails.data && stackDetails.data.stack && stackDetails.data.stack.settings) {
66
66
  const newStackVersion = stackDetails.data.stack.settings.version;
67
67
  const newStackDate = new Date(newStackVersion).toString();
68
- const stackFilePath = path.join(importConfig.data, importConfig.modules.stack.dirName, importConfig.modules.stack.fileName);
68
+ const stackFilePath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), (0, cli_utilities_1.sanitizePath)(importConfig.modules.stack.dirName), (0, cli_utilities_1.sanitizePath)(importConfig.modules.stack.fileName));
69
69
  const oldStackDetails = (0, file_helper_1.readFileSync)(stackFilePath);
70
70
  if (!oldStackDetails || !oldStackDetails.settings || !oldStackDetails.settings.hasOwnProperty('version')) {
71
71
  throw new Error(`${JSON.stringify(oldStackDetails)} is invalid!`);
@@ -42,7 +42,7 @@ export declare const schemaTemplate: {
42
42
  };
43
43
  /*!
44
44
  * Contentstack Import
45
- * Copyright (c) 2019 Contentstack LLC
45
+ * Copyright (c) 2024 Contentstack LLC
46
46
  * MIT Licensed
47
47
  */
48
48
  export declare const suppressSchemaReference: (schema: any, flag: any) => void;
@@ -47,7 +47,7 @@ exports.schemaTemplate = {
47
47
  };
48
48
  /*!
49
49
  * Contentstack Import
50
- * Copyright (c) 2019 Contentstack LLC
50
+ * Copyright (c) 2024 Contentstack LLC
51
51
  * MIT Licensed
52
52
  */
53
53
  const suppressSchemaReference = function (schema, flag) {
@@ -84,15 +84,18 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
84
84
  }
85
85
  }
86
86
  else {
87
- _entry = _entry[_parent[j]];
88
- let _keys = _.clone(_parent).splice(j + 1, len);
89
- if (Array.isArray(_entry)) {
90
- for (let i = 0, _i = _entry === null || _entry === void 0 ? void 0 : _entry.length; i < _i; i++) {
91
- update(_keys, form_id, _entry[i]);
87
+ const key = _parent[j];
88
+ if (Object.prototype.hasOwnProperty.call(_entry, key)) {
89
+ _entry = _entry[key];
90
+ let _keys = _.clone(_parent).splice(j + 1, len);
91
+ if (Array.isArray(_entry)) {
92
+ for (let i = 0, _i = _entry === null || _entry === void 0 ? void 0 : _entry.length; i < _i; i++) {
93
+ update(_keys, form_id, _entry[i]);
94
+ }
95
+ }
96
+ else if (!(_entry instanceof Object)) {
97
+ break;
92
98
  }
93
- }
94
- else if (!(_entry instanceof Object)) {
95
- break;
96
99
  }
97
100
  }
98
101
  }
@@ -201,8 +204,12 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
201
204
  if (mappedUids.hasOwnProperty(uid)) {
202
205
  const sanitizedUid = (0, cli_utilities_1.escapeRegExp)(uid);
203
206
  const escapedMappedUid = (0, cli_utilities_1.escapeRegExp)(mappedUids[uid]);
204
- entry = entry.replace(new RegExp(sanitizedUid, 'img'), escapedMappedUid);
205
- mapped.push(uid);
207
+ const uidRegex = new RegExp(`\\b${sanitizedUid}\\b`, 'img');
208
+ let { status } = (0, cli_utilities_1.validateRegex)(uidRegex);
209
+ if (status === 'safe') {
210
+ entry = entry.replace(uidRegex, escapedMappedUid);
211
+ mapped.push(uid);
212
+ }
206
213
  }
207
214
  else {
208
215
  unmapped.push(uid);
@@ -566,7 +573,11 @@ const restoreJsonRteEntryRefs = (entry, sourceStackEntry, ctSchema = [], { uidMa
566
573
  };
567
574
  exports.restoreJsonRteEntryRefs = restoreJsonRteEntryRefs;
568
575
  function updateUids(str, match, uidMapper) {
569
- return str.replace(new RegExp(match, 'g'), (match) => uidMapper[match]);
576
+ const sanitizedMatch = (0, cli_utilities_1.escapeRegExp)(match);
577
+ const regex = new RegExp(`\\b${sanitizedMatch}\\b`, 'g');
578
+ let { status } = (0, cli_utilities_1.validateRegex)(regex);
579
+ if (status === 'safe')
580
+ return str.replace(regex, (matchedString) => uidMapper[matchedString]);
570
581
  }
571
582
  function setDirtyTrue(jsonRteChild) {
572
583
  // also removing uids in this function
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.lookupExtension = void 0;
7
7
  /*!
8
8
  * Contentstack Import
9
- * Copyright (c) 2019 Contentstack LLC
9
+ * Copyright (c) 2024 Contentstack LLC
10
10
  * MIT Licensed
11
11
  */
12
12
  const node_path_1 = require("node:path");
@@ -9,7 +9,7 @@ const bigJSON = tslib_1.__importStar(require("big-json"));
9
9
  const cli_utilities_1 = require("@contentstack/cli-utilities");
10
10
  const readFileSync = function (filePath, parse = true) {
11
11
  let data;
12
- filePath = path.resolve(filePath);
12
+ filePath = path.resolve((0, cli_utilities_1.sanitizePath)(filePath));
13
13
  if (fs.existsSync(filePath)) {
14
14
  try {
15
15
  data = parse ? JSON.parse(fs.readFileSync(filePath, 'utf-8')) : data;
@@ -24,7 +24,7 @@ exports.readFileSync = readFileSync;
24
24
  // by default file type is json
25
25
  const readFile = async (filePath, options = { type: 'json' }) => {
26
26
  return new Promise((resolve, reject) => {
27
- filePath = path.resolve(filePath);
27
+ filePath = path.resolve((0, cli_utilities_1.sanitizePath)(filePath));
28
28
  fs.readFile(filePath, 'utf-8', (error, data) => {
29
29
  if (error) {
30
30
  if (error.code === 'ENOENT') {
@@ -46,7 +46,7 @@ const readLargeFile = function (filePath, opts) {
46
46
  if (typeof filePath !== 'string') {
47
47
  return;
48
48
  }
49
- filePath = path.resolve(filePath);
49
+ filePath = path.resolve((0, cli_utilities_1.sanitizePath)(filePath));
50
50
  if (fs.existsSync(filePath)) {
51
51
  return new Promise((resolve, reject) => {
52
52
  const readStream = fs.createReadStream(filePath, { encoding: 'utf-8' });
@@ -87,7 +87,7 @@ const writeLargeFile = function (filePath, data) {
87
87
  if (typeof filePath !== 'string' || typeof data !== 'object') {
88
88
  return;
89
89
  }
90
- filePath = path.resolve(filePath);
90
+ filePath = path.resolve((0, cli_utilities_1.sanitizePath)(filePath));
91
91
  return new Promise((resolve, reject) => {
92
92
  const stringifyStream = bigJSON.createStringifyStream({
93
93
  body: data,
@@ -123,7 +123,7 @@ const readdirSync = function (dirPath) {
123
123
  exports.readdirSync = readdirSync;
124
124
  const isFolderExist = async (folderPath) => {
125
125
  return new Promise((resolve, reject) => {
126
- folderPath = path.resolve(folderPath);
126
+ folderPath = path.resolve((0, cli_utilities_1.sanitizePath)(folderPath));
127
127
  fs.access(folderPath, (error) => {
128
128
  if (error) {
129
129
  return resolve(false);
@@ -75,7 +75,7 @@ const setupConfig = async (importCmdFlags) => {
75
75
  config.skipPrivateAppRecreationIfExist = importCmdFlags['skip-app-recreation'];
76
76
  if (importCmdFlags['branch']) {
77
77
  config.branchName = importCmdFlags['branch'];
78
- config.branchDir = path.join(config.contentDir, config.branchName);
78
+ config.branchDir = path.join((0, cli_utilities_1.sanitizePath)(config.contentDir), (0, cli_utilities_1.sanitizePath)(config.branchName));
79
79
  }
80
80
  if (importCmdFlags['module']) {
81
81
  config.moduleName = importCmdFlags['module'];
package/lib/utils/log.js CHANGED
@@ -22,7 +22,7 @@ exports.log = log;
22
22
  function initLogger(config) {
23
23
  var _a;
24
24
  if (!logger) {
25
- const basePath = (0, cli_utilities_1.pathValidator)((0, path_1.join)((_a = config === null || config === void 0 ? void 0 : config.cliLogsPath) !== null && _a !== void 0 ? _a : process.cwd(), 'logs', 'import'));
25
+ const basePath = (0, cli_utilities_1.pathValidator)((0, path_1.join)((0, cli_utilities_1.sanitizePath)((_a = config === null || config === void 0 ? void 0 : config.cliLogsPath) !== null && _a !== void 0 ? _a : process.cwd()), 'logs', 'import'));
26
26
  exports.logger = logger = new cli_utilities_1.Logger(Object.assign(config !== null && config !== void 0 ? config : {}, { basePath }));
27
27
  }
28
28
  return logger;
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Export
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ImportConfig } from '../types';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /*!
3
3
  * Contentstack Export
4
- * Copyright (c) 2019 Contentstack LLC
4
+ * Copyright (c) 2024 Contentstack LLC
5
5
  * MIT Licensed
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -9,6 +9,7 @@ exports.unlinkFileLogger = exports.log = void 0;
9
9
  const tslib_1 = require("tslib");
10
10
  const winston = tslib_1.__importStar(require("winston"));
11
11
  const path = tslib_1.__importStar(require("path"));
12
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
12
13
  const slice = Array.prototype.slice;
13
14
  const ansiRegexPattern = [
14
15
  '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
@@ -54,16 +55,16 @@ let successTransport;
54
55
  let errorTransport;
55
56
  function init(_logPath) {
56
57
  if (!logger || !errorLogger) {
57
- const logsDir = path.resolve(_logPath, 'logs', 'import');
58
+ const logsDir = path.resolve((0, cli_utilities_1.sanitizePath)(_logPath), 'logs', 'import');
58
59
  successTransport = {
59
- filename: path.join(logsDir, 'success.log'),
60
+ filename: path.join((0, cli_utilities_1.sanitizePath)(logsDir), 'success.log'),
60
61
  maxFiles: 20,
61
62
  maxsize: 1000000,
62
63
  tailable: true,
63
64
  level: 'info',
64
65
  };
65
66
  errorTransport = {
66
- filename: path.join(logsDir, 'error.log'),
67
+ filename: path.join((0, cli_utilities_1.sanitizePath)(logsDir), 'error.log'),
67
68
  maxFiles: 20,
68
69
  maxsize: 1000000,
69
70
  tailable: true,
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Contentstack Import
3
- * Copyright (c) 2019 Contentstack LLC
3
+ * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
6
  import { ImportConfig } from '../types';
@@ -4,7 +4,7 @@
4
4
  /* eslint-disable no-empty */
5
5
  /*!
6
6
  * Contentstack Import
7
- * Copyright (c) 2019 Contentstack LLC
7
+ * Copyright (c) 2024 Contentstack LLC
8
8
  * MIT Licensed
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.15.5",
2
+ "version": "1.15.6",
3
3
  "commands": {
4
4
  "cm:stacks:import": {
5
5
  "id": "cm:stacks:import",
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.15.5",
4
+ "version": "1.15.6",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-audit": "~1.6.1",
8
+ "@contentstack/cli-audit": "~1.6.2",
9
9
  "@contentstack/cli-command": "~1.2.18",
10
- "@contentstack/cli-utilities": "~1.6.1",
10
+ "@contentstack/cli-utilities": "~1.6.2",
11
11
  "@contentstack/management": "~1.15.3",
12
12
  "@oclif/core": "^3.26.5",
13
13
  "big-json": "^3.2.0",