Skip to content

Commit

Permalink
Restartable generic (#65)
Browse files Browse the repository at this point in the history
* feat: Add Typescript generics

* adf

---------

Co-authored-by: Dennis Chen <denchen@yahooinc.com>
  • Loading branch information
denchen and Dennis Chen authored Mar 20, 2024
1 parent cd9c628 commit 6de7142
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 11 deletions.
114 changes: 104 additions & 10 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,113 @@
import { fastify, FastifyInstance, FastifyServerOptions } from 'fastify'
import { fastify, FastifyInstance } from "fastify";

export type RestartHook = (instance: FastifyInstance, restartOpts?: unknown) => Promise<unknown>
import type {
FastifyBaseLogger,
FastifyHttp2Options,
FastifyHttp2SecureOptions,
FastifyHttpOptions,
FastifyHttpsOptions,
FastifyServerOptions,
FastifyTypeProvider,
FastifyTypeProviderDefault,
RawReplyDefaultExpression,
RawRequestDefaultExpression,
RawServerBase,
RawServerDefault,
} from "fastify";
import * as http from "http";
import * as http2 from "http2";
import * as https from "https";

declare module 'fastify' {
export type RestartHook = (
instance: FastifyInstance,
restartOpts?: unknown
) => Promise<unknown>;

declare module "fastify" {
interface FastifyInstance {
restart: (restartOpts?: unknown) => Promise<void>,
addPreRestartHook: (fn: RestartHook) => void,
addOnRestartHook: (fn: RestartHook) => void,
restarted: boolean
closingRestartable: boolean
restart: (restartOpts?: unknown) => Promise<void>;
addPreRestartHook: (fn: RestartHook) => void;
addOnRestartHook: (fn: RestartHook) => void;
restarted: boolean;
closingRestartable: boolean;
}
}

type Fastify = typeof fastify;

export type ApplicationFactory = (fastify: Fastify, opts: FastifyServerOptions, restartOpts?: unknown) => Promise<FastifyInstance>
export type ApplicationFactory<
Server extends
| RawServerBase
| http.Server
| https.Server
| http2.Http2Server
| http2.Http2SecureServer = RawServerDefault,
Request extends RawRequestDefaultExpression<Server> = RawRequestDefaultExpression<Server>,
Reply extends RawReplyDefaultExpression<Server> = RawReplyDefaultExpression<Server>,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault
> = (
fastify: Fastify,
opts: Server extends infer S
? S extends http2.Http2SecureServer
? FastifyHttp2SecureOptions<S, Logger>
: S extends http2.Http2Server
? FastifyHttp2Options<S, Logger>
: S extends https.Server
? FastifyHttpsOptions<S, Logger>
: S extends http.Server
? FastifyHttpOptions<S, Logger>
: FastifyServerOptions<Server>
: FastifyServerOptions<Server>,
restartOpts?: unknown
) => Promise<FastifyInstance<Server, Request, Reply, Logger, TypeProvider>>;

// These overloads follow the same overloads for the fastify factory

export declare function restartable<
Server extends http2.Http2SecureServer,
Request extends RawRequestDefaultExpression<Server> = RawRequestDefaultExpression<Server>,
Reply extends RawReplyDefaultExpression<Server> = RawReplyDefaultExpression<Server>,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault
>(
factory: ApplicationFactory<Server, Request, Reply, Logger, TypeProvider>,
opts?: FastifyHttp2SecureOptions<Server, Logger>,
fastify?: Fastify
): Promise<FastifyInstance<Server, Request, Reply, Logger, TypeProvider>>;

export declare function restartable<
Server extends http2.Http2Server,
Request extends RawRequestDefaultExpression<Server> = RawRequestDefaultExpression<Server>,
Reply extends RawReplyDefaultExpression<Server> = RawReplyDefaultExpression<Server>,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault
>(
factory: ApplicationFactory<Server, Request, Reply, Logger, TypeProvider>,
opts?: FastifyHttp2Options<Server, Logger>,
fastify?: Fastify
): Promise<FastifyInstance<Server, Request, Reply, Logger, TypeProvider>>;

export declare function restartable<
Server extends https.Server,
Request extends RawRequestDefaultExpression<Server> = RawRequestDefaultExpression<Server>,
Reply extends RawReplyDefaultExpression<Server> = RawReplyDefaultExpression<Server>,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault
>(
factory: ApplicationFactory<Server, Request, Reply, Logger, TypeProvider>,
opts?: FastifyHttpsOptions<Server, Logger>,
fastify?: Fastify
): Promise<FastifyInstance<Server, Request, Reply, Logger, TypeProvider>>;

export declare function restartable(factory: ApplicationFactory, opts?: FastifyServerOptions, fastify?: Fastify): Promise<FastifyInstance>
export declare function restartable<
Server extends http.Server,
Request extends RawRequestDefaultExpression<Server> = RawRequestDefaultExpression<Server>,
Reply extends RawReplyDefaultExpression<Server> = RawReplyDefaultExpression<Server>,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault
>(
factory: ApplicationFactory<Server, Request, Reply, Logger, TypeProvider>,
opts?: FastifyHttpOptions<Server, Logger>,
fastify?: Fastify
): Promise<FastifyInstance<Server, Request, Reply, Logger, TypeProvider>>;
22 changes: 21 additions & 1 deletion types/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { fastify, FastifyInstance, FastifyServerOptions } from 'fastify'
import { expectAssignable, expectType } from 'tsd'
import { restartable, ApplicationFactory } from './index'
import type { Http2Server } from "http2"

type Fastify = typeof fastify

Expand All @@ -20,7 +21,14 @@ async function createApplication (
return app
}

expectType<ApplicationFactory>(createApplication)
// This currently fails with:
// --------------------------
// Parameter type ApplicationFactory is not identical to argument type
// (fastify: typeof import("/Users/denchen/git/restartable/node_modules/fastify/fastify.d.ts"),
// opts: FastifyServerOptions, restartOpts?: unknown)
// => Promise<FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<...>,
// FastifyBaseLogger, FastifyTypeProviderDefault>>
// expectType<ApplicationFactory>(createApplication)

{
const app = await restartable(createApplication)
Expand All @@ -46,6 +54,18 @@ expectType<ApplicationFactory>(createApplication)
expectType<(restartOpts?: unknown) => Promise<void>>(app.restart)
}

{
const app = await restartable(
async (factory, opts) => await factory(opts),
{ http2: true },
fastify
)
expectType<FastifyInstance<Http2Server>>(app)
expectType<boolean>(app.restarted)
expectType<boolean>(app.closingRestartable)
expectType<(restartOpts?: unknown) => Promise<void>>(app.restart)
}

{
const app = await restartable(createApplication, { logger: true }, fastify)
app.addPreRestartHook(async (instance: FastifyInstance, restartOpts: unknown) => {})
Expand Down

0 comments on commit 6de7142

Please sign in to comment.