fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #2344 from Daschi1/issue-2194

authored by

Lubos and committed by
GitHub
d780a69a 08f219ec

+2928 -74
+5
.changeset/stale-starfishes-sell.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + fix(valibot): expand support for `format: int64`
+9
packages/openapi-ts-tests/main/test/3.1.x.test.ts
··· 798 798 }), 799 799 description: "validator schemas with merged unions (can't use .merge())", 800 800 }, 801 + { 802 + config: createConfig({ 803 + input: 'integer-formats.yaml', 804 + output: 'integer-formats', 805 + plugins: ['valibot'], 806 + }), 807 + description: 808 + 'generates validator schemas for all integer format combinations (number/integer/string types with int8, int16, int32, int64, uint8, uint16, uint32, uint64 formats)', 809 + }, 801 810 ]; 802 811 803 812 it.each(scenarios)('$description', async ({ config }) => {
+5 -1
packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts
··· 4 4 5 5 export const vFoo = v.object({ 6 6 bar: v.optional(v.pipe(v.number(), v.integer())), 7 - foo: v.optional(v.bigint(), BigInt(0)), 7 + foo: v.optional(v.pipe(v.union([ 8 + v.number(), 9 + v.string(), 10 + v.bigint() 11 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1')), BigInt(0)), 8 12 id: v.string() 9 13 }); 10 14
+1 -1
packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/valibot/default/valibot.gen.ts
··· 664 664 export const vTypesData = v.object({ 665 665 body: v.optional(v.never()), 666 666 path: v.optional(v.object({ 667 - id: v.optional(v.pipe(v.number(), v.integer())) 667 + id: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'))) 668 668 })), 669 669 query: v.object({ 670 670 parameterNumber: v.optional(v.number(), 123),
+5 -1
packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts
··· 4 4 5 5 export const vFoo = v.object({ 6 6 bar: v.optional(v.pipe(v.number(), v.integer())), 7 - foo: v.optional(v.bigint(), BigInt(0)), 7 + foo: v.optional(v.pipe(v.union([ 8 + v.number(), 9 + v.string(), 10 + v.bigint() 11 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1')), BigInt(0)), 8 12 id: v.string() 9 13 }); 10 14
+9 -9
packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/valibot/default/valibot.gen.ts
··· 714 714 }); 715 715 716 716 export const vPageable = v.object({ 717 - page: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0)), 0), 718 - size: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))), 717 + page: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'), v.minValue(0)), 0), 718 + size: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'), v.minValue(1))), 719 719 sort: v.optional(v.array(v.string())) 720 720 }); 721 721 ··· 775 775 ]), 776 776 v.object({ 777 777 baz: v.union([ 778 - v.pipe(v.number(), v.integer(), v.minValue(0)), 778 + v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint16 to be >= 0'), v.maxValue(65535, 'Invalid value: Expected uint16 to be <= 2^16-1'), v.minValue(0)), 779 779 v.null() 780 780 ]), 781 - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) 781 + qux: v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint8 to be >= 0'), v.maxValue(255, 'Invalid value: Expected uint8 to be <= 2^8-1'), v.minValue(0)) 782 782 }) 783 783 ]); 784 784 ··· 943 943 ]), 944 944 v.object({ 945 945 baz: v.union([ 946 - v.pipe(v.number(), v.integer(), v.minValue(0)), 946 + v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint16 to be >= 0'), v.maxValue(65535, 'Invalid value: Expected uint16 to be <= 2^16-1'), v.minValue(0)), 947 947 v.null() 948 948 ]), 949 - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) 949 + qux: v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint8 to be >= 0'), v.maxValue(255, 'Invalid value: Expected uint8 to be <= 2^8-1'), v.minValue(0)) 950 950 }) 951 951 ]); 952 952 ··· 1812 1812 export const vTypesData = v.object({ 1813 1813 body: v.optional(v.never()), 1814 1814 path: v.optional(v.object({ 1815 - id: v.optional(v.pipe(v.number(), v.integer())) 1815 + id: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'))) 1816 1816 })), 1817 1817 query: v.object({ 1818 1818 parameterNumber: v.optional(v.number(), 123), ··· 1958 1958 vModelWithDictionary 1959 1959 ]), 1960 1960 user: v.optional(v.pipe(v.object({ 1961 - id: v.optional(v.pipe(v.pipe(v.number(), v.integer()), v.readonly())), 1961 + id: v.optional(v.pipe(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1')), v.readonly())), 1962 1962 name: v.optional(v.pipe(v.union([ 1963 1963 v.pipe(v.string(), v.readonly()), 1964 1964 v.null() ··· 1966 1966 }), v.readonly())) 1967 1967 })), 1968 1968 path: v.object({ 1969 - id: v.pipe(v.number(), v.integer()), 1969 + id: v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1')), 1970 1970 'api-version': v.string() 1971 1971 }), 1972 1972 query: v.optional(v.never())
+50
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/integer-formats/valibot.gen.ts
··· 1 + // This file is auto-generated by @hey-api/openapi-ts 2 + 3 + import * as v from 'valibot'; 4 + 5 + export const vIntegerFormats = v.object({ 6 + numberNoFormat: v.optional(v.number()), 7 + numberInt8: v.optional(v.pipe(v.number(), v.minValue(-128, 'Invalid value: Expected int8 to be >= -2^7'), v.maxValue(127, 'Invalid value: Expected int8 to be <= 2^7-1'))), 8 + numberInt16: v.optional(v.pipe(v.number(), v.minValue(-32768, 'Invalid value: Expected int16 to be >= -2^15'), v.maxValue(32767, 'Invalid value: Expected int16 to be <= 2^15-1'))), 9 + numberInt32: v.optional(v.pipe(v.number(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'))), 10 + numberInt64: v.optional(v.pipe(v.union([ 11 + v.number(), 12 + v.string(), 13 + v.bigint() 14 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1'))), 15 + numberUint8: v.optional(v.pipe(v.number(), v.minValue(0, 'Invalid value: Expected uint8 to be >= 0'), v.maxValue(255, 'Invalid value: Expected uint8 to be <= 2^8-1'))), 16 + numberUint16: v.optional(v.pipe(v.number(), v.minValue(0, 'Invalid value: Expected uint16 to be >= 0'), v.maxValue(65535, 'Invalid value: Expected uint16 to be <= 2^16-1'))), 17 + numberUint32: v.optional(v.pipe(v.number(), v.minValue(0, 'Invalid value: Expected uint32 to be >= 0'), v.maxValue(4294967295, 'Invalid value: Expected uint32 to be <= 2^32-1'))), 18 + numberUint64: v.optional(v.pipe(v.union([ 19 + v.number(), 20 + v.string(), 21 + v.bigint() 22 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('0'), 'Invalid value: Expected uint64 to be >= 0'), v.maxValue(BigInt('18446744073709551615'), 'Invalid value: Expected uint64 to be <= 2^64-1'))), 23 + integerNoFormat: v.optional(v.pipe(v.number(), v.integer())), 24 + integerInt8: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-128, 'Invalid value: Expected int8 to be >= -2^7'), v.maxValue(127, 'Invalid value: Expected int8 to be <= 2^7-1'))), 25 + integerInt16: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-32768, 'Invalid value: Expected int16 to be >= -2^15'), v.maxValue(32767, 'Invalid value: Expected int16 to be <= 2^15-1'))), 26 + integerInt32: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'))), 27 + integerInt64: v.optional(v.pipe(v.union([ 28 + v.number(), 29 + v.string(), 30 + v.bigint() 31 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1'))), 32 + integerUint8: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint8 to be >= 0'), v.maxValue(255, 'Invalid value: Expected uint8 to be <= 2^8-1'))), 33 + integerUint16: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint16 to be >= 0'), v.maxValue(65535, 'Invalid value: Expected uint16 to be <= 2^16-1'))), 34 + integerUint32: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint32 to be >= 0'), v.maxValue(4294967295, 'Invalid value: Expected uint32 to be <= 2^32-1'))), 35 + integerUint64: v.optional(v.pipe(v.union([ 36 + v.number(), 37 + v.string(), 38 + v.bigint() 39 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('0'), 'Invalid value: Expected uint64 to be >= 0'), v.maxValue(BigInt('18446744073709551615'), 'Invalid value: Expected uint64 to be <= 2^64-1'))), 40 + stringInt64: v.optional(v.pipe(v.union([ 41 + v.number(), 42 + v.string(), 43 + v.bigint() 44 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1'))), 45 + stringUint64: v.optional(v.pipe(v.union([ 46 + v.number(), 47 + v.string(), 48 + v.bigint() 49 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('0'), 'Invalid value: Expected uint64 to be >= 0'), v.maxValue(BigInt('18446744073709551615'), 'Invalid value: Expected uint64 to be <= 2^64-1'))) 50 + });
+5 -1
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts
··· 4 4 5 5 export const vFoo = v.object({ 6 6 bar: v.optional(v.pipe(v.number(), v.integer())), 7 - foo: v.optional(v.bigint(), BigInt(0)), 7 + foo: v.optional(v.pipe(v.union([ 8 + v.number(), 9 + v.string(), 10 + v.bigint() 11 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1')), BigInt(0)), 8 12 id: v.string() 9 13 }); 10 14
+9 -9
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/valibot/default/valibot.gen.ts
··· 709 709 }); 710 710 711 711 export const vPageable = v.object({ 712 - page: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0)), 0), 713 - size: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))), 712 + page: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'), v.minValue(0)), 0), 713 + size: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'), v.minValue(1))), 714 714 sort: v.optional(v.array(v.string())) 715 715 }); 716 716 ··· 766 766 ]), 767 767 v.object({ 768 768 baz: v.union([ 769 - v.pipe(v.number(), v.integer(), v.minValue(0)), 769 + v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint16 to be >= 0'), v.maxValue(65535, 'Invalid value: Expected uint16 to be <= 2^16-1'), v.minValue(0)), 770 770 v.null() 771 771 ]), 772 - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) 772 + qux: v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint8 to be >= 0'), v.maxValue(255, 'Invalid value: Expected uint8 to be <= 2^8-1'), v.minValue(0)) 773 773 }) 774 774 ]); 775 775 ··· 941 941 ]), 942 942 v.object({ 943 943 baz: v.union([ 944 - v.pipe(v.number(), v.integer(), v.minValue(0)), 944 + v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint16 to be >= 0'), v.maxValue(65535, 'Invalid value: Expected uint16 to be <= 2^16-1'), v.minValue(0)), 945 945 v.null() 946 946 ]), 947 - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) 947 + qux: v.pipe(v.number(), v.integer(), v.minValue(0, 'Invalid value: Expected uint8 to be >= 0'), v.maxValue(255, 'Invalid value: Expected uint8 to be <= 2^8-1'), v.minValue(0)) 948 948 }) 949 949 ]); 950 950 ··· 1817 1817 export const vTypesData = v.object({ 1818 1818 body: v.optional(v.never()), 1819 1819 path: v.optional(v.object({ 1820 - id: v.optional(v.pipe(v.number(), v.integer())) 1820 + id: v.optional(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1'))) 1821 1821 })), 1822 1822 query: v.object({ 1823 1823 parameterNumber: v.optional(v.number(), 123), ··· 1964 1964 vModelWithDictionary 1965 1965 ]), 1966 1966 user: v.optional(v.pipe(v.object({ 1967 - id: v.optional(v.pipe(v.pipe(v.number(), v.integer()), v.readonly())), 1967 + id: v.optional(v.pipe(v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1')), v.readonly())), 1968 1968 name: v.optional(v.pipe(v.union([ 1969 1969 v.pipe(v.string(), v.readonly()), 1970 1970 v.null() ··· 1972 1972 }), v.readonly())) 1973 1973 })), 1974 1974 path: v.object({ 1975 - id: v.pipe(v.number(), v.integer()), 1975 + id: v.pipe(v.number(), v.integer(), v.minValue(-2147483648, 'Invalid value: Expected int32 to be >= -2^31'), v.maxValue(2147483647, 'Invalid value: Expected int32 to be <= 2^31-1')), 1976 1976 'api-version': v.string() 1977 1977 }), 1978 1978 query: v.optional(v.never())
+18
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/types.gen.ts
··· 16 16 [key: string]: unknown; 17 17 }; 18 18 garply?: 10n; 19 + numberInt8?: 100; 20 + numberInt16?: 1000; 21 + numberInt32?: 100000; 22 + numberInt64?: 1000000000000; 23 + numberUint8?: 200; 24 + numberUint16?: 50000; 25 + numberUint32?: 3000000000; 26 + numberUint64?: 18000000000000000000; 27 + integerInt8?: -100; 28 + integerInt16?: -1000; 29 + integerInt32?: -100000; 30 + integerInt64?: -1000000000000; 31 + integerUint8?: 255; 32 + integerUint16?: 65535; 33 + integerUint32?: 4294967295; 34 + integerUint64?: 18446744073709551615n; 35 + stringInt64?: '-9223372036854775808'; 36 + stringUint64?: '18446744073709551615'; 19 37 }; 20 38 21 39 export type ClientOptions = {
+19 -1
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/valibot.gen.ts
··· 15 15 v.literal(true) 16 16 ])), 17 17 corge: v.optional(v.object({})), 18 - garply: v.optional(v.bigint()) 18 + garply: v.optional(v.literal(BigInt('10'))), 19 + numberInt8: v.optional(v.literal(100)), 20 + numberInt16: v.optional(v.literal(1000)), 21 + numberInt32: v.optional(v.literal(100000)), 22 + numberInt64: v.optional(v.literal(BigInt('1000000000000'))), 23 + numberUint8: v.optional(v.literal(200)), 24 + numberUint16: v.optional(v.literal(50000)), 25 + numberUint32: v.optional(v.literal(3000000000)), 26 + numberUint64: v.optional(v.literal(BigInt('18000000000000000000'))), 27 + integerInt8: v.optional(v.literal(-100)), 28 + integerInt16: v.optional(v.literal(-1000)), 29 + integerInt32: v.optional(v.literal(-100000)), 30 + integerInt64: v.optional(v.literal(BigInt('-1000000000000'))), 31 + integerUint8: v.optional(v.literal(255)), 32 + integerUint16: v.optional(v.literal(65535)), 33 + integerUint32: v.optional(v.literal(4294967295)), 34 + integerUint64: v.optional(v.literal(BigInt('18446744073709551615'))), 35 + stringInt64: v.optional(v.literal(BigInt('-9223372036854775808'))), 36 + stringUint64: v.optional(v.literal(BigInt('18446744073709551615'))) 19 37 });
+5 -1
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/validators-bigint-min-max/valibot.gen.ts
··· 3 3 import * as v from 'valibot'; 4 4 5 5 export const vFoo = v.object({ 6 - foo: v.optional(v.pipe(v.bigint(), v.minValue(BigInt(0)), v.maxValue(BigInt(100)))) 6 + foo: v.optional(v.pipe(v.union([ 7 + v.number(), 8 + v.string(), 9 + v.bigint() 10 + ]), v.transform(x => BigInt(x)), v.minValue(BigInt('-9223372036854775808'), 'Invalid value: Expected int64 to be >= -2^63'), v.maxValue(BigInt('9223372036854775807'), 'Invalid value: Expected int64 to be <= 2^63-1'), v.minValue(BigInt(0)), v.maxValue(BigInt(100)))) 7 11 });
+93
packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.yaml
··· 1 + openapi: '3.1.0' 2 + info: 3 + title: Number Type Const Values Test API 4 + version: '1.0.0' 5 + paths: {} 6 + components: 7 + schemas: 8 + NumberNoFormat: 9 + type: number 10 + const: 42.5 11 + IntegerNoFormat: 12 + type: integer 13 + const: -1 14 + NumberInt8: 15 + type: number 16 + format: int8 17 + const: 100 18 + NumberInt16: 19 + type: number 20 + format: int16 21 + const: 1000 22 + NumberInt32: 23 + type: number 24 + format: int32 25 + const: 100000 26 + NumberInt64: 27 + type: number 28 + format: int64 29 + const: 1000000000000 30 + NumberUint8: 31 + type: number 32 + format: uint8 33 + const: 200 34 + NumberUint16: 35 + type: number 36 + format: uint16 37 + const: 50000 38 + NumberUint32: 39 + type: number 40 + format: uint32 41 + const: 3000000000 42 + NumberUint64: 43 + type: number 44 + format: uint64 45 + const: 18000000000000000000 46 + IntegerInt8: 47 + type: integer 48 + format: int8 49 + const: -100 50 + IntegerInt16: 51 + type: integer 52 + format: int16 53 + const: -1000 54 + IntegerInt32: 55 + type: integer 56 + format: int32 57 + const: -100000 58 + IntegerInt64: 59 + type: integer 60 + format: int64 61 + const: -1000000000000 62 + IntegerUint8: 63 + type: integer 64 + format: uint8 65 + const: 255 66 + IntegerUint16: 67 + type: integer 68 + format: uint16 69 + const: 65535 70 + IntegerUint32: 71 + type: integer 72 + format: uint32 73 + const: 4294967295 74 + IntegerUint64: 75 + type: integer 76 + format: uint64 77 + const: 1000000000000 78 + StringInt64: 79 + type: string 80 + format: int64 81 + const: '-9223372036854775808' 82 + StringUint64: 83 + type: string 84 + format: uint64 85 + const: '18446744073709551615' 86 + StringInt64n: 87 + type: string 88 + format: int64 89 + const: '-9223372036854775808n' 90 + StringUint64n: 91 + type: string 92 + format: uint64 93 + const: '18446744073709551615n'
+64
packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.yaml
··· 1 + openapi: '3.1.0' 2 + info: 3 + title: Integer Formats Test 4 + version: '1.0.0' 5 + components: 6 + schemas: 7 + NumberNoFormat: 8 + type: number 9 + NumberInt8: 10 + type: number 11 + format: int8 12 + NumberInt16: 13 + type: number 14 + format: int16 15 + NumberInt32: 16 + type: number 17 + format: int32 18 + NumberInt64: 19 + type: number 20 + format: int64 21 + NumberUint8: 22 + type: number 23 + format: uint8 24 + NumberUint16: 25 + type: number 26 + format: uint16 27 + NumberUint32: 28 + type: number 29 + format: uint32 30 + NumberUint64: 31 + type: number 32 + format: uint64 33 + IntegerNoFormat: 34 + type: integer 35 + IntegerInt8: 36 + type: integer 37 + format: int8 38 + IntegerInt16: 39 + type: integer 40 + format: int16 41 + IntegerInt32: 42 + type: integer 43 + format: int32 44 + IntegerInt64: 45 + type: integer 46 + format: int64 47 + IntegerUint8: 48 + type: integer 49 + format: uint8 50 + IntegerUint16: 51 + type: integer 52 + format: uint16 53 + IntegerUint32: 54 + type: integer 55 + format: uint32 56 + IntegerUint64: 57 + type: integer 58 + format: uint64 59 + StringInt64: 60 + type: string 61 + format: int64 62 + StringUint64: 63 + type: string 64 + format: uint64
+141
packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.yaml
··· 1 + openapi: '3.1.0' 2 + info: 3 + title: Number Type Min/Max Constraints Test API 4 + version: '1.0.0' 5 + paths: {} 6 + components: 7 + schemas: 8 + NumberWithMinimum: 9 + type: number 10 + minimum: 10 11 + NumberWithMaximum: 12 + type: number 13 + maximum: 100 14 + NumberWithMinMax: 15 + type: number 16 + minimum: 0 17 + maximum: 100 18 + IntegerWithMinimum: 19 + type: integer 20 + minimum: 5 21 + IntegerWithMaximum: 22 + type: integer 23 + maximum: 999 24 + IntegerWithMinMax: 25 + type: integer 26 + minimum: 1 27 + maximum: 999 28 + NumberWithExclusiveMin: 29 + type: number 30 + exclusiveMinimum: 0 31 + NumberWithExclusiveMax: 32 + type: number 33 + exclusiveMaximum: 100 34 + NumberWithExclusiveMinMax: 35 + type: number 36 + exclusiveMinimum: 0 37 + exclusiveMaximum: 1 38 + IntegerWithExclusiveMin: 39 + type: integer 40 + exclusiveMinimum: 10 41 + IntegerWithExclusiveMax: 42 + type: integer 43 + exclusiveMaximum: 50 44 + IntegerWithExclusiveMinMax: 45 + type: integer 46 + exclusiveMinimum: 5 47 + exclusiveMaximum: 15 48 + NumberWithExclusiveMinInclusiveMax: 49 + type: number 50 + exclusiveMinimum: 10 51 + maximum: 90 52 + NumberWithInclusiveMinExclusiveMax: 53 + type: number 54 + minimum: 20 55 + exclusiveMaximum: 80 56 + IntegerWithExclusiveMinInclusiveMax: 57 + type: integer 58 + exclusiveMinimum: 5 59 + maximum: 50 60 + IntegerWithInclusiveMinExclusiveMax: 61 + type: integer 62 + minimum: 10 63 + exclusiveMaximum: 100 64 + Int64WithMinimum: 65 + type: integer 66 + format: int64 67 + minimum: -5000000000000 68 + Int64WithMaximum: 69 + type: integer 70 + format: int64 71 + maximum: 5000000000000 72 + Int64WithMinMax: 73 + type: integer 74 + format: int64 75 + minimum: -4000000000000 76 + maximum: 4000000000000 77 + Int64WithExclusiveMin: 78 + type: integer 79 + format: int64 80 + exclusiveMinimum: -3000000000000 81 + Int64WithExclusiveMax: 82 + type: integer 83 + format: int64 84 + exclusiveMaximum: 3000000000000 85 + Int64WithExclusiveMinMax: 86 + type: integer 87 + format: int64 88 + exclusiveMinimum: -2000000000000 89 + exclusiveMaximum: 2000000000000 90 + Int64WithExclusiveMinInclusiveMax: 91 + type: integer 92 + format: int64 93 + exclusiveMinimum: -6000000000000 94 + maximum: 6000000000000 95 + Int64WithInclusiveMinExclusiveMax: 96 + type: integer 97 + format: int64 98 + minimum: -7000000000000 99 + exclusiveMaximum: 7000000000000 100 + UInt64WithMinimum: 101 + type: integer 102 + format: uint64 103 + minimum: 5000000000000 104 + UInt64WithMaximum: 105 + type: integer 106 + format: uint64 107 + maximum: 15000000000000 108 + UInt64WithMinMax: 109 + type: integer 110 + format: uint64 111 + minimum: 1000000000000 112 + maximum: 10000000000000 113 + UInt64WithExclusiveMin: 114 + type: integer 115 + format: uint64 116 + exclusiveMinimum: 8000000000000 117 + UInt64WithExclusiveMax: 118 + type: integer 119 + format: uint64 120 + exclusiveMaximum: 12000000000000 121 + UInt64WithExclusiveMinMax: 122 + type: integer 123 + format: uint64 124 + exclusiveMinimum: 2000000000000 125 + exclusiveMaximum: 8000000000000 126 + UInt64WithExclusiveMinInclusiveMax: 127 + type: integer 128 + format: uint64 129 + exclusiveMinimum: 3000000000000 130 + maximum: 13000000000000 131 + UInt64WithInclusiveMinExclusiveMax: 132 + type: integer 133 + format: uint64 134 + minimum: 4000000000000 135 + exclusiveMaximum: 14000000000000 136 + PrecedenceTest: 137 + type: number 138 + minimum: 10 139 + maximum: 90 140 + exclusiveMinimum: 5 141 + exclusiveMaximum: 95
+211
packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts
··· 1 + /** 2 + * Test helper for Valibot plugin tests 3 + * Provides common functionality for schema generation and loading 4 + */ 5 + 6 + import fs from 'node:fs'; 7 + import path from 'node:path'; 8 + 9 + import { createClient } from '@hey-api/openapi-ts'; 10 + import * as v from 'valibot'; 11 + 12 + /** 13 + * Detect test name from the calling file 14 + */ 15 + function detectTestName(): string { 16 + const stack = new Error().stack; 17 + if (!stack) { 18 + throw new Error('Unable to detect test name: no stack trace available'); 19 + } 20 + 21 + // Find the first stack frame that contains a .test.ts file 22 + const testFileMatch = stack.match(/([^\\/]+)\.test\.ts/); 23 + if (!testFileMatch || !testFileMatch[1]) { 24 + throw new Error( 25 + 'Unable to detect test name: no .test.ts file found in stack trace', 26 + ); 27 + } 28 + 29 + return testFileMatch[1]; 30 + } 31 + 32 + /** 33 + * Detect base directory from the calling file 34 + */ 35 + function detectBaseDir(): string { 36 + const stack = new Error().stack; 37 + if (!stack) { 38 + throw new Error( 39 + 'Unable to detect base directory: no stack trace available', 40 + ); 41 + } 42 + 43 + // Try multiple regex patterns to match different stack trace formats 44 + const patterns = [ 45 + /at .* \(([^)]+\.test\.ts):\d+:\d+\)/, // Original pattern 46 + /at ([^:]+\.test\.ts):\d+:\d+/, // Alternative pattern without parentheses 47 + /([^:\s]+\.test\.ts):\d+:\d+/, // Simple pattern 48 + ]; 49 + 50 + for (const pattern of patterns) { 51 + const testFileMatch = stack.match(pattern); 52 + if (testFileMatch && testFileMatch[1]) { 53 + return path.dirname(testFileMatch[1]); 54 + } 55 + } 56 + 57 + throw new Error( 58 + 'Unable to detect base directory: no .test.ts file found in stack trace', 59 + ); 60 + } 61 + 62 + /** 63 + * Detect function name from the test file path 64 + * Extracts the directory name between 'test/' and the test file 65 + * e.g., from 'test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts' 66 + * extracts 'numberTypeToValibotSchema' 67 + */ 68 + function detectFunctionName(): string { 69 + const stack = new Error().stack; 70 + if (!stack) { 71 + throw new Error('Unable to detect function name: no stack trace available'); 72 + } 73 + 74 + // Try multiple regex patterns to match different stack trace formats 75 + const patterns = [ 76 + /at .* \(([^)]+\.test\.ts):\d+:\d+\)/, // Original pattern 77 + /at ([^:]+\.test\.ts):\d+:\d+/, // Alternative pattern without parentheses 78 + /([^:\s]+\.test\.ts):\d+:\d+/, // Simple pattern 79 + ]; 80 + 81 + for (const pattern of patterns) { 82 + const testFileMatch = stack.match(pattern); 83 + if (testFileMatch && testFileMatch[1]) { 84 + const testFilePath = testFileMatch[1]; 85 + 86 + // Extract function name from path pattern: .../test/[FUNCTION_NAME]/[TEST_NAME].test.ts 87 + const pathParts = testFilePath.split(/[/\\]/); 88 + const testIndex = pathParts.lastIndexOf('test'); 89 + 90 + if (testIndex !== -1 && testIndex < pathParts.length - 2) { 91 + const functionName = pathParts[testIndex + 1]; 92 + if (functionName) { 93 + return functionName; 94 + } 95 + } 96 + 97 + throw new Error( 98 + `Unable to extract function name from test path: ${testFilePath}\n` + 99 + `Expected path pattern: .../test/[FUNCTION_NAME]/[TEST_NAME].test.ts`, 100 + ); 101 + } 102 + } 103 + 104 + throw new Error( 105 + 'Unable to detect function name: no .test.ts file found in stack trace', 106 + ); 107 + } 108 + 109 + /** 110 + * Load and evaluate the generated schemas 111 + */ 112 + function loadGeneratedSchemas(generatedPath: string): any { 113 + if (!fs.existsSync(generatedPath)) { 114 + throw new Error( 115 + `Generated schema file not found: ${generatedPath}\n` + 116 + `Schema generation may have failed. Check the input schema file for errors.`, 117 + ); 118 + } 119 + 120 + try { 121 + const generatedCode = fs.readFileSync(generatedPath, 'utf-8'); 122 + 123 + // Extract all export statements and create a proper return object 124 + const exportMatches = generatedCode.match(/export const (\w+)/g); 125 + if (!exportMatches) { 126 + // noinspection ExceptionCaughtLocallyJS 127 + throw new Error('No exported schemas found in generated code'); 128 + } 129 + 130 + // Create evaluation code that returns an object with all exports 131 + const schemaNames = exportMatches.map((match: string) => 132 + match.replace('export const ', ''), 133 + ); 134 + const evalCode = 135 + generatedCode 136 + .replace(/import \* as v from 'valibot';/, '') 137 + .replace(/export const/g, 'const') 138 + .replace(/v\./g, 'vModule.') + 139 + `\n\nreturn { ${schemaNames.join(', ')} };`; 140 + 141 + // Wrap in a function to capture the return value 142 + const schemaFunction = new Function('vModule', evalCode); 143 + return schemaFunction(v); 144 + } catch (error) { 145 + throw new Error( 146 + `Failed to load generated schemas from ${generatedPath}: ${error instanceof Error ? error.message : String(error)}\n` + 147 + `The generated file may contain syntax errors or be malformed.`, 148 + ); 149 + } 150 + } 151 + 152 + /** 153 + * Setup function for Valibot tests 154 + * Automatically detects test name and paths, generates schemas, and returns them 155 + */ 156 + export async function setupValibotTest(): Promise<any> { 157 + // Detect test name, function name, and base directory from calling file 158 + const testName = detectTestName(); 159 + const functionName = detectFunctionName(); 160 + const baseDir = detectBaseDir(); 161 + 162 + // Construct paths dynamically based on detected function name 163 + const schemaPath = path.join( 164 + baseDir, 165 + '..', 166 + '..', 167 + 'spec', 168 + functionName, 169 + `${testName}.yaml`, 170 + ); 171 + const outputPath = path.join( 172 + baseDir, 173 + '..', 174 + '..', 175 + 'generated', 176 + functionName, 177 + testName, 178 + ); 179 + 180 + // Check if spec file exists 181 + if (!fs.existsSync(schemaPath)) { 182 + throw new Error( 183 + `Schema file not found: ${schemaPath}\n` + 184 + `Expected schema file for test '${testName}' in function '${functionName}' at the above location.\n` + 185 + `Please ensure the spec file exists and matches the test name.`, 186 + ); 187 + } 188 + 189 + try { 190 + // Create output directory 191 + fs.mkdirSync(outputPath, { recursive: true }); 192 + 193 + // Generate Valibot schemas 194 + await createClient({ 195 + input: schemaPath, 196 + logs: { level: 'silent' }, 197 + output: outputPath, 198 + plugins: ['valibot'], 199 + }); 200 + 201 + // Load and return the generated schemas 202 + const generatedPath = path.join(outputPath, 'valibot.gen.ts'); 203 + return loadGeneratedSchemas(generatedPath); 204 + } catch (error) { 205 + throw new Error( 206 + `Failed to generate schemas for test '${testName}' in function '${functionName}': ${error instanceof Error ? error.message : String(error)}\n` + 207 + `Schema path: ${schemaPath}\n` + 208 + `Output path: ${outputPath}`, 209 + ); 210 + } 211 + }
+292
packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts
··· 1 + import * as v from 'valibot'; 2 + import { beforeAll, describe, expect, it } from 'vitest'; 3 + 4 + import { setupValibotTest } from '../../test-helper'; 5 + 6 + describe('Number Type Const Values Tests', () => { 7 + let generatedSchemas: any; 8 + 9 + beforeAll(async () => { 10 + generatedSchemas = await setupValibotTest(); 11 + }); 12 + 13 + describe('Number Type Const Validation', () => { 14 + it('should accept exact const value', () => { 15 + const result = v.safeParse(generatedSchemas.vNumberNoFormat, 42.5); 16 + expect(result.success).toBe(true); 17 + }); 18 + 19 + it('should reject non-matching values', () => { 20 + const result = v.safeParse(generatedSchemas.vNumberNoFormat, 42.6); 21 + expect(result.success).toBe(false); 22 + }); 23 + }); 24 + 25 + describe('Number Type Format Const Validation', () => { 26 + it('should accept NumberInt8 exact const value', () => { 27 + const result = v.safeParse(generatedSchemas.vNumberInt8, 100); 28 + expect(result.success).toBe(true); 29 + }); 30 + 31 + it('should reject NumberInt8 non-matching values', () => { 32 + const result = v.safeParse(generatedSchemas.vNumberInt8, 101); 33 + expect(result.success).toBe(false); 34 + }); 35 + 36 + it('should accept NumberInt16 exact const value', () => { 37 + const result = v.safeParse(generatedSchemas.vNumberInt16, 1000); 38 + expect(result.success).toBe(true); 39 + }); 40 + 41 + it('should reject NumberInt16 non-matching values', () => { 42 + const result = v.safeParse(generatedSchemas.vNumberInt16, 1001); 43 + expect(result.success).toBe(false); 44 + }); 45 + 46 + it('should accept NumberInt32 exact const value', () => { 47 + const result = v.safeParse(generatedSchemas.vNumberInt32, 100000); 48 + expect(result.success).toBe(true); 49 + }); 50 + 51 + it('should reject NumberInt32 non-matching values', () => { 52 + const result = v.safeParse(generatedSchemas.vNumberInt32, 100001); 53 + expect(result.success).toBe(false); 54 + }); 55 + 56 + it('should accept NumberInt64 exact const value', () => { 57 + const result = v.safeParse( 58 + generatedSchemas.vNumberInt64, 59 + BigInt('1000000000000'), 60 + ); 61 + expect(result.success).toBe(true); 62 + }); 63 + 64 + it('should reject NumberInt64 non-matching values', () => { 65 + const result = v.safeParse( 66 + generatedSchemas.vNumberInt64, 67 + BigInt('1000000000001'), 68 + ); 69 + expect(result.success).toBe(false); 70 + }); 71 + 72 + it('should accept NumberUint8 exact const value', () => { 73 + const result = v.safeParse(generatedSchemas.vNumberUint8, 200); 74 + expect(result.success).toBe(true); 75 + }); 76 + 77 + it('should reject NumberUint8 non-matching values', () => { 78 + const result = v.safeParse(generatedSchemas.vNumberUint8, 201); 79 + expect(result.success).toBe(false); 80 + }); 81 + 82 + it('should accept NumberUint16 exact const value', () => { 83 + const result = v.safeParse(generatedSchemas.vNumberUint16, 50000); 84 + expect(result.success).toBe(true); 85 + }); 86 + 87 + it('should reject NumberUint16 non-matching values', () => { 88 + const result = v.safeParse(generatedSchemas.vNumberUint16, 50001); 89 + expect(result.success).toBe(false); 90 + }); 91 + 92 + it('should accept NumberUint32 exact const value', () => { 93 + const result = v.safeParse(generatedSchemas.vNumberUint32, 3000000000); 94 + expect(result.success).toBe(true); 95 + }); 96 + 97 + it('should reject NumberUint32 non-matching values', () => { 98 + const result = v.safeParse(generatedSchemas.vNumberUint32, 3000000001); 99 + expect(result.success).toBe(false); 100 + }); 101 + 102 + it('should accept NumberUint64 exact const value', () => { 103 + const result = v.safeParse( 104 + generatedSchemas.vNumberUint64, 105 + BigInt('18000000000000000000'), 106 + ); 107 + expect(result.success).toBe(true); 108 + }); 109 + 110 + it('should reject NumberUint64 non-matching values', () => { 111 + const result = v.safeParse( 112 + generatedSchemas.vNumberUint64, 113 + BigInt('18000000000000000001'), 114 + ); 115 + expect(result.success).toBe(false); 116 + }); 117 + }); 118 + 119 + describe('Integer Type Const Validation', () => { 120 + it('should accept exact const value', () => { 121 + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, -1); 122 + expect(result.success).toBe(true); 123 + }); 124 + 125 + it('should reject non-matching values', () => { 126 + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, 0); 127 + expect(result.success).toBe(false); 128 + }); 129 + }); 130 + 131 + describe('Integer Type Format Const Validation', () => { 132 + it('should accept IntegerInt8 exact const value', () => { 133 + const result = v.safeParse(generatedSchemas.vIntegerInt8, -100); 134 + expect(result.success).toBe(true); 135 + }); 136 + 137 + it('should reject IntegerInt8 non-matching values', () => { 138 + const result = v.safeParse(generatedSchemas.vIntegerInt8, -99); 139 + expect(result.success).toBe(false); 140 + }); 141 + 142 + it('should accept IntegerInt16 exact const value', () => { 143 + const result = v.safeParse(generatedSchemas.vIntegerInt16, -1000); 144 + expect(result.success).toBe(true); 145 + }); 146 + 147 + it('should reject IntegerInt16 non-matching values', () => { 148 + const result = v.safeParse(generatedSchemas.vIntegerInt16, -999); 149 + expect(result.success).toBe(false); 150 + }); 151 + 152 + it('should accept IntegerInt32 exact const value', () => { 153 + const result = v.safeParse(generatedSchemas.vIntegerInt32, -100000); 154 + expect(result.success).toBe(true); 155 + }); 156 + 157 + it('should reject IntegerInt32 non-matching values', () => { 158 + const result = v.safeParse(generatedSchemas.vIntegerInt32, -99999); 159 + expect(result.success).toBe(false); 160 + }); 161 + 162 + it('should accept IntegerInt64 exact const value', () => { 163 + const result = v.safeParse( 164 + generatedSchemas.vIntegerInt64, 165 + BigInt('-1000000000000'), 166 + ); 167 + expect(result.success).toBe(true); 168 + }); 169 + 170 + it('should reject IntegerInt64 non-matching values', () => { 171 + const result = v.safeParse( 172 + generatedSchemas.vIntegerInt64, 173 + BigInt('-999999999999'), 174 + ); 175 + expect(result.success).toBe(false); 176 + }); 177 + 178 + it('should accept IntegerUint8 exact const value', () => { 179 + const result = v.safeParse(generatedSchemas.vIntegerUint8, 255); 180 + expect(result.success).toBe(true); 181 + }); 182 + 183 + it('should reject IntegerUint8 non-matching values', () => { 184 + const result = v.safeParse(generatedSchemas.vIntegerUint8, 254); 185 + expect(result.success).toBe(false); 186 + }); 187 + 188 + it('should accept IntegerUint16 exact const value', () => { 189 + const result = v.safeParse(generatedSchemas.vIntegerUint16, 65535); 190 + expect(result.success).toBe(true); 191 + }); 192 + 193 + it('should reject IntegerUint16 non-matching values', () => { 194 + const result = v.safeParse(generatedSchemas.vIntegerUint16, 65534); 195 + expect(result.success).toBe(false); 196 + }); 197 + 198 + it('should accept IntegerUint32 exact const value', () => { 199 + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967295); 200 + expect(result.success).toBe(true); 201 + }); 202 + 203 + it('should reject IntegerUint32 non-matching values', () => { 204 + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967294); 205 + expect(result.success).toBe(false); 206 + }); 207 + 208 + it('should accept IntegerUint64 exact const value', () => { 209 + const result = v.safeParse( 210 + generatedSchemas.vIntegerUint64, 211 + BigInt('1000000000000'), 212 + ); 213 + expect(result.success).toBe(true); 214 + }); 215 + 216 + it('should reject IntegerUint64 non-matching values', () => { 217 + const result = v.safeParse( 218 + generatedSchemas.vIntegerUint64, 219 + BigInt('1000000000001'), 220 + ); 221 + expect(result.success).toBe(false); 222 + }); 223 + }); 224 + 225 + describe('String Type Format Const Validation', () => { 226 + it('should accept StringInt64 exact const value', () => { 227 + const result = v.safeParse( 228 + generatedSchemas.vStringInt64, 229 + BigInt('-9223372036854775808'), 230 + ); 231 + expect(result.success).toBe(true); 232 + }); 233 + 234 + it('should reject StringInt64 non-matching values', () => { 235 + const result = v.safeParse( 236 + generatedSchemas.vStringInt64, 237 + BigInt('-9223372036854775807'), 238 + ); 239 + expect(result.success).toBe(false); 240 + }); 241 + 242 + it('should accept StringUint64 exact const value', () => { 243 + const result = v.safeParse( 244 + generatedSchemas.vStringUint64, 245 + BigInt('18446744073709551615'), 246 + ); 247 + expect(result.success).toBe(true); 248 + }); 249 + 250 + it('should reject StringUint64 non-matching values', () => { 251 + const result = v.safeParse( 252 + generatedSchemas.vStringUint64, 253 + BigInt('18446744073709551614'), 254 + ); 255 + expect(result.success).toBe(false); 256 + }); 257 + }); 258 + 259 + describe('String Type Format Const Validation (BigInt Literal)', () => { 260 + it('should accept StringInt64n exact const value', () => { 261 + const result = v.safeParse( 262 + generatedSchemas.vStringInt64n, 263 + BigInt('-9223372036854775808'), 264 + ); 265 + expect(result.success).toBe(true); 266 + }); 267 + 268 + it('should reject StringInt64n non-matching values', () => { 269 + const result = v.safeParse( 270 + generatedSchemas.vStringInt64n, 271 + BigInt('-9223372036854775807'), 272 + ); 273 + expect(result.success).toBe(false); 274 + }); 275 + 276 + it('should accept StringUint64n exact const value', () => { 277 + const result = v.safeParse( 278 + generatedSchemas.vStringUint64n, 279 + BigInt('18446744073709551615'), 280 + ); 281 + expect(result.success).toBe(true); 282 + }); 283 + 284 + it('should reject StringUint64n non-matching values', () => { 285 + const result = v.safeParse( 286 + generatedSchemas.vStringUint64n, 287 + BigInt('18446744073709551614'), 288 + ); 289 + expect(result.success).toBe(false); 290 + }); 291 + }); 292 + });
+550
packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts
··· 1 + import * as v from 'valibot'; 2 + import { beforeAll, describe, expect, it } from 'vitest'; 3 + 4 + import { setupValibotTest } from '../../test-helper'; 5 + 6 + describe('Number Type Formats Tests', () => { 7 + let generatedSchemas: any; 8 + 9 + beforeAll(async () => { 10 + generatedSchemas = await setupValibotTest(); 11 + }); 12 + 13 + // Format bounds and error messages from INTEGER_FORMATS 14 + const FORMAT_BOUNDS = { 15 + int16: { 16 + max: 32767, 17 + maxError: 'Expected int16 to be <= 2^15-1', 18 + min: -32768, 19 + minError: 'Expected int16 to be >= -2^15', 20 + }, 21 + int32: { 22 + max: 2147483647, 23 + maxError: 'Expected int32 to be <= 2^31-1', 24 + min: -2147483648, 25 + minError: 'Expected int32 to be >= -2^31', 26 + }, 27 + int64: { 28 + max: '9223372036854775807', 29 + maxError: 'Expected int64 to be <= 2^63-1', 30 + min: '-9223372036854775808', 31 + minError: 'Expected int64 to be >= -2^63', 32 + }, 33 + int8: { 34 + max: 127, 35 + maxError: 'Expected int8 to be <= 2^7-1', 36 + min: -128, 37 + minError: 'Expected int8 to be >= -2^7', 38 + }, 39 + uint16: { 40 + max: 65535, 41 + maxError: 'Expected uint16 to be <= 2^16-1', 42 + min: 0, 43 + minError: 'Expected uint16 to be >= 0', 44 + }, 45 + uint32: { 46 + max: 4294967295, 47 + maxError: 'Expected uint32 to be <= 2^32-1', 48 + min: 0, 49 + minError: 'Expected uint32 to be >= 0', 50 + }, 51 + uint64: { 52 + max: '18446744073709551615', 53 + maxError: 'Expected uint64 to be <= 2^64-1', 54 + min: '0', 55 + minError: 'Expected uint64 to be >= 0', 56 + }, 57 + uint8: { 58 + max: 255, 59 + maxError: 'Expected uint8 to be <= 2^8-1', 60 + min: 0, 61 + minError: 'Expected uint8 to be >= 0', 62 + }, 63 + }; 64 + 65 + describe('Number Type Format Validation', () => { 66 + describe('numberNoFormat', () => { 67 + it('should validate any number value', () => { 68 + const result = v.safeParse(generatedSchemas.vNumberNoFormat, 123.456); 69 + expect(result.success).toBe(true); 70 + }); 71 + }); 72 + 73 + describe('numberInt8', () => { 74 + it('should validate values within int8 range', () => { 75 + const result = v.safeParse(generatedSchemas.vNumberInt8, 100); 76 + expect(result.success).toBe(true); 77 + }); 78 + 79 + it('should reject values below int8 minimum', () => { 80 + const result = v.safeParse(generatedSchemas.vNumberInt8, -129); 81 + expect(result.success).toBe(false); 82 + expect(result.issues![0].message).toContain( 83 + FORMAT_BOUNDS.int8.minError, 84 + ); 85 + }); 86 + 87 + it('should reject values above int8 maximum', () => { 88 + const result = v.safeParse(generatedSchemas.vNumberInt8, 128); 89 + expect(result.success).toBe(false); 90 + expect(result.issues![0].message).toContain( 91 + FORMAT_BOUNDS.int8.maxError, 92 + ); 93 + }); 94 + }); 95 + 96 + describe('numberInt16', () => { 97 + it('should validate values within int16 range', () => { 98 + const result = v.safeParse(generatedSchemas.vNumberInt16, 30000); 99 + expect(result.success).toBe(true); 100 + }); 101 + 102 + it('should reject values below int16 minimum', () => { 103 + const result = v.safeParse(generatedSchemas.vNumberInt16, -32769); 104 + expect(result.success).toBe(false); 105 + expect(result.issues![0].message).toContain( 106 + FORMAT_BOUNDS.int16.minError, 107 + ); 108 + }); 109 + 110 + it('should reject values above int16 maximum', () => { 111 + const result = v.safeParse(generatedSchemas.vNumberInt16, 32768); 112 + expect(result.success).toBe(false); 113 + expect(result.issues![0].message).toContain( 114 + FORMAT_BOUNDS.int16.maxError, 115 + ); 116 + }); 117 + }); 118 + 119 + describe('numberInt32', () => { 120 + it('should validate values within int32 range', () => { 121 + const result = v.safeParse(generatedSchemas.vNumberInt32, 2000000000); 122 + expect(result.success).toBe(true); 123 + }); 124 + 125 + it('should reject values below int32 minimum', () => { 126 + const result = v.safeParse(generatedSchemas.vNumberInt32, -2147483649); 127 + expect(result.success).toBe(false); 128 + expect(result.issues![0].message).toContain( 129 + FORMAT_BOUNDS.int32.minError, 130 + ); 131 + }); 132 + 133 + it('should reject values above int32 maximum', () => { 134 + const result = v.safeParse(generatedSchemas.vNumberInt32, 2147483648); 135 + expect(result.success).toBe(false); 136 + expect(result.issues![0].message).toContain( 137 + FORMAT_BOUNDS.int32.maxError, 138 + ); 139 + }); 140 + }); 141 + 142 + describe('numberInt64', () => { 143 + it('should validate values within int64 range and convert to BigInt', () => { 144 + const result = v.safeParse( 145 + generatedSchemas.vNumberInt64, 146 + 1000000000000, 147 + ); 148 + expect(result.success).toBe(true); 149 + expect(typeof result.output).toBe('bigint'); 150 + }); 151 + 152 + it('should validate string values within int64 range', () => { 153 + const result = v.safeParse( 154 + generatedSchemas.vNumberInt64, 155 + '1000000000000', 156 + ); 157 + expect(result.success).toBe(true); 158 + expect(typeof result.output).toBe('bigint'); 159 + }); 160 + 161 + it('should reject values above int64 maximum', () => { 162 + const result = v.safeParse( 163 + generatedSchemas.vNumberInt64, 164 + '9223372036854775808', 165 + ); 166 + expect(result.success).toBe(false); 167 + expect(result.issues![0].message).toContain( 168 + FORMAT_BOUNDS.int64.maxError, 169 + ); 170 + }); 171 + }); 172 + 173 + describe('numberUint8', () => { 174 + it('should validate values within uint8 range', () => { 175 + const result = v.safeParse(generatedSchemas.vNumberUint8, 200); 176 + expect(result.success).toBe(true); 177 + }); 178 + 179 + it('should reject negative values', () => { 180 + const result = v.safeParse(generatedSchemas.vNumberUint8, -1); 181 + expect(result.success).toBe(false); 182 + expect(result.issues![0].message).toContain( 183 + FORMAT_BOUNDS.uint8.minError, 184 + ); 185 + }); 186 + 187 + it('should reject values above uint8 maximum', () => { 188 + const result = v.safeParse(generatedSchemas.vNumberUint8, 256); 189 + expect(result.success).toBe(false); 190 + expect(result.issues![0].message).toContain( 191 + FORMAT_BOUNDS.uint8.maxError, 192 + ); 193 + }); 194 + }); 195 + 196 + describe('numberUint16', () => { 197 + it('should validate values within uint16 range', () => { 198 + const result = v.safeParse(generatedSchemas.vNumberUint16, 60000); 199 + expect(result.success).toBe(true); 200 + }); 201 + 202 + it('should reject negative values', () => { 203 + const result = v.safeParse(generatedSchemas.vNumberUint16, -1); 204 + expect(result.success).toBe(false); 205 + expect(result.issues![0].message).toContain( 206 + FORMAT_BOUNDS.uint16.minError, 207 + ); 208 + }); 209 + 210 + it('should reject values above uint16 maximum', () => { 211 + const result = v.safeParse(generatedSchemas.vNumberUint16, 65536); 212 + expect(result.success).toBe(false); 213 + expect(result.issues![0].message).toContain( 214 + FORMAT_BOUNDS.uint16.maxError, 215 + ); 216 + }); 217 + }); 218 + 219 + describe('numberUint32', () => { 220 + it('should validate values within uint32 range', () => { 221 + const result = v.safeParse(generatedSchemas.vNumberUint32, 4000000000); 222 + expect(result.success).toBe(true); 223 + }); 224 + 225 + it('should reject negative values', () => { 226 + const result = v.safeParse(generatedSchemas.vNumberUint32, -1); 227 + expect(result.success).toBe(false); 228 + expect(result.issues![0].message).toContain( 229 + FORMAT_BOUNDS.uint32.minError, 230 + ); 231 + }); 232 + 233 + it('should reject values above uint32 maximum', () => { 234 + const result = v.safeParse(generatedSchemas.vNumberUint32, 4294967296); 235 + expect(result.success).toBe(false); 236 + expect(result.issues![0].message).toContain( 237 + FORMAT_BOUNDS.uint32.maxError, 238 + ); 239 + }); 240 + }); 241 + 242 + describe('numberUint64', () => { 243 + it('should validate values within uint64 range and convert to BigInt', () => { 244 + const result = v.safeParse( 245 + generatedSchemas.vNumberUint64, 246 + 1000000000000, 247 + ); 248 + expect(result.success).toBe(true); 249 + expect(typeof result.output).toBe('bigint'); 250 + }); 251 + 252 + it('should reject negative values', () => { 253 + const result = v.safeParse(generatedSchemas.vNumberUint64, -1); 254 + expect(result.success).toBe(false); 255 + expect(result.issues![0].message).toContain( 256 + FORMAT_BOUNDS.uint64.minError, 257 + ); 258 + }); 259 + 260 + it('should reject values above uint64 maximum', () => { 261 + const result = v.safeParse( 262 + generatedSchemas.vNumberUint64, 263 + '18446744073709551616', 264 + ); 265 + expect(result.success).toBe(false); 266 + expect(result.issues![0].message).toContain( 267 + FORMAT_BOUNDS.uint64.maxError, 268 + ); 269 + }); 270 + }); 271 + }); 272 + 273 + describe('Integer Type Format Validation', () => { 274 + describe('integerNoFormat', () => { 275 + it('should validate any integer value', () => { 276 + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, 123); 277 + expect(result.success).toBe(true); 278 + }); 279 + 280 + it('should reject non-integer values', () => { 281 + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, 123.456); 282 + expect(result.success).toBe(false); 283 + }); 284 + }); 285 + 286 + describe('integerInt8', () => { 287 + it('should validate values within int8 range', () => { 288 + const result = v.safeParse(generatedSchemas.vIntegerInt8, 100); 289 + expect(result.success).toBe(true); 290 + }); 291 + 292 + it('should reject values below int8 minimum', () => { 293 + const result = v.safeParse(generatedSchemas.vIntegerInt8, -129); 294 + expect(result.success).toBe(false); 295 + expect(result.issues![0].message).toContain( 296 + FORMAT_BOUNDS.int8.minError, 297 + ); 298 + }); 299 + 300 + it('should reject values above int8 maximum', () => { 301 + const result = v.safeParse(generatedSchemas.vIntegerInt8, 128); 302 + expect(result.success).toBe(false); 303 + expect(result.issues![0].message).toContain( 304 + FORMAT_BOUNDS.int8.maxError, 305 + ); 306 + }); 307 + }); 308 + 309 + describe('integerInt16', () => { 310 + it('should validate values within int16 range', () => { 311 + const result = v.safeParse(generatedSchemas.vIntegerInt16, 30000); 312 + expect(result.success).toBe(true); 313 + }); 314 + 315 + it('should reject values below int16 minimum', () => { 316 + const result = v.safeParse(generatedSchemas.vIntegerInt16, -32769); 317 + expect(result.success).toBe(false); 318 + expect(result.issues![0].message).toContain( 319 + FORMAT_BOUNDS.int16.minError, 320 + ); 321 + }); 322 + 323 + it('should reject values above int16 maximum', () => { 324 + const result = v.safeParse(generatedSchemas.vIntegerInt16, 32768); 325 + expect(result.success).toBe(false); 326 + expect(result.issues![0].message).toContain( 327 + FORMAT_BOUNDS.int16.maxError, 328 + ); 329 + }); 330 + }); 331 + 332 + describe('integerInt32', () => { 333 + it('should validate values within int32 range', () => { 334 + const result = v.safeParse(generatedSchemas.vIntegerInt32, 2000000000); 335 + expect(result.success).toBe(true); 336 + }); 337 + 338 + it('should reject values below int32 minimum', () => { 339 + const result = v.safeParse(generatedSchemas.vIntegerInt32, -2147483649); 340 + expect(result.success).toBe(false); 341 + expect(result.issues![0].message).toContain( 342 + FORMAT_BOUNDS.int32.minError, 343 + ); 344 + }); 345 + 346 + it('should reject values above int32 maximum', () => { 347 + const result = v.safeParse(generatedSchemas.vIntegerInt32, 2147483648); 348 + expect(result.success).toBe(false); 349 + expect(result.issues![0].message).toContain( 350 + FORMAT_BOUNDS.int32.maxError, 351 + ); 352 + }); 353 + }); 354 + 355 + describe('integerInt64', () => { 356 + it('should validate values within int64 range and convert to BigInt', () => { 357 + const result = v.safeParse( 358 + generatedSchemas.vIntegerInt64, 359 + 1000000000000, 360 + ); 361 + expect(result.success).toBe(true); 362 + expect(typeof result.output).toBe('bigint'); 363 + }); 364 + 365 + it('should validate string values within int64 range', () => { 366 + const result = v.safeParse( 367 + generatedSchemas.vIntegerInt64, 368 + '1000000000000', 369 + ); 370 + expect(result.success).toBe(true); 371 + expect(typeof result.output).toBe('bigint'); 372 + }); 373 + 374 + it('should reject values above int64 maximum', () => { 375 + const result = v.safeParse( 376 + generatedSchemas.vIntegerInt64, 377 + '9223372036854775808', 378 + ); 379 + expect(result.success).toBe(false); 380 + expect(result.issues![0].message).toContain( 381 + FORMAT_BOUNDS.int64.maxError, 382 + ); 383 + }); 384 + }); 385 + 386 + describe('integerUint8', () => { 387 + it('should validate values within uint8 range', () => { 388 + const result = v.safeParse(generatedSchemas.vIntegerUint8, 200); 389 + expect(result.success).toBe(true); 390 + }); 391 + 392 + it('should reject negative values', () => { 393 + const result = v.safeParse(generatedSchemas.vIntegerUint8, -1); 394 + expect(result.success).toBe(false); 395 + expect(result.issues![0].message).toContain( 396 + FORMAT_BOUNDS.uint8.minError, 397 + ); 398 + }); 399 + 400 + it('should reject values above uint8 maximum', () => { 401 + const result = v.safeParse(generatedSchemas.vIntegerUint8, 256); 402 + expect(result.success).toBe(false); 403 + expect(result.issues![0].message).toContain( 404 + FORMAT_BOUNDS.uint8.maxError, 405 + ); 406 + }); 407 + }); 408 + 409 + describe('integerUint16', () => { 410 + it('should validate values within uint16 range', () => { 411 + const result = v.safeParse(generatedSchemas.vIntegerUint16, 60000); 412 + expect(result.success).toBe(true); 413 + }); 414 + 415 + it('should reject negative values', () => { 416 + const result = v.safeParse(generatedSchemas.vIntegerUint16, -1); 417 + expect(result.success).toBe(false); 418 + expect(result.issues![0].message).toContain( 419 + FORMAT_BOUNDS.uint16.minError, 420 + ); 421 + }); 422 + 423 + it('should reject values above uint16 maximum', () => { 424 + const result = v.safeParse(generatedSchemas.vIntegerUint16, 65536); 425 + expect(result.success).toBe(false); 426 + expect(result.issues![0].message).toContain( 427 + FORMAT_BOUNDS.uint16.maxError, 428 + ); 429 + }); 430 + }); 431 + 432 + describe('integerUint32', () => { 433 + it('should validate values within uint32 range', () => { 434 + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4000000000); 435 + expect(result.success).toBe(true); 436 + }); 437 + 438 + it('should reject negative values', () => { 439 + const result = v.safeParse(generatedSchemas.vIntegerUint32, -1); 440 + expect(result.success).toBe(false); 441 + expect(result.issues![0].message).toContain( 442 + FORMAT_BOUNDS.uint32.minError, 443 + ); 444 + }); 445 + 446 + it('should reject values above uint32 maximum', () => { 447 + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967296); 448 + expect(result.success).toBe(false); 449 + expect(result.issues![0].message).toContain( 450 + FORMAT_BOUNDS.uint32.maxError, 451 + ); 452 + }); 453 + }); 454 + 455 + describe('integerUint64', () => { 456 + it('should validate values within uint64 range and convert to BigInt', () => { 457 + const result = v.safeParse( 458 + generatedSchemas.vIntegerUint64, 459 + 1000000000000, 460 + ); 461 + expect(result.success).toBe(true); 462 + expect(typeof result.output).toBe('bigint'); 463 + }); 464 + 465 + it('should reject negative values', () => { 466 + const result = v.safeParse(generatedSchemas.vIntegerUint64, -1); 467 + expect(result.success).toBe(false); 468 + expect(result.issues![0].message).toContain( 469 + FORMAT_BOUNDS.uint64.minError, 470 + ); 471 + }); 472 + 473 + it('should reject values above uint64 maximum', () => { 474 + const result = v.safeParse( 475 + generatedSchemas.vIntegerUint64, 476 + '18446744073709551616', 477 + ); 478 + expect(result.success).toBe(false); 479 + expect(result.issues![0].message).toContain( 480 + FORMAT_BOUNDS.uint64.maxError, 481 + ); 482 + }); 483 + }); 484 + }); 485 + 486 + describe('String Type Format Validation', () => { 487 + describe('stringInt64', () => { 488 + it('should validate string values within int64 range and convert to BigInt', () => { 489 + const result = v.safeParse( 490 + generatedSchemas.vStringInt64, 491 + '1000000000000', 492 + ); 493 + expect(result.success).toBe(true); 494 + expect(typeof result.output).toBe('bigint'); 495 + }); 496 + 497 + it('should reject values below int64 minimum', () => { 498 + const result = v.safeParse( 499 + generatedSchemas.vStringInt64, 500 + '-9223372036854775809', 501 + ); 502 + expect(result.success).toBe(false); 503 + expect(result.issues![0].message).toContain( 504 + FORMAT_BOUNDS.int64.minError, 505 + ); 506 + }); 507 + 508 + it('should reject values above int64 maximum', () => { 509 + const result = v.safeParse( 510 + generatedSchemas.vStringInt64, 511 + '9223372036854775808', 512 + ); 513 + expect(result.success).toBe(false); 514 + expect(result.issues![0].message).toContain( 515 + FORMAT_BOUNDS.int64.maxError, 516 + ); 517 + }); 518 + }); 519 + 520 + describe('stringUint64', () => { 521 + it('should validate string values within uint64 range and convert to BigInt', () => { 522 + const result = v.safeParse( 523 + generatedSchemas.vStringUint64, 524 + '1000000000000', 525 + ); 526 + expect(result.success).toBe(true); 527 + expect(typeof result.output).toBe('bigint'); 528 + }); 529 + 530 + it('should reject negative values', () => { 531 + const result = v.safeParse(generatedSchemas.vStringUint64, '-1'); 532 + expect(result.success).toBe(false); 533 + expect(result.issues![0].message).toContain( 534 + FORMAT_BOUNDS.uint64.minError, 535 + ); 536 + }); 537 + 538 + it('should reject values above uint64 maximum', () => { 539 + const result = v.safeParse( 540 + generatedSchemas.vStringUint64, 541 + '18446744073709551616', 542 + ); 543 + expect(result.success).toBe(false); 544 + expect(result.issues![0].message).toContain( 545 + FORMAT_BOUNDS.uint64.maxError, 546 + ); 547 + }); 548 + }); 549 + }); 550 + });
+909
packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts
··· 1 + import * as v from 'valibot'; 2 + import { beforeAll, describe, expect, it } from 'vitest'; 3 + 4 + import { setupValibotTest } from '../../test-helper'; 5 + 6 + describe('Number Type Min/Max Constraints Tests', () => { 7 + let generatedSchemas: any; 8 + 9 + beforeAll(async () => { 10 + generatedSchemas = await setupValibotTest(); 11 + }); 12 + 13 + describe('Basic Number Constraints', () => { 14 + describe('NumberWithMinimum', () => { 15 + it('should accept values at minimum boundary', () => { 16 + const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 10); 17 + expect(result.success).toBe(true); 18 + }); 19 + 20 + it('should accept values above minimum', () => { 21 + const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 15); 22 + expect(result.success).toBe(true); 23 + }); 24 + 25 + it('should reject values below minimum', () => { 26 + const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 9); 27 + expect(result.success).toBe(false); 28 + }); 29 + }); 30 + 31 + describe('NumberWithMaximum', () => { 32 + it('should accept values at maximum boundary', () => { 33 + const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 100); 34 + expect(result.success).toBe(true); 35 + }); 36 + 37 + it('should accept values below maximum', () => { 38 + const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 50); 39 + expect(result.success).toBe(true); 40 + }); 41 + 42 + it('should reject values above maximum', () => { 43 + const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 101); 44 + expect(result.success).toBe(false); 45 + }); 46 + }); 47 + 48 + describe('NumberWithMinMax', () => { 49 + it('should accept values within range', () => { 50 + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 50); 51 + expect(result.success).toBe(true); 52 + }); 53 + 54 + it('should accept values at minimum boundary', () => { 55 + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 0); 56 + expect(result.success).toBe(true); 57 + }); 58 + 59 + it('should accept values at maximum boundary', () => { 60 + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 100); 61 + expect(result.success).toBe(true); 62 + }); 63 + 64 + it('should reject values below minimum', () => { 65 + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, -1); 66 + expect(result.success).toBe(false); 67 + }); 68 + 69 + it('should reject values above maximum', () => { 70 + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 101); 71 + expect(result.success).toBe(false); 72 + }); 73 + }); 74 + }); 75 + 76 + describe('Basic Integer Constraints', () => { 77 + describe('IntegerWithMinimum', () => { 78 + it('should accept values at minimum boundary', () => { 79 + const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 5); 80 + expect(result.success).toBe(true); 81 + }); 82 + 83 + it('should accept values above minimum', () => { 84 + const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 10); 85 + expect(result.success).toBe(true); 86 + }); 87 + 88 + it('should reject values below minimum', () => { 89 + const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 4); 90 + expect(result.success).toBe(false); 91 + }); 92 + }); 93 + 94 + describe('IntegerWithMaximum', () => { 95 + it('should accept values at maximum boundary', () => { 96 + const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 999); 97 + expect(result.success).toBe(true); 98 + }); 99 + 100 + it('should accept values below maximum', () => { 101 + const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 500); 102 + expect(result.success).toBe(true); 103 + }); 104 + 105 + it('should reject values above maximum', () => { 106 + const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 1000); 107 + expect(result.success).toBe(false); 108 + }); 109 + }); 110 + 111 + describe('IntegerWithMinMax', () => { 112 + it('should accept values within range', () => { 113 + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 500); 114 + expect(result.success).toBe(true); 115 + }); 116 + 117 + it('should accept values at minimum boundary', () => { 118 + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 1); 119 + expect(result.success).toBe(true); 120 + }); 121 + 122 + it('should accept values at maximum boundary', () => { 123 + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 999); 124 + expect(result.success).toBe(true); 125 + }); 126 + 127 + it('should reject values below minimum', () => { 128 + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 0); 129 + expect(result.success).toBe(false); 130 + }); 131 + 132 + it('should reject values above maximum', () => { 133 + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 1000); 134 + expect(result.success).toBe(false); 135 + }); 136 + }); 137 + }); 138 + 139 + describe('Exclusive Constraints', () => { 140 + describe('NumberWithExclusiveMin', () => { 141 + it('should accept values above exclusive minimum', () => { 142 + const result = v.safeParse( 143 + generatedSchemas.vNumberWithExclusiveMin, 144 + 0.1, 145 + ); 146 + expect(result.success).toBe(true); 147 + }); 148 + 149 + it('should reject values at exclusive minimum', () => { 150 + const result = v.safeParse(generatedSchemas.vNumberWithExclusiveMin, 0); 151 + expect(result.success).toBe(false); 152 + }); 153 + 154 + it('should reject values below exclusive minimum', () => { 155 + const result = v.safeParse( 156 + generatedSchemas.vNumberWithExclusiveMin, 157 + -1, 158 + ); 159 + expect(result.success).toBe(false); 160 + }); 161 + }); 162 + 163 + describe('NumberWithExclusiveMax', () => { 164 + it('should accept values below exclusive maximum', () => { 165 + const result = v.safeParse( 166 + generatedSchemas.vNumberWithExclusiveMax, 167 + 99.9, 168 + ); 169 + expect(result.success).toBe(true); 170 + }); 171 + 172 + it('should reject values at exclusive maximum', () => { 173 + const result = v.safeParse( 174 + generatedSchemas.vNumberWithExclusiveMax, 175 + 100, 176 + ); 177 + expect(result.success).toBe(false); 178 + }); 179 + 180 + it('should reject values above exclusive maximum', () => { 181 + const result = v.safeParse( 182 + generatedSchemas.vNumberWithExclusiveMax, 183 + 101, 184 + ); 185 + expect(result.success).toBe(false); 186 + }); 187 + }); 188 + 189 + describe('NumberWithExclusiveMinMax', () => { 190 + it('should accept values within exclusive range', () => { 191 + const result = v.safeParse( 192 + generatedSchemas.vNumberWithExclusiveMinMax, 193 + 0.5, 194 + ); 195 + expect(result.success).toBe(true); 196 + }); 197 + 198 + it('should reject values at exclusive minimum', () => { 199 + const result = v.safeParse( 200 + generatedSchemas.vNumberWithExclusiveMinMax, 201 + 0, 202 + ); 203 + expect(result.success).toBe(false); 204 + }); 205 + 206 + it('should reject values at exclusive maximum', () => { 207 + const result = v.safeParse( 208 + generatedSchemas.vNumberWithExclusiveMinMax, 209 + 1, 210 + ); 211 + expect(result.success).toBe(false); 212 + }); 213 + }); 214 + 215 + describe('IntegerWithExclusiveMin', () => { 216 + it('should accept values above exclusive minimum', () => { 217 + const result = v.safeParse( 218 + generatedSchemas.vIntegerWithExclusiveMin, 219 + 11, 220 + ); 221 + expect(result.success).toBe(true); 222 + }); 223 + 224 + it('should reject values at exclusive minimum', () => { 225 + const result = v.safeParse( 226 + generatedSchemas.vIntegerWithExclusiveMin, 227 + 10, 228 + ); 229 + expect(result.success).toBe(false); 230 + }); 231 + 232 + it('should reject values below exclusive minimum', () => { 233 + const result = v.safeParse( 234 + generatedSchemas.vIntegerWithExclusiveMin, 235 + 9, 236 + ); 237 + expect(result.success).toBe(false); 238 + }); 239 + }); 240 + 241 + describe('IntegerWithExclusiveMax', () => { 242 + it('should accept values below exclusive maximum', () => { 243 + const result = v.safeParse( 244 + generatedSchemas.vIntegerWithExclusiveMax, 245 + 49, 246 + ); 247 + expect(result.success).toBe(true); 248 + }); 249 + 250 + it('should reject values at exclusive maximum', () => { 251 + const result = v.safeParse( 252 + generatedSchemas.vIntegerWithExclusiveMax, 253 + 50, 254 + ); 255 + expect(result.success).toBe(false); 256 + }); 257 + 258 + it('should reject values above exclusive maximum', () => { 259 + const result = v.safeParse( 260 + generatedSchemas.vIntegerWithExclusiveMax, 261 + 51, 262 + ); 263 + expect(result.success).toBe(false); 264 + }); 265 + }); 266 + 267 + describe('IntegerWithExclusiveMinMax', () => { 268 + it('should accept values within exclusive range', () => { 269 + const result = v.safeParse( 270 + generatedSchemas.vIntegerWithExclusiveMinMax, 271 + 10, 272 + ); 273 + expect(result.success).toBe(true); 274 + }); 275 + 276 + it('should reject values at exclusive minimum', () => { 277 + const result = v.safeParse( 278 + generatedSchemas.vIntegerWithExclusiveMinMax, 279 + 5, 280 + ); 281 + expect(result.success).toBe(false); 282 + }); 283 + 284 + it('should reject values at exclusive maximum', () => { 285 + const result = v.safeParse( 286 + generatedSchemas.vIntegerWithExclusiveMinMax, 287 + 15, 288 + ); 289 + expect(result.success).toBe(false); 290 + }); 291 + }); 292 + }); 293 + 294 + describe('Mixed Constraints', () => { 295 + describe('NumberWithExclusiveMinInclusiveMax', () => { 296 + it('should accept values above exclusive minimum and at inclusive maximum', () => { 297 + const result = v.safeParse( 298 + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, 299 + 90, 300 + ); 301 + expect(result.success).toBe(true); 302 + }); 303 + 304 + it('should accept values above exclusive minimum and below inclusive maximum', () => { 305 + const result = v.safeParse( 306 + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, 307 + 50, 308 + ); 309 + expect(result.success).toBe(true); 310 + }); 311 + 312 + it('should reject values at exclusive minimum', () => { 313 + const result = v.safeParse( 314 + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, 315 + 10, 316 + ); 317 + expect(result.success).toBe(false); 318 + }); 319 + 320 + it('should reject values above inclusive maximum', () => { 321 + const result = v.safeParse( 322 + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, 323 + 91, 324 + ); 325 + expect(result.success).toBe(false); 326 + }); 327 + }); 328 + 329 + describe('NumberWithInclusiveMinExclusiveMax', () => { 330 + it('should accept values at inclusive minimum and below exclusive maximum', () => { 331 + const result = v.safeParse( 332 + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, 333 + 20, 334 + ); 335 + expect(result.success).toBe(true); 336 + }); 337 + 338 + it('should accept values above inclusive minimum and below exclusive maximum', () => { 339 + const result = v.safeParse( 340 + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, 341 + 50, 342 + ); 343 + expect(result.success).toBe(true); 344 + }); 345 + 346 + it('should reject values below inclusive minimum', () => { 347 + const result = v.safeParse( 348 + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, 349 + 19, 350 + ); 351 + expect(result.success).toBe(false); 352 + }); 353 + 354 + it('should reject values at exclusive maximum', () => { 355 + const result = v.safeParse( 356 + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, 357 + 80, 358 + ); 359 + expect(result.success).toBe(false); 360 + }); 361 + }); 362 + 363 + describe('IntegerWithExclusiveMinInclusiveMax', () => { 364 + it('should accept values above exclusive minimum and at inclusive maximum', () => { 365 + const result = v.safeParse( 366 + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, 367 + 50, 368 + ); 369 + expect(result.success).toBe(true); 370 + }); 371 + 372 + it('should accept values above exclusive minimum and below inclusive maximum', () => { 373 + const result = v.safeParse( 374 + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, 375 + 25, 376 + ); 377 + expect(result.success).toBe(true); 378 + }); 379 + 380 + it('should reject values at exclusive minimum', () => { 381 + const result = v.safeParse( 382 + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, 383 + 5, 384 + ); 385 + expect(result.success).toBe(false); 386 + }); 387 + 388 + it('should reject values above inclusive maximum', () => { 389 + const result = v.safeParse( 390 + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, 391 + 51, 392 + ); 393 + expect(result.success).toBe(false); 394 + }); 395 + }); 396 + 397 + describe('IntegerWithInclusiveMinExclusiveMax', () => { 398 + it('should accept values at inclusive minimum and below exclusive maximum', () => { 399 + const result = v.safeParse( 400 + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, 401 + 10, 402 + ); 403 + expect(result.success).toBe(true); 404 + }); 405 + 406 + it('should accept values above inclusive minimum and below exclusive maximum', () => { 407 + const result = v.safeParse( 408 + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, 409 + 55, 410 + ); 411 + expect(result.success).toBe(true); 412 + }); 413 + 414 + it('should reject values below inclusive minimum', () => { 415 + const result = v.safeParse( 416 + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, 417 + 9, 418 + ); 419 + expect(result.success).toBe(false); 420 + }); 421 + 422 + it('should reject values at exclusive maximum', () => { 423 + const result = v.safeParse( 424 + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, 425 + 100, 426 + ); 427 + expect(result.success).toBe(false); 428 + }); 429 + }); 430 + }); 431 + 432 + describe('Format-Specific Constraints (Int64)', () => { 433 + describe('Int64WithMinimum', () => { 434 + it('should accept BigInt values at minimum boundary', () => { 435 + const result = v.safeParse( 436 + generatedSchemas.vInt64WithMinimum, 437 + BigInt('-5000000000000'), 438 + ); 439 + expect(result.success).toBe(true); 440 + }); 441 + 442 + it('should accept BigInt values above minimum', () => { 443 + const result = v.safeParse( 444 + generatedSchemas.vInt64WithMinimum, 445 + BigInt('0'), 446 + ); 447 + expect(result.success).toBe(true); 448 + }); 449 + 450 + it('should reject BigInt values below minimum', () => { 451 + const result = v.safeParse( 452 + generatedSchemas.vInt64WithMinimum, 453 + BigInt('-5000000000001'), 454 + ); 455 + expect(result.success).toBe(false); 456 + }); 457 + }); 458 + 459 + describe('Int64WithMaximum', () => { 460 + it('should accept BigInt values at maximum boundary', () => { 461 + const result = v.safeParse( 462 + generatedSchemas.vInt64WithMaximum, 463 + BigInt('5000000000000'), 464 + ); 465 + expect(result.success).toBe(true); 466 + }); 467 + 468 + it('should accept BigInt values below maximum', () => { 469 + const result = v.safeParse( 470 + generatedSchemas.vInt64WithMaximum, 471 + BigInt('1000000000000'), 472 + ); 473 + expect(result.success).toBe(true); 474 + }); 475 + 476 + it('should reject BigInt values above maximum', () => { 477 + const result = v.safeParse( 478 + generatedSchemas.vInt64WithMaximum, 479 + BigInt('5000000000001'), 480 + ); 481 + expect(result.success).toBe(false); 482 + }); 483 + }); 484 + 485 + describe('Int64WithMinMax', () => { 486 + it('should accept BigInt values within range', () => { 487 + const result = v.safeParse( 488 + generatedSchemas.vInt64WithMinMax, 489 + BigInt('0'), 490 + ); 491 + expect(result.success).toBe(true); 492 + }); 493 + 494 + it('should accept BigInt values at minimum boundary', () => { 495 + const result = v.safeParse( 496 + generatedSchemas.vInt64WithMinMax, 497 + BigInt('-4000000000000'), 498 + ); 499 + expect(result.success).toBe(true); 500 + }); 501 + 502 + it('should accept BigInt values at maximum boundary', () => { 503 + const result = v.safeParse( 504 + generatedSchemas.vInt64WithMinMax, 505 + BigInt('4000000000000'), 506 + ); 507 + expect(result.success).toBe(true); 508 + }); 509 + 510 + it('should reject BigInt values below minimum', () => { 511 + const result = v.safeParse( 512 + generatedSchemas.vInt64WithMinMax, 513 + BigInt('-4000000000001'), 514 + ); 515 + expect(result.success).toBe(false); 516 + }); 517 + 518 + it('should reject BigInt values above maximum', () => { 519 + const result = v.safeParse( 520 + generatedSchemas.vInt64WithMinMax, 521 + BigInt('4000000000001'), 522 + ); 523 + expect(result.success).toBe(false); 524 + }); 525 + }); 526 + 527 + describe('Int64WithExclusiveMin', () => { 528 + it('should accept BigInt values above exclusive minimum', () => { 529 + const result = v.safeParse( 530 + generatedSchemas.vInt64WithExclusiveMin, 531 + BigInt('-2999999999999'), 532 + ); 533 + expect(result.success).toBe(true); 534 + }); 535 + 536 + it('should reject BigInt values at exclusive minimum', () => { 537 + const result = v.safeParse( 538 + generatedSchemas.vInt64WithExclusiveMin, 539 + BigInt('-3000000000000'), 540 + ); 541 + expect(result.success).toBe(false); 542 + }); 543 + }); 544 + 545 + describe('Int64WithExclusiveMax', () => { 546 + it('should accept BigInt values below exclusive maximum', () => { 547 + const result = v.safeParse( 548 + generatedSchemas.vInt64WithExclusiveMax, 549 + BigInt('2999999999999'), 550 + ); 551 + expect(result.success).toBe(true); 552 + }); 553 + 554 + it('should reject BigInt values at exclusive maximum', () => { 555 + const result = v.safeParse( 556 + generatedSchemas.vInt64WithExclusiveMax, 557 + BigInt('3000000000000'), 558 + ); 559 + expect(result.success).toBe(false); 560 + }); 561 + }); 562 + 563 + describe('Int64WithExclusiveMinMax', () => { 564 + it('should accept BigInt values within exclusive range', () => { 565 + const result = v.safeParse( 566 + generatedSchemas.vInt64WithExclusiveMinMax, 567 + BigInt('0'), 568 + ); 569 + expect(result.success).toBe(true); 570 + }); 571 + 572 + it('should reject BigInt values at exclusive minimum', () => { 573 + const result = v.safeParse( 574 + generatedSchemas.vInt64WithExclusiveMinMax, 575 + BigInt('-2000000000000'), 576 + ); 577 + expect(result.success).toBe(false); 578 + }); 579 + 580 + it('should reject BigInt values at exclusive maximum', () => { 581 + const result = v.safeParse( 582 + generatedSchemas.vInt64WithExclusiveMinMax, 583 + BigInt('2000000000000'), 584 + ); 585 + expect(result.success).toBe(false); 586 + }); 587 + }); 588 + 589 + describe('Int64WithExclusiveMinInclusiveMax', () => { 590 + it('should accept values above exclusive minimum and at inclusive maximum', () => { 591 + const result = v.safeParse( 592 + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, 593 + BigInt('6000000000000'), 594 + ); 595 + expect(result.success).toBe(true); 596 + }); 597 + 598 + it('should accept values above exclusive minimum and below inclusive maximum', () => { 599 + const result = v.safeParse( 600 + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, 601 + BigInt('0'), 602 + ); 603 + expect(result.success).toBe(true); 604 + }); 605 + 606 + it('should reject values at exclusive minimum', () => { 607 + const result = v.safeParse( 608 + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, 609 + BigInt('-6000000000000'), 610 + ); 611 + expect(result.success).toBe(false); 612 + }); 613 + 614 + it('should reject values above inclusive maximum', () => { 615 + const result = v.safeParse( 616 + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, 617 + BigInt('6000000000001'), 618 + ); 619 + expect(result.success).toBe(false); 620 + }); 621 + }); 622 + 623 + describe('Int64WithInclusiveMinExclusiveMax', () => { 624 + it('should accept values at inclusive minimum and below exclusive maximum', () => { 625 + const result = v.safeParse( 626 + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, 627 + BigInt('-7000000000000'), 628 + ); 629 + expect(result.success).toBe(true); 630 + }); 631 + 632 + it('should accept values above inclusive minimum and below exclusive maximum', () => { 633 + const result = v.safeParse( 634 + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, 635 + BigInt('0'), 636 + ); 637 + expect(result.success).toBe(true); 638 + }); 639 + 640 + it('should reject values below inclusive minimum', () => { 641 + const result = v.safeParse( 642 + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, 643 + BigInt('-7000000000001'), 644 + ); 645 + expect(result.success).toBe(false); 646 + }); 647 + 648 + it('should reject values at exclusive maximum', () => { 649 + const result = v.safeParse( 650 + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, 651 + BigInt('7000000000000'), 652 + ); 653 + expect(result.success).toBe(false); 654 + }); 655 + }); 656 + }); 657 + 658 + describe('Format-Specific Constraints (UInt64)', () => { 659 + describe('UInt64WithMinimum', () => { 660 + it('should accept BigInt values at minimum boundary', () => { 661 + const result = v.safeParse( 662 + generatedSchemas.vUInt64WithMinimum, 663 + BigInt('5000000000000'), 664 + ); 665 + expect(result.success).toBe(true); 666 + }); 667 + 668 + it('should accept BigInt values above minimum', () => { 669 + const result = v.safeParse( 670 + generatedSchemas.vUInt64WithMinimum, 671 + BigInt('8000000000000'), 672 + ); 673 + expect(result.success).toBe(true); 674 + }); 675 + 676 + it('should reject BigInt values below minimum', () => { 677 + const result = v.safeParse( 678 + generatedSchemas.vUInt64WithMinimum, 679 + BigInt('4999999999999'), 680 + ); 681 + expect(result.success).toBe(false); 682 + }); 683 + }); 684 + 685 + describe('UInt64WithMaximum', () => { 686 + it('should accept BigInt values at maximum boundary', () => { 687 + const result = v.safeParse( 688 + generatedSchemas.vUInt64WithMaximum, 689 + BigInt('15000000000000'), 690 + ); 691 + expect(result.success).toBe(true); 692 + }); 693 + 694 + it('should accept BigInt values below maximum', () => { 695 + const result = v.safeParse( 696 + generatedSchemas.vUInt64WithMaximum, 697 + BigInt('10000000000000'), 698 + ); 699 + expect(result.success).toBe(true); 700 + }); 701 + 702 + it('should reject BigInt values above maximum', () => { 703 + const result = v.safeParse( 704 + generatedSchemas.vUInt64WithMaximum, 705 + BigInt('15000000000001'), 706 + ); 707 + expect(result.success).toBe(false); 708 + }); 709 + }); 710 + 711 + describe('UInt64WithMinMax', () => { 712 + it('should accept BigInt values within range', () => { 713 + const result = v.safeParse( 714 + generatedSchemas.vUInt64WithMinMax, 715 + BigInt('5000000000000'), 716 + ); 717 + expect(result.success).toBe(true); 718 + }); 719 + 720 + it('should accept BigInt values at minimum boundary', () => { 721 + const result = v.safeParse( 722 + generatedSchemas.vUInt64WithMinMax, 723 + BigInt('1000000000000'), 724 + ); 725 + expect(result.success).toBe(true); 726 + }); 727 + 728 + it('should accept BigInt values at maximum boundary', () => { 729 + const result = v.safeParse( 730 + generatedSchemas.vUInt64WithMinMax, 731 + BigInt('10000000000000'), 732 + ); 733 + expect(result.success).toBe(true); 734 + }); 735 + 736 + it('should reject BigInt values below minimum', () => { 737 + const result = v.safeParse( 738 + generatedSchemas.vUInt64WithMinMax, 739 + BigInt('999999999999'), 740 + ); 741 + expect(result.success).toBe(false); 742 + }); 743 + 744 + it('should reject BigInt values above maximum', () => { 745 + const result = v.safeParse( 746 + generatedSchemas.vUInt64WithMinMax, 747 + BigInt('10000000000001'), 748 + ); 749 + expect(result.success).toBe(false); 750 + }); 751 + }); 752 + 753 + describe('UInt64WithExclusiveMin', () => { 754 + it('should accept BigInt values above exclusive minimum', () => { 755 + const result = v.safeParse( 756 + generatedSchemas.vUInt64WithExclusiveMin, 757 + BigInt('8000000000001'), 758 + ); 759 + expect(result.success).toBe(true); 760 + }); 761 + 762 + it('should reject BigInt values at exclusive minimum', () => { 763 + const result = v.safeParse( 764 + generatedSchemas.vUInt64WithExclusiveMin, 765 + BigInt('8000000000000'), 766 + ); 767 + expect(result.success).toBe(false); 768 + }); 769 + }); 770 + 771 + describe('UInt64WithExclusiveMax', () => { 772 + it('should accept BigInt values below exclusive maximum', () => { 773 + const result = v.safeParse( 774 + generatedSchemas.vUInt64WithExclusiveMax, 775 + BigInt('11999999999999'), 776 + ); 777 + expect(result.success).toBe(true); 778 + }); 779 + 780 + it('should reject BigInt values at exclusive maximum', () => { 781 + const result = v.safeParse( 782 + generatedSchemas.vUInt64WithExclusiveMax, 783 + BigInt('12000000000000'), 784 + ); 785 + expect(result.success).toBe(false); 786 + }); 787 + }); 788 + 789 + describe('UInt64WithExclusiveMinMax', () => { 790 + it('should accept BigInt values within exclusive range', () => { 791 + const result = v.safeParse( 792 + generatedSchemas.vUInt64WithExclusiveMinMax, 793 + BigInt('5000000000000'), 794 + ); 795 + expect(result.success).toBe(true); 796 + }); 797 + 798 + it('should reject BigInt values at exclusive minimum', () => { 799 + const result = v.safeParse( 800 + generatedSchemas.vUInt64WithExclusiveMinMax, 801 + BigInt('2000000000000'), 802 + ); 803 + expect(result.success).toBe(false); 804 + }); 805 + 806 + it('should reject BigInt values at exclusive maximum', () => { 807 + const result = v.safeParse( 808 + generatedSchemas.vUInt64WithExclusiveMinMax, 809 + BigInt('8000000000000'), 810 + ); 811 + expect(result.success).toBe(false); 812 + }); 813 + }); 814 + 815 + describe('UInt64WithExclusiveMinInclusiveMax', () => { 816 + it('should accept values above exclusive minimum and at inclusive maximum', () => { 817 + const result = v.safeParse( 818 + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, 819 + BigInt('13000000000000'), 820 + ); 821 + expect(result.success).toBe(true); 822 + }); 823 + 824 + it('should accept values above exclusive minimum and below inclusive maximum', () => { 825 + const result = v.safeParse( 826 + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, 827 + BigInt('8000000000000'), 828 + ); 829 + expect(result.success).toBe(true); 830 + }); 831 + 832 + it('should reject values at exclusive minimum', () => { 833 + const result = v.safeParse( 834 + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, 835 + BigInt('3000000000000'), 836 + ); 837 + expect(result.success).toBe(false); 838 + }); 839 + 840 + it('should reject values above inclusive maximum', () => { 841 + const result = v.safeParse( 842 + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, 843 + BigInt('13000000000001'), 844 + ); 845 + expect(result.success).toBe(false); 846 + }); 847 + }); 848 + 849 + describe('UInt64WithInclusiveMinExclusiveMax', () => { 850 + it('should accept values at inclusive minimum and below exclusive maximum', () => { 851 + const result = v.safeParse( 852 + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, 853 + BigInt('4000000000000'), 854 + ); 855 + expect(result.success).toBe(true); 856 + }); 857 + 858 + it('should accept values above inclusive minimum and below exclusive maximum', () => { 859 + const result = v.safeParse( 860 + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, 861 + BigInt('9000000000000'), 862 + ); 863 + expect(result.success).toBe(true); 864 + }); 865 + 866 + it('should reject values below inclusive minimum', () => { 867 + const result = v.safeParse( 868 + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, 869 + BigInt('3999999999999'), 870 + ); 871 + expect(result.success).toBe(false); 872 + }); 873 + 874 + it('should reject values at exclusive maximum', () => { 875 + const result = v.safeParse( 876 + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, 877 + BigInt('14000000000000'), 878 + ); 879 + expect(result.success).toBe(false); 880 + }); 881 + }); 882 + }); 883 + 884 + describe('Special Cases', () => { 885 + describe('PrecedenceTest', () => { 886 + it('should use exclusive constraints over inclusive (exclusive minimum takes precedence)', () => { 887 + // exclusiveMinimum: 5, minimum: 10 - exclusive should take precedence 888 + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 6); 889 + expect(result.success).toBe(true); 890 + }); 891 + 892 + it('should use exclusive constraints over inclusive (exclusive maximum takes precedence)', () => { 893 + // exclusiveMaximum: 95, maximum: 90 - exclusive should take precedence 894 + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 94); 895 + expect(result.success).toBe(true); 896 + }); 897 + 898 + it('should reject values at exclusive minimum boundary', () => { 899 + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 5); 900 + expect(result.success).toBe(false); 901 + }); 902 + 903 + it('should reject values at exclusive maximum boundary', () => { 904 + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 95); 905 + expect(result.success).toBe(false); 906 + }); 907 + }); 908 + }); 909 + });
+67
packages/openapi-ts-tests/specs/3.1.x/integer-formats.yaml
··· 1 + openapi: '3.1.0' 2 + info: 3 + title: Integer Formats Test 4 + version: '1.0.0' 5 + components: 6 + schemas: 7 + IntegerFormats: 8 + type: object 9 + properties: 10 + numberNoFormat: 11 + type: number 12 + numberInt8: 13 + type: number 14 + format: int8 15 + numberInt16: 16 + type: number 17 + format: int16 18 + numberInt32: 19 + type: number 20 + format: int32 21 + numberInt64: 22 + type: number 23 + format: int64 24 + numberUint8: 25 + type: number 26 + format: uint8 27 + numberUint16: 28 + type: number 29 + format: uint16 30 + numberUint32: 31 + type: number 32 + format: uint32 33 + numberUint64: 34 + type: number 35 + format: uint64 36 + integerNoFormat: 37 + type: integer 38 + integerInt8: 39 + type: integer 40 + format: int8 41 + integerInt16: 42 + type: integer 43 + format: int16 44 + integerInt32: 45 + type: integer 46 + format: int32 47 + integerInt64: 48 + type: integer 49 + format: int64 50 + integerUint8: 51 + type: integer 52 + format: uint8 53 + integerUint16: 54 + type: integer 55 + format: uint16 56 + integerUint32: 57 + type: integer 58 + format: uint32 59 + integerUint64: 60 + type: integer 61 + format: uint64 62 + stringInt64: 63 + type: string 64 + format: int64 65 + stringUint64: 66 + type: string 67 + format: uint64
+75
packages/openapi-ts-tests/specs/3.1.x/schema-const.yaml
··· 31 31 const: 10n 32 32 format: int64 33 33 type: integer 34 + # Integer format const examples - number type 35 + numberInt8: 36 + const: 100 37 + format: int8 38 + type: number 39 + numberInt16: 40 + const: 1000 41 + format: int16 42 + type: number 43 + numberInt32: 44 + const: 100000 45 + format: int32 46 + type: number 47 + numberInt64: 48 + const: 1000000000000 49 + format: int64 50 + type: number 51 + numberUint8: 52 + const: 200 53 + format: uint8 54 + type: number 55 + numberUint16: 56 + const: 50000 57 + format: uint16 58 + type: number 59 + numberUint32: 60 + const: 3000000000 61 + format: uint32 62 + type: number 63 + numberUint64: 64 + const: 18000000000000000000 65 + format: uint64 66 + type: number 67 + # Integer format const examples - integer type 68 + integerInt8: 69 + const: -100 70 + format: int8 71 + type: integer 72 + integerInt16: 73 + const: -1000 74 + format: int16 75 + type: integer 76 + integerInt32: 77 + const: -100000 78 + format: int32 79 + type: integer 80 + integerInt64: 81 + const: -1000000000000 82 + format: int64 83 + type: integer 84 + integerUint8: 85 + const: 255 86 + format: uint8 87 + type: integer 88 + integerUint16: 89 + const: 65535 90 + format: uint16 91 + type: integer 92 + integerUint32: 93 + const: 4294967295 94 + format: uint32 95 + type: integer 96 + integerUint64: 97 + const: 18446744073709551615n 98 + format: uint64 99 + type: integer 100 + # Integer format const examples - string type (only for 64-bit formats) 101 + stringInt64: 102 + const: '-9223372036854775808' 103 + format: int64 104 + type: string 105 + stringUint64: 106 + const: '18446744073709551615' 107 + format: uint64 108 + type: string 34 109 type: object
+19 -1
packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts
··· 15 15 z.literal(true) 16 16 ])), 17 17 corge: z.optional(z.object({})), 18 - garply: z.optional(z.coerce.bigint()) 18 + garply: z.optional(z.coerce.bigint()), 19 + numberInt8: z.optional(z.literal(100)), 20 + numberInt16: z.optional(z.literal(1000)), 21 + numberInt32: z.optional(z.literal(100000)), 22 + numberInt64: z.optional(z.literal(1000000000000)), 23 + numberUint8: z.optional(z.literal(200)), 24 + numberUint16: z.optional(z.literal(50000)), 25 + numberUint32: z.optional(z.literal(3000000000)), 26 + numberUint64: z.optional(z.literal(18000000000000000000)), 27 + integerInt8: z.optional(z.literal(-100)), 28 + integerInt16: z.optional(z.literal(-1000)), 29 + integerInt32: z.optional(z.literal(-100000)), 30 + integerInt64: z.optional(z.literal(-1000000000000)), 31 + integerUint8: z.optional(z.literal(255)), 32 + integerUint16: z.optional(z.literal(65535)), 33 + integerUint32: z.optional(z.literal(4294967295)), 34 + integerUint64: z.optional(z.int()), 35 + stringInt64: z.optional(z.literal('-9223372036854775808')), 36 + stringUint64: z.optional(z.literal('18446744073709551615')) 19 37 });
+19 -1
packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts
··· 15 15 z.literal(true) 16 16 ]).optional(), 17 17 corge: z.object({}).optional(), 18 - garply: z.coerce.bigint().optional() 18 + garply: z.coerce.bigint().optional(), 19 + numberInt8: z.literal(100).optional(), 20 + numberInt16: z.literal(1000).optional(), 21 + numberInt32: z.literal(100000).optional(), 22 + numberInt64: z.literal(1000000000000).optional(), 23 + numberUint8: z.literal(200).optional(), 24 + numberUint16: z.literal(50000).optional(), 25 + numberUint32: z.literal(3000000000).optional(), 26 + numberUint64: z.literal(18000000000000000000).optional(), 27 + integerInt8: z.literal(-100).optional(), 28 + integerInt16: z.literal(-1000).optional(), 29 + integerInt32: z.literal(-100000).optional(), 30 + integerInt64: z.literal(-1000000000000).optional(), 31 + integerUint8: z.literal(255).optional(), 32 + integerUint16: z.literal(65535).optional(), 33 + integerUint32: z.literal(4294967295).optional(), 34 + integerUint64: z.number().int().optional(), 35 + stringInt64: z.literal('-9223372036854775808').optional(), 36 + stringUint64: z.literal('18446744073709551615').optional() 19 37 });
+19 -1
packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts
··· 15 15 z.literal(true) 16 16 ])), 17 17 corge: z.optional(z.object({})), 18 - garply: z.optional(z.coerce.bigint()) 18 + garply: z.optional(z.coerce.bigint()), 19 + numberInt8: z.optional(z.literal(100)), 20 + numberInt16: z.optional(z.literal(1000)), 21 + numberInt32: z.optional(z.literal(100000)), 22 + numberInt64: z.optional(z.literal(1000000000000)), 23 + numberUint8: z.optional(z.literal(200)), 24 + numberUint16: z.optional(z.literal(50000)), 25 + numberUint32: z.optional(z.literal(3000000000)), 26 + numberUint64: z.optional(z.literal(18000000000000000000)), 27 + integerInt8: z.optional(z.literal(-100)), 28 + integerInt16: z.optional(z.literal(-1000)), 29 + integerInt32: z.optional(z.literal(-100000)), 30 + integerInt64: z.optional(z.literal(-1000000000000)), 31 + integerUint8: z.optional(z.literal(255)), 32 + integerUint16: z.optional(z.literal(65535)), 33 + integerUint32: z.optional(z.literal(4294967295)), 34 + integerUint64: z.optional(z.int()), 35 + stringInt64: z.optional(z.literal('-9223372036854775808')), 36 + stringUint64: z.optional(z.literal('18446744073709551615')) 19 37 });
+19 -1
packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts
··· 15 15 z.literal(true) 16 16 ])), 17 17 corge: z.optional(z.object({})), 18 - garply: z.optional(z.coerce.bigint()) 18 + garply: z.optional(z.coerce.bigint()), 19 + numberInt8: z.optional(z.literal(100)), 20 + numberInt16: z.optional(z.literal(1000)), 21 + numberInt32: z.optional(z.literal(100000)), 22 + numberInt64: z.optional(z.literal(1000000000000)), 23 + numberUint8: z.optional(z.literal(200)), 24 + numberUint16: z.optional(z.literal(50000)), 25 + numberUint32: z.optional(z.literal(3000000000)), 26 + numberUint64: z.optional(z.literal(18000000000000000000)), 27 + integerInt8: z.optional(z.literal(-100)), 28 + integerInt16: z.optional(z.literal(-1000)), 29 + integerInt32: z.optional(z.literal(-100000)), 30 + integerInt64: z.optional(z.literal(-1000000000000)), 31 + integerUint8: z.optional(z.literal(255)), 32 + integerUint16: z.optional(z.literal(65535)), 33 + integerUint32: z.optional(z.literal(4294967295)), 34 + integerUint64: z.optional(z.int()), 35 + stringInt64: z.optional(z.literal('-9223372036854775808')), 36 + stringUint64: z.optional(z.literal('18446744073709551615')) 19 37 });
+19 -1
packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts
··· 15 15 z.literal(true) 16 16 ]).optional(), 17 17 corge: z.object({}).optional(), 18 - garply: z.coerce.bigint().optional() 18 + garply: z.coerce.bigint().optional(), 19 + numberInt8: z.literal(100).optional(), 20 + numberInt16: z.literal(1000).optional(), 21 + numberInt32: z.literal(100000).optional(), 22 + numberInt64: z.literal(1000000000000).optional(), 23 + numberUint8: z.literal(200).optional(), 24 + numberUint16: z.literal(50000).optional(), 25 + numberUint32: z.literal(3000000000).optional(), 26 + numberUint64: z.literal(18000000000000000000).optional(), 27 + integerInt8: z.literal(-100).optional(), 28 + integerInt16: z.literal(-1000).optional(), 29 + integerInt32: z.literal(-100000).optional(), 30 + integerInt64: z.literal(-1000000000000).optional(), 31 + integerUint8: z.literal(255).optional(), 32 + integerUint16: z.literal(65535).optional(), 33 + integerUint32: z.literal(4294967295).optional(), 34 + integerUint64: z.number().int().optional(), 35 + stringInt64: z.literal('-9223372036854775808').optional(), 36 + stringUint64: z.literal('18446744073709551615').optional() 19 37 });
+19 -1
packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts
··· 15 15 z.literal(true) 16 16 ])), 17 17 corge: z.optional(z.object({})), 18 - garply: z.optional(z.coerce.bigint()) 18 + garply: z.optional(z.coerce.bigint()), 19 + numberInt8: z.optional(z.literal(100)), 20 + numberInt16: z.optional(z.literal(1000)), 21 + numberInt32: z.optional(z.literal(100000)), 22 + numberInt64: z.optional(z.literal(1000000000000)), 23 + numberUint8: z.optional(z.literal(200)), 24 + numberUint16: z.optional(z.literal(50000)), 25 + numberUint32: z.optional(z.literal(3000000000)), 26 + numberUint64: z.optional(z.literal(18000000000000000000)), 27 + integerInt8: z.optional(z.literal(-100)), 28 + integerInt16: z.optional(z.literal(-1000)), 29 + integerInt32: z.optional(z.literal(-100000)), 30 + integerInt64: z.optional(z.literal(-1000000000000)), 31 + integerUint8: z.optional(z.literal(255)), 32 + integerUint16: z.optional(z.literal(65535)), 33 + integerUint32: z.optional(z.literal(4294967295)), 34 + integerUint64: z.optional(z.int()), 35 + stringInt64: z.optional(z.literal('-9223372036854775808')), 36 + stringUint64: z.optional(z.literal('18446744073709551615')) 19 37 });
+95
packages/openapi-ts/src/plugins/valibot/number-helpers.ts
··· 1 + import { compiler } from '../../compiler'; 2 + 3 + // Integer format ranges and properties 4 + export const INTEGER_FORMATS = { 5 + int16: { 6 + max: 32767, 7 + maxError: 'Invalid value: Expected int16 to be <= 2^15-1', 8 + min: -32768, 9 + minError: 'Invalid value: Expected int16 to be >= -2^15', 10 + needsBigInt: false, 11 + }, 12 + int32: { 13 + max: 2147483647, 14 + maxError: 'Invalid value: Expected int32 to be <= 2^31-1', 15 + min: -2147483648, 16 + minError: 'Invalid value: Expected int32 to be >= -2^31', 17 + needsBigInt: false, 18 + }, 19 + int64: { 20 + max: '9223372036854775807', 21 + maxError: 'Invalid value: Expected int64 to be <= 2^63-1', 22 + min: '-9223372036854775808', 23 + minError: 'Invalid value: Expected int64 to be >= -2^63', 24 + needsBigInt: true, 25 + }, 26 + int8: { 27 + max: 127, 28 + maxError: 'Invalid value: Expected int8 to be <= 2^7-1', 29 + min: -128, 30 + minError: 'Invalid value: Expected int8 to be >= -2^7', 31 + needsBigInt: false, 32 + }, 33 + uint16: { 34 + max: 65535, 35 + maxError: 'Invalid value: Expected uint16 to be <= 2^16-1', 36 + min: 0, 37 + minError: 'Invalid value: Expected uint16 to be >= 0', 38 + needsBigInt: false, 39 + }, 40 + uint32: { 41 + max: 4294967295, 42 + maxError: 'Invalid value: Expected uint32 to be <= 2^32-1', 43 + min: 0, 44 + minError: 'Invalid value: Expected uint32 to be >= 0', 45 + needsBigInt: false, 46 + }, 47 + uint64: { 48 + max: '18446744073709551615', 49 + maxError: 'Invalid value: Expected uint64 to be <= 2^64-1', 50 + min: '0', 51 + minError: 'Invalid value: Expected uint64 to be >= 0', 52 + needsBigInt: true, 53 + }, 54 + uint8: { 55 + max: 255, 56 + maxError: 'Invalid value: Expected uint8 to be <= 2^8-1', 57 + min: 0, 58 + minError: 'Invalid value: Expected uint8 to be >= 0', 59 + needsBigInt: false, 60 + }, 61 + } as const; 62 + 63 + export type IntegerFormat = keyof typeof INTEGER_FORMATS; 64 + 65 + export const isIntegerFormat = ( 66 + format: string | undefined, 67 + ): format is IntegerFormat => format !== undefined && format in INTEGER_FORMATS; 68 + 69 + export const needsBigIntForFormat = (format: string | undefined): boolean => 70 + isIntegerFormat(format) && INTEGER_FORMATS[format].needsBigInt; 71 + 72 + export const numberParameter = ({ 73 + isBigInt, 74 + value, 75 + }: { 76 + isBigInt: boolean; 77 + value: unknown; 78 + }) => { 79 + const expression = compiler.valueToExpression({ value }); 80 + 81 + if ( 82 + isBigInt && 83 + (typeof value === 'bigint' || 84 + typeof value === 'number' || 85 + typeof value === 'string' || 86 + typeof value === 'boolean') 87 + ) { 88 + return compiler.callExpression({ 89 + functionName: 'BigInt', 90 + parameters: [expression], 91 + }); 92 + } 93 + 94 + return expression; 95 + };
+177 -44
packages/openapi-ts/src/plugins/valibot/plugin.ts
··· 8 8 import { numberRegExp } from '../../utils/regexp'; 9 9 import { createSchemaComment } from '../shared/utils/schema'; 10 10 import { identifiers, valibotId } from './constants'; 11 + import { 12 + INTEGER_FORMATS, 13 + isIntegerFormat, 14 + needsBigIntForFormat, 15 + numberParameter, 16 + } from './number-helpers'; 11 17 import { operationToValibotSchema } from './operation'; 12 18 import type { ValibotPlugin } from './types'; 13 19 ··· 253 259 return expression; 254 260 }; 255 261 256 - const numberParameter = ({ 257 - isBigInt, 258 - value, 259 - }: { 260 - isBigInt: boolean; 261 - value: unknown; 262 - }) => { 263 - const expression = compiler.valueToExpression({ value }); 264 - 265 - if ( 266 - isBigInt && 267 - (typeof value === 'bigint' || 268 - typeof value === 'number' || 269 - typeof value === 'string' || 270 - typeof value === 'boolean') 271 - ) { 272 - return compiler.callExpression({ 273 - functionName: 'BigInt', 274 - parameters: [expression], 275 - }); 276 - } 277 - 278 - return expression; 279 - }; 280 - 281 262 const numberTypeToValibotSchema = ({ 282 263 schema, 283 264 }: { 284 265 schema: SchemaWithType<'integer' | 'number'>; 285 266 }) => { 286 - const isBigInt = schema.type === 'integer' && schema.format === 'int64'; 267 + const format = schema.format; 268 + const isInteger = schema.type === 'integer'; 269 + const isBigInt = needsBigIntForFormat(format); 270 + const formatInfo = isIntegerFormat(format) ? INTEGER_FORMATS[format] : null; 271 + 272 + // Return early if const is defined since we can create a literal type directly without additional validation 273 + if (schema.const !== undefined && schema.const !== null) { 274 + const constValue = schema.const; 275 + let literalValue; 276 + 277 + // Case 1: Number with no format -> generate literal with the number 278 + if (typeof constValue === 'number' && !format) { 279 + literalValue = compiler.ots.number(constValue); 280 + } 281 + // Case 2: Number with format -> check if format needs BigInt, generate appropriate literal 282 + else if (typeof constValue === 'number' && format) { 283 + if (isBigInt) { 284 + // Format requires BigInt, convert number to BigInt 285 + literalValue = compiler.callExpression({ 286 + functionName: 'BigInt', 287 + parameters: [compiler.ots.string(constValue.toString())], 288 + }); 289 + } else { 290 + // Regular format, use number as-is 291 + literalValue = compiler.ots.number(constValue); 292 + } 293 + } 294 + // Case 3: Format that allows string -> generate BigInt literal (for int64/uint64 formats) 295 + else if (typeof constValue === 'string' && isBigInt) { 296 + // Remove 'n' suffix if present in string 297 + const cleanString = constValue.endsWith('n') 298 + ? constValue.slice(0, -1) 299 + : constValue; 300 + literalValue = compiler.callExpression({ 301 + functionName: 'BigInt', 302 + parameters: [compiler.ots.string(cleanString)], 303 + }); 304 + } 305 + // Case 4: Const is typeof bigint (literal) -> transform from literal to BigInt() 306 + else if (typeof constValue === 'bigint') { 307 + // Convert BigInt to string and remove 'n' suffix that toString() adds 308 + const bigintString = constValue.toString(); 309 + const cleanString = bigintString.endsWith('n') 310 + ? bigintString.slice(0, -1) 311 + : bigintString; 312 + literalValue = compiler.callExpression({ 313 + functionName: 'BigInt', 314 + parameters: [compiler.ots.string(cleanString)], 315 + }); 316 + } 317 + // Default case: use value as-is for other types 318 + else { 319 + literalValue = compiler.valueToExpression({ value: constValue }); 320 + } 287 321 288 - if (typeof schema.const === 'number') { 289 - // TODO: parser - handle bigint constants 290 - const expression = compiler.callExpression({ 322 + return compiler.callExpression({ 291 323 functionName: compiler.propertyAccessExpression({ 292 324 expression: identifiers.v, 293 325 name: identifiers.schemas.literal, 294 326 }), 295 - parameters: [compiler.ots.number(schema.const)], 327 + parameters: [literalValue], 296 328 }); 297 - return expression; 298 329 } 299 330 300 331 const pipes: Array<ts.CallExpression> = []; 301 332 302 - // Zod uses coerce for bigint here, might be needed for Valibot too 303 - const expression = compiler.callExpression({ 304 - functionName: isBigInt 305 - ? compiler.propertyAccessExpression({ 306 - expression: identifiers.v, 307 - name: identifiers.schemas.bigInt, 308 - }) 309 - : compiler.propertyAccessExpression({ 310 - expression: identifiers.v, 311 - name: identifiers.schemas.number, 333 + // For bigint formats (int64, uint64), create union of number, string, and bigint with transform 334 + if (isBigInt) { 335 + const unionExpression = compiler.callExpression({ 336 + functionName: compiler.propertyAccessExpression({ 337 + expression: identifiers.v, 338 + name: identifiers.schemas.union, 339 + }), 340 + parameters: [ 341 + compiler.arrayLiteralExpression({ 342 + elements: [ 343 + compiler.callExpression({ 344 + functionName: compiler.propertyAccessExpression({ 345 + expression: identifiers.v, 346 + name: identifiers.schemas.number, 347 + }), 348 + }), 349 + compiler.callExpression({ 350 + functionName: compiler.propertyAccessExpression({ 351 + expression: identifiers.v, 352 + name: identifiers.schemas.string, 353 + }), 354 + }), 355 + compiler.callExpression({ 356 + functionName: compiler.propertyAccessExpression({ 357 + expression: identifiers.v, 358 + name: identifiers.schemas.bigInt, 359 + }), 360 + }), 361 + ], 362 + multiLine: false, 312 363 }), 313 - }); 314 - pipes.push(expression); 364 + ], 365 + }); 366 + pipes.push(unionExpression); 315 367 316 - if (!isBigInt && schema.type === 'integer') { 368 + // Add transform to convert to BigInt 369 + const transformExpression = compiler.callExpression({ 370 + functionName: compiler.propertyAccessExpression({ 371 + expression: identifiers.v, 372 + name: identifiers.actions.transform, 373 + }), 374 + parameters: [ 375 + compiler.arrowFunction({ 376 + parameters: [{ name: 'x' }], 377 + statements: compiler.callExpression({ 378 + functionName: 'BigInt', 379 + parameters: [compiler.identifier({ text: 'x' })], 380 + }), 381 + }), 382 + ], 383 + }); 384 + pipes.push(transformExpression); 385 + } else { 386 + // For regular number formats, use number schema 387 + const expression = compiler.callExpression({ 388 + functionName: compiler.propertyAccessExpression({ 389 + expression: identifiers.v, 390 + name: identifiers.schemas.number, 391 + }), 392 + }); 393 + pipes.push(expression); 394 + } 395 + 396 + // Add integer validation for integer types (except when using bigint union) 397 + if (!isBigInt && isInteger) { 317 398 const expression = compiler.callExpression({ 318 399 functionName: compiler.propertyAccessExpression({ 319 400 expression: identifiers.v, ··· 321 402 }), 322 403 }); 323 404 pipes.push(expression); 405 + } 406 + 407 + // Add format-specific range validations 408 + if (formatInfo) { 409 + const minValue = formatInfo.min; 410 + const maxValue = formatInfo.max; 411 + const minErrorMessage = formatInfo.minError; 412 + const maxErrorMessage = formatInfo.maxError; 413 + 414 + // Add minimum value validation 415 + const minExpression = compiler.callExpression({ 416 + functionName: compiler.propertyAccessExpression({ 417 + expression: identifiers.v, 418 + name: identifiers.actions.minValue, 419 + }), 420 + parameters: [ 421 + isBigInt 422 + ? compiler.callExpression({ 423 + functionName: 'BigInt', 424 + parameters: [compiler.ots.string(minValue.toString())], 425 + }) 426 + : compiler.ots.number(minValue as number), 427 + compiler.ots.string(minErrorMessage), 428 + ], 429 + }); 430 + pipes.push(minExpression); 431 + 432 + // Add maximum value validation 433 + const maxExpression = compiler.callExpression({ 434 + functionName: compiler.propertyAccessExpression({ 435 + expression: identifiers.v, 436 + name: identifiers.actions.maxValue, 437 + }), 438 + parameters: [ 439 + isBigInt 440 + ? compiler.callExpression({ 441 + functionName: 'BigInt', 442 + parameters: [compiler.ots.string(maxValue.toString())], 443 + }) 444 + : compiler.ots.number(maxValue as number), 445 + compiler.ots.string(maxErrorMessage), 446 + ], 447 + }); 448 + pipes.push(maxExpression); 324 449 } 325 450 326 451 if (schema.exclusiveMinimum !== undefined) { ··· 763 888 state, 764 889 }); 765 890 case 'string': 891 + // For string schemas with int64/uint64 formats, use number handler to generate union with transform 892 + if (schema.format === 'int64' || schema.format === 'uint64') { 893 + return { 894 + expression: numberTypeToValibotSchema({ 895 + schema: schema as SchemaWithType<'integer' | 'number'>, 896 + }), 897 + }; 898 + } 766 899 return { 767 900 expression: stringTypeToValibotSchema({ 768 901 schema: schema as SchemaWithType<'string'>,