From 4ed592b64b062c5fc24207800cc49810bb1a490d Mon Sep 17 00:00:00 2001 From: Daschi Date: Wed, 23 Jul 2025 14:23:33 +0200 Subject: [PATCH 01/10] test: add valibot numberTypeToValibotSchema tests --- .../const-values.json | 120 ++ .../numberTypeToValibotSchema/formats.json | 89 ++ .../min-max-constraints.json | 179 +++ .../test/plugins/valibot/test-helper.ts | 211 +++ .../const-values.test.ts | 358 +++++ .../numberTypeToValibotSchema/formats.test.ts | 634 +++++++++ .../min-max-constraints.test.ts | 1245 +++++++++++++++++ 7 files changed, 2836 insertions(+) create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/test-helper.ts create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts create mode 100644 packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts diff --git a/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json b/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json new file mode 100644 index 0000000000..f9d1f71982 --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json @@ -0,0 +1,120 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Number Type Const Values Test API", + "version": "1.0.0" + }, + "paths": {}, + "components": { + "schemas": { + "NumberNoFormat": { + "type": "number", + "const": 42.5 + }, + "IntegerNoFormat": { + "type": "integer", + "const": -1 + }, + "NumberInt8": { + "type": "number", + "format": "int8", + "const": 100 + }, + "NumberInt16": { + "type": "number", + "format": "int16", + "const": 1000 + }, + "NumberInt32": { + "type": "number", + "format": "int32", + "const": 100000 + }, + "NumberInt64": { + "type": "number", + "format": "int64", + "const": 1000000000000 + }, + "NumberUint8": { + "type": "number", + "format": "uint8", + "const": 200 + }, + "NumberUint16": { + "type": "number", + "format": "uint16", + "const": 50000 + }, + "NumberUint32": { + "type": "number", + "format": "uint32", + "const": 3000000000 + }, + "NumberUint64": { + "type": "number", + "format": "uint64", + "const": 18000000000000000000 + }, + "IntegerInt8": { + "type": "integer", + "format": "int8", + "const": -100 + }, + "IntegerInt16": { + "type": "integer", + "format": "int16", + "const": -1000 + }, + "IntegerInt32": { + "type": "integer", + "format": "int32", + "const": -100000 + }, + "IntegerInt64": { + "type": "integer", + "format": "int64", + "const": -1000000000000 + }, + "IntegerUint8": { + "type": "integer", + "format": "uint8", + "const": 255 + }, + "IntegerUint16": { + "type": "integer", + "format": "uint16", + "const": 65535 + }, + "IntegerUint32": { + "type": "integer", + "format": "uint32", + "const": 4294967295 + }, + "IntegerUint64": { + "type": "integer", + "format": "uint64", + "const": 1000000000000 + }, + "StringInt64": { + "type": "string", + "format": "int64", + "const": "-9223372036854775808" + }, + "StringUint64": { + "type": "string", + "format": "uint64", + "const": "18446744073709551615" + }, + "StringInt64n": { + "type": "string", + "format": "int64", + "const": "-9223372036854775808n" + }, + "StringUint64n": { + "type": "string", + "format": "uint64", + "const": "18446744073709551615n" + } + } + } +} diff --git a/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json b/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json new file mode 100644 index 0000000000..f35e865d7b --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json @@ -0,0 +1,89 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Integer Formats Test", + "version": "1.0.0" + }, + "components": { + "schemas": { + "NumberNoFormat": { + "type": "number" + }, + "NumberInt8": { + "type": "number", + "format": "int8" + }, + "NumberInt16": { + "type": "number", + "format": "int16" + }, + "NumberInt32": { + "type": "number", + "format": "int32" + }, + "NumberInt64": { + "type": "number", + "format": "int64" + }, + "NumberUint8": { + "type": "number", + "format": "uint8" + }, + "NumberUint16": { + "type": "number", + "format": "uint16" + }, + "NumberUint32": { + "type": "number", + "format": "uint32" + }, + "NumberUint64": { + "type": "number", + "format": "uint64" + }, + "IntegerNoFormat": { + "type": "integer" + }, + "IntegerInt8": { + "type": "integer", + "format": "int8" + }, + "IntegerInt16": { + "type": "integer", + "format": "int16" + }, + "IntegerInt32": { + "type": "integer", + "format": "int32" + }, + "IntegerInt64": { + "type": "integer", + "format": "int64" + }, + "IntegerUint8": { + "type": "integer", + "format": "uint8" + }, + "IntegerUint16": { + "type": "integer", + "format": "uint16" + }, + "IntegerUint32": { + "type": "integer", + "format": "uint32" + }, + "IntegerUint64": { + "type": "integer", + "format": "uint64" + }, + "StringInt64": { + "type": "string", + "format": "int64" + }, + "StringUint64": { + "type": "string", + "format": "uint64" + } + } + } +} diff --git a/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json b/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json new file mode 100644 index 0000000000..f35c61af71 --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json @@ -0,0 +1,179 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Number Type Min/Max Constraints Test API", + "version": "1.0.0" + }, + "paths": {}, + "components": { + "schemas": { + "NumberWithMinimum": { + "type": "number", + "minimum": 10 + }, + "NumberWithMaximum": { + "type": "number", + "maximum": 100 + }, + "NumberWithMinMax": { + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "IntegerWithMinimum": { + "type": "integer", + "minimum": 5 + }, + "IntegerWithMaximum": { + "type": "integer", + "maximum": 999 + }, + "IntegerWithMinMax": { + "type": "integer", + "minimum": 1, + "maximum": 999 + }, + "NumberWithExclusiveMin": { + "type": "number", + "exclusiveMinimum": 0 + }, + "NumberWithExclusiveMax": { + "type": "number", + "exclusiveMaximum": 100 + }, + "NumberWithExclusiveMinMax": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1 + }, + "IntegerWithExclusiveMin": { + "type": "integer", + "exclusiveMinimum": 10 + }, + "IntegerWithExclusiveMax": { + "type": "integer", + "exclusiveMaximum": 50 + }, + "IntegerWithExclusiveMinMax": { + "type": "integer", + "exclusiveMinimum": 5, + "exclusiveMaximum": 15 + }, + "NumberWithExclusiveMinInclusiveMax": { + "type": "number", + "exclusiveMinimum": 10, + "maximum": 90 + }, + "NumberWithInclusiveMinExclusiveMax": { + "type": "number", + "minimum": 20, + "exclusiveMaximum": 80 + }, + "IntegerWithExclusiveMinInclusiveMax": { + "type": "integer", + "exclusiveMinimum": 5, + "maximum": 50 + }, + "IntegerWithInclusiveMinExclusiveMax": { + "type": "integer", + "minimum": 10, + "exclusiveMaximum": 100 + }, + "Int64WithMinimum": { + "type": "integer", + "format": "int64", + "minimum": -5000000000000 + }, + "Int64WithMaximum": { + "type": "integer", + "format": "int64", + "maximum": 5000000000000 + }, + "Int64WithMinMax": { + "type": "integer", + "format": "int64", + "minimum": -4000000000000, + "maximum": 4000000000000 + }, + "Int64WithExclusiveMin": { + "type": "integer", + "format": "int64", + "exclusiveMinimum": -3000000000000 + }, + "Int64WithExclusiveMax": { + "type": "integer", + "format": "int64", + "exclusiveMaximum": 3000000000000 + }, + "Int64WithExclusiveMinMax": { + "type": "integer", + "format": "int64", + "exclusiveMinimum": -2000000000000, + "exclusiveMaximum": 2000000000000 + }, + "Int64WithExclusiveMinInclusiveMax": { + "type": "integer", + "format": "int64", + "exclusiveMinimum": -6000000000000, + "maximum": 6000000000000 + }, + "Int64WithInclusiveMinExclusiveMax": { + "type": "integer", + "format": "int64", + "minimum": -7000000000000, + "exclusiveMaximum": 7000000000000 + }, + "UInt64WithMinimum": { + "type": "integer", + "format": "uint64", + "minimum": 5000000000000 + }, + "UInt64WithMaximum": { + "type": "integer", + "format": "uint64", + "maximum": 15000000000000 + }, + "UInt64WithMinMax": { + "type": "integer", + "format": "uint64", + "minimum": 1000000000000, + "maximum": 10000000000000 + }, + "UInt64WithExclusiveMin": { + "type": "integer", + "format": "uint64", + "exclusiveMinimum": 8000000000000 + }, + "UInt64WithExclusiveMax": { + "type": "integer", + "format": "uint64", + "exclusiveMaximum": 12000000000000 + }, + "UInt64WithExclusiveMinMax": { + "type": "integer", + "format": "uint64", + "exclusiveMinimum": 2000000000000, + "exclusiveMaximum": 8000000000000 + }, + "UInt64WithExclusiveMinInclusiveMax": { + "type": "integer", + "format": "uint64", + "exclusiveMinimum": 3000000000000, + "maximum": 13000000000000 + }, + "UInt64WithInclusiveMinExclusiveMax": { + "type": "integer", + "format": "uint64", + "minimum": 4000000000000, + "exclusiveMaximum": 14000000000000 + }, + "PrecedenceTest": { + "type": "number", + "minimum": 10, + "maximum": 90, + "exclusiveMinimum": 5, + "exclusiveMaximum": 95 + } + } + } +} diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test-helper.ts b/packages/openapi-ts-tests/test/plugins/valibot/test-helper.ts new file mode 100644 index 0000000000..4c513d909d --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/test-helper.ts @@ -0,0 +1,211 @@ +/** + * Test helper for Valibot plugin tests + * Provides common functionality for schema generation and loading + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +import { createClient } from '@hey-api/openapi-ts'; +import * as v from 'valibot'; + +/** + * Detect test name from the calling file + */ +function detectTestName(): string { + const stack = new Error().stack; + if (!stack) { + throw new Error('Unable to detect test name: no stack trace available'); + } + + // Find the first stack frame that contains a .test.ts file + const testFileMatch = stack.match(/([^\\/]+)\.test\.ts/); + if (!testFileMatch || !testFileMatch[1]) { + throw new Error( + 'Unable to detect test name: no .test.ts file found in stack trace', + ); + } + + return testFileMatch[1]; +} + +/** + * Detect base directory from the calling file + */ +function detectBaseDir(): string { + const stack = new Error().stack; + if (!stack) { + throw new Error( + 'Unable to detect base directory: no stack trace available', + ); + } + + // Try multiple regex patterns to match different stack trace formats + const patterns = [ + /at .* \(([^)]+\.test\.ts):\d+:\d+\)/, // Original pattern + /at ([^:]+\.test\.ts):\d+:\d+/, // Alternative pattern without parentheses + /([^:\s]+\.test\.ts):\d+:\d+/, // Simple pattern + ]; + + for (const pattern of patterns) { + const testFileMatch = stack.match(pattern); + if (testFileMatch && testFileMatch[1]) { + return path.dirname(testFileMatch[1]); + } + } + + throw new Error( + 'Unable to detect base directory: no .test.ts file found in stack trace', + ); +} + +/** + * Detect function name from the test file path + * Extracts the directory name between 'test/' and the test file + * e.g., from 'test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts' + * extracts 'numberTypeToValibotSchema' + */ +function detectFunctionName(): string { + const stack = new Error().stack; + if (!stack) { + throw new Error('Unable to detect function name: no stack trace available'); + } + + // Try multiple regex patterns to match different stack trace formats + const patterns = [ + /at .* \(([^)]+\.test\.ts):\d+:\d+\)/, // Original pattern + /at ([^:]+\.test\.ts):\d+:\d+/, // Alternative pattern without parentheses + /([^:\s]+\.test\.ts):\d+:\d+/, // Simple pattern + ]; + + for (const pattern of patterns) { + const testFileMatch = stack.match(pattern); + if (testFileMatch && testFileMatch[1]) { + const testFilePath = testFileMatch[1]; + + // Extract function name from path pattern: .../test/[FUNCTION_NAME]/[TEST_NAME].test.ts + const pathParts = testFilePath.split(/[/\\]/); + const testIndex = pathParts.lastIndexOf('test'); + + if (testIndex !== -1 && testIndex < pathParts.length - 2) { + const functionName = pathParts[testIndex + 1]; + if (functionName) { + return functionName; + } + } + + throw new Error( + `Unable to extract function name from test path: ${testFilePath}\n` + + `Expected path pattern: .../test/[FUNCTION_NAME]/[TEST_NAME].test.ts`, + ); + } + } + + throw new Error( + 'Unable to detect function name: no .test.ts file found in stack trace', + ); +} + +/** + * Load and evaluate the generated schemas + */ +function loadGeneratedSchemas(generatedPath: string): any { + if (!fs.existsSync(generatedPath)) { + throw new Error( + `Generated schema file not found: ${generatedPath}\n` + + `Schema generation may have failed. Check the input schema file for errors.`, + ); + } + + try { + const generatedCode = fs.readFileSync(generatedPath, 'utf-8'); + + // Extract all export statements and create a proper return object + const exportMatches = generatedCode.match(/export const (\w+)/g); + if (!exportMatches) { + // noinspection ExceptionCaughtLocallyJS + throw new Error('No exported schemas found in generated code'); + } + + // Create evaluation code that returns an object with all exports + const schemaNames = exportMatches.map((match: string) => + match.replace('export const ', ''), + ); + const evalCode = + generatedCode + .replace(/import \* as v from 'valibot';/, '') + .replace(/export const/g, 'const') + .replace(/v\./g, 'vModule.') + + `\n\nreturn { ${schemaNames.join(', ')} };`; + + // Wrap in a function to capture the return value + const schemaFunction = new Function('vModule', evalCode); + return schemaFunction(v); + } catch (error) { + throw new Error( + `Failed to load generated schemas from ${generatedPath}: ${error instanceof Error ? error.message : String(error)}\n` + + `The generated file may contain syntax errors or be malformed.`, + ); + } +} + +/** + * Setup function for Valibot tests + * Automatically detects test name and paths, generates schemas, and returns them + */ +export async function setupValibotTest(): Promise { + // Detect test name, function name, and base directory from calling file + const testName = detectTestName(); + const functionName = detectFunctionName(); + const baseDir = detectBaseDir(); + + // Construct paths dynamically based on detected function name + const schemaPath = path.join( + baseDir, + '..', + '..', + 'spec', + functionName, + `${testName}.json`, + ); + const outputPath = path.join( + baseDir, + '..', + '..', + 'generated', + functionName, + testName, + ); + + // Check if spec file exists + if (!fs.existsSync(schemaPath)) { + throw new Error( + `Schema file not found: ${schemaPath}\n` + + `Expected schema file for test '${testName}' in function '${functionName}' at the above location.\n` + + `Please ensure the spec file exists and matches the test name.`, + ); + } + + try { + // Create output directory + fs.mkdirSync(outputPath, { recursive: true }); + + // Generate Valibot schemas + await createClient({ + input: schemaPath, + logs: { level: 'silent' }, + output: outputPath, + plugins: ['valibot'], + }); + + // Load and return the generated schemas + const generatedPath = path.join(outputPath, 'valibot.gen.ts'); + return loadGeneratedSchemas(generatedPath); + } catch (error) { + throw new Error( + `Failed to generate schemas for test '${testName}' in function '${functionName}': ${error instanceof Error ? error.message : String(error)}\n` + + `Schema path: ${schemaPath}\n` + + `Output path: ${outputPath}`, + ); + } +} diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts b/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts new file mode 100644 index 0000000000..72a1c826a9 --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts @@ -0,0 +1,358 @@ +import * as v from 'valibot'; +import { beforeAll, describe, expect, it } from 'vitest'; + +import { setupValibotTest } from '../../test-helper'; + +describe('Number Type Const Values Tests', () => { + let generatedSchemas: any; + + beforeAll(async () => { + generatedSchemas = await setupValibotTest(); + }); + + describe('Number Type Const Validation', () => { + it('should accept exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberNoFormat, 42.5); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(42.5); + } + }); + + it('should reject non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberNoFormat, 42.6); + expect(result.success).toBe(false); + }); + }); + + describe('Number Type Format Const Validation', () => { + it('should accept NumberInt8 exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberInt8, 100); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(100); + } + }); + + it('should reject NumberInt8 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberInt8, 101); + expect(result.success).toBe(false); + }); + + it('should accept NumberInt16 exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberInt16, 1000); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(1000); + } + }); + + it('should reject NumberInt16 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberInt16, 1001); + expect(result.success).toBe(false); + }); + + it('should accept NumberInt32 exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberInt32, 100000); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(100000); + } + }); + + it('should reject NumberInt32 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberInt32, 100001); + expect(result.success).toBe(false); + }); + + it('should accept NumberInt64 exact const value', () => { + const result = v.safeParse( + generatedSchemas.vNumberInt64, + BigInt('1000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('1000000000000')); + } + }); + + it('should reject NumberInt64 non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vNumberInt64, + BigInt('1000000000001'), + ); + expect(result.success).toBe(false); + }); + + it('should accept NumberUint8 exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberUint8, 200); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(200); + } + }); + + it('should reject NumberUint8 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint8, 201); + expect(result.success).toBe(false); + }); + + it('should accept NumberUint16 exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberUint16, 50000); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(50000); + } + }); + + it('should reject NumberUint16 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint16, 50001); + expect(result.success).toBe(false); + }); + + it('should accept NumberUint32 exact const value', () => { + const result = v.safeParse(generatedSchemas.vNumberUint32, 3000000000); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(3000000000); + } + }); + + it('should reject NumberUint32 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint32, 3000000001); + expect(result.success).toBe(false); + }); + + it('should accept NumberUint64 exact const value', () => { + const result = v.safeParse( + generatedSchemas.vNumberUint64, + BigInt('18000000000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('18000000000000000000')); + } + }); + + it('should reject NumberUint64 non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vNumberUint64, + BigInt('18000000000000000001'), + ); + expect(result.success).toBe(false); + }); + }); + + describe('Integer Type Const Validation', () => { + it('should accept exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, -1); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(-1); + } + }); + + it('should reject non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, 0); + expect(result.success).toBe(false); + }); + }); + + describe('Integer Type Format Const Validation', () => { + it('should accept IntegerInt8 exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt8, -100); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(-100); + } + }); + + it('should reject IntegerInt8 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt8, -99); + expect(result.success).toBe(false); + }); + + it('should accept IntegerInt16 exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt16, -1000); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(-1000); + } + }); + + it('should reject IntegerInt16 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt16, -999); + expect(result.success).toBe(false); + }); + + it('should accept IntegerInt32 exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt32, -100000); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(-100000); + } + }); + + it('should reject IntegerInt32 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt32, -99999); + expect(result.success).toBe(false); + }); + + it('should accept IntegerInt64 exact const value', () => { + const result = v.safeParse( + generatedSchemas.vIntegerInt64, + BigInt('-1000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-1000000000000')); + } + }); + + it('should reject IntegerInt64 non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vIntegerInt64, + BigInt('-999999999999'), + ); + expect(result.success).toBe(false); + }); + + it('should accept IntegerUint8 exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint8, 255); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(255); + } + }); + + it('should reject IntegerUint8 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint8, 254); + expect(result.success).toBe(false); + }); + + it('should accept IntegerUint16 exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint16, 65535); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(65535); + } + }); + + it('should reject IntegerUint16 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint16, 65534); + expect(result.success).toBe(false); + }); + + it('should accept IntegerUint32 exact const value', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967295); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(4294967295); + } + }); + + it('should reject IntegerUint32 non-matching values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967294); + expect(result.success).toBe(false); + }); + + it('should accept IntegerUint64 exact const value', () => { + const result = v.safeParse( + generatedSchemas.vIntegerUint64, + BigInt('1000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('1000000000000')); + } + }); + + it('should reject IntegerUint64 non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vIntegerUint64, + BigInt('1000000000001'), + ); + expect(result.success).toBe(false); + }); + }); + + describe('String Type Format Const Validation', () => { + it('should accept StringInt64 exact const value', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64, + BigInt('-9223372036854775808'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-9223372036854775808')); + } + }); + + it('should reject StringInt64 non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64, + BigInt('-9223372036854775807'), + ); + expect(result.success).toBe(false); + }); + + it('should accept StringUint64 exact const value', () => { + const result = v.safeParse( + generatedSchemas.vStringUint64, + BigInt('18446744073709551615'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('18446744073709551615')); + } + }); + + it('should reject StringUint64 non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vStringUint64, + BigInt('18446744073709551614'), + ); + expect(result.success).toBe(false); + }); + }); + + describe('String Type Format Const Validation (BigInt Literal)', () => { + it('should accept StringInt64n exact const value', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64n, + BigInt('-9223372036854775808'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-9223372036854775808')); + } + }); + + it('should reject StringInt64n non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64n, + BigInt('-9223372036854775807'), + ); + expect(result.success).toBe(false); + }); + + it('should accept StringUint64n exact const value', () => { + const result = v.safeParse( + generatedSchemas.vStringUint64n, + BigInt('18446744073709551615'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('18446744073709551615')); + } + }); + + it('should reject StringUint64n non-matching values', () => { + const result = v.safeParse( + generatedSchemas.vStringUint64n, + BigInt('18446744073709551614'), + ); + expect(result.success).toBe(false); + }); + }); +}); diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts b/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts new file mode 100644 index 0000000000..c25de6925d --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts @@ -0,0 +1,634 @@ +import * as v from 'valibot'; +import { beforeAll, describe, expect, it } from 'vitest'; + +import { setupValibotTest } from '../../test-helper'; + +describe('Number Type Formats Tests', () => { + let generatedSchemas: any; + + beforeAll(async () => { + generatedSchemas = await setupValibotTest(); + }); + + // Format bounds and error messages from INTEGER_FORMATS + const FORMAT_BOUNDS = { + int16: { + max: 32767, + maxError: 'Expected int16 to be <= 2^15-1', + min: -32768, + minError: 'Expected int16 to be >= -2^15', + }, + int32: { + max: 2147483647, + maxError: 'Expected int32 to be <= 2^31-1', + min: -2147483648, + minError: 'Expected int32 to be >= -2^31', + }, + int64: { + max: '9223372036854775807', + maxError: 'Expected int64 to be <= 2^63-1', + min: '-9223372036854775808', + minError: 'Expected int64 to be >= -2^63', + }, + int8: { + max: 127, + maxError: 'Expected int8 to be <= 2^7-1', + min: -128, + minError: 'Expected int8 to be >= -2^7', + }, + uint16: { + max: 65535, + maxError: 'Expected uint16 to be <= 2^16-1', + min: 0, + minError: 'Expected uint16 to be >= 0', + }, + uint32: { + max: 4294967295, + maxError: 'Expected uint32 to be <= 2^32-1', + min: 0, + minError: 'Expected uint32 to be >= 0', + }, + uint64: { + max: '18446744073709551615', + maxError: 'Expected uint64 to be <= 2^64-1', + min: '0', + minError: 'Expected uint64 to be >= 0', + }, + uint8: { + max: 255, + maxError: 'Expected uint8 to be <= 2^8-1', + min: 0, + minError: 'Expected uint8 to be >= 0', + }, + }; + + describe('Number Type Format Validation', () => { + describe('numberNoFormat', () => { + it('should validate any number value', () => { + const result = v.safeParse(generatedSchemas.vNumberNoFormat, 123.456); + expect(result.success).toBe(true); + }); + }); + + describe('numberInt8', () => { + it('should validate values within int8 range', () => { + const result = v.safeParse(generatedSchemas.vNumberInt8, 100); + expect(result.success).toBe(true); + }); + + it('should reject values below int8 minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberInt8, -129); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int8.minError, + ); + } + }); + + it('should reject values above int8 maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberInt8, 128); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int8.maxError, + ); + } + }); + }); + + describe('numberInt16', () => { + it('should validate values within int16 range', () => { + const result = v.safeParse(generatedSchemas.vNumberInt16, 30000); + expect(result.success).toBe(true); + }); + + it('should reject values below int16 minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberInt16, -32769); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int16.minError, + ); + } + }); + + it('should reject values above int16 maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberInt16, 32768); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int16.maxError, + ); + } + }); + }); + + describe('numberInt32', () => { + it('should validate values within int32 range', () => { + const result = v.safeParse(generatedSchemas.vNumberInt32, 2000000000); + expect(result.success).toBe(true); + }); + + it('should reject values below int32 minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberInt32, -2147483649); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int32.minError, + ); + } + }); + + it('should reject values above int32 maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberInt32, 2147483648); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int32.maxError, + ); + } + }); + }); + + describe('numberInt64', () => { + it('should validate values within int64 range and convert to BigInt', () => { + const result = v.safeParse( + generatedSchemas.vNumberInt64, + 1000000000000, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should validate string values within int64 range', () => { + const result = v.safeParse( + generatedSchemas.vNumberInt64, + '1000000000000', + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should reject values above int64 maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberInt64, + '9223372036854775808', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int64.maxError, + ); + } + }); + }); + + describe('numberUint8', () => { + it('should validate values within uint8 range', () => { + const result = v.safeParse(generatedSchemas.vNumberUint8, 200); + expect(result.success).toBe(true); + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint8, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint8.minError, + ); + } + }); + + it('should reject values above uint8 maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberUint8, 256); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint8.maxError, + ); + } + }); + }); + + describe('numberUint16', () => { + it('should validate values within uint16 range', () => { + const result = v.safeParse(generatedSchemas.vNumberUint16, 60000); + expect(result.success).toBe(true); + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint16, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint16.minError, + ); + } + }); + + it('should reject values above uint16 maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberUint16, 65536); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint16.maxError, + ); + } + }); + }); + + describe('numberUint32', () => { + it('should validate values within uint32 range', () => { + const result = v.safeParse(generatedSchemas.vNumberUint32, 4000000000); + expect(result.success).toBe(true); + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint32, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint32.minError, + ); + } + }); + + it('should reject values above uint32 maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberUint32, 4294967296); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint32.maxError, + ); + } + }); + }); + + describe('numberUint64', () => { + it('should validate values within uint64 range and convert to BigInt', () => { + const result = v.safeParse( + generatedSchemas.vNumberUint64, + 1000000000000, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vNumberUint64, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint64.minError, + ); + } + }); + + it('should reject values above uint64 maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberUint64, + '18446744073709551616', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint64.maxError, + ); + } + }); + }); + }); + + describe('Integer Type Format Validation', () => { + describe('integerNoFormat', () => { + it('should validate any integer value', () => { + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, 123); + expect(result.success).toBe(true); + }); + + it('should reject non-integer values', () => { + const result = v.safeParse(generatedSchemas.vIntegerNoFormat, 123.456); + expect(result.success).toBe(false); + }); + }); + + describe('integerInt8', () => { + it('should validate values within int8 range', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt8, 100); + expect(result.success).toBe(true); + }); + + it('should reject values below int8 minimum', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt8, -129); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int8.minError, + ); + } + }); + + it('should reject values above int8 maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt8, 128); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int8.maxError, + ); + } + }); + }); + + describe('integerInt16', () => { + it('should validate values within int16 range', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt16, 30000); + expect(result.success).toBe(true); + }); + + it('should reject values below int16 minimum', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt16, -32769); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int16.minError, + ); + } + }); + + it('should reject values above int16 maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt16, 32768); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int16.maxError, + ); + } + }); + }); + + describe('integerInt32', () => { + it('should validate values within int32 range', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt32, 2000000000); + expect(result.success).toBe(true); + }); + + it('should reject values below int32 minimum', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt32, -2147483649); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int32.minError, + ); + } + }); + + it('should reject values above int32 maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerInt32, 2147483648); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int32.maxError, + ); + } + }); + }); + + describe('integerInt64', () => { + it('should validate values within int64 range and convert to BigInt', () => { + const result = v.safeParse( + generatedSchemas.vIntegerInt64, + 1000000000000, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should validate string values within int64 range', () => { + const result = v.safeParse( + generatedSchemas.vIntegerInt64, + '1000000000000', + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should reject values above int64 maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerInt64, + '9223372036854775808', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int64.maxError, + ); + } + }); + }); + + describe('integerUint8', () => { + it('should validate values within uint8 range', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint8, 200); + expect(result.success).toBe(true); + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint8, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint8.minError, + ); + } + }); + + it('should reject values above uint8 maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint8, 256); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint8.maxError, + ); + } + }); + }); + + describe('integerUint16', () => { + it('should validate values within uint16 range', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint16, 60000); + expect(result.success).toBe(true); + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint16, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint16.minError, + ); + } + }); + + it('should reject values above uint16 maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint16, 65536); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint16.maxError, + ); + } + }); + }); + + describe('integerUint32', () => { + it('should validate values within uint32 range', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4000000000); + expect(result.success).toBe(true); + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint32, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint32.minError, + ); + } + }); + + it('should reject values above uint32 maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967296); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint32.maxError, + ); + } + }); + }); + + describe('integerUint64', () => { + it('should validate values within uint64 range and convert to BigInt', () => { + const result = v.safeParse( + generatedSchemas.vIntegerUint64, + 1000000000000, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vIntegerUint64, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint64.minError, + ); + } + }); + + it('should reject values above uint64 maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerUint64, + '18446744073709551616', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint64.maxError, + ); + } + }); + }); + }); + + describe('String Type Format Validation', () => { + describe('stringInt64', () => { + it('should validate string values within int64 range and convert to BigInt', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64, + '1000000000000', + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should reject values below int64 minimum', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64, + '-9223372036854775809', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int64.minError, + ); + } + }); + + it('should reject values above int64 maximum', () => { + const result = v.safeParse( + generatedSchemas.vStringInt64, + '9223372036854775808', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.int64.maxError, + ); + } + }); + }); + + describe('stringUint64', () => { + it('should validate string values within uint64 range and convert to BigInt', () => { + const result = v.safeParse( + generatedSchemas.vStringUint64, + '1000000000000', + ); + expect(result.success).toBe(true); + if (result.success) { + expect(typeof result.output).toBe('bigint'); + } + }); + + it('should reject negative values', () => { + const result = v.safeParse(generatedSchemas.vStringUint64, '-1'); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint64.minError, + ); + } + }); + + it('should reject values above uint64 maximum', () => { + const result = v.safeParse( + generatedSchemas.vStringUint64, + '18446744073709551616', + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain( + FORMAT_BOUNDS.uint64.maxError, + ); + } + }); + }); + }); +}); diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts b/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts new file mode 100644 index 0000000000..f0471b7719 --- /dev/null +++ b/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts @@ -0,0 +1,1245 @@ +import * as v from 'valibot'; +import { beforeAll, describe, expect, it } from 'vitest'; + +import { setupValibotTest } from '../../test-helper'; + +describe('Number Type Min/Max Constraints Tests', () => { + let generatedSchemas: any; + + beforeAll(async () => { + generatedSchemas = await setupValibotTest(); + }); + + describe('Basic Number Constraints', () => { + describe('NumberWithMinimum', () => { + it('should accept values at minimum boundary', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 10); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(10); + } + }); + + it('should accept values above minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 15); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(15); + } + }); + + it('should reject values below minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 9); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('NumberWithMaximum', () => { + it('should accept values at maximum boundary', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 100); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(100); + } + }); + + it('should accept values below maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 50); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(50); + } + }); + + it('should reject values above maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 101); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('NumberWithMinMax', () => { + it('should accept values within range', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 50); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(50); + } + }); + + it('should accept values at minimum boundary', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 0); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(0); + } + }); + + it('should accept values at maximum boundary', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 100); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(100); + } + }); + + it('should reject values below minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, -1); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values above maximum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 101); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + }); + + describe('Basic Integer Constraints', () => { + describe('IntegerWithMinimum', () => { + it('should accept values at minimum boundary', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 5); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(5); + } + }); + + it('should accept values above minimum', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 10); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(10); + } + }); + + it('should reject values below minimum', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 4); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithMaximum', () => { + it('should accept values at maximum boundary', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 999); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(999); + } + }); + + it('should accept values below maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 500); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(500); + } + }); + + it('should reject values above maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 1000); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithMinMax', () => { + it('should accept values within range', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 500); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(500); + } + }); + + it('should accept values at minimum boundary', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 1); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(1); + } + }); + + it('should accept values at maximum boundary', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 999); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(999); + } + }); + + it('should reject values below minimum', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 0); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values above maximum', () => { + const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 1000); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + }); + + describe('Exclusive Constraints', () => { + describe('NumberWithExclusiveMin', () => { + it('should accept values above exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMin, + 0.1, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(0.1); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse(generatedSchemas.vNumberWithExclusiveMin, 0); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values below exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMin, + -1, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('NumberWithExclusiveMax', () => { + it('should accept values below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMax, + 99.9, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(99.9); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMax, + 100, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values above exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMax, + 101, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('NumberWithExclusiveMinMax', () => { + it('should accept values within exclusive range', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinMax, + 0.5, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(0.5); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinMax, + 0, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinMax, + 1, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithExclusiveMin', () => { + it('should accept values above exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMin, + 11, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(11); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMin, + 10, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values below exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMin, + 9, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithExclusiveMax', () => { + it('should accept values below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMax, + 49, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(49); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMax, + 50, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values above exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMax, + 51, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithExclusiveMinMax', () => { + it('should accept values within exclusive range', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinMax, + 10, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(10); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinMax, + 5, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinMax, + 15, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + }); + + describe('Mixed Constraints', () => { + describe('NumberWithExclusiveMinInclusiveMax', () => { + it('should accept values above exclusive minimum and at inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, + 90, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(90); + } + }); + + it('should accept values above exclusive minimum and below inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, + 50, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(50); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, + 10, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values above inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithExclusiveMinInclusiveMax, + 91, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('NumberWithInclusiveMinExclusiveMax', () => { + it('should accept values at inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, + 20, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(20); + } + }); + + it('should accept values above inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, + 50, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(50); + } + }); + + it('should reject values below inclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, + 19, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vNumberWithInclusiveMinExclusiveMax, + 80, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithExclusiveMinInclusiveMax', () => { + it('should accept values above exclusive minimum and at inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, + 50, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(50); + } + }); + + it('should accept values above exclusive minimum and below inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, + 25, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(25); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, + 5, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values above inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithExclusiveMinInclusiveMax, + 51, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + + describe('IntegerWithInclusiveMinExclusiveMax', () => { + it('should accept values at inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, + 10, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(10); + } + }); + + it('should accept values above inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, + 55, + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(55); + } + }); + + it('should reject values below inclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, + 9, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vIntegerWithInclusiveMinExclusiveMax, + 100, + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + }); + + describe('Format-Specific Constraints (Int64)', () => { + describe('Int64WithMinimum', () => { + it('should accept BigInt values at minimum boundary', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinimum, + BigInt('-5000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-5000000000000')); + } + }); + + it('should accept BigInt values above minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinimum, + BigInt('0'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('0')); + } + }); + + it('should reject BigInt values below minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinimum, + BigInt('-5000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithMaximum', () => { + it('should accept BigInt values at maximum boundary', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMaximum, + BigInt('5000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('5000000000000')); + } + }); + + it('should accept BigInt values below maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMaximum, + BigInt('1000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('1000000000000')); + } + }); + + it('should reject BigInt values above maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMaximum, + BigInt('5000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithMinMax', () => { + it('should accept BigInt values within range', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinMax, + BigInt('0'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('0')); + } + }); + + it('should accept BigInt values at minimum boundary', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinMax, + BigInt('-4000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-4000000000000')); + } + }); + + it('should accept BigInt values at maximum boundary', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinMax, + BigInt('4000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('4000000000000')); + } + }); + + it('should reject BigInt values below minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinMax, + BigInt('-4000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject BigInt values above maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithMinMax, + BigInt('4000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithExclusiveMin', () => { + it('should accept BigInt values above exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMin, + BigInt('-2999999999999'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-2999999999999')); + } + }); + + it('should reject BigInt values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMin, + BigInt('-3000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithExclusiveMax', () => { + it('should accept BigInt values below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMax, + BigInt('2999999999999'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('2999999999999')); + } + }); + + it('should reject BigInt values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMax, + BigInt('3000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithExclusiveMinMax', () => { + it('should accept BigInt values within exclusive range', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinMax, + BigInt('0'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('0')); + } + }); + + it('should reject BigInt values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinMax, + BigInt('-2000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject BigInt values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinMax, + BigInt('2000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithExclusiveMinInclusiveMax', () => { + it('should accept values above exclusive minimum and at inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, + BigInt('6000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('6000000000000')); + } + }); + + it('should accept values above exclusive minimum and below inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, + BigInt('0'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('0')); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, + BigInt('-6000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject values above inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithExclusiveMinInclusiveMax, + BigInt('6000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('Int64WithInclusiveMinExclusiveMax', () => { + it('should accept values at inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, + BigInt('-7000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('-7000000000000')); + } + }); + + it('should accept values above inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, + BigInt('0'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('0')); + } + }); + + it('should reject values below inclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, + BigInt('-7000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vInt64WithInclusiveMinExclusiveMax, + BigInt('7000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + }); + + describe('Format-Specific Constraints (UInt64)', () => { + describe('UInt64WithMinimum', () => { + it('should accept BigInt values at minimum boundary', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinimum, + BigInt('5000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('5000000000000')); + } + }); + + it('should accept BigInt values above minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinimum, + BigInt('8000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('8000000000000')); + } + }); + + it('should reject BigInt values below minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinimum, + BigInt('4999999999999'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithMaximum', () => { + it('should accept BigInt values at maximum boundary', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMaximum, + BigInt('15000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('15000000000000')); + } + }); + + it('should accept BigInt values below maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMaximum, + BigInt('10000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('10000000000000')); + } + }); + + it('should reject BigInt values above maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMaximum, + BigInt('15000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithMinMax', () => { + it('should accept BigInt values within range', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinMax, + BigInt('5000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('5000000000000')); + } + }); + + it('should accept BigInt values at minimum boundary', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinMax, + BigInt('1000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('1000000000000')); + } + }); + + it('should accept BigInt values at maximum boundary', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinMax, + BigInt('10000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('10000000000000')); + } + }); + + it('should reject BigInt values below minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinMax, + BigInt('999999999999'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject BigInt values above maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithMinMax, + BigInt('10000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithExclusiveMin', () => { + it('should accept BigInt values above exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMin, + BigInt('8000000000001'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('8000000000001')); + } + }); + + it('should reject BigInt values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMin, + BigInt('8000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithExclusiveMax', () => { + it('should accept BigInt values below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMax, + BigInt('11999999999999'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('11999999999999')); + } + }); + + it('should reject BigInt values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMax, + BigInt('12000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithExclusiveMinMax', () => { + it('should accept BigInt values within exclusive range', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinMax, + BigInt('5000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('5000000000000')); + } + }); + + it('should reject BigInt values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinMax, + BigInt('2000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject BigInt values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinMax, + BigInt('8000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithExclusiveMinInclusiveMax', () => { + it('should accept values above exclusive minimum and at inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, + BigInt('13000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('13000000000000')); + } + }); + + it('should accept values above exclusive minimum and below inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, + BigInt('8000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('8000000000000')); + } + }); + + it('should reject values at exclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, + BigInt('3000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject values above inclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithExclusiveMinInclusiveMax, + BigInt('13000000000001'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + + describe('UInt64WithInclusiveMinExclusiveMax', () => { + it('should accept values at inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, + BigInt('4000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('4000000000000')); + } + }); + + it('should accept values above inclusive minimum and below exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, + BigInt('9000000000000'), + ); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(BigInt('9000000000000')); + } + }); + + it('should reject values below inclusive minimum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, + BigInt('3999999999999'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + + it('should reject values at exclusive maximum', () => { + const result = v.safeParse( + generatedSchemas.vUInt64WithInclusiveMinExclusiveMax, + BigInt('14000000000000'), + ); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Expected'); + } + }); + }); + }); + + describe('Special Cases', () => { + describe('PrecedenceTest', () => { + it('should use exclusive constraints over inclusive (exclusive minimum takes precedence)', () => { + // exclusiveMinimum: 5, minimum: 10 - exclusive should take precedence + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 6); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(6); + } + }); + + it('should use exclusive constraints over inclusive (exclusive maximum takes precedence)', () => { + // exclusiveMaximum: 95, maximum: 90 - exclusive should take precedence + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 94); + expect(result.success).toBe(true); + if (result.success) { + expect(result.output).toBe(94); + } + }); + + it('should reject values at exclusive minimum boundary', () => { + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 5); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + + it('should reject values at exclusive maximum boundary', () => { + const result = v.safeParse(generatedSchemas.vPrecedenceTest, 95); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.issues[0].message).toContain('Invalid value: Expected'); + } + }); + }); + }); +}); From a0c909be184f81e19b892c32abe3bbd88f5c1c4d Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 08:08:40 +0200 Subject: [PATCH 02/10] feat(valibot): add integer format and BigInt handling and tests --- .../openapi-ts-tests/main/test/3.1.x.test.ts | 9 + .../const-values.json | 0 .../numberTypeToValibotSchema/formats.json | 0 .../min-max-constraints.json | 0 .../test/plugins/valibot/test-helper.ts | 0 .../const-values.test.ts | 0 .../numberTypeToValibotSchema/formats.test.ts | 0 .../min-max-constraints.test.ts | 0 .../specs/3.1.x/integer-formats.json | 94 +++++++ .../specs/3.1.x/schema-const.yaml | 75 +++++ .../openapi-ts/src/plugins/valibot/plugin.ts | 258 ++++++++++++++++-- 11 files changed, 417 insertions(+), 19 deletions(-) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json (100%) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json (100%) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json (100%) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/test-helper.ts (100%) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts (100%) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts (100%) rename packages/openapi-ts-tests/{ => main}/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts (100%) create mode 100644 packages/openapi-ts-tests/specs/3.1.x/integer-formats.json diff --git a/packages/openapi-ts-tests/main/test/3.1.x.test.ts b/packages/openapi-ts-tests/main/test/3.1.x.test.ts index 7203ce26a5..bdcfa5f9a0 100644 --- a/packages/openapi-ts-tests/main/test/3.1.x.test.ts +++ b/packages/openapi-ts-tests/main/test/3.1.x.test.ts @@ -798,6 +798,15 @@ describe(`OpenAPI ${version}`, () => { }), description: "validator schemas with merged unions (can't use .merge())", }, + { + config: createConfig({ + input: 'integer-formats.json', + output: 'integer-formats', + plugins: ['valibot'], + }), + description: + 'generates validator schemas for all integer format combinations (number/integer/string types with int8, int16, int32, int64, uint8, uint16, uint32, uint64 formats)', + }, ]; it.each(scenarios)('$description', async ({ config }) => { diff --git a/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json rename to packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json diff --git a/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json rename to packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json diff --git a/packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json rename to packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test-helper.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/test-helper.ts rename to packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts rename to packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts rename to packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts diff --git a/packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts similarity index 100% rename from packages/openapi-ts-tests/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts rename to packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts diff --git a/packages/openapi-ts-tests/specs/3.1.x/integer-formats.json b/packages/openapi-ts-tests/specs/3.1.x/integer-formats.json new file mode 100644 index 0000000000..2436e30fbf --- /dev/null +++ b/packages/openapi-ts-tests/specs/3.1.x/integer-formats.json @@ -0,0 +1,94 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Integer Formats Test", + "version": "1.0.0" + }, + "components": { + "schemas": { + "IntegerFormats": { + "type": "object", + "properties": { + "numberNoFormat": { + "type": "number" + }, + "numberInt8": { + "type": "number", + "format": "int8" + }, + "numberInt16": { + "type": "number", + "format": "int16" + }, + "numberInt32": { + "type": "number", + "format": "int32" + }, + "numberInt64": { + "type": "number", + "format": "int64" + }, + "numberUint8": { + "type": "number", + "format": "uint8" + }, + "numberUint16": { + "type": "number", + "format": "uint16" + }, + "numberUint32": { + "type": "number", + "format": "uint32" + }, + "numberUint64": { + "type": "number", + "format": "uint64" + }, + "integerNoFormat": { + "type": "integer" + }, + "integerInt8": { + "type": "integer", + "format": "int8" + }, + "integerInt16": { + "type": "integer", + "format": "int16" + }, + "integerInt32": { + "type": "integer", + "format": "int32" + }, + "integerInt64": { + "type": "integer", + "format": "int64" + }, + "integerUint8": { + "type": "integer", + "format": "uint8" + }, + "integerUint16": { + "type": "integer", + "format": "uint16" + }, + "integerUint32": { + "type": "integer", + "format": "uint32" + }, + "integerUint64": { + "type": "integer", + "format": "uint64" + }, + "stringInt64": { + "type": "string", + "format": "int64" + }, + "stringUint64": { + "type": "string", + "format": "uint64" + } + } + } + } + } +} diff --git a/packages/openapi-ts-tests/specs/3.1.x/schema-const.yaml b/packages/openapi-ts-tests/specs/3.1.x/schema-const.yaml index b7fc8e8282..0298bc5958 100644 --- a/packages/openapi-ts-tests/specs/3.1.x/schema-const.yaml +++ b/packages/openapi-ts-tests/specs/3.1.x/schema-const.yaml @@ -31,4 +31,79 @@ components: const: 10n format: int64 type: integer + # Integer format const examples - number type + numberInt8: + const: 100 + format: int8 + type: number + numberInt16: + const: 1000 + format: int16 + type: number + numberInt32: + const: 100000 + format: int32 + type: number + numberInt64: + const: 1000000000000 + format: int64 + type: number + numberUint8: + const: 200 + format: uint8 + type: number + numberUint16: + const: 50000 + format: uint16 + type: number + numberUint32: + const: 3000000000 + format: uint32 + type: number + numberUint64: + const: 18000000000000000000 + format: uint64 + type: number + # Integer format const examples - integer type + integerInt8: + const: -100 + format: int8 + type: integer + integerInt16: + const: -1000 + format: int16 + type: integer + integerInt32: + const: -100000 + format: int32 + type: integer + integerInt64: + const: -1000000000000 + format: int64 + type: integer + integerUint8: + const: 255 + format: uint8 + type: integer + integerUint16: + const: 65535 + format: uint16 + type: integer + integerUint32: + const: 4294967295 + format: uint32 + type: integer + integerUint64: + const: 18446744073709551615n + format: uint64 + type: integer + # Integer format const examples - string type (only for 64-bit formats) + stringInt64: + const: '-9223372036854775808' + format: int64 + type: string + stringUint64: + const: '18446744073709551615' + format: uint64 + type: string type: object diff --git a/packages/openapi-ts/src/plugins/valibot/plugin.ts b/packages/openapi-ts/src/plugins/valibot/plugin.ts index de92eb04e0..5e3bb55e7a 100644 --- a/packages/openapi-ts/src/plugins/valibot/plugin.ts +++ b/packages/openapi-ts/src/plugins/valibot/plugin.ts @@ -253,6 +253,74 @@ const nullTypeToValibotSchema = (_props: { return expression; }; +// Integer format ranges and properties +const INTEGER_FORMATS = { + int16: { + max: 32767, + maxError: 'Invalid value: Expected int16 to be <= 2^15-1', + min: -32768, + minError: 'Invalid value: Expected int16 to be >= -2^15', + needsBigInt: false, + }, + int32: { + max: 2147483647, + maxError: 'Invalid value: Expected int32 to be <= 2^31-1', + min: -2147483648, + minError: 'Invalid value: Expected int32 to be >= -2^31', + needsBigInt: false, + }, + int64: { + max: '9223372036854775807', + maxError: 'Invalid value: Expected int64 to be <= 2^63-1', + min: '-9223372036854775808', + minError: 'Invalid value: Expected int64 to be >= -2^63', + needsBigInt: true, + }, + int8: { + max: 127, + maxError: 'Invalid value: Expected int8 to be <= 2^7-1', + min: -128, + minError: 'Invalid value: Expected int8 to be >= -2^7', + needsBigInt: false, + }, + uint16: { + max: 65535, + maxError: 'Invalid value: Expected uint16 to be <= 2^16-1', + min: 0, + minError: 'Invalid value: Expected uint16 to be >= 0', + needsBigInt: false, + }, + uint32: { + max: 4294967295, + maxError: 'Invalid value: Expected uint32 to be <= 2^32-1', + min: 0, + minError: 'Invalid value: Expected uint32 to be >= 0', + needsBigInt: false, + }, + uint64: { + max: '18446744073709551615', + maxError: 'Invalid value: Expected uint64 to be <= 2^64-1', + min: '0', + minError: 'Invalid value: Expected uint64 to be >= 0', + needsBigInt: true, + }, + uint8: { + max: 255, + maxError: 'Invalid value: Expected uint8 to be <= 2^8-1', + min: 0, + minError: 'Invalid value: Expected uint8 to be >= 0', + needsBigInt: false, + }, +} as const; + +type IntegerFormat = keyof typeof INTEGER_FORMATS; + +const isIntegerFormat = (format: string | undefined): format is IntegerFormat => + format !== undefined && format in INTEGER_FORMATS; + +const needsBigIntForFormat = (format: string | undefined): boolean => + isIntegerFormat(format) && INTEGER_FORMATS[format].needsBigInt; + const numberParameter = ({ isBigInt, value, @@ -283,37 +351,137 @@ const numberTypeToValibotSchema = ({ }: { schema: SchemaWithType<'integer' | 'number'>; }) => { - const isBigInt = schema.type === 'integer' && schema.format === 'int64'; + const format = schema.format; + const isInteger = schema.type === 'integer'; + const isBigInt = needsBigIntForFormat(format); + const formatInfo = isIntegerFormat(format) ? INTEGER_FORMATS[format] : null; + + // Return early if const is defined since we can create a literal type directly without additional validation + if (schema.const !== undefined && schema.const !== null) { + const constValue = schema.const; + let literalValue; + + // Case 1: Number with no format -> generate literal with the number + if (typeof constValue === 'number' && !format) { + literalValue = compiler.ots.number(constValue); + } + // Case 2: Number with format -> check if format needs BigInt, generate appropriate literal + else if (typeof constValue === 'number' && format) { + if (isBigInt) { + // Format requires BigInt, convert number to BigInt + literalValue = compiler.callExpression({ + functionName: 'BigInt', + parameters: [compiler.ots.string(constValue.toString())], + }); + } else { + // Regular format, use number as-is + literalValue = compiler.ots.number(constValue); + } + } + // Case 3: Format that allows string -> generate BigInt literal (for int64/uint64 formats) + else if (typeof constValue === 'string' && isBigInt) { + // Remove 'n' suffix if present in string + const cleanString = constValue.endsWith('n') + ? constValue.slice(0, -1) + : constValue; + literalValue = compiler.callExpression({ + functionName: 'BigInt', + parameters: [compiler.ots.string(cleanString)], + }); + } + // Case 4: Const is typeof bigint (literal) -> transform from literal to BigInt() + else if (typeof constValue === 'bigint') { + // Convert BigInt to string and remove 'n' suffix that toString() adds + const bigintString = constValue.toString(); + const cleanString = bigintString.endsWith('n') + ? bigintString.slice(0, -1) + : bigintString; + literalValue = compiler.callExpression({ + functionName: 'BigInt', + parameters: [compiler.ots.string(cleanString)], + }); + } + // Default case: use value as-is for other types + else { + literalValue = compiler.valueToExpression({ value: constValue }); + } - if (typeof schema.const === 'number') { - // TODO: parser - handle bigint constants - const expression = compiler.callExpression({ + return compiler.callExpression({ functionName: compiler.propertyAccessExpression({ expression: identifiers.v, name: identifiers.schemas.literal, }), - parameters: [compiler.ots.number(schema.const)], + parameters: [literalValue], }); - return expression; } const pipes: Array = []; - // Zod uses coerce for bigint here, might be needed for Valibot too - const expression = compiler.callExpression({ - functionName: isBigInt - ? compiler.propertyAccessExpression({ - expression: identifiers.v, - name: identifiers.schemas.bigInt, - }) - : compiler.propertyAccessExpression({ - expression: identifiers.v, - name: identifiers.schemas.number, + // For bigint formats (int64, uint64), create union of number, string, and bigint with transform + if (isBigInt) { + const unionExpression = compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.schemas.union, + }), + parameters: [ + compiler.arrayLiteralExpression({ + elements: [ + compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.schemas.number, + }), + }), + compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.schemas.string, + }), + }), + compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.schemas.bigInt, + }), + }), + ], + multiLine: false, }), - }); - pipes.push(expression); + ], + }); + pipes.push(unionExpression); - if (!isBigInt && schema.type === 'integer') { + // Add transform to convert to BigInt + const transformExpression = compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.actions.transform, + }), + parameters: [ + compiler.arrowFunction({ + parameters: [{ name: 'x' }], + statements: compiler.callExpression({ + functionName: 'BigInt', + parameters: [compiler.identifier({ text: 'x' })], + }), + }), + ], + }); + pipes.push(transformExpression); + } else { + // For regular number formats, use number schema + const expression = compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.schemas.number, + }), + }); + pipes.push(expression); + } + + // Add integer validation for integer types (except when using bigint union) + if (!isBigInt && isInteger) { const expression = compiler.callExpression({ functionName: compiler.propertyAccessExpression({ expression: identifiers.v, @@ -323,6 +491,50 @@ const numberTypeToValibotSchema = ({ pipes.push(expression); } + // Add format-specific range validations + if (formatInfo) { + const minValue = formatInfo.min; + const maxValue = formatInfo.max; + const minErrorMessage = formatInfo.minError; + const maxErrorMessage = formatInfo.maxError; + + // Add minimum value validation + const minExpression = compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.actions.minValue, + }), + parameters: [ + isBigInt + ? compiler.callExpression({ + functionName: 'BigInt', + parameters: [compiler.ots.string(minValue.toString())], + }) + : compiler.ots.number(minValue as number), + compiler.ots.string(minErrorMessage), + ], + }); + pipes.push(minExpression); + + // Add maximum value validation + const maxExpression = compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: identifiers.v, + name: identifiers.actions.maxValue, + }), + parameters: [ + isBigInt + ? compiler.callExpression({ + functionName: 'BigInt', + parameters: [compiler.ots.string(maxValue.toString())], + }) + : compiler.ots.number(maxValue as number), + compiler.ots.string(maxErrorMessage), + ], + }); + pipes.push(maxExpression); + } + if (schema.exclusiveMinimum !== undefined) { const expression = compiler.callExpression({ functionName: compiler.propertyAccessExpression({ @@ -763,6 +975,14 @@ const schemaTypeToValibotSchema = ({ state, }); case 'string': + // For string schemas with int64/uint64 formats, use number handler to generate union with transform + if (schema.format === 'int64' || schema.format === 'uint64') { + return { + expression: numberTypeToValibotSchema({ + schema: schema as SchemaWithType<'integer' | 'number'>, + }), + }; + } return { expression: stringTypeToValibotSchema({ schema: schema as SchemaWithType<'string'>, From f1c16f47a68a0b03e5ad35e5e0774364dc8d6544 Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 08:09:42 +0200 Subject: [PATCH 03/10] test: update snapshots --- .../type-format-valibot/valibot.gen.ts | 6 ++- .../plugins/valibot/default/valibot.gen.ts | 2 +- .../type-format-valibot/valibot.gen.ts | 6 ++- .../plugins/valibot/default/valibot.gen.ts | 18 +++---- .../3.1.x/integer-formats/valibot.gen.ts | 50 +++++++++++++++++++ .../type-format-valibot/valibot.gen.ts | 6 ++- .../plugins/valibot/default/valibot.gen.ts | 18 +++---- .../3.1.x/schema-const/types.gen.ts | 18 +++++++ .../3.1.x/schema-const/valibot.gen.ts | 20 +++++++- .../validators-bigint-min-max/valibot.gen.ts | 6 ++- .../3.1.x/mini/schema-const/zod.gen.ts | 20 +++++++- .../3.1.x/v3/schema-const/zod.gen.ts | 20 +++++++- .../3.1.x/v4/schema-const/zod.gen.ts | 20 +++++++- .../3.1.x/mini/schema-const/zod.gen.ts | 20 +++++++- .../3.1.x/v3/schema-const/zod.gen.ts | 20 +++++++- .../3.1.x/v4/schema-const/zod.gen.ts | 20 +++++++- 16 files changed, 240 insertions(+), 30 deletions(-) create mode 100644 packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/integer-formats/valibot.gen.ts diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts index 077f21d146..e49e2e14e2 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts @@ -4,7 +4,11 @@ import * as v from 'valibot'; export const vFoo = v.object({ bar: v.optional(v.pipe(v.number(), v.integer())), - foo: v.optional(v.bigint(), BigInt(0)), + foo: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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)), id: v.string() }); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/valibot/default/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/valibot/default/valibot.gen.ts index 50141df6c2..f082c391b4 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/valibot/default/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/valibot/default/valibot.gen.ts @@ -664,7 +664,7 @@ export const vCollectionFormatData = v.object({ export const vTypesData = v.object({ body: v.optional(v.never()), path: v.optional(v.object({ - id: v.optional(v.pipe(v.number(), v.integer())) + 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'))) })), query: v.object({ parameterNumber: v.optional(v.number(), 123), diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts index 077f21d146..e49e2e14e2 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts @@ -4,7 +4,11 @@ import * as v from 'valibot'; export const vFoo = v.object({ bar: v.optional(v.pipe(v.number(), v.integer())), - foo: v.optional(v.bigint(), BigInt(0)), + foo: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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)), id: v.string() }); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/valibot/default/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/valibot/default/valibot.gen.ts index bd2c582c6c..d623cf75cd 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/valibot/default/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/valibot/default/valibot.gen.ts @@ -714,8 +714,8 @@ export const vDefault = v.object({ }); export const vPageable = v.object({ - page: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0)), 0), - size: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))), + 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), + 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))), sort: v.optional(v.array(v.string())) }); @@ -775,10 +775,10 @@ export const vCompositionWithOneOfAndProperties = v.intersect([ ]), v.object({ baz: v.union([ - v.pipe(v.number(), v.integer(), v.minValue(0)), + 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)), v.null() ]), - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) + 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)) }) ]); @@ -943,10 +943,10 @@ export const vModelWithOneOfAndProperties = v.intersect([ ]), v.object({ baz: v.union([ - v.pipe(v.number(), v.integer(), v.minValue(0)), + 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)), v.null() ]), - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) + 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)) }) ]); @@ -1812,7 +1812,7 @@ export const vCollectionFormatData = v.object({ export const vTypesData = v.object({ body: v.optional(v.never()), path: v.optional(v.object({ - id: v.optional(v.pipe(v.number(), v.integer())) + 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'))) })), query: v.object({ parameterNumber: v.optional(v.number(), 123), @@ -1958,7 +1958,7 @@ export const vComplexParamsData = v.object({ vModelWithDictionary ]), user: v.optional(v.pipe(v.object({ - id: v.optional(v.pipe(v.pipe(v.number(), v.integer()), v.readonly())), + 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())), name: v.optional(v.pipe(v.union([ v.pipe(v.string(), v.readonly()), v.null() @@ -1966,7 +1966,7 @@ export const vComplexParamsData = v.object({ }), v.readonly())) })), path: v.object({ - id: v.pipe(v.number(), v.integer()), + 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')), 'api-version': v.string() }), query: v.optional(v.never()) diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/integer-formats/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/integer-formats/valibot.gen.ts new file mode 100644 index 0000000000..ac62ef6995 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/integer-formats/valibot.gen.ts @@ -0,0 +1,50 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as v from 'valibot'; + +export const vIntegerFormats = v.object({ + numberNoFormat: v.optional(v.number()), + 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'))), + 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'))), + 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'))), + numberInt64: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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'))), + 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'))), + 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'))), + 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'))), + numberUint64: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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'))), + integerNoFormat: v.optional(v.pipe(v.number(), v.integer())), + 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'))), + 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'))), + 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'))), + integerInt64: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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'))), + 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'))), + 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'))), + 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'))), + integerUint64: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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'))), + stringInt64: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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'))), + stringUint64: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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'))) +}); \ No newline at end of file diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts index 077f21d146..e49e2e14e2 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts @@ -4,7 +4,11 @@ import * as v from 'valibot'; export const vFoo = v.object({ bar: v.optional(v.pipe(v.number(), v.integer())), - foo: v.optional(v.bigint(), BigInt(0)), + foo: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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)), id: v.string() }); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/valibot/default/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/valibot/default/valibot.gen.ts index aed5cb87ec..62fe728b9d 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/valibot/default/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/valibot/default/valibot.gen.ts @@ -709,8 +709,8 @@ export const vDefault = v.object({ }); export const vPageable = v.object({ - page: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0)), 0), - size: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))), + 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), + 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))), sort: v.optional(v.array(v.string())) }); @@ -766,10 +766,10 @@ export const vCompositionWithOneOfAndProperties = v.intersect([ ]), v.object({ baz: v.union([ - v.pipe(v.number(), v.integer(), v.minValue(0)), + 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)), v.null() ]), - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) + 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)) }) ]); @@ -941,10 +941,10 @@ export const vModelWithOneOfAndProperties = v.intersect([ ]), v.object({ baz: v.union([ - v.pipe(v.number(), v.integer(), v.minValue(0)), + 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)), v.null() ]), - qux: v.pipe(v.number(), v.integer(), v.minValue(0)) + 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)) }) ]); @@ -1817,7 +1817,7 @@ export const vCollectionFormatData = v.object({ export const vTypesData = v.object({ body: v.optional(v.never()), path: v.optional(v.object({ - id: v.optional(v.pipe(v.number(), v.integer())) + 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'))) })), query: v.object({ parameterNumber: v.optional(v.number(), 123), @@ -1964,7 +1964,7 @@ export const vComplexParamsData = v.object({ vModelWithDictionary ]), user: v.optional(v.pipe(v.object({ - id: v.optional(v.pipe(v.pipe(v.number(), v.integer()), v.readonly())), + 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())), name: v.optional(v.pipe(v.union([ v.pipe(v.string(), v.readonly()), v.null() @@ -1972,7 +1972,7 @@ export const vComplexParamsData = v.object({ }), v.readonly())) })), path: v.object({ - id: v.pipe(v.number(), v.integer()), + 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')), 'api-version': v.string() }), query: v.optional(v.never()) diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/types.gen.ts index 32a8594973..7fc17b7957 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/types.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/types.gen.ts @@ -16,6 +16,24 @@ export type Foo = { [key: string]: unknown; }; garply?: 10n; + numberInt8?: 100; + numberInt16?: 1000; + numberInt32?: 100000; + numberInt64?: 1000000000000; + numberUint8?: 200; + numberUint16?: 50000; + numberUint32?: 3000000000; + numberUint64?: 18000000000000000000; + integerInt8?: -100; + integerInt16?: -1000; + integerInt32?: -100000; + integerInt64?: -1000000000000; + integerUint8?: 255; + integerUint16?: 65535; + integerUint32?: 4294967295; + integerUint64?: 18446744073709551615n; + stringInt64?: '-9223372036854775808'; + stringUint64?: '18446744073709551615'; }; export type ClientOptions = { diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/valibot.gen.ts index 43a69a8778..01d8e66df6 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/schema-const/valibot.gen.ts @@ -15,5 +15,23 @@ export const vFoo = v.object({ v.literal(true) ])), corge: v.optional(v.object({})), - garply: v.optional(v.bigint()) + garply: v.optional(v.literal(BigInt('10'))), + numberInt8: v.optional(v.literal(100)), + numberInt16: v.optional(v.literal(1000)), + numberInt32: v.optional(v.literal(100000)), + numberInt64: v.optional(v.literal(BigInt('1000000000000'))), + numberUint8: v.optional(v.literal(200)), + numberUint16: v.optional(v.literal(50000)), + numberUint32: v.optional(v.literal(3000000000)), + numberUint64: v.optional(v.literal(BigInt('18000000000000000000'))), + integerInt8: v.optional(v.literal(-100)), + integerInt16: v.optional(v.literal(-1000)), + integerInt32: v.optional(v.literal(-100000)), + integerInt64: v.optional(v.literal(BigInt('-1000000000000'))), + integerUint8: v.optional(v.literal(255)), + integerUint16: v.optional(v.literal(65535)), + integerUint32: v.optional(v.literal(4294967295)), + integerUint64: v.optional(v.literal(BigInt('18446744073709551615'))), + stringInt64: v.optional(v.literal(BigInt('-9223372036854775808'))), + stringUint64: v.optional(v.literal(BigInt('18446744073709551615'))) }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/validators-bigint-min-max/valibot.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/validators-bigint-min-max/valibot.gen.ts index c438767bb0..284f1ae3bb 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/validators-bigint-min-max/valibot.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/validators-bigint-min-max/valibot.gen.ts @@ -3,5 +3,9 @@ import * as v from 'valibot'; export const vFoo = v.object({ - foo: v.optional(v.pipe(v.bigint(), v.minValue(BigInt(0)), v.maxValue(BigInt(100)))) + foo: v.optional(v.pipe(v.union([ + v.number(), + v.string(), + v.bigint() + ]), 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)))) }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts index 08519c6585..76b32a6f43 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts @@ -15,5 +15,23 @@ export const zFoo = z.object({ z.literal(true) ])), corge: z.optional(z.object({})), - garply: z.optional(z.coerce.bigint()) + garply: z.optional(z.coerce.bigint()), + numberInt8: z.optional(z.literal(100)), + numberInt16: z.optional(z.literal(1000)), + numberInt32: z.optional(z.literal(100000)), + numberInt64: z.optional(z.literal(1000000000000)), + numberUint8: z.optional(z.literal(200)), + numberUint16: z.optional(z.literal(50000)), + numberUint32: z.optional(z.literal(3000000000)), + numberUint64: z.optional(z.literal(18000000000000000000)), + integerInt8: z.optional(z.literal(-100)), + integerInt16: z.optional(z.literal(-1000)), + integerInt32: z.optional(z.literal(-100000)), + integerInt64: z.optional(z.literal(-1000000000000)), + integerUint8: z.optional(z.literal(255)), + integerUint16: z.optional(z.literal(65535)), + integerUint32: z.optional(z.literal(4294967295)), + integerUint64: z.optional(z.int()), + stringInt64: z.optional(z.literal('-9223372036854775808')), + stringUint64: z.optional(z.literal('18446744073709551615')) }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts index 808d0e91b3..a7aad3761e 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts @@ -15,5 +15,23 @@ export const zFoo = z.object({ z.literal(true) ]).optional(), corge: z.object({}).optional(), - garply: z.coerce.bigint().optional() + garply: z.coerce.bigint().optional(), + numberInt8: z.literal(100).optional(), + numberInt16: z.literal(1000).optional(), + numberInt32: z.literal(100000).optional(), + numberInt64: z.literal(1000000000000).optional(), + numberUint8: z.literal(200).optional(), + numberUint16: z.literal(50000).optional(), + numberUint32: z.literal(3000000000).optional(), + numberUint64: z.literal(18000000000000000000).optional(), + integerInt8: z.literal(-100).optional(), + integerInt16: z.literal(-1000).optional(), + integerInt32: z.literal(-100000).optional(), + integerInt64: z.literal(-1000000000000).optional(), + integerUint8: z.literal(255).optional(), + integerUint16: z.literal(65535).optional(), + integerUint32: z.literal(4294967295).optional(), + integerUint64: z.number().int().optional(), + stringInt64: z.literal('-9223372036854775808').optional(), + stringUint64: z.literal('18446744073709551615').optional() }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts index 7135338e0d..ee6fdf50e6 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts @@ -15,5 +15,23 @@ export const zFoo = z.object({ z.literal(true) ])), corge: z.optional(z.object({})), - garply: z.optional(z.coerce.bigint()) + garply: z.optional(z.coerce.bigint()), + numberInt8: z.optional(z.literal(100)), + numberInt16: z.optional(z.literal(1000)), + numberInt32: z.optional(z.literal(100000)), + numberInt64: z.optional(z.literal(1000000000000)), + numberUint8: z.optional(z.literal(200)), + numberUint16: z.optional(z.literal(50000)), + numberUint32: z.optional(z.literal(3000000000)), + numberUint64: z.optional(z.literal(18000000000000000000)), + integerInt8: z.optional(z.literal(-100)), + integerInt16: z.optional(z.literal(-1000)), + integerInt32: z.optional(z.literal(-100000)), + integerInt64: z.optional(z.literal(-1000000000000)), + integerUint8: z.optional(z.literal(255)), + integerUint16: z.optional(z.literal(65535)), + integerUint32: z.optional(z.literal(4294967295)), + integerUint64: z.optional(z.int()), + stringInt64: z.optional(z.literal('-9223372036854775808')), + stringUint64: z.optional(z.literal('18446744073709551615')) }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts index 0381c10ec4..c3a7d4a82e 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/schema-const/zod.gen.ts @@ -15,5 +15,23 @@ export const zFoo = z.object({ z.literal(true) ])), corge: z.optional(z.object({})), - garply: z.optional(z.coerce.bigint()) + garply: z.optional(z.coerce.bigint()), + numberInt8: z.optional(z.literal(100)), + numberInt16: z.optional(z.literal(1000)), + numberInt32: z.optional(z.literal(100000)), + numberInt64: z.optional(z.literal(1000000000000)), + numberUint8: z.optional(z.literal(200)), + numberUint16: z.optional(z.literal(50000)), + numberUint32: z.optional(z.literal(3000000000)), + numberUint64: z.optional(z.literal(18000000000000000000)), + integerInt8: z.optional(z.literal(-100)), + integerInt16: z.optional(z.literal(-1000)), + integerInt32: z.optional(z.literal(-100000)), + integerInt64: z.optional(z.literal(-1000000000000)), + integerUint8: z.optional(z.literal(255)), + integerUint16: z.optional(z.literal(65535)), + integerUint32: z.optional(z.literal(4294967295)), + integerUint64: z.optional(z.int()), + stringInt64: z.optional(z.literal('-9223372036854775808')), + stringUint64: z.optional(z.literal('18446744073709551615')) }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts index 9a51568131..354d86ddba 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/schema-const/zod.gen.ts @@ -15,5 +15,23 @@ export const zFoo = z.object({ z.literal(true) ]).optional(), corge: z.object({}).optional(), - garply: z.coerce.bigint().optional() + garply: z.coerce.bigint().optional(), + numberInt8: z.literal(100).optional(), + numberInt16: z.literal(1000).optional(), + numberInt32: z.literal(100000).optional(), + numberInt64: z.literal(1000000000000).optional(), + numberUint8: z.literal(200).optional(), + numberUint16: z.literal(50000).optional(), + numberUint32: z.literal(3000000000).optional(), + numberUint64: z.literal(18000000000000000000).optional(), + integerInt8: z.literal(-100).optional(), + integerInt16: z.literal(-1000).optional(), + integerInt32: z.literal(-100000).optional(), + integerInt64: z.literal(-1000000000000).optional(), + integerUint8: z.literal(255).optional(), + integerUint16: z.literal(65535).optional(), + integerUint32: z.literal(4294967295).optional(), + integerUint64: z.number().int().optional(), + stringInt64: z.literal('-9223372036854775808').optional(), + stringUint64: z.literal('18446744073709551615').optional() }); \ No newline at end of file diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts index e6b50257a5..e4e073a25a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts @@ -15,5 +15,23 @@ export const zFoo = z.object({ z.literal(true) ])), corge: z.optional(z.object({})), - garply: z.optional(z.coerce.bigint()) + garply: z.optional(z.coerce.bigint()), + numberInt8: z.optional(z.literal(100)), + numberInt16: z.optional(z.literal(1000)), + numberInt32: z.optional(z.literal(100000)), + numberInt64: z.optional(z.literal(1000000000000)), + numberUint8: z.optional(z.literal(200)), + numberUint16: z.optional(z.literal(50000)), + numberUint32: z.optional(z.literal(3000000000)), + numberUint64: z.optional(z.literal(18000000000000000000)), + integerInt8: z.optional(z.literal(-100)), + integerInt16: z.optional(z.literal(-1000)), + integerInt32: z.optional(z.literal(-100000)), + integerInt64: z.optional(z.literal(-1000000000000)), + integerUint8: z.optional(z.literal(255)), + integerUint16: z.optional(z.literal(65535)), + integerUint32: z.optional(z.literal(4294967295)), + integerUint64: z.optional(z.int()), + stringInt64: z.optional(z.literal('-9223372036854775808')), + stringUint64: z.optional(z.literal('18446744073709551615')) }); \ No newline at end of file From 6ebc9744bb3b9e0fb2b42061001d6054c774f486 Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 08:38:02 +0200 Subject: [PATCH 04/10] test: switch integer-formats spec from JSON to YAML --- .../openapi-ts-tests/main/test/3.1.x.test.ts | 2 +- .../specs/3.1.x/integer-formats.json | 94 ------------------- .../specs/3.1.x/integer-formats.yaml | 67 +++++++++++++ 3 files changed, 68 insertions(+), 95 deletions(-) delete mode 100644 packages/openapi-ts-tests/specs/3.1.x/integer-formats.json create mode 100644 packages/openapi-ts-tests/specs/3.1.x/integer-formats.yaml diff --git a/packages/openapi-ts-tests/main/test/3.1.x.test.ts b/packages/openapi-ts-tests/main/test/3.1.x.test.ts index bdcfa5f9a0..f159eacb72 100644 --- a/packages/openapi-ts-tests/main/test/3.1.x.test.ts +++ b/packages/openapi-ts-tests/main/test/3.1.x.test.ts @@ -800,7 +800,7 @@ describe(`OpenAPI ${version}`, () => { }, { config: createConfig({ - input: 'integer-formats.json', + input: 'integer-formats.yaml', output: 'integer-formats', plugins: ['valibot'], }), diff --git a/packages/openapi-ts-tests/specs/3.1.x/integer-formats.json b/packages/openapi-ts-tests/specs/3.1.x/integer-formats.json deleted file mode 100644 index 2436e30fbf..0000000000 --- a/packages/openapi-ts-tests/specs/3.1.x/integer-formats.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Integer Formats Test", - "version": "1.0.0" - }, - "components": { - "schemas": { - "IntegerFormats": { - "type": "object", - "properties": { - "numberNoFormat": { - "type": "number" - }, - "numberInt8": { - "type": "number", - "format": "int8" - }, - "numberInt16": { - "type": "number", - "format": "int16" - }, - "numberInt32": { - "type": "number", - "format": "int32" - }, - "numberInt64": { - "type": "number", - "format": "int64" - }, - "numberUint8": { - "type": "number", - "format": "uint8" - }, - "numberUint16": { - "type": "number", - "format": "uint16" - }, - "numberUint32": { - "type": "number", - "format": "uint32" - }, - "numberUint64": { - "type": "number", - "format": "uint64" - }, - "integerNoFormat": { - "type": "integer" - }, - "integerInt8": { - "type": "integer", - "format": "int8" - }, - "integerInt16": { - "type": "integer", - "format": "int16" - }, - "integerInt32": { - "type": "integer", - "format": "int32" - }, - "integerInt64": { - "type": "integer", - "format": "int64" - }, - "integerUint8": { - "type": "integer", - "format": "uint8" - }, - "integerUint16": { - "type": "integer", - "format": "uint16" - }, - "integerUint32": { - "type": "integer", - "format": "uint32" - }, - "integerUint64": { - "type": "integer", - "format": "uint64" - }, - "stringInt64": { - "type": "string", - "format": "int64" - }, - "stringUint64": { - "type": "string", - "format": "uint64" - } - } - } - } - } -} diff --git a/packages/openapi-ts-tests/specs/3.1.x/integer-formats.yaml b/packages/openapi-ts-tests/specs/3.1.x/integer-formats.yaml new file mode 100644 index 0000000000..c2d2ade1af --- /dev/null +++ b/packages/openapi-ts-tests/specs/3.1.x/integer-formats.yaml @@ -0,0 +1,67 @@ +openapi: '3.1.0' +info: + title: Integer Formats Test + version: '1.0.0' +components: + schemas: + IntegerFormats: + type: object + properties: + numberNoFormat: + type: number + numberInt8: + type: number + format: int8 + numberInt16: + type: number + format: int16 + numberInt32: + type: number + format: int32 + numberInt64: + type: number + format: int64 + numberUint8: + type: number + format: uint8 + numberUint16: + type: number + format: uint16 + numberUint32: + type: number + format: uint32 + numberUint64: + type: number + format: uint64 + integerNoFormat: + type: integer + integerInt8: + type: integer + format: int8 + integerInt16: + type: integer + format: int16 + integerInt32: + type: integer + format: int32 + integerInt64: + type: integer + format: int64 + integerUint8: + type: integer + format: uint8 + integerUint16: + type: integer + format: uint16 + integerUint32: + type: integer + format: uint32 + integerUint64: + type: integer + format: uint64 + stringInt64: + type: string + format: int64 + stringUint64: + type: string + format: uint64 From 69ec0104808744bc2128d0138c611470115fb42e Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 08:49:26 +0200 Subject: [PATCH 05/10] test(valibot): switch spec from JSON to YAML --- .../const-values.json | 120 ------------ .../const-values.yaml | 93 +++++++++ .../numberTypeToValibotSchema/formats.json | 89 --------- .../numberTypeToValibotSchema/formats.yaml | 64 +++++++ .../min-max-constraints.json | 179 ------------------ .../min-max-constraints.yaml | 141 ++++++++++++++ .../main/test/plugins/valibot/test-helper.ts | 2 +- 7 files changed, 299 insertions(+), 389 deletions(-) delete mode 100644 packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json create mode 100644 packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.yaml delete mode 100644 packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json create mode 100644 packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.yaml delete mode 100644 packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json create mode 100644 packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.yaml diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json deleted file mode 100644 index f9d1f71982..0000000000 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Number Type Const Values Test API", - "version": "1.0.0" - }, - "paths": {}, - "components": { - "schemas": { - "NumberNoFormat": { - "type": "number", - "const": 42.5 - }, - "IntegerNoFormat": { - "type": "integer", - "const": -1 - }, - "NumberInt8": { - "type": "number", - "format": "int8", - "const": 100 - }, - "NumberInt16": { - "type": "number", - "format": "int16", - "const": 1000 - }, - "NumberInt32": { - "type": "number", - "format": "int32", - "const": 100000 - }, - "NumberInt64": { - "type": "number", - "format": "int64", - "const": 1000000000000 - }, - "NumberUint8": { - "type": "number", - "format": "uint8", - "const": 200 - }, - "NumberUint16": { - "type": "number", - "format": "uint16", - "const": 50000 - }, - "NumberUint32": { - "type": "number", - "format": "uint32", - "const": 3000000000 - }, - "NumberUint64": { - "type": "number", - "format": "uint64", - "const": 18000000000000000000 - }, - "IntegerInt8": { - "type": "integer", - "format": "int8", - "const": -100 - }, - "IntegerInt16": { - "type": "integer", - "format": "int16", - "const": -1000 - }, - "IntegerInt32": { - "type": "integer", - "format": "int32", - "const": -100000 - }, - "IntegerInt64": { - "type": "integer", - "format": "int64", - "const": -1000000000000 - }, - "IntegerUint8": { - "type": "integer", - "format": "uint8", - "const": 255 - }, - "IntegerUint16": { - "type": "integer", - "format": "uint16", - "const": 65535 - }, - "IntegerUint32": { - "type": "integer", - "format": "uint32", - "const": 4294967295 - }, - "IntegerUint64": { - "type": "integer", - "format": "uint64", - "const": 1000000000000 - }, - "StringInt64": { - "type": "string", - "format": "int64", - "const": "-9223372036854775808" - }, - "StringUint64": { - "type": "string", - "format": "uint64", - "const": "18446744073709551615" - }, - "StringInt64n": { - "type": "string", - "format": "int64", - "const": "-9223372036854775808n" - }, - "StringUint64n": { - "type": "string", - "format": "uint64", - "const": "18446744073709551615n" - } - } - } -} diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.yaml b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.yaml new file mode 100644 index 0000000000..31fef4d21c --- /dev/null +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/const-values.yaml @@ -0,0 +1,93 @@ +openapi: '3.1.0' +info: + title: Number Type Const Values Test API + version: '1.0.0' +paths: {} +components: + schemas: + NumberNoFormat: + type: number + const: 42.5 + IntegerNoFormat: + type: integer + const: -1 + NumberInt8: + type: number + format: int8 + const: 100 + NumberInt16: + type: number + format: int16 + const: 1000 + NumberInt32: + type: number + format: int32 + const: 100000 + NumberInt64: + type: number + format: int64 + const: 1000000000000 + NumberUint8: + type: number + format: uint8 + const: 200 + NumberUint16: + type: number + format: uint16 + const: 50000 + NumberUint32: + type: number + format: uint32 + const: 3000000000 + NumberUint64: + type: number + format: uint64 + const: 18000000000000000000 + IntegerInt8: + type: integer + format: int8 + const: -100 + IntegerInt16: + type: integer + format: int16 + const: -1000 + IntegerInt32: + type: integer + format: int32 + const: -100000 + IntegerInt64: + type: integer + format: int64 + const: -1000000000000 + IntegerUint8: + type: integer + format: uint8 + const: 255 + IntegerUint16: + type: integer + format: uint16 + const: 65535 + IntegerUint32: + type: integer + format: uint32 + const: 4294967295 + IntegerUint64: + type: integer + format: uint64 + const: 1000000000000 + StringInt64: + type: string + format: int64 + const: '-9223372036854775808' + StringUint64: + type: string + format: uint64 + const: '18446744073709551615' + StringInt64n: + type: string + format: int64 + const: '-9223372036854775808n' + StringUint64n: + type: string + format: uint64 + const: '18446744073709551615n' diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json deleted file mode 100644 index f35e865d7b..0000000000 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Integer Formats Test", - "version": "1.0.0" - }, - "components": { - "schemas": { - "NumberNoFormat": { - "type": "number" - }, - "NumberInt8": { - "type": "number", - "format": "int8" - }, - "NumberInt16": { - "type": "number", - "format": "int16" - }, - "NumberInt32": { - "type": "number", - "format": "int32" - }, - "NumberInt64": { - "type": "number", - "format": "int64" - }, - "NumberUint8": { - "type": "number", - "format": "uint8" - }, - "NumberUint16": { - "type": "number", - "format": "uint16" - }, - "NumberUint32": { - "type": "number", - "format": "uint32" - }, - "NumberUint64": { - "type": "number", - "format": "uint64" - }, - "IntegerNoFormat": { - "type": "integer" - }, - "IntegerInt8": { - "type": "integer", - "format": "int8" - }, - "IntegerInt16": { - "type": "integer", - "format": "int16" - }, - "IntegerInt32": { - "type": "integer", - "format": "int32" - }, - "IntegerInt64": { - "type": "integer", - "format": "int64" - }, - "IntegerUint8": { - "type": "integer", - "format": "uint8" - }, - "IntegerUint16": { - "type": "integer", - "format": "uint16" - }, - "IntegerUint32": { - "type": "integer", - "format": "uint32" - }, - "IntegerUint64": { - "type": "integer", - "format": "uint64" - }, - "StringInt64": { - "type": "string", - "format": "int64" - }, - "StringUint64": { - "type": "string", - "format": "uint64" - } - } - } -} diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.yaml b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.yaml new file mode 100644 index 0000000000..8fc26a6f47 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/formats.yaml @@ -0,0 +1,64 @@ +openapi: '3.1.0' +info: + title: Integer Formats Test + version: '1.0.0' +components: + schemas: + NumberNoFormat: + type: number + NumberInt8: + type: number + format: int8 + NumberInt16: + type: number + format: int16 + NumberInt32: + type: number + format: int32 + NumberInt64: + type: number + format: int64 + NumberUint8: + type: number + format: uint8 + NumberUint16: + type: number + format: uint16 + NumberUint32: + type: number + format: uint32 + NumberUint64: + type: number + format: uint64 + IntegerNoFormat: + type: integer + IntegerInt8: + type: integer + format: int8 + IntegerInt16: + type: integer + format: int16 + IntegerInt32: + type: integer + format: int32 + IntegerInt64: + type: integer + format: int64 + IntegerUint8: + type: integer + format: uint8 + IntegerUint16: + type: integer + format: uint16 + IntegerUint32: + type: integer + format: uint32 + IntegerUint64: + type: integer + format: uint64 + StringInt64: + type: string + format: int64 + StringUint64: + type: string + format: uint64 diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json deleted file mode 100644 index f35c61af71..0000000000 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Number Type Min/Max Constraints Test API", - "version": "1.0.0" - }, - "paths": {}, - "components": { - "schemas": { - "NumberWithMinimum": { - "type": "number", - "minimum": 10 - }, - "NumberWithMaximum": { - "type": "number", - "maximum": 100 - }, - "NumberWithMinMax": { - "type": "number", - "minimum": 0, - "maximum": 100 - }, - "IntegerWithMinimum": { - "type": "integer", - "minimum": 5 - }, - "IntegerWithMaximum": { - "type": "integer", - "maximum": 999 - }, - "IntegerWithMinMax": { - "type": "integer", - "minimum": 1, - "maximum": 999 - }, - "NumberWithExclusiveMin": { - "type": "number", - "exclusiveMinimum": 0 - }, - "NumberWithExclusiveMax": { - "type": "number", - "exclusiveMaximum": 100 - }, - "NumberWithExclusiveMinMax": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1 - }, - "IntegerWithExclusiveMin": { - "type": "integer", - "exclusiveMinimum": 10 - }, - "IntegerWithExclusiveMax": { - "type": "integer", - "exclusiveMaximum": 50 - }, - "IntegerWithExclusiveMinMax": { - "type": "integer", - "exclusiveMinimum": 5, - "exclusiveMaximum": 15 - }, - "NumberWithExclusiveMinInclusiveMax": { - "type": "number", - "exclusiveMinimum": 10, - "maximum": 90 - }, - "NumberWithInclusiveMinExclusiveMax": { - "type": "number", - "minimum": 20, - "exclusiveMaximum": 80 - }, - "IntegerWithExclusiveMinInclusiveMax": { - "type": "integer", - "exclusiveMinimum": 5, - "maximum": 50 - }, - "IntegerWithInclusiveMinExclusiveMax": { - "type": "integer", - "minimum": 10, - "exclusiveMaximum": 100 - }, - "Int64WithMinimum": { - "type": "integer", - "format": "int64", - "minimum": -5000000000000 - }, - "Int64WithMaximum": { - "type": "integer", - "format": "int64", - "maximum": 5000000000000 - }, - "Int64WithMinMax": { - "type": "integer", - "format": "int64", - "minimum": -4000000000000, - "maximum": 4000000000000 - }, - "Int64WithExclusiveMin": { - "type": "integer", - "format": "int64", - "exclusiveMinimum": -3000000000000 - }, - "Int64WithExclusiveMax": { - "type": "integer", - "format": "int64", - "exclusiveMaximum": 3000000000000 - }, - "Int64WithExclusiveMinMax": { - "type": "integer", - "format": "int64", - "exclusiveMinimum": -2000000000000, - "exclusiveMaximum": 2000000000000 - }, - "Int64WithExclusiveMinInclusiveMax": { - "type": "integer", - "format": "int64", - "exclusiveMinimum": -6000000000000, - "maximum": 6000000000000 - }, - "Int64WithInclusiveMinExclusiveMax": { - "type": "integer", - "format": "int64", - "minimum": -7000000000000, - "exclusiveMaximum": 7000000000000 - }, - "UInt64WithMinimum": { - "type": "integer", - "format": "uint64", - "minimum": 5000000000000 - }, - "UInt64WithMaximum": { - "type": "integer", - "format": "uint64", - "maximum": 15000000000000 - }, - "UInt64WithMinMax": { - "type": "integer", - "format": "uint64", - "minimum": 1000000000000, - "maximum": 10000000000000 - }, - "UInt64WithExclusiveMin": { - "type": "integer", - "format": "uint64", - "exclusiveMinimum": 8000000000000 - }, - "UInt64WithExclusiveMax": { - "type": "integer", - "format": "uint64", - "exclusiveMaximum": 12000000000000 - }, - "UInt64WithExclusiveMinMax": { - "type": "integer", - "format": "uint64", - "exclusiveMinimum": 2000000000000, - "exclusiveMaximum": 8000000000000 - }, - "UInt64WithExclusiveMinInclusiveMax": { - "type": "integer", - "format": "uint64", - "exclusiveMinimum": 3000000000000, - "maximum": 13000000000000 - }, - "UInt64WithInclusiveMinExclusiveMax": { - "type": "integer", - "format": "uint64", - "minimum": 4000000000000, - "exclusiveMaximum": 14000000000000 - }, - "PrecedenceTest": { - "type": "number", - "minimum": 10, - "maximum": 90, - "exclusiveMinimum": 5, - "exclusiveMaximum": 95 - } - } - } -} diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.yaml b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.yaml new file mode 100644 index 0000000000..be4c35945a --- /dev/null +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/spec/numberTypeToValibotSchema/min-max-constraints.yaml @@ -0,0 +1,141 @@ +openapi: '3.1.0' +info: + title: Number Type Min/Max Constraints Test API + version: '1.0.0' +paths: {} +components: + schemas: + NumberWithMinimum: + type: number + minimum: 10 + NumberWithMaximum: + type: number + maximum: 100 + NumberWithMinMax: + type: number + minimum: 0 + maximum: 100 + IntegerWithMinimum: + type: integer + minimum: 5 + IntegerWithMaximum: + type: integer + maximum: 999 + IntegerWithMinMax: + type: integer + minimum: 1 + maximum: 999 + NumberWithExclusiveMin: + type: number + exclusiveMinimum: 0 + NumberWithExclusiveMax: + type: number + exclusiveMaximum: 100 + NumberWithExclusiveMinMax: + type: number + exclusiveMinimum: 0 + exclusiveMaximum: 1 + IntegerWithExclusiveMin: + type: integer + exclusiveMinimum: 10 + IntegerWithExclusiveMax: + type: integer + exclusiveMaximum: 50 + IntegerWithExclusiveMinMax: + type: integer + exclusiveMinimum: 5 + exclusiveMaximum: 15 + NumberWithExclusiveMinInclusiveMax: + type: number + exclusiveMinimum: 10 + maximum: 90 + NumberWithInclusiveMinExclusiveMax: + type: number + minimum: 20 + exclusiveMaximum: 80 + IntegerWithExclusiveMinInclusiveMax: + type: integer + exclusiveMinimum: 5 + maximum: 50 + IntegerWithInclusiveMinExclusiveMax: + type: integer + minimum: 10 + exclusiveMaximum: 100 + Int64WithMinimum: + type: integer + format: int64 + minimum: -5000000000000 + Int64WithMaximum: + type: integer + format: int64 + maximum: 5000000000000 + Int64WithMinMax: + type: integer + format: int64 + minimum: -4000000000000 + maximum: 4000000000000 + Int64WithExclusiveMin: + type: integer + format: int64 + exclusiveMinimum: -3000000000000 + Int64WithExclusiveMax: + type: integer + format: int64 + exclusiveMaximum: 3000000000000 + Int64WithExclusiveMinMax: + type: integer + format: int64 + exclusiveMinimum: -2000000000000 + exclusiveMaximum: 2000000000000 + Int64WithExclusiveMinInclusiveMax: + type: integer + format: int64 + exclusiveMinimum: -6000000000000 + maximum: 6000000000000 + Int64WithInclusiveMinExclusiveMax: + type: integer + format: int64 + minimum: -7000000000000 + exclusiveMaximum: 7000000000000 + UInt64WithMinimum: + type: integer + format: uint64 + minimum: 5000000000000 + UInt64WithMaximum: + type: integer + format: uint64 + maximum: 15000000000000 + UInt64WithMinMax: + type: integer + format: uint64 + minimum: 1000000000000 + maximum: 10000000000000 + UInt64WithExclusiveMin: + type: integer + format: uint64 + exclusiveMinimum: 8000000000000 + UInt64WithExclusiveMax: + type: integer + format: uint64 + exclusiveMaximum: 12000000000000 + UInt64WithExclusiveMinMax: + type: integer + format: uint64 + exclusiveMinimum: 2000000000000 + exclusiveMaximum: 8000000000000 + UInt64WithExclusiveMinInclusiveMax: + type: integer + format: uint64 + exclusiveMinimum: 3000000000000 + maximum: 13000000000000 + UInt64WithInclusiveMinExclusiveMax: + type: integer + format: uint64 + minimum: 4000000000000 + exclusiveMaximum: 14000000000000 + PrecedenceTest: + type: number + minimum: 10 + maximum: 90 + exclusiveMinimum: 5 + exclusiveMaximum: 95 diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts index 4c513d909d..cb8fc413d6 100644 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/test-helper.ts @@ -166,7 +166,7 @@ export async function setupValibotTest(): Promise { '..', 'spec', functionName, - `${testName}.json`, + `${testName}.yaml`, ); const outputPath = path.join( baseDir, From a7df1f2d26ad6e739b4fb0493ba4099b96900912 Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 09:17:01 +0200 Subject: [PATCH 06/10] test(valibot): remove redundant assertion checks --- .../const-values.test.ts | 66 ---- .../min-max-constraints.test.ts | 336 ------------------ 2 files changed, 402 deletions(-) diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts index 72a1c826a9..473c218026 100644 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/const-values.test.ts @@ -14,9 +14,6 @@ describe('Number Type Const Values Tests', () => { it('should accept exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberNoFormat, 42.5); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(42.5); - } }); it('should reject non-matching values', () => { @@ -29,9 +26,6 @@ describe('Number Type Const Values Tests', () => { it('should accept NumberInt8 exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberInt8, 100); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(100); - } }); it('should reject NumberInt8 non-matching values', () => { @@ -42,9 +36,6 @@ describe('Number Type Const Values Tests', () => { it('should accept NumberInt16 exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberInt16, 1000); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(1000); - } }); it('should reject NumberInt16 non-matching values', () => { @@ -55,9 +46,6 @@ describe('Number Type Const Values Tests', () => { it('should accept NumberInt32 exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberInt32, 100000); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(100000); - } }); it('should reject NumberInt32 non-matching values', () => { @@ -71,9 +59,6 @@ describe('Number Type Const Values Tests', () => { BigInt('1000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('1000000000000')); - } }); it('should reject NumberInt64 non-matching values', () => { @@ -87,9 +72,6 @@ describe('Number Type Const Values Tests', () => { it('should accept NumberUint8 exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberUint8, 200); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(200); - } }); it('should reject NumberUint8 non-matching values', () => { @@ -100,9 +82,6 @@ describe('Number Type Const Values Tests', () => { it('should accept NumberUint16 exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberUint16, 50000); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(50000); - } }); it('should reject NumberUint16 non-matching values', () => { @@ -113,9 +92,6 @@ describe('Number Type Const Values Tests', () => { it('should accept NumberUint32 exact const value', () => { const result = v.safeParse(generatedSchemas.vNumberUint32, 3000000000); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(3000000000); - } }); it('should reject NumberUint32 non-matching values', () => { @@ -129,9 +105,6 @@ describe('Number Type Const Values Tests', () => { BigInt('18000000000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('18000000000000000000')); - } }); it('should reject NumberUint64 non-matching values', () => { @@ -147,9 +120,6 @@ describe('Number Type Const Values Tests', () => { it('should accept exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerNoFormat, -1); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(-1); - } }); it('should reject non-matching values', () => { @@ -162,9 +132,6 @@ describe('Number Type Const Values Tests', () => { it('should accept IntegerInt8 exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerInt8, -100); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(-100); - } }); it('should reject IntegerInt8 non-matching values', () => { @@ -175,9 +142,6 @@ describe('Number Type Const Values Tests', () => { it('should accept IntegerInt16 exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerInt16, -1000); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(-1000); - } }); it('should reject IntegerInt16 non-matching values', () => { @@ -188,9 +152,6 @@ describe('Number Type Const Values Tests', () => { it('should accept IntegerInt32 exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerInt32, -100000); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(-100000); - } }); it('should reject IntegerInt32 non-matching values', () => { @@ -204,9 +165,6 @@ describe('Number Type Const Values Tests', () => { BigInt('-1000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-1000000000000')); - } }); it('should reject IntegerInt64 non-matching values', () => { @@ -220,9 +178,6 @@ describe('Number Type Const Values Tests', () => { it('should accept IntegerUint8 exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerUint8, 255); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(255); - } }); it('should reject IntegerUint8 non-matching values', () => { @@ -233,9 +188,6 @@ describe('Number Type Const Values Tests', () => { it('should accept IntegerUint16 exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerUint16, 65535); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(65535); - } }); it('should reject IntegerUint16 non-matching values', () => { @@ -246,9 +198,6 @@ describe('Number Type Const Values Tests', () => { it('should accept IntegerUint32 exact const value', () => { const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967295); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(4294967295); - } }); it('should reject IntegerUint32 non-matching values', () => { @@ -262,9 +211,6 @@ describe('Number Type Const Values Tests', () => { BigInt('1000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('1000000000000')); - } }); it('should reject IntegerUint64 non-matching values', () => { @@ -283,9 +229,6 @@ describe('Number Type Const Values Tests', () => { BigInt('-9223372036854775808'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-9223372036854775808')); - } }); it('should reject StringInt64 non-matching values', () => { @@ -302,9 +245,6 @@ describe('Number Type Const Values Tests', () => { BigInt('18446744073709551615'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('18446744073709551615')); - } }); it('should reject StringUint64 non-matching values', () => { @@ -323,9 +263,6 @@ describe('Number Type Const Values Tests', () => { BigInt('-9223372036854775808'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-9223372036854775808')); - } }); it('should reject StringInt64n non-matching values', () => { @@ -342,9 +279,6 @@ describe('Number Type Const Values Tests', () => { BigInt('18446744073709551615'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('18446744073709551615')); - } }); it('should reject StringUint64n non-matching values', () => { diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts index f0471b7719..faeaafbc16 100644 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/min-max-constraints.test.ts @@ -15,25 +15,16 @@ describe('Number Type Min/Max Constraints Tests', () => { it('should accept values at minimum boundary', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 10); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(10); - } }); it('should accept values above minimum', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 15); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(15); - } }); it('should reject values below minimum', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinimum, 9); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -41,25 +32,16 @@ describe('Number Type Min/Max Constraints Tests', () => { it('should accept values at maximum boundary', () => { const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 100); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(100); - } }); it('should accept values below maximum', () => { const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 50); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(50); - } }); it('should reject values above maximum', () => { const result = v.safeParse(generatedSchemas.vNumberWithMaximum, 101); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -67,41 +49,26 @@ describe('Number Type Min/Max Constraints Tests', () => { it('should accept values within range', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 50); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(50); - } }); it('should accept values at minimum boundary', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 0); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(0); - } }); it('should accept values at maximum boundary', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 100); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(100); - } }); it('should reject values below minimum', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinMax, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values above maximum', () => { const result = v.safeParse(generatedSchemas.vNumberWithMinMax, 101); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); }); @@ -111,25 +78,16 @@ describe('Number Type Min/Max Constraints Tests', () => { it('should accept values at minimum boundary', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 5); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(5); - } }); it('should accept values above minimum', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 10); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(10); - } }); it('should reject values below minimum', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinimum, 4); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -137,25 +95,16 @@ describe('Number Type Min/Max Constraints Tests', () => { it('should accept values at maximum boundary', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 999); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(999); - } }); it('should accept values below maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 500); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(500); - } }); it('should reject values above maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMaximum, 1000); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -163,41 +112,26 @@ describe('Number Type Min/Max Constraints Tests', () => { it('should accept values within range', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 500); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(500); - } }); it('should accept values at minimum boundary', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 1); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(1); - } }); it('should accept values at maximum boundary', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 999); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(999); - } }); it('should reject values below minimum', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 0); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values above maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerWithMinMax, 1000); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); }); @@ -210,17 +144,11 @@ describe('Number Type Min/Max Constraints Tests', () => { 0.1, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(0.1); - } }); it('should reject values at exclusive minimum', () => { const result = v.safeParse(generatedSchemas.vNumberWithExclusiveMin, 0); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values below exclusive minimum', () => { @@ -229,9 +157,6 @@ describe('Number Type Min/Max Constraints Tests', () => { -1, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -242,9 +167,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 99.9, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(99.9); - } }); it('should reject values at exclusive maximum', () => { @@ -253,9 +175,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 100, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values above exclusive maximum', () => { @@ -264,9 +183,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 101, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -277,9 +193,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 0.5, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(0.5); - } }); it('should reject values at exclusive minimum', () => { @@ -288,9 +201,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 0, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values at exclusive maximum', () => { @@ -299,9 +209,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 1, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -312,9 +219,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 11, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(11); - } }); it('should reject values at exclusive minimum', () => { @@ -323,9 +227,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 10, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values below exclusive minimum', () => { @@ -334,9 +235,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 9, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -347,9 +245,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 49, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(49); - } }); it('should reject values at exclusive maximum', () => { @@ -358,9 +253,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 50, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values above exclusive maximum', () => { @@ -369,9 +261,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 51, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -382,9 +271,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 10, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(10); - } }); it('should reject values at exclusive minimum', () => { @@ -393,9 +279,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 5, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values at exclusive maximum', () => { @@ -404,9 +287,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 15, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); }); @@ -419,9 +299,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 90, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(90); - } }); it('should accept values above exclusive minimum and below inclusive maximum', () => { @@ -430,9 +307,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 50, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(50); - } }); it('should reject values at exclusive minimum', () => { @@ -441,9 +315,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 10, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values above inclusive maximum', () => { @@ -452,9 +323,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 91, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -465,9 +333,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 20, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(20); - } }); it('should accept values above inclusive minimum and below exclusive maximum', () => { @@ -476,9 +341,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 50, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(50); - } }); it('should reject values below inclusive minimum', () => { @@ -487,9 +349,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 19, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values at exclusive maximum', () => { @@ -498,9 +357,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 80, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -511,9 +367,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 50, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(50); - } }); it('should accept values above exclusive minimum and below inclusive maximum', () => { @@ -522,9 +375,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 25, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(25); - } }); it('should reject values at exclusive minimum', () => { @@ -533,9 +383,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 5, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values above inclusive maximum', () => { @@ -544,9 +391,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 51, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); @@ -557,9 +401,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 10, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(10); - } }); it('should accept values above inclusive minimum and below exclusive maximum', () => { @@ -568,9 +409,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 55, ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(55); - } }); it('should reject values below inclusive minimum', () => { @@ -579,9 +417,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 9, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values at exclusive maximum', () => { @@ -590,9 +425,6 @@ describe('Number Type Min/Max Constraints Tests', () => { 100, ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); }); @@ -605,9 +437,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-5000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-5000000000000')); - } }); it('should accept BigInt values above minimum', () => { @@ -616,9 +445,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('0'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('0')); - } }); it('should reject BigInt values below minimum', () => { @@ -627,9 +453,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-5000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -640,9 +463,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('5000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('5000000000000')); - } }); it('should accept BigInt values below maximum', () => { @@ -651,9 +471,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('1000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('1000000000000')); - } }); it('should reject BigInt values above maximum', () => { @@ -662,9 +479,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('5000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -675,9 +489,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('0'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('0')); - } }); it('should accept BigInt values at minimum boundary', () => { @@ -686,9 +497,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-4000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-4000000000000')); - } }); it('should accept BigInt values at maximum boundary', () => { @@ -697,9 +505,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('4000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('4000000000000')); - } }); it('should reject BigInt values below minimum', () => { @@ -708,9 +513,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-4000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject BigInt values above maximum', () => { @@ -719,9 +521,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('4000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -732,9 +531,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-2999999999999'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-2999999999999')); - } }); it('should reject BigInt values at exclusive minimum', () => { @@ -743,9 +539,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-3000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -756,9 +549,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('2999999999999'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('2999999999999')); - } }); it('should reject BigInt values at exclusive maximum', () => { @@ -767,9 +557,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('3000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -780,9 +567,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('0'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('0')); - } }); it('should reject BigInt values at exclusive minimum', () => { @@ -791,9 +575,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-2000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject BigInt values at exclusive maximum', () => { @@ -802,9 +583,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('2000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -815,9 +593,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('6000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('6000000000000')); - } }); it('should accept values above exclusive minimum and below inclusive maximum', () => { @@ -826,9 +601,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('0'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('0')); - } }); it('should reject values at exclusive minimum', () => { @@ -837,9 +609,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-6000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject values above inclusive maximum', () => { @@ -848,9 +617,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('6000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -861,9 +627,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-7000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('-7000000000000')); - } }); it('should accept values above inclusive minimum and below exclusive maximum', () => { @@ -872,9 +635,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('0'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('0')); - } }); it('should reject values below inclusive minimum', () => { @@ -883,9 +643,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('-7000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject values at exclusive maximum', () => { @@ -894,9 +651,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('7000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); }); @@ -909,9 +663,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('5000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('5000000000000')); - } }); it('should accept BigInt values above minimum', () => { @@ -920,9 +671,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('8000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('8000000000000')); - } }); it('should reject BigInt values below minimum', () => { @@ -931,9 +679,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('4999999999999'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -944,9 +689,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('15000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('15000000000000')); - } }); it('should accept BigInt values below maximum', () => { @@ -955,9 +697,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('10000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('10000000000000')); - } }); it('should reject BigInt values above maximum', () => { @@ -966,9 +705,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('15000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -979,9 +715,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('5000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('5000000000000')); - } }); it('should accept BigInt values at minimum boundary', () => { @@ -990,9 +723,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('1000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('1000000000000')); - } }); it('should accept BigInt values at maximum boundary', () => { @@ -1001,9 +731,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('10000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('10000000000000')); - } }); it('should reject BigInt values below minimum', () => { @@ -1012,9 +739,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('999999999999'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject BigInt values above maximum', () => { @@ -1023,9 +747,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('10000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -1036,9 +757,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('8000000000001'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('8000000000001')); - } }); it('should reject BigInt values at exclusive minimum', () => { @@ -1047,9 +765,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('8000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -1060,9 +775,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('11999999999999'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('11999999999999')); - } }); it('should reject BigInt values at exclusive maximum', () => { @@ -1071,9 +783,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('12000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -1084,9 +793,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('5000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('5000000000000')); - } }); it('should reject BigInt values at exclusive minimum', () => { @@ -1095,9 +801,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('2000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject BigInt values at exclusive maximum', () => { @@ -1106,9 +809,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('8000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -1119,9 +819,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('13000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('13000000000000')); - } }); it('should accept values above exclusive minimum and below inclusive maximum', () => { @@ -1130,9 +827,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('8000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('8000000000000')); - } }); it('should reject values at exclusive minimum', () => { @@ -1141,9 +835,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('3000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject values above inclusive maximum', () => { @@ -1152,9 +843,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('13000000000001'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); @@ -1165,9 +853,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('4000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('4000000000000')); - } }); it('should accept values above inclusive minimum and below exclusive maximum', () => { @@ -1176,9 +861,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('9000000000000'), ); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(BigInt('9000000000000')); - } }); it('should reject values below inclusive minimum', () => { @@ -1187,9 +869,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('3999999999999'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); it('should reject values at exclusive maximum', () => { @@ -1198,9 +877,6 @@ describe('Number Type Min/Max Constraints Tests', () => { BigInt('14000000000000'), ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Expected'); - } }); }); }); @@ -1211,34 +887,22 @@ describe('Number Type Min/Max Constraints Tests', () => { // exclusiveMinimum: 5, minimum: 10 - exclusive should take precedence const result = v.safeParse(generatedSchemas.vPrecedenceTest, 6); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(6); - } }); it('should use exclusive constraints over inclusive (exclusive maximum takes precedence)', () => { // exclusiveMaximum: 95, maximum: 90 - exclusive should take precedence const result = v.safeParse(generatedSchemas.vPrecedenceTest, 94); expect(result.success).toBe(true); - if (result.success) { - expect(result.output).toBe(94); - } }); it('should reject values at exclusive minimum boundary', () => { const result = v.safeParse(generatedSchemas.vPrecedenceTest, 5); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); it('should reject values at exclusive maximum boundary', () => { const result = v.safeParse(generatedSchemas.vPrecedenceTest, 95); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain('Invalid value: Expected'); - } }); }); }); From d573e06501f263a4b046dd791bcf243568b3213f Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 09:50:37 +0200 Subject: [PATCH 07/10] refactor(valibot): extract number helper functions to separate file --- .../src/plugins/valibot/number-helpers.ts | 95 ++++++++++++++++++ .../openapi-ts/src/plugins/valibot/plugin.ts | 99 ++----------------- 2 files changed, 101 insertions(+), 93 deletions(-) create mode 100644 packages/openapi-ts/src/plugins/valibot/number-helpers.ts diff --git a/packages/openapi-ts/src/plugins/valibot/number-helpers.ts b/packages/openapi-ts/src/plugins/valibot/number-helpers.ts new file mode 100644 index 0000000000..bc75c42a21 --- /dev/null +++ b/packages/openapi-ts/src/plugins/valibot/number-helpers.ts @@ -0,0 +1,95 @@ +import { compiler } from '../../compiler'; + +// Integer format ranges and properties +export const INTEGER_FORMATS = { + int16: { + max: 32767, + maxError: 'Invalid value: Expected int16 to be <= 2^15-1', + min: -32768, + minError: 'Invalid value: Expected int16 to be >= -2^15', + needsBigInt: false, + }, + int32: { + max: 2147483647, + maxError: 'Invalid value: Expected int32 to be <= 2^31-1', + min: -2147483648, + minError: 'Invalid value: Expected int32 to be >= -2^31', + needsBigInt: false, + }, + int64: { + max: '9223372036854775807', + maxError: 'Invalid value: Expected int64 to be <= 2^63-1', + min: '-9223372036854775808', + minError: 'Invalid value: Expected int64 to be >= -2^63', + needsBigInt: true, + }, + int8: { + max: 127, + maxError: 'Invalid value: Expected int8 to be <= 2^7-1', + min: -128, + minError: 'Invalid value: Expected int8 to be >= -2^7', + needsBigInt: false, + }, + uint16: { + max: 65535, + maxError: 'Invalid value: Expected uint16 to be <= 2^16-1', + min: 0, + minError: 'Invalid value: Expected uint16 to be >= 0', + needsBigInt: false, + }, + uint32: { + max: 4294967295, + maxError: 'Invalid value: Expected uint32 to be <= 2^32-1', + min: 0, + minError: 'Invalid value: Expected uint32 to be >= 0', + needsBigInt: false, + }, + uint64: { + max: '18446744073709551615', + maxError: 'Invalid value: Expected uint64 to be <= 2^64-1', + min: '0', + minError: 'Invalid value: Expected uint64 to be >= 0', + needsBigInt: true, + }, + uint8: { + max: 255, + maxError: 'Invalid value: Expected uint8 to be <= 2^8-1', + min: 0, + minError: 'Invalid value: Expected uint8 to be >= 0', + needsBigInt: false, + }, +} as const; + +export type IntegerFormat = keyof typeof INTEGER_FORMATS; + +export const isIntegerFormat = ( + format: string | undefined, +): format is IntegerFormat => format !== undefined && format in INTEGER_FORMATS; + +export const needsBigIntForFormat = (format: string | undefined): boolean => + isIntegerFormat(format) && INTEGER_FORMATS[format].needsBigInt; + +export const numberParameter = ({ + isBigInt, + value, +}: { + isBigInt: boolean; + value: unknown; +}) => { + const expression = compiler.valueToExpression({ value }); + + if ( + isBigInt && + (typeof value === 'bigint' || + typeof value === 'number' || + typeof value === 'string' || + typeof value === 'boolean') + ) { + return compiler.callExpression({ + functionName: 'BigInt', + parameters: [expression], + }); + } + + return expression; +}; diff --git a/packages/openapi-ts/src/plugins/valibot/plugin.ts b/packages/openapi-ts/src/plugins/valibot/plugin.ts index 5e3bb55e7a..6ec86f477c 100644 --- a/packages/openapi-ts/src/plugins/valibot/plugin.ts +++ b/packages/openapi-ts/src/plugins/valibot/plugin.ts @@ -8,6 +8,12 @@ import type { StringCase, StringName } from '../../types/case'; import { numberRegExp } from '../../utils/regexp'; import { createSchemaComment } from '../shared/utils/schema'; import { identifiers, valibotId } from './constants'; +import { + INTEGER_FORMATS, + isIntegerFormat, + needsBigIntForFormat, + numberParameter, +} from './number-helpers'; import { operationToValibotSchema } from './operation'; import type { ValibotPlugin } from './types'; @@ -253,99 +259,6 @@ const nullTypeToValibotSchema = (_props: { return expression; }; -// Integer format ranges and properties -const INTEGER_FORMATS = { - int16: { - max: 32767, - maxError: 'Invalid value: Expected int16 to be <= 2^15-1', - min: -32768, - minError: 'Invalid value: Expected int16 to be >= -2^15', - needsBigInt: false, - }, - int32: { - max: 2147483647, - maxError: 'Invalid value: Expected int32 to be <= 2^31-1', - min: -2147483648, - minError: 'Invalid value: Expected int32 to be >= -2^31', - needsBigInt: false, - }, - int64: { - max: '9223372036854775807', - maxError: 'Invalid value: Expected int64 to be <= 2^63-1', - min: '-9223372036854775808', - minError: 'Invalid value: Expected int64 to be >= -2^63', - needsBigInt: true, - }, - int8: { - max: 127, - maxError: 'Invalid value: Expected int8 to be <= 2^7-1', - min: -128, - minError: 'Invalid value: Expected int8 to be >= -2^7', - needsBigInt: false, - }, - uint16: { - max: 65535, - maxError: 'Invalid value: Expected uint16 to be <= 2^16-1', - min: 0, - minError: 'Invalid value: Expected uint16 to be >= 0', - needsBigInt: false, - }, - uint32: { - max: 4294967295, - maxError: 'Invalid value: Expected uint32 to be <= 2^32-1', - min: 0, - minError: 'Invalid value: Expected uint32 to be >= 0', - needsBigInt: false, - }, - uint64: { - max: '18446744073709551615', - maxError: 'Invalid value: Expected uint64 to be <= 2^64-1', - min: '0', - minError: 'Invalid value: Expected uint64 to be >= 0', - needsBigInt: true, - }, - uint8: { - max: 255, - maxError: 'Invalid value: Expected uint8 to be <= 2^8-1', - min: 0, - minError: 'Invalid value: Expected uint8 to be >= 0', - needsBigInt: false, - }, -} as const; - -type IntegerFormat = keyof typeof INTEGER_FORMATS; - -const isIntegerFormat = (format: string | undefined): format is IntegerFormat => - format !== undefined && format in INTEGER_FORMATS; - -const needsBigIntForFormat = (format: string | undefined): boolean => - isIntegerFormat(format) && INTEGER_FORMATS[format].needsBigInt; - -const numberParameter = ({ - isBigInt, - value, -}: { - isBigInt: boolean; - value: unknown; -}) => { - const expression = compiler.valueToExpression({ value }); - - if ( - isBigInt && - (typeof value === 'bigint' || - typeof value === 'number' || - typeof value === 'string' || - typeof value === 'boolean') - ) { - return compiler.callExpression({ - functionName: 'BigInt', - parameters: [expression], - }); - } - - return expression; -}; - const numberTypeToValibotSchema = ({ schema, }: { From 41478080227b132a1b196d435cd6c75cc0ef7927 Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 10:03:40 +0200 Subject: [PATCH 08/10] test(valibot): remove redundant if conditions --- .../numberTypeToValibotSchema/formats.test.ts | 272 +++++++----------- 1 file changed, 102 insertions(+), 170 deletions(-) diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts index c25de6925d..6de9201537 100644 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts @@ -79,21 +79,17 @@ describe('Number Type Formats Tests', () => { it('should reject values below int8 minimum', () => { const result = v.safeParse(generatedSchemas.vNumberInt8, -129); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int8.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int8.minError, + ); }); it('should reject values above int8 maximum', () => { const result = v.safeParse(generatedSchemas.vNumberInt8, 128); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int8.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int8.maxError, + ); }); }); @@ -106,21 +102,17 @@ describe('Number Type Formats Tests', () => { it('should reject values below int16 minimum', () => { const result = v.safeParse(generatedSchemas.vNumberInt16, -32769); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int16.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int16.minError, + ); }); it('should reject values above int16 maximum', () => { const result = v.safeParse(generatedSchemas.vNumberInt16, 32768); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int16.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int16.maxError, + ); }); }); @@ -133,21 +125,17 @@ describe('Number Type Formats Tests', () => { it('should reject values below int32 minimum', () => { const result = v.safeParse(generatedSchemas.vNumberInt32, -2147483649); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int32.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int32.minError, + ); }); it('should reject values above int32 maximum', () => { const result = v.safeParse(generatedSchemas.vNumberInt32, 2147483648); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int32.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int32.maxError, + ); }); }); @@ -180,11 +168,9 @@ describe('Number Type Formats Tests', () => { '9223372036854775808', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int64.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int64.maxError, + ); }); }); @@ -197,21 +183,17 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vNumberUint8, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint8.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint8.minError, + ); }); it('should reject values above uint8 maximum', () => { const result = v.safeParse(generatedSchemas.vNumberUint8, 256); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint8.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint8.maxError, + ); }); }); @@ -224,21 +206,17 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vNumberUint16, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint16.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint16.minError, + ); }); it('should reject values above uint16 maximum', () => { const result = v.safeParse(generatedSchemas.vNumberUint16, 65536); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint16.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint16.maxError, + ); }); }); @@ -251,21 +229,17 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vNumberUint32, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint32.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint32.minError, + ); }); it('should reject values above uint32 maximum', () => { const result = v.safeParse(generatedSchemas.vNumberUint32, 4294967296); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint32.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint32.maxError, + ); }); }); @@ -284,11 +258,9 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vNumberUint64, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint64.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint64.minError, + ); }); it('should reject values above uint64 maximum', () => { @@ -297,11 +269,9 @@ describe('Number Type Formats Tests', () => { '18446744073709551616', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint64.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint64.maxError, + ); }); }); }); @@ -328,21 +298,17 @@ describe('Number Type Formats Tests', () => { it('should reject values below int8 minimum', () => { const result = v.safeParse(generatedSchemas.vIntegerInt8, -129); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int8.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int8.minError, + ); }); it('should reject values above int8 maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerInt8, 128); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int8.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int8.maxError, + ); }); }); @@ -355,21 +321,17 @@ describe('Number Type Formats Tests', () => { it('should reject values below int16 minimum', () => { const result = v.safeParse(generatedSchemas.vIntegerInt16, -32769); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int16.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int16.minError, + ); }); it('should reject values above int16 maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerInt16, 32768); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int16.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int16.maxError, + ); }); }); @@ -382,21 +344,17 @@ describe('Number Type Formats Tests', () => { it('should reject values below int32 minimum', () => { const result = v.safeParse(generatedSchemas.vIntegerInt32, -2147483649); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int32.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int32.minError, + ); }); it('should reject values above int32 maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerInt32, 2147483648); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int32.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int32.maxError, + ); }); }); @@ -429,11 +387,9 @@ describe('Number Type Formats Tests', () => { '9223372036854775808', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int64.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int64.maxError, + ); }); }); @@ -446,21 +402,17 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vIntegerUint8, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint8.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint8.minError, + ); }); it('should reject values above uint8 maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerUint8, 256); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint8.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint8.maxError, + ); }); }); @@ -473,21 +425,17 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vIntegerUint16, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint16.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint16.minError, + ); }); it('should reject values above uint16 maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerUint16, 65536); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint16.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint16.maxError, + ); }); }); @@ -500,21 +448,17 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vIntegerUint32, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint32.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint32.minError, + ); }); it('should reject values above uint32 maximum', () => { const result = v.safeParse(generatedSchemas.vIntegerUint32, 4294967296); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint32.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint32.maxError, + ); }); }); @@ -533,11 +477,9 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vIntegerUint64, -1); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint64.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint64.minError, + ); }); it('should reject values above uint64 maximum', () => { @@ -546,11 +488,9 @@ describe('Number Type Formats Tests', () => { '18446744073709551616', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint64.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint64.maxError, + ); }); }); }); @@ -574,11 +514,9 @@ describe('Number Type Formats Tests', () => { '-9223372036854775809', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int64.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int64.minError, + ); }); it('should reject values above int64 maximum', () => { @@ -587,11 +525,9 @@ describe('Number Type Formats Tests', () => { '9223372036854775808', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.int64.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.int64.maxError, + ); }); }); @@ -610,11 +546,9 @@ describe('Number Type Formats Tests', () => { it('should reject negative values', () => { const result = v.safeParse(generatedSchemas.vStringUint64, '-1'); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint64.minError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint64.minError, + ); }); it('should reject values above uint64 maximum', () => { @@ -623,11 +557,9 @@ describe('Number Type Formats Tests', () => { '18446744073709551616', ); expect(result.success).toBe(false); - if (!result.success) { - expect(result.issues[0].message).toContain( - FORMAT_BOUNDS.uint64.maxError, - ); - } + expect(result.issues![0].message).toContain( + FORMAT_BOUNDS.uint64.maxError, + ); }); }); }); From 84eea31307de549a54f0cdcd6527dba8a811e5f5 Mon Sep 17 00:00:00 2001 From: Daschi Date: Thu, 24 Jul 2025 11:14:14 +0200 Subject: [PATCH 09/10] test(valibot): remove redundant if conditions --- .../numberTypeToValibotSchema/formats.test.ts | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts index 6de9201537..3f1ce37bc0 100644 --- a/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts +++ b/packages/openapi-ts-tests/main/test/plugins/valibot/test/numberTypeToValibotSchema/formats.test.ts @@ -146,9 +146,7 @@ describe('Number Type Formats Tests', () => { 1000000000000, ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should validate string values within int64 range', () => { @@ -157,9 +155,7 @@ describe('Number Type Formats Tests', () => { '1000000000000', ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should reject values above int64 maximum', () => { @@ -250,9 +246,7 @@ describe('Number Type Formats Tests', () => { 1000000000000, ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should reject negative values', () => { @@ -365,9 +359,7 @@ describe('Number Type Formats Tests', () => { 1000000000000, ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should validate string values within int64 range', () => { @@ -376,9 +368,7 @@ describe('Number Type Formats Tests', () => { '1000000000000', ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should reject values above int64 maximum', () => { @@ -469,9 +459,7 @@ describe('Number Type Formats Tests', () => { 1000000000000, ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should reject negative values', () => { @@ -503,9 +491,7 @@ describe('Number Type Formats Tests', () => { '1000000000000', ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should reject values below int64 minimum', () => { @@ -538,9 +524,7 @@ describe('Number Type Formats Tests', () => { '1000000000000', ); expect(result.success).toBe(true); - if (result.success) { - expect(typeof result.output).toBe('bigint'); - } + expect(typeof result.output).toBe('bigint'); }); it('should reject negative values', () => { From fb7b7243663ca40bf79bd76bd7af7a9376474505 Mon Sep 17 00:00:00 2001 From: Lubos Date: Thu, 24 Jul 2025 17:47:08 +0800 Subject: [PATCH 10/10] Create stale-starfishes-sell.md --- .changeset/stale-starfishes-sell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/stale-starfishes-sell.md diff --git a/.changeset/stale-starfishes-sell.md b/.changeset/stale-starfishes-sell.md new file mode 100644 index 0000000000..13e5fcd181 --- /dev/null +++ b/.changeset/stale-starfishes-sell.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +fix(valibot): expand support for `format: int64`