serverstruct
Version:
Type safe and modular servers with Hono
47 lines (43 loc) • 2.85 kB
text/typescript
import { HollywoodOf, AnyHollywood, RegisterTokens, InferContainer, ContainerOptions, Hollywood } from 'hollywood-di';
import { Hono } from 'hono';
type Spread<T> = {
[K in keyof T]: T[K];
} & {};
type Merge<T, To> = T & Omit<To, keyof T>;
type IsEmptyObject<T> = keyof T extends never ? true : false;
type KnownKey<T> = string extends T ? never : number extends T ? never : symbol extends T ? never : T;
type KnownMappedKeys<T> = {
[K in keyof T as KnownKey<K>]: T[K];
} & {};
type SubModule<T extends Record<string, any> = any> = {
app: (container: IsEmptyObject<T> extends true ? HollywoodOf<any> | undefined : HollywoodOf<T>) => Hono<any, any, any>;
};
type SubModules<TContainer extends Record<string, any> = any> = Record<string, SubModule<TContainer>>;
type InferSubModules<R extends SubModules = {}> = {
[K in keyof R]: R[K] extends Module<infer App, any, any> ? App : never;
} & {};
declare class Module<App extends Hono<any, any, any>, Deps extends Record<string, any>, Modules extends SubModules> {
private _context;
private _route;
constructor(_context: [
tokens: {
tokens: RegisterTokens<any, any>;
options?: ContainerOptions;
} | undefined,
routes: SubModules<any>
][], _route: (container: Deps, modules: InferSubModules<Modules>) => App);
app(container: IsEmptyObject<Deps> extends true ? HollywoodOf<any> | undefined : HollywoodOf<Deps>): App;
app(): IsEmptyObject<Deps> extends true ? App : never;
}
declare class ModuleBuilder<App extends Hono<any, any, any>, Deps extends Record<string, any>, Modules extends SubModules, Container extends AnyHollywood | undefined> {
private app;
constructor(app: App);
private context;
use<T extends Container extends AnyHollywood ? never : Record<string, any>>(): Container extends AnyHollywood ? never : ModuleBuilder<App, T, Modules, HollywoodOf<T>>;
provide<T extends Record<string, any> = {}>(tokens: RegisterTokens<T, Container extends AnyHollywood ? InferContainer<Container> : Deps>, options?: ContainerOptions): ModuleBuilder<App, Deps, Modules, Container extends AnyHollywood ? Hollywood<T, InferContainer<Container>> : Hollywood<T, {}>>;
submodules<T extends SubModules<Container extends AnyHollywood ? KnownMappedKeys<InferContainer<Container>> : Deps>>(modules: T): ModuleBuilder<App, Deps, Spread<Merge<T, Modules>>, Container>;
route<T extends Hono<any, any, any>>(fn: (app: App, container: Container extends AnyHollywood ? KnownMappedKeys<InferContainer<Container>> : Deps, modules: InferSubModules<Modules>) => T): Module<T, Deps, Modules>;
}
declare function createModule<App extends Hono<any, any, any> = Hono>(app: App): ModuleBuilder<App, {}, {}, undefined>;
declare function createModule(): ModuleBuilder<Hono, {}, {}, undefined>;
export { createModule };