@@ -516,19 +516,25 @@ export const isFalsy = (value: string | boolean | number | undefined) =>
516516export { getEnv }
517517
518518/**
519- * Coerce an env-derived value to a positive finite number, falling back to the
520- * provided default when the value is unset, empty, non-finite, or negative.
521- * Zero is accepted — some configs (e.g. `KB_CONFIG_DELAY_BETWEEN_BATCHES`)
522- * use `0` to mean "no delay / max throughput".
519+ * Coerce an env-derived value to a finite number ≥ `min`, falling back to the
520+ * provided default when the value is unset, empty, non-finite, or below `min`.
521+ * `min` defaults to `0` so configs like `KB_CONFIG_DELAY_BETWEEN_BATCHES=0`
522+ * (meaning "no delay / max throughput") are honored. Pass `min: 1` for configs
523+ * where zero is invalid (e.g. Redis TTLs, capacity limits).
523524 *
524525 * `createEnv` is configured with `skipValidation: true`, so values declared as
525526 * `z.number()` arrive as raw strings when sourced from `process.env` or Helm.
526527 * Use this helper anywhere a numeric env override is consumed to normalize the
527528 * type at the boundary instead of relying on JS implicit coercion.
528529 */
529- export function envNumber ( value : number | string | undefined | null , fallback : number ) : number {
530- if ( typeof value === 'number' && Number . isFinite ( value ) && value >= 0 ) return value
530+ export function envNumber (
531+ value : number | string | undefined | null ,
532+ fallback : number ,
533+ options : { min ?: number } = { }
534+ ) : number {
535+ const min = options . min ?? 0
536+ if ( typeof value === 'number' && Number . isFinite ( value ) && value >= min ) return value
531537 if ( value === undefined || value === null || value === '' ) return fallback
532538 const parsed = Number ( value )
533- return Number . isFinite ( parsed ) && parsed >= 0 ? parsed : fallback
539+ return Number . isFinite ( parsed ) && parsed >= min ? parsed : fallback
534540}
0 commit comments