refactor(auto-reply): share set/unset command action parsing

This commit is contained in:
Peter Steinberger
2026-02-18 17:13:40 +00:00
parent 288015a9fc
commit 818419b4c4
4 changed files with 98 additions and 22 deletions

View File

@@ -0,0 +1,50 @@
import { describe, expect, it } from "vitest";
import { parseSetUnsetCommand, parseSetUnsetCommandAction } from "./commands-setunset.js";
describe("parseSetUnsetCommand", () => {
it("parses unset values", () => {
expect(
parseSetUnsetCommand({
slash: "/config",
action: "unset",
args: "foo.bar",
}),
).toEqual({ kind: "unset", path: "foo.bar" });
});
it("parses set values", () => {
expect(
parseSetUnsetCommand({
slash: "/config",
action: "set",
args: 'foo.bar={"x":1}',
}),
).toEqual({ kind: "set", path: "foo.bar", value: { x: 1 } });
});
});
describe("parseSetUnsetCommandAction", () => {
it("returns null for non set/unset actions", () => {
const result = parseSetUnsetCommandAction({
slash: "/config",
action: "show",
args: "",
onSet: (path, value) => ({ action: "set", path, value }),
onUnset: (path) => ({ action: "unset", path }),
onError: (message) => ({ action: "error", message }),
});
expect(result).toBeNull();
});
it("maps parse errors through onError", () => {
const result = parseSetUnsetCommandAction({
slash: "/config",
action: "set",
args: "",
onSet: (path, value) => ({ action: "set", path, value }),
onUnset: (path) => ({ action: "unset", path }),
onError: (message) => ({ action: "error", message }),
});
expect(result).toEqual({ action: "error", message: "Usage: /config set path=value" });
});
});

View File

@@ -36,3 +36,27 @@ export function parseSetUnsetCommand(params: {
}
return { kind: "set", path, value: parsed.value };
}
export function parseSetUnsetCommandAction<T>(params: {
slash: string;
action: string;
args: string;
onSet: (path: string, value: unknown) => T;
onUnset: (path: string) => T;
onError: (message: string) => T;
}): T | null {
if (params.action !== "set" && params.action !== "unset") {
return null;
}
const parsed = parseSetUnsetCommand({
slash: params.slash,
action: params.action,
args: params.args,
});
if (parsed.kind === "error") {
return params.onError(parsed.message);
}
return parsed.kind === "set"
? params.onSet(parsed.path, parsed.value)
: params.onUnset(parsed.path);
}

View File

@@ -1,4 +1,4 @@
import { parseSetUnsetCommand } from "./commands-setunset.js";
import { parseSetUnsetCommandAction } from "./commands-setunset.js";
import { parseSlashCommandOrNull } from "./commands-slash-parse.js";
export type ConfigCommand =
@@ -18,22 +18,23 @@ export function parseConfigCommand(raw: string): ConfigCommand | null {
return { action: "error", message: parsed.message };
}
const { action, args } = parsed;
const setUnset = parseSetUnsetCommandAction<ConfigCommand>({
slash: "/config",
action,
args,
onSet: (path, value) => ({ action: "set", path, value }),
onUnset: (path) => ({ action: "unset", path }),
onError: (message) => ({ action: "error", message }),
});
if (setUnset) {
return setUnset;
}
switch (action) {
case "show":
return { action: "show", path: args || undefined };
case "get":
return { action: "show", path: args || undefined };
case "unset":
case "set": {
const parsed = parseSetUnsetCommand({ slash: "/config", action, args });
if (parsed.kind === "error") {
return { action: "error", message: parsed.message };
}
return parsed.kind === "set"
? { action: "set", path: parsed.path, value: parsed.value }
: { action: "unset", path: parsed.path };
}
default:
return {
action: "error",

View File

@@ -1,4 +1,4 @@
import { parseSetUnsetCommand } from "./commands-setunset.js";
import { parseSetUnsetCommandAction } from "./commands-setunset.js";
import { parseSlashCommandOrNull } from "./commands-slash-parse.js";
export type DebugCommand =
@@ -19,22 +19,23 @@ export function parseDebugCommand(raw: string): DebugCommand | null {
return { action: "error", message: parsed.message };
}
const { action, args } = parsed;
const setUnset = parseSetUnsetCommandAction<DebugCommand>({
slash: "/debug",
action,
args,
onSet: (path, value) => ({ action: "set", path, value }),
onUnset: (path) => ({ action: "unset", path }),
onError: (message) => ({ action: "error", message }),
});
if (setUnset) {
return setUnset;
}
switch (action) {
case "show":
return { action: "show" };
case "reset":
return { action: "reset" };
case "unset":
case "set": {
const parsed = parseSetUnsetCommand({ slash: "/debug", action, args });
if (parsed.kind === "error") {
return { action: "error", message: parsed.message };
}
return parsed.kind === "set"
? { action: "set", path: parsed.path, value: parsed.value }
: { action: "unset", path: parsed.path };
}
default:
return {
action: "error",