@strapi/utils
Version:
Shared utilities for the Strapi packages
202 lines (198 loc) • 8.03 kB
JavaScript
;
var _ = require('lodash');
var fp = require('lodash/fp');
const SINGLE_TYPE = 'singleType';
const COLLECTION_TYPE = 'collectionType';
const ID_ATTRIBUTE = 'id';
const DOC_ID_ATTRIBUTE = 'documentId';
const PUBLISHED_AT_ATTRIBUTE = 'publishedAt';
const CREATED_BY_ATTRIBUTE = 'createdBy';
const UPDATED_BY_ATTRIBUTE = 'updatedBy';
const CREATED_AT_ATTRIBUTE = 'createdAt';
const UPDATED_AT_ATTRIBUTE = 'updatedAt';
const constants = {
ID_ATTRIBUTE,
DOC_ID_ATTRIBUTE,
PUBLISHED_AT_ATTRIBUTE,
CREATED_BY_ATTRIBUTE,
UPDATED_BY_ATTRIBUTE,
CREATED_AT_ATTRIBUTE,
UPDATED_AT_ATTRIBUTE,
SINGLE_TYPE,
COLLECTION_TYPE
};
const getTimestamps = (model)=>{
const attributes = [];
if (fp.has(CREATED_AT_ATTRIBUTE, model.attributes)) {
attributes.push(CREATED_AT_ATTRIBUTE);
}
if (fp.has(UPDATED_AT_ATTRIBUTE, model.attributes)) {
attributes.push(UPDATED_AT_ATTRIBUTE);
}
return attributes;
};
const getCreatorFields = (model)=>{
const attributes = [];
if (fp.has(CREATED_BY_ATTRIBUTE, model.attributes)) {
attributes.push(CREATED_BY_ATTRIBUTE);
}
if (fp.has(UPDATED_BY_ATTRIBUTE, model.attributes)) {
attributes.push(UPDATED_BY_ATTRIBUTE);
}
return attributes;
};
const getNonWritableAttributes = (model)=>{
if (!model) return [];
const nonWritableAttributes = _.reduce(model.attributes, (acc, attr, attrName)=>attr.writable === false ? acc.concat(attrName) : acc, []);
return _.uniq([
ID_ATTRIBUTE,
DOC_ID_ATTRIBUTE,
...getTimestamps(model),
...nonWritableAttributes
]);
};
const getWritableAttributes = (model)=>{
if (!model) return [];
return _.difference(Object.keys(model.attributes), getNonWritableAttributes(model));
};
const isWritableAttribute = (model, attributeName)=>{
return getWritableAttributes(model).includes(attributeName);
};
const getNonVisibleAttributes = (model)=>{
const nonVisibleAttributes = _.reduce(model.attributes, (acc, attr, attrName)=>attr.visible === false ? acc.concat(attrName) : acc, []);
return _.uniq([
ID_ATTRIBUTE,
DOC_ID_ATTRIBUTE,
...getTimestamps(model),
...nonVisibleAttributes
]);
};
const getVisibleAttributes = (model)=>{
return _.difference(_.keys(model.attributes), getNonVisibleAttributes(model));
};
const isVisibleAttribute = (model, attributeName)=>{
return getVisibleAttributes(model).includes(attributeName);
};
const getOptions = (model)=>_.assign({
draftAndPublish: false
}, _.get(model, 'options', {}));
const hasDraftAndPublish = (model)=>_.get(model, 'options.draftAndPublish', false) === true;
const isDraft = (data, model)=>hasDraftAndPublish(model) && _.get(data, PUBLISHED_AT_ATTRIBUTE) === null;
const isSchema = (data)=>{
return typeof data === 'object' && data !== null && 'modelType' in data && typeof data.modelType === 'string' && [
'component',
'contentType'
].includes(data.modelType);
};
const isComponentSchema = (data)=>{
return isSchema(data) && data.modelType === 'component';
};
const isContentTypeSchema = (data)=>{
return isSchema(data) && data.modelType === 'contentType';
};
const isSingleType = ({ kind = COLLECTION_TYPE })=>kind === SINGLE_TYPE;
const isCollectionType = ({ kind = COLLECTION_TYPE })=>kind === COLLECTION_TYPE;
const isKind = (kind)=>(model)=>model.kind === kind;
const getStoredPrivateAttributes = (model)=>fp.union(strapi?.config?.get('api.responses.privateAttributes', []) ?? [], fp.getOr([], 'options.privateAttributes', model));
const getPrivateAttributes = (model)=>{
return _.union(getStoredPrivateAttributes(model), _.keys(_.pickBy(model.attributes, (attr)=>!!attr.private)));
};
const isPrivateAttribute = (model, attributeName)=>{
if (model?.attributes?.[attributeName]?.private === true) {
return true;
}
return getStoredPrivateAttributes(model).includes(attributeName);
};
const isScalarAttribute = (attribute)=>{
return attribute && ![
'media',
'component',
'relation',
'dynamiczone'
].includes(attribute.type);
};
const getDoesAttributeRequireValidation = (attribute)=>{
return attribute.required || attribute.unique || Object.prototype.hasOwnProperty.call(attribute, 'max') || Object.prototype.hasOwnProperty.call(attribute, 'min') || Object.prototype.hasOwnProperty.call(attribute, 'maxLength') || Object.prototype.hasOwnProperty.call(attribute, 'minLength');
};
const isMediaAttribute = (attribute)=>attribute?.type === 'media';
const isRelationalAttribute = (attribute)=>attribute?.type === 'relation';
const HAS_RELATION_REORDERING = [
'manyToMany',
'manyToOne',
'oneToMany'
];
const hasRelationReordering = (attribute)=>isRelationalAttribute(attribute) && HAS_RELATION_REORDERING.includes(attribute.relation);
const isComponentAttribute = (attribute)=>[
'component',
'dynamiczone'
].includes(attribute?.type);
const isDynamicZoneAttribute = (attribute)=>!!attribute && attribute.type === 'dynamiczone';
const isMorphToRelationalAttribute = (attribute)=>{
return !!attribute && isRelationalAttribute(attribute) && attribute.relation?.startsWith?.('morphTo');
};
const getComponentAttributes = (schema)=>{
return _.reduce(schema.attributes, (acc, attr, attrName)=>{
if (isComponentAttribute(attr)) acc.push(attrName);
return acc;
}, []);
};
const getScalarAttributes = (schema)=>{
return _.reduce(schema.attributes, (acc, attr, attrName)=>{
if (isScalarAttribute(attr)) acc.push(attrName);
return acc;
}, []);
};
const getRelationalAttributes = (schema)=>{
return _.reduce(schema.attributes, (acc, attr, attrName)=>{
if (isRelationalAttribute(attr)) acc.push(attrName);
return acc;
}, []);
};
/**
* Checks if an attribute is of type `type`
* @param {object} attribute
* @param {string} type
*/ const isTypedAttribute = (attribute, type)=>{
return _.has(attribute, 'type') && attribute.type === type;
};
/**
* Returns a route prefix for a contentType
* @param {object} contentType
* @returns {string}
*/ const getContentTypeRoutePrefix = (contentType)=>{
return isSingleType(contentType) ? _.kebabCase(contentType.info.singularName) : _.kebabCase(contentType.info.pluralName);
};
exports.constants = constants;
exports.getComponentAttributes = getComponentAttributes;
exports.getContentTypeRoutePrefix = getContentTypeRoutePrefix;
exports.getCreatorFields = getCreatorFields;
exports.getDoesAttributeRequireValidation = getDoesAttributeRequireValidation;
exports.getNonVisibleAttributes = getNonVisibleAttributes;
exports.getNonWritableAttributes = getNonWritableAttributes;
exports.getOptions = getOptions;
exports.getPrivateAttributes = getPrivateAttributes;
exports.getRelationalAttributes = getRelationalAttributes;
exports.getScalarAttributes = getScalarAttributes;
exports.getTimestamps = getTimestamps;
exports.getVisibleAttributes = getVisibleAttributes;
exports.getWritableAttributes = getWritableAttributes;
exports.hasDraftAndPublish = hasDraftAndPublish;
exports.hasRelationReordering = hasRelationReordering;
exports.isCollectionType = isCollectionType;
exports.isComponentAttribute = isComponentAttribute;
exports.isComponentSchema = isComponentSchema;
exports.isContentTypeSchema = isContentTypeSchema;
exports.isDraft = isDraft;
exports.isDynamicZoneAttribute = isDynamicZoneAttribute;
exports.isKind = isKind;
exports.isMediaAttribute = isMediaAttribute;
exports.isMorphToRelationalAttribute = isMorphToRelationalAttribute;
exports.isPrivateAttribute = isPrivateAttribute;
exports.isRelationalAttribute = isRelationalAttribute;
exports.isScalarAttribute = isScalarAttribute;
exports.isSchema = isSchema;
exports.isSingleType = isSingleType;
exports.isTypedAttribute = isTypedAttribute;
exports.isVisibleAttribute = isVisibleAttribute;
exports.isWritableAttribute = isWritableAttribute;
//# sourceMappingURL=content-types.js.map