Skip to content

Commit bb5d305

Browse files
chore: implement smallint
1 parent fa77c58 commit bb5d305

File tree

6 files changed

+112
-2
lines changed

6 files changed

+112
-2
lines changed

src/types/base.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export type ValidationNames = 'base' |
7474
'timestampTz' |
7575
'float' |
7676
'decimal' |
77-
'time'
77+
'time' |
78+
'smallint'
7879

7980
export type Infer<T> = T extends Validator<infer U> ? U : never

src/types/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { FloatValidatorType } from './float'
88
import type { BigintValidatorType, NumberValidatorType } from './number'
99
import type { ObjectValidatorType } from './object'
1010
import type { PasswordValidatorType } from './password'
11+
import type { SmallintValidatorType } from './smallint'
1112
// Re-export ValidationInstance type
1213
import type { StringValidatorType, TextValidatorType } from './string'
1314
import type { TimeValidatorType } from './time'
@@ -22,14 +23,17 @@ export * from './boolean'
2223
export * from './custom'
2324
export * from './date'
2425
export * from './decimal'
26+
export * from './decimal'
2527
export * from './enum'
2628
export * from './float'
29+
export * from './float'
2730
export * from './number'
31+
2832
export * from './object'
2933
// Options types
3034
export * from './options'
31-
3235
export * from './password'
36+
export * from './smallint'
3337
// Validator types
3438
export * from './string'
3539
export * from './time'
@@ -55,6 +59,7 @@ export interface ValidationInstance {
5559
float: () => FloatValidatorType
5660
decimal: () => DecimalValidatorType
5761
time: () => TimeValidatorType
62+
smallint: () => SmallintValidatorType
5863
}
5964

6065
export type ValidationType = {

src/types/smallint.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { SmallintValidator } from '../validators/smallint'
2+
import type { LengthValidator, Validator } from './base'
3+
4+
export interface SmallintValidatorType extends Validator<number>, LengthValidator<SmallintValidator> {
5+
positive: () => SmallintValidator
6+
negative: () => SmallintValidator
7+
divisibleBy: (divisor: number) => SmallintValidator
8+
custom: (fn: (value: number) => boolean, message: string) => SmallintValidator
9+
}

src/validation.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { float } from './validators/float'
1111
import { number } from './validators/numbers'
1212
import { object } from './validators/objects'
1313
import { password } from './validators/password'
14+
import { smallint } from './validators/smallint'
1415
import { string } from './validators/strings'
1516
import { text } from './validators/text'
1617
import { time } from './validators/time'
@@ -37,4 +38,5 @@ export const v: ValidationInstance = {
3738
float,
3839
decimal,
3940
time,
41+
smallint,
4042
}

src/validators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export * from './float'
99
export * from './numbers'
1010
export * from './objects'
1111
export * from './password'
12+
export * from './smallint'
1213
export * from './strings'
1314
export * from './time'
1415
export * from './timestamps'

src/validators/smallint.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import type { SmallintValidatorType, ValidationNames } from '../types'
2+
import isDivisibleBy from '../lib/isDivisibleBy'
3+
import isInt from '../lib/isInt'
4+
import { BaseValidator } from './base'
5+
6+
export class SmallintValidator extends BaseValidator<number> implements SmallintValidatorType {
7+
public name: ValidationNames = 'smallint'
8+
9+
constructor() {
10+
super()
11+
this.addRule({
12+
name: 'smallint',
13+
test: (value: unknown): value is number => {
14+
if (typeof value !== 'number' || Number.isNaN(value)) {
15+
return false
16+
}
17+
// Check if it's an integer
18+
if (!isInt(String(value), {})) {
19+
return false
20+
}
21+
// Check if it's within smallint range (-32,768 to 32,767)
22+
return value >= -32768 && value <= 32767
23+
},
24+
message: 'Must be a valid smallint (-32,768 to 32,767)',
25+
})
26+
}
27+
28+
min(min: number): this {
29+
return this.addRule({
30+
name: 'min',
31+
test: (value: number) => value >= min,
32+
message: 'Must be at least {min}',
33+
params: { min },
34+
})
35+
}
36+
37+
max(max: number): this {
38+
return this.addRule({
39+
name: 'max',
40+
test: (value: number) => value <= max,
41+
message: 'Must be at most {max}',
42+
params: { max },
43+
})
44+
}
45+
46+
length(length: number): this {
47+
return this.addRule({
48+
name: 'length',
49+
test: (value: number) => value.toString().length === length,
50+
message: 'Must be exactly {length} digits',
51+
params: { length },
52+
})
53+
}
54+
55+
positive(): this {
56+
return this.addRule({
57+
name: 'positive',
58+
test: (value: number) => value > 0,
59+
message: 'Must be a positive number',
60+
})
61+
}
62+
63+
negative(): this {
64+
return this.addRule({
65+
name: 'negative',
66+
test: (value: number) => value < 0,
67+
message: 'Must be a negative number',
68+
})
69+
}
70+
71+
divisibleBy(divisor: number): this {
72+
return this.addRule({
73+
name: 'divisibleBy',
74+
test: (value: number) => isDivisibleBy(String(value), divisor),
75+
message: 'Must be divisible by {divisor}',
76+
params: { divisor },
77+
})
78+
}
79+
80+
custom(fn: (value: number) => boolean, message: string): this {
81+
return this.addRule({
82+
name: 'custom',
83+
test: fn,
84+
message,
85+
})
86+
}
87+
}
88+
89+
// Export a function to create smallint validators
90+
export function smallint(): SmallintValidator {
91+
return new SmallintValidator()
92+
}

0 commit comments

Comments
 (0)