Files
Tom Moor 5610df5a26 chore: Reduce no-explicit-any warnings in server directory (#12202)
* chore: Reduce no-explicit-any warnings in server directory

Tightens types across test response bodies, decorator signatures, the
TestServer wrapper, base class generics, and presenter Record types.
Where any is genuinely load-bearing (Sequelize model generics,
PropertyDescriptor decorator returns, plugin-registered template
classes, Fix mixin), keeps any with a targeted eslint-disable plus
reason rather than masking the constraint. Cuts server-only
no-explicit-any warnings from 162 to 70.

* fix: groups test asserts on first response instead of second

Caught by Copilot review on the no-explicit-any cleanup. Also fixes
the pre-existing getChangsetSkipped → getChangesetSkipped typo
surfaced while reviewing nearby decorator code.
2026-04-28 19:50:45 -04:00

226 lines
6.6 KiB
TypeScript

import { differenceInMinutes, formatDistanceToNowStrict } from "date-fns";
import { t } from "i18next";
import type { UnfurlResponse } from "@shared/types";
import { UnfurlResourceType } from "@shared/types";
import { dateLocale } from "@shared/utils/date";
import type { Document, User, Group } from "@server/models";
import { View } from "@server/models";
import { opts } from "@server/utils/i18n";
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- heterogeneous payload from internal callers and third-party unfurl plugins.
type UnfurlData = Record<string, any>;
async function presentUnfurl(
data: UnfurlData,
options?: { includeEmail: boolean }
) {
switch (data.type) {
case UnfurlResourceType.Mention:
return presentMention(data, options);
case UnfurlResourceType.Group:
return presentGroup(data);
case UnfurlResourceType.Document:
return presentDocument(data);
case UnfurlResourceType.PR:
return presentPR(data);
case UnfurlResourceType.Issue:
return presentIssue(data);
case UnfurlResourceType.Project:
return presentProject(data);
default:
return presentURL(data);
}
}
const presentURL = (
data: UnfurlData
): UnfurlResponse[UnfurlResourceType.URL] => {
// TODO: For backwards compatibility, remove once cache has expired in next release.
if (data.transformedUnfurl) {
delete data.transformedUnfurl;
return data as UnfurlResponse[UnfurlResourceType.URL]; // this would have been transformed by the unfurl plugin.
}
return {
type: UnfurlResourceType.URL,
url: data.url,
title: data.meta.title,
description: data.meta.description,
thumbnailUrl: (data.links.thumbnail ?? [])[0]?.href ?? "",
faviconUrl: (data.links.icon ?? [])[0]?.href ?? "",
};
};
const presentMention = async (
data: UnfurlData,
options?: { includeEmail: boolean }
): Promise<UnfurlResponse[UnfurlResourceType.Mention]> => {
const user: User = data.user;
const document: Document = data.document;
const lastOnlineInfo = presentLastOnlineInfoFor(user);
const lastViewedInfo = await presentLastViewedInfoFor(user, document);
return {
type: UnfurlResourceType.Mention,
name: user.name,
email: options && options.includeEmail ? user.email : null,
avatarUrl: user.avatarUrl,
color: user.color,
lastActive: `${lastOnlineInfo}${lastViewedInfo}`,
};
};
const presentGroup = async (
data: UnfurlData
): Promise<UnfurlResponse[UnfurlResourceType.Group]> => {
const group: Group = data.group;
const memberCount = await group.memberCount;
return {
type: UnfurlResourceType.Group,
name: group.name,
description: group.description,
memberCount,
users: (data.users as User[]).map((user) => ({
id: user.id,
name: user.name,
avatarUrl: user.avatarUrl,
color: user.color,
})),
};
};
const presentDocument = (
data: UnfurlData
): UnfurlResponse[UnfurlResourceType.Document] => {
const document: Document = data.document;
const viewer: User | undefined = data.viewer;
const url: string | undefined = data.url;
return {
url: url ?? document.url,
type: UnfurlResourceType.Document,
id: document.id,
title: document.titleWithDefault,
summary: document.getSummary(),
lastActivityByViewer: viewer
? presentLastActivityInfoFor(document, viewer)
: undefined,
};
};
const presentPR = (data: UnfurlData): UnfurlResponse[UnfurlResourceType.PR] =>
data as UnfurlResponse[UnfurlResourceType.PR]; // this would have been transformed by the unfurl plugin.
const presentIssue = (
data: UnfurlData
): UnfurlResponse[UnfurlResourceType.Issue] =>
data as UnfurlResponse[UnfurlResourceType.Issue]; // this would have been transformed by the unfurl plugin.
const presentProject = (
data: UnfurlData
): UnfurlResponse[UnfurlResourceType.Project] =>
data as UnfurlResponse[UnfurlResourceType.Project]; // this would have been transformed by the unfurl plugin.
const presentLastOnlineInfoFor = (user: User) => {
const locale = dateLocale(user.language);
let info: string;
if (!user.lastActiveAt) {
info = t("Never logged in", { ...opts(user) });
} else if (differenceInMinutes(new Date(), user.lastActiveAt) < 5) {
info = t("Online now", { ...opts(user) });
} else {
info = t("Online {{ timeAgo }}", {
timeAgo: formatDistanceToNowStrict(user.lastActiveAt, {
addSuffix: true,
locale,
}),
...opts(user),
});
}
return info;
};
const presentLastViewedInfoFor = async (user: User, document: Document) => {
const lastView = await View.findOne({
where: {
userId: user.id,
documentId: document.id,
},
order: [["updatedAt", "DESC"]],
});
const lastViewedAt = lastView ? lastView.updatedAt : undefined;
const locale = dateLocale(user.language);
let info: string;
if (!lastViewedAt) {
info = t("Never viewed", { ...opts(user) });
} else if (differenceInMinutes(new Date(), lastViewedAt) < 5) {
info = t("Viewed just now", { ...opts(user) });
} else {
info = t("Viewed {{ timeAgo }}", {
timeAgo: formatDistanceToNowStrict(lastViewedAt, {
addSuffix: true,
locale,
}),
...opts(user),
});
}
return info;
};
const presentLastActivityInfoFor = (document: Document, viewer: User) => {
const locale = dateLocale(viewer.language);
const wasUpdated = document.createdAt !== document.updatedAt;
let info: string;
if (wasUpdated) {
const lastUpdatedByViewer = document.updatedBy.id === viewer.id;
if (lastUpdatedByViewer) {
info = t("You updated {{ timeAgo }}", {
timeAgo: formatDistanceToNowStrict(document.updatedAt, {
addSuffix: true,
locale,
}),
...opts(viewer),
});
} else {
info = t("{{ user }} updated {{ timeAgo }}", {
user: document.updatedBy.name,
timeAgo: formatDistanceToNowStrict(document.updatedAt, {
addSuffix: true,
locale,
}),
...opts(viewer),
});
}
} else {
const lastCreatedByViewer = document.createdById === viewer.id;
if (lastCreatedByViewer) {
info = t("You created {{ timeAgo }}", {
timeAgo: formatDistanceToNowStrict(document.createdAt, {
addSuffix: true,
locale,
}),
...opts(viewer),
});
} else {
info = t("{{ user }} created {{ timeAgo }}", {
user: document.createdBy.name,
timeAgo: formatDistanceToNowStrict(document.createdAt, {
addSuffix: true,
locale,
}),
...opts(viewer),
});
}
}
return info;
};
export default presentUnfurl;