mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:20:43 +00:00
refactor: share interactive payload normalizers
This commit is contained in:
@@ -46,17 +46,9 @@ export type MessagePresentationTone = "info" | "success" | "warning" | "danger"
|
||||
|
||||
export type MessagePresentationButtonStyle = InteractiveButtonStyle;
|
||||
|
||||
export type MessagePresentationButton = {
|
||||
label: string;
|
||||
value?: string;
|
||||
url?: string;
|
||||
style?: MessagePresentationButtonStyle;
|
||||
};
|
||||
export type MessagePresentationButton = InteractiveReplyButton;
|
||||
|
||||
export type MessagePresentationOption = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
export type MessagePresentationOption = InteractiveReplyOption;
|
||||
|
||||
export type MessagePresentationTextBlock = {
|
||||
type: "text";
|
||||
@@ -124,11 +116,18 @@ function normalizePresentationTone(value: unknown): MessagePresentationTone | un
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function normalizeInteractiveButton(raw: unknown): InteractiveReplyButton | undefined {
|
||||
function toRecord(raw: unknown): Record<string, unknown> | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
return raw as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function normalizeButton(raw: unknown): InteractiveReplyButton | undefined {
|
||||
const record = toRecord(raw);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
const label = normalizeOptionalString(record.label) ?? normalizeOptionalString(record.text);
|
||||
const value =
|
||||
normalizeOptionalString(record.value) ??
|
||||
@@ -146,11 +145,11 @@ function normalizeInteractiveButton(raw: unknown): InteractiveReplyButton | unde
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeInteractiveOption(raw: unknown): InteractiveReplyOption | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
function normalizeOption(raw: unknown): InteractiveReplyOption | undefined {
|
||||
const record = toRecord(raw);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
const label = normalizeOptionalString(record.label) ?? normalizeOptionalString(record.text);
|
||||
const value = normalizeOptionalString(record.value);
|
||||
if (!label || !value) {
|
||||
@@ -159,30 +158,28 @@ function normalizeInteractiveOption(raw: unknown): InteractiveReplyOption | unde
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function normalizeList<T>(value: unknown, normalizeEntry: (entry: unknown) => T | undefined): T[] {
|
||||
return Array.isArray(value)
|
||||
? value.map((entry) => normalizeEntry(entry)).filter((entry): entry is T => Boolean(entry))
|
||||
: [];
|
||||
}
|
||||
|
||||
function normalizeInteractiveBlock(raw: unknown): InteractiveReplyBlock | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
const record = toRecord(raw);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
const type = normalizeOptionalLowercaseString(record.type);
|
||||
if (type === "text") {
|
||||
const text = normalizeOptionalString(record.text);
|
||||
return text ? { type: "text", text } : undefined;
|
||||
}
|
||||
if (type === "buttons") {
|
||||
const buttons = Array.isArray(record.buttons)
|
||||
? record.buttons
|
||||
.map((entry) => normalizeInteractiveButton(entry))
|
||||
.filter((entry): entry is InteractiveReplyButton => Boolean(entry))
|
||||
: [];
|
||||
const buttons = normalizeList(record.buttons, normalizeButton);
|
||||
return buttons.length > 0 ? { type: "buttons", buttons } : undefined;
|
||||
}
|
||||
if (type === "select") {
|
||||
const options = Array.isArray(record.options)
|
||||
? record.options
|
||||
.map((entry) => normalizeInteractiveOption(entry))
|
||||
.filter((entry): entry is InteractiveReplyOption => Boolean(entry))
|
||||
: [];
|
||||
const options = normalizeList(record.options, normalizeOption);
|
||||
return options.length > 0
|
||||
? {
|
||||
type: "select",
|
||||
@@ -195,50 +192,19 @@ function normalizeInteractiveBlock(raw: unknown): InteractiveReplyBlock | undefi
|
||||
}
|
||||
|
||||
export function normalizeInteractiveReply(raw: unknown): InteractiveReply | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
const record = toRecord(raw);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
const blocks = Array.isArray(record.blocks)
|
||||
? record.blocks
|
||||
.map((entry) => normalizeInteractiveBlock(entry))
|
||||
.filter((entry): entry is InteractiveReplyBlock => Boolean(entry))
|
||||
: [];
|
||||
const blocks = normalizeList(record.blocks, normalizeInteractiveBlock);
|
||||
return blocks.length > 0 ? { blocks } : undefined;
|
||||
}
|
||||
|
||||
function normalizePresentationButton(raw: unknown): MessagePresentationButton | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
const label = normalizeOptionalString(record.label) ?? normalizeOptionalString(record.text);
|
||||
const value =
|
||||
normalizeOptionalString(record.value) ??
|
||||
normalizeOptionalString(record.callbackData) ??
|
||||
normalizeOptionalString(record.callback_data);
|
||||
const url = normalizeOptionalString(record.url);
|
||||
if (!label || (!value && !url)) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
label,
|
||||
...(value ? { value } : {}),
|
||||
...(url ? { url } : {}),
|
||||
style: normalizeButtonStyle(record.style),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizePresentationOption(raw: unknown): MessagePresentationOption | undefined {
|
||||
const option = normalizeInteractiveOption(raw);
|
||||
return option ? { label: option.label, value: option.value } : undefined;
|
||||
}
|
||||
|
||||
function normalizePresentationBlock(raw: unknown): MessagePresentationBlock | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
const record = toRecord(raw);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
const type = normalizeOptionalLowercaseString(record.type);
|
||||
if (type === "text" || type === "context") {
|
||||
const text = normalizeOptionalString(record.text);
|
||||
@@ -248,19 +214,11 @@ function normalizePresentationBlock(raw: unknown): MessagePresentationBlock | un
|
||||
return { type: "divider" };
|
||||
}
|
||||
if (type === "buttons") {
|
||||
const buttons = Array.isArray(record.buttons)
|
||||
? record.buttons
|
||||
.map((entry) => normalizePresentationButton(entry))
|
||||
.filter((entry): entry is MessagePresentationButton => Boolean(entry))
|
||||
: [];
|
||||
const buttons = normalizeList(record.buttons, normalizeButton);
|
||||
return buttons.length > 0 ? { type: "buttons", buttons } : undefined;
|
||||
}
|
||||
if (type === "select") {
|
||||
const options = Array.isArray(record.options)
|
||||
? record.options
|
||||
.map((entry) => normalizePresentationOption(entry))
|
||||
.filter((entry): entry is MessagePresentationOption => Boolean(entry))
|
||||
: [];
|
||||
const options = normalizeList(record.options, normalizeOption);
|
||||
return options.length > 0
|
||||
? {
|
||||
type: "select",
|
||||
@@ -273,15 +231,11 @@ function normalizePresentationBlock(raw: unknown): MessagePresentationBlock | un
|
||||
}
|
||||
|
||||
export function normalizeMessagePresentation(raw: unknown): MessagePresentation | undefined {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
const record = toRecord(raw);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
const record = raw as Record<string, unknown>;
|
||||
const blocks = Array.isArray(record.blocks)
|
||||
? record.blocks
|
||||
.map((entry) => normalizePresentationBlock(entry))
|
||||
.filter((entry): entry is MessagePresentationBlock => Boolean(entry))
|
||||
: [];
|
||||
const blocks = normalizeList(record.blocks, normalizePresentationBlock);
|
||||
const title = normalizeOptionalString(record.title);
|
||||
if (!title && blocks.length === 0) {
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user