import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js" ;
export type SlashCommandParseResult =
| { kind: "no-match" }
| { kind: "empty" }
| { kind: "invalid" }
| { kind: "parsed" ; action: string; args: string };
export type ParsedSlashCommand =
| { ok: true ; action: string; args: string }
| { ok: false ; message: string };
export function parseSlashCommandActionArgs(raw: string, slash: string): SlashCommandParseResult {
const trimmed = raw.trim();
const slashLower = normalizeLowercaseStringOrEmpty(slash);
if (!normalizeLowercaseStringOrEmpty(trimmed).startsWith(slashLower)) {
return { kind: "no-match" };
}
const rest = trimmed.slice(slash.length).trim();
if (!rest) {
return { kind: "empty" };
}
const match = rest.match(/^(\S+)(?:\s+([\s\S]+))?$/);
if (!match) {
return { kind: "invalid" };
}
const action = normalizeLowercaseStringOrEmpty(match[1 ]);
const args = (match[2 ] ?? "" ).trim();
return { kind: "parsed" , action, args };
}
export function parseSlashCommandOrNull(
raw: string,
slash: string,
opts: { invalidMessage: string; defaultAction?: string },
): ParsedSlashCommand | null {
const parsed = parseSlashCommandActionArgs(raw, slash);
if (parsed.kind === "no-match" ) {
return null ;
}
if (parsed.kind === "invalid" ) {
return { ok: false , message: opts.invalidMessage };
}
if (parsed.kind === "empty" ) {
return { ok: true , action: opts.defaultAction ?? "show" , args: "" };
}
return { ok: true , action: parsed.action, args: parsed.args };
}
Messung V0.5 in Prozent C=99 H=99 G=98
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland