@nebula-db/plugin-versioning
Version:
Document versioning plugin for NebulaDB
61 lines (60 loc) • 1.81 kB
JavaScript
// src/index.ts
function createVersioningPlugin(options = {}) {
const {
versionField = "_version",
timestampField = "_updatedAt",
historyCollectionSuffix = "_history",
maxVersions = 0
// 0 means unlimited
} = options;
let db;
return {
name: "versioning",
onInit(database) {
db = database;
},
async onBeforeInsert(collection, doc) {
return {
...doc,
[versionField]: 1,
[timestampField]: (/* @__PURE__ */ new Date()).toISOString()
};
},
async onBeforeUpdate(collection, query, update) {
const docsToUpdate = await db.collection(collection).find(query);
if (docsToUpdate.length === 0) {
return [query, update];
}
const historyCollection = db.collection(`${collection}${historyCollectionSuffix}`);
for (const doc of docsToUpdate) {
await historyCollection.insert({
...doc,
_originalId: doc.id,
id: `${doc.id}_v${doc[versionField] || 1}`
});
if (maxVersions > 0) {
const history = await historyCollection.find({ _originalId: doc.id });
if (history.length > maxVersions) {
history.sort((a, b) => (b[versionField] || 0) - (a[versionField] || 0));
for (let i = maxVersions; i < history.length; i++) {
await historyCollection.delete({ id: history[i].id });
}
}
}
}
const newUpdate = { ...update };
if (!newUpdate.$set) {
newUpdate.$set = {};
}
if (!newUpdate.$inc) {
newUpdate.$inc = {};
}
newUpdate.$inc[versionField] = 1;
newUpdate.$set[timestampField] = (/* @__PURE__ */ new Date()).toISOString();
return [query, newUpdate];
}
};
}
export {
createVersioningPlugin
};