Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
@@ -0,0 +1,179 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer } from "./generated/core/bodySerializer.gen.js";
|
||||
import { buildClientParams } from "./generated/core/params.gen.js";
|
||||
import {
|
||||
defaultPathSerializer,
|
||||
getUrl,
|
||||
getValidRequestBody,
|
||||
} from "./generated/core/utils.gen.js";
|
||||
import {
|
||||
separatorArrayExplode,
|
||||
separatorArrayNoExplode,
|
||||
separatorObjectExplode,
|
||||
serializeArrayParam,
|
||||
serializeObjectParam,
|
||||
serializePrimitiveParam,
|
||||
} from "./generated/core/pathSerializer.gen.js";
|
||||
import { serializeQueryKeyValue, stringifyToJsonValue } from "./generated/core/queryKeySerializer.gen.js";
|
||||
|
||||
describe("generated core body serializers", () => {
|
||||
it("serializes JSON bodies with bigint values", () => {
|
||||
expect(jsonBodySerializer.bodySerializer({ id: 12n, name: "tool" })).toBe('{"id":"12","name":"tool"}');
|
||||
});
|
||||
|
||||
it("serializes FormData bodies while skipping nullish values", async () => {
|
||||
const file = new Blob(["hello"], { type: "text/plain" });
|
||||
const date = new Date("2026-05-25T10:30:00.000Z");
|
||||
|
||||
const data = formDataBodySerializer.bodySerializer({
|
||||
ignored: undefined,
|
||||
list: ["a", 2],
|
||||
meta: { ok: true },
|
||||
stamp: date,
|
||||
upload: file,
|
||||
});
|
||||
|
||||
expect(data.getAll("list")).toEqual(["a", "2"]);
|
||||
expect(data.get("meta")).toBe('{"ok":true}');
|
||||
expect(data.get("stamp")).toBe(date.toISOString());
|
||||
expect(data.get("upload")).toBeInstanceOf(Blob);
|
||||
expect(data.has("ignored")).toBe(false);
|
||||
});
|
||||
|
||||
it("serializes URLSearchParams bodies with repeated array entries", () => {
|
||||
expect(
|
||||
urlSearchParamsBodySerializer.bodySerializer({
|
||||
filters: ["active", { owner: "me" }],
|
||||
page: 2,
|
||||
skipped: null,
|
||||
})
|
||||
).toBe("filters=active&filters=%7B%22owner%22%3A%22me%22%7D&page=2");
|
||||
});
|
||||
});
|
||||
|
||||
describe("generated core parameter mapping", () => {
|
||||
it("maps positional and object parameters into request slots", () => {
|
||||
const params = buildClientParams(
|
||||
[
|
||||
"project-1",
|
||||
{ raw: true },
|
||||
{
|
||||
$headers_traceparent: "00-ab",
|
||||
$query_search: "drill",
|
||||
apiVersion: "2026-05",
|
||||
extra: "kept",
|
||||
payload: { name: "new tool" },
|
||||
},
|
||||
],
|
||||
[
|
||||
{ in: "path", key: "projectId", map: "project_id" },
|
||||
{ in: "body" },
|
||||
{
|
||||
allowExtra: { query: true },
|
||||
args: [
|
||||
{ in: "headers", key: "apiVersion", map: "X-Api-Version" },
|
||||
{ key: "payload", map: "body" },
|
||||
],
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
expect(params).toEqual({
|
||||
body: { name: "new tool" },
|
||||
headers: {
|
||||
"X-Api-Version": "2026-05",
|
||||
traceparent: "00-ab",
|
||||
},
|
||||
path: { project_id: "project-1" },
|
||||
query: {
|
||||
extra: "kept",
|
||||
search: "drill",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("removes empty slots from the mapped params", () => {
|
||||
expect(buildClientParams(["abc"], [{ in: "path", key: "id" }])).toEqual({ path: { id: "abc" } });
|
||||
});
|
||||
});
|
||||
|
||||
describe("generated core path and URL serializers", () => {
|
||||
it("serializes primitive, array, and object path params", () => {
|
||||
expect(
|
||||
defaultPathSerializer({
|
||||
path: {
|
||||
coords: ["10", "20"],
|
||||
filter: { status: "open", owner: "ops" },
|
||||
id: "tool/a",
|
||||
tag: "beta",
|
||||
},
|
||||
url: "/v1/tools/{id}/{.tag}/{;coords*}/{filter}",
|
||||
})
|
||||
).toBe("/v1/tools/tool%2Fa/.beta/;coords=10;coords=20/status,open,owner,ops");
|
||||
});
|
||||
|
||||
it("serializes query and path parameters into a full URL", () => {
|
||||
const url = getUrl({
|
||||
baseUrl: "https://api.example.test",
|
||||
path: { id: "a/b" },
|
||||
query: { active: true, tags: ["red", "blue"] },
|
||||
querySerializer: (query) => `?active=${query.active}&tags=${(query.tags as string[]).join(",")}`,
|
||||
url: "v1/tools/{id}",
|
||||
});
|
||||
|
||||
expect(url).toBe("https://api.example.test/v1/tools/a%2Fb?active=true&tags=red,blue");
|
||||
});
|
||||
|
||||
it("exposes OpenAPI separator and primitive serialization behavior", () => {
|
||||
expect(separatorArrayExplode("label")).toBe(".");
|
||||
expect(separatorArrayNoExplode("pipeDelimited")).toBe("|");
|
||||
expect(separatorObjectExplode("matrix")).toBe(";");
|
||||
expect(serializeArrayParam({ explode: false, name: "ids", style: "pipeDelimited", value: ["a/b", "c"] })).toBe("ids=a%2Fb|c");
|
||||
expect(serializePrimitiveParam({ allowReserved: true, name: "q", value: "a/b?c" })).toBe("q=a/b?c");
|
||||
expect(() => serializePrimitiveParam({ name: "bad", value: { nested: true } as never })).toThrow(/Deeply-nested/);
|
||||
});
|
||||
|
||||
it("serializes object params for dates, labels, and deep objects", () => {
|
||||
const date = new Date("2026-05-25T12:00:00.000Z");
|
||||
|
||||
expect(serializeObjectParam({ explode: true, name: "at", style: "form", value: date, valueOnly: true })).toBe(date.toISOString());
|
||||
expect(serializeObjectParam({ explode: false, name: "filter", style: "label", value: { status: "open" } })).toBe(".status,open");
|
||||
expect(serializeObjectParam({ explode: true, name: "filter", style: "deepObject", value: { status: "open" } })).toBe(
|
||||
"filter[status]=open"
|
||||
);
|
||||
});
|
||||
|
||||
it("returns the valid request body shape for serialized, plain, and empty bodies", () => {
|
||||
expect(getValidRequestBody({ body: { ok: true } })).toEqual({ ok: true });
|
||||
expect(getValidRequestBody({ body: "", bodySerializer: JSON.stringify })).toBeNull();
|
||||
expect(getValidRequestBody({ body: { ok: true }, bodySerializer: JSON.stringify, serializedBody: '{"ok":true}' })).toBe('{"ok":true}');
|
||||
expect(getValidRequestBody({ body: { ok: true }, bodySerializer: JSON.stringify, serializedBody: "" })).toBeNull();
|
||||
expect(getValidRequestBody({})).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("generated core query key serialization", () => {
|
||||
it("normalizes query key values into JSON-safe shapes", () => {
|
||||
const params = new URLSearchParams([
|
||||
["b", "2"],
|
||||
["a", "1"],
|
||||
["a", "3"],
|
||||
]);
|
||||
|
||||
expect(serializeQueryKeyValue(params)).toEqual({ a: ["1", "3"], b: "2" });
|
||||
expect(serializeQueryKeyValue({ createdAt: new Date("2026-05-25T00:00:00.000Z"), id: 123n })).toEqual({
|
||||
createdAt: "2026-05-25T00:00:00.000Z",
|
||||
id: "123",
|
||||
});
|
||||
expect(serializeQueryKeyValue(Object.create(null))).toEqual({});
|
||||
expect(serializeQueryKeyValue(Symbol("skip"))).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined when JSON serialization cannot produce a value", () => {
|
||||
const circular: Record<string, unknown> = {};
|
||||
circular.self = circular;
|
||||
|
||||
expect(stringifyToJsonValue(circular)).toBeUndefined();
|
||||
expect(stringifyToJsonValue(() => undefined)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user