fix(gateway): resolve iOS node invokes
This commit is contained in:
@@ -51,7 +51,8 @@ export class GatewayClient {
|
||||
start() {
|
||||
if (this.closed) return;
|
||||
const url = this.opts.url ?? "ws://127.0.0.1:18789";
|
||||
this.ws = new WebSocket(url, { maxPayload: 512 * 1024 });
|
||||
// Allow node screen snapshots and other large responses.
|
||||
this.ws = new WebSocket(url, { maxPayload: 10 * 1024 * 1024 });
|
||||
|
||||
this.ws.on("open", () => this.sendConnect());
|
||||
this.ws.on("message", (data) => this.handleMessage(data.toString()));
|
||||
|
||||
@@ -38,6 +38,8 @@ import {
|
||||
HelloOkSchema,
|
||||
type NodeInvokeParams,
|
||||
NodeInvokeParamsSchema,
|
||||
type NodeListParams,
|
||||
NodeListParamsSchema,
|
||||
type NodePairApproveParams,
|
||||
NodePairApproveParamsSchema,
|
||||
type NodePairListParams,
|
||||
@@ -105,6 +107,8 @@ export const validateNodePairRejectParams = ajv.compile<NodePairRejectParams>(
|
||||
export const validateNodePairVerifyParams = ajv.compile<NodePairVerifyParams>(
|
||||
NodePairVerifyParamsSchema,
|
||||
);
|
||||
export const validateNodeListParams =
|
||||
ajv.compile<NodeListParams>(NodeListParamsSchema);
|
||||
export const validateNodeInvokeParams = ajv.compile<NodeInvokeParams>(
|
||||
NodeInvokeParamsSchema,
|
||||
);
|
||||
@@ -163,6 +167,7 @@ export {
|
||||
NodePairApproveParamsSchema,
|
||||
NodePairRejectParamsSchema,
|
||||
NodePairVerifyParamsSchema,
|
||||
NodeListParamsSchema,
|
||||
NodeInvokeParamsSchema,
|
||||
SessionsListParamsSchema,
|
||||
SessionsPatchParamsSchema,
|
||||
@@ -205,6 +210,7 @@ export type {
|
||||
NodePairApproveParams,
|
||||
NodePairRejectParams,
|
||||
NodePairVerifyParams,
|
||||
NodeListParams,
|
||||
NodeInvokeParams,
|
||||
SessionsListParams,
|
||||
SessionsPatchParams,
|
||||
|
||||
@@ -243,12 +243,18 @@ export const NodePairVerifyParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
export const NodeListParamsSchema = Type.Object(
|
||||
{},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
export const NodeInvokeParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
command: NonEmptyString,
|
||||
params: Type.Optional(Type.Unknown()),
|
||||
timeoutMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
||||
idempotencyKey: NonEmptyString,
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
@@ -507,6 +513,7 @@ export const ProtocolSchemas: Record<string, TSchema> = {
|
||||
NodePairApproveParams: NodePairApproveParamsSchema,
|
||||
NodePairRejectParams: NodePairRejectParamsSchema,
|
||||
NodePairVerifyParams: NodePairVerifyParamsSchema,
|
||||
NodeListParams: NodeListParamsSchema,
|
||||
NodeInvokeParams: NodeInvokeParamsSchema,
|
||||
SessionsListParams: SessionsListParamsSchema,
|
||||
SessionsPatchParams: SessionsPatchParamsSchema,
|
||||
@@ -545,6 +552,7 @@ export type NodePairListParams = Static<typeof NodePairListParamsSchema>;
|
||||
export type NodePairApproveParams = Static<typeof NodePairApproveParamsSchema>;
|
||||
export type NodePairRejectParams = Static<typeof NodePairRejectParamsSchema>;
|
||||
export type NodePairVerifyParams = Static<typeof NodePairVerifyParamsSchema>;
|
||||
export type NodeListParams = Static<typeof NodeListParamsSchema>;
|
||||
export type NodeInvokeParams = Static<typeof NodeInvokeParamsSchema>;
|
||||
export type SessionsListParams = Static<typeof SessionsListParamsSchema>;
|
||||
export type SessionsPatchParams = Static<typeof SessionsPatchParamsSchema>;
|
||||
|
||||
@@ -399,6 +399,7 @@ describe("gateway server", () => {
|
||||
command: "screen.eval",
|
||||
params: { javaScript: "2+2" },
|
||||
timeoutMs: 123,
|
||||
idempotencyKey: "idem-1",
|
||||
});
|
||||
expect(res.ok).toBe(true);
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ import {
|
||||
validateCronStatusParams,
|
||||
validateCronUpdateParams,
|
||||
validateNodeInvokeParams,
|
||||
validateNodeListParams,
|
||||
validateNodePairApproveParams,
|
||||
validateNodePairListParams,
|
||||
validateNodePairRejectParams,
|
||||
@@ -177,6 +178,7 @@ const METHODS = [
|
||||
"node.pair.approve",
|
||||
"node.pair.reject",
|
||||
"node.pair.verify",
|
||||
"node.list",
|
||||
"node.invoke",
|
||||
"cron.list",
|
||||
"cron.status",
|
||||
@@ -2056,6 +2058,49 @@ export async function startGatewayServer(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "node.list": {
|
||||
const params = (req.params ?? {}) as Record<string, unknown>;
|
||||
if (!validateNodeListParams(params)) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
`invalid node.list params: ${formatValidationErrors(validateNodeListParams.errors)}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const list = await listNodePairing();
|
||||
const connected = bridge?.listConnected?.() ?? [];
|
||||
const connectedById = new Map(
|
||||
connected.map((n) => [n.nodeId, n]),
|
||||
);
|
||||
|
||||
const nodes = list.paired.map((n) => {
|
||||
const live = connectedById.get(n.nodeId);
|
||||
return {
|
||||
nodeId: n.nodeId,
|
||||
displayName: live?.displayName ?? n.displayName,
|
||||
platform: live?.platform ?? n.platform,
|
||||
version: live?.version ?? n.version,
|
||||
remoteIp: live?.remoteIp ?? n.remoteIp,
|
||||
connected: Boolean(live),
|
||||
};
|
||||
});
|
||||
|
||||
respond(true, { ts: Date.now(), nodes }, undefined);
|
||||
} catch (err) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "node.invoke": {
|
||||
const params = (req.params ?? {}) as Record<string, unknown>;
|
||||
if (!validateNodeInvokeParams(params)) {
|
||||
@@ -2082,6 +2127,7 @@ export async function startGatewayServer(
|
||||
command: string;
|
||||
params?: unknown;
|
||||
timeoutMs?: number;
|
||||
idempotencyKey: string;
|
||||
};
|
||||
const nodeId = String(p.nodeId ?? "").trim();
|
||||
const command = String(p.command ?? "").trim();
|
||||
|
||||
Reference in New Issue
Block a user