Files
Primora/apps/cli/src/commands/documents.ts
T
Tomas DvorakandDevin 8892c6dc43 feat: PostgREST-style document filtering and ordering
GET /collections/:id/documents accepts filter (field.op.value terms; eq neq
gt gte lt lte like in is; dotted paths index into document data) and order
(field.asc|desc). Whitelisted field/operator parsing with parameterized
values; plain lists keep the sqlc path. CLI gains `documents list
--collection --filter --order`; OpenAPI + generated client updated.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-24 18:55:56 +02:00

65 lines
1.8 KiB
TypeScript

import { CollectionsService } from "@primora/api-client";
import { loadConfig } from "../config.js";
import { CliError, configureClient, requireAuth, requireProject } from "../http.js";
import { formatDate, isJson, printJson, printTable } from "../out.js";
interface DocumentsListOptions {
project?: string;
collection?: string;
filter?: string;
order?: string;
limit?: number;
offset?: number;
json?: boolean;
}
// Accepts a collection id or slug.
async function collectionIdFor(projectId: string, ref: string): Promise<string> {
const { items } = await CollectionsService.listCollections({ projectId });
const match = items.find((c) => c.id === ref || c.slug === ref || c.name === ref);
if (!match) {
throw new CliError(
`Collection "${ref}" not found.`,
`Known: ${items.map((c) => c.slug).join(", ") || "(none)"}`,
);
}
return match.id;
}
export async function cmdDocumentsList(options: DocumentsListOptions): Promise<void> {
if (!options.collection) {
throw new CliError("Missing --collection <slug|id>.");
}
const cfg = loadConfig();
requireAuth(cfg);
configureClient(cfg);
const projectId = requireProject(cfg, options.project);
const collectionId = await collectionIdFor(projectId, options.collection);
const res = await CollectionsService.listDocuments({
collectionId,
limit: options.limit,
offset: options.offset,
filter: options.filter,
order: options.order,
});
if (isJson(options)) {
printJson(res);
return;
}
if (!res.items.length) {
console.log("No documents.");
return;
}
printTable(
["ID", "DATA", "UPDATED"],
res.items.map((d) => [
d.id.slice(0, 8),
JSON.stringify(d.data).slice(0, 80),
formatDate(d.updated_at),
]),
);
console.log(`${res.items.length} of ${res.total}`);
}