dev/2026-04-08 #1
@@ -7,7 +7,8 @@ It is referenced as a git submodule by both `Yonexus.Server` and `Yonexus.Client
|
|||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
- `PROTOCOL.md` — full protocol specification
|
- `PROTOCOL.md` — full protocol specification
|
||||||
- TypeScript type definitions (planned: `src/types.ts`)
|
- `src/types.ts` — shared builtin envelope / payload TypeScript definitions
|
||||||
|
- `src/index.ts` — package export surface
|
||||||
- Canonical JSON shape references
|
- Canonical JSON shape references
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|||||||
1
src/index.ts
Normal file
1
src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./types.js";
|
||||||
182
src/types.ts
Normal file
182
src/types.ts
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
export const YONEXUS_PROTOCOL_VERSION = "1" as const;
|
||||||
|
|
||||||
|
export const builtinMessageTypes = [
|
||||||
|
"hello",
|
||||||
|
"hello_ack",
|
||||||
|
"pair_request",
|
||||||
|
"pair_confirm",
|
||||||
|
"pair_success",
|
||||||
|
"pair_failed",
|
||||||
|
"auth_request",
|
||||||
|
"auth_success",
|
||||||
|
"auth_failed",
|
||||||
|
"re_pair_required",
|
||||||
|
"heartbeat",
|
||||||
|
"heartbeat_ack",
|
||||||
|
"status_update",
|
||||||
|
"disconnect_notice",
|
||||||
|
"error"
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type BuiltinMessageType = (typeof builtinMessageTypes)[number];
|
||||||
|
|
||||||
|
export interface BuiltinEnvelope<
|
||||||
|
TType extends BuiltinMessageType = BuiltinMessageType,
|
||||||
|
TPayload extends Record<string, unknown> = Record<string, unknown>
|
||||||
|
> {
|
||||||
|
type: TType;
|
||||||
|
requestId?: string;
|
||||||
|
timestamp?: number;
|
||||||
|
payload?: TPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HelloPayload {
|
||||||
|
identifier: string;
|
||||||
|
hasSecret: boolean;
|
||||||
|
hasKeyPair: boolean;
|
||||||
|
publicKey?: string;
|
||||||
|
protocolVersion: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HelloAckNextAction =
|
||||||
|
| "pair_required"
|
||||||
|
| "auth_required"
|
||||||
|
| "rejected"
|
||||||
|
| "waiting_pair_confirm";
|
||||||
|
|
||||||
|
export interface HelloAckPayload {
|
||||||
|
identifier: string;
|
||||||
|
nextAction: HelloAckNextAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AdminNotificationStatus = "sent" | "failed";
|
||||||
|
|
||||||
|
export interface PairRequestPayload {
|
||||||
|
identifier: string;
|
||||||
|
expiresAt: number;
|
||||||
|
ttlSeconds: number;
|
||||||
|
adminNotification: AdminNotificationStatus;
|
||||||
|
codeDelivery: "out_of_band";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PairConfirmPayload {
|
||||||
|
identifier: string;
|
||||||
|
pairingCode: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PairSuccessPayload {
|
||||||
|
identifier: string;
|
||||||
|
secret: string;
|
||||||
|
pairedAt: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PairFailedReason =
|
||||||
|
| "expired"
|
||||||
|
| "invalid_code"
|
||||||
|
| "identifier_not_allowed"
|
||||||
|
| "admin_notification_failed"
|
||||||
|
| "internal_error";
|
||||||
|
|
||||||
|
export interface PairFailedPayload {
|
||||||
|
identifier: string;
|
||||||
|
reason: PairFailedReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthRequestPayload {
|
||||||
|
identifier: string;
|
||||||
|
nonce: string;
|
||||||
|
proofTimestamp: number;
|
||||||
|
signature: string;
|
||||||
|
publicKey?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthSuccessPayload {
|
||||||
|
identifier: string;
|
||||||
|
authenticatedAt: number;
|
||||||
|
status: "online";
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AuthFailedReason =
|
||||||
|
| "unknown_identifier"
|
||||||
|
| "not_paired"
|
||||||
|
| "invalid_signature"
|
||||||
|
| "invalid_secret"
|
||||||
|
| "stale_timestamp"
|
||||||
|
| "future_timestamp"
|
||||||
|
| "nonce_collision"
|
||||||
|
| "rate_limited"
|
||||||
|
| "re_pair_required";
|
||||||
|
|
||||||
|
export interface AuthFailedPayload {
|
||||||
|
identifier: string;
|
||||||
|
reason: AuthFailedReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RePairRequiredPayload {
|
||||||
|
identifier: string;
|
||||||
|
reason: "nonce_collision" | "rate_limited" | "trust_revoked";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeartbeatPayload {
|
||||||
|
identifier: string;
|
||||||
|
status: "alive";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeartbeatAckPayload {
|
||||||
|
identifier: string;
|
||||||
|
status: "online" | "unstable" | "offline";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StatusUpdatePayload {
|
||||||
|
identifier: string;
|
||||||
|
status: "online" | "unstable" | "offline";
|
||||||
|
reason: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DisconnectNoticePayload {
|
||||||
|
identifier: string;
|
||||||
|
reason: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProtocolErrorCode =
|
||||||
|
| "MALFORMED_MESSAGE"
|
||||||
|
| "UNSUPPORTED_PROTOCOL_VERSION"
|
||||||
|
| "IDENTIFIER_NOT_ALLOWED"
|
||||||
|
| "PAIRING_REQUIRED"
|
||||||
|
| "PAIRING_EXPIRED"
|
||||||
|
| "ADMIN_NOTIFICATION_FAILED"
|
||||||
|
| "AUTH_FAILED"
|
||||||
|
| "NONCE_COLLISION"
|
||||||
|
| "RATE_LIMITED"
|
||||||
|
| "RE_PAIR_REQUIRED"
|
||||||
|
| "CLIENT_OFFLINE"
|
||||||
|
| "INTERNAL_ERROR";
|
||||||
|
|
||||||
|
export interface ErrorPayload {
|
||||||
|
code: ProtocolErrorCode;
|
||||||
|
message?: string;
|
||||||
|
details?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BuiltinPayloadMap = {
|
||||||
|
hello: HelloPayload;
|
||||||
|
hello_ack: HelloAckPayload;
|
||||||
|
pair_request: PairRequestPayload;
|
||||||
|
pair_confirm: PairConfirmPayload;
|
||||||
|
pair_success: PairSuccessPayload;
|
||||||
|
pair_failed: PairFailedPayload;
|
||||||
|
auth_request: AuthRequestPayload;
|
||||||
|
auth_success: AuthSuccessPayload;
|
||||||
|
auth_failed: AuthFailedPayload;
|
||||||
|
re_pair_required: RePairRequiredPayload;
|
||||||
|
heartbeat: HeartbeatPayload;
|
||||||
|
heartbeat_ack: HeartbeatAckPayload;
|
||||||
|
status_update: StatusUpdatePayload;
|
||||||
|
disconnect_notice: DisconnectNoticePayload;
|
||||||
|
error: ErrorPayload;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TypedBuiltinEnvelope<TType extends keyof BuiltinPayloadMap> = BuiltinEnvelope<
|
||||||
|
TType,
|
||||||
|
BuiltinPayloadMap[TType]
|
||||||
|
>;
|
||||||
Reference in New Issue
Block a user