decap-cms-core
Version:
Decap CMS core application, see decap-cms package for the main distribution.
427 lines (419 loc) • 18.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.getFieldsNames = getFieldsNames;
exports.getFileFromSlug = getFileFromSlug;
exports.selectAllowDeletion = selectAllowDeletion;
exports.selectAllowNewEntries = selectAllowNewEntries;
exports.selectDefaultSortableFields = selectDefaultSortableFields;
exports.selectEntryCollectionTitle = selectEntryCollectionTitle;
exports.selectEntryPath = selectEntryPath;
exports.selectEntrySlug = selectEntrySlug;
exports.selectField = selectField;
exports.selectFields = selectFields;
exports.selectFieldsComments = selectFieldsComments;
exports.selectFieldsWithMediaFolders = selectFieldsWithMediaFolders;
exports.selectFileEntryLabel = selectFileEntryLabel;
exports.selectFolderEntryExtension = selectFolderEntryExtension;
exports.selectHasMetaPath = selectHasMetaPath;
exports.selectIdentifier = selectIdentifier;
exports.selectInferredField = selectInferredField;
exports.selectMediaFolders = selectMediaFolders;
exports.selectSortDataPath = selectSortDataPath;
exports.selectSortableFields = selectSortableFields;
exports.selectTemplateName = selectTemplateName;
exports.selectViewFilters = selectViewFilters;
exports.selectViewGroups = selectViewGroups;
exports.traverseFields = traverseFields;
exports.updateFieldByKey = updateFieldByKey;
var _escapeRegExp2 = _interopRequireDefault(require("lodash/escapeRegExp"));
var _get2 = _interopRequireDefault(require("lodash/get"));
var _immutable = require("immutable");
var _decapCmsLibWidgets = require("decap-cms-lib-widgets");
var _consoleError = _interopRequireDefault(require("../lib/consoleError"));
var _config = require("../actions/config");
var _collectionTypes = require("../constants/collectionTypes");
var _commitProps = require("../constants/commitProps");
var _fieldInference = require("../constants/fieldInference");
var _formats = require("../formats/formats");
var _entries = require("./entries");
var _formatters = require("../lib/formatters");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const {
keyToPathArray
} = _decapCmsLibWidgets.stringTemplate;
const defaultState = (0, _immutable.fromJS)({});
function collections(state = defaultState, action) {
switch (action.type) {
case _config.CONFIG_SUCCESS:
{
const collections = action.payload.collections;
let newState = (0, _immutable.OrderedMap)({});
collections.forEach(collection => {
newState = newState.set(collection.name, (0, _immutable.fromJS)(collection));
});
return newState;
}
default:
return state;
}
}
const selectors = {
[_collectionTypes.FOLDER]: {
entryExtension(collection) {
const ext = collection.get('extension') || (0, _get2.default)((0, _formats.getFormatExtensions)(), collection.get('format') || 'frontmatter');
if (!ext) {
throw new Error(`No extension found for format ${collection.get('format')}`);
}
return ext.replace(/^\./, '');
},
fields(collection) {
return collection.get('fields');
},
entryPath(collection, slug) {
const folder = collection.get('folder').replace(/\/$/, '');
return `${folder}/${slug}.${this.entryExtension(collection)}`;
},
entrySlug(collection, path) {
var _path$split$pop;
const folder = collection.get('folder').replace(/\/$/, '');
const slug = (_path$split$pop = path.split(folder + '/').pop()) === null || _path$split$pop === void 0 ? void 0 : _path$split$pop.replace(new RegExp(`\\.${(0, _escapeRegExp2.default)(this.entryExtension(collection))}$`), '');
return slug;
},
allowNewEntries(collection) {
return collection.get('create');
},
allowDeletion(collection) {
return collection.get('delete', true);
},
templateName(collection) {
return collection.get('name');
}
},
[_collectionTypes.FILES]: {
fileForEntry(collection, slug) {
const files = collection.get('files');
return files && files.filter(f => (f === null || f === void 0 ? void 0 : f.get('name')) === slug).get(0);
},
fields(collection, slug) {
const file = this.fileForEntry(collection, slug);
return file && file.get('fields');
},
entryPath(collection, slug) {
const file = this.fileForEntry(collection, slug);
return file && file.get('file');
},
entrySlug(collection, path) {
const file = collection.get('files').filter(f => (f === null || f === void 0 ? void 0 : f.get('file')) === path).get(0);
return file && file.get('name');
},
entryLabel(collection, slug) {
const file = this.fileForEntry(collection, slug);
return file && file.get('label');
},
allowNewEntries() {
return false;
},
allowDeletion(collection) {
return collection.get('delete', false);
},
templateName(_collection, slug) {
return slug;
}
}
};
function getFieldsWithMediaFolders(fields) {
const fieldsWithMediaFolders = fields.reduce((acc, f) => {
if (f.has('media_folder')) {
acc = [...acc, f];
}
if (f.has('fields')) {
var _f$get;
const fields = (_f$get = f.get('fields')) === null || _f$get === void 0 ? void 0 : _f$get.toArray();
acc = [...acc, ...getFieldsWithMediaFolders(fields)];
} else if (f.has('field')) {
const field = f.get('field');
acc = [...acc, ...getFieldsWithMediaFolders([field])];
} else if (f.has('types')) {
var _f$get2;
const types = (_f$get2 = f.get('types')) === null || _f$get2 === void 0 ? void 0 : _f$get2.toArray();
acc = [...acc, ...getFieldsWithMediaFolders(types)];
}
return acc;
}, []);
return fieldsWithMediaFolders;
}
function getFileFromSlug(collection, slug) {
var _collection$get;
return (_collection$get = collection.get('files')) === null || _collection$get === void 0 ? void 0 : _collection$get.toArray().find(f => f.get('name') === slug);
}
function selectFieldsWithMediaFolders(collection, slug) {
if (collection.has('folder')) {
const fields = collection.get('fields').toArray();
return getFieldsWithMediaFolders(fields);
} else if (collection.has('files')) {
var _getFileFromSlug;
const fields = ((_getFileFromSlug = getFileFromSlug(collection, slug)) === null || _getFileFromSlug === void 0 ? void 0 : _getFileFromSlug.get('fields').toArray()) || [];
return getFieldsWithMediaFolders(fields);
}
return [];
}
function selectMediaFolders(config, collection, entry) {
const fields = selectFieldsWithMediaFolders(collection, entry.get('slug'));
const folders = fields.map(f => (0, _entries.selectMediaFolder)(config, collection, entry, f));
if (collection.has('files')) {
const file = getFileFromSlug(collection, entry.get('slug'));
if (file) {
folders.unshift((0, _entries.selectMediaFolder)(config, collection, entry, undefined));
}
}
if (collection.has('media_folder')) {
// stop evaluating media folders at collection level
collection = collection.delete('files');
folders.unshift((0, _entries.selectMediaFolder)(config, collection, entry, undefined));
}
return (0, _immutable.Set)(folders).toArray();
}
function selectFields(collection, slug) {
return selectors[collection.get('type')].fields(collection, slug);
}
function selectFolderEntryExtension(collection) {
return selectors[_collectionTypes.FOLDER].entryExtension(collection);
}
function selectFileEntryLabel(collection, slug) {
return selectors[_collectionTypes.FILES].entryLabel(collection, slug);
}
function selectEntryPath(collection, slug) {
return selectors[collection.get('type')].entryPath(collection, slug);
}
function selectEntrySlug(collection, path) {
return selectors[collection.get('type')].entrySlug(collection, path);
}
function selectAllowNewEntries(collection) {
return selectors[collection.get('type')].allowNewEntries(collection);
}
function selectAllowDeletion(collection) {
return selectors[collection.get('type')].allowDeletion(collection);
}
function selectTemplateName(collection, slug) {
return selectors[collection.get('type')].templateName(collection, slug);
}
function getFieldsNames(fields, prefix = '') {
let names = fields.map(f => `${prefix}${f.get('name')}`);
fields.forEach((f, index) => {
if (f.has('fields')) {
var _f$get3;
const fields = (_f$get3 = f.get('fields')) === null || _f$get3 === void 0 ? void 0 : _f$get3.toArray();
names = [...names, ...getFieldsNames(fields, `${names[index]}.`)];
} else if (f.has('field')) {
const field = f.get('field');
names = [...names, ...getFieldsNames([field], `${names[index]}.`)];
} else if (f.has('types')) {
var _f$get4;
const types = (_f$get4 = f.get('types')) === null || _f$get4 === void 0 ? void 0 : _f$get4.toArray();
names = [...names, ...getFieldsNames(types, `${names[index]}.`)];
}
});
return names;
}
function selectField(collection, key) {
const array = keyToPathArray(key);
let name;
let field;
let fields = collection.get('fields', (0, _immutable.List)()).toArray();
while ((name = array.shift()) && fields) {
var _field, _field3, _field5;
field = fields.find(f => f.get('name') === name);
if ((_field = field) !== null && _field !== void 0 && _field.has('fields')) {
var _field2, _field2$get;
fields = (_field2 = field) === null || _field2 === void 0 ? void 0 : (_field2$get = _field2.get('fields')) === null || _field2$get === void 0 ? void 0 : _field2$get.toArray();
} else if ((_field3 = field) !== null && _field3 !== void 0 && _field3.has('field')) {
var _field4;
fields = [(_field4 = field) === null || _field4 === void 0 ? void 0 : _field4.get('field')];
} else if ((_field5 = field) !== null && _field5 !== void 0 && _field5.has('types')) {
var _field6, _field6$get;
fields = (_field6 = field) === null || _field6 === void 0 ? void 0 : (_field6$get = _field6.get('types')) === null || _field6$get === void 0 ? void 0 : _field6$get.toArray();
}
}
return field;
}
function traverseFields(fields, updater, done = () => false) {
if (done()) {
return fields;
}
fields = fields.map(f => {
const field = updater(f);
if (done()) {
return field;
} else if (field.has('fields')) {
return field.set('fields', traverseFields(field.get('fields'), updater, done));
} else if (field.has('field')) {
return field.set('field', traverseFields((0, _immutable.List)([field.get('field')]), updater, done).get(0));
} else if (field.has('types')) {
return field.set('types', traverseFields(field.get('types'), updater, done));
} else {
return field;
}
}).toList();
return fields;
}
function updateFieldByKey(collection, key, updater) {
const selected = selectField(collection, key);
if (!selected) {
return collection;
}
let updated = false;
function updateAndBreak(f) {
const field = f;
if (field === selected) {
updated = true;
return updater(field);
} else {
return field;
}
}
collection = collection.set('fields', traverseFields(collection.get('fields', (0, _immutable.List)()), updateAndBreak, () => updated));
return collection;
}
function selectIdentifier(collection) {
const identifier = collection.get('identifier_field');
const identifierFields = identifier ? [identifier, ..._fieldInference.IDENTIFIER_FIELDS] : [..._fieldInference.IDENTIFIER_FIELDS];
const fieldNames = getFieldsNames(collection.get('fields', (0, _immutable.List)()).toArray());
return identifierFields.find(id => fieldNames.find(name => name.toLowerCase().trim() === id.toLowerCase().trim()));
}
function selectInferredField(collection, fieldName) {
if (fieldName === 'title' && collection.get('identifier_field')) {
return selectIdentifier(collection);
}
const inferableField = _fieldInference.INFERABLE_FIELDS[fieldName];
const fields = collection.get('fields');
let field;
// If collection has no fields or fieldName is not defined within inferables list, return null
if (!fields || !inferableField) return null;
// Try to return a field of the specified type with one of the synonyms
const mainTypeFields = fields.filter(f => (f === null || f === void 0 ? void 0 : f.get('widget', 'string')) === inferableField.type).map(f => f === null || f === void 0 ? void 0 : f.get('name'));
field = mainTypeFields.filter(f => inferableField.synonyms.indexOf(f) !== -1);
if (field && field.size > 0) return field.first();
// Try to return a field for each of the specified secondary types
const secondaryTypeFields = fields.filter(f => inferableField.secondaryTypes.indexOf(f === null || f === void 0 ? void 0 : f.get('widget', 'string')) !== -1).map(f => f === null || f === void 0 ? void 0 : f.get('name'));
field = secondaryTypeFields.filter(f => inferableField.synonyms.indexOf(f) !== -1);
if (field && field.size > 0) return field.first();
// Try to return the first field of the specified type
if (inferableField.fallbackToFirstField && mainTypeFields.size > 0) return mainTypeFields.first();
// Coundn't infer the field. Show error and return null.
if (inferableField.showError) {
(0, _consoleError.default)(`The Field ${fieldName} is missing for the collection “${collection.get('name')}”`, `Decap CMS tries to infer the entry ${fieldName} automatically, but one couldn't be found for entries of the collection “${collection.get('name')}”. Please check your site configuration.`);
}
return null;
}
function selectEntryCollectionTitle(collection, entry) {
// prefer formatted summary over everything else
const summaryTemplate = collection.get('summary');
if (summaryTemplate) return (0, _formatters.summaryFormatter)(summaryTemplate, entry, collection);
// if the collection is a file collection return the label of the entry
if (collection.get('type') == _collectionTypes.FILES) {
const label = selectFileEntryLabel(collection, entry.get('slug'));
if (label) return label;
}
// try to infer a title field from the entry data
const entryData = entry.get('data');
const titleField = selectInferredField(collection, 'title');
const result = titleField && entryData.getIn(keyToPathArray(titleField));
// if the custom field does not yield a result, fallback to 'title'
if (!result && titleField !== 'title') {
return entryData.getIn(keyToPathArray('title'));
}
return result;
}
function selectDefaultSortableFields(collection, backend, hasIntegration) {
let defaultSortable = _fieldInference.SORTABLE_FIELDS.map(type => {
const field = selectInferredField(collection, type);
if (backend.isGitBackend() && type === 'author' && !field && !hasIntegration) {
// default to commit author if not author field is found
return _commitProps.COMMIT_AUTHOR;
}
return field;
}).filter(Boolean);
if (backend.isGitBackend() && !hasIntegration) {
// always have commit date by default
defaultSortable = [_commitProps.COMMIT_DATE, ...defaultSortable];
}
return defaultSortable;
}
function selectSortableFields(collection, t) {
const fields = collection.get('sortable_fields').toArray().map(key => {
if (key === _commitProps.COMMIT_DATE) {
return {
key,
field: {
name: key,
label: t('collection.defaultFields.updatedOn.label')
}
};
}
const field = selectField(collection, key);
if (key === _commitProps.COMMIT_AUTHOR && !field) {
return {
key,
field: {
name: key,
label: t('collection.defaultFields.author.label')
}
};
}
return {
key,
field: field === null || field === void 0 ? void 0 : field.toJS()
};
}).filter(item => !!item.field).map(item => _objectSpread(_objectSpread({}, item.field), {}, {
key: item.key
}));
return fields;
}
function selectSortDataPath(collection, key) {
if (key === _commitProps.COMMIT_DATE) {
return 'updatedOn';
} else if (key === _commitProps.COMMIT_AUTHOR && !selectField(collection, key)) {
return 'author';
} else {
return `data.${key}`;
}
}
function selectViewFilters(collection) {
const viewFilters = collection.get('view_filters').toJS();
return viewFilters;
}
function selectViewGroups(collection) {
const viewGroups = collection.get('view_groups').toJS();
return viewGroups;
}
function selectFieldsComments(collection, entryMap) {
let fields = [];
if (collection.has('folder')) {
fields = collection.get('fields').toArray();
} else if (collection.has('files')) {
const file = collection.get('files').find(f => (f === null || f === void 0 ? void 0 : f.get('name')) === entryMap.get('slug'));
fields = file.get('fields').toArray();
}
const comments = {};
const names = getFieldsNames(fields);
names.forEach(name => {
const field = selectField(collection, name);
if (field !== null && field !== void 0 && field.has('comment')) {
comments[name] = field.get('comment');
}
});
return comments;
}
function selectHasMetaPath(collection) {
var _collection$get2;
return collection.has('folder') && collection.get('type') === _collectionTypes.FOLDER && collection.has('meta') && ((_collection$get2 = collection.get('meta')) === null || _collection$get2 === void 0 ? void 0 : _collection$get2.has('path'));
}
var _default = exports.default = collections;