165 lines
4.6 KiB
TypeScript
165 lines
4.6 KiB
TypeScript
import { Type } from "@sinclair/typebox";
|
|
import { GatewayClientIdSchema, GatewayClientModeSchema, NonEmptyString } from "./primitives.js";
|
|
import { SnapshotSchema, StateVersionSchema } from "./snapshot.js";
|
|
|
|
export const TickEventSchema = Type.Object(
|
|
{
|
|
ts: Type.Integer({ minimum: 0 }),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const ShutdownEventSchema = Type.Object(
|
|
{
|
|
reason: NonEmptyString,
|
|
restartExpectedMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const ConnectParamsSchema = Type.Object(
|
|
{
|
|
minProtocol: Type.Integer({ minimum: 1 }),
|
|
maxProtocol: Type.Integer({ minimum: 1 }),
|
|
client: Type.Object(
|
|
{
|
|
id: GatewayClientIdSchema,
|
|
displayName: Type.Optional(NonEmptyString),
|
|
version: NonEmptyString,
|
|
platform: NonEmptyString,
|
|
deviceFamily: Type.Optional(NonEmptyString),
|
|
modelIdentifier: Type.Optional(NonEmptyString),
|
|
mode: GatewayClientModeSchema,
|
|
instanceId: Type.Optional(NonEmptyString),
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
caps: Type.Optional(Type.Array(NonEmptyString, { default: [] })),
|
|
commands: Type.Optional(Type.Array(NonEmptyString)),
|
|
permissions: Type.Optional(Type.Record(NonEmptyString, Type.Boolean())),
|
|
pathEnv: Type.Optional(Type.String()),
|
|
role: Type.Optional(NonEmptyString),
|
|
scopes: Type.Optional(Type.Array(NonEmptyString)),
|
|
device: Type.Optional(
|
|
Type.Object(
|
|
{
|
|
id: NonEmptyString,
|
|
publicKey: NonEmptyString,
|
|
signature: NonEmptyString,
|
|
signedAt: Type.Integer({ minimum: 0 }),
|
|
nonce: Type.Optional(NonEmptyString),
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
),
|
|
auth: Type.Optional(
|
|
Type.Object(
|
|
{
|
|
token: Type.Optional(Type.String()),
|
|
password: Type.Optional(Type.String()),
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
),
|
|
locale: Type.Optional(Type.String()),
|
|
userAgent: Type.Optional(Type.String()),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const HelloOkSchema = Type.Object(
|
|
{
|
|
type: Type.Literal("hello-ok"),
|
|
protocol: Type.Integer({ minimum: 1 }),
|
|
server: Type.Object(
|
|
{
|
|
version: NonEmptyString,
|
|
commit: Type.Optional(NonEmptyString),
|
|
host: Type.Optional(NonEmptyString),
|
|
connId: NonEmptyString,
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
features: Type.Object(
|
|
{
|
|
methods: Type.Array(NonEmptyString),
|
|
events: Type.Array(NonEmptyString),
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
snapshot: SnapshotSchema,
|
|
canvasHostUrl: Type.Optional(NonEmptyString),
|
|
auth: Type.Optional(
|
|
Type.Object(
|
|
{
|
|
deviceToken: NonEmptyString,
|
|
role: NonEmptyString,
|
|
scopes: Type.Array(NonEmptyString),
|
|
issuedAtMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
),
|
|
policy: Type.Object(
|
|
{
|
|
maxPayload: Type.Integer({ minimum: 1 }),
|
|
maxBufferedBytes: Type.Integer({ minimum: 1 }),
|
|
tickIntervalMs: Type.Integer({ minimum: 1 }),
|
|
},
|
|
{ additionalProperties: false },
|
|
),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const ErrorShapeSchema = Type.Object(
|
|
{
|
|
code: NonEmptyString,
|
|
message: NonEmptyString,
|
|
details: Type.Optional(Type.Unknown()),
|
|
retryable: Type.Optional(Type.Boolean()),
|
|
retryAfterMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const RequestFrameSchema = Type.Object(
|
|
{
|
|
type: Type.Literal("req"),
|
|
id: NonEmptyString,
|
|
method: NonEmptyString,
|
|
params: Type.Optional(Type.Unknown()),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const ResponseFrameSchema = Type.Object(
|
|
{
|
|
type: Type.Literal("res"),
|
|
id: NonEmptyString,
|
|
ok: Type.Boolean(),
|
|
payload: Type.Optional(Type.Unknown()),
|
|
error: Type.Optional(ErrorShapeSchema),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const EventFrameSchema = Type.Object(
|
|
{
|
|
type: Type.Literal("event"),
|
|
event: NonEmptyString,
|
|
payload: Type.Optional(Type.Unknown()),
|
|
seq: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
stateVersion: Type.Optional(StateVersionSchema),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
// Discriminated union of all top-level frames. Using a discriminator makes
|
|
// downstream codegen (quicktype) produce tighter types instead of all-optional
|
|
// blobs.
|
|
export const GatewayFrameSchema = Type.Union(
|
|
[RequestFrameSchema, ResponseFrameSchema, EventFrameSchema],
|
|
{ discriminator: "type" },
|
|
);
|