@stackbit/cms-sanity
Version:
Stackbit Sanity CMS Interface
484 lines • 19.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertAssets = exports.convertDocuments = exports.filterScheduledActions = exports.convertScheduledAction = exports.convertAndFilterScheduledActions = exports.isDraftId = exports.getDraftObjectId = exports.getPureObjectId = exports.DRAFT_ID_PREFIX = void 0;
const lodash_1 = __importDefault(require("lodash"));
const utils_1 = require("./utils");
exports.DRAFT_ID_PREFIX = 'drafts.';
function getPureObjectId(objectId) {
return objectId.replace(/^drafts\./, '');
}
exports.getPureObjectId = getPureObjectId;
function getDraftObjectId(objectId) {
return isDraftId(objectId) ? objectId : `${exports.DRAFT_ID_PREFIX}${objectId}`;
}
exports.getDraftObjectId = getDraftObjectId;
function isDraftId(objectId) {
return objectId && objectId.startsWith(exports.DRAFT_ID_PREFIX);
}
exports.isDraftId = isDraftId;
function convertAndFilterScheduledActions(sanitySchedules) {
const allScheduledActions = sanitySchedules.map((schedule) => convertScheduledAction(schedule));
return filterScheduledActions(allScheduledActions);
}
exports.convertAndFilterScheduledActions = convertAndFilterScheduledActions;
function convertScheduledAction(sanitySchedule) {
return {
id: sanitySchedule.id,
name: sanitySchedule.name,
state: getScheduledActionState(sanitySchedule),
action: sanitySchedule.action,
createdAt: sanitySchedule.createdAt,
createdBy: sanitySchedule.author,
executeAt: sanitySchedule.executeAt || sanitySchedule.executedAt || '',
documentIds: sanitySchedule.documents.map((doc) => doc.documentId)
};
}
exports.convertScheduledAction = convertScheduledAction;
function filterScheduledActions(scheduledActions) {
const cutoffDate = new Date();
cutoffDate.setMonth(cutoffDate.getMonth() - 1);
const cutoffDateStr = cutoffDate.toISOString();
return scheduledActions.filter((scheduledAction) => scheduledAction.state !== 'cancelled' && scheduledAction.executeAt.localeCompare(cutoffDateStr) > 0);
}
exports.filterScheduledActions = filterScheduledActions;
function convertDocuments({ documents, getModelByName, documentsHistory, studioUrl }) {
const publishedDocuments = lodash_1.default.keyBy(documents.filter((document) => !isDraftId(document._id)), '_id');
const draftDocuments = lodash_1.default.keyBy(documents.filter((document) => isDraftId(document._id)), (document) => getPureObjectId(document._id));
return lodash_1.default.uniq([...lodash_1.default.keys(publishedDocuments), ...lodash_1.default.keys(draftDocuments)])
.map((documentId) => {
const docId = draftDocuments[documentId]?._id;
const draftDocumentHistory = docId ? documentsHistory?.[docId] : undefined;
return convertDocument({
publishedDocument: publishedDocuments[documentId],
draftDocument: draftDocuments[documentId],
getModelByName,
documentHistory: draftDocumentHistory,
studioUrl
});
})
.filter((document) => !!document);
}
exports.convertDocuments = convertDocuments;
function convertDocument({ publishedDocument, draftDocument, getModelByName, documentHistory, studioUrl }) {
const document = draftDocument || publishedDocument;
if (!document) {
return;
}
const model = getModelByName(document._type);
if (!model) {
return;
}
const pureObjectId = getPureObjectId(document._id);
const manageUrl = studioUrl ? `${studioUrl}/desk/${model.name};${pureObjectId}` : '';
return {
type: 'document',
id: pureObjectId,
manageUrl,
modelName: model.name,
...commonFields({ publishedDocument, draftDocument, documentHistory }),
fields: convertFields({
object: document,
modelFields: model.fields,
rootModel: model,
modelFieldPath: [],
getModelByName
}),
context: {
draftDocument,
publishedDocument
}
};
}
function convertAssets({ assets, documentsHistory }) {
const publishedDocuments = lodash_1.default.keyBy(assets.filter((document) => !isDraftId(document._id)), '_id');
const draftDocuments = lodash_1.default.keyBy(assets.filter((document) => isDraftId(document._id)), (document) => getPureObjectId(document._id));
return lodash_1.default.uniq([...lodash_1.default.keys(publishedDocuments), ...lodash_1.default.keys(draftDocuments)]).map((documentId) => {
const publishedDocument = publishedDocuments[documentId];
const draftDocument = draftDocuments[documentId];
const document = (draftDocument || publishedDocument);
const pureObjectId = getPureObjectId(document._id);
const draftDocId = draftDocument?._id;
const draftDocumentHistory = draftDocId ? documentsHistory[draftDocId] : undefined;
return {
type: 'asset',
id: pureObjectId,
manageUrl: document.url,
...commonFields({ draftDocument, publishedDocument, documentHistory: draftDocumentHistory }),
fields: {
title: {
type: 'string',
value: document.originalFilename
},
file: {
type: 'assetFile',
url: document.url,
fileName: document.originalFilename,
contentType: document.mimeType,
dimensions: document.metadata?.dimensions
}
},
context: {
publishedDocument,
draftDocument
}
};
});
}
exports.convertAssets = convertAssets;
function convertFields({ object, modelFields, rootModel, modelFieldPath, getModelByName }) {
const fieldsByName = lodash_1.default.keyBy(modelFields, 'name');
const result = {};
for (const fieldName in fieldsByName) {
const value = object[fieldName];
const modelField = fieldsByName[fieldName];
if (!modelField) {
continue;
}
const field = convertFieldType({
value,
modelField,
rootModel,
modelFieldPath: modelFieldPath.concat(fieldName),
getModelByName
});
if (field) {
result[fieldName] = field;
}
}
return result;
}
function convertFieldType({ value, modelField, rootModel, modelFieldPath, getModelByName }) {
switch (modelField.type) {
case 'string':
case 'text':
case 'html':
case 'url':
case 'boolean':
case 'number':
case 'date':
case 'datetime':
case 'enum':
case 'json':
case 'style':
case 'markdown': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: modelField.type },
documentFieldSpecificProps: (value) => {
if (lodash_1.default.isUndefined(value)) {
return undefined;
}
return { value };
}
});
}
case 'cross-reference': {
return undefined;
}
case 'list': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: 'list' },
documentFieldSpecificProps: (value) => {
return {
items: lodash_1.default.reduce(value, (accum, item) => {
const itemModel = (0, utils_1.getItemTypeForListItem)(item, modelField);
if (!itemModel) {
return accum;
}
const documentField = convertFieldType({
value: item,
modelField: itemModel,
rootModel,
modelFieldPath: modelFieldPath.concat('items'),
getModelByName
});
if (!documentField) {
return accum;
}
return accum.concat(documentField);
}, [])
};
}
});
}
case 'object': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: 'object' },
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
fields: convertFields({
object: value,
modelFields: modelField.fields,
rootModel,
modelFieldPath,
getModelByName
})
};
}
});
}
case 'model': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: 'model' },
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
const modelName = (0, utils_1.resolvedFieldType)({ sanityFieldType: value._type, model: rootModel, modelFieldPath });
const model = getModelByName(modelName);
if (!model) {
return undefined;
}
return {
modelName: model.name,
fields: convertFields({
object: value,
modelFields: model.fields,
rootModel: model,
modelFieldPath: [],
getModelByName
})
};
}
});
}
case 'reference': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: {
type: 'reference',
refType: 'document'
},
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
let refId = lodash_1.default.get(value, '_ref', null);
if (refId) {
refId = refId.replace(/^drafts\./, '');
}
return {
refId
};
}
});
}
case 'color': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: 'color' },
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
value: lodash_1.default.get(value, 'hex')
};
}
});
}
case 'richText': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: 'richText' },
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
value: value,
hint: flattenRichText(value).substring(0, 200)
};
}
});
}
case 'image': {
if (modelField.source && ['cloudinary', 'aprimo', 'bynder'].includes(modelField.source)) {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: {
type: 'image',
source: modelField.source
},
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
sourceData: value,
...(modelField.source === 'bynder'
? {
fields: {
title: {
type: 'string',
value: value?.name
},
url: {
type: 'string',
value: value?.previewImg
}
}
}
: null)
};
}
});
}
return createDocumentField({
fieldValue: value,
// The modelField.type and documentField.type should match.
// However, in the case of the modelField.type === 'image',
// it is OK to have the documentField.type === 'reference'
// and documentField.type === 'asset.
modelField: modelField,
documentFieldBaseProps: {
type: 'reference',
refType: 'asset'
},
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
refId: lodash_1.default.get(value, 'asset._ref')
};
}
});
}
case 'file': {
return createDocumentField({
fieldValue: value,
// The modelField.type and documentField.type should match.
// However, in the case of the modelField.type === 'file',
// it is OK to have the documentField.type === 'reference'
// and documentField.type === 'asset.
modelField: modelField,
documentFieldBaseProps: {
type: 'reference',
refType: 'asset'
},
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
refId: lodash_1.default.get(value, 'asset._ref')
};
}
});
}
case 'slug': {
return createDocumentField({
fieldValue: value,
modelField: modelField,
documentFieldBaseProps: { type: 'slug' },
documentFieldSpecificProps: (value) => {
if (!value) {
return undefined;
}
return {
value: lodash_1.default.get(value, 'current')
};
}
});
}
default: {
const _exhaustiveCheck = modelField;
return _exhaustiveCheck;
}
}
}
function commonFields({ draftDocument, publishedDocument, documentHistory }) {
const document = draftDocument ?? publishedDocument;
if (!document) {
throw new Error('No draft or published document found');
}
const isDraft = isDraftId(document._id);
let status;
if (isDraft && !publishedDocument) {
status = 'added';
}
else {
status = isDraft ? 'modified' : 'published';
}
const updatedByList = documentHistory?.map(({ author }) => author);
return {
status,
createdAt: document._createdAt,
// createdBy: createdByEmail,
updatedAt: document._updatedAt,
updatedBy: lodash_1.default.uniq(updatedByList)
};
}
function createDocumentField({ fieldValue, modelField, documentFieldBaseProps, documentFieldSpecificProps }) {
if ((0, utils_1.isLocalizedModelField)(modelField)) {
if (!Array.isArray(fieldValue)) {
return undefined;
}
return {
...documentFieldBaseProps,
localized: true,
locales: lodash_1.default.reduce(fieldValue, (accum, localizedItem) => {
if (localizedItem === null || typeof localizedItem === 'undefined') {
return accum;
}
const fieldSpecificProps = documentFieldSpecificProps(localizedItem.value);
if (!fieldSpecificProps) {
return accum;
}
accum[localizedItem._key] = {
locale: localizedItem._key,
...fieldSpecificProps
};
return accum;
}, {})
};
}
const fieldSpecificProps = documentFieldSpecificProps(fieldValue);
if (!fieldSpecificProps) {
return undefined;
}
return {
...documentFieldBaseProps,
...fieldSpecificProps
};
}
function flattenRichText(richTextArray) {
return lodash_1.default.reduce(richTextArray, (accum, node) => {
if (lodash_1.default.get(node, '_type') !== 'block') {
return accum;
}
const children = lodash_1.default.get(node, 'children', []);
return (accum +
lodash_1.default.reduce(children, (accum, node) => {
if (lodash_1.default.get(node, '_type') !== 'span') {
return accum;
}
return accum + lodash_1.default.get(node, 'text', '');
}, ''));
}, '');
}
function getScheduledActionState(sanitySchedule) {
if (sanitySchedule.state === 'cancelled' && sanitySchedule.stateReason !== 'cancelled by user') {
return 'failed';
}
return sanitySchedule.state;
}
//# sourceMappingURL=sanity-document-converter.js.map