Smart Coercion Plugin
Automatically converts input values to match schema types without manually defining coercion logic.
WARNING
This plugin improves developer experience but impacts performance. For high-performance applications or complex schemas, manually defining coercion in your schema validation is more efficient.
Installation
npm install @orpc/json-schema@latest
yarn add @orpc/json-schema@latest
pnpm add @orpc/json-schema@latest
bun add @orpc/json-schema@latest
deno install npm:@orpc/json-schema@latest
Setup
Configure the plugin with JSON Schema Converters for your validation libraries.
import { OpenAPIHandler } from '@orpc/openapi/fetch'
import {
experimental_SmartCoercionPlugin as SmartCoercionPlugin
} from '@orpc/json-schema'
const handler = new OpenAPIHandler(router, {
plugins: [
new SmartCoercionPlugin({
schemaConverters: [
new ZodToJsonSchemaConverter(),
// Add other schema converters as needed
],
})
]
})
How It Works
The plugin converts values safely using these rules:
- Schema-guided: Only converts when the schema says what type to use
- Safe only: Only converts values that make sense (like
'123'
to123
) - Keep original: If conversion is unsafe, keeps the original value
- Smart unions: Picks the best conversion for union types
- Deep conversion: Works inside nested objects and arrays
INFO
JavaScript native types such as BigInt, Date, RegExp, URL, Set, and Map are not natively supported by JSON Schema. To enable correct coercion, oRPC relies on the x-native-type
metadata in your schema:
x-native-type: 'bigint'
for BigIntx-native-type: 'date'
for Datex-native-type: 'regexp'
for RegExpx-native-type: 'url'
for URLx-native-type: 'set'
for Setx-native-type: 'map'
for Map
The built-in JSON Schema Converters handle these cases (except for some experimental converters). Since this approach is not part of the official JSON Schema specification, if you use a custom converter, you may need to add the appropriate x-native-type
metadata to your schemas to ensure proper coercion.
Conversion Rules
String → Boolean
Support specific string values (case-insensitive):
'true'
,'on'
→true
'false'
,'off'
→false
INFO
HTML <input type="checkbox">
elements submit 'on'
or 'off'
as values, so this conversion is especially useful for handling checkbox input in forms.
String → Number
Support valid numeric strings:
'123'
→123
'3.14'
→3.14
String/Number → BigInt
Support valid numeric strings or numbers:
'12345678901234567890'
→12345678901234567890n
12345678901234567890
→12345678901234567890n
String → Date
Support ISO date/datetime strings:
'2023-10-01'
→new Date('2023-10-01')
'2020-01-01T06:15'
→new Date('2020-01-01T06:15')
'2020-01-01T06:15Z'
→new Date('2020-01-01T06:15Z')
'2020-01-01T06:15:00Z'
→new Date('2020-01-01T06:15:00Z')
'2020-01-01T06:15:00.123Z'
→new Date('2020-01-01T06:15:00.123Z')
String → RegExp
Support valid regular expression strings:
'/^\\d+$/i'
→new RegExp('^\\d+$', 'i')
'/abc/'
→new RegExp('abc')
String → URL
Support valid URL strings:
'https://example.com'
→new URL('https://example.com')
Array → Set
Support arrays of unique values:
['apple', 'banana']
→new Set(['apple', 'banana'])
Array → Object
Converts arrays to objects with numeric keys:
['apple', 'banana']
→{ 0: 'apple', 1: 'banana' }
INFO
This is particularly useful for Bracket Notation when you need objects with numeric keys.
Array → Map
Support arrays of key-value pairs:
[['key1', 'value1'], ['key2', 'value2']]
→new Map([['key1', 'value1'], ['key2', 'value2']])