feat: complete issue list filters, sort, and fields (task 0002)
Finish the `issue list` flag surface left minimal by the tracer slice: - Server-side filters `--label`, `--assignee`, `--author`, `--milestone`, mapped to Gitea's `labels`, `assigned_by`, `created_by`, `milestones`. - Client-side `--sort <created|updated|comments>`, always descending, over the fully paginated set (ADR 0005); `--limit` caps the sorted result. - `--fields` exposing body, closedAt, labels, milestone, updatedAt, url. - `--search` refused with a VALIDATION_ERROR redirecting to `search issues`. Exhaustive pagination lands as a shared `paginate.ts`, since ADR 0005 makes it a policy later slices reuse; `lookup.ts` drops its hand-rolled copy of the same loop. The helper carries the 20-page cap that copy encoded, matching the 1000-item ceiling Principle 8 sets.
This commit is contained in:
33
src/flags.ts
33
src/flags.ts
@@ -38,6 +38,39 @@ export function flagValue(
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
/** ["open", "closed", "all"] → "open, closed, or all". */
|
||||
function orList(values: readonly string[]): string {
|
||||
if (values.length < 2) {
|
||||
return values[0] ?? "";
|
||||
}
|
||||
return `${values.slice(0, -1).join(", ")}, or ${values[values.length - 1]}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a flag whose value must be one of a fixed set. Returns undefined when the
|
||||
* flag was absent, leaving the default to the caller — a flag with no default
|
||||
* (`--sort`) and one with a default (`--state`) then differ only in what they do
|
||||
* with that undefined.
|
||||
*/
|
||||
export function parseEnumFlag<T extends string>(
|
||||
value: string | true | undefined,
|
||||
name: string,
|
||||
allowed: readonly T[],
|
||||
suggestions: string[],
|
||||
): T | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (value === true || !allowed.includes(value as T)) {
|
||||
throw axiError(
|
||||
`Invalid ${name} value: ${String(value)} (expected ${orList(allowed)})`,
|
||||
"VALIDATION_ERROR",
|
||||
suggestions,
|
||||
);
|
||||
}
|
||||
return value as T;
|
||||
}
|
||||
|
||||
/** Split "--flag=value" into name and inline value; "--flag" has none. */
|
||||
export function splitFlag(arg: string): SplitFlag {
|
||||
const equals = arg.indexOf("=");
|
||||
|
||||
Reference in New Issue
Block a user