Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 81aa868

Browse files
committed
feat: BigInt support
1 parent aaeb7ff commit 81aa868

7 files changed

Lines changed: 358 additions & 0 deletions

File tree

src/schema/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
StringType,
2121
ObjectType,
2222
NumberType,
23+
BigIntType,
2324
EnumSetType,
2425
BooleanType,
2526
TypedSchema,
@@ -284,6 +285,28 @@ oneOf.nullableAndOptional = function nullableAndOptionalEnum(enumOptions: any[],
284285
>
285286
}
286287

288+
/**
289+
* BigInt schema type
290+
*/
291+
function bigint(rules?: Rule[]) {
292+
return getLiteralType('bigint', false, false, undefined, rules || []) as ReturnType<BigIntType>
293+
}
294+
bigint.optional = function optionalBigInt(rules?: Rule[]) {
295+
return getLiteralType('bigint', true, false, undefined, rules || []) as ReturnType<
296+
BigIntType['optional']
297+
>
298+
}
299+
bigint.nullable = function nullableBigInt(rules?: Rule[]) {
300+
return getLiteralType('bigint', false, true, undefined, rules || []) as ReturnType<
301+
BigIntType['nullable']
302+
>
303+
}
304+
bigint.nullableAndOptional = function nullableAndOptionalBigInt(rules?: Rule[]) {
305+
return getLiteralType('bigint', true, true, undefined, rules || []) as ReturnType<
306+
BigIntType['nullableAndOptional']
307+
>
308+
}
309+
287310
/**
288311
* Enum set schema type
289312
*/
@@ -365,6 +388,7 @@ export const schema: Schema = {
365388
date,
366389
object,
367390
array,
391+
bigint,
368392
enum: oneOf as unknown as EnumType,
369393
enumSet: enumSet as unknown as EnumSetType,
370394
file,

src/types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,28 @@ export type EnumSetReturnValue<Options extends AllowedEnumOptions> =
523523
? Options[number][]
524524
: never
525525

526+
/**
527+
* BigInt schema types
528+
*/
529+
export interface BigIntType {
530+
(rules?: Rule[]): {
531+
t: bigint
532+
getTree(): SchemaLiteral
533+
}
534+
optional(rules?: Rule[]): {
535+
t?: bigint
536+
getTree(): SchemaLiteral
537+
}
538+
nullable(rules?: Rule[]): {
539+
t: bigint | null
540+
getTree(): SchemaLiteral
541+
}
542+
nullableAndOptional(rules?: Rule[]): {
543+
t?: bigint | null
544+
getTree(): SchemaLiteral
545+
}
546+
}
547+
526548
/**
527549
* Signature to define an enum type. We accept a static list of enum
528550
* values or a ref that is resolved lazily.
@@ -644,6 +666,7 @@ export interface Schema {
644666
boolean: BooleanType
645667
number: NumberType
646668
date: DateType
669+
bigint: BigIntType
647670
enum: EnumType
648671
enumSet: EnumSetType
649672
object: ObjectType

src/validations/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { file } from './primitives/file.js'
4343
import { number } from './primitives/number.js'
4444
import { object } from './primitives/object.js'
4545
import { string } from './primitives/string.js'
46+
import { bigint } from './primitives/bigint.js'
4647

4748
import { alpha } from './string/alpha.js'
4849
import { alphaNum } from './string/alpha_num.js'
@@ -70,6 +71,7 @@ const validations = {
7071
beforeOrEqual,
7172
beforeField,
7273
beforeOrEqualToField,
74+
bigint,
7375
confirmed,
7476
required,
7577
nullable,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* @adonisjs/validator
3+
*
4+
* (c) Harminder Virk <virk@adonisjs.com>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { SyncValidation } from '../../types.js'
11+
import { wrapCompile } from '../../validator/helpers.js'
12+
13+
const DEFAULT_MESSAGE = 'bigint validation failed'
14+
const RULE_NAME = 'bigint'
15+
16+
/**
17+
* Ensure the value is a valid bigint. Numeric string will be casted
18+
* to valid bigint
19+
*/
20+
export const bigint: SyncValidation = {
21+
compile: wrapCompile(RULE_NAME),
22+
validate(value, _, { mutate, errorReporter, pointer, arrayExpressionPointer }) {
23+
if (typeof value === 'bigint') {
24+
return
25+
}
26+
27+
/**
28+
* Report error when value is not a bigint and neither a string or a number
29+
*/
30+
if (typeof value !== 'string' && typeof value !== 'number') {
31+
errorReporter.report(pointer, RULE_NAME, DEFAULT_MESSAGE, arrayExpressionPointer)
32+
return
33+
}
34+
35+
/**
36+
* Attempt to cast string or number to a bigint. In case of
37+
* failure report the validation error
38+
*/
39+
try {
40+
const castedValue = BigInt(value)
41+
42+
/**
43+
* Mutate the value
44+
*/
45+
mutate(castedValue)
46+
} catch (e) {
47+
errorReporter.report(pointer, RULE_NAME, DEFAULT_MESSAGE, arrayExpressionPointer)
48+
}
49+
},
50+
}

src/validations/primitives/number.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ export const number: SyncValidation = {
4242
return
4343
}
4444

45+
if (castedValue === Number.POSITIVE_INFINITY || castedValue === Number.NEGATIVE_INFINITY) {
46+
errorReporter.report(pointer, RULE_NAME, DEFAULT_MESSAGE, arrayExpressionPointer)
47+
return
48+
}
49+
4550
/**
4651
* Mutate the value
4752
*/

tests/schema.spec.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,116 @@ test.group('Schema | Date', () => {
647647
})
648648
})
649649

650+
test.group('Schema | BigInt', () => {
651+
test('define schema with bigint rule', ({ assert }) => {
652+
assert.deepEqual(
653+
schema.create({
654+
username: schema.bigint(),
655+
}).tree,
656+
{
657+
username: {
658+
type: 'literal',
659+
subtype: 'bigint',
660+
optional: false,
661+
nullable: false,
662+
rules: [
663+
{
664+
name: 'required',
665+
allowUndefineds: true,
666+
async: false,
667+
compiledOptions: [],
668+
},
669+
{
670+
name: 'bigint',
671+
allowUndefineds: false,
672+
async: false,
673+
compiledOptions: [],
674+
},
675+
],
676+
},
677+
}
678+
)
679+
})
680+
681+
test('define schema with optional bigint rule', ({ assert }) => {
682+
assert.deepEqual(
683+
schema.create({
684+
username: schema.bigint.optional(),
685+
}).tree,
686+
{
687+
username: {
688+
type: 'literal',
689+
subtype: 'bigint',
690+
optional: true,
691+
nullable: false,
692+
rules: [
693+
{
694+
name: 'bigint',
695+
allowUndefineds: false,
696+
async: false,
697+
compiledOptions: [],
698+
},
699+
],
700+
},
701+
}
702+
)
703+
})
704+
705+
test('define schema with nullable bigint rule', ({ assert }) => {
706+
assert.deepEqual(
707+
schema.create({
708+
username: schema.bigint.nullable(),
709+
}).tree,
710+
{
711+
username: {
712+
type: 'literal',
713+
subtype: 'bigint',
714+
optional: false,
715+
nullable: true,
716+
rules: [
717+
{
718+
name: 'nullable',
719+
allowUndefineds: true,
720+
async: false,
721+
compiledOptions: [],
722+
},
723+
{
724+
name: 'bigint',
725+
allowUndefineds: false,
726+
async: false,
727+
compiledOptions: [],
728+
},
729+
],
730+
},
731+
}
732+
)
733+
})
734+
735+
test('define schema with both optional and nullable bigint rule', ({ assert }) => {
736+
assert.deepEqual(
737+
schema.create({
738+
username: schema.bigint.nullableAndOptional(),
739+
}).tree,
740+
{
741+
username: {
742+
type: 'literal',
743+
subtype: 'bigint',
744+
optional: true,
745+
nullable: true,
746+
rules: [
747+
{
748+
name: 'bigint',
749+
allowUndefineds: false,
750+
async: false,
751+
compiledOptions: [],
752+
},
753+
],
754+
},
755+
}
756+
)
757+
})
758+
})
759+
650760
test.group('Schema | Enum', () => {
651761
test('define schema with enum rule', ({ assert }) => {
652762
assert.deepEqual(

0 commit comments

Comments
 (0)