mirror of
https://github.com/outline/outline.git
synced 2025-12-21 10:39:41 -06:00
Truncate Notion document titles to fit validation limits (#9041)
closes #9040
This commit is contained in:
@@ -15,9 +15,11 @@ import {
|
||||
import { RateLimit } from "async-sema";
|
||||
import emojiRegex from "emoji-regex";
|
||||
import compact from "lodash/compact";
|
||||
import truncate from "lodash/truncate";
|
||||
import { z } from "zod";
|
||||
import { Second } from "@shared/utils/time";
|
||||
import { isUrl } from "@shared/utils/urls";
|
||||
import { CollectionValidation, DocumentValidation } from "@shared/validations";
|
||||
import { NotionUtils } from "../shared/NotionUtils";
|
||||
import { Block, Page, PageType } from "../shared/types";
|
||||
import env from "./env";
|
||||
@@ -116,7 +118,9 @@ export class NotionClient {
|
||||
pages.push({
|
||||
type: item.object === "page" ? PageType.Page : PageType.Database,
|
||||
id: item.id,
|
||||
name: this.parseTitle(item),
|
||||
name: this.parseTitle(item, {
|
||||
maxLength: CollectionValidation.maxNameLength,
|
||||
}),
|
||||
emoji: this.parseEmoji(item),
|
||||
});
|
||||
}
|
||||
@@ -162,7 +166,6 @@ export class NotionClient {
|
||||
cursor = response.next_cursor ?? undefined;
|
||||
}
|
||||
|
||||
// Recursive fetch when direct children have their own children.
|
||||
await Promise.all(
|
||||
blocks.map(async (block) => {
|
||||
if (
|
||||
@@ -203,7 +206,9 @@ export class NotionClient {
|
||||
return {
|
||||
type: PageType.Page,
|
||||
id: item.id,
|
||||
name: this.parseTitle(item),
|
||||
name: this.parseTitle(item, {
|
||||
maxLength: DocumentValidation.maxTitleLength,
|
||||
}),
|
||||
emoji: this.parseEmoji(item),
|
||||
};
|
||||
})
|
||||
@@ -227,7 +232,9 @@ export class NotionClient {
|
||||
const author = await this.fetchUsername(page.created_by.id);
|
||||
|
||||
return {
|
||||
title: this.parseTitle(page),
|
||||
title: this.parseTitle(page, {
|
||||
maxLength: DocumentValidation.maxTitleLength,
|
||||
}),
|
||||
emoji: this.parseEmoji(page),
|
||||
author: author ?? undefined,
|
||||
createdAt: !page.created_time ? undefined : new Date(page.created_time),
|
||||
@@ -246,7 +253,9 @@ export class NotionClient {
|
||||
const author = await this.fetchUsername(database.created_by.id);
|
||||
|
||||
return {
|
||||
title: this.parseTitle(database),
|
||||
title: this.parseTitle(database, {
|
||||
maxLength: DocumentValidation.maxTitleLength,
|
||||
}),
|
||||
emoji: this.parseEmoji(database),
|
||||
author: author ?? undefined,
|
||||
createdAt: !database.created_time
|
||||
@@ -267,12 +276,12 @@ export class NotionClient {
|
||||
return user.name;
|
||||
}
|
||||
|
||||
// bot belongs to a user, get the user's name.
|
||||
// bot belongs to a user, get the user's name
|
||||
if (user.bot.owner.type === "user" && isFullUser(user.bot.owner.user)) {
|
||||
return user.bot.owner.user.name;
|
||||
}
|
||||
|
||||
// bot belongs to a workspace, fallback to bot's name.
|
||||
// bot belongs to a workspace, fallback to bot's name
|
||||
return user.name;
|
||||
} catch (error) {
|
||||
// Handle the case where a user can't be found
|
||||
@@ -286,7 +295,12 @@ export class NotionClient {
|
||||
}
|
||||
}
|
||||
|
||||
private parseTitle(item: PageObjectResponse | DatabaseObjectResponse) {
|
||||
private parseTitle(
|
||||
item: PageObjectResponse | DatabaseObjectResponse,
|
||||
{
|
||||
maxLength = DocumentValidation.maxTitleLength,
|
||||
}: { maxLength?: number } = {}
|
||||
) {
|
||||
let richTexts: RichTextItemResponse[];
|
||||
|
||||
if (item.object === "page") {
|
||||
@@ -298,7 +312,10 @@ export class NotionClient {
|
||||
richTexts = item.title;
|
||||
}
|
||||
|
||||
return richTexts.map((richText) => richText.plain_text).join("");
|
||||
const title = richTexts.map((richText) => richText.plain_text).join("");
|
||||
|
||||
// Truncate title to fit within validation limits
|
||||
return truncate(title, { length: maxLength });
|
||||
}
|
||||
|
||||
private parseEmoji(item: PageObjectResponse | DatabaseObjectResponse) {
|
||||
|
||||
Reference in New Issue
Block a user