### Full Configuration with Custom Schemas Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/exports.md Illustrates a comprehensive setup using Fastify with a custom JSON Schema to TS type provider. This example defines request and response schemas, registers them, and configures the Fastify instance with specific schema options, including date-time deserialization. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const requestSchema = { $id: 'request', type: 'object', properties: { data: { type: 'string' } } } as const satisfies JSONSchema const responseSchema = { $id: 'response', type: 'object', properties: { id: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' } } } as const satisfies JSONSchema const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [requestSchema] }, SerializerSchemaOptions: { references: [responseSchema], deserialize: [{ pattern: { type: 'string', format: 'date-time' }, output: Date }] } }> >() fastify.addSchema(requestSchema) fastify.addSchema(responseSchema) fastify.post('/', { schema: { body: { $ref: 'request#' }, response: { 200: { $ref: 'response#' } } } }, (req, reply) => { reply.send({ id: '123', timestamp: new Date() }) }) ``` -------------------------------- ### Full Example tsconfig.json Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/configuration.md A comprehensive tsconfig.json example including essential options for strict type checking, module resolution, and output configuration required for the JSON schema to TS type provider. ```json { "compilerOptions": { "target": "ES2020", "module": "ESNext", "lib": ["ES2020"], "moduleResolution": "node", "strict": true, "noStrictGenericChecks": false, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "declaration": true, "declarationMap": true, "outDir": "./dist" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "**/*.test.ts"] } ``` -------------------------------- ### Usage Example with Schema and Route Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Demonstrates how to use the plugin to define a schema and register a route with typed responses. ```APIDOC ## Usage Example ```typescript import { FastifyPluginCallbackJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const healthSchema = { $id: 'healthResponse', type: 'object', properties: { status: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' } }, required: ['status', 'timestamp'] } as const satisfies JSONSchema const healthPlugin: FastifyPluginCallbackJsonSchemaToTs<{ SerializerSchemaOptions: { references: [typeof healthSchema], deserialize: [ { pattern: { type: 'string', format: 'date-time' }, output: Date } ] } }> = (fastify, options, done) => { fastify.addSchema(healthSchema) fastify.get( '/health', { schema: { response: { 200: { $ref: 'healthResponse#' } } } }, (req, reply) => { reply.send({ status: 'healthy', timestamp: new Date() }) } ) done() } export default healthPlugin ``` ``` -------------------------------- ### Usage Example with Error Handling Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Illustrates how to implement error handling within the plugin registration. ```APIDOC ## With Error Handling ```typescript import { FastifyPluginCallbackJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' const initPlugin: FastifyPluginCallbackJsonSchemaToTs = ( fastify, options, done ) => { try { fastify.get('/init', async (req, reply) => { reply.send({ initialized: true }) }) done() } catch (error) { done(error as Error) } } export default initPlugin ``` ``` -------------------------------- ### Fastify Example with JsonSchemaToTsProvider Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/types.md Illustrates setting up a Fastify instance with JsonSchemaToTsProvider and defining a route with inferred body and response types from JSON Schema. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const productSchema = { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' }, price: { type: 'number', minimum: 0 } }, required: ['id', 'name', 'price'] } as const satisfies JSONSchema const fastify = Fastify().withTypeProvider() fastify.post( '/products', { schema: { body: productSchema } }, (req, reply) => { // req.body type is inferred as: { id: number, name: string, price: number } const { id, name, price } = req.body reply.send({ success: true, productId: id }) } ) ``` -------------------------------- ### Example Usage of FastifyPluginJsonSchemaToTsOptions Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/types.md Demonstrates how to define custom types for logger, plugin options, and server, and how to configure schema options with references. This setup enables full type safety for plugin configurations. ```typescript import { FastifyPluginJsonSchemaToTsOptions } from '@fastify/type-provider-json-schema-to-ts' import { FastifyPluginOptions, FastifyBaseLogger } from 'fastify' import type { JSONSchema } from 'json-schema-to-ts' import { Http2SecureServer } from 'http2' interface CustomLogger extends FastifyBaseLogger { custom(msg: string, level: string): void } interface ApiPluginOptions extends FastifyPluginOptions { apiKey: string timeout: number } const userSchema = { $id: 'user', type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' } } } as const satisfies JSONSchema type ApiPluginConfig = FastifyPluginJsonSchemaToTsOptions & { Options: ApiPluginOptions Server: Http2SecureServer Logger: CustomLogger ValidatorSchemaOptions: { references: [typeof userSchema] } } ``` -------------------------------- ### Async Plugin Example Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/exports.md Demonstrates how to define an asynchronous plugin using FastifyPluginAsyncJsonSchemaToTs. This pattern is suitable for plugins that perform asynchronous operations during their setup. ```typescript import { FastifyPluginAsyncJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' const plugin: FastifyPluginAsyncJsonSchemaToTs = async (fastify) => { fastify.get('/', (req, reply) => { reply.send({ ok: true }) }) } export default plugin ``` -------------------------------- ### Registering a Schema and Route Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Example of how to register a JSON schema and define a route that uses it for the response. This snippet demonstrates schema definition, adding it to Fastify, and configuring a GET request with a referenced response schema. ```typescript import { FastifyPluginCallbackJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const healthSchema = { $id: 'healthResponse', type: 'object', properties: { status: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' } }, required: ['status', 'timestamp'] } as const satisfies JSONSchema const healthPlugin: FastifyPluginCallbackJsonSchemaToTs <{ SerializerSchemaOptions: { references: [typeof healthSchema], deserialize: [ { pattern: { type: 'string', format: 'date-time' }, output: Date } ] } }> = (fastify, options, done) => { fastify.addSchema(healthSchema) fastify.get( '/health', { schema: { response: { 200: { $ref: 'healthResponse#' } } } }, (req, reply) => { reply.send({ status: 'healthy', timestamp: new Date() }) } ) done() } export default healthPlugin ``` -------------------------------- ### Install @fastify/type-provider-json-schema-to-ts Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/README.md Install the package using npm. Ensure you are using TypeScript 4.3 or above with strict mode enabled. ```bash npm i @fastify/type-provider-json-schema-to-ts ``` -------------------------------- ### Usage Example Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Demonstrates how to use JsonSchemaToTsProvider with Fastify to automatically type request bodies based on a JSON schema. ```APIDOC ## Usage Example ### Description This example shows how to integrate `JsonSchemaToTsProvider` with Fastify to leverage automatic TypeScript type inference for request bodies defined via JSON Schema. ### Code Example ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' const fastify = Fastify().withTypeProvider() fastify.get( '/', { schema: { body: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' } }, required: ['name', 'age'] } as const } }, (req, reply) => { // req.body is automatically typed as { name: string; age: number } const { name, age } = req.body reply.send({ greeting: `Hello ${name}, you are ${age} years old` }) } ) ``` ### Explanation - The `Fastify` instance is configured with `JsonSchemaToTsProvider` using `.withTypeProvider()`. - A route is defined with a `schema` object that includes a `body` property specifying the expected structure and types. - Inside the route handler, `req.body` is correctly typed as `{ name: string; age: number }`, allowing for type-safe access to its properties. ``` -------------------------------- ### Basic Usage Example Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Demonstrates how to integrate JsonSchemaToTsProvider with Fastify to automatically type request bodies based on a defined JSON schema. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' const fastify = Fastify().withTypeProvider() fastify.get( '/', { schema: { body: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' } }, required: ['name', 'age'] } as const } }, (req, reply) => { // req.body is automatically typed as { name: string; age: number } const { name, age } = req.body reply.send({ greeting: `Hello ${name}, you are ${age} years old` }) } ) ``` -------------------------------- ### Minimal Fastify Setup with Type Inference Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/usage-patterns.md Demonstrates the simplest way to integrate type inference for request bodies using @fastify/type-provider-json-schema-to-ts. Ensure Fastify and the type provider are imported. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' const fastify = Fastify().withTypeProvider() fastify.get('/', { schema: { body: { type: 'object', properties: { message: { type: 'string' } }, required: ['message'] } } }, (req, reply) => { // req.body is automatically typed as { message: string } console.log(req.body.message) reply.send({ received: req.body.message }) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Callback Plugin with Options Example Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/exports.md Shows how to create a callback-based plugin that accepts options, using FastifyPluginCallbackJsonSchemaToTs. This is useful for plugins that require configuration during instantiation. ```typescript import { FastifyPluginCallbackJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' interface PluginOpts { namespace: string } const plugin: FastifyPluginCallbackJsonSchemaToTs<{ Options: PluginOpts }> = (fastify, opts, done) => { fastify.get(`/${opts.namespace}/health`, (req, reply) => { reply.send({ ok: true }) }) done() } export default plugin ``` -------------------------------- ### Example Usage of JsonSchemaToTsProviderOptions Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/types.md Demonstrates how to configure JsonSchemaToTsProviderOptions with shared schemas and custom deserialization for date-time formats. ```typescript import { JsonSchemaToTsProviderOptions } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const sharedSchema = { $id: 'shared', definitions: { user: { type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' } } } } } as const satisfies JSONSchema const options: JsonSchemaToTsProviderOptions = { ValidatorSchemaOptions: { references: [sharedSchema] }, SerializerSchemaOptions: { references: [sharedSchema], deserialize: [ { pattern: { type: 'string', format: 'date-time' }, output: Date } ] } } ``` -------------------------------- ### Example Plugin with Custom Options and Types Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Demonstrates how to define a plugin using `FastifyPluginAsyncJsonSchemaToTs` with custom options, a specific server type, and schema options for validation and serialization. The comments show the resolved types for the `fastify` instance and `options` parameter within the plugin. ```typescript interface MyPluginOptions extends FastifyPluginOptions { timeout: number } const myPlugin: FastifyPluginAsyncJsonSchemaToTs<{ Options: MyPluginOptions, Server: Http2SecureServer, ValidatorSchemaOptions: { references: [schema1] }, SerializerSchemaOptions: { references: [schema2] } }> = async (fastify, options) => { // Resolves to: // fastify: FastifyInstance< // Http2SecureServer, // RawRequestDefaultExpression, // RawReplyDefaultExpression, // FastifyBaseLogger, // JsonSchemaToTsProvider<{ // ValidatorSchemaOptions: { references: [schema1] }, // SerializerSchemaOptions: { references: [schema2] } // }> // > // options: MyPluginOptions } ``` -------------------------------- ### Async Plugin with Custom Options Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Example of an async Fastify plugin configured with custom options, demonstrating type-safe access to these options within the plugin. ```typescript import { FastifyPluginAsyncJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import type { FastifyPluginOptions, FastifyPluginAsync } from 'fastify' interface PluginOptions extends FastifyPluginOptions { prefix: string timeout: number } const customPlugin: FastifyPluginAsyncJsonSchemaToTs<{ Options: PluginOptions }> = async (fastify, options) => { // options.prefix and options.timeout are type-safe fastify.get(`${options.prefix}/health`, async (req, reply) => { reply.send({ status: 'ok' }) }) } export default customPlugin ``` -------------------------------- ### Minimal Fastify Example with Type Provider Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md A basic Fastify application demonstrating the integration of JsonSchemaToTsProvider for type-safe request handling, including schema definition and type inference for request body properties. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' const fastify = Fastify().withTypeProvider() fastify.get('/', { schema: { body: { type: 'object', properties: { x: { type: 'string' } } } } }, (req, reply) => { console.log(req.body.x) // Type: string | undefined reply.send({ ok: true }) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Define and Use JSON Schema with Fastify Callback Plugin Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/README.md This example demonstrates using a JSON schema with a Fastify callback-style plugin. It shows how to define the schema and register a route that references it for request and response handling. The `FastifyPluginCallbackJsonSchemaToTs` utility ensures type safety for the plugin and its options. ```typescript const callbackPlugin: FastifyPluginCallbackJsonSchemaToTs<{ ValidatorSchemaOptions: { references: [typeof schemaPerson] } SerializerSchemaOptions: { references: [typeof schemaPerson] deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }] }; }> = (fastify, options, done) => { // Type check for custom options expectType(options.optionA) // Schema is already added above // fastify.addSchema(schemaPerson); fastify.get( "/callback-profile", { schema: { body: { type: "object", properties: { user: { $ref: "schema:person" }, }, required: ["user"], }, response: { 200: { $ref: "schema:person" }, }, }, }, (req, reply) => { const { givenName, familyName, joinedAt } = req.body.user reply.send({ givenName, familyName, joinedAt: new Date(), }); } ); done() }; ``` -------------------------------- ### Schema with References Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/configuration.md Utilize JSON schema references to reuse schema definitions across different routes. This example defines a 'userBase' schema and references it in a POST route's body schema. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const userBase = { $id: 'userBase', type: 'object', properties: { id: { type: 'string' }, email: { type: 'string', format: 'email' } }, required: ['id', 'email'] } as const satisfies JSONSchema const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [userBase] } }> >() fastify.addSchema(userBase) fastify.post('/users', { schema: { body: { allOf: [ { $ref: 'userBase#' }, { type: 'object', properties: { password: { type: 'string' } }, required: ['password'] } ] } } }, (req, reply) => { // req.body: { id: string, email: string, password: string } reply.send({ created: true }) }) ``` -------------------------------- ### Callback Plugin with JSON Schema Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/types.md Example of a callback-style Fastify plugin using JSON Schema for type inference. This plugin defines a route with a custom namespace option, demonstrating how to pass options to the plugin. ```typescript import { FastifyPluginCallbackJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' interface ServiceOptions { namespace: string } const servicePlugin: FastifyPluginCallbackJsonSchemaToTs<{ Options: ServiceOptions }> = (fastify, options, done) => { const { namespace } = options fastify.get(`/${namespace}/status`, (req, reply) => { reply.send({ status: 'ok', namespace }) }) done() } export default servicePlugin ``` -------------------------------- ### Async Plugin with Schema Definition and Routes Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Example of an async Fastify plugin using JSON Schema to TypeScript for request body and response validation. It demonstrates adding schemas and defining routes with type-safe request and response payloads. ```typescript import { FastifyPluginAsyncJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const userSchema = { $id: 'user', type: 'object', properties: { id: { type: 'string' }, email: { type: 'string', format: 'email' }, name: { type: 'string' } }, required: ['id', 'email', 'name'] } as const satisfies JSONSchema const usersPlugin: FastifyPluginAsyncJsonSchemaToTs<{ ValidatorSchemaOptions: { references: [typeof userSchema] } }> = async (fastify) => { fastify.addSchema(userSchema) fastify.get( '/users/:id', { schema: { response: { 200: { $ref: 'user#' } } } }, async (req, reply) => { // fastify.database is a custom property const user = await fastify.database.users.findById(req.params.id) reply.send(user) } ) fastify.post( '/users', { schema: { body: { $ref: 'user#' }, response: { 201: { $ref: 'user#' } } } }, async (req, reply) => { const newUser = await fastify.database.users.create(req.body) reply.code(201).send(newUser) } ) } export default usersPlugin ``` -------------------------------- ### Conditional Request and Response Schemas Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/usage-patterns.md This example demonstrates how to define separate schemas for request bodies and response payloads, allowing for different structures and validation rules. It configures the type provider to use specific schemas for validation and serialization. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' // Request schema (what client sends) const createPostInput = { $id: 'createPostInput', type: 'object', properties: { title: { type: 'string' }, content: { type: 'string' }, tags: { type: 'array', items: { type: 'string' } } }, required: ['title', 'content'] } as const satisfies JSONSchema // Response schema (what server returns) const postOutput = { $id: 'postOutput', type: 'object', properties: { id: { type: 'string' }, title: { type: 'string' }, content: { type: 'string' }, tags: { type: 'array', items: { type: 'string' } }, createdAt: { type: 'string', format: 'date-time' }, updatedAt: { type: 'string', format: 'date-time' }, authorId: { type: 'string' }, views: { type: 'integer', minimum: 0 } }, required: ['id', 'title', 'content', 'createdAt', 'updatedAt', 'authorId', 'views'] } as const satisfies JSONSchema const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [createPostInput] }, SerializerSchemaOptions: { references: [postOutput], deserialize: [{ pattern: { type: 'string', format: 'date-time' }, output: Date }] } }> >() fastify.addSchema(createPostInput) fastify.addSchema(postOutput) fastify.post( '/posts', { schema: { body: { $ref: 'createPostInput#' }, response: { 201: { $ref: 'postOutput#' } } } }, async (req, reply) => { // req.body is { title: string; content: string; tags?: string[] } const { title, content, tags } = req.body // Response is { id, title, content, tags, createdAt: Date, updatedAt: Date, authorId, views } const post = { id: crypto.randomUUID(), title, content, tags: tags || [], createdAt: new Date(), updatedAt: new Date(), authorId: 'current-user-id', views: 0 } reply.code(201).send(post) } ) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Using Schema References with $ref Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md Reference schemas using `$ref` to avoid duplication. This example shows how to define a `postSchema` that references a `userSchema` using `$ref: 'user#'`. Ensure to configure `references` in `ValidatorSchemaOptions`. ```typescript const userSchema = { $id: 'user', /* ... */ } const postSchema = { $id: 'post', type: 'object', properties: { author: { $ref: 'user#' } } } const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [userSchema, postSchema] } }> >() ``` -------------------------------- ### Basic Import Pattern Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/exports.md Demonstrates the simplest way to import and use the type provider without any custom configuration. This is suitable for straightforward applications. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' const fastify = Fastify().withTypeProvider() fastify.get('/', { schema: { body: { type: 'object', properties: { name: { type: 'string' } } } } }, (req) => { // req.body is typed automatically }) ``` -------------------------------- ### Fastify with JsonSchemaToTsProvider Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md Integrate JsonSchemaToTsProvider with Fastify to enable automatic type inference for request bodies based on JSON Schema definitions. The inferred type for `req.body` will be `{ name: string }` in this example. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' const fastify = Fastify().withTypeProvider() fastify.get('/', { schema: { body: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] } } }, (req, reply) => { // req.body is automatically typed as { name: string } reply.send({ greeting: `Hello ${req.body.name}` }) }) ``` -------------------------------- ### Using JsonSchemaToTsProvider Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md Demonstrates how to integrate JsonSchemaToTsProvider with Fastify to enable schema-based type inference for routes. ```typescript withTypeProvider() withTypeProvider>() ``` -------------------------------- ### Optimizing Schema Reuse with References Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Demonstrates how reusing schemas via references (`$ref`) is faster than inline definitions because the schema is inferred only once. This improves build times for complex schemas. ```typescript // Faster (schema defined once) fastify.post('/', { schema: { body: { $ref: 'user#' } } }, handler) fastify.put('/', { schema: { body: { $ref: 'user#' } } }, handler) // Slower (schema inference repeated) fastify.post('/', { schema: { body: userSchema } }, handler) fastify.put('/', { schema: { body: userSchema } }, handler) ``` -------------------------------- ### Schema as Type Definition Example Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md Define JSON Schemas directly and let the library infer TypeScript types, avoiding the need for separate interface definitions. This approach leverages the `satisfies JSONSchema` for type safety. ```typescript const userSchema = { $id: 'user', type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, email: { type: 'string', format: 'email' } }, required: ['id', 'name', 'email'] } as const satisfies JSONSchema // Type is automatically inferred when used in routes ``` -------------------------------- ### Main Exports Overview Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/INDEX.md Provides a quick reference to the main types exported by the library, including the core type provider, configuration options, and plugin types. ```typescript // Main type provider JsonSchemaToTsProvider // Configuration options JsonSchemaToTsProviderOptions // Plugin configuration FastifyPluginJsonSchemaToTsOptions // Plugin types FastifyPluginAsyncJsonSchemaToTs FastifyPluginCallbackJsonSchemaToTs ``` -------------------------------- ### Handling Circular References in JSON Schema Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Provides an example of a circular reference in JSON Schema using `$ref`. While `json-schema-to-ts` handles this, TypeScript's type display might be limited due to potential infinite recursion. ```typescript const listSchema = { $id: 'list', type: 'array', items: { $ref: 'list#' } // Circular! } as const satisfies JSONSchema // This may cause TypeScript errors due to infinite recursion // json-schema-to-ts handles this, but TypeScript's display may be limited ``` -------------------------------- ### Async Plugin with JSON Schema Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/types.md Example of an asynchronous Fastify plugin using JSON Schema to define request/response types. It adds a schema and defines a route that uses this schema for responses. Date objects are automatically serialized. ```typescript import { FastifyPluginAsyncJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' const postSchema = { $id: 'post', type: 'object', properties: { id: { type: 'string' }, title: { type: 'string' }, content: { type: 'string' }, createdAt: { type: 'string', format: 'date-time' } }, required: ['id', 'title', 'content', 'createdAt'] } as const satisfies JSONSchema const postsPlugin: FastifyPluginAsyncJsonSchemaToTs<{ SerializerSchemaOptions: { references: [typeof postSchema], deserialize: [ { pattern: { type: 'string', format: 'date-time' }, output: Date } ] } }> = async (fastify) => { fastify.addSchema(postSchema) fastify.get('/posts/:id', { schema: { response: { 200: { $ref: 'post#' } } } }, async (req, reply) => { // Response must match post schema; Date objects auto-serialize reply.send({ id: '1', title: 'Hello', content: 'World', createdAt: new Date() }) }) } export default postsPlugin ``` -------------------------------- ### Plugin Registration Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/api-reference.md Details the parameters and return type for registering the Fastify plugin. ```APIDOC ## Plugin Parameters The plugin function receives three parameters: | Parameter | Type | Description | |-----------|------|-------------| | `fastify` | `FastifyInstance` | Fastify instance with JsonSchemaToTsProvider type applied. Provides route registration methods. | | `options` | `FastifyPluginOptions` | Plugin options passed during registration. Type is inferred from Options generic parameter. | | `done` | `(err?: Error) => void` | Callback function to signal completion. Pass an Error to indicate failure. | ### Return Type `void` - The plugin is synchronous with a callback-based completion pattern. ``` -------------------------------- ### Define and Version Schemas with References Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/configuration.md Demonstrates how to define a JSON schema with a version identifier ($id) and use it as a reference within the Fastify type provider configuration. This approach ensures schemas are treated as literal types for precise inference and supports schema evolution. ```typescript import Fastify from 'fastify' import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' // Define and version schemas const userV1 = { $id: 'user:v1', type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, email: { type: 'string' } }, required: ['id', 'name', 'email'] } as const satisfies JSONSchema const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [userV1] } }> >() fastify.addSchema(userV1) // Routes using versioned schema fastify.get('/users/:id', { schema: { response: { 200: { $ref: 'user:v1#' } } } }, (req, reply) => { reply.send({ id: '1', name: 'John', email: 'john@example.com' }) }) ``` -------------------------------- ### Advanced Schema Configuration with References and Deserialization Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/README.md Configure `FromSchema` with schema references and custom deserialization rules for validation and serialization. This allows for advanced type handling, such as converting date-time strings to Date objects. ```typescript const userSchema = { type: "object", additionalProperties: false, properties: { givenName: { type: "string" }, familyName: { type: "string" }, }, required: ["givenName", "familyName"], } as const satisfies JSONSchema; const sharedSchema = { $id: "shared-schema", definitions: { user: userSchema, }, } as const satisfies JSONSchema; const userProfileSchema = { $id: "userProfile", type: "object", additionalProperties: false, properties: { user: { $ref: "shared-schema#/definitions/user", }, joinedAt: { type: "string", format: "date-time" }, }, required: ["user", "joinedAt"] } as const satisfies JSONSchema type UserProfile = FromSchema; // Use JsonSchemaToTsProvider with shared schema references const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [typeof sharedSchema] } SerializerSchemaOptions: { references: [typeof userProfileSchema] deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }] } }> >() fastify.get( "/profile", { schema: { body: { type: "object", properties: { user: { $ref: "shared-schema#/definitions/user", }, }, required: ['user'], }, response: { 200: { $ref: "userProfile#" }, }, } as const, }, (req, reply) => { // `givenName` and `familyName` are correctly typed as strings const { givenName, familyName } = req.body.user; // Construct a compatible response type const profile: UserProfile = { user: { givenName: "John", familyName: "Doe" }, joinedAt: new Date(), // Returning a Date object }; // A type error is surfaced if profile doesn't match the serialization schema reply.send(profile) } ) ``` -------------------------------- ### Basic Type Provider Usage Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/exports.md Instantiates Fastify with the basic JsonSchemaToTsProvider for automatic type inference. Use this when no special schema options are needed. ```typescript const fastify = Fastify().withTypeProvider() const fastifyWithOptions = Fastify().withTypeProvider< JsonSchemaToTsProvider({ ValidatorSchemaOptions: { references: [userSchema] } }) >() ``` -------------------------------- ### Schema Validation vs. Type Inference Mismatch Example Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Highlights a potential mismatch between TypeScript type inference and runtime validation when a schema is missing the `required` field. Use `required: [...]` in your schema to ensure both type safety and validation. ```typescript // This compiles but has runtime validation mismatch: const schema = { type: 'object', properties: { x: { type: 'string' } } } as const satisfies JSONSchema const fastify = Fastify().withTypeProvider() fastify.get('/', { schema: { body: schema } }, (req) => { // TypeScript: req.body: { x?: string } (optional because not in required) // But Fastify validation might allow it anyway }) ``` -------------------------------- ### FromSchema with References Option Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Illustrates how to use the `FromSchema` utility with the `references` option to resolve `$ref` pointers within a JSON schema. This is useful when schemas depend on other defined schemas. ```typescript interface FromSchemaOptions { references?: readonly JSONSchema[] } // Usage: type User = FromSchema<{ $ref: 'user#' }, { references: [userSchema] }> ``` -------------------------------- ### Callback Plugin Signature with Schema Inference Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md Illustrates the type signature for a callback-style Fastify plugin that supports schema-based type inference. ```typescript (fastify: FastifyInstance, options: PluginOptions, done: (err?: Error) => void) => void ``` -------------------------------- ### Route Handler Typing with JsonSchemaToTsProvider Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Illustrates how Fastify infers route handler parameter types using `JsonSchemaToTsProvider`. It explains how `options.schema` and `TypeProvider` are used to determine types for `req.body`, `req.params`, `req.querystring`, and the `reply` parameter. ```typescript fastify.get(path, options, handler) // Fastify's overloads look at: // 1. options.schema to determine request/response types // 2. TypeProvider to infer those types from schema // 3. Handler parameters are typed based on inference // If TypeProvider is JsonSchemaToTsProvider: // - req.body is FromSchema // - req.params is FromSchema // - req.querystring is FromSchema // - reply parameter is typed for schema.response ``` -------------------------------- ### Optimizing Validator and Serializer Options Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Shows how to optimize performance by sharing validator and serializer options. Computing independent options can be slower than using shared ones. ```typescript // Faster (shared options) const provider = JsonSchemaToTsProvider<{ ValidatorSchemaOptions: opts }> // Slower (independent options to compute) const provider = JsonSchemaToTsProvider<{ ValidatorSchemaOptions: opts1, SerializerSchemaOptions: opts2 }> ``` -------------------------------- ### Plugin with Server Type and Schema Options Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/configuration.md Configure a Fastify plugin to use a specific server type (e.g., Http2SecureServer) and define serializer schema options. This allows for type-safe handling of server instances and response schemas. ```typescript import { FastifyPluginAsyncJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import { createSecureServer } from 'http2' import { Http2SecureServer } from 'http2' import Fastify from 'fastify' import type { JSONSchema } from 'json-schema-to-ts' const healthSchema = { $id: 'health', type: 'object', properties: { status: { type: 'string' }, uptime: { type: 'number' } }, required: ['status', 'uptime'] } as const satisfies JSONSchema const healthPlugin: FastifyPluginAsyncJsonSchemaToTs<{ Server: Http2SecureServer, SerializerSchemaOptions: { references: [healthSchema] } }> = async (fastify) => { fastify.addSchema(healthSchema) fastify.get('/health', { schema: { response: { 200: { $ref: 'health#' } } } }, (req, reply) => { // fastify.server is typed as Http2SecureServer reply.send({ status: 'healthy', uptime: process.uptime() }) }) } // Create HTTP/2 server with type support const fastify = Fastify({ http2: true, https: { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') } }).withTypeProvider< JsonSchemaToTsProvider<{ SerializerSchemaOptions: { references: [healthSchema] } }> >() fastify.register(healthPlugin) ``` -------------------------------- ### Troubleshooting: $ref is not resolving Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/README.md Fixes '$ref is not resolving' issues by adding the schema to both the reference array and `fastify.addSchema()`. ```typescript const fastify = Fastify().withTypeProvider< JsonSchemaToTsProvider<{ ValidatorSchemaOptions: { references: [userSchema] } }> >() fastify.addSchema(userSchema) ``` -------------------------------- ### Fastify Instance withTypeProvider Declaration Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Shows the declaration for Fastify's `withTypeProvider` method, which accepts a type implementing `FastifyTypeProvider` and stores it on the instance for type inference. ```typescript declare class FastifyInstance { withTypeProvider(): FastifyInstance< Server, Request, Reply, Logger, TypeProvider > } ``` -------------------------------- ### FromSchema with Deserialization Option Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/implementation-reference.md Shows how to configure `FromSchema` to deserialize specific data formats, such as date-time strings, into TypeScript types like `Date`. This is achieved using the `deserialize` option with a pattern and its corresponding output type. ```typescript interface FromSchemaOptions { deserialize?: readonly { pattern: JSONSchema output: any }[] } // Usage: type Event = FromSchema ``` -------------------------------- ### Importing Core Exports Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/exports.md Imports all essential types and interfaces from the package root. These are the building blocks for using the type provider. ```typescript import { JsonSchemaToTsProvider, JsonSchemaToTsProviderOptions, FastifyPluginAsyncJsonSchemaToTs, FastifyPluginCallbackJsonSchemaToTs, FastifyPluginJsonSchemaToTsOptions } from '@fastify/type-provider-json-schema-to-ts' ``` -------------------------------- ### Organize Code with Typed Plugins Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/_autodocs/usage-patterns.md Structure your Fastify application using reusable, typed plugins. This pattern demonstrates how to define shared schemas and register multiple plugins, including a health check and a products API, with type safety. ```typescript import Fastify from 'fastify' import { FastifyPluginAsyncJsonSchemaToTs } from '@fastify/type-provider-json-schema-to-ts' import type { JSONSchema } from 'json-schema-to-ts' // Shared schemas const productSchema = { $id: 'product', type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, price: { type: 'number', minimum: 0 }, inStock: { type: 'boolean' } }, required: ['id', 'name', 'price', 'inStock'] } as const satisfies JSONSchema // Products plugin const productsPlugin: FastifyPluginAsyncJsonSchemaToTs<{ SerializerSchemaOptions: { references: [productSchema] } }> = async (fastify) => { fastify.addSchema(productSchema) fastify.get( '/products', { schema: { response: { 200: { type: 'array', items: { $ref: 'product#' } } } } }, async (req, reply) => { const products = [ { id: '1', name: 'Widget', price: 9.99, inStock: true }, { id: '2', name: 'Gadget', price: 19.99, inStock: false } ] reply.send(products) } ) fastify.get( '/products/:id', { schema: { response: { 200: { $ref: 'product#' } } } }, async (req, reply) => { const product = { id: req.params.id, name: 'Widget', price: 9.99, inStock: true } reply.send(product) } ) } // Health check plugin const healthPlugin: FastifyPluginAsyncJsonSchemaToTs = async (fastify) => { fastify.get('/health', (req, reply) => { reply.send({ status: 'ok' }) }) } // Main application async function main() { const fastify = Fastify().withTypeProvider() fastify.register(healthPlugin) fastify.register(productsPlugin, { prefix: '/api' }) await fastify.listen({ port: 3000 }) } main() ``` -------------------------------- ### Basic Plugin Definition with Type Inference Source: https://github.com/fastify/fastify-type-provider-json-schema-to-ts/blob/main/README.md Define a Fastify plugin with automatic type inference for request bodies based on JSON schema. `withTypeProvider` is not required when using plugin types. ```typescript const plugin: FastifyPluginAsyncJsonSchemaToTs = async function ( fastify, _opts ) { fastify.get( "/", { schema: { body: { type: "object", properties: { x: { type: "string" }, y: { type: "number" }, z: { type: "boolean" }, }, required: ["x", "y", "z"], } as const, }, }, (req) => { // The `x`, `y`, and `z` types are automatically inferred const { x, y, z } = req.body; } ); }; ```