Merge remote-tracking branch 'origin/feat/repo-query-sort' into release/0.5

# Conflicts:
#	app/src/data/api/DataController.ts
This commit is contained in:
dswbx
2025-01-10 08:23:51 +01:00
2 changed files with 31 additions and 8 deletions

View File

@@ -1,16 +1,15 @@
import { describe, expect, test } from "bun:test"; import { describe, expect, test } from "bun:test";
import type { QueryObject } from "ufo"; import { Value } from "../../src/core/utils";
import { WhereBuilder, type WhereQuery } from "../../src/data/entities/query/WhereBuilder"; import { WhereBuilder, type WhereQuery, querySchema } from "../../src/data";
import { getDummyConnection } from "./helper"; import { getDummyConnection } from "./helper";
const t = "t";
describe("data-query-impl", () => { describe("data-query-impl", () => {
function qb() { function qb() {
const c = getDummyConnection(); const c = getDummyConnection();
const kysely = c.dummyConnection.kysely; const kysely = c.dummyConnection.kysely;
return kysely.selectFrom(t).selectAll(); return kysely.selectFrom("t").selectAll();
} }
function compile(q: QueryObject) { function compile(q: WhereQuery) {
const { sql, parameters } = WhereBuilder.addClause(qb(), q).compile(); const { sql, parameters } = WhereBuilder.addClause(qb(), q).compile();
return { sql, parameters }; return { sql, parameters };
} }
@@ -90,3 +89,20 @@ describe("data-query-impl", () => {
} }
}); });
}); });
describe("data-query-impl: Typebox", () => {
test("sort", async () => {
const decode = (input: any, expected: any) => {
const result = Value.Decode(querySchema, input);
expect(result.sort).toEqual(expected);
};
const _dflt = { by: "id", dir: "asc" };
decode({ sort: "" }, _dflt);
decode({ sort: "name" }, { by: "name", dir: "asc" });
decode({ sort: "-name" }, { by: "name", dir: "desc" });
decode({ sort: "-posts.name" }, { by: "posts.name", dir: "desc" });
decode({ sort: "-1name" }, _dflt);
decode({ sort: { by: "name", dir: "desc" } }, { by: "name", dir: "desc" });
});
});

View File

@@ -6,7 +6,6 @@ import {
Type, Type,
Value Value
} from "core/utils"; } from "core/utils";
import type { Simplify } from "type-fest";
import { WhereBuilder } from "../entities"; import { WhereBuilder } from "../entities";
const NumberOrString = (options: SchemaOptions = {}) => const NumberOrString = (options: SchemaOptions = {}) =>
@@ -19,17 +18,25 @@ const limit = NumberOrString({ default: 10 });
const offset = NumberOrString({ default: 0 }); const offset = NumberOrString({ default: 0 });
// @todo: allow "id" and "-id" // @todo: allow "id" and "-id"
const sort_default = { by: "id", dir: "asc" };
const sort = Type.Transform( const sort = Type.Transform(
Type.Union( Type.Union(
[Type.String(), Type.Object({ by: Type.String(), dir: StringEnum(["asc", "desc"]) })], [Type.String(), Type.Object({ by: Type.String(), dir: StringEnum(["asc", "desc"]) })],
{ {
default: { by: "id", dir: "asc" } default: sort_default
} }
) )
) )
.Decode((value) => { .Decode((value) => {
if (typeof value === "string") { if (typeof value === "string") {
return JSON.parse(value); if (/^-?[a-zA-Z_][a-zA-Z0-9_.]*$/.test(value)) {
const dir = value[0] === "-" ? "desc" : "asc";
return { by: dir === "desc" ? value.slice(1) : value, dir };
} else if (/^{.*}$/.test(value)) {
return JSON.parse(value);
}
return sort_default;
} }
return value; return value;
}) })