pl-api: moar blind search and replace

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-10-15 00:07:22 +02:00
parent 0bed543c20
commit b29b488d7e
11 changed files with 48 additions and 30 deletions

View file

@ -88,7 +88,7 @@ const baseAccountSchema = v.object({
suspended: v.fallback(v.optional(v.boolean()), undefined),
limited: v.fallback(v.optional(v.boolean()), undefined),
created_at: z.string().datetime().catch(new Date().toUTCString()),
last_status_at: v.fallback(v.nullable(z.string().date()), null),
last_status_at: v.fallback(v.nullable(v.pipe(v.string(), v.isoDate())), null),
statuses_count: v.fallback(v.number(), 0),
followers_count: v.fallback(v.number(), 0),
following_count: v.fallback(v.number(), 0),
@ -108,7 +108,7 @@ const baseAccountSchema = v.object({
hide_follows_count: v.fallback(v.optional(v.boolean()), undefined),
accepts_chat_messages: v.fallback(v.nullable(v.boolean()), null),
favicon: v.fallback(v.optional(v.string()), undefined),
birthday: z.string().date().optional().catch(undefined),
birthday: v.fallback(v.optional(v.pipe(v.string(), v.isoDate())), undefined),
deactivated: v.fallback(v.optional(v.boolean()), undefined),
location: v.fallback(v.optional(v.string()), undefined),
@ -126,7 +126,8 @@ const baseAccountSchema = v.object({
}),
});
const accountWithMovedAccountSchema = baseAccountSchema.extend({
const accountWithMovedAccountSchema = v.object({
...baseAccountSchema.entries,
moved: v.fallback(v.nullable(z.lazy((): typeof baseAccountSchema => accountWithMovedAccountSchema as any)), null),
});
@ -141,7 +142,8 @@ type Account = v.InferOutput<typeof accountWithMovedAccountSchema> & WithMoved;
const accountSchema: z.ZodType<Account> = untypedAccountSchema as any;
const untypedCredentialAccountSchema = z.preprocess(preprocessAccount, accountWithMovedAccountSchema.extend({
const untypedCredentialAccountSchema = z.preprocess(preprocessAccount, v.object({
...accountWithMovedAccountSchema.entries,
source: v.fallback(v.nullable(v.object({
note: v.fallback(v.string(), ''),
fields: filteredArray(fieldSchema),
@ -173,7 +175,8 @@ type CredentialAccount = v.InferOutput<typeof untypedCredentialAccountSchema> &
const credentialAccountSchema: z.ZodType<CredentialAccount> = untypedCredentialAccountSchema as any;
const untypedMutedAccountSchema = z.preprocess(preprocessAccount, accountWithMovedAccountSchema.extend({
const untypedMutedAccountSchema = z.preprocess(preprocessAccount, v.object({
...accountWithMovedAccountSchema.entries,
mute_expires_at: v.fallback(v.nullable(dateSchema), null),
}));

View file

@ -42,7 +42,7 @@ const adminAccountSchema = z.preprocess((account: any) => {
domain: v.fallback(v.nullable(v.string()), null),
created_at: dateSchema,
email: v.fallback(v.nullable(v.string()), null),
ip: v.fallback(v.nullable(z.string().ip()), null),
ip: v.fallback(v.nullable(v.pipe(v.string(), v.ip())), null),
ips: filteredArray(adminIpSchema),
locale: v.fallback(v.nullable(v.string()), null),
invite_request: v.fallback(v.nullable(v.string()), null),

View file

@ -7,7 +7,8 @@ import { announcementSchema } from '../announcement';
const adminAnnouncementSchema = z.preprocess((announcement: any) => ({
...announcement,
...pick(announcement.pleroma, 'raw_content'),
}), announcementSchema.extend({
}), v.object({
...announcementSchema.entries,
raw_content: v.fallback(v.string(), ''),
}));

View file

@ -3,7 +3,8 @@ import * as v from 'valibot';
import { tagSchema } from '../tag';
/** @see {@link https://docs.joinmastodon.org/entities/Tag/#admin} */
const adminTagSchema = tagSchema.extend({
const adminTagSchema = v.object({
...tagSchema.entries,
id: v.string(),
trendable: v.boolean(),
usable: v.boolean(),

View file

@ -1,7 +1,7 @@
import * as v from 'valibot';
const directoryStatisticsPeriodSchema = v.object({
period: z.string().date(),
period: v.pipe(v.string(), v.isoDate()),
server_count: v.fallback(v.nullable(v.pipe(v.unknown(), v.transform(Number))), null),
user_count: v.fallback(v.nullable(v.pipe(v.unknown(), v.transform(Number))), null),
active_user_count: v.fallback(v.nullable(v.pipe(v.unknown(), v.transform(Number))), null),

View file

@ -51,7 +51,8 @@ const videoAttachmentSchema = v.object({
type: v.literal('video'),
meta: v.fallback(v.object({
duration: v.fallback(v.optional(v.number()), undefined),
original: v.fallback(v.optional(imageMetaSchema.extend({
original: v.fallback(v.optional(v.object({
...imageMetaSchema.entries,
frame_rate: v.fallback(v.nullable(v.pipe(v.string(), v.regex(/\d+\/\d+$/))), null),
duration: v.fallback(v.nullable(z.number().nonnegative()), null),
})), undefined),

View file

@ -20,54 +20,64 @@ const baseNotificationSchema = v.object({
is_seen: v.fallback(v.optional(v.boolean()), undefined),
});
const accountNotificationSchema = baseNotificationSchema.extend({
const accountNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.picklist(['follow', 'follow_request', 'admin.sign_up', 'bite']),
});
const mentionNotificationSchema = baseNotificationSchema.extend({
const mentionNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('mention'),
subtype: v.fallback(v.nullable(v.picklist(['reply'])), null),
status: statusSchema,
});
const statusNotificationSchema = baseNotificationSchema.extend({
const statusNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.picklist(['status', 'reblog', 'favourite', 'poll', 'update', 'event_reminder']),
status: statusSchema,
});
const reportNotificationSchema = baseNotificationSchema.extend({
const reportNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('admin.report'),
report: reportSchema,
});
const severedRelationshipNotificationSchema = baseNotificationSchema.extend({
const severedRelationshipNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('severed_relationships'),
relationship_severance_event: relationshipSeveranceEventSchema,
});
const moderationWarningNotificationSchema = baseNotificationSchema.extend({
const moderationWarningNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('moderation_warning'),
moderation_warning: accountWarningSchema,
});
const moveNotificationSchema = baseNotificationSchema.extend({
const moveNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('move'),
target: accountSchema,
});
const emojiReactionNotificationSchema = baseNotificationSchema.extend({
const emojiReactionNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('emoji_reaction'),
emoji: v.string(),
emoji_url: v.fallback(v.nullable(v.string()), null),
status: statusSchema,
});
const chatMentionNotificationSchema = baseNotificationSchema.extend({
const chatMentionNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.literal('chat_mention'),
chat_message: chatMessageSchema,
});
const eventParticipationRequestNotificationSchema = baseNotificationSchema.extend({
const eventParticipationRequestNotificationSchema = v.object({
...baseNotificationSchema.entries,
type: v.picklist(['participation_accepted', 'participation_request']),
status: statusSchema,
participation_message: v.fallback(v.nullable(v.string()), null),
@ -81,7 +91,7 @@ const notificationSchema: z.ZodType<Notification> = z.preprocess((notification:
type: notification.type === 'pleroma:report'
? 'admin.report'
: notification.type?.replace(/^pleroma:/, ''),
}), z.discriminatedUnion('type', [
}), v.variant('type', [
accountNotificationSchema,
mentionNotificationSchema,
statusNotificationSchema,

View file

@ -7,7 +7,7 @@ const pollOptionSchema = v.object({
title: v.fallback(v.string(), ''),
votes_count: v.fallback(v.number(), 0),
title_map: v.record(v.string(), v.string()).nullable().catch(null),
title_map: v.fallback(v.nullable(v.record(v.string(), v.string())), null),
});
/** @see {@link https://docs.joinmastodon.org/entities/Poll/} */

View file

@ -1,11 +1,11 @@
import * as v from 'valibot';
const hexSchema = z.string().regex(/^#[a-f0-9]{6}$/i);
const hexSchema = v.pipe(v.string(), v.regex(/^#[a-f0-9]{6}$/i));
const roleSchema = v.object({
id: v.fallback(v.string(), ''),
name: v.fallback(v.string(), ''),
color: hexSchema.catch(''),
color: v.fallback(hexSchema, ''),
permissions: v.fallback(v.string(), ''),
highlighted: v.fallback(v.boolean(), true),
});

View file

@ -8,11 +8,11 @@ const statusSourceSchema = v.object({
text: v.fallback(v.string(), ''),
spoiler_text: v.fallback(v.string(), ''),
content_type: z.string().catch('text/plain'),
content_type: v.fallback(v.string(), 'text/plain'),
location: v.fallback(v.nullable(locationSchema), null),
text_map: v.record(v.string(), v.string()).nullable().catch(null),
spoiler_text_map: v.record(v.string(), v.string()).nullable().catch(null),
text_map: v.fallback(v.nullable(v.record(v.string(), v.string())), null),
spoiler_text_map: v.fallback(v.nullable(v.record(v.string(), v.string())), null),
});
type StatusSource = v.InferOutput<typeof statusSourceSchema>;

View file

@ -90,7 +90,7 @@ const baseStatusSchema = v.object({
bookmark_folder: v.fallback(v.nullable(v.string()), null),
event: v.fallback(v.nullable(statusEventSchema), null),
translation: translationSchema.nullable().or(v.literal(false)).catch(null),
translation: v.fallback(v.union([v.nullable(translationSchema), v.literal(false)]), null),
content_map: v.fallback(v.nullable(v.record(v.string(), v.string())), null),
text_map: v.fallback(v.nullable(v.record(v.string(), v.string())), null),
@ -134,13 +134,15 @@ const preprocess = (status: any) => {
return status;
};
const statusSchema: z.ZodType<Status> = z.preprocess(preprocess, baseStatusSchema.extend({
const statusSchema: z.ZodType<Status> = z.preprocess(preprocess, v.object({
...baseStatusSchema.entries,
reblog: v.fallback(v.nullable(z.lazy(() => statusSchema)), null),
quote: v.fallback(v.nullable(z.lazy(() => statusSchema)), null),
})) as any;
const statusWithoutAccountSchema = z.preprocess(preprocess, baseStatusSchema.omit({ account: true }).extend({
const statusWithoutAccountSchema = z.preprocess(preprocess, v.object({
...(v.omit(baseStatusSchema, ['account']).entries),
account: v.fallback(v.nullable(accountSchema), null),
reblog: v.fallback(v.nullable(z.lazy(() => statusSchema)), null),