@contentstack/cli-migration 0.1.1-beta.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 +69 -0
- package/oclif.manifest.json +1 -0
- package/package.json +68 -0
- package/src/actions/action-list.js +32 -0
- package/src/actions/index.js +218 -0
- package/src/commands/cm/migration.js +182 -0
- package/src/config/api-config.js +19 -0
- package/src/config/default-options.js +7 -0
- package/src/config/index.js +7 -0
- package/src/config/master-locale.js +10 -0
- package/src/modules/base.js +95 -0
- package/src/modules/content-types.js +208 -0
- package/src/modules/fields.js +304 -0
- package/src/modules/index.js +8 -0
- package/src/modules/locale.js +33 -0
- package/src/modules/migration.js +106 -0
- package/src/modules/parser.js +84 -0
- package/src/services/content-types.js +323 -0
- package/src/services/index.js +6 -0
- package/src/services/locales.js +74 -0
- package/src/utils/auto-retry.js +30 -0
- package/src/utils/callsite.js +22 -0
- package/src/utils/constants.js +219 -0
- package/src/utils/contentstack-sdk.js +71 -0
- package/src/utils/error-handler.js +21 -0
- package/src/utils/error-helper.js +58 -0
- package/src/utils/fs-helper.js +14 -0
- package/src/utils/get-batches.js +7 -0
- package/src/utils/get-config.js +13 -0
- package/src/utils/group-by.js +38 -0
- package/src/utils/index.js +21 -0
- package/src/utils/logger.js +84 -0
- package/src/utils/map.js +40 -0
- package/src/utils/object-helper.js +9 -0
- package/src/utils/request.js +95 -0
- package/src/utils/safe-promise.js +3 -0
- package/src/utils/schema-helper.js +35 -0
- package/src/utils/success-handler.js +12 -0
- package/src/validators/api-error.js +18 -0
- package/src/validators/base-validator.js +39 -0
- package/src/validators/create-content-type-validator.js +58 -0
- package/src/validators/edit-content-type-validator.js +56 -0
- package/src/validators/field-validator.js +19 -0
- package/src/validators/index.js +11 -0
- package/src/validators/migration-error.js +18 -0
- package/src/validators/schema-validator.js +21 -0
- package/src/validators/type-error.js +21 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
const {version, defaultDataType, actions} = require('./constants')
|
|
5
|
+
|
|
6
|
+
exports.getSchema = (field, subAction) => {
|
|
7
|
+
const {EDIT_FIELD, DELETE_FIELD} = actions
|
|
8
|
+
|
|
9
|
+
const schema = {
|
|
10
|
+
display_name: field,
|
|
11
|
+
uid: this.getUid(field),
|
|
12
|
+
data_type: defaultDataType, // This will be overridden if user specifies data type
|
|
13
|
+
mandatory: this.getMandatoryVal(field),
|
|
14
|
+
unique: this.getUniqueVal(field),
|
|
15
|
+
field_metadata: this.getFieldMetaData(field),
|
|
16
|
+
non_localizable: false,
|
|
17
|
+
// isDelete: !!isDelete,
|
|
18
|
+
isDelete: subAction === DELETE_FIELD,
|
|
19
|
+
isEdit: subAction === EDIT_FIELD,
|
|
20
|
+
}
|
|
21
|
+
return schema
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
exports.getUid = data => data.split(' ').join('_').toLowerCase()
|
|
25
|
+
|
|
26
|
+
exports.getMandatoryVal = data => data.toLowerCase() === 'title' || data.toLowerCase() === 'url'
|
|
27
|
+
|
|
28
|
+
exports.getUniqueVal = data => data.toLowerCase() === 'title' || data.toLowerCase() === 'url'
|
|
29
|
+
|
|
30
|
+
exports.getFieldMetaData = data => {
|
|
31
|
+
return {
|
|
32
|
+
_default: this.getMandatoryVal(data),
|
|
33
|
+
version,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {success} = require('./logger')
|
|
4
|
+
const {successMessageHandler} = require('./constants')
|
|
5
|
+
|
|
6
|
+
module.exports = (data, type, method) => {
|
|
7
|
+
if (data && type && method) {
|
|
8
|
+
//success(`Successfully ${successMessageHandler[method]} ${type}: ${data}`);
|
|
9
|
+
} else {
|
|
10
|
+
success(`${type} successfully completed`)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class ApiError {
|
|
4
|
+
validate(data) {
|
|
5
|
+
if (data.payload.apiError) {
|
|
6
|
+
return [{
|
|
7
|
+
...data,
|
|
8
|
+
message: `${data.payload.apiError.error_message}`,
|
|
9
|
+
}]
|
|
10
|
+
}
|
|
11
|
+
return []
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
isApplicable(action) {
|
|
15
|
+
return action.type === 'apiError'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
module.exports = ApiError
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {keys} = Object
|
|
4
|
+
class BaseValidator {
|
|
5
|
+
commonValidate(properties, data) {
|
|
6
|
+
const errors = []
|
|
7
|
+
const opts = data.payload.options
|
|
8
|
+
const dataKeys = keys(opts)
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < properties.length; i++) {
|
|
11
|
+
let prop = properties[i]
|
|
12
|
+
// Check if property is mandatory but not present in user specified params
|
|
13
|
+
if (prop.mandatory && !dataKeys.includes(prop.name)) {
|
|
14
|
+
errors.push({...data, message: `${prop.name} is required.`})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (prop.name in opts) {
|
|
18
|
+
const dataType = this.getDataType(opts[prop.name])
|
|
19
|
+
if (dataType !== prop.type) {
|
|
20
|
+
errors.push({...data, message: `${prop.name} is a ${dataType} type`})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (prop.dependsOn && !(prop.dependsOn in opts) && opts[prop.name]) {
|
|
24
|
+
errors.push({...data, message: `${prop.dependsOn} is required with ${prop.name}`})
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return errors
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getDataType(data) {
|
|
33
|
+
if (Array.isArray(data)) {
|
|
34
|
+
return 'array'
|
|
35
|
+
}
|
|
36
|
+
return typeof data
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
module.exports = BaseValidator
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {keys} = Object
|
|
4
|
+
// Utils
|
|
5
|
+
const {map: _map, constants} = require('../utils')
|
|
6
|
+
// Properties
|
|
7
|
+
const {getMapInstance, get} = _map
|
|
8
|
+
const {contentTypeProperties} = constants
|
|
9
|
+
|
|
10
|
+
const mandatoryKeys = [
|
|
11
|
+
'uid',
|
|
12
|
+
'title',
|
|
13
|
+
'description',
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
class CreateContentTypeValidator {
|
|
17
|
+
constructor() {
|
|
18
|
+
// super();
|
|
19
|
+
this.errors = []
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
validate(data) {
|
|
23
|
+
// Validate the latest updated object in the global map object
|
|
24
|
+
const mapInstance = getMapInstance()
|
|
25
|
+
const mapObj = get(data.payload.contentTypeId, mapInstance)
|
|
26
|
+
const actionObj = mapObj[data.payload.action].content_type
|
|
27
|
+
const userProvidedFields = keys(actionObj)
|
|
28
|
+
|
|
29
|
+
for (const key of mandatoryKeys) {
|
|
30
|
+
if (!keys(actionObj).includes(key) || !actionObj[key]) {
|
|
31
|
+
data = {...data, message: `${key} is missing.`}
|
|
32
|
+
this.errors.push(data)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// TODO: Fix error messages
|
|
37
|
+
const propertyNames = this.getPropertyNames()
|
|
38
|
+
|
|
39
|
+
for (let i = 0; i < userProvidedFields.length; i++) {
|
|
40
|
+
let key = userProvidedFields[i]
|
|
41
|
+
if (!propertyNames.includes(key)) {
|
|
42
|
+
data = {...data, message: `${key} is not valid property.`}
|
|
43
|
+
this.errors.push(data)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return this.errors
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
isApplicable(action) {
|
|
50
|
+
return action.type === 'create'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getPropertyNames() {
|
|
54
|
+
return contentTypeProperties
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = CreateContentTypeValidator
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {keys} = Object
|
|
4
|
+
|
|
5
|
+
// Utils
|
|
6
|
+
const {map: _map, constants} = require('../utils')
|
|
7
|
+
// Properties
|
|
8
|
+
const {getMapInstance, get} = _map
|
|
9
|
+
const {contentTypeProperties} = constants
|
|
10
|
+
|
|
11
|
+
const mandatoryKeys = [
|
|
12
|
+
'uid',
|
|
13
|
+
'title',
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
class EditContentTypeValidator {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.errors = []
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
validate(data) {
|
|
22
|
+
// Validate the latest updated object in the global map object
|
|
23
|
+
const mapInstance = getMapInstance()
|
|
24
|
+
const mapObj = get(data.payload.contentTypeId, mapInstance)
|
|
25
|
+
const actionObj = mapObj[data.payload.action].content_type
|
|
26
|
+
const userProvidedFields = keys(actionObj)
|
|
27
|
+
|
|
28
|
+
for (const key of mandatoryKeys) {
|
|
29
|
+
if (!userProvidedFields.includes(key)) {
|
|
30
|
+
data = {...data, message: `${key} is missing.`}
|
|
31
|
+
this.errors.push(data)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// TODO: Fix error messages
|
|
35
|
+
const propertyNames = this.getPropertyNames()
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < userProvidedFields.length; i++) {
|
|
38
|
+
let key = userProvidedFields[i]
|
|
39
|
+
if (!propertyNames.includes(key)) {
|
|
40
|
+
data = {...data, message: `${key} is not valid property.`}
|
|
41
|
+
this.errors.push(data)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return this.errors
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
isApplicable(action) {
|
|
48
|
+
return action.type === 'edit'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getPropertyNames() {
|
|
52
|
+
return contentTypeProperties
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = EditContentTypeValidator
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class FieldValidator {
|
|
4
|
+
validate(data) {
|
|
5
|
+
if (data.payload.field) {
|
|
6
|
+
return [{
|
|
7
|
+
...data,
|
|
8
|
+
message: data.payload.field.message,
|
|
9
|
+
}]
|
|
10
|
+
}
|
|
11
|
+
return []
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
isApplicable(action) {
|
|
15
|
+
return action.type === 'field'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = FieldValidator
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
CreateContentTypeValidator: require('./create-content-type-validator'),
|
|
5
|
+
EditContentTypeValidator: require('./edit-content-type-validator'),
|
|
6
|
+
SchemaValidator: require('./schema-validator'),
|
|
7
|
+
FieldValidator: require('./field-validator'),
|
|
8
|
+
_TypeError: require('./type-error'),
|
|
9
|
+
ApiError: require('./api-error'),
|
|
10
|
+
MigrationError: require('./migration-error'),
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class MigrationError {
|
|
4
|
+
validate(data) {
|
|
5
|
+
if (data.payload.migrationError) {
|
|
6
|
+
return [{
|
|
7
|
+
...data,
|
|
8
|
+
message: `${data.payload.migrationError.migrationError.message}`,
|
|
9
|
+
}]
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
isApplicable(action) {
|
|
14
|
+
return action.type === 'migrationError'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = MigrationError
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class SchemaValidator {
|
|
4
|
+
validate(data) {
|
|
5
|
+
const {fromField, toField, toReferenceField, deriveField} = data.payload
|
|
6
|
+
// const fieldsToValidate = [payload]
|
|
7
|
+
if (fromField || toField || toReferenceField || deriveField) {
|
|
8
|
+
return [{
|
|
9
|
+
...data,
|
|
10
|
+
message: `${fromField || toField || toReferenceField || deriveField} does not exist on schema.`,
|
|
11
|
+
}]
|
|
12
|
+
}
|
|
13
|
+
return []
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
isApplicable(action) {
|
|
17
|
+
return action.type === 'schema'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = SchemaValidator
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class _TypeError {
|
|
4
|
+
constructor() {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
validate(data) {
|
|
8
|
+
if (data.payload.typeErrors) {
|
|
9
|
+
return [{
|
|
10
|
+
...data,
|
|
11
|
+
message: `${data.payload.typeErrors[0]} is not a valid function`,
|
|
12
|
+
}]
|
|
13
|
+
}
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
isApplicable(action) {
|
|
18
|
+
return action.type === 'typeError'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
module.exports = _TypeError
|