From f178a9dc41d360cbee3bb3e8fc8e185bb48850a2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 00:32:39 +0100 Subject: [PATCH] refactor: dedupe extension string record helpers --- extensions/feishu/src/comment-shared.ts | 13 ++++--------- extensions/matrix/src/matrix/sdk.ts | 6 ++---- extensions/qqbot/src/config-record-shared.ts | 8 +++----- extensions/tlon/src/monitor/utils.ts | 5 ++--- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/extensions/feishu/src/comment-shared.ts b/extensions/feishu/src/comment-shared.ts index 91b8b8a1c36..a626cb2fa6e 100644 --- a/extensions/feishu/src/comment-shared.ts +++ b/extensions/feishu/src/comment-shared.ts @@ -1,3 +1,5 @@ +import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime"; + export function encodeQuery(params: Record): string { const query = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { @@ -14,20 +16,13 @@ export function readString(value: unknown): string | undefined { return typeof value === "string" ? value : undefined; } -export function normalizeString(value: unknown): string | undefined { - return readString(value)?.trim() || undefined; -} +export const normalizeString = normalizeOptionalString; export function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null; } -export function asRecord(value: unknown): Record | undefined { - if (!value || typeof value !== "object" || Array.isArray(value)) { - return undefined; - } - return value as Record; -} +export const asRecord = asOptionalRecord; export function hasNonEmptyString(value: unknown): value is string { return typeof value === "string" && value.trim().length > 0; diff --git a/extensions/matrix/src/matrix/sdk.ts b/extensions/matrix/src/matrix/sdk.ts index 55ac3f366f8..9c118ecea28 100644 --- a/extensions/matrix/src/matrix/sdk.ts +++ b/extensions/matrix/src/matrix/sdk.ts @@ -10,6 +10,7 @@ import { import { VerificationMethod } from "matrix-js-sdk/lib/types.js"; import { KeyedAsyncQueue } from "openclaw/plugin-sdk/core"; import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/infra-runtime"; +import { normalizeNullableString } from "openclaw/plugin-sdk/text-runtime"; import type { SsrFPolicy } from "../runtime-api.js"; import { resolveMatrixRoomKeyBackupReadinessError } from "./backup-health.js"; import { FileBackedMatrixSyncStore } from "./client/file-sync-store.js"; @@ -173,10 +174,7 @@ async function loadMatrixCryptoRuntime(): Promise { return await matrixCryptoRuntimePromise; } -function normalizeOptionalString(value: string | null | undefined): string | null { - const normalized = value?.trim(); - return normalized ? normalized : null; -} +const normalizeOptionalString = normalizeNullableString; function isUnsupportedAuthenticatedMediaEndpointError(err: unknown): boolean { const statusCode = (err as { statusCode?: number })?.statusCode; diff --git a/extensions/qqbot/src/config-record-shared.ts b/extensions/qqbot/src/config-record-shared.ts index 1c0f1951fe2..9dae082a32c 100644 --- a/extensions/qqbot/src/config-record-shared.ts +++ b/extensions/qqbot/src/config-record-shared.ts @@ -1,8 +1,6 @@ -export function asRecord(value: unknown): Record | undefined { - return typeof value === "object" && value !== null - ? (value as Record) - : undefined; -} +import { asOptionalObjectRecord } from "openclaw/plugin-sdk/text-runtime"; + +export const asRecord = asOptionalObjectRecord; export function readString( record: Record | undefined, diff --git a/extensions/tlon/src/monitor/utils.ts b/extensions/tlon/src/monitor/utils.ts index 5f83b27ae88..d54903092b8 100644 --- a/extensions/tlon/src/monitor/utils.ts +++ b/extensions/tlon/src/monitor/utils.ts @@ -1,3 +1,4 @@ +import { asNullableObjectRecord } from "openclaw/plugin-sdk/text-runtime"; import { normalizeShip } from "../targets.js"; // Cite types for message references @@ -181,9 +182,7 @@ export async function resolveAuthorizedMessageText(params: { return citedContent + rawText; } -export function asRecord(value: unknown): Record | null { - return value && typeof value === "object" ? (value as Record) : null; -} +export const asRecord = asNullableObjectRecord; export function formatErrorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error);