@funduck/connectrpc-fastify 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ import { GenService, GenServiceMethods } from '@bufbuild/protobuf/codegenv2';
2
+ import { FastifyInstance } from 'fastify';
3
+ import { Guard, Logger, Middleware, MiddlewareConfigUnion, Service } from './interfaces';
4
+ declare class ConnectRPCClass {
5
+ setLogger(customLogger: Logger): void;
6
+ registerMiddleware(self: Middleware, options?: {
7
+ allowMultipleInstances?: boolean;
8
+ }): void;
9
+ /**
10
+ * @param self - instance of controller
11
+ * @param service - generated service that is implemented by controller
12
+ */
13
+ registerController<T extends GenServiceMethods>(self: Service<GenService<T>>, service: GenService<T>, options?: {
14
+ allowMultipleInstances?: boolean;
15
+ }): void;
16
+ registerGuard(self: Guard, options?: {
17
+ allowMultipleInstances?: boolean;
18
+ }): void;
19
+ registerFastifyPlugin(server: FastifyInstance): Promise<void>;
20
+ private _middlewaresInitialized;
21
+ initMiddlewares(server: FastifyInstance, middlewareConfigs: MiddlewareConfigUnion[]): Promise<void>;
22
+ private _guardsInitialized;
23
+ initGuards(server: FastifyInstance): Promise<void>;
24
+ }
25
+ /**
26
+ * Main ConnectRPC class to manage registration of controllers and middlewares
27
+ */
28
+ export declare const ConnectRPC: ConnectRPCClass;
29
+ export {};
@@ -0,0 +1,22 @@
1
+ import { FastifyReply, FastifyRequest } from 'fastify';
2
+ import { ExecutionContext, Type } from './interfaces';
3
+ export declare class ManualExecutionContext implements ExecutionContext {
4
+ readonly request: FastifyRequest['raw'];
5
+ readonly response: FastifyReply['raw'];
6
+ readonly next: <T = any>() => T;
7
+ readonly args: any[];
8
+ readonly constructorRef: Type<any> | null;
9
+ readonly handler: Function | null;
10
+ constructor(request: FastifyRequest['raw'], response: FastifyReply['raw'], next: <T = any>() => T, args: any[], constructorRef?: Type<any> | null, handler?: Function | null);
11
+ getClass<T = any>(): Type<T>;
12
+ getHandler(): Function;
13
+ getArgs<T extends Array<any> = any[]>(): T;
14
+ getArgByIndex<T = any>(index: number): T;
15
+ switchToHttp(): this & {
16
+ getRequest: () => import("node:http").IncomingMessage;
17
+ getResponse: () => import("node:http").ServerResponse<import("node:http").IncomingMessage>;
18
+ getNext: () => <T = any>() => T;
19
+ };
20
+ switchToRpc(): void;
21
+ switchToWs(): void;
22
+ }
@@ -0,0 +1,5 @@
1
+ import { Compression } from '@connectrpc/connect/protocol';
2
+ import { FastifyInstance } from 'fastify';
3
+ export declare function registerFastifyPlugin(server: FastifyInstance, options?: {
4
+ acceptCompression?: Compression[];
5
+ }): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { FastifyInstance } from 'fastify';
2
+ import { ExecutionContext, Guard } from './interfaces';
3
+ export declare class ManualGuardExecutor {
4
+ executeGuard(guard: Guard, context: ExecutionContext): Promise<boolean>;
5
+ executeGuards(guards: Guard[], context: ExecutionContext): Promise<boolean>;
6
+ }
7
+ export declare function getGuards(controller: any): Guard[];
8
+ /**
9
+ * Initialize guards middleware - this should be called after all other middlewares are registered
10
+ */
11
+ export declare function initGuards(server: FastifyInstance): Promise<void>;
@@ -0,0 +1,13 @@
1
+ import { GenService } from '@bufbuild/protobuf/codegenv2';
2
+ import { FastifyReply, FastifyRequest } from 'fastify';
3
+ import { Logger } from './interfaces';
4
+ /**
5
+ * Automatically discover method mappings by matching service methods to controller methods
6
+ */
7
+ export declare function discoverMethodMappings(prototype: any, service: GenService<any>): Record<string, string>;
8
+ /**
9
+ * Helper to convert NestJS middleware to Fastify hook
10
+ */
11
+ export declare function convertMiddlewareToHook(middlewareInstance: any): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
12
+ export declare let logger: Logger;
13
+ export declare function setLogger(customLogger: Logger): void;
@@ -0,0 +1,6 @@
1
+ export declare function printMsg(): void;
2
+ export { ConnectRPC } from './connectrpc';
3
+ export { middlewareConfig } from './interfaces';
4
+ export type { ExecutionContext, Guard, Logger, Middleware, MiddlewareConfig, MiddlewareConfigUnion, Service, } from './interfaces';
5
+ export { initGuards } from './guards';
6
+ export type { OmitConnectrpcFields } from './types';
@@ -0,0 +1,125 @@
1
+ import type { GenMessage, GenService } from '@bufbuild/protobuf/codegenv2';
2
+ import { FastifyReply, FastifyRequest } from 'fastify';
3
+ import { OmitConnectrpcFields } from './types';
4
+ export interface Logger {
5
+ log: (...args: any[]) => void;
6
+ error: (...args: any[]) => void;
7
+ warn: (...args: any[]) => void;
8
+ debug: (...args: any[]) => void;
9
+ verbose: (...args: any[]) => void;
10
+ }
11
+ export interface Middleware {
12
+ use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: (err?: any) => void): void;
13
+ }
14
+ export interface Type<T = any> extends Function {
15
+ new (...args: any[]): T;
16
+ }
17
+ /**
18
+ * Extract the input type from a method schema
19
+ */
20
+ type ExtractInput<T> = T extends {
21
+ input: GenMessage<infer M>;
22
+ } ? M : never;
23
+ /**
24
+ * Extract the output type from a method schema
25
+ */
26
+ type ExtractOutput<T> = T extends {
27
+ output: GenMessage<infer M>;
28
+ } ? M : never;
29
+ /**
30
+ * Convert a service method to a controller method signature
31
+ */
32
+ type ServiceMethod<T> = T extends {
33
+ methodKind: 'unary';
34
+ } ? (request: ExtractInput<T>) => Promise<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
35
+ methodKind: 'server_streaming';
36
+ } ? (request: ExtractInput<T>) => AsyncIterable<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
37
+ methodKind: 'client_streaming';
38
+ } ? (request: AsyncIterable<ExtractInput<T>>) => Promise<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
39
+ methodKind: 'bidi_streaming';
40
+ } ? (request: AsyncIterable<ExtractInput<T>>) => AsyncIterable<OmitConnectrpcFields<ExtractOutput<T>>> : never;
41
+ /**
42
+ * Generic interface that maps a ConnectRPC service to controller methods
43
+ *
44
+ * Controllers can implement any subset of the service methods.
45
+ * TypeScript will enforce correct signatures for implemented methods.
46
+ *
47
+ * Usage:
48
+ * ```typescript
49
+ * export class ElizaController implements Service<typeof ElizaService> {
50
+ * constructor() {
51
+ * ConnectRPC.registerController(this, ElizaService);
52
+ * }
53
+ *
54
+ * async say(request: SayRequest): Promise<SayResponse> {
55
+ * // implementation
56
+ * }
57
+ * // Other methods are optional
58
+ * }
59
+ * ```
60
+ */
61
+ export type Service<T> = T extends GenService<infer Methods> ? {
62
+ [K in keyof Methods]?: ServiceMethod<Methods[K]>;
63
+ } : never;
64
+ export type ServiceMethodNames<T> = T extends GenService<infer Methods> ? {
65
+ [K in keyof Methods]: K;
66
+ }[keyof Methods] : never;
67
+ /**
68
+ * Middleware configuration for ConnectRPC routes - without service specified
69
+ */
70
+ export type MiddlewareConfigGlobal = {
71
+ /**
72
+ * The middleware class to apply (must be decorated with @Middleware())
73
+ */
74
+ use: Type<Middleware>;
75
+ /**
76
+ * Middleware applies to all services and all methods
77
+ */
78
+ on?: never;
79
+ methods?: never;
80
+ };
81
+ /**
82
+ * Middleware configuration for ConnectRPC routes - with service specified
83
+ */
84
+ export type MiddlewareConfig<T extends GenService<any>> = {
85
+ /**
86
+ * The middleware class to apply (must be decorated with @Middleware())
87
+ */
88
+ use: Type<Middleware>;
89
+ /**
90
+ * The service to apply middleware to
91
+ */
92
+ on: T;
93
+ /**
94
+ * Optional: Specific method names to apply middleware to.
95
+ * If omitted, middleware applies to all methods of the service.
96
+ * Method names should match the protobuf method names (e.g., 'say', 'sayMany')
97
+ */
98
+ methods?: Array<ServiceMethodNames<T>>;
99
+ };
100
+ /**
101
+ * Middleware configuration for ConnectRPC routes
102
+ */
103
+ export type MiddlewareConfigUnion = MiddlewareConfigGlobal | MiddlewareConfig<any>;
104
+ /**
105
+ * Helper function to create a type-safe middleware configuration
106
+ * This ensures proper type inference for method names based on the service
107
+ */
108
+ export declare function middlewareConfig<T extends GenService<any>>(use: Type<Middleware>, on?: T, methods?: Array<ServiceMethodNames<T>>): MiddlewareConfigUnion;
109
+ export interface ExecutionContext {
110
+ getClass<T = any>(): Type<T>;
111
+ getHandler(): Function;
112
+ getArgs<T extends Array<any> = any[]>(): T;
113
+ getArgByIndex<T = any>(index: number): T;
114
+ switchToHttp(): {
115
+ getRequest(): FastifyRequest['raw'];
116
+ getResponse(): FastifyReply['raw'];
117
+ getNext<T = any>(): () => T;
118
+ };
119
+ switchToRpc(): any;
120
+ switchToWs(): any;
121
+ }
122
+ export interface Guard {
123
+ canActivate(context: ExecutionContext): boolean | Promise<boolean>;
124
+ }
125
+ export {};
@@ -0,0 +1,3 @@
1
+ import { FastifyInstance } from 'fastify';
2
+ import { MiddlewareConfigUnion } from './interfaces';
3
+ export declare function initMiddlewares(server: FastifyInstance, middlewareConfigs: MiddlewareConfigUnion[]): Promise<void>;
@@ -0,0 +1,92 @@
1
+ import { GenService, GenServiceMethods } from '@bufbuild/protobuf/codegenv2';
2
+ import { Guard, Middleware, Service, Type } from './interfaces';
3
+ declare class ControllersStoreClass {
4
+ private controllers;
5
+ values(): {
6
+ instance: any;
7
+ service: GenService<any>;
8
+ target: Type<any>;
9
+ }[];
10
+ registerInstance<T extends GenServiceMethods>(self: Service<GenService<T>>, service: GenService<T>, { allowMultipleInstances, }?: {
11
+ allowMultipleInstances?: boolean;
12
+ }): void;
13
+ }
14
+ export declare const ControllersStore: ControllersStoreClass;
15
+ /**
16
+ * Store for middleware classes and their instances
17
+ */
18
+ declare class MiddlewareStoreClass {
19
+ private middlewares;
20
+ /**
21
+ * Register a middleware instance from its constructor
22
+ */
23
+ registerInstance(self: Middleware, { allowMultipleInstances, }?: {
24
+ allowMultipleInstances?: boolean;
25
+ }): void;
26
+ /**
27
+ * Get a middleware instance by its class
28
+ */
29
+ getInstance(middlewareClass: Type<Middleware>): Middleware | null;
30
+ }
31
+ export declare const MiddlewareStore: MiddlewareStoreClass;
32
+ /**
33
+ * Store for route metadata - maps URL paths to controller class and method info
34
+ */
35
+ declare class RouteMetadataStoreClass {
36
+ private routes;
37
+ /**
38
+ * Register route metadata for a specific service method
39
+ * @param serviceName - The full service name (e.g., "connectrpc.eliza.v1.ElizaService")
40
+ * @param methodName - The method name in PascalCase (e.g., "Say")
41
+ * @param controllerClass - The controller class
42
+ * @param controllerMethod - The bound controller method
43
+ * @param controllerMethodName - The name of the controller method
44
+ * @param instance - The controller instance
45
+ */
46
+ registerRoute(serviceName: string, methodName: string, controllerClass: Type<any>, controllerMethod: Function, controllerMethodName: string, instance: any): void;
47
+ /**
48
+ * Get route metadata by URL path
49
+ */
50
+ getRouteMetadata(urlPath: string): {
51
+ controllerClass: Type<any>;
52
+ controllerMethod: Function;
53
+ controllerMethodName: string;
54
+ instance: any;
55
+ serviceName: string;
56
+ methodName: string;
57
+ } | null;
58
+ /**
59
+ * Get all registered routes
60
+ */
61
+ getAllRoutes(): [string, {
62
+ controllerClass: Type<any>;
63
+ controllerMethod: Function;
64
+ controllerMethodName: string;
65
+ instance: any;
66
+ serviceName: string;
67
+ methodName: string;
68
+ }][];
69
+ }
70
+ export declare const RouteMetadataStore: RouteMetadataStoreClass;
71
+ /**
72
+ * Store for guard classes and their instances
73
+ */
74
+ declare class GuardsStoreClass {
75
+ private guards;
76
+ /**
77
+ * Register a guard instance from its constructor
78
+ */
79
+ registerInstance(self: Guard, { allowMultipleInstances, }?: {
80
+ allowMultipleInstances?: boolean;
81
+ }): void;
82
+ /**
83
+ * Get a guard instance by its class
84
+ */
85
+ getInstance(guardClass: Type<Guard>): Guard | null;
86
+ /**
87
+ * Get all registered guards
88
+ */
89
+ getAllGuards(): Guard[];
90
+ }
91
+ export declare const GuardsStore: GuardsStoreClass;
92
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { OptionalKeysOf, Primitive, RequiredKeysOf } from 'type-fest';
2
+ export type OmitFieldsDeep<T, K extends keyof any> = T extends Primitive | Date ? T : T extends Array<any> ? {
3
+ [P in keyof T]?: OmitFieldsDeep<T[P], K>;
4
+ } : T extends object ? {
5
+ [P in Exclude<RequiredKeysOf<T>, K>]: OmitFieldsDeep<T[P], K>;
6
+ } & {
7
+ [P in Exclude<OptionalKeysOf<T>, K>]?: OmitFieldsDeep<T[P], K>;
8
+ } : T;
9
+ /**
10
+ * Used to simplify types by omitting ConnectRPC specific fields like `$typeName` and `$unknown`
11
+ * The fields are omitted deeply in nested structures.
12
+ */
13
+ export type OmitConnectrpcFields<T> = OmitFieldsDeep<T, '$typeName' | '$unknown'>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funduck/connectrpc-fastify",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "author": "Oleg Milekhin <qlfunduck@gmail.com>",
5
5
  "description": "Wrapper for official @connectrpc/connect and fastify. Simplifies configuration, type safe binding to controller, simplifies use of middlewares and guards.",
6
6
  "main": "dist/src/index.js",