(
value: unknown,
paramName = 'value',
options: { min?: number; max?: number } = {}
)
| 266 | * ``` |
| 267 | */ |
| 268 | export function validateInteger( |
| 269 | value: unknown, |
| 270 | paramName = 'value', |
| 271 | options: { min?: number; max?: number } = {} |
| 272 | ): ValidationResult { |
| 273 | if (value === null || value === undefined) { |
| 274 | return { |
| 275 | isValid: false, |
| 276 | error: `${paramName} is required`, |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | if (typeof value !== 'number') { |
| 281 | logger.warn('Value is not a number', { paramName, valueType: typeof value }) |
| 282 | return { |
| 283 | isValid: false, |
| 284 | error: `${paramName} must be a number`, |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | if (Number.isNaN(value) || !Number.isFinite(value)) { |
| 289 | logger.warn('Invalid number value', { paramName, value }) |
| 290 | return { |
| 291 | isValid: false, |
| 292 | error: `${paramName} must be a valid number`, |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | if (!Number.isInteger(value)) { |
| 297 | logger.warn('Value is not an integer', { paramName, value }) |
| 298 | return { |
| 299 | isValid: false, |
| 300 | error: `${paramName} must be an integer`, |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | if (options.min !== undefined && value < options.min) { |
| 305 | return { |
| 306 | isValid: false, |
| 307 | error: `${paramName} must be at least ${options.min}`, |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | if (options.max !== undefined && value > options.max) { |
| 312 | return { |
| 313 | isValid: false, |
| 314 | error: `${paramName} must be at most ${options.max}`, |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | return { isValid: true } |
| 319 | } |
| 320 | |
| 321 | /** |
| 322 | * Validates that a value is in an allowed list (enum validation) |
no test coverage detected