From 4752feb1b8e88f8c5e434c91ebc3f99574a3ec22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 21 Oct 2023 23:45:54 +0200 Subject: [PATCH] =?UTF-8?q?Update=20Takah=C4=93=20compatibility,=20add=20f?= =?UTF-8?q?ixVersion=20to=20instanceSchema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- src/schemas/instance.ts | 22 ++++++++++++++++++++++ src/utils/features.ts | 12 +++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/schemas/instance.ts b/src/schemas/instance.ts index 74f4928f0..4e55a7456 100644 --- a/src/schemas/instance.ts +++ b/src/schemas/instance.ts @@ -6,6 +6,25 @@ import { mrfSimpleSchema } from './pleroma'; import { ruleSchema } from './rule'; import { coerceObject, filteredArray, mimeSchema } from './utils'; +const fixVersion = (version: string) => { + // Handle Mastodon release candidates + if (new RegExp(/[0-9.]+rc[0-9]+/g).test(version)) { + version = version.split('rc').join('-rc'); + } + + // Rename Akkoma to Pleroma+akkoma + if (version.includes('Akkoma')) { + version = '2.7.2 (compatible; Pleroma 2.4.50+akkoma)'; + } + + // Set Takahē version to a Pleroma-like string + if (version.startsWith('takahe/')) { + version = `0.0.0 (compatible; Takahe ${version.slice(7)})`; + } + + return version; +}; + const configurationSchema = coerceObject({ chats: coerceObject({ max_characters: z.number().catch(5000), @@ -136,6 +155,8 @@ const instanceSchema = coerceObject({ }).transform(({ max_media_attachments, max_toot_chars, poll_limits, ...instance }) => { const { configuration } = instance; + const version = fixVersion(instance.version); + const polls = { ...configuration.polls, max_characters_per_option: configuration.polls.max_characters_per_option ?? poll_limits.max_option_chars ?? 25, @@ -157,6 +178,7 @@ const instanceSchema = coerceObject({ polls, statuses, }, + version, }; }); diff --git a/src/utils/features.ts b/src/utils/features.ts index a1224eda2..b7dadd51b 100644 --- a/src/utils/features.ts +++ b/src/utils/features.ts @@ -194,6 +194,7 @@ const getInstanceFeatures = (instance: Instance) => { announcements: any([ v.software === MASTODON && gte(v.compatVersion, '3.1.0'), v.software === PLEROMA && gte(v.version, '2.2.49'), + v.software === TAKAHE && gte(v.version, '0.7.0'), ]), /** @@ -233,6 +234,7 @@ const getInstanceFeatures = (instance: Instance) => { v.software === MASTODON && gte(v.compatVersion, '3.1.0'), v.software === PLEROMA && gte(v.version, '0.9.9'), v.software === PIXELFED, + v.software === TAKAHE && gte(v.version, '0.9.0'), ]), /** @@ -366,9 +368,14 @@ const getInstanceFeatures = (instance: Instance) => { v.software === WILDEBEEST, ]), + /** + * Ability to edit published posts. + * @see PUT /api/v1/statuses/:id + */ editStatuses: any([ v.software === FRIENDICA && gte(v.version, '2022.12.0'), v.software === MASTODON && gte(v.version, '3.5.0'), + v.software === TAKAHE && gte(v.version, '0.8.0'), features.includes('editing'), ]), @@ -491,6 +498,7 @@ const getInstanceFeatures = (instance: Instance) => { followHashtags: any([ v.software === MASTODON && gte(v.compatVersion, '4.0.0'), v.software === PLEROMA && v.build === AKKOMA, + v.software === TAKAHE && gte(v.version, '0.9.0'), ]), /** @@ -677,6 +685,7 @@ const getInstanceFeatures = (instance: Instance) => { mutesDuration: any([ v.software === PLEROMA && gte(v.version, '2.3.0'), v.software === MASTODON && gte(v.compatVersion, '3.3.0'), + v.software === TAKAHE, ]), /** @@ -732,6 +741,7 @@ const getInstanceFeatures = (instance: Instance) => { v.software === FIREFISH, v.software === MASTODON && gte(v.version, '2.8.0'), v.software === PLEROMA, + v.software === TAKAHE && gte(v.version, '0.8.0'), v.software === TRUTHSOCIAL, ]), @@ -758,6 +768,7 @@ const getInstanceFeatures = (instance: Instance) => { profileFields: any([ v.software === MASTODON, v.software === PLEROMA, + v.software === TAKAHE && gte(v.version, '0.7.0'), ]), /** @@ -978,7 +989,6 @@ export const parseVersion = (version: string): Backend => { loose: true, }) : null; const compat = match ? semverParse(match[1]) || semverCoerce(match[1]) : null; - if (match && semver && compat) { return { build: semver.build[0],