11import { randomBytes } from "node:crypto" ;
22import { inspect } from "node:util" ;
3+ import { parseFiniteNumber } from "openclaw/plugin-sdk/number-runtime" ;
34import { serializeRequestBody } from "./rest-body.js" ;
45import {
56 DiscordError ,
@@ -41,6 +42,12 @@ export type RequestClientOptions = {
4142 fetch ?: ( input : string | URL | Request , init ?: RequestInit ) => Promise < Response > ;
4243} ;
4344
45+ type NormalizedRequestClientOptions = RequestClientOptions & {
46+ apiVersion : number ;
47+ maxQueueSize : number ;
48+ timeout : number ;
49+ } ;
50+
4451export type RequestData = {
4552 body ?: unknown ;
4653 multipartStyle ?: "message" | "form" ;
@@ -134,7 +141,7 @@ async function normalizeFetchBody(
134141}
135142
136143export class RequestClient {
137- readonly options : RequestClientOptions ;
144+ readonly options : NormalizedRequestClientOptions ;
138145 protected token : string ;
139146 protected customFetch : RequestClientOptions [ "fetch" ] ;
140147 protected requestControllers = new Set < AbortController > ( ) ;
@@ -143,16 +150,23 @@ export class RequestClient {
143150 constructor ( token : string , options ?: RequestClientOptions ) {
144151 this . token = token . replace ( / ^ B o t \s + / i, "" ) ;
145152 this . customFetch = options ?. fetch ;
146- this . options = { ... defaultOptions , ... options } ;
153+ this . options = normalizeRequestClientOptions ( options ) ;
147154 this . scheduler = new RestScheduler < RequestData > (
148155 {
149- lanes : normalizeSchedulerLanes (
150- this . options . maxQueueSize ?? defaultOptions . maxQueueSize ,
151- this . options . scheduler ?. lanes ,
156+ lanes : normalizeSchedulerLanes ( this . options . maxQueueSize , this . options . scheduler ?. lanes ) ,
157+ maxConcurrency : normalizeIntegerOption (
158+ this . options . scheduler ?. maxConcurrency ,
159+ DEFAULT_MAX_CONCURRENT_WORKERS ,
160+ { min : 1 } ,
161+ ) ,
162+ maxQueueSize : this . options . maxQueueSize ,
163+ maxRateLimitRetries : normalizeIntegerOption (
164+ this . options . scheduler ?. maxRateLimitRetries ,
165+ 3 ,
166+ {
167+ min : 0 ,
168+ } ,
152169 ) ,
153- maxConcurrency : this . options . scheduler ?. maxConcurrency ?? DEFAULT_MAX_CONCURRENT_WORKERS ,
154- maxQueueSize : this . options . maxQueueSize ?? defaultOptions . maxQueueSize ,
155- maxRateLimitRetries : this . options . scheduler ?. maxRateLimitRetries ?? 3 ,
156170 } ,
157171 async ( request ) =>
158172 await this . executeRequest (
@@ -280,11 +294,36 @@ export class RequestClient {
280294 }
281295}
282296
297+ function normalizeIntegerOption (
298+ value : number | undefined ,
299+ fallback : number ,
300+ params : { min : number } ,
301+ ) : number {
302+ const candidate = parseFiniteNumber ( value ) ?? fallback ;
303+ return Math . max ( params . min , Math . floor ( candidate ) ) ;
304+ }
305+
306+ function normalizeRequestClientOptions (
307+ options ?: RequestClientOptions ,
308+ ) : NormalizedRequestClientOptions {
309+ const merged = { ...defaultOptions , ...options } ;
310+ return {
311+ ...merged ,
312+ apiVersion : normalizeIntegerOption ( merged . apiVersion , defaultOptions . apiVersion , { min : 1 } ) ,
313+ timeout : normalizeIntegerOption ( merged . timeout , defaultOptions . timeout , { min : 1 } ) ,
314+ maxQueueSize : normalizeIntegerOption ( merged . maxQueueSize , defaultOptions . maxQueueSize , {
315+ min : 1 ,
316+ } ) ,
317+ } ;
318+ }
319+
283320function normalizeSchedulerLanes (
284321 maxQueueSize : number ,
285322 lanes ?: RequestSchedulerOptions [ "lanes" ] ,
286323) : Record < RestRequestPriority , { maxQueueSize : number ; staleAfterMs ?: number ; weight : number } > {
287- const fallbackMaxQueueSize = Math . max ( 1 , Math . floor ( maxQueueSize ) ) ;
324+ const fallbackMaxQueueSize = normalizeIntegerOption ( maxQueueSize , defaultOptions . maxQueueSize , {
325+ min : 1 ,
326+ } ) ;
288327 return {
289328 critical : normalizeSchedulerLane ( "critical" , fallbackMaxQueueSize , lanes ?. critical ) ,
290329 standard : normalizeSchedulerLane ( "standard" , fallbackMaxQueueSize , lanes ?. standard ) ,
@@ -298,17 +337,20 @@ function normalizeSchedulerLane(
298337 options ?: { maxQueueSize ?: number ; staleAfterMs ?: number ; weight ?: number } ,
299338) : { maxQueueSize : number ; staleAfterMs ?: number ; weight : number } {
300339 const defaults = defaultLaneOptions [ lane ] ;
340+ const staleAfterMs =
341+ options ?. staleAfterMs !== undefined
342+ ? normalizeIntegerOption ( options . staleAfterMs , defaults . staleAfterMs ?? 0 , { min : 0 } )
343+ : defaults . staleAfterMs ;
301344 return {
302345 maxQueueSize :
303346 options ?. maxQueueSize !== undefined
304- ? Math . max ( 1 , Math . floor ( options . maxQueueSize ) )
347+ ? normalizeIntegerOption ( options . maxQueueSize , maxQueueSize , { min : 1 } )
305348 : maxQueueSize ,
306- staleAfterMs :
307- options ?. staleAfterMs !== undefined
308- ? Math . max ( 0 , Math . floor ( options . staleAfterMs ) )
309- : defaults . staleAfterMs ,
349+ ...( staleAfterMs !== undefined ? { staleAfterMs } : { } ) ,
310350 weight :
311- options ?. weight !== undefined ? Math . max ( 1 , Math . floor ( options . weight ) ) : defaults . weight ,
351+ options ?. weight !== undefined
352+ ? normalizeIntegerOption ( options . weight , defaults . weight , { min : 1 } )
353+ : defaults . weight ,
312354 } ;
313355}
314356
0 commit comments