fix: various fixes to sentry-reported errors and more
This commit is contained in:
@@ -93,25 +93,21 @@ export interface SearchableGuild {
|
||||
verificationLevel: number;
|
||||
mfaLevel: number;
|
||||
nsfwLevel: number;
|
||||
memberCount: number;
|
||||
createdAt: number;
|
||||
discoveryDescription: string | null;
|
||||
discoveryCategory: number | null;
|
||||
isDiscoverable: boolean;
|
||||
onlineCount: number;
|
||||
}
|
||||
|
||||
export interface GuildSearchFilters {
|
||||
ownerId?: string;
|
||||
minMembers?: number;
|
||||
maxMembers?: number;
|
||||
verificationLevel?: number;
|
||||
mfaLevel?: number;
|
||||
nsfwLevel?: number;
|
||||
hasFeature?: Array<string>;
|
||||
isDiscoverable?: boolean;
|
||||
discoveryCategory?: number;
|
||||
sortBy?: 'createdAt' | 'memberCount' | 'onlineCount' | 'relevance';
|
||||
sortBy?: 'createdAt' | 'relevance';
|
||||
sortOrder?: 'asc' | 'desc';
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ const SearchIndexTypeEnum = createNamedStringLiteralUnion(
|
||||
['channel_messages', 'channel_messages', 'Channel message search index'],
|
||||
['guild_members', 'guild_members', 'Guild member search index'],
|
||||
['favorite_memes', 'favorite_memes', 'Favourite meme search index'],
|
||||
['discovery', 'discovery', 'Discovery guild search index'],
|
||||
],
|
||||
'Type of search index to refresh',
|
||||
);
|
||||
|
||||
@@ -407,6 +407,19 @@ export const BulkScheduleUserDeletionRequest = z.object({
|
||||
|
||||
export type BulkScheduleUserDeletionRequest = z.infer<typeof BulkScheduleUserDeletionRequest>;
|
||||
|
||||
export const ListWebAuthnCredentialsRequest = z.object({
|
||||
user_id: SnowflakeType.describe('ID of the user to list WebAuthn credentials for'),
|
||||
});
|
||||
|
||||
export type ListWebAuthnCredentialsRequest = z.infer<typeof ListWebAuthnCredentialsRequest>;
|
||||
|
||||
export const DeleteWebAuthnCredentialRequest = z.object({
|
||||
user_id: SnowflakeType.describe('ID of the user who owns the credential'),
|
||||
credential_id: createStringType(1, 512).describe('ID of the WebAuthn credential to delete'),
|
||||
});
|
||||
|
||||
export type DeleteWebAuthnCredentialRequest = z.infer<typeof DeleteWebAuthnCredentialRequest>;
|
||||
|
||||
export const ListUserChangeLogRequest = z.object({
|
||||
user_id: SnowflakeType.describe('ID of the user to list change logs for'),
|
||||
limit: z.number().min(1).max(200).default(50).describe('Maximum number of entries to return'),
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {MAX_GROUP_DM_RECIPIENTS} from '@fluxer/constants/src/LimitConstants';
|
||||
import {type UserPartial, UserPartialResponse} from '@fluxer/schema/src/domains/user/UserResponseSchemas';
|
||||
import {ChannelOverwriteTypeSchema, ChannelTypeSchema} from '@fluxer/schema/src/primitives/ChannelValidators';
|
||||
import {PermissionStringType} from '@fluxer/schema/src/primitives/PermissionValidators';
|
||||
@@ -73,7 +74,7 @@ export const ChannelResponse = z.object({
|
||||
.describe('The permission overwrites for this channel'),
|
||||
recipients: z
|
||||
.array(z.lazy(() => UserPartialResponse))
|
||||
.max(10)
|
||||
.max(MAX_GROUP_DM_RECIPIENTS)
|
||||
.optional()
|
||||
.describe('The recipients of the DM channel'),
|
||||
nsfw: z.boolean().optional().describe('Whether the channel is marked as NSFW'),
|
||||
@@ -103,7 +104,11 @@ export const ChannelPartialResponse = z.object({
|
||||
id: SnowflakeStringType.describe('The unique identifier (snowflake) for this channel'),
|
||||
name: z.string().nullish().describe('The name of the channel'),
|
||||
type: ChannelTypeSchema.describe('The type of the channel'),
|
||||
recipients: z.array(ChannelPartialRecipientResponse).max(10).optional().describe('The recipients of the DM channel'),
|
||||
recipients: z
|
||||
.array(ChannelPartialRecipientResponse)
|
||||
.max(MAX_GROUP_DM_RECIPIENTS)
|
||||
.optional()
|
||||
.describe('The recipients of the DM channel'),
|
||||
});
|
||||
|
||||
export type ChannelPartialResponse = z.infer<typeof ChannelPartialResponse>;
|
||||
|
||||
79
packages/schema/src/domains/channel/ChunkedUploadSchemas.tsx
Normal file
79
packages/schema/src/domains/channel/ChunkedUploadSchemas.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {FilenameType} from '@fluxer/schema/src/primitives/FileValidators';
|
||||
import {
|
||||
coerceNumberFromString,
|
||||
createStringType,
|
||||
Int32Type,
|
||||
SnowflakeType,
|
||||
} from '@fluxer/schema/src/primitives/SchemaPrimitives';
|
||||
import {z} from 'zod';
|
||||
|
||||
export const CreateChunkedUploadRequest = z.object({
|
||||
filename: FilenameType.describe('The name of the file being uploaded'),
|
||||
file_size: z.number().int().positive().describe('The total size of the file in bytes'),
|
||||
});
|
||||
export type CreateChunkedUploadRequest = z.infer<typeof CreateChunkedUploadRequest>;
|
||||
|
||||
export const CreateChunkedUploadResponse = z.object({
|
||||
upload_id: z.string().describe('The unique identifier for the upload session'),
|
||||
upload_filename: z.string().describe('The temporary filename used to reference this upload'),
|
||||
chunk_size: z.number().int().describe('The size of each chunk in bytes'),
|
||||
chunk_count: z.number().int().describe('The total number of chunks to upload'),
|
||||
});
|
||||
export type CreateChunkedUploadResponse = z.infer<typeof CreateChunkedUploadResponse>;
|
||||
|
||||
export const UploadChunkResponse = z.object({
|
||||
etag: z.string().describe('The ETag of the uploaded chunk'),
|
||||
});
|
||||
export type UploadChunkResponse = z.infer<typeof UploadChunkResponse>;
|
||||
|
||||
export const CompleteChunkedUploadRequest = z.object({
|
||||
etags: z
|
||||
.array(
|
||||
z.object({
|
||||
chunk_index: z.number().int().min(0).describe('The zero-based index of the chunk'),
|
||||
etag: z.string().describe('The ETag returned when the chunk was uploaded'),
|
||||
}),
|
||||
)
|
||||
.min(1)
|
||||
.describe('Array of chunk ETags in order'),
|
||||
});
|
||||
export type CompleteChunkedUploadRequest = z.infer<typeof CompleteChunkedUploadRequest>;
|
||||
|
||||
export const CompleteChunkedUploadResponse = z.object({
|
||||
upload_filename: z.string().describe('The temporary filename used to reference this upload'),
|
||||
file_size: z.number().int().describe('The total size of the uploaded file in bytes'),
|
||||
content_type: z.string().describe('The MIME type of the uploaded file'),
|
||||
});
|
||||
export type CompleteChunkedUploadResponse = z.infer<typeof CompleteChunkedUploadResponse>;
|
||||
|
||||
export const ChunkedUploadParam = z.object({
|
||||
channel_id: SnowflakeType.describe('The ID of the channel'),
|
||||
upload_id: createStringType(1, 128).describe('The ID of the chunked upload session'),
|
||||
});
|
||||
export type ChunkedUploadParam = z.infer<typeof ChunkedUploadParam>;
|
||||
|
||||
export const ChunkedUploadChunkParam = z.object({
|
||||
channel_id: SnowflakeType.describe('The ID of the channel'),
|
||||
upload_id: createStringType(1, 128).describe('The ID of the chunked upload session'),
|
||||
chunk_index: coerceNumberFromString(Int32Type.min(0)).describe('The zero-based index of the chunk'),
|
||||
});
|
||||
export type ChunkedUploadChunkParam = z.infer<typeof ChunkedUploadChunkParam>;
|
||||
@@ -48,6 +48,7 @@ const ClientAttachmentBase = z.object({
|
||||
export const ClientAttachmentRequest = ClientAttachmentBase.extend({
|
||||
id: coerceNumberFromString(Int32Type).describe('The client-side identifier for this attachment'),
|
||||
filename: FilenameType.describe('The name of the file being uploaded'),
|
||||
uploaded_filename: z.string().optional().describe('The temporary filename from a completed chunked upload'),
|
||||
});
|
||||
export type ClientAttachmentRequest = z.infer<typeof ClientAttachmentRequest>;
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ function isValidBase64(value: string): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeFilename(value: string): string {
|
||||
export function normalizeFilename(value: string): string {
|
||||
let normalized = normalizeString(value);
|
||||
|
||||
// biome-ignore lint/suspicious/noControlCharactersInRegex: null byte filtering is intentional for security
|
||||
|
||||
Reference in New Issue
Block a user