mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 04:46:23 +00:00
fix(matrix): centralize initial sync limit coercion
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { resolveIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
||||
|
||||
export function resolveMatrixActionLimit(raw: unknown, fallback: number): number {
|
||||
if (typeof raw !== "number" || !Number.isFinite(raw)) {
|
||||
return fallback;
|
||||
}
|
||||
return Math.max(1, Math.floor(raw));
|
||||
return resolveIntegerOption(raw, fallback, { min: 1 });
|
||||
}
|
||||
|
||||
@@ -85,6 +85,24 @@ describe("Matrix auth/config live surfaces", () => {
|
||||
expect(resolved.encryption).toBe(false);
|
||||
});
|
||||
|
||||
it("ignores non-finite initial sync limits", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
matrix: {
|
||||
initialSyncLimit: Number.NaN,
|
||||
accounts: {
|
||||
ops: {
|
||||
initialSyncLimit: Number.POSITIVE_INFINITY,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as CoreConfig;
|
||||
|
||||
const resolved = resolveMatrixConfigForAccount(cfg, "ops", {} as NodeJS.ProcessEnv);
|
||||
expect(resolved.initialSyncLimit).toBeUndefined();
|
||||
});
|
||||
|
||||
it("resolves accessToken SecretRef against the provided env", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import { resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
||||
import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
|
||||
import {
|
||||
@@ -412,7 +413,7 @@ function readMatrixAccountConfigField(
|
||||
}
|
||||
|
||||
function clampMatrixInitialSyncLimit(value: unknown): number | undefined {
|
||||
return typeof value === "number" ? Math.max(0, Math.floor(value)) : undefined;
|
||||
return resolveOptionalIntegerOption(value, { min: 0 });
|
||||
}
|
||||
|
||||
function buildMatrixNetworkFields(params: {
|
||||
|
||||
@@ -54,6 +54,27 @@ describe("updateMatrixAccountConfig", () => {
|
||||
expect(account?.userId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not store non-finite initial sync limits", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
matrix: {
|
||||
accounts: {
|
||||
default: {
|
||||
initialSyncLimit: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as CoreConfig;
|
||||
|
||||
const updated = updateMatrixAccountConfig(cfg, "default", {
|
||||
initialSyncLimit: Number.NaN,
|
||||
});
|
||||
|
||||
expect(updated.channels?.matrix?.initialSyncLimit).toBeUndefined();
|
||||
expect(updated.channels?.matrix?.accounts?.default?.initialSyncLimit).toBeUndefined();
|
||||
});
|
||||
|
||||
it("preserves SecretRef auth inputs when updating config", () => {
|
||||
const updated = updateMatrixAccountConfig({} as CoreConfig, "default", {
|
||||
accessToken: { source: "env", provider: "default", id: "MATRIX_ACCESS_TOKEN" },
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
||||
import { resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { coerceSecretRef } from "openclaw/plugin-sdk/secret-ref-runtime";
|
||||
import { normalizeSecretInputString } from "openclaw/plugin-sdk/setup";
|
||||
import type { CoreConfig, MatrixConfig } from "../types.js";
|
||||
@@ -188,7 +189,12 @@ export function updateMatrixAccountConfig(
|
||||
if (patch.initialSyncLimit === null) {
|
||||
delete nextAccount.initialSyncLimit;
|
||||
} else {
|
||||
nextAccount.initialSyncLimit = Math.max(0, Math.floor(patch.initialSyncLimit));
|
||||
const initialSyncLimit = resolveOptionalIntegerOption(patch.initialSyncLimit, { min: 0 });
|
||||
if (initialSyncLimit === undefined) {
|
||||
delete nextAccount.initialSyncLimit;
|
||||
} else {
|
||||
nextAccount.initialSyncLimit = initialSyncLimit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plu
|
||||
import type { ChannelRuntimeSurface } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import { resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
||||
import {
|
||||
GROUP_POLICY_BLOCKED_LABEL,
|
||||
resolveThreadBindingIdleTimeoutMsForChannel,
|
||||
@@ -214,9 +215,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
|
||||
const auth = await resolveMatrixAuth({ cfg, accountId: effectiveAccountId });
|
||||
const resolvedInitialSyncLimit =
|
||||
typeof opts.initialSyncLimit === "number"
|
||||
? Math.max(0, Math.floor(opts.initialSyncLimit))
|
||||
: auth.initialSyncLimit;
|
||||
resolveOptionalIntegerOption(opts.initialSyncLimit, { min: 0 }) ?? auth.initialSyncLimit;
|
||||
const authWithLimit =
|
||||
resolvedInitialSyncLimit === auth.initialSyncLimit
|
||||
? auth
|
||||
|
||||
@@ -4,6 +4,7 @@ export {
|
||||
parseFiniteNumber,
|
||||
resolveIntegerOption,
|
||||
resolveNonNegativeIntegerOption,
|
||||
resolveOptionalIntegerOption,
|
||||
parseStrictInteger,
|
||||
parseStrictFiniteNumber,
|
||||
parseStrictNonNegativeInteger,
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
parseFiniteNumber,
|
||||
resolveIntegerOption,
|
||||
resolveNonNegativeIntegerOption,
|
||||
resolveOptionalIntegerOption,
|
||||
parseStrictFiniteNumber,
|
||||
parseStrictInteger,
|
||||
parseStrictNonNegativeInteger,
|
||||
@@ -76,4 +77,12 @@ describe("number-coercion", () => {
|
||||
expect(resolveIntegerOption(40, 1, { max: 10 })).toBe(10);
|
||||
expect(resolveNonNegativeIntegerOption(Number.NaN, 3.9)).toBe(3);
|
||||
});
|
||||
|
||||
test("optional integer option helper rejects non-finite values", () => {
|
||||
expect(resolveOptionalIntegerOption(7.9, { min: 1, max: 10 })).toBe(7);
|
||||
expect(resolveOptionalIntegerOption(Number.NaN, { min: 1 })).toBeUndefined();
|
||||
expect(resolveOptionalIntegerOption(Number.POSITIVE_INFINITY, { min: 1 })).toBeUndefined();
|
||||
expect(resolveOptionalIntegerOption(-4, { min: 0 })).toBe(0);
|
||||
expect(resolveOptionalIntegerOption(40, { max: 10 })).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,6 +107,19 @@ export function resolveIntegerOption(
|
||||
return range.max === undefined ? minBounded : Math.min(range.max, minBounded);
|
||||
}
|
||||
|
||||
export function resolveOptionalIntegerOption(
|
||||
value: unknown,
|
||||
range: {
|
||||
min?: number;
|
||||
max?: number;
|
||||
} = {},
|
||||
): number | undefined {
|
||||
if (typeof value !== "number" || !Number.isFinite(value)) {
|
||||
return undefined;
|
||||
}
|
||||
return resolveIntegerOption(value, value, range);
|
||||
}
|
||||
|
||||
export function resolveNonNegativeIntegerOption(value: unknown, fallback: number): number {
|
||||
return resolveIntegerOption(value, fallback, { min: 0 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user