mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-11 10:57:07 +00:00
Fix plugin RPCs with schema transforms (#8550)
* fix(plugins): parse RPC values once at the receiver Sending parsed values caused transforms to run again on incompatible schema outputs. Keep the wire values in schema-input form and parse only where consumed. * fix(plugins): let omitted RPC inputs reach schema defaults * fix(plugins): accept omitted RPC outputs for client defaults
This commit is contained in:
@@ -24,17 +24,23 @@ describe("plugin RPC contracts", () => {
|
||||
expectTypeOf<RpcOutput<typeof contract>>().toEqualTypeOf<{ value: number }>();
|
||||
});
|
||||
|
||||
it("validates input before invoking the daemon", async () => {
|
||||
let invocations = 0;
|
||||
const invoke = async () => {
|
||||
invocations += 1;
|
||||
return { value: 2 };
|
||||
it("sends input unchanged for the plugin to parse", async () => {
|
||||
let parses = 0;
|
||||
const transformed = defineRpc({
|
||||
name: "transformed",
|
||||
input: z.string().transform((text) => {
|
||||
parses += 1;
|
||||
return Number(text);
|
||||
}),
|
||||
output: z.number(),
|
||||
});
|
||||
const invoke = async (_method: string, input: unknown) => {
|
||||
expect(input).toBe("2");
|
||||
expect(parses).toBe(0);
|
||||
return transformed.input.parseAsync(input);
|
||||
};
|
||||
|
||||
await expect(callPluginRpc(contract, invoke, { value: "wrong" })).rejects.toBeInstanceOf(
|
||||
z.ZodError,
|
||||
);
|
||||
expect(invocations).toBe(0);
|
||||
await expect(callPluginRpc(transformed, invoke, "2")).resolves.toBe(2);
|
||||
expect(parses).toBe(1);
|
||||
});
|
||||
|
||||
it("validates output before resolving", async () => {
|
||||
|
||||
@@ -39,8 +39,7 @@ export async function callPluginRpc<InputSchema extends ZodType, OutputSchema ex
|
||||
invoke: (method: string, input: unknown) => Promise<unknown>,
|
||||
input: PluginWireInput<ZodInput<InputSchema>>,
|
||||
): Promise<ZodOutput<OutputSchema>> {
|
||||
const parsedInput = await contract.input.parseAsync(input);
|
||||
const output = await invoke(contract.name, parsedInput);
|
||||
const output = await invoke(contract.name, input);
|
||||
return contract.output.parseAsync(output);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user