mirror of
https://github.com/outline/outline.git
synced 2026-08-03 13:27:25 +03:00
perf: Reduce data loading on revisions.list endpoint (#13202)
* perf: Reduce data loading on revisions.list endpoint * test: Cover includeContent option on Document.findByPk Also fixes a JSDoc typo on the includeViews option. --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -300,6 +300,23 @@ describe("#findByPk", () => {
|
||||
).rejects.toThrow(EmptyResultError);
|
||||
});
|
||||
|
||||
it("should omit content columns when includeContent is false", async () => {
|
||||
const document = await buildDocument({ text: "# Heading" });
|
||||
|
||||
const response = await Document.findByPk(document.id, {
|
||||
includeContent: false,
|
||||
});
|
||||
expect(response?.id).toBe(document.id);
|
||||
expect(response?.title).toBe(document.title);
|
||||
expect(response?.dataValues.content).toBeUndefined();
|
||||
expect(response?.dataValues.text).toBeUndefined();
|
||||
expect(response?.dataValues.state).toBeUndefined();
|
||||
|
||||
const withContent = await Document.findByPk(document.id);
|
||||
expect(withContent?.dataValues.content).toBeDefined();
|
||||
expect(withContent?.dataValues.text).toBeDefined();
|
||||
});
|
||||
|
||||
it("should not allow a passed where to override the id", async () => {
|
||||
const document = await buildDocument();
|
||||
const other = await buildDocument();
|
||||
|
||||
@@ -99,7 +99,12 @@ type AdditionalFindOptions = {
|
||||
userId?: string;
|
||||
/** Whether to include the state column in the attributes. */
|
||||
includeState?: boolean;
|
||||
/** Whether to views (default: true). */
|
||||
/**
|
||||
* Whether to include the content columns in the attributes (default: true).
|
||||
* Pass false when the document is only needed for authorization.
|
||||
*/
|
||||
includeContent?: boolean;
|
||||
/** Whether to include views (default: true). */
|
||||
includeViews?: boolean;
|
||||
/** Whether to reject the query if no document is found. */
|
||||
rejectOnEmpty?: boolean | Error;
|
||||
@@ -151,6 +156,11 @@ interface QueryGeneratorWithWhere {
|
||||
include: [stateIfContentEmpty],
|
||||
},
|
||||
},
|
||||
withoutContent: {
|
||||
attributes: {
|
||||
exclude: ["state", "content", "text"],
|
||||
},
|
||||
},
|
||||
withCollection: {
|
||||
include: [
|
||||
{
|
||||
@@ -797,15 +807,21 @@ class Document extends ArchivableModel<
|
||||
const {
|
||||
includeViews = true,
|
||||
includeState = false,
|
||||
includeContent = true,
|
||||
userId,
|
||||
...rest
|
||||
} = options;
|
||||
|
||||
let contentScope = includeState ? "withState" : "withoutState";
|
||||
if (!includeContent) {
|
||||
contentScope = "withoutContent";
|
||||
}
|
||||
|
||||
// allow default preloading of collection membership if `userId` is passed in find options
|
||||
// almost every endpoint needs the collection membership to determine policy permissions.
|
||||
const scope = this.scope([
|
||||
"withDrafts",
|
||||
includeState ? "withState" : "withoutState",
|
||||
contentScope,
|
||||
...((includeViews
|
||||
? [
|
||||
{
|
||||
|
||||
@@ -42,11 +42,14 @@ router.post(
|
||||
|
||||
const document = await Document.findByPk(revision.documentId, {
|
||||
userId: user.id,
|
||||
includeContent: false,
|
||||
includeViews: false,
|
||||
});
|
||||
authorize(user, "listRevisions", document);
|
||||
} else if (documentId) {
|
||||
const document = await Document.findByPk(documentId, {
|
||||
userId: user.id,
|
||||
includeViews: false,
|
||||
});
|
||||
authorize(user, "listRevisions", document);
|
||||
revision = Revision.buildFromDocument(document);
|
||||
@@ -76,6 +79,8 @@ router.post(
|
||||
});
|
||||
const document = await Document.findByPk(revision.documentId, {
|
||||
userId: user.id,
|
||||
includeContent: false,
|
||||
includeViews: false,
|
||||
});
|
||||
authorize(user, "update", document);
|
||||
authorize(user, "update", revision);
|
||||
@@ -110,6 +115,8 @@ router.post(
|
||||
});
|
||||
const document = await Document.findByPk(revision.documentId, {
|
||||
userId: user.id,
|
||||
includeContent: false,
|
||||
includeViews: false,
|
||||
});
|
||||
authorize(user, "read", document);
|
||||
authorize(user, "delete", revision);
|
||||
@@ -139,6 +146,8 @@ router.post(
|
||||
const document = await Document.findByPk(revision.documentId, {
|
||||
userId: user.id,
|
||||
rejectOnEmpty: true,
|
||||
includeContent: false,
|
||||
includeViews: false,
|
||||
});
|
||||
authorize(user, "listRevisions", document);
|
||||
|
||||
@@ -239,10 +248,15 @@ router.post(
|
||||
const document = await Document.findByPk(documentId, {
|
||||
userId: user.id,
|
||||
paranoid: false,
|
||||
includeContent: false,
|
||||
includeViews: false,
|
||||
});
|
||||
authorize(user, "listRevisions", document);
|
||||
|
||||
const revisions = await Revision.findAll({
|
||||
attributes: {
|
||||
exclude: ["content", "text"],
|
||||
},
|
||||
where: {
|
||||
documentId: document.id,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user