Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ export async function apiGet(
params?: Record<string, unknown>,
) {
const client = createClient();
// The server runs tRPC with the SuperJSON transformer, so GET input must
// be sent in SuperJSON's serialized shape ({ json: ... }); a bare object
// deserializes to undefined and every parameterized query fails with 400.
const query = params
? `?input=${encodeURIComponent(JSON.stringify(params))}`
? `?input=${encodeURIComponent(JSON.stringify({ json: params }))}`
: "";
const response = await client.get(`/trpc/${endpoint}${query}`);
return response.data?.result?.data?.json ?? response.data;
Expand Down
57 changes: 57 additions & 0 deletions tests/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

vi.mock("axios", () => {
return {
default: {
create: () => ({
get: () => Promise.resolve({ data: {} }),
post: () => Promise.resolve({ data: {} }),
}),
},
};
});

describe("readAuthConfig", () => {
const originalEnv = { ...process.env };

Expand Down Expand Up @@ -48,6 +59,52 @@ describe("readAuthConfig", () => {
});
});

describe("apiGet", () => {
it("should wrap GET params in the SuperJSON { json: ... } input envelope", async () => {
process.env.DOKPLOY_URL = "https://test.dokploy.com";
process.env.DOKPLOY_API_KEY = "test-key-123";

Comment thread
WilliamAGH marked this conversation as resolved.
const urls: string[] = [];
const axiosMock = await import("axios");
axiosMock.default.create = () =>
({
get: async (url: string) => {
urls.push(url);
return { data: {} };
},
}) as never;
Comment thread
WilliamAGH marked this conversation as resolved.
Outdated

const { apiGet } = await import("../src/client.js");
await apiGet("compose.one", { composeId: "abc123", limit: 1 });

expect(urls[0]).toBe(
`/trpc/compose.one?input=${encodeURIComponent(
JSON.stringify({ json: { composeId: "abc123", limit: 1 } }),
)}`,
);
});

it("should omit the input query string when no params are passed", async () => {
process.env.DOKPLOY_URL = "https://test.dokploy.com";
process.env.DOKPLOY_API_KEY = "test-key-123";

const urls: string[] = [];
const axiosMock = await import("axios");
axiosMock.default.create = () =>
({
get: async (url: string) => {
urls.push(url);
return { data: {} };
},
}) as never;

const { apiGet } = await import("../src/client.js");
await apiGet("project.all");

expect(urls[0]).toBe("/trpc/project.all");
});
});

describe("saveAuthConfig", () => {
it("should write config with correct structure", async () => {
const { saveAuthConfig } = await import("../src/client.js");
Expand Down