@contentstack/cli-migration 0.1.1-beta.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -25
  3. package/oclif.manifest.json +1 -1
  4. package/package.json +17 -12
  5. package/src/actions/action-list.js +11 -11
  6. package/src/actions/index.js +33 -34
  7. package/src/commands/cm/stacks/migration.js +299 -0
  8. package/src/config/api-config.js +5 -6
  9. package/src/config/default-options.js +2 -2
  10. package/src/config/index.js +2 -2
  11. package/src/config/master-locale.js +2 -2
  12. package/src/modules/base.js +33 -33
  13. package/src/modules/content-types.js +76 -76
  14. package/src/modules/fields.js +73 -73
  15. package/src/modules/index.js +2 -2
  16. package/src/modules/locale.js +13 -13
  17. package/src/modules/migration.js +45 -46
  18. package/src/modules/parser.js +68 -47
  19. package/src/services/content-types.js +160 -163
  20. package/src/services/index.js +2 -2
  21. package/src/services/locales.js +33 -35
  22. package/src/utils/auto-retry.js +14 -12
  23. package/src/utils/callsite.js +14 -14
  24. package/src/utils/constants.js +35 -33
  25. package/src/utils/contentstack-sdk.js +42 -43
  26. package/src/utils/error-handler.js +8 -8
  27. package/src/utils/error-helper.js +41 -40
  28. package/src/utils/fs-helper.js +24 -10
  29. package/src/utils/get-batches.js +4 -4
  30. package/src/utils/get-config.js +6 -6
  31. package/src/utils/group-by.js +17 -17
  32. package/src/utils/index.js +2 -2
  33. package/src/utils/logger.js +42 -52
  34. package/src/utils/object-helper.js +7 -7
  35. package/src/utils/safe-promise.js +2 -2
  36. package/src/utils/schema-helper.js +12 -12
  37. package/src/utils/success-handler.js +5 -5
  38. package/src/validators/api-error.js +10 -8
  39. package/src/validators/base-validator.js +14 -14
  40. package/src/validators/create-content-type-validator.js +21 -25
  41. package/src/validators/edit-content-type-validator.js +21 -24
  42. package/src/validators/field-validator.js +10 -8
  43. package/src/validators/index.js +2 -2
  44. package/src/validators/migration-error.js +9 -7
  45. package/src/validators/schema-validator.js +11 -9
  46. package/src/validators/type-error.js +11 -10
  47. package/src/commands/cm/migration.js +0 -182
@@ -1,22 +1,22 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- const getCallsites = require('callsites')
4
- const {parse, resolve} = require('path')
3
+ const getCallsites = require('callsites');
4
+ const { parse, resolve } = require('path');
5
5
 
6
6
  function getFileDirectory(path) {
7
- const parentPath = resolve(path, '../') // Assuming that will be 2 folders up
8
- return parse(parentPath).dir
7
+ const parentPath = resolve(path, '../'); // Assuming that will be 2 folders up
8
+ return parse(parentPath).dir;
9
9
  }
10
10
 
11
11
  module.exports = () => {
12
- const thisDir = getFileDirectory(__filename)
13
- const callsites = getCallsites()
12
+ const thisDir = getFileDirectory(__filename);
13
+ const callsites = getCallsites();
14
14
 
15
- const externalFile = callsites.find(callsite => {
16
- const currentDir = getFileDirectory(callsite.getFileName())
17
- const isNotThisDir = thisDir !== currentDir
18
- return isNotThisDir
19
- })
15
+ const externalFile = callsites.find((callsite) => {
16
+ const currentDir = getFileDirectory(callsite.getFileName());
17
+ const isNotThisDir = thisDir !== currentDir;
18
+ return isNotThisDir;
19
+ });
20
20
 
21
- return externalFile
22
- }
21
+ return externalFile;
22
+ };
@@ -1,24 +1,26 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- exports.mapObject = new Map()
3
+ exports.mapObject = new Map();
4
4
 
5
- exports.version = 3 // TODO: Fetch it from CMA
5
+ exports.version = 3; // TODO: Fetch it from CMA
6
6
 
7
- exports.defaultDataType = 'text'
7
+ exports.defaultDataType = 'text';
8
8
 
9
- exports.MANAGEMENT_SDK = 'MANAGEMENT_SDK'
10
- exports.MANAGEMENT_SDK = 'MANAGEMENT_TOKEN'
11
- exports.AUTH_TOKEN = 'AUTH_TOKEN'
12
- exports.API_KEY = 'API_KEY'
13
- exports.BRANCH = 'BRANCH'
9
+ exports.MANAGEMENT_SDK = 'MANAGEMENT_SDK';
10
+ exports.MANAGEMENT_CLIENT = 'MANAGEMENT_CLIENT';
11
+ exports.MANAGEMENT_TOKEN = 'MANAGEMENT_TOKEN';
12
+ exports.AUTH_TOKEN = 'AUTH_TOKEN';
13
+ exports.API_KEY = 'API_KEY';
14
+ exports.BRANCH = 'BRANCH';
15
+ exports.SOURCE_BRANCH = 'SOURCE_BRANCH';
14
16
 
15
- exports.data_type = 'data_type'
16
- exports.mandatory = 'mandatory'
17
- exports._default = 'default'
18
- exports.unique = 'unique'
19
- exports.display_name = 'display_name'
20
- exports.reference_to = 'reference_to'
21
- exports.field_metadata = 'field_metadata'
17
+ exports.data_type = 'data_type';
18
+ exports.mandatory = 'mandatory';
19
+ exports._default = 'default';
20
+ exports.unique = 'unique';
21
+ exports.display_name = 'display_name';
22
+ exports.reference_to = 'reference_to';
23
+ exports.field_metadata = 'field_metadata';
22
24
 
23
25
  exports.actions = {
24
26
  CUSTOM_TASK: 'CUSTOM_TASK',
@@ -29,40 +31,40 @@ exports.actions = {
29
31
  EDIT_FIELD: 'EDIT_FIELD',
30
32
  DELETE_FIELD: 'DELETE_FIELD',
31
33
  MOVE_FIELD: 'MOVE_FIELD',
32
- }
34
+ };
33
35
 
34
36
  // Http call max retry
35
- exports.MAX_RETRY = 3
37
+ exports.MAX_RETRY = 3;
36
38
 
37
39
  // This key holds the value for http objects in map
38
- exports.requests = 'REQUESTS'
40
+ exports.requests = 'REQUESTS';
39
41
 
40
- exports.limit = 1 // Limit for concurrent tasks executed parallely
42
+ exports.limit = 1; // Limit for concurrent tasks executed parallely
41
43
 
42
- exports.nonWritableMethods = ['GET', 'DELETE']
44
+ exports.nonWritableMethods = ['GET', 'DELETE'];
43
45
 
44
- exports.ContentType = 'Content type'
45
- exports.Entry = 'Entry'
46
+ exports.ContentType = 'Content type';
47
+ exports.Entry = 'Entry';
46
48
 
47
49
  exports.errorMessageHandler = {
48
50
  POST: 'saving',
49
51
  GET: 'fetching',
50
52
  PUT: 'updating',
51
53
  DELETE: 'deleting',
52
- }
54
+ };
53
55
 
54
56
  exports.successMessageHandler = {
55
57
  POST: 'saved',
56
58
  GET: 'fetched',
57
59
  PUT: 'updated',
58
60
  DELETE: 'deleted',
59
- }
61
+ };
60
62
  // map key
61
- exports.actionMapper = 'actions'
63
+ exports.actionMapper = 'actions';
62
64
 
63
- exports.batchLimit = 20
65
+ exports.batchLimit = 20;
64
66
 
65
- exports.contentTypeProperties = ['description', 'title', 'uid', 'options', 'force', 'schema']
67
+ exports.contentTypeProperties = ['description', 'title', 'uid', 'options', 'force', 'schema'];
66
68
 
67
69
  exports.validationAction = {
68
70
  create: 'create',
@@ -76,7 +78,7 @@ exports.validationAction = {
76
78
  schema: 'schema',
77
79
  __migrationError: 'migrationError',
78
80
  field: 'field',
79
- }
81
+ };
80
82
 
81
83
  exports.transformEntriesProperties = [
82
84
  {
@@ -110,7 +112,7 @@ exports.transformEntriesProperties = [
110
112
  type: 'function',
111
113
  mandatory: true,
112
114
  },
113
- ]
115
+ ];
114
116
 
115
117
  exports.deriveLinkedEntriesProperties = [
116
118
  {
@@ -159,7 +161,7 @@ exports.deriveLinkedEntriesProperties = [
159
161
  type: 'function',
160
162
  mandatory: true,
161
163
  },
162
- ]
164
+ ];
163
165
 
164
166
  exports.transformEntriesToTypeProperties = [
165
167
  {
@@ -203,7 +205,7 @@ exports.transformEntriesToTypeProperties = [
203
205
  type: 'function',
204
206
  mandatory: true,
205
207
  },
206
- ]
208
+ ];
207
209
 
208
210
  exports.SDK_ACTIONS = {
209
211
  CONTENTTYPE_GET: 'CONTENTTYPE_GET',
@@ -216,4 +218,4 @@ exports.SDK_ACTIONS = {
216
218
  ENTRY_PUT: 'ENTRY_PUT',
217
219
  ENTRY_DELETE: 'ENTRY_DELETE',
218
220
  ENTRY_PUBLISH: 'ENTRY_PUBLISH',
219
- }
221
+ };
@@ -1,10 +1,10 @@
1
- 'use strict'
1
+ 'use strict';
2
2
  /** Dependencies */
3
3
 
4
4
  // Map helper
5
- const {getMapInstance, getDataWithAction, get} = require('./map')
5
+ const { getMapInstance, getDataWithAction, get } = require('./map');
6
6
  // Constants
7
- const {MANAGEMENT_SDK, SDK_ACTIONS} = require('./constants')
7
+ const { MANAGEMENT_SDK, SDK_ACTIONS } = require('./constants');
8
8
  // List of actions
9
9
  const {
10
10
  CONTENTTYPE_DELETE,
@@ -17,55 +17,54 @@ const {
17
17
  ENTRY_POST,
18
18
  ENTRY_PUBLISH,
19
19
  ENTRY_PUT,
20
- } = SDK_ACTIONS
20
+ } = SDK_ACTIONS;
21
21
 
22
- module.exports = ({action, id, sdkAction}) => {
23
- return async _data => {
24
- _data = getData(_data, id, action)
22
+ module.exports = ({ action, id, sdkAction }) => {
23
+ return async (_data) => {
24
+ _data = getData(_data, id, action);
25
25
 
26
- const mapInstance = getMapInstance()
27
- const managementSdk = get(MANAGEMENT_SDK, mapInstance)
28
- const {stack} = managementSdk
26
+ const mapInstance = getMapInstance();
27
+ const managementSdk = get(MANAGEMENT_SDK, mapInstance);
28
+ const { stack } = managementSdk;
29
29
 
30
- let response
30
+ let response;
31
31
 
32
32
  switch (sdkAction) {
33
- case CONTENTTYPE_GET:
34
- response = await stack.contentType(id).fetch()
35
- return response
36
- case CONTENTTYPE_POST:
37
- response = await stack.contentType().create(_data)
38
- return response
39
- case CONTENTTYPE_PUT:
40
- // const contentType = await stack.contentType(id).fetch();
41
- response = await stack.contentType(_data).update()
42
- return response
43
- case CONTENTTYPE_DELETE:
44
- response = await stack.contentType(id).delete()
45
- return response
46
- case LOCALES_GET:
47
- return response
48
- case ENTRY_GET:
49
- return response
50
- case ENTRY_POST:
51
- return response
52
- case ENTRY_PUBLISH:
53
- return response
54
- case ENTRY_DELETE:
55
- return response
56
- case ENTRY_PUT:
57
- return response
58
- default:
33
+ case CONTENTTYPE_GET:
34
+ response = await stack.contentType(id).fetch();
35
+ return response;
36
+ case CONTENTTYPE_POST:
37
+ response = await stack.contentType().create(_data);
38
+ return response;
39
+ case CONTENTTYPE_PUT:
40
+ // const contentType = await stack.contentType(id).fetch();
41
+ response = await stack.contentType(_data).update();
42
+ return response;
43
+ case CONTENTTYPE_DELETE:
44
+ response = await stack.contentType(id).delete();
45
+ return response;
46
+ case LOCALES_GET:
47
+ return response;
48
+ case ENTRY_GET:
49
+ return response;
50
+ case ENTRY_POST:
51
+ return response;
52
+ case ENTRY_PUBLISH:
53
+ return response;
54
+ case ENTRY_DELETE:
55
+ return response;
56
+ case ENTRY_PUT:
57
+ return response;
58
+ default:
59
59
  }
60
- }
61
- }
60
+ };
61
+ };
62
62
 
63
63
  function getData(_data, id, action) {
64
- let mapInstance = getMapInstance()
64
+ let mapInstance = getMapInstance();
65
65
 
66
- let data = _data ? _data : getDataWithAction(id, mapInstance, action)
66
+ let data = _data ? _data : getDataWithAction(id, mapInstance, action);
67
67
 
68
68
  // return stringify(data);
69
- return data
69
+ return data;
70
70
  }
71
-
@@ -1,21 +1,21 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- const {error} = require('./logger')
4
- const {errorMessageHandler} = require('./constants')
3
+ const { error } = require('./logger');
4
+ const { errorMessageHandler } = require('./constants');
5
5
 
6
6
  module.exports = (data, type, method, err) => {
7
7
  if (data && type && method) {
8
- error(`Error occurred while ${errorMessageHandler[method]} ${type}: ${data}.`)
8
+ error(`Error occurred while ${errorMessageHandler[method]} ${type}: ${data}.`);
9
9
  }
10
10
 
11
11
  if (err.errorMessage) {
12
- error(err.errorMessage)
12
+ error(err.errorMessage);
13
13
  }
14
14
  if (err instanceof Error && err && err.message && err.stack) {
15
- error(err.message)
15
+ error(err.message);
16
16
  // error(err.stack)
17
17
  } else {
18
- error(err)
18
+ error(err);
19
19
  }
20
20
  // throw new Error(err);
21
- }
21
+ };
@@ -1,53 +1,54 @@
1
+ const { highlight } = require('cardinal');
2
+ const { keys } = Object;
3
+ const chalk = require('chalk');
1
4
 
2
- const {highlight} = require('cardinal')
3
- const {keys} = Object
4
- const chalk = require('chalk')
5
-
6
- const {readFile} = require('./fs-helper')
7
- const groupBy = require('./group-by')
5
+ const { readFile } = require('./fs-helper');
6
+ const groupBy = require('./group-by');
8
7
 
9
8
  const getLineWithContext = (lines, lineNumber, context) => {
10
- const line = (lineNumber - 1)
9
+ const line = lineNumber - 1;
11
10
 
12
- const firstLine = (line > context) ? (line - context) : 0
13
- const lastLine = (line + context) < lines.length ? line + context : lines.length
11
+ const firstLine = line > context ? line - context : 0;
12
+ const lastLine = line + context < lines.length ? line + context : lines.length;
14
13
 
15
14
  return {
16
15
  before: lines.slice(firstLine, line),
17
16
  line: lines[line],
18
17
  after: lines.slice(line + 1, lastLine + 1),
19
- }
20
- }
18
+ };
19
+ };
21
20
 
22
- module.exports = errors => {
23
- const errorsByFile = groupBy(errors, 'file')
24
- const messages = []
21
+ module.exports = (errors) => {
22
+ const errorsByFile = groupBy(errors, 'file');
23
+ const messages = [];
25
24
  for (const file of keys(errorsByFile)) {
26
- const fileContents = readFile(file)
27
- const highlightedCode = highlight(fileContents, {linenos: true})
28
- const lines = highlightedCode.split('\n')
29
-
30
- const fileErrorsMessage = chalk`{red Errors in ${file}}\n\n`
31
- const errorMessages = errorsByFile[file].map(error => {
32
- const callsite = error.meta.callsite
33
- const context = 2
34
- const {before, line, after} = getLineWithContext(lines, callsite.line, context)
35
-
36
- const beforeLines = before.map(line => chalk`${line}\n`)
37
- const afterLines = after.map(line => chalk`${line}\n`)
38
- const highlightedLine = chalk`{bold ${line}}\n`
39
-
40
- const formattedCode = beforeLines + highlightedLine + afterLines
41
- if (error.payload.apiError) {
42
- return chalk`{red Line ${String(callsite.line)}:} {bold ${error.payload.apiError.message}}\n${formattedCode}`
43
- }
44
- if (error.message) {
45
- return chalk`{red Line ${String(callsite.line)}:} {bold ${error.message}}\n${formattedCode}`
46
- }
47
- return chalk`{red Line ${String(callsite.line)}:} {bold something went wrong here.}\n${formattedCode}`
48
- }).join('\n')
49
-
50
- messages.push(`${fileErrorsMessage}${errorMessages}`)
25
+ const fileContents = readFile(file);
26
+ const highlightedCode = highlight(fileContents, { linenos: true });
27
+ const lines = highlightedCode.split('\n');
28
+
29
+ const fileErrorsMessage = chalk`{red Errors in ${file}}\n\n`;
30
+ const errorMessages = errorsByFile[file]
31
+ .map((error) => {
32
+ const callsite = error.meta.callsite;
33
+ const context = 2;
34
+ const { before, line, after } = getLineWithContext(lines, callsite.line, context);
35
+
36
+ const beforeLines = before.map((_line) => chalk`${_line}\n`);
37
+ const afterLines = after.map((_line) => chalk`${_line}\n`);
38
+ const highlightedLine = chalk`{bold ${line}}\n`;
39
+
40
+ const formattedCode = beforeLines + highlightedLine + afterLines;
41
+ if (error.payload.apiError) {
42
+ return chalk`{red Line ${String(callsite.line)}:} {bold ${error.payload.apiError.message}}\n${formattedCode}`;
43
+ }
44
+ if (error.message) {
45
+ return chalk`{red Line ${String(callsite.line)}:} {bold ${error.message}}\n${formattedCode}`;
46
+ }
47
+ return chalk`{red Line ${String(callsite.line)}:} {bold something went wrong here.}\n${formattedCode}`;
48
+ })
49
+ .join('\n');
50
+
51
+ messages.push(`${fileErrorsMessage}${errorMessages}`);
51
52
  }
52
53
  // eslint-disable-next-line
53
54
  // console.error(chalk`{red.bold Validation failed}\n\n`);
@@ -55,4 +56,4 @@ module.exports = errors => {
55
56
  console.log(messages.join('\n'));
56
57
  // eslint-disable-next-line
57
58
  console.log(chalk`{bold.red Migration unsuccessful}`);
58
- }
59
+ };
@@ -1,14 +1,28 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- const {existsSync, mkdirSync, readFileSync} = require('fs')
3
+ const { existsSync, mkdirSync, readFileSync, readFile } = require('fs');
4
+ const path = require('path');
4
5
 
5
- exports.makeDir = dirname => {
6
- !this.existsSync(dirname) && mkdirSync(dirname)
7
- }
6
+ exports.makeDir = (dirname) => {
7
+ !this.existsSync(dirname) && mkdirSync(dirname);
8
+ };
8
9
 
9
- exports.existsSync = filePath => existsSync(filePath)
10
+ exports.existsSync = (filePath) => existsSync(filePath);
10
11
 
11
- exports.readFile = filePath => {
12
- if (!existsSync(filePath)) throw new Error('File does not exist')
13
- return readFileSync(filePath, 'utf-8')
14
- }
12
+ exports.readFile = (filePath) => {
13
+ if (!existsSync(filePath)) throw new Error('File does not exist');
14
+ return readFileSync(filePath, 'utf-8');
15
+ };
16
+
17
+ exports.readJSONFile = (filePath) => {
18
+ return new Promise((resolve, reject) => {
19
+ filePath = path.resolve(filePath);
20
+ readFile(filePath, 'utf-8', (error, data) => {
21
+ if (error) {
22
+ reject(error);
23
+ } else {
24
+ resolve(JSON.parse(data));
25
+ }
26
+ });
27
+ });
28
+ };
@@ -1,7 +1,7 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
3
  module.exports = (count, batchLimit) => {
4
- const partitions = Math.ceil(count / batchLimit)
4
+ const partitions = Math.ceil(count / batchLimit);
5
5
  // Returns array filled with indexes
6
- return new Array(partitions).fill(null).map((_, i) => i)
7
- }
6
+ return new Array(partitions).fill(null).map((_, i) => i);
7
+ };
@@ -1,13 +1,13 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- const {apiConfig} = require('../config')
3
+ const { apiConfig } = require('../config');
4
4
 
5
- module.exports = ({method, path, sdkAction}) => {
5
+ module.exports = ({ method, path, sdkAction }) => {
6
6
  return {
7
7
  ...apiConfig,
8
8
  path: path ? `${apiConfig.version}${path}` : apiConfig.version,
9
9
  method,
10
- headers: {...apiConfig.headers},
10
+ headers: { ...apiConfig.headers },
11
11
  sdkAction,
12
- }
13
- }
12
+ };
13
+ };
@@ -1,38 +1,38 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
3
  module.exports = function groupBy(data, field, i = 0, finalObj = {}, originalArray = []) {
4
- if (!data) return finalObj
4
+ if (!data) return finalObj;
5
5
 
6
6
  if (Array.isArray(data)) {
7
- groupBy(data[i], field, 0, finalObj, data)
7
+ groupBy(data[i], field, 0, finalObj, data);
8
8
  } else if (field in data) {
9
- let dataField = data[field]
9
+ let dataField = data[field];
10
10
  if (dataField in finalObj) {
11
- finalObj[dataField].push(originalArray[i])
11
+ finalObj[dataField].push(originalArray[i]);
12
12
  } else {
13
- finalObj[dataField] = []
14
- finalObj[dataField].push(originalArray[i])
13
+ finalObj[dataField] = [];
14
+ finalObj[dataField].push(originalArray[i]);
15
15
  }
16
16
 
17
- i++
17
+ i++;
18
18
 
19
19
  // Breaks when i has been incremented more than length of original array
20
- if (i !== 0 && i >= originalArray.length) return finalObj
20
+ if (i !== 0 && i >= originalArray.length) return finalObj;
21
21
  /**
22
- * After the field is found only then increment i and inspect next item
23
- * This will restrict iterating through array just to the length of array
24
- */
25
- groupBy(originalArray[i], field, i, finalObj, originalArray)
22
+ * After the field is found only then increment i and inspect next item
23
+ * This will restrict iterating through array just to the length of array
24
+ */
25
+ groupBy(originalArray[i], field, i, finalObj, originalArray);
26
26
  } else {
27
27
  for (let key in data) {
28
28
  if (key) {
29
- let dataKey = data[key]
29
+ let dataKey = data[key];
30
30
  if (!Array.isArray(dataKey) && typeof dataKey === 'object') {
31
- groupBy(dataKey, field, i, finalObj, originalArray)
31
+ groupBy(dataKey, field, i, finalObj, originalArray);
32
32
  }
33
33
  }
34
34
  }
35
35
  }
36
36
 
37
- return finalObj
38
- }
37
+ return finalObj;
38
+ };
@@ -1,4 +1,4 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
3
  module.exports = {
4
4
  map: require('./map'),
@@ -18,4 +18,4 @@ module.exports = {
18
18
  getBatches: require('./get-batches'),
19
19
  autoRetry: require('./auto-retry'),
20
20
  contentstackSdk: require('./contentstack-sdk'),
21
- }
21
+ };