import { z } from "zod"; import { legalDocsSchema } from "./features/legal/schema"; import { community, conversation } from "./features/conversation/schema"; const fileFromMessage = z.object({ name: z.string(), id: z.uuidv4(), type: z.enum(["image", "image_top_right", "file"]), }); const message = z.object({ height: z.number(), not_encrypted: z.boolean().optional(), sent_by_self: z.boolean(), timestamp: z.number(), content: z.base64(), files: z.array(fileFromMessage).optional(), tint: z.string().length(7).startsWith("#").optional(), avatar: z.boolean().optional(), display: z.boolean().optional(), }); // Socket export const socket = { identification: { request: z .object({ user_id: z.number().optional(), iota_id: z.number().optional(), }) .refine( (value) => (typeof value.user_id === "number") !== (typeof value.iota_id === "number"), { message: "Either user_id or iota_id must be provided", }, ), response: z.object({ challenge: z.string(), public_key: z.base64(), }), }, get_user_data: { request: z.object({ user_id: z.number(), }), response: z.object({ about: z.string().max(255).optional(), avatar: z.string().optional(), display: z.string().max(15), iota_id: z.number(), omikron_connections: z.array(z.number()), omikron_id: z.number().optional(), online_status: z.enum([ "user_offline", "user_online", "user_dnd", "user_idle", "user_wc", "user_borked", "iota_offline", "iota_online", "iota_borked", ]), public_key: z.base64(), status: z.string().max(15).optional(), sub_end: z.number(), sub_level: z.number(), user_id: z.number(), username: z.string().max(15), }), }, challenge_response: { request: z.object({ challenge: z.base64(), }), response: z.object({ accepted: z.boolean(), }), }, ping: { request: z.object({ last_ping: z.number(), }), response: z.object({ ping_iota: z.number(), }), }, get_chats: { request: z.object({}), response: z.object({ user_ids: z.array(conversation), }), }, get_communities: { request: z.object({}), response: z.object({ communities: z.array(community), }), }, message_live: { request: z.object({}), response: z.object({ sender_id: z.number(), send_time: z.number(), message, }), }, messages_get: { request: z.object({ user_id: z.number(), amount: z.number(), offset: z.number(), }), response: z.object({ messages: z.array(message), }), }, message_send: { request: z.object({ height: z.number(), content: z.base64(), receiver_id: z.number(), send_time: z.number(), files: z.array(fileFromMessage).optional(), }), response: z.object({}), }, } satisfies Record; export type Socket = typeof socket; // Storage export interface Storage { user_id: number; private_key: string; ppandtos_done: boolean; accepted_terms_of_service: boolean; accepted_privacy_policy: boolean; analytics_crash_reports: boolean; analytics_usage_data: boolean; analytics_done: boolean; legal_docs: z.infer; chat_invert_enter_behaviour: boolean; } export const storageDefaults: Storage = { user_id: 0, private_key: "", ppandtos_done: false, accepted_terms_of_service: false, accepted_privacy_policy: false, analytics_crash_reports: true, analytics_usage_data: true, analytics_done: false, legal_docs: { eula: { version: "0.0", hash: "000000000000", unix: 0, }, tos: { version: "0.0", hash: "000000000000", unix: 0, }, pp: { version: "0.0", hash: "000000000000", unix: 0, }, }, chat_invert_enter_behaviour: false, };