diff --git a/src/schemas/instance.ts b/src/schemas/instance.ts index 807d0c657..74f4928f0 100644 --- a/src/schemas/instance.ts +++ b/src/schemas/instance.ts @@ -3,7 +3,8 @@ import z from 'zod'; import { accountSchema } from './account'; import { mrfSimpleSchema } from './pleroma'; -import { coerceObject, mimeSchema } from './utils'; +import { ruleSchema } from './rule'; +import { coerceObject, filteredArray, mimeSchema } from './utils'; const configurationSchema = coerceObject({ chats: coerceObject({ @@ -24,14 +25,14 @@ const configurationSchema = coerceObject({ video_size_limit: z.number().optional().catch(undefined), }), polls: coerceObject({ - max_characters_per_option: z.number().catch(25), - max_expiration: z.number().catch(2629746), - max_options: z.number().catch(4), - min_expiration: z.number().catch(300), + max_characters_per_option: z.number().optional().catch(undefined), + max_expiration: z.number().optional().catch(undefined), + max_options: z.number().optional().catch(undefined), + min_expiration: z.number().optional().catch(undefined), }), statuses: coerceObject({ - max_characters: z.number().catch(500), - max_media_attachments: z.number().catch(4), + max_characters: z.number().optional().catch(undefined), + max_media_attachments: z.number().optional().catch(undefined), }), }); @@ -51,7 +52,11 @@ const pleromaSchema = coerceObject({ mrf_policies: z.string().array().optional().catch(undefined), mrf_simple: mrfSimpleSchema, }), - fields_limits: z.any(), + fields_limits: coerceObject({ + max_fields: z.number().nonnegative().catch(4), + name_length: z.number().nonnegative().catch(255), + value_length: z.number().nonnegative().catch(2047), + }), migration_cooldown_period: z.number().optional().catch(undefined), restrict_unauthenticated: coerceObject({ activities: coerceObject({ @@ -81,6 +86,13 @@ const pleromaSchema = coerceObject({ vapid_public_key: z.string().catch(''), }); +const pleromaPollLimitsSchema = coerceObject({ + max_expiration: z.number().optional().catch(undefined), + max_option_chars: z.number().optional().catch(undefined), + max_options: z.number().optional().catch(undefined), + min_expiration: z.number().optional().catch(undefined), +}); + const statsSchema = coerceObject({ domain_count: z.number().catch(0), status_count: z.number().catch(0), @@ -107,10 +119,13 @@ const instanceSchema = coerceObject({ feature_quote: z.boolean().catch(false), fedibird_capabilities: z.array(z.string()).catch([]), languages: z.string().array().catch([]), + max_media_attachments: z.number().optional().catch(undefined), + max_toot_chars: z.number().optional().catch(undefined), nostr: nostrSchema.optional().catch(undefined), pleroma: pleromaSchema, + poll_limits: pleromaPollLimitsSchema, registrations: z.boolean().catch(false), - rules: z.any(), + rules: filteredArray(ruleSchema), short_description: z.string().catch(''), stats: statsSchema, thumbnail: z.string().catch(''), @@ -118,6 +133,31 @@ const instanceSchema = coerceObject({ urls: urlsSchema, usage: usageSchema, version: z.string().catch(''), +}).transform(({ max_media_attachments, max_toot_chars, poll_limits, ...instance }) => { + const { configuration } = instance; + + const polls = { + ...configuration.polls, + max_characters_per_option: configuration.polls.max_characters_per_option ?? poll_limits.max_option_chars ?? 25, + max_expiration: configuration.polls.max_expiration ?? poll_limits.max_expiration ?? 2629746, + max_options: configuration.polls.max_options ?? poll_limits.max_options ?? 4, + min_expiration: configuration.polls.min_expiration ?? poll_limits.min_expiration ?? 300, + }; + + const statuses = { + ...configuration.statuses, + max_characters: configuration.statuses.max_characters ?? max_toot_chars ?? 500, + max_media_attachments: configuration.statuses.max_media_attachments ?? max_media_attachments ?? 4, + }; + + return { + ...instance, + configuration: { + ...configuration, + polls, + statuses, + }, + }; }); type Instance = z.infer; diff --git a/src/schemas/rule.ts b/src/schemas/rule.ts new file mode 100644 index 000000000..32f949b08 --- /dev/null +++ b/src/schemas/rule.ts @@ -0,0 +1,12 @@ +import { z } from 'zod'; + +import { coerceObject } from './utils'; + +const ruleSchema = coerceObject({ + id: z.string(), + text: z.string().catch(''), +}); + +type Rule = z.infer; + +export { ruleSchema, type Rule }; \ No newline at end of file