@firecms/core
Version:
Awesome Firebase/Firestore-based headless open-source CMS
123 lines (108 loc) • 4.39 kB
text/typescript
import { EntityCallbacks } from "../types";
import { mergeDeep } from "./objects";
export const mergeCallbacks = (
baseCallbacks: EntityCallbacks = {},
pluginCallbacks: EntityCallbacks = {}
): EntityCallbacks | undefined => {
if (!baseCallbacks && !pluginCallbacks) {
return undefined;
}
const mergedCallbacks: EntityCallbacks = {};
// Handle onFetch - returns Entity<M> or Promise<Entity<M>>
if (baseCallbacks.onFetch || pluginCallbacks.onFetch) {
mergedCallbacks.onFetch = async (props) => {
let entity = props.entity;
if (baseCallbacks.onFetch) {
entity = await Promise.resolve(baseCallbacks.onFetch(props));
}
if (pluginCallbacks.onFetch) {
entity = await Promise.resolve(pluginCallbacks.onFetch({
...props,
entity
}));
}
return entity;
};
}
// Handle onSaveSuccess - returns void or Promise<void>
if (baseCallbacks.onSaveSuccess || pluginCallbacks.onSaveSuccess) {
mergedCallbacks.onSaveSuccess = async (props) => {
if (baseCallbacks.onSaveSuccess) {
await Promise.resolve(baseCallbacks.onSaveSuccess(props));
}
if (pluginCallbacks.onSaveSuccess) {
await Promise.resolve(pluginCallbacks.onSaveSuccess(props));
}
};
}
// Handle onSaveFailure - returns void or Promise<void>
if (baseCallbacks.onSaveFailure || pluginCallbacks.onSaveFailure) {
mergedCallbacks.onSaveFailure = async (props) => {
if (baseCallbacks.onSaveFailure) {
await Promise.resolve(baseCallbacks.onSaveFailure(props));
}
if (pluginCallbacks.onSaveFailure) {
await Promise.resolve(pluginCallbacks.onSaveFailure(props));
}
};
}
// Handle onPreSave - returns Partial<EntityValues<M>> or Promise<Partial<EntityValues<M>>>
if (baseCallbacks.onPreSave || pluginCallbacks.onPreSave) {
mergedCallbacks.onPreSave = async (props) => {
let values = props.values;
if (baseCallbacks.onPreSave) {
const baseValues = await Promise.resolve(baseCallbacks.onPreSave(props));
// Use mergeDeep to preserve class instances like EntityReference, GeoPoint
values = mergeDeep(values, baseValues);
}
if (pluginCallbacks.onPreSave) {
const pluginValues = await Promise.resolve(pluginCallbacks.onPreSave({
...props,
values
}));
// Use mergeDeep to preserve class instances like EntityReference, GeoPoint
values = mergeDeep(values, pluginValues);
}
return values;
};
}
// Handle onPreDelete - returns void
if (baseCallbacks.onPreDelete || pluginCallbacks.onPreDelete) {
mergedCallbacks.onPreDelete = (props) => {
if (baseCallbacks.onPreDelete) {
baseCallbacks.onPreDelete(props);
}
if (pluginCallbacks.onPreDelete) {
pluginCallbacks.onPreDelete(props);
}
};
}
// Handle onDelete - returns void
if (baseCallbacks.onDelete || pluginCallbacks.onDelete) {
mergedCallbacks.onDelete = (props) => {
if (baseCallbacks.onDelete) {
baseCallbacks.onDelete(props);
}
if (pluginCallbacks.onDelete) {
pluginCallbacks.onDelete(props);
}
};
}
// Handle onIdUpdate - returns string or Promise<string>
if (baseCallbacks.onIdUpdate || pluginCallbacks.onIdUpdate) {
mergedCallbacks.onIdUpdate = async (props) => {
let id = props.entityId || "";
if (baseCallbacks.onIdUpdate) {
id = await Promise.resolve(baseCallbacks.onIdUpdate(props));
}
if (pluginCallbacks.onIdUpdate) {
id = await Promise.resolve(pluginCallbacks.onIdUpdate({
...props,
entityId: id
}));
}
return id;
};
}
return Object.keys(mergedCallbacks).length > 0 ? mergedCallbacks : undefined;
};