Files
outline/server/queues/processors/BacklinksProcessor.ts
Tom Moor db73879918 Assorted cleanup, minor bug fixes, styling fixes, eslint rules (#5165
* fix: Logic error in toast
fix: Remove useless component

* fix: Logout not clearing all stores

* Add icons to notification settings

* Add eslint rule to enforce spaced comment

* Add eslint rule for arrow-body-style

* Add eslint rule to enforce self-closing components

* Add menu to api key settings
Fix: Deleting webhook subscription does not remove from UI
Split webhook subscriptions into active and inactive
Styling updates
2023-04-08 05:25:20 -07:00

112 lines
3.0 KiB
TypeScript

import { Op } from "sequelize";
import { Document, Backlink } from "@server/models";
import { Event, DocumentEvent, RevisionEvent } from "@server/types";
import parseDocumentIds from "@server/utils/parseDocumentIds";
import BaseProcessor from "./BaseProcessor";
export default class BacklinksProcessor extends BaseProcessor {
static applicableEvents: Event["name"][] = [
"documents.publish",
"documents.update",
"documents.delete",
];
async perform(event: DocumentEvent | RevisionEvent) {
switch (event.name) {
case "documents.publish": {
const document = await Document.findByPk(event.documentId);
if (!document) {
return;
}
const linkIds = parseDocumentIds(document.text);
await Promise.all(
linkIds.map(async (linkId) => {
const linkedDocument = await Document.findByPk(linkId);
if (!linkedDocument || linkedDocument.id === event.documentId) {
return;
}
await Backlink.findOrCreate({
where: {
documentId: linkedDocument.id,
reverseDocumentId: event.documentId,
},
defaults: {
userId: document.lastModifiedById,
},
});
})
);
break;
}
case "documents.update": {
const document = await Document.findByPk(event.documentId);
if (!document) {
return;
}
// backlinks are only created for published documents
if (!document.publishedAt) {
return;
}
const linkIds = parseDocumentIds(document.text);
const linkedDocumentIds: string[] = [];
// create or find existing backlink records for referenced docs
await Promise.all(
linkIds.map(async (linkId) => {
const linkedDocument = await Document.findByPk(linkId);
if (!linkedDocument || linkedDocument.id === event.documentId) {
return;
}
await Backlink.findOrCreate({
where: {
documentId: linkedDocument.id,
reverseDocumentId: event.documentId,
},
defaults: {
userId: document.lastModifiedById,
},
});
linkedDocumentIds.push(linkedDocument.id);
})
);
// delete any backlinks that no longer exist
await Backlink.destroy({
where: {
documentId: {
[Op.notIn]: linkedDocumentIds,
},
reverseDocumentId: event.documentId,
},
});
break;
}
case "documents.delete": {
await Backlink.destroy({
where: {
[Op.or]: [
{
reverseDocumentId: event.documentId,
},
{
documentId: event.documentId,
},
],
},
});
break;
}
default:
}
}
}