Rework core integration: validated capability layer, docs, and session state
This commit is contained in:
@@ -25,8 +25,6 @@ export const enum IpcEvents {
|
||||
GET_SETTINGS = "VCD_GET_SETTINGS",
|
||||
SET_SETTINGS = "VCD_SET_SETTINGS",
|
||||
|
||||
VESKSLOP_GET_TOKEN = "VCD_VESKSLOP_GET_TOKEN",
|
||||
|
||||
IS_USING_CUSTOM_VENCORD_DIR = "VCD_IS_USING_CUSTOM_VENCORD_DIR",
|
||||
SHOW_CUSTOM_VENCORD_DIR = "VCD_SHOW_CUSTOM_VENCORD_DIR",
|
||||
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
|
||||
@@ -85,11 +83,5 @@ export const enum IpcCommands {
|
||||
|
||||
GET_LANGUAGES = "navigator.languages",
|
||||
|
||||
SCREEN_SHARE_PICKER = "screenshare:picker",
|
||||
|
||||
/* Veskslop puppet commands */
|
||||
STATE_GET = "state:get",
|
||||
MESSAGE_SEND = "message:send",
|
||||
MESSAGE_READ = "message:read",
|
||||
DM_SEND = "dm:send"
|
||||
SCREEN_SHARE_PICKER = "screenshare:picker"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Vesktop ⇄ Veskslop daemon protocol.
|
||||
*
|
||||
* This is the only surface the external daemon can reach. Every action is
|
||||
* validated by the core before anything touches Discord, and every failure is
|
||||
* returned as a structured error instead of throwing.
|
||||
*/
|
||||
|
||||
export const enum PuppetAction {
|
||||
Ping = "ping",
|
||||
EventsSubscribe = "events.subscribe",
|
||||
StateGet = "state.get",
|
||||
MessageSend = "message.send",
|
||||
MessageRead = "message.read",
|
||||
DmSend = "dm.send"
|
||||
}
|
||||
|
||||
export const PuppetActions: readonly PuppetAction[] = [
|
||||
PuppetAction.Ping,
|
||||
PuppetAction.EventsSubscribe,
|
||||
PuppetAction.StateGet,
|
||||
PuppetAction.MessageSend,
|
||||
PuppetAction.MessageRead,
|
||||
PuppetAction.DmSend
|
||||
];
|
||||
|
||||
export const enum PuppetErrorCode {
|
||||
InvalidRequest = "INVALID_REQUEST",
|
||||
PayloadTooLarge = "PAYLOAD_TOO_LARGE",
|
||||
UnknownAction = "UNKNOWN_ACTION",
|
||||
CoreUnavailable = "CORE_UNAVAILABLE",
|
||||
NotLoggedIn = "NOT_LOGGED_IN",
|
||||
InvalidSnowflake = "INVALID_SNOWFLAKE",
|
||||
InvalidParam = "INVALID_PARAM",
|
||||
ContentEmpty = "CONTENT_EMPTY",
|
||||
ContentTooLong = "CONTENT_TOO_LONG",
|
||||
ChannelNotFound = "CHANNEL_NOT_FOUND",
|
||||
NotSendable = "NOT_SENDABLE",
|
||||
SendFailed = "SEND_FAILED",
|
||||
DmUnavailable = "DM_UNAVAILABLE",
|
||||
RateLimited = "RATE_LIMITED",
|
||||
Internal = "INTERNAL"
|
||||
}
|
||||
|
||||
export interface PuppetError {
|
||||
code: PuppetErrorCode | string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface PuppetRequest {
|
||||
id?: string | number;
|
||||
action: string;
|
||||
params?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export type PuppetResult =
|
||||
| { ok: true; result?: unknown }
|
||||
| { ok: false; error: PuppetError };
|
||||
|
||||
export type PuppetResponse =
|
||||
| { id?: string | number; ok: true; result?: unknown }
|
||||
| { id?: string | number; ok: false; error: PuppetError };
|
||||
|
||||
export interface PuppetEvent {
|
||||
type: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/** Hard safety limits applied core-side, regardless of what the daemon asks for. */
|
||||
export const PUPPET_LIMITS = {
|
||||
maxContentLength: 2000,
|
||||
maxReadLimit: 100,
|
||||
minActionIntervalMs: 500,
|
||||
maxActionsPerMinute: 30,
|
||||
maxRequestBytes: 64 * 1024,
|
||||
maxChannelsPerGuild: 1000
|
||||
};
|
||||
|
||||
const SNOWFLAKE_RE = /^\d{17,20}$/;
|
||||
|
||||
export function isSnowflake(value: unknown): value is string {
|
||||
return typeof value === "string" && SNOWFLAKE_RE.test(value);
|
||||
}
|
||||
Reference in New Issue
Block a user