refactor: share zalo status issue helpers

This commit is contained in:
Peter Steinberger 2026-03-14 01:12:57 +00:00
parent 7285e04ead
commit 1ec6b012f8
4 changed files with 61 additions and 54 deletions

View File

@ -0,0 +1,18 @@
export function readStatusIssueFields<TField extends string>(
value: unknown,
fields: readonly TField[],
): Record<TField, unknown> | null {
if (!value || typeof value !== "object") {
return null;
}
const record = value as Record<string, unknown>;
const result = {} as Record<TField, unknown>;
for (const field of fields) {
result[field] = record[field];
}
return result;
}
export function coerceStatusIssueAccountId(value: unknown): string | undefined {
return typeof value === "string" ? value : typeof value === "number" ? String(value) : undefined;
}

View File

@ -0,0 +1,29 @@
import { describe, expect, it } from "vitest";
import { collectZaloStatusIssues } from "./status-issues.js";
describe("collectZaloStatusIssues", () => {
it("warns when dmPolicy is open", () => {
const issues = collectZaloStatusIssues([
{
accountId: "default",
enabled: true,
configured: true,
dmPolicy: "open",
},
]);
expect(issues).toHaveLength(1);
expect(issues[0]?.kind).toBe("config");
});
it("skips unconfigured accounts", () => {
const issues = collectZaloStatusIssues([
{
accountId: "default",
enabled: true,
configured: false,
dmPolicy: "open",
},
]);
expect(issues).toHaveLength(0);
});
});

View File

@ -1,38 +1,16 @@
import type { ChannelAccountSnapshot, ChannelStatusIssue } from "openclaw/plugin-sdk/zalo";
import { coerceStatusIssueAccountId, readStatusIssueFields } from "../../shared/status-issues.js";
type ZaloAccountStatus = {
accountId?: unknown;
enabled?: unknown;
configured?: unknown;
dmPolicy?: unknown;
};
const isRecord = (value: unknown): value is Record<string, unknown> =>
Boolean(value && typeof value === "object");
const asString = (value: unknown): string | undefined =>
typeof value === "string" ? value : typeof value === "number" ? String(value) : undefined;
function readZaloAccountStatus(value: ChannelAccountSnapshot): ZaloAccountStatus | null {
if (!isRecord(value)) {
return null;
}
return {
accountId: value.accountId,
enabled: value.enabled,
configured: value.configured,
dmPolicy: value.dmPolicy,
};
}
const ZALO_STATUS_FIELDS = ["accountId", "enabled", "configured", "dmPolicy"] as const;
export function collectZaloStatusIssues(accounts: ChannelAccountSnapshot[]): ChannelStatusIssue[] {
const issues: ChannelStatusIssue[] = [];
for (const entry of accounts) {
const account = readZaloAccountStatus(entry);
const account = readStatusIssueFields(entry, ZALO_STATUS_FIELDS);
if (!account) {
continue;
}
const accountId = asString(account.accountId) ?? "default";
const accountId = coerceStatusIssueAccountId(account.accountId) ?? "default";
const enabled = account.enabled !== false;
const configured = account.configured === true;
if (!enabled || !configured) {

View File

@ -1,42 +1,24 @@
import type { ChannelAccountSnapshot, ChannelStatusIssue } from "openclaw/plugin-sdk/zalouser";
import { coerceStatusIssueAccountId, readStatusIssueFields } from "../../shared/status-issues.js";
type ZalouserAccountStatus = {
accountId?: unknown;
enabled?: unknown;
configured?: unknown;
dmPolicy?: unknown;
lastError?: unknown;
};
const isRecord = (value: unknown): value is Record<string, unknown> =>
Boolean(value && typeof value === "object");
const asString = (value: unknown): string | undefined =>
typeof value === "string" ? value : typeof value === "number" ? String(value) : undefined;
function readZalouserAccountStatus(value: ChannelAccountSnapshot): ZalouserAccountStatus | null {
if (!isRecord(value)) {
return null;
}
return {
accountId: value.accountId,
enabled: value.enabled,
configured: value.configured,
dmPolicy: value.dmPolicy,
lastError: value.lastError,
};
}
const ZALOUSER_STATUS_FIELDS = [
"accountId",
"enabled",
"configured",
"dmPolicy",
"lastError",
] as const;
export function collectZalouserStatusIssues(
accounts: ChannelAccountSnapshot[],
): ChannelStatusIssue[] {
const issues: ChannelStatusIssue[] = [];
for (const entry of accounts) {
const account = readZalouserAccountStatus(entry);
const account = readStatusIssueFields(entry, ZALOUSER_STATUS_FIELDS);
if (!account) {
continue;
}
const accountId = asString(account.accountId) ?? "default";
const accountId = coerceStatusIssueAccountId(account.accountId) ?? "default";
const enabled = account.enabled !== false;
if (!enabled) {
continue;