import { expect } from 'tstyche' import fastifyPlugin from '.' import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify' import { Server } from 'node:https' import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox' import fastifyExampleCallback from './example-callback.tst' import fastifyExampleAsync from './example-async.tst' interface Options { foo: string; } const testSymbol = Symbol('foobar') const pluginCallback: FastifyPluginCallback = (_fastify, _options, _next) => {} expect(fastifyPlugin(pluginCallback)).type.toBe() const pluginCallbackWithTypes = ( _fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void ): void => {} expect( fastifyPlugin(pluginCallbackWithTypes) ).type.toBeAssignableTo() expect( fastifyPlugin( ( _fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void ): void => {} ) ).type.toBeAssignableTo() expect(fastifyPlugin(pluginCallback, '')).type.toBe() expect( fastifyPlugin(pluginCallback, { fastify: '', name: '', decorators: { fastify: ['', testSymbol], reply: ['', testSymbol], request: ['', testSymbol] }, dependencies: [''], encapsulate: true }) ).type.toBe() const pluginCallbackWithOptions: FastifyPluginCallback = ( _fastify, options, _next ) => { expect(options.foo).type.toBe() } expect(fastifyPlugin(pluginCallbackWithOptions)).type.toBe< FastifyPluginCallback >() const pluginCallbackWithServer: FastifyPluginCallback = ( fastify, _options, _next ) => { expect(fastify.server).type.toBe() } expect(fastifyPlugin(pluginCallbackWithServer)).type.toBe< FastifyPluginCallback >() const pluginCallbackWithTypeProvider: FastifyPluginCallback< Options, Server, TypeBoxTypeProvider > = (_fastify, _options, _next) => {} expect(fastifyPlugin(pluginCallbackWithTypeProvider)).type.toBe< FastifyPluginCallback >(); (async () => { const pluginAsync: FastifyPluginAsync = async (_fastify, _options) => {} expect(fastifyPlugin(pluginAsync)).type.toBe() const pluginAsyncWithTypes = async ( _fastify: FastifyInstance, _options: FastifyPluginOptions ): Promise => {} expect(fastifyPlugin(pluginAsyncWithTypes)).type.toBe< FastifyPluginAsync< FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault > >() expect( fastifyPlugin( async ( _fastify: FastifyInstance, _options: FastifyPluginOptions ): Promise => {} ) ).type.toBe< FastifyPluginAsync< FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault > >() expect(fastifyPlugin(pluginAsync, '')).type.toBe() expect( fastifyPlugin(pluginAsync, { fastify: '', name: '', decorators: { fastify: ['', testSymbol], reply: ['', testSymbol], request: ['', testSymbol] }, dependencies: [''], encapsulate: true }) ).type.toBe() const pluginAsyncWithOptions: FastifyPluginAsync = async ( _fastify, options ) => { expect(options.foo).type.toBe() } expect(fastifyPlugin(pluginAsyncWithOptions)).type.toBe< FastifyPluginAsync >() const pluginAsyncWithServer: FastifyPluginAsync = async ( fastify, _options ) => { expect(fastify.server).type.toBe() } expect(fastifyPlugin(pluginAsyncWithServer)).type.toBe< FastifyPluginAsync >() const pluginAsyncWithTypeProvider: FastifyPluginAsync< Options, Server, TypeBoxTypeProvider > = async (_fastify, _options) => {} expect(fastifyPlugin(pluginAsyncWithTypeProvider)).type.toBe< FastifyPluginAsync >() const server = fastify() server.register(fastifyPlugin(pluginCallback)) server.register(fastifyPlugin(pluginCallbackWithTypes), { foo: 'bar' }) server.register(fastifyPlugin(pluginCallbackWithOptions), { foo: 'bar' }) server.register(fastifyPlugin(pluginCallbackWithServer), { foo: 'bar' }) server.register(fastifyPlugin(pluginCallbackWithTypeProvider), { foo: 'bar' }) server.register(fastifyPlugin(pluginAsync)) server.register(fastifyPlugin(pluginAsyncWithTypes), { foo: 'bar' }) server.register(fastifyPlugin(pluginAsyncWithOptions), { foo: 'bar' }) server.register(fastifyPlugin(pluginAsyncWithServer), { foo: 'bar' }) server.register(fastifyPlugin(pluginAsyncWithTypeProvider), { foo: 'bar' }) // Handling Callback and Async Inline fastifyPlugin(function (fastify, options, next) { expect(fastify).type.toBe() expect(options).type.toBe>() expect(next).type.toBe<(err?: Error) => void>() }) fastifyPlugin(function (fastify, options, next) { expect(fastify).type.toBe() expect(options).type.toBe() expect(next).type.toBe<(err?: Error) => void>() }) fastifyPlugin(async function (fastify, options) { expect(fastify).type.toBe() expect(options).type.toBe() }) expect( fastifyPlugin(async function ( _fastify: FastifyInstance, _options: Options ) {}) ).type.toBeAssignableTo< FastifyPluginAsync< Options, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger > >() fastifyPlugin(async function (fastify, options: Options) { expect(fastify).type.toBe() expect(options).type.toBe() }) fastifyPlugin(async function (fastify, options) { expect(fastify).type.toBe() expect(options).type.toBe>() }) // @ts-expect-error Target signature provides too few arguments fastifyPlugin(async function (fastify, options, next) {}) expect( fastifyPlugin(function (_fastify, _options, _next) {}) ).type.toBeAssignableTo>() fastifyPlugin(function (fastify, options: Options, next) { expect(fastify).type.toBe() expect(options).type.toBe() expect(next).type.toBe<(err?: Error) => void>() }) // @ts-expect-error Target signature provides too few arguments fastifyPlugin(function (fastify, options, next) { return Promise.resolve() }) server.register(fastifyExampleCallback, { foo: 'bar' }) expect(server.register).type.not.toBeCallableWith(fastifyExampleCallback, { foo: 'baz' }) server.register(fastifyExampleAsync, { foo: 'bar' }) expect(server.register).type.not.toBeCallableWith(fastifyExampleAsync, { foo: 'baz' }) })()