Files
plainleaf/client/runtime_api/objects_api.ts
T

100 lines
2.5 KiB
TypeScript

import {
translateListRequest,
TranslationError,
type Filter,
type OrderKey,
} from "./translate_query.ts";
import { parseExpressionString } from "../space_lua/parse.ts";
import type { LuaExpression } from "../space_lua/ast.ts";
import {
type LuaEnv,
type LuaStackFrame,
luaValueToJS,
} from "../space_lua/runtime.ts";
export type ObjectsRequest =
| { kind: "list_tags" }
| { kind: "get"; tag: string; ref: string }
| {
kind: "list";
tag: string;
filters: Filter[];
order: OrderKey[];
limit: number;
offset: number;
select?: string[];
debug?: boolean;
};
export type ObjectsResponse =
| { ok: true; items: any[]; equivalentLua?: string }
| { ok: true; item: any }
| { ok: false; code: string; error: string };
export type ObjectsDeps = {
objectIndex: {
queryLuaObjects(env: LuaEnv, tag: string, query: any): Promise<any[]>;
tagNames(): Promise<string[]>;
};
env: LuaEnv;
stackFrame: LuaStackFrame;
};
export async function handleObjectsRequest(
deps: ObjectsDeps,
req: ObjectsRequest,
): Promise<ObjectsResponse> {
try {
switch (req.kind) {
case "list_tags": {
const items = await deps.objectIndex.tagNames();
return { ok: true, items };
}
case "get": {
const items = await deps.objectIndex.queryLuaObjects(
deps.env,
req.tag,
{
objectVariable: "_it",
where: parseExpressionString(
`_it.ref == ${JSON.stringify(req.ref)}`,
) as LuaExpression,
limit: 1,
},
);
if (items.length === 0) {
return {
ok: false,
code: "not_found",
error: `${req.tag}/${req.ref} not found`,
};
}
return { ok: true, item: items[0] };
}
case "list": {
const { query, equivalentLua } = translateListRequest(req);
const rawItems = await deps.objectIndex.queryLuaObjects(
deps.env,
req.tag,
query,
);
const items = req.select?.length
? await Promise.all(
rawItems.map((v) => luaValueToJS(v, deps.stackFrame)),
)
: rawItems;
return { ok: true, items, equivalentLua };
}
}
} catch (e: unknown) {
if (e instanceof TranslationError) {
return { ok: false, code: e.code, error: e.cause };
}
return {
ok: false,
code: "internal_error",
error: e instanceof Error ? e.message : String(e),
};
}
}