@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.
- package/dist/connectrpc.d.ts +29 -0
- package/dist/execution-context.d.ts +22 -0
- package/dist/fastify-plugin.d.ts +5 -0
- package/dist/guards.d.ts +11 -0
- package/dist/helpers.d.ts +13 -0
- package/dist/index.d.ts +6 -0
- package/dist/interfaces.d.ts +125 -0
- package/dist/middlewares.d.ts +3 -0
- package/dist/stores.d.ts +92 -0
- package/dist/types.d.ts +13 -0
- package/package.json +1 -1
|
@@ -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
|
+
}
|
package/dist/guards.d.ts
ADDED
|
@@ -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;
|
package/dist/index.d.ts
ADDED
|
@@ -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 {};
|
package/dist/stores.d.ts
ADDED
|
@@ -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 {};
|
package/dist/types.d.ts
ADDED
|
@@ -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.
|
|
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",
|