make pl-api compile

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak
2024-10-16 17:03:27 +02:00
parent 2f7e149f75
commit a521c9044d
32 changed files with 93 additions and 77 deletions

View File

@@ -1,7 +1,7 @@
import * as v from 'valibot';
import { accountSchema } from './account';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/Appeal/} */
const appealSchema = v.object({
@@ -17,7 +17,7 @@ const accountWarningSchema = v.object({
status_ids: v.fallback(v.array(v.string()), []),
target_account: accountSchema,
appeal: v.fallback(v.nullable(appealSchema), null),
created_at: dateSchema,
created_at: v.fallback(datetimeSchema, new Date().toISOString()),
});
type AccountWarning = v.InferOutput<typeof accountWarningSchema>;

View File

@@ -4,7 +4,7 @@ import * as v from 'valibot';
import { customEmojiSchema } from './custom-emoji';
import { relationshipSchema } from './relationship';
import { roleSchema } from './role';
import { coerceObject, dateSchema, filteredArray } from './utils';
import { coerceObject, datetimeSchema, filteredArray } from './utils';
const filterBadges = (tags?: string[]) =>
tags?.filter(tag => tag.startsWith('badge:')).map(tag => v.parse(roleSchema, { id: tag, name: tag.replace(/^badge:/, '') }));
@@ -64,7 +64,7 @@ const preprocessAccount = v.transform((account: any) => {
const fieldSchema = v.object({
name: v.string(),
value: v.string(),
verified_at: v.fallback(v.nullable(z.string().datetime({ offset: true })), null),
verified_at: v.fallback(v.nullable(datetimeSchema), null),
});
const baseAccountSchema = v.object({
@@ -87,7 +87,7 @@ const baseAccountSchema = v.object({
noindex: v.fallback(v.nullable(v.boolean()), null),
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()),
created_at: v.fallback(datetimeSchema, new Date().toUTCString()),
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),
@@ -177,7 +177,7 @@ const credentialAccountSchema: v.BaseSchema<any, CredentialAccount, v.BaseIssue<
const untypedMutedAccountSchema = v.pipe(v.any(), preprocessAccount, v.object({
...accountWithMovedAccountSchema.entries,
mute_expires_at: v.fallback(v.nullable(dateSchema), null),
mute_expires_at: v.fallback(v.nullable(datetimeSchema), null),
}));
type MutedAccount = v.InferOutput<typeof untypedMutedAccountSchema> & WithMoved;

View File

@@ -2,7 +2,7 @@ import * as v from 'valibot';
import { accountSchema } from '../account';
import { roleSchema } from '../role';
import { dateSchema, filteredArray } from '../utils';
import { datetimeSchema, filteredArray } from '../utils';
import { adminIpSchema } from './ip';
@@ -43,7 +43,7 @@ const adminAccountSchema = v.pipe(
id: v.string(),
username: v.string(),
domain: v.fallback(v.nullable(v.string()), null),
created_at: dateSchema,
created_at: v.fallback(datetimeSchema, new Date().toISOString()),
email: v.fallback(v.nullable(v.string()), null),
ip: v.fallback(v.nullable(v.pipe(v.string(), v.ip())), null),
ips: filteredArray(adminIpSchema),

View File

@@ -1,11 +1,13 @@
import * as v from 'valibot';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_Cohort/} */
const adminCohortSchema = v.object({
period: z.string().datetime({ offset: true }),
period: datetimeSchema,
frequency: v.picklist(['day', 'month']),
data: v.array(v.object({
date: z.string().datetime({ offset: true }),
date: datetimeSchema,
rate: v.number(),
value: v.pipe(v.number(), v.integer()),
})),

View File

@@ -1,12 +1,12 @@
import * as v from 'valibot';
import { dateSchema } from '../utils';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_DomainAllow/} */
const adminDomainAllowSchema = v.object({
id: v.string(),
domain: v.string(),
created_at: dateSchema,
created_at: datetimeSchema,
});
type AdminDomainAllow = v.InferOutput<typeof adminDomainAllowSchema>;

View File

@@ -1,13 +1,13 @@
import * as v from 'valibot';
import { dateSchema } from '../utils';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_DomainBlock/} */
const adminDomainBlockSchema = v.object({
id: v.string(),
domain: v.string(),
digest: v.string(),
created_at: dateSchema,
created_at: datetimeSchema,
severity: v.picklist(['silence', 'suspend', 'noop']),
reject_media: v.boolean(),
reject_reports: v.boolean(),

View File

@@ -1,11 +1,13 @@
import * as v from 'valibot';
import { datetimeSchema } from '../utils';
const adminDomainSchema = v.object({
domain: v.fallback(v.string(), ''),
id: v.pipe(v.unknown(), v.transform(String)),
public: v.fallback(v.boolean(), false),
resolves: v.fallback(v.boolean(), false),
last_checked_at: z.string().datetime().catch(''),
last_checked_at: v.fallback(v.nullable(datetimeSchema), null),
});
type AdminDomain = v.InferOutput<typeof adminDomainSchema>

View File

@@ -1,12 +1,12 @@
import * as v from 'valibot';
import { dateSchema } from '../utils';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_EmailDomainBlock/} */
const adminEmailDomainBlockSchema = v.object({
id: v.string(),
domain: v.string(),
created_at: dateSchema,
created_at: datetimeSchema,
history: v.array(v.object({
day: v.pipe(v.unknown(), v.transform(String)),
accounts: v.pipe(v.unknown(), v.transform(String)),

View File

@@ -1,6 +1,6 @@
import * as v from 'valibot';
import { dateSchema } from '../utils';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_IpBlock/} */
const adminIpBlockSchema = v.object({
@@ -8,8 +8,8 @@ const adminIpBlockSchema = v.object({
ip: v.pipe(v.string(), v.ip()),
severity: v.picklist(['sign_up_requires_approval', 'sign_up_block', 'no_access']),
comment: v.fallback(v.string(), ''),
created_at: dateSchema,
expires_at: z.string().datetime({ offset: true }),
created_at: datetimeSchema,
expires_at: v.fallback(v.nullable(datetimeSchema), null),
});
type AdminIpBlock = v.InferOutput<typeof adminIpBlockSchema>;

View File

@@ -1,11 +1,11 @@
import * as v from 'valibot';
import { dateSchema } from '../utils';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_Ip/} */
const adminIpSchema = v.object({
ip: v.pipe(v.string(), v.ip()),
used_at: dateSchema,
used_at: datetimeSchema,
});
type AdminIp = v.InferOutput<typeof adminIpSchema>;

View File

@@ -1,5 +1,7 @@
import * as v from 'valibot';
import { datetimeSchema } from '../utils';
/** @see {@link https://docs.joinmastodon.org/entities/Admin_Measure/} */
const adminMeasureSchema = v.object({
key: v.string(),
@@ -8,7 +10,7 @@ const adminMeasureSchema = v.object({
human_value: v.fallback(v.optional(v.string()), undefined),
previous_total: v.fallback(v.optional(v.pipe(v.unknown(), v.transform(String))), undefined),
data: v.array(v.object({
date: z.string().datetime({ offset: true }),
date: datetimeSchema,
value: v.pipe(v.unknown(), v.transform(String)),
})),
});

View File

@@ -3,7 +3,7 @@ import * as v from 'valibot';
import { ruleSchema } from '../rule';
import { statusWithoutAccountSchema } from '../status';
import { dateSchema, filteredArray } from '../utils';
import { datetimeSchema, filteredArray } from '../utils';
import { adminAccountSchema } from './account';
@@ -30,12 +30,12 @@ const adminReportSchema = v.pipe(
v.object({
id: v.string(),
action_taken: v.fallback(v.optional(v.boolean()), undefined),
action_taken_at: v.fallback(v.nullable(dateSchema), null),
action_taken_at: v.fallback(v.nullable(datetimeSchema), null),
category: v.fallback(v.optional(v.string()), undefined),
comment: v.fallback(v.optional(v.string()), undefined),
forwarded: v.fallback(v.optional(v.boolean()), undefined),
created_at: v.fallback(v.optional(dateSchema), undefined),
updated_at: v.fallback(v.optional(dateSchema), undefined),
created_at: v.fallback(v.optional(datetimeSchema), undefined),
updated_at: v.fallback(v.optional(datetimeSchema), undefined),
account: adminAccountSchema,
target_account: adminAccountSchema,
assigned_account: v.fallback(v.nullable(adminAccountSchema), null),

View File

@@ -4,17 +4,17 @@ import { announcementReactionSchema } from './announcement-reaction';
import { customEmojiSchema } from './custom-emoji';
import { mentionSchema } from './mention';
import { tagSchema } from './tag';
import { dateSchema, filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/announcement/} */
const announcementSchema = v.object({
id: v.string(),
content: v.fallback(v.string(), ''),
starts_at: v.fallback(v.nullable(z.string().datetime()), null),
ends_at: v.fallback(v.nullable(z.string().datetime()), null),
starts_at: v.fallback(v.nullable(datetimeSchema), null),
ends_at: v.fallback(v.nullable(datetimeSchema), null),
all_day: v.fallback(v.boolean(), false),
read: v.fallback(v.boolean(), false),
published_at: dateSchema,
published_at: v.fallback(datetimeSchema, new Date().toISOString()),
reactions: filteredArray(announcementReactionSchema),
statuses: v.pipe(
v.any(),
@@ -26,7 +26,7 @@ const announcementSchema = v.object({
mentions: filteredArray(mentionSchema),
tags: filteredArray(tagSchema),
emojis: filteredArray(customEmojiSchema),
updated_at: dateSchema,
updated_at: v.fallback(datetimeSchema, new Date().toISOString()),
});
type Announcement = v.InferOutput<typeof announcementSchema>;

View File

@@ -1,13 +1,13 @@
import * as v from 'valibot';
import { dateSchema, mimeSchema } from './utils';
import { datetimeSchema, mimeSchema } from './utils';
/** @see {@link https://docs.pleroma.social/backend/development/API/pleroma_api/#post-apiv1pleromabackups} */
const backupSchema = v.object({
id: v.pipe(v.unknown(), v.transform(String)),
contentType: mimeSchema,
file_size: v.fallback(v.number(), 0),
inserted_at: dateSchema,
inserted_at: datetimeSchema,
processed: v.fallback(v.boolean(), false),
url: v.fallback(v.string(), ''),
});

View File

@@ -3,7 +3,7 @@ import * as v from 'valibot';
import { customEmojiSchema } from './custom-emoji';
import { mediaAttachmentSchema } from './media-attachment';
import { previewCardSchema } from './preview-card';
import { dateSchema, filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
/** @see {@link https://docs.pleroma.social/backend/development/API/chats/#getting-the-messages-for-a-chat} */
const chatMessageSchema = v.object({
@@ -11,7 +11,7 @@ const chatMessageSchema = v.object({
content: v.fallback(v.string(), ''),
chat_id: v.string(),
account_id: v.string(),
created_at: dateSchema,
created_at: datetimeSchema,
emojis: filteredArray(customEmojiSchema),
attachment: v.fallback(v.nullable(mediaAttachmentSchema), null),
unread: v.boolean(),

View File

@@ -2,7 +2,7 @@ import * as v from 'valibot';
import { accountSchema } from './account';
import { chatMessageSchema } from './chat-message';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.pleroma.social/backend/development/API/chats/#getting-a-list-of-chats} */
const chatSchema = v.object({
@@ -10,7 +10,7 @@ const chatSchema = v.object({
account: accountSchema,
unread: v.pipe(v.number(), v.integer()),
last_message: v.fallback(v.nullable(chatMessageSchema), null),
created_at: dateSchema,
updated_at: datetimeSchema,
});
type Chat = v.InferOutput<typeof chatSchema>;

View File

@@ -1,10 +1,10 @@
import * as v from 'valibot';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/ExtendedDescription} */
const extendedDescriptionSchema = v.object({
updated_at: dateSchema,
updated_at: datetimeSchema,
content: v.string(),
});

View File

@@ -1,6 +1,6 @@
import * as v from 'valibot';
import { filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/FilterKeyword/} */
const filterKeywordSchema = v.object({
@@ -37,7 +37,7 @@ const filterSchema = v.pipe(
id: v.string(),
title: v.string(),
context: v.array(v.picklist(['home', 'notifications', 'public', 'thread', 'account'])),
expires_at: v.fallback(v.nullable(z.string().datetime({ offset: true })), null),
expires_at: v.fallback(v.nullable(datetimeSchema), null),
filter_action: v.fallback(v.picklist(['warn', 'hide']), 'warn'),
keywords: filteredArray(filterKeywordSchema),
statuses: filteredArray(filterStatusSchema),

View File

@@ -2,12 +2,12 @@ import * as v from 'valibot';
import { customEmojiSchema } from './custom-emoji';
import { groupRelationshipSchema } from './group-relationship';
import { filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
const groupSchema = v.object({
avatar: v.fallback(v.string(), ''),
avatar_static: v.fallback(v.string(), ''),
created_at: z.string().datetime().catch(new Date().toUTCString()),
created_at: v.fallback(datetimeSchema, new Date().toISOString()),
display_name: v.fallback(v.string(), ''),
domain: v.fallback(v.string(), ''),
emojis: filteredArray(customEmojiSchema),

View File

@@ -2,14 +2,15 @@ import * as v from 'valibot';
import { accountSchema } from './account';
import { statusSchema } from './status';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.gotosocial.org/en/latest/api/swagger.yaml#/definitions/interactionRequest} */
const interactionRequestSchema = v.object({
accepted_at: v.fallback(v.nullable(z.string().datetime()), null),
accepted_at: v.fallback(v.nullable(datetimeSchema), null),
account: accountSchema,
created_at: z.string().datetime(),
created_at: datetimeSchema,
id: v.string(),
rejected_at: v.fallback(v.nullable(z.string().datetime()), null),
rejected_at: v.fallback(v.nullable(datetimeSchema), null),
reply: v.fallback(v.nullable(statusSchema), null),
status: v.fallback(v.nullable(statusSchema), null),
type: v.picklist(['favourite', 'reply', 'reblog']),

View File

@@ -1,6 +1,6 @@
import * as v from 'valibot';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
const markerSchema = v.pipe(
v.any(),
@@ -11,7 +11,7 @@ const markerSchema = v.pipe(
v.object({
last_read_id: v.string(),
version: v.pipe(v.number(), v.integer()),
updated_at: dateSchema,
updated_at: datetimeSchema,
unread_count: v.fallback(v.optional(v.pipe(v.number(), v.integer())), undefined),
}),
);

View File

@@ -1,14 +1,14 @@
import * as v from 'valibot';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
import { accountSchema, statusSchema } from '.';
/** @see {@link https://docs.joinmastodon.org/entities/NotificationRequest} */
const notificationRequestSchema = v.object({
id: v.string(),
created_at: dateSchema,
updated_at: dateSchema,
created_at: datetimeSchema,
updated_at: datetimeSchema,
account: accountSchema,
notifications_count: v.pipe(v.unknown(), v.transform(String)),
last_status: v.fallback(v.optional(statusSchema), undefined),

View File

@@ -7,11 +7,11 @@ import { chatMessageSchema } from './chat-message';
import { relationshipSeveranceEventSchema } from './relationship-severance-event';
import { reportSchema } from './report';
import { statusSchema } from './status';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
const baseNotificationSchema = v.object({
account: accountSchema,
created_at: dateSchema,
created_at: v.fallback(datetimeSchema, new Date().toISOString()),
id: v.string(),
group_key: v.string(),
type: v.string(),

View File

@@ -1,5 +1,7 @@
import * as v from 'valibot';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.pleroma.social/backend/development/API/pleroma_api/#get-apioauth_tokens} */
const oauthTokenSchema = v.pipe(
v.any(),
@@ -10,7 +12,7 @@ const oauthTokenSchema = v.pipe(
v.object({
app_name: v.string(),
id: v.number(),
valid_until: z.string().datetime({ offset: true }),
valid_until: datetimeSchema,
}),
);

View File

@@ -1,7 +1,7 @@
import * as v from 'valibot';
import { customEmojiSchema } from './custom-emoji';
import { filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
const pollOptionSchema = v.object({
title: v.fallback(v.string(), ''),
@@ -14,7 +14,7 @@ const pollOptionSchema = v.object({
const pollSchema = v.object({
emojis: filteredArray(customEmojiSchema),
expired: v.fallback(v.boolean(), false),
expires_at: v.fallback(v.nullable(z.string().datetime()), null),
expires_at: v.fallback(v.nullable(datetimeSchema), null),
id: v.string(),
multiple: v.fallback(v.boolean(), false),
options: v.pipe(v.array(pollOptionSchema), v.minLength(2)),

View File

@@ -1,6 +1,6 @@
import * as v from 'valibot';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/RelationshipSeveranceEvent/} */
const relationshipSeveranceEventSchema = v.object({
@@ -8,7 +8,7 @@ const relationshipSeveranceEventSchema = v.object({
type: v.picklist(['domain_block', 'user_domain_block', 'account_suspension']),
purged: v.string(),
relationships_count: v.fallback(v.optional(v.number()), undefined),
created_at: dateSchema,
created_at: datetimeSchema,
});
type RelationshipSeveranceEvent = v.InferOutput<typeof relationshipSeveranceEventSchema>;

View File

@@ -1,17 +1,17 @@
import * as v from 'valibot';
import { accountSchema } from './account';
import { dateSchema } from './utils';
import { datetimeSchema } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/Report/} */
const reportSchema = v.object({
id: v.string(),
action_taken: v.fallback(v.optional(v.boolean()), undefined),
action_taken_at: v.fallback(v.nullable(dateSchema), null),
action_taken_at: v.fallback(v.nullable(datetimeSchema), null),
category: v.fallback(v.optional(v.string()), undefined),
comment: v.fallback(v.optional(v.string()), undefined),
forwarded: v.fallback(v.optional(v.boolean()), undefined),
created_at: v.fallback(v.optional(dateSchema), undefined),
created_at: v.fallback(v.optional(datetimeSchema), undefined),
status_ids: v.fallback(v.nullable(v.string()), null),
rule_ids: v.fallback(v.nullable(v.string()), null),
target_account: v.fallback(v.nullable(accountSchema), null),

View File

@@ -1,12 +1,12 @@
import * as v from 'valibot';
import { mediaAttachmentSchema } from './media-attachment';
import { filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/ScheduledStatus/} */
const scheduledStatusSchema = v.object({
id: v.string(),
scheduled_at: z.string().datetime({ offset: true }),
scheduled_at: datetimeSchema,
params: v.object({
text: v.fallback(v.nullable(v.string()), null),
poll: v.fallback(v.nullable(v.object({
@@ -22,7 +22,7 @@ const scheduledStatusSchema = v.object({
in_reply_to_id: v.fallback(v.nullable(v.string()), null),
language: v.fallback(v.nullable(v.string()), null),
application_id: v.fallback(v.nullable(v.pipe(v.number(), v.integer())), null),
scheduled_at: v.fallback(v.nullable(z.string().datetime({ offset: true })), null),
scheduled_at: v.fallback(v.nullable(datetimeSchema), null),
idempotency: v.fallback(v.nullable(v.string()), null),
with_rate_limit: v.fallback(v.boolean(), false),

View File

@@ -1,6 +1,7 @@
import * as v from 'valibot';
import { accountSchema } from './account';
import { datetimeSchema } from './utils';
const scrobbleSchema = v.pipe(
v.any(),
@@ -11,7 +12,7 @@ const scrobbleSchema = v.pipe(
v.object({
id: v.pipe(v.unknown(), v.transform(String)),
account: accountSchema,
created_at: z.string().datetime({ offset: true }),
created_at: datetimeSchema,
title: v.string(),
artist: v.fallback(v.string(), ''),
album: v.fallback(v.string(), ''),

View File

@@ -3,14 +3,14 @@ import * as v from 'valibot';
import { accountSchema } from './account';
import { customEmojiSchema } from './custom-emoji';
import { mediaAttachmentSchema } from './media-attachment';
import { dateSchema, filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
/** @see {@link https://docs.joinmastodon.org/entities/StatusEdit/} */
const statusEditSchema = v.object({
content: v.fallback(v.string(), ''),
spoiler_text: v.fallback(v.string(), ''),
sensitive: v.pipe(v.unknown(), v.transform(Boolean)),
created_at: dateSchema,
created_at: v.fallback(datetimeSchema, new Date().toISOString()),
account: accountSchema,
poll: v.fallback(v.nullable(v.object({
options: v.array(v.object({

View File

@@ -13,12 +13,12 @@ import { pollSchema } from './poll';
import { previewCardSchema } from './preview-card';
import { tagSchema } from './tag';
import { translationSchema } from './translation';
import { dateSchema, filteredArray } from './utils';
import { datetimeSchema, filteredArray } from './utils';
const statusEventSchema = v.object({
name: v.fallback(v.string(), ''),
start_time: v.fallback(v.nullable(z.string().datetime()), null),
end_time: v.fallback(v.nullable(z.string().datetime()), null),
start_time: v.fallback(v.nullable(datetimeSchema), null),
end_time: v.fallback(v.nullable(datetimeSchema), null),
join_mode: v.fallback(v.nullable(v.picklist(['free', 'restricted', 'invite'])), null),
participants_count: v.fallback(v.number(), 0),
location: v.fallback(v.nullable(v.object({
@@ -39,7 +39,7 @@ const statusEventSchema = v.object({
const baseStatusSchema = v.object({
id: v.string(),
uri: v.fallback(v.pipe(v.string(), v.url()), ''),
created_at: dateSchema,
created_at: v.fallback(datetimeSchema, new Date().toISOString()),
account: accountSchema,
content: v.fallback(v.string(), ''),
visibility: v.fallback(v.string(), 'public'),
@@ -63,7 +63,7 @@ const baseStatusSchema = v.object({
card: v.fallback(v.nullable(previewCardSchema), null),
language: v.fallback(v.nullable(v.string()), null),
text: v.fallback(v.nullable(v.string()), null),
edited_at: v.fallback(v.nullable(z.string().datetime()), null),
edited_at: v.fallback(v.nullable(datetimeSchema), null),
favourited: v.pipe(v.unknown(), v.transform(Boolean)),
reblogged: v.pipe(v.unknown(), v.transform(Boolean)),
muted: v.pipe(v.unknown(), v.transform(Boolean)),
@@ -79,11 +79,11 @@ const baseStatusSchema = v.object({
conversation_id: v.fallback(v.optional(v.string()), undefined),
direct_conversation_id: v.fallback(v.optional(v.string()), undefined),
in_reply_to_account_acct: v.fallback(v.optional(v.string()), undefined),
expires_at: v.fallback(v.optional(z.string().datetime({ offset: true })), undefined),
expires_at: v.fallback(v.optional(datetimeSchema), undefined),
thread_muted: v.fallback(v.optional(v.boolean()), undefined),
emoji_reactions: filteredArray(emojiReactionSchema),
parent_visible: v.fallback(v.optional(v.boolean()), undefined),
pinned_at: v.fallback(v.nullable(z.string().datetime({ offset: true })), null),
pinned_at: v.fallback(v.nullable(datetimeSchema), null),
quote_visible: v.fallback(v.optional(v.boolean()), undefined),
quote_url: v.fallback(v.optional(v.string()), undefined),
quotes_count: v.fallback(v.number(), 0),

View File

@@ -1,7 +1,13 @@
import * as v from 'valibot';
/** Validate to Mastodon's date format, or use the current date. */
const dateSchema = z.string().datetime({ offset: true }).catch(new Date().toUTCString());
const datetimeSchema = v.pipe(
v.string(),
// Adapted from Zod
// https://github.com/colinhacks/zod/blob/main/src/types.ts#L619
// at least it's not chatgpt
v.regex(/^\d{4}-\d{2}-\d{2}T([01]\d|2[0-3]):[0-5]\d:[0-5]\d(\.\d+)?(([+-]\d{2}:?\d{2})|(Z)?)$/),
);
/** Validates individual items in an array, dropping any that aren't valid. */
const filteredArray = <T>(schema: v.BaseSchema<any, T, v.BaseIssue<unknown>>) =>
@@ -29,4 +35,4 @@ const coerceObject = <T extends v.ObjectEntries>(shape: T) =>
v.object(shape),
);
export { filteredArray, emojiSchema, dateSchema, mimeSchema, coerceObject };
export { filteredArray, emojiSchema, datetimeSchema, mimeSchema, coerceObject };