contentful-import
Version:
this tool allows you to import JSON dump exported by contentful-export
280 lines (243 loc) • 10.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.default = pushToSpace;
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _listr = require('listr');
var _listr2 = _interopRequireDefault(_listr);
var _listrVerboseRenderer = require('listr-verbose-renderer');
var _listrVerboseRenderer2 = _interopRequireDefault(_listrVerboseRenderer);
var _logging = require('contentful-batch-libs/dist/logging');
var _listr3 = require('contentful-batch-libs/dist/listr');
var _assets = require('./assets');
var assets = _interopRequireWildcard(_assets);
var _creation = require('./creation');
var creation = _interopRequireWildcard(_creation);
var _publishing = require('./publishing');
var publishing = _interopRequireWildcard(_publishing);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const DEFAULT_CONTENT_STRUCTURE = {
entries: [],
assets: [],
contentTypes: [],
tags: [],
locales: [],
webhooks: [],
editorInterfaces: []
/**
* Pushes all changes to a given space. Handles (un)publishing
* as well as delays after creation and before publishing.
*
* Creates everything in the right order so that a content type for a given entry
* is there when entry creation for that content type is attempted.
*
* Allows only content model or only content pushing.
*
* Options:
* - sourceData: see DEFAULT_CONTENT_STRUCTURE
* - destinationData: see DEFAULT_CONTENT_STRUCTURE
* - client: preconfigured management API client
* - spaceId: ID of space content is being copied to
* - prePublishDelay: milliseconds wait before publishing
* - contentModelOnly: synchronizes only content types and locales
* - skipLocales: skips locales when synchronizing the content model
* - skipContentModel: synchronizes only entries and assets
* - skipContentPublishing: create content but don't publish it
*/
};function pushToSpace({
sourceData,
destinationData = {},
client,
spaceId,
environmentId,
prePublishDelay,
contentModelOnly,
skipContentModel,
skipLocales,
skipContentPublishing,
timeout,
retryLimit,
listrOptions
}) {
sourceData = _extends({}, DEFAULT_CONTENT_STRUCTURE, sourceData);
destinationData = _extends({}, DEFAULT_CONTENT_STRUCTURE, destinationData);
listrOptions = listrOptions || {
renderer: _listrVerboseRenderer2.default
};
return new _listr2.default([{
title: 'Connecting to space',
task: (0, _listr3.wrapTask)((ctx, task) => {
return client.getSpace(spaceId).then(space => {
ctx.space = space;
return space.getEnvironment(environmentId);
}).then(environment => {
ctx.environment = environment;
});
})
}, {
title: 'Importing Locales',
task: (0, _listr3.wrapTask)((ctx, task) => {
return creation.createLocales({ target: ctx.environment, type: 'Locale' }, sourceData.locales, destinationData.locales).then(locales => {
ctx.data.locales = locales;
});
}),
skip: () => skipContentModel || skipLocales
}, {
title: 'Importing Content Types',
task: (0, _listr3.wrapTask)((ctx, task) => {
return creation.createEntities({ target: ctx.environment, type: 'ContentType' }, sourceData.contentTypes, destinationData.contentTypes).then(removeEmptyEntities).then(contentTypes => {
ctx.data.contentTypes = contentTypes;
if (contentTypes.length < 5) {
return _bluebird2.default.delay(prePublishDelay);
}
});
}),
skip: () => skipContentModel
}, {
title: 'Publishing Content Types',
task: (0, _listr3.wrapTask)((ctx, task) => {
return publishEntities(ctx, task, ctx.data.contentTypes, sourceData.contentTypes).then(removeEmptyEntities).then(contentTypes => {
ctx.data.contentTypes = contentTypes;
});
}),
skip: ctx => skipContentModel
}, {
title: 'Importing Tags',
task: (0, _listr3.wrapTask)((ctx, task) => {
return creation.createEntities({ target: ctx.environment, type: 'Tag' }, sourceData.tags, destinationData.tags).then(removeEmptyEntities).then(tags => {
ctx.data.tags = tags;
});
}),
// we remove `tags` from destination data if an error was thrown trying to access them
// this means the user doesn't have access to this feature, skip importing tags
skip: () => !destinationData.tags
}, {
title: 'Importing Editor Interfaces',
task: (0, _listr3.wrapTask)((ctx, task) => {
let contentTypesWithEditorInterface = ctx.data.contentTypes.map(contentType => {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = sourceData.editorInterfaces[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
let editorInterface = _step.value;
if (editorInterface.sys.contentType.sys.id === contentType.sys.id) {
return ctx.environment.getEditorInterfaceForContentType(contentType.sys.id).then(ctEditorInterface => {
_logging.logEmitter.emit('info', `Fetched editor interface for ${contentType.name}`);
ctEditorInterface.controls = editorInterface.controls;
return ctEditorInterface.update();
}).catch(err => {
err.entity = editorInterface;
throw err;
});
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _bluebird2.default.resolve();
});
return _bluebird2.default.all(contentTypesWithEditorInterface).then(removeEmptyEntities).then(editorInterfaces => {
ctx.data.editorInterfaces = editorInterfaces;
});
}),
skip: ctx => skipContentModel || ctx.data.contentTypes.length === 0
}, {
title: 'Importing Assets',
task: (0, _listr3.wrapTask)((ctx, task) => {
return creation.createEntities({ target: ctx.environment, type: 'Asset' }, sourceData.assets, destinationData.assets).then(removeEmptyEntities).then(assetsToProcess => {
return assets.processAssets(assetsToProcess, { timeout, retryLimit });
}).then(removeEmptyEntities).then(assets => {
ctx.data.assets = assets;
if (assets.length < 5) {
return _bluebird2.default.delay(prePublishDelay);
}
});
}),
skip: ctx => contentModelOnly
}, {
title: 'Publishing Assets',
task: (0, _listr3.wrapTask)((ctx, task) => {
return publishEntities(ctx, task, ctx.data.assets, sourceData.assets).then(removeEmptyEntities).then(assets => {
ctx.data.publishedAssets = assets;
});
}),
skip: ctx => contentModelOnly || skipContentPublishing
}, {
title: 'Archiving Assets',
task: (0, _listr3.wrapTask)((ctx, task) => {
return archiveEntities(ctx, task, ctx.data.assets, sourceData.assets).then(removeEmptyEntities).then(assets => {
ctx.data.archivedAssets = assets;
});
}),
skip: ctx => contentModelOnly || skipContentPublishing
}, {
title: 'Importing Content Entries',
task: (0, _listr3.wrapTask)((ctx, task) => {
return creation.createEntries({ target: ctx.environment, skipContentModel }, sourceData.entries, destinationData.entries).then(removeEmptyEntities).then(entries => {
ctx.data.entries = entries;
if (entries.length < 5) {
return _bluebird2.default.delay(prePublishDelay);
}
});
}),
skip: ctx => contentModelOnly
}, {
title: 'Publishing Content Entries',
task: (0, _listr3.wrapTask)((ctx, task) => {
return publishEntities(ctx, task, ctx.data.entries, sourceData.entries).then(removeEmptyEntities).then(entries => {
ctx.data.publishedEntries = entries;
});
}),
skip: ctx => contentModelOnly || skipContentPublishing
}, {
title: 'Archiving Entries',
task: (0, _listr3.wrapTask)((ctx, task) => {
return archiveEntities(ctx, task, ctx.data.entries, sourceData.entries).then(removeEmptyEntities).then(entries => {
ctx.data.archivedEntries = entries;
});
}),
skip: ctx => contentModelOnly || skipContentPublishing
}, {
title: 'Creating Web Hooks',
task: (0, _listr3.wrapTask)((ctx, task) => {
return creation.createEntities({ target: ctx.space, type: 'Webhook' }, sourceData.webhooks, destinationData.webhooks).then(removeEmptyEntities).then(webhooks => {
ctx.data.webhooks = webhooks;
});
}),
skip: ctx => contentModelOnly || environmentId !== 'master' && 'Webhooks can only be imported in master environment'
}], listrOptions);
}
// In case some entity throws an error, we null it in the list to avoid further processing.
// This functions removes the nulled entities from the lists.
function removeEmptyEntities(entityList) {
return entityList.filter(entity => !!entity && entity.sys);
}
function archiveEntities(ctx, task, entities, sourceEntities) {
const entityIdsToArchive = sourceEntities.filter(({ original }) => original.sys.archivedVersion).map(({ original }) => original.sys.id);
const entitiesToArchive = entities.filter(entity => entityIdsToArchive.indexOf(entity.sys.id) !== -1);
return publishing.archiveEntities(entitiesToArchive);
}
function publishEntities(ctx, task, entities, sourceEntities) {
// Find all entities in source content which are published
const entityIdsToPublish = sourceEntities.filter(({ original }) => original.sys.publishedVersion).map(({ original }) => original.sys.id);
// Filter imported entities and publish only these who got published in the source
const entitiesToPublish = entities.filter(entity => entityIdsToPublish.indexOf(entity.sys.id) !== -1);
return publishing.publishEntities(entitiesToPublish);
}
module.exports = exports.default;