Skip to content

Commit ddde144

Browse files
committed
refactor: dedupe signal lowercase helpers
1 parent 9e007ef commit ddde144

10 files changed

Lines changed: 37 additions & 22 deletions

File tree

extensions/signal/src/channel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
createComputedAccountStatusAdapter,
1919
createDefaultChannelRuntimeState,
2020
} from "openclaw/plugin-sdk/status-helpers";
21+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
2122
import { resolveSignalAccount, type ResolvedSignalAccount } from "./accounts.js";
2223
import { signalApprovalAuth } from "./approval-auth.js";
2324
import { markdownToSignalTextChunks } from "./format.js";
@@ -103,7 +104,7 @@ function inferSignalTargetChatType(rawTo: string) {
103104
if (!to) {
104105
return undefined;
105106
}
106-
const lower = to.toLowerCase();
107+
const lower = normalizeLowercaseStringOrEmpty(to);
107108
if (lower.startsWith("group:")) {
108109
return "group" as const;
109110
}

extensions/signal/src/format.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { MarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
22
import {
33
markdownToIR,
4+
normalizeLowercaseStringOrEmpty,
45
type MarkdownIR,
56
type MarkdownStyle,
67
renderMarkdownIRChunksWithinLimit,
@@ -35,7 +36,7 @@ type Insertion = {
3536
};
3637

3738
function normalizeUrlForComparison(url: string): string {
38-
let normalized = url.toLowerCase();
39+
let normalized = normalizeLowercaseStringOrEmpty(url);
3940
// Strip protocol
4041
normalized = normalized.replace(/^https?:\/\//, "");
4142
// Strip www. prefix

extensions/signal/src/identity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { evaluateSenderGroupAccessForPolicy } from "openclaw/plugin-sdk/group-access";
2-
import { normalizeE164 } from "openclaw/plugin-sdk/text-runtime";
2+
import { normalizeE164, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
33
import { looksLikeUuid } from "./uuid.js";
44

55
export type SignalSender =
@@ -69,7 +69,7 @@ function parseSignalAllowEntry(entry: string): SignalAllowEntry | null {
6969
}
7070

7171
const stripped = stripSignalPrefix(trimmed);
72-
const lower = stripped.toLowerCase();
72+
const lower = normalizeLowercaseStringOrEmpty(stripped);
7373
if (lower.startsWith("uuid:")) {
7474
const raw = stripped.slice("uuid:".length).trim();
7575
if (!raw) {

extensions/signal/src/install-signal-cli.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
88
import { runPluginCommandWithTimeout } from "openclaw/plugin-sdk/run-command";
99
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
1010
import { CONFIG_DIR, extractArchive, resolveBrewExecutable } from "openclaw/plugin-sdk/setup-tools";
11+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
1112

1213
export type ReleaseAsset = {
1314
name?: string;
@@ -64,10 +65,12 @@ export function pickAsset(
6465
);
6566

6667
// Archives only, excluding signature files (.asc)
67-
const archives = withName.filter((a) => looksLikeArchive(a.name.toLowerCase()));
68+
const archives = withName.filter((a) =>
69+
looksLikeArchive(normalizeLowercaseStringOrEmpty(a.name)),
70+
);
6871

6972
const byName = (pattern: RegExp) =>
70-
archives.find((asset) => pattern.test(asset.name.toLowerCase()));
73+
archives.find((asset) => pattern.test(normalizeLowercaseStringOrEmpty(asset.name)));
7174

7275
if (platform === "linux") {
7376
// The official "Linux-native" asset is an x86-64 GraalVM binary.
@@ -253,7 +256,7 @@ async function installSignalCliFromRelease(runtime: RuntimeEnv): Promise<SignalI
253256
const installRoot = path.join(CONFIG_DIR, "tools", "signal-cli", version);
254257
await fs.mkdir(installRoot, { recursive: true });
255258

256-
if (!looksLikeArchive(asset.name.toLowerCase())) {
259+
if (!looksLikeArchive(normalizeLowercaseStringOrEmpty(asset.name))) {
257260
return { ok: false, error: `Unsupported archive type: ${asset.name}` };
258261
}
259262
try {

extensions/signal/src/message-actions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
ChannelMessageActionAdapter,
55
ChannelMessageActionName,
66
} from "openclaw/plugin-sdk/channel-contract";
7+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
78
import { removeReactionSignal, sendReactionSignal } from "../reaction-runtime-api.js";
89
import { listEnabledSignalAccounts, resolveSignalAccount } from "./accounts.js";
910
import { resolveSignalReactionLevel } from "./reaction-level.js";
@@ -20,7 +21,7 @@ function normalizeSignalReactionRecipient(raw: string): string {
2021
if (!withoutSignal) {
2122
return withoutSignal;
2223
}
23-
if (withoutSignal.toLowerCase().startsWith("uuid:")) {
24+
if (normalizeLowercaseStringOrEmpty(withoutSignal).startsWith("uuid:")) {
2425
return withoutSignal.slice("uuid:".length).trim();
2526
}
2627
return withoutSignal;
@@ -35,7 +36,7 @@ function resolveSignalReactionTarget(raw: string): { recipient?: string; groupId
3536
if (!withoutSignal) {
3637
return {};
3738
}
38-
if (withoutSignal.toLowerCase().startsWith(GROUP_PREFIX)) {
39+
if (normalizeLowercaseStringOrEmpty(withoutSignal).startsWith(GROUP_PREFIX)) {
3940
const groupId = withoutSignal.slice(GROUP_PREFIX.length).trim();
4041
return groupId ? { groupId } : {};
4142
}

extensions/signal/src/normalize.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
1+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
2+
13
export function normalizeSignalMessagingTarget(raw: string): string | undefined {
24
const trimmed = raw.trim();
35
if (!trimmed) {
46
return undefined;
57
}
68
let normalized = trimmed;
7-
if (normalized.toLowerCase().startsWith("signal:")) {
9+
if (normalizeLowercaseStringOrEmpty(normalized).startsWith("signal:")) {
810
normalized = normalized.slice("signal:".length).trim();
911
}
1012
if (!normalized) {
1113
return undefined;
1214
}
13-
const lower = normalized.toLowerCase();
15+
const lower = normalizeLowercaseStringOrEmpty(normalized);
1416
if (lower.startsWith("group:")) {
1517
const id = normalized.slice("group:".length).trim();
1618
return id ? `group:${id}` : undefined;
1719
}
1820
if (lower.startsWith("username:")) {
1921
const id = normalized.slice("username:".length).trim();
20-
return id ? `username:${id}`.toLowerCase() : undefined;
22+
return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : undefined;
2123
}
2224
if (lower.startsWith("u:")) {
2325
const id = normalized.slice("u:".length).trim();
24-
return id ? `username:${id}`.toLowerCase() : undefined;
26+
return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : undefined;
2527
}
2628
if (lower.startsWith("uuid:")) {
2729
const id = normalized.slice("uuid:".length).trim();
28-
return id ? id.toLowerCase() : undefined;
30+
return id ? normalizeLowercaseStringOrEmpty(id) : undefined;
2931
}
30-
return normalized.toLowerCase();
32+
return normalizeLowercaseStringOrEmpty(normalized);
3133
}
3234

3335
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

extensions/signal/src/outbound-session.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type RoutePeer } from "openclaw/plugin-sdk/routing";
2+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
23
import { resolveSignalPeerId, resolveSignalRecipient, resolveSignalSender } from "./identity.js";
34
import { looksLikeUuid } from "./uuid.js";
45

@@ -11,7 +12,7 @@ export type ResolvedSignalOutboundTarget = {
1112

1213
export function resolveSignalOutboundTarget(target: string): ResolvedSignalOutboundTarget | null {
1314
const stripped = target.replace(/^signal:/i, "").trim();
14-
const lowered = stripped.toLowerCase();
15+
const lowered = normalizeLowercaseStringOrEmpty(stripped);
1516
if (lowered.startsWith("group:")) {
1617
const groupId = stripped.slice("group:".length).trim();
1718
if (!groupId) {
@@ -35,7 +36,7 @@ export function resolveSignalOutboundTarget(target: string): ResolvedSignalOutbo
3536
return null;
3637
}
3738

38-
const uuidCandidate = recipient.toLowerCase().startsWith("uuid:")
39+
const uuidCandidate = normalizeLowercaseStringOrEmpty(recipient).startsWith("uuid:")
3940
? recipient.slice("uuid:".length)
4041
: recipient;
4142
const sender = resolveSignalSender({

extensions/signal/src/send-reactions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
6+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
67
import { resolveSignalAccount } from "./accounts.js";
78
import { signalRpcRequest } from "./client.js";
89
import { resolveSignalRpcContext } from "./rpc-context.js";
@@ -52,7 +53,7 @@ function normalizeSignalUuid(raw: string): string {
5253
if (!trimmed) {
5354
return "";
5455
}
55-
if (trimmed.toLowerCase().startsWith("uuid:")) {
56+
if (normalizeLowercaseStringOrEmpty(trimmed).startsWith("uuid:")) {
5657
return trimmed.slice("uuid:".length).trim();
5758
}
5859
return trimmed;

extensions/signal/src/send.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { loadConfig, type OpenClawConfig } from "openclaw/plugin-sdk/config-runt
22
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
33
import { kindFromMime } from "openclaw/plugin-sdk/media-runtime";
44
import { resolveOutboundAttachmentFromUrl } from "openclaw/plugin-sdk/media-runtime";
5+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
56
import { resolveSignalAccount } from "./accounts.js";
67
import { signalRpcRequest } from "./client.js";
78
import { markdownToSignalText, type SignalTextStyleRange } from "./format.js";
@@ -66,11 +67,11 @@ function parseTarget(raw: string): SignalTarget {
6667
if (!value) {
6768
throw new Error("Signal recipient is required");
6869
}
69-
const lower = value.toLowerCase();
70+
const lower = normalizeLowercaseStringOrEmpty(value);
7071
if (lower.startsWith("signal:")) {
7172
value = value.slice("signal:".length).trim();
7273
}
73-
const normalized = value.toLowerCase();
74+
const normalized = normalizeLowercaseStringOrEmpty(value);
7475
if (normalized.startsWith("group:")) {
7576
return { type: "group", groupId: value.slice("group:".length).trim() };
7677
}

extensions/signal/src/setup-core.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import {
1818
type WizardPrompter,
1919
} from "openclaw/plugin-sdk/setup-runtime";
2020
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
21-
import { normalizeE164, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
21+
import {
22+
normalizeE164,
23+
normalizeLowercaseStringOrEmpty,
24+
normalizeOptionalString,
25+
} from "openclaw/plugin-sdk/text-runtime";
2226
import { resolveDefaultSignalAccountId, resolveSignalAccount } from "./accounts.js";
2327

2428
const channel = "signal" as const;
@@ -50,7 +54,7 @@ function isUuidLike(value: string): boolean {
5054

5155
export function parseSignalAllowFromEntries(raw: string): { entries: string[]; error?: string } {
5256
return parseSetupEntriesAllowingWildcard(raw, (entry) => {
53-
if (entry.toLowerCase().startsWith("uuid:")) {
57+
if (normalizeLowercaseStringOrEmpty(entry).startsWith("uuid:")) {
5458
const id = entry.slice("uuid:".length).trim();
5559
if (!id) {
5660
return { error: "Invalid uuid entry" };

0 commit comments

Comments
 (0)