contentful-migration
Version:
Migration tooling for contentful
249 lines • 9.04 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = __importDefault(require("./errors"));
const ctErrors = errors_1.default.contentType;
class DuplicateCreate {
validate(intent, context) {
if (!intent.isContentTypeCreate()) {
return;
}
const contentTypeId = intent.getContentTypeId();
if (!context.created.has(contentTypeId)) {
return;
}
return ctErrors.create.CONTENT_TYPE_ALREADY_CREATED(contentTypeId);
}
}
class EditBeforeCreate {
validate(intent, context) {
const isRelevant = intent.isContentTypeUpdate() ||
intent.isContentTransform() ||
intent.isEntryDerive() ||
intent.isEntrySetTags();
if (!isRelevant) {
return;
}
const checkContentTypeId = (contentTypeId) => {
const exists = context.remote.has(contentTypeId) || context.created.has(contentTypeId);
const willBeCreated = context.toBeCreated.has(contentTypeId);
return { contentTypeId, exists, willBeCreated };
};
if (intent.isEntryDerive()) {
return intent
.getRelatedContentTypeIds()
.map(checkContentTypeId)
.filter(({ exists, willBeCreated }) => {
return !exists && willBeCreated;
})
.map(({ contentTypeId }) => ctErrors.deriveEntries.DERIVE_BEFORE_CONTENT_TYPE_CREATE(contentTypeId));
}
const contentTypeId = intent.getContentTypeId();
const { exists, willBeCreated } = checkContentTypeId(contentTypeId);
if (exists || !willBeCreated) {
return;
}
if (intent.isContentTypeUpdate()) {
return ctErrors.update.CONTENT_TYPE_NOT_YET_CREATED(contentTypeId);
}
if (intent.isContentTransform()) {
return ctErrors.transformEntries.TRANSFORM_BEFORE_CONTENT_TYPE_CREATE(contentTypeId);
}
if (intent.isEntrySetTags()) {
return ctErrors.setTagsForEntries.SET_TAGS_BEFORE_CONTENT_TYPE_CREATE(contentTypeId);
}
}
}
class NonExistingEdits {
validate(intent, context) {
const isRelevant = intent.isContentTypeUpdate() ||
intent.isContentTransform() ||
intent.isEntryDerive() ||
intent.isEntrySetTags();
if (!isRelevant) {
return;
}
const checkContentTypeId = (contentTypeId) => {
const exists = context.remote.has(contentTypeId) || context.created.has(contentTypeId);
const willBeCreated = context.toBeCreated.has(contentTypeId);
return { contentTypeId, exists, willBeCreated };
};
if (intent.isEntryDerive()) {
return intent
.getRelatedContentTypeIds()
.map(checkContentTypeId)
.filter(({ exists, willBeCreated }) => {
return !exists && !willBeCreated;
})
.map(({ contentTypeId }) => ctErrors.deriveEntries.CONTENT_TYPE_DOES_NOT_EXIST(contentTypeId));
}
const contentTypeId = intent.getContentTypeId();
const { exists, willBeCreated } = checkContentTypeId(contentTypeId);
if (exists || willBeCreated) {
return;
}
if (intent.isContentTypeUpdate()) {
return ctErrors.update.CONTENT_TYPE_DOES_NOT_EXIST(contentTypeId);
}
if (intent.isContentTransform()) {
return ctErrors.transformEntries.CONTENT_TYPE_DOES_NOT_EXIST(contentTypeId);
}
if (intent.isEntrySetTags()) {
return ctErrors.setTagsForEntries.CONTENT_TYPE_DOES_NOT_EXIST(contentTypeId);
}
}
}
class AlreadyExistingCreates {
constructor() {
this.message = ctErrors.create.CONTENT_TYPE_ALREADY_EXISTS;
}
validate(intent, context) {
if (!intent.isContentTypeCreate()) {
return;
}
const contentTypeId = intent.getContentTypeId();
if (!context.remote.has(contentTypeId)) {
return;
}
return ctErrors.create.CONTENT_TYPE_ALREADY_EXISTS(contentTypeId);
}
}
class NonExistingDeletes {
validate(intent, context) {
if (!intent.isContentTypeDelete()) {
return;
}
const contentTypeId = intent.getContentTypeId();
if (context.remote.has(contentTypeId) || context.deleted.has(contentTypeId)) {
return;
}
return ctErrors.delete.CONTENT_TYPE_DOES_NOT_EXIST(contentTypeId);
}
}
class DuplicateDeletes {
validate(intent, context) {
if (!intent.isContentTypeDelete()) {
return;
}
const contentTypeId = intent.getContentTypeId();
if (!context.deleted.has(contentTypeId)) {
return;
}
return ctErrors.delete.CONTENT_TYPE_ALREADY_DELETED(contentTypeId);
}
}
class EditsAfterDeletes {
validate(intent, context) {
const isRelevant = intent.isFieldUpdate() ||
intent.isContentTypeUpdate() ||
intent.isContentTransform() ||
intent.isEntryDerive() ||
intent.isEntrySetTags();
if (!isRelevant) {
return;
}
const checkContentTypeId = (contentTypeId) => {
const deleted = context.deleted.has(contentTypeId);
return { contentTypeId, deleted };
};
if (intent.isEntryDerive()) {
return intent
.getRelatedContentTypeIds()
.map(checkContentTypeId)
.filter(({ deleted }) => {
return deleted;
})
.map(({ contentTypeId }) => ctErrors.deriveEntries.DERIVE_AFTER_CONTENT_TYPE_DELETE(contentTypeId));
}
const contentTypeId = intent.getContentTypeId();
const { deleted } = checkContentTypeId(contentTypeId);
if (!deleted) {
return;
}
if (intent.isContentTypeUpdate() || intent.isFieldUpdate()) {
return ctErrors.delete.EDIT_AFTER_DELETE(contentTypeId);
}
if (intent.isContentTransform()) {
return ctErrors.transformEntries.TRANSFORM_AFTER_CONTENT_TYPE_DELETE(contentTypeId);
}
if (intent.isEntrySetTags()) {
return ctErrors.setTagsForEntries.SET_TAGS_AFTER_CONTENT_TYPE_CREATE(contentTypeId);
}
}
}
class DeleteCtWithEntries {
validate(intent, context) {
if (!intent.isContentTypeDelete()) {
return;
}
const contentTypeId = intent.getContentTypeId();
const contentType = context.remoteContentTypes.find((ct) => {
return ct.id === contentTypeId;
});
if (!contentType || !contentType.hasEntries) {
return;
}
return ctErrors.delete.HAS_ENTRIES(contentTypeId);
}
}
const checks = [
new DuplicateCreate(),
new EditBeforeCreate(),
new EditsAfterDeletes(),
new NonExistingEdits(),
new NonExistingDeletes(),
new AlreadyExistingCreates(),
new DuplicateDeletes(),
new DeleteCtWithEntries()
];
function default_1(intents, contentTypes) {
const remote = contentTypes.map((ct) => ct.id);
const toBeCreated = intents
.filter((intent) => intent.isContentTypeCreate())
.map((intent) => intent.getContentTypeId());
let context = {
remote: new Set(remote),
created: new Set(),
deleted: new Set(),
toBeCreated: new Set(toBeCreated),
remoteContentTypes: contentTypes
};
let errors = [];
for (const intent of intents) {
let error;
for (const check of checks) {
error = check.validate(intent, context);
if (error && error.length) {
// proceed with next intent
break;
}
}
if (error) {
const errorList = Array.isArray(error) ? error : [error];
const invalidActions = errorList.map((error) => ({
type: 'InvalidAction',
message: error,
details: { intent }
}));
errors = errors.concat(invalidActions);
// do not update context
continue;
}
const contentTypeId = intent.getContentTypeId();
if (intent.isContentTypeCreate()) {
context.created.add(contentTypeId);
context.toBeCreated.delete(contentTypeId);
context.deleted.delete(contentTypeId);
}
if (intent.isContentTypeDelete()) {
context.deleted.add(contentTypeId);
context.remote.delete(contentTypeId);
context.created.delete(contentTypeId);
}
}
return errors;
}
exports.default = default_1;
//# sourceMappingURL=content-type.js.map