@contentstack/cli-migration 2.0.0-beta.2 → 2.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/package.json +19 -12
  2. package/src/actions/action-list.js +0 -32
  3. package/src/actions/index.js +0 -217
  4. package/src/commands/cm/stacks/migration.js +0 -283
  5. package/src/config/api-config.js +0 -18
  6. package/src/config/default-options.js +0 -7
  7. package/src/config/index.js +0 -7
  8. package/src/config/master-locale.js +0 -10
  9. package/src/modules/base.js +0 -95
  10. package/src/modules/content-types.js +0 -208
  11. package/src/modules/fields.js +0 -340
  12. package/src/modules/index.js +0 -8
  13. package/src/modules/locale.js +0 -33
  14. package/src/modules/migration.js +0 -112
  15. package/src/modules/parser.js +0 -105
  16. package/src/services/content-types.js +0 -317
  17. package/src/services/index.js +0 -6
  18. package/src/services/locales.js +0 -71
  19. package/src/utils/auto-retry.js +0 -32
  20. package/src/utils/callsite.js +0 -23
  21. package/src/utils/constants.js +0 -223
  22. package/src/utils/contentstack-sdk.js +0 -70
  23. package/src/utils/error-helper.js +0 -105
  24. package/src/utils/fs-helper.js +0 -29
  25. package/src/utils/get-batches.js +0 -7
  26. package/src/utils/get-config.js +0 -13
  27. package/src/utils/group-by.js +0 -38
  28. package/src/utils/index.js +0 -21
  29. package/src/utils/logger.js +0 -75
  30. package/src/utils/map.js +0 -40
  31. package/src/utils/migration-logger.js +0 -21
  32. package/src/utils/modules.js +0 -134
  33. package/src/utils/object-helper.js +0 -9
  34. package/src/utils/request.js +0 -95
  35. package/src/utils/safe-promise.js +0 -3
  36. package/src/utils/schema-helper.js +0 -35
  37. package/src/utils/success-handler.js +0 -12
  38. package/src/validators/api-error.js +0 -20
  39. package/src/validators/base-validator.js +0 -39
  40. package/src/validators/create-content-type-validator.js +0 -54
  41. package/src/validators/edit-content-type-validator.js +0 -53
  42. package/src/validators/field-validator.js +0 -21
  43. package/src/validators/index.js +0 -11
  44. package/src/validators/migration-error.js +0 -20
  45. package/src/validators/schema-validator.js +0 -23
  46. package/src/validators/type-error.js +0 -22
@@ -1,95 +0,0 @@
1
- 'use strict';
2
-
3
- // Utils
4
- const { map: _map, constants } = require('../utils');
5
- // Actions
6
- const { actionCreators } = require('../actions');
7
- // Utils properties
8
- const { getMapInstance, get } = _map;
9
- const { actionMapper } = constants;
10
-
11
- /**
12
- * Base class for module classes
13
- * @class Base
14
- * @ignore
15
- */
16
- class Base {
17
- constructor(id, action) {
18
- this.id = id;
19
- this.action = action;
20
- this.actions = [];
21
- }
22
-
23
- /**
24
- * Chained function which takes value for title
25
- * @param {string} value Title
26
- * @returns {Base} current instance of inherited class
27
- */
28
- title(value) {
29
- const mapInstance = getMapInstance();
30
- const { id, action } = this;
31
-
32
- const contentType = get(id, mapInstance);
33
-
34
- contentType[action].content_type.title = value;
35
-
36
- return this;
37
- }
38
-
39
- /**
40
- * Chained function which takes value for description
41
- * @param {string} value Description
42
- * @returns {Base} current instance of inherited class
43
- */
44
- description(value) {
45
- const mapInstance = getMapInstance();
46
- const { id, action } = this;
47
- const contentType = get(id, mapInstance);
48
- contentType[action].content_type.description = value;
49
- return this;
50
- }
51
-
52
- /**
53
- * Chained function takes boolean value for force while deleting content type
54
- * @param {boolean} value Force delete
55
- * @returns {Base} current instance of inherited class
56
- */
57
- force(value) {
58
- const mapInstance = getMapInstance();
59
- const { id, action } = this;
60
-
61
- const contentType = get(id, mapInstance);
62
-
63
- contentType[action].content_type.force = value;
64
-
65
- return this;
66
- }
67
-
68
- /**
69
- * Accumulates actions for validating user provided inputs
70
- * @ignore
71
- * @param {Object} callsite Gets the file location and file number of caller
72
- * @param {string} id unique id of action type
73
- * @param {Object} opts holds payload to be validated
74
- * @param {string} method type of action
75
- */
76
- dispatch(callsite, id, opts, method) {
77
- if (!id && !opts) {
78
- let mapInstance = getMapInstance();
79
- let actions = get(actionMapper, mapInstance); // Returns an array if empty
80
- let action = actionCreators.customTasks(callsite, opts);
81
- actions.push(action);
82
- } else {
83
- let mapInstance = getMapInstance();
84
- let actions = get(actionMapper, mapInstance); // Returns an array if empty
85
- let action = actionCreators.contentType[method](callsite, id, { ...opts, id });
86
- actions.push(action);
87
- }
88
- }
89
-
90
- getActions() {
91
- return this.actions;
92
- }
93
- }
94
-
95
- module.exports = Base;
@@ -1,208 +0,0 @@
1
- /* eslint-disable camelcase */
2
- 'use strict';
3
-
4
- const Field = require('./fields');
5
-
6
- // Services
7
- const { ContentTypeService } = require('../services');
8
-
9
- // Config
10
- const { defaultOptions } = require('../config');
11
-
12
- // Utils
13
- const { map: _map, schemaHelper, constants, getCallsite } = require('../utils');
14
-
15
- // Base class
16
- const Base = require('./base');
17
-
18
- // Properties
19
- const { getMapInstance, set, get } = _map;
20
- const { actions, validationAction } = constants;
21
- const { getUid } = schemaHelper;
22
- const { create, edit } = validationAction;
23
-
24
- /**
25
- * ContentType class
26
- * @class ContentType
27
- * @augments Base
28
- */
29
- class ContentType extends Base {
30
- constructor() {
31
- super();
32
- this.contentTypeService = new ContentTypeService();
33
- }
34
-
35
- /**
36
- * Creates content type by passing content type name and options
37
- * @param {string} id Content type UID
38
- * @param {Object} opts Optional: Content type fields definition
39
- * @returns {Field} instance of Field
40
- * @example
41
- * module.exports = ({migration}) => {
42
- * const blog = migration
43
- * .createContentType('blog')
44
- * .title('blog title')
45
- * .description('blog 1')
46
- * blog.createField('title').display_name('Title').data_type('text').mandatory(true);
47
- * }
48
- */
49
- createContentType(id, opts = {}) {
50
- const callsite = getCallsite();
51
- // base class method
52
- let options = { ...defaultOptions, ...opts };
53
- delete options.title;
54
- delete options.description;
55
- this.dispatch(callsite, id, opts, create);
56
- const { title, description } = opts;
57
- const mapInstance = getMapInstance();
58
-
59
- const { CREATE_CT } = actions;
60
- const uid = getUid(id);
61
-
62
- const ctObj = { content_type: { title, uid, description, options } };
63
-
64
- const ctActionObj = { [CREATE_CT]: ctObj };
65
-
66
- const { contentTypeService } = this;
67
- // Sets data to post in map object
68
- set(id, mapInstance, ctActionObj);
69
- // Sets action and id in content type service
70
- contentTypeService.setIdAndAction(id, CREATE_CT);
71
- const tasks = [contentTypeService.postContentTypes.bind(contentTypeService, callsite, id, CREATE_CT)];
72
- const req = {
73
- title: `Adding content type: ${id}`,
74
- failMessage: `Failed to create content type: ${id}`,
75
- successMessage: `Successfully added content type: ${id}`,
76
- tasks,
77
- };
78
- let field = new Field(id, CREATE_CT, contentTypeService, req);
79
- // TODO: should find better way to attach content type level methods
80
- field.singleton = this.singleton;
81
- field.isPage = this.isPage;
82
- return field;
83
- }
84
-
85
- /**
86
- * Set content type to singleton or multiple
87
- * @param {boolean} value set value true to set content type as singleton default it is multiple
88
- * @returns {ContentType} instance of ContentType for chaining
89
- */
90
- singleton(value) {
91
- const mapInstance = getMapInstance();
92
- const { id, action } = this;
93
- const contentType = get(id, mapInstance);
94
-
95
- contentType[action].content_type.options.singleton = value;
96
- return this;
97
- }
98
-
99
- /**
100
- * Set content type to singleton or multiple
101
- * @param {boolean} value set value false to set content type as content as block default true
102
- * @returns {ContentType} instance of ContentType for chaining
103
- */
104
- isPage(value) {
105
- const mapInstance = getMapInstance();
106
- const { id, action } = this;
107
- const contentType = get(id, mapInstance);
108
-
109
- contentType[action].content_type.options.is_page = value;
110
- return this;
111
- }
112
-
113
- /**
114
- * Edits content type by passing content type name and options
115
- * @param {string} id Content type UID
116
- * @param {Object} opts Optional: Content type fields definition
117
- * @returns {Field} instance of Field
118
- * @example
119
- * module.exports = ({migration}) => {
120
- * const blog = migration.editContentType('blog');
121
- * blog.description('Changed description');
122
- * }
123
- */
124
- editContentType(id, opts = {}) {
125
- let options = { ...defaultOptions, ...opts };
126
- delete options.title;
127
- delete options.description;
128
-
129
- const callsite = getCallsite();
130
- // base class method
131
- this.dispatch(callsite, id, {}, edit);
132
- const { title, description } = opts;
133
- const mapInstance = getMapInstance();
134
-
135
- const { EDIT_CT } = actions;
136
-
137
- const uid = id;
138
-
139
- const ctObj = { content_type: { title, uid, description, options } };
140
- const ctActionObj = { [EDIT_CT]: ctObj };
141
-
142
- const { contentTypeService } = this;
143
-
144
- // Sets data to update in map object
145
- let ctAction = get(id, mapInstance);
146
-
147
- set(id, mapInstance, { ...ctActionObj, ...ctAction });
148
- // Sets action and id in content type service
149
- contentTypeService.setIdAndAction(id, EDIT_CT);
150
- const tasks = [
151
- contentTypeService.fetchContentType.bind(contentTypeService, callsite, id),
152
- contentTypeService.applyActionsOnFields.bind(contentTypeService, callsite),
153
- contentTypeService.editContentType.bind(contentTypeService, callsite),
154
- ];
155
-
156
- const req = {
157
- title: `Editing content type: ${id}`,
158
- failMessage: `Failed to edit content type: ${id}`,
159
- successMessage: `Successfully updated content type: ${id}`,
160
- tasks,
161
- };
162
-
163
- // Keeping the same instance of contentTypeService in Field class
164
- let fieldI = new Field(id, EDIT_CT, contentTypeService, req);
165
- // TODO: should find better way to attach content type level methods
166
- fieldI.singleton = this.singleton;
167
- fieldI.isPage = this.isPage;
168
- return fieldI;
169
- }
170
-
171
- /**
172
- * Deletes content type by passing content type name
173
- * @param {string} id Content type UID
174
- * @returns {Field} instance of Field
175
- * @example
176
- * module.exports = {migrations} => {
177
- * const blog = migrations.deleteContentType('blog');
178
- * }
179
- */
180
- deleteContentType(id) {
181
- const callsite = getCallsite();
182
-
183
- const mapInstance = getMapInstance();
184
-
185
- const { DELETE_CT } = actions;
186
-
187
- const uid = getUid(id);
188
-
189
- const ctObj = { content_type: { uid, force: false } }; // keep by default false
190
-
191
- const ctActionObj = { [DELETE_CT]: ctObj };
192
-
193
- const { contentTypeService } = this;
194
-
195
- // Sets data to delete in map object
196
- set(id, mapInstance, ctActionObj);
197
- // Sets action and id in content type service
198
- contentTypeService.setIdAndAction(id, DELETE_CT);
199
-
200
- const tasks = [contentTypeService.deleteContentType.bind(contentTypeService, callsite)];
201
-
202
- const req = { title: 'Deleting content type', tasks };
203
-
204
- return new Field(id, DELETE_CT, contentTypeService, req);
205
- }
206
- }
207
-
208
- module.exports = ContentType;
@@ -1,340 +0,0 @@
1
- 'use strict';
2
-
3
- const { keys } = Object;
4
- // Utils
5
- const { map: _map, schemaHelper, constants } = require('../utils');
6
-
7
- // Utils Properties
8
- const { getMapInstance, get } = _map;
9
- const { getSchema } = schemaHelper;
10
- const {
11
- data_type,
12
- mandatory,
13
- _default,
14
- unique,
15
- display_name,
16
- field_metadata,
17
- reference_to,
18
- actions: _actions,
19
- taxonomies,
20
- multiple,
21
- } = constants;
22
-
23
- // Base class
24
- const Base = require('./base');
25
-
26
- /**
27
- * Field class
28
- * @class Field
29
- */
30
- class Field extends Base {
31
- // prop, value
32
- constructor(uid, action, contentTypeService, request) {
33
- super(uid);
34
- this.uid = uid;
35
- this.action = action;
36
- this.contentTypeService = contentTypeService;
37
- this.request = request;
38
- }
39
-
40
- /**
41
- * @typedef {Object} Task
42
- * @param {string} title - Title for custom task
43
- * @param {function[]} task - array of async function to be executed
44
- * @param {string} failMessage message to be printed when task fails
45
- * @param {string} successMessage - message to be printed when task succeeds
46
- */
47
-
48
- /**
49
- * Creates a field with provided uid.
50
- * @param {string} field Field name to be created
51
- * @param {Object} opts Options to be passed
52
- * @returns {Field} current instance of field object to chain further methods.
53
- * @example
54
- * module.exports =({ migration })=> {
55
- * const blog = migration.editContentType('blog');
56
- *
57
- * blog.createField('author')
58
- * .display_name('Author')
59
- * .data_type('text')
60
- * .mandatory(false);
61
- * };
62
- *
63
- * Create a taxonomy field
64
- *
65
- * module.exports =({ migration })=> {
66
- * const blog = migration.editContentType('blog');
67
- *
68
- * blog.createField('taxonomies')
69
- * .display_name('Taxonomy1')
70
- * .data_type('taxonomy')
71
- * .taxonomies([{ "taxonomy_uid": "test_taxonomy1", "max_terms": 2, "mandatory": false}])
72
- * .multiple(true)
73
- * .mandatory(false);
74
- * };
75
- */
76
- createField(field, opts) {
77
- this.updateContentTypeSchema(field);
78
-
79
- // Build schema from options provided
80
- if (opts && keys(opts).length) return this.getSchemaFromOptions(opts, field);
81
- return this;
82
- }
83
-
84
- /**
85
- * Edits the field with provided uid.
86
- * @param {string} field Field name to be edited
87
- * @param {Object} opts Options to be passed
88
- * @returns {Field} current instance of field object to chain further methods.
89
- * @example
90
- * module.exports =({ migration })=> {
91
- * const blog = migration.editContentType('blog');
92
- *
93
- * blog.editField('uniqueid')
94
- * .display_name('Unique ID')
95
- * .mandatory(false);
96
- * };
97
- */
98
- editField(field, opts) {
99
- const { EDIT_FIELD } = _actions;
100
- this.updateContentTypeSchema(field, EDIT_FIELD);
101
-
102
- // Build schema from options provided
103
- if (opts && keys(opts).length) return this.getSchemaFromOptions(opts, field);
104
- return this;
105
- }
106
-
107
- /**
108
- * Delete a field from the content type
109
- * @param {string} field Field uid to be deleted
110
- * @returns {Field} current instance of field object to chain further methods.
111
- * @example
112
- * module.exports =({ migration })=> {
113
- * const blog = migration.editContentType('blog');
114
- *
115
- * blog.deleteField('uniqueid');
116
- * };
117
- */
118
- deleteField(field) {
119
- const { DELETE_FIELD } = _actions;
120
- this.updateContentTypeSchema(field, DELETE_FIELD);
121
-
122
- return this;
123
- }
124
-
125
- /**
126
- * Move the field (position of the field in the editor)
127
- * @param {string} field Field uid to be moved
128
- * @returns {Field} current instance of field object to chain further methods.
129
- * @example
130
- * module.exports = ({migration}) => {
131
- * const blog = migration.editContentType('blog');
132
- *
133
- * blog.createField('credits')
134
- * .display_name('Credits')
135
- * .data_type('text')
136
- * .mandatory(false);
137
- *
138
- * blog.createField('references')
139
- * .display_name('References')
140
- * .data_type('text')
141
- * .mandatory(false);
142
- *
143
- * blog.moveField('uniqueid').toTheBottom();
144
- * blog.moveField('references').beforeField('credits');
145
- * blog.moveField('author').toTheTop();
146
- * blog.moveField('url').afterField('author');
147
- * };
148
- */
149
- moveField(field) {
150
- this.fieldToMove = field;
151
- return this;
152
- }
153
-
154
- updateContentTypeSchema(field, subAction) {
155
- const mapInstance = getMapInstance();
156
-
157
- const { uid, action } = this;
158
-
159
- const contentType = get(uid, mapInstance);
160
-
161
- let contentTypeSchema = contentType[action].content_type.schema;
162
- contentTypeSchema = contentTypeSchema || [];
163
-
164
- const schemaObj = getSchema(field, subAction);
165
- contentTypeSchema.push(schemaObj);
166
-
167
- contentType[action].content_type.schema = contentTypeSchema;
168
-
169
- this.field = schemaObj.uid;
170
- }
171
-
172
- // changeFieldId(currentId, newId) { }
173
-
174
- /**
175
- *
176
- * @param {string} value set display name for the field
177
- * @returns {Field} current instance of field object to chain further methods.
178
- */
179
- display_name(value) {
180
- this.buildSchema(display_name, this.field, value);
181
- return this;
182
- }
183
-
184
- /**
185
- *
186
- * @param {string} value Set data type of the field e.g. text, json, boolean
187
- * @returns {Field} current instance of field object to chain further methods.
188
- */
189
- data_type(value) {
190
- this.buildSchema(data_type, this.field, value);
191
- return this;
192
- }
193
-
194
- /**
195
- *
196
- * @param {boolean} value set true when field is mandatory
197
- * @returns {Field} current instance of field object to chain further methods.
198
- */
199
- mandatory(value) {
200
- this.buildSchema(mandatory, this.field, value);
201
- return this;
202
- }
203
-
204
- /**
205
- *
206
- * @param {string|boolean|number} value set true when field is mandatory
207
- * @returns {Field} current instance of field object to chain further methods.
208
- */
209
- default(value) {
210
- this.buildSchema(_default, this.field, value);
211
- return this;
212
- }
213
-
214
- /**
215
- *
216
- * @param {boolean} value set true if field is unique
217
- * @returns {Field} current instance of field object to chain further methods.
218
- */
219
- unique(value) {
220
- this.buildSchema(unique, this.field, value);
221
- return this;
222
- }
223
-
224
- /**
225
- *
226
- * @param {string | string[]} value uid of reference content type set array if ref_multipleContentType true
227
- * @see {@link ref_multipleContentType}
228
- * @returns {Field} current instance of field object to chain further methods.
229
- */
230
- reference_to(value) {
231
- this.buildSchema(reference_to, this.field, value);
232
- return this;
233
- }
234
-
235
- /**
236
- *
237
- * @param {string} value set true if accepts multiple entries as reference
238
- * @returns {Field} current instance of field object to chain further methods.
239
- */
240
- ref_multiple(value) {
241
- this.buildSchema(field_metadata, this.field, { ref_multiple: value, ref_multiple_content_types: true });
242
- return this;
243
- }
244
-
245
- /**
246
- * The 'taxonomies' property should contain at least one taxonomy object
247
- * @param {string | string[]} value list of taxonomies.
248
- * @returns {Field} current instance of field object to chain further methods.
249
- */
250
- taxonomies(value) {
251
- this.buildSchema(taxonomies, this.field, value);
252
- return this;
253
- }
254
-
255
- /**
256
- *
257
- * @param {boolean} value set true if field is multiple
258
- * @returns {Field} current instance of field object to chain further methods.
259
- */
260
- multiple(value) {
261
- this.buildSchema(multiple, this.field, value);
262
- return this;
263
- }
264
-
265
- /**
266
- *
267
- * @param {boolean} value set true if refer to multiple content types
268
- * @returns {Field} current instance of field object to chain further methods.
269
- */
270
- ref_multipleContentType(value) {
271
- this.buildSchema(field_metadata, this.field, { ref_multiple_content_types: value });
272
- return this;
273
- }
274
-
275
- toTheBottom() {
276
- const { fieldToMove, contentTypeService } = this;
277
-
278
- if (!fieldToMove) throw new Error('Cannot access this method directly.');
279
-
280
- contentTypeService.getActions({ action: 'toTheBottom', fieldToMove });
281
- }
282
-
283
- toTheTop() {
284
- const { fieldToMove, contentTypeService } = this;
285
- if (!fieldToMove) throw new Error('Cannot access this method directly.');
286
-
287
- contentTypeService.getActions({ action: 'toTheTop', fieldToMove });
288
- }
289
-
290
- afterField(field) {
291
- const { fieldToMove, contentTypeService } = this;
292
-
293
- if (!fieldToMove) throw new Error('Cannot access this method directly.');
294
-
295
- contentTypeService.getActions({ action: 'afterField', fieldToMove, against: field });
296
- }
297
-
298
- beforeField(field) {
299
- const { fieldToMove, contentTypeService } = this;
300
-
301
- if (!fieldToMove) throw new Error('Cannot access this method directly.');
302
-
303
- contentTypeService.getActions({ action: 'beforeField', fieldToMove, against: field });
304
- }
305
-
306
- buildSchema(prop, field, value) {
307
- const mapInstance = getMapInstance();
308
-
309
- const { uid, action } = this;
310
-
311
- const contentType = get(uid, mapInstance);
312
-
313
- for (const _schema of contentType[action].content_type.schema) {
314
- if (_schema.uid === field) {
315
- _schema[prop] = value;
316
- break;
317
- }
318
- }
319
- }
320
-
321
- /**
322
- * Once you add the fields to content type you can call this method to get the task definition
323
- * @returns {Task} This task definition is to pass to migration.addTask()
324
- * @example
325
- * migration.addTask(foo.getTaskDefinition())
326
- */
327
- getTaskDefinition() {
328
- return this.request;
329
- }
330
-
331
- getSchemaFromOptions(opts, field) {
332
- const allKeys = keys(opts);
333
- allKeys.forEach((_key) => {
334
- this.buildSchema(_key, field, opts[_key]);
335
- });
336
- return this;
337
- }
338
- }
339
-
340
- module.exports = Field;
@@ -1,8 +0,0 @@
1
- 'use strict';
2
-
3
- module.exports = {
4
- ContentType: require('./content-types'),
5
- Field: require('./fields'),
6
- Migration: require('./migration'),
7
- Parser: require('./parser'),
8
- };
@@ -1,33 +0,0 @@
1
- 'use strict';
2
-
3
- // Service
4
- const { LocaleService } = require('../services');
5
-
6
- // Config
7
- const { masterLocale } = require('../config');
8
-
9
- // Utils
10
- const { safePromise } = require('../utils');
11
-
12
- class Locale {
13
- constructor() {
14
- this.localeService = new LocaleService();
15
- }
16
-
17
- async fetchLocales(callback) {
18
- let { master_locale } = masterLocale;
19
-
20
- let { localeService } = this;
21
- let [err, result] = await safePromise(localeService.getLocale());
22
-
23
- if (err) throw new Error(err);
24
-
25
- // Use default code, if no result is found
26
- result = result.length ? result : [master_locale];
27
-
28
- if (callback) return callback(null, result);
29
- return result;
30
- }
31
- }
32
-
33
- module.exports = Locale;