@funduck/connectrpc-fastify 1.0.10 → 1.0.12

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/README.md CHANGED
@@ -9,7 +9,7 @@ This is a wrapper for [Connectrpc](https://github.com/connectrpc/connect-es) usi
9
9
 
10
10
  If you are comfortable with HTTP/1 only and want a compact, ready-to-use setup, this repository is for you.
11
11
 
12
- It simplifies the binding of controllers, middlewares, and guards.
12
+ It simplifies the binding of controllers and middlewares.
13
13
 
14
14
  I use it as a basis for integration into Nestjs, which will be implemented [here](https://github.com/funduck/connectrpc-fastify-nestjs).
15
15
 
@@ -21,17 +21,22 @@ This library allows you to:
21
21
  * Perform RPC with simple request and response messages
22
22
  * Perform RPC with streaming responses
23
23
  * Perform RPC with streaming requests
24
- * Use middlewares
25
- * Use global guards
24
+ * Use middlewares with Fastify hooks
25
+ * Access HandlerContext in controllers (headers, context values, etc.)
26
26
 
27
27
  *Bidirectional streaming RPC is currently out of scope because it requires HTTP/2, which is unstable on public networks. In practice, HTTP/1 provides more consistent performance.*
28
28
 
29
29
  ## How To Use
30
- You can check out `test` directory for a complete example of server and client. Start reading from `test/server.ts`.
30
+ You can check out `test` directory for a complete example of server and client. Start reading from `test/demo/server.ts`.
31
31
 
32
32
  ### Controllers
33
33
  Controller must implement the service interface and register itself with `ConnectRPC.registerController` in the constructor.
34
+
35
+ Controller methods receive `HandlerContext` which provides access to request headers, context values, and other metadata.
36
+
34
37
  ```TS
38
+ import type { HandlerContext } from '@connectrpc/connect';
39
+
35
40
  export class ElizaController implements Service<typeof ElizaService> {
36
41
  constructor() {
37
42
  ConnectRPC.registerController(this, ElizaService);
@@ -39,7 +44,11 @@ export class ElizaController implements Service<typeof ElizaService> {
39
44
 
40
45
  async say(
41
46
  request: SayRequest,
47
+ context: HandlerContext,
42
48
  ) {
49
+ // Access headers from context
50
+ const authHeader = context.requestHeader.get('authorization');
51
+
43
52
  return {
44
53
  sentence: `You said: ${request.sentence}`,
45
54
  };
@@ -66,91 +75,44 @@ try {
66
75
  ```
67
76
 
68
77
  ### Middlewares
69
- You can use middlewares for pre-processing requests.
78
+ Middlewares run as Fastify hooks and have access to raw request/response objects.
70
79
 
71
80
  Middleware must implement `Middleware` interface and register itself with `ConnectRPC.registerMiddleware` in the constructor.
72
81
  ```TS
73
- export class TestMiddleware1 implements Middleware {
82
+ export class AuthMiddleware implements Middleware {
74
83
  constructor() {
75
84
  ConnectRPC.registerMiddleware(this);
76
85
  }
77
86
 
78
87
  use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
88
+ // Check authentication
89
+ const authHeader = req.headers['authorization'];
90
+ if (!authHeader) {
91
+ res.statusCode = 401;
92
+ res.end('Unauthorized');
93
+ return;
94
+ }
79
95
  next();
80
96
  }
81
97
  }
82
98
  ```
83
99
 
84
- Then create an instance of the middleware before registering the ConnectRPC plugin.
100
+ Create an instance of the middleware before registering the ConnectRPC plugin.
85
101
  ```TS
86
- const fastify = Fastify({
87
- logger: true,
88
- });
102
+ const fastify = Fastify({ logger: true });
89
103
 
90
104
  new ElizaController();
91
-
92
- new TestMiddleware1();
105
+ new AuthMiddleware();
93
106
 
94
107
  await ConnectRPC.registerFastifyPlugin(fastify);
95
108
 
96
109
  ConnectRPC.initMiddlewares(fastify, [
97
- middlewareConfig(TestMiddleware1), // Global middleware for all services and methods
98
- //middlewareConfig(TestMiddleware1, ElizaService), // Middleware for all ElizaService methods
99
- //middlewareConfig(TestMiddleware1, ElizaService, ['say']), // Middleware for ElizaService's say method only
110
+ middlewareConfig(AuthMiddleware), // Global middleware for all services and methods
111
+ // middlewareConfig(AuthMiddleware, ElizaService), // Middleware for all ElizaService methods
112
+ // middlewareConfig(AuthMiddleware, ElizaService, ['say']), // Middleware for specific method only
100
113
  ]);
101
114
 
102
- try {
103
- await fastify.listen({ port: 3000 });
104
- } catch (err) {
105
- fastify.log.error(err);
106
- process.exit(1);
107
- }
108
- ```
109
-
110
- ### Guards
111
- Guards are used to restrict access to certain services or methods.
112
-
113
- Guard must implement `Guard` interface and register itself with `ConnectRPC.registerGuard` in the constructor.
114
- ```TS
115
- export class TestGuard1 implements Guard {
116
- constructor() {
117
- ConnectRPC.registerGuard(this);
118
- }
119
-
120
- canActivate(context: ExecutionContext): boolean {
121
- return true;
122
- }
123
- }
124
- ```
125
-
126
- Then create an instance of the guard before registering the ConnectRPC plugin and initialize it similarly to middlewares.
127
- ```TS
128
- const fastify = Fastify({
129
- logger: true,
130
- });
131
-
132
- new ElizaController();
133
-
134
- new TestMiddleware1();
135
-
136
- new TestGuard1();
137
-
138
- await ConnectRPC.registerFastifyPlugin(fastify);
139
-
140
- ConnectRPC.initMiddlewares(fastify, [
141
- middlewareConfig(TestMiddleware1), // Global middleware for all services and methods
142
- // middlewareConfig(TestMiddleware1, ElizaService), // Middleware for all ElizaService methods
143
- // middlewareConfig(TestMiddleware1, ElizaService, ['say']), // Middleware for ElizaService's say method only
144
- ]);
145
-
146
- ConnectRPC.initGuards(fastify);
147
-
148
- try {
149
- await fastify.listen({ port: 3000 });
150
- } catch (err) {
151
- fastify.log.error(err);
152
- process.exit(1);
153
- }
115
+ await fastify.listen({ port: 3000 });
154
116
  ```
155
117
 
156
118
  ## Feedback
@@ -1,6 +1,6 @@
1
1
  import { GenService, GenServiceMethods } from '@bufbuild/protobuf/codegenv2';
2
2
  import { FastifyInstance } from 'fastify';
3
- import { Guard, Logger, Middleware, MiddlewareConfigUnion, Service } from './interfaces';
3
+ import { Logger, Middleware, MiddlewareConfigUnion, Service } from './interfaces';
4
4
  declare class ConnectRPCClass {
5
5
  setLogger(customLogger: Logger): void;
6
6
  registerMiddleware(self: Middleware, options?: {
@@ -13,14 +13,9 @@ declare class ConnectRPCClass {
13
13
  registerController<T extends GenServiceMethods>(self: Service<GenService<T>>, service: GenService<T>, options?: {
14
14
  allowMultipleInstances?: boolean;
15
15
  }): void;
16
- registerGuard(self: Guard, options?: {
17
- allowMultipleInstances?: boolean;
18
- }): void;
19
16
  registerFastifyPlugin(server: FastifyInstance): Promise<void>;
20
17
  private _middlewaresInitialized;
21
18
  initMiddlewares(server: FastifyInstance, middlewareConfigs: MiddlewareConfigUnion[]): Promise<void>;
22
- private _guardsInitialized;
23
- initGuards(server: FastifyInstance): Promise<void>;
24
19
  }
25
20
  /**
26
21
  * Main ConnectRPC class to manage registration of controllers and middlewares
@@ -2,14 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConnectRPC = void 0;
4
4
  const fastify_plugin_1 = require("./fastify-plugin");
5
- const guards_1 = require("./guards");
6
5
  const helpers_1 = require("./helpers");
7
6
  const middlewares_1 = require("./middlewares");
8
7
  const stores_1 = require("./stores");
9
8
  class ConnectRPCClass {
10
9
  constructor() {
11
10
  this._middlewaresInitialized = false;
12
- this._guardsInitialized = false;
13
11
  }
14
12
  setLogger(customLogger) {
15
13
  (0, helpers_1.setLogger)(customLogger);
@@ -24,9 +22,6 @@ class ConnectRPCClass {
24
22
  registerController(self, service, options) {
25
23
  stores_1.ControllersStore.registerInstance(self, service, options);
26
24
  }
27
- registerGuard(self, options) {
28
- stores_1.GuardsStore.registerInstance(self, options);
29
- }
30
25
  registerFastifyPlugin(server) {
31
26
  return (0, fastify_plugin_1.registerFastifyPlugin)(server);
32
27
  }
@@ -34,19 +29,9 @@ class ConnectRPCClass {
34
29
  if (this._middlewaresInitialized) {
35
30
  throw new Error('Middlewares have already been initialized!');
36
31
  }
37
- if (this._guardsInitialized) {
38
- throw new Error('Middlewares must be initialized before guards!');
39
- }
40
32
  this._middlewaresInitialized = true;
41
33
  return (0, middlewares_1.initMiddlewares)(server, middlewareConfigs);
42
34
  }
43
- initGuards(server) {
44
- if (this._guardsInitialized) {
45
- throw new Error('Guards have already been initialized!');
46
- }
47
- this._guardsInitialized = true;
48
- return (0, guards_1.initGuards)(server);
49
- }
50
35
  }
51
36
  /**
52
37
  * Main ConnectRPC class to manage registration of controllers and middlewares
@@ -1 +1 @@
1
- {"version":3,"file":"connectrpc.js","sourceRoot":"","sources":["../src/connectrpc.ts"],"names":[],"mappings":";;;AAEA,qDAAyD;AACzD,qCAAsC;AACtC,uCAAsC;AAQtC,+CAAgD;AAChD,qCAA0E;AAE1E,MAAM,eAAe;IAArB;QAyCU,4BAAuB,GAAG,KAAK,CAAC;QAgBhC,uBAAkB,GAAG,KAAK,CAAC;IASrC,CAAC;IAjEC,SAAS,CAAC,YAAoB;QAC5B,IAAA,mBAAS,EAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IAED,kBAAkB,CAChB,IAAgB,EAChB,OAEC;QAED,wBAAe,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAChB,IAA4B,EAC5B,OAAsB,EACtB,OAEC;QAED,yBAAgB,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,aAAa,CACX,IAAW,EACX,OAEC;QAED,oBAAW,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,qBAAqB,CAAC,MAAuB;QAC3C,OAAO,IAAA,sCAAqB,EAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAID,eAAe,CACb,MAAuB,EACvB,iBAA0C;QAE1C,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,OAAO,IAAA,6BAAe,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACpD,CAAC;IAID,UAAU,CAAC,MAAuB;QAChC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;CACF;AAED;;GAEG;AACU,QAAA,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"connectrpc.js","sourceRoot":"","sources":["../src/connectrpc.ts"],"names":[],"mappings":";;;AAEA,qDAAyD;AACzD,uCAAsC;AAOtC,+CAAgD;AAChD,qCAA6D;AAE7D,MAAM,eAAe;IAArB;QAgCU,4BAAuB,GAAG,KAAK,CAAC;IAY1C,CAAC;IA3CC,SAAS,CAAC,YAAoB;QAC5B,IAAA,mBAAS,EAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IAED,kBAAkB,CAChB,IAAgB,EAChB,OAEC;QAED,wBAAe,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAChB,IAA4B,EAC5B,OAAsB,EACtB,OAEC;QAED,yBAAgB,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,qBAAqB,CAAC,MAAuB;QAC3C,OAAO,IAAA,sCAAqB,EAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAID,eAAe,CACb,MAAuB,EACvB,iBAA0C;QAE1C,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,OAAO,IAAA,6BAAe,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACpD,CAAC;CACF;AAED;;GAEG;AACU,QAAA,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { ContextKey, ContextValues } from '@connectrpc/connect';
2
+ /**
3
+ * Custom ContextValues implementation that extends the standard ConnectRPC ContextValues
4
+ * with an entries() method to iterate over key-value pairs.
5
+ */
6
+ export declare class CustomContextValues implements ContextValues {
7
+ private values;
8
+ /**
9
+ * Get a context value by key
10
+ */
11
+ get<T>(key: ContextKey<T>): T;
12
+ /**
13
+ * Set a context value by key
14
+ */
15
+ set<T>(key: ContextKey<T>, value: T): this;
16
+ /**
17
+ * Delete a context value by key
18
+ */
19
+ delete(key: ContextKey<unknown>): this;
20
+ /**
21
+ * Iterate over all key-value pairs in the context
22
+ * Returns an iterator of [ContextKey, value] pairs
23
+ */
24
+ entries(): IterableIterator<[symbol, unknown]>;
25
+ }
26
+ /**
27
+ * Create a new CustomContextValues instance
28
+ */
29
+ export declare function createCustomContextValues(): CustomContextValues;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CustomContextValues = void 0;
4
+ exports.createCustomContextValues = createCustomContextValues;
5
+ /**
6
+ * Custom ContextValues implementation that extends the standard ConnectRPC ContextValues
7
+ * with an entries() method to iterate over key-value pairs.
8
+ */
9
+ class CustomContextValues {
10
+ constructor() {
11
+ this.values = new Map();
12
+ }
13
+ /**
14
+ * Get a context value by key
15
+ */
16
+ get(key) {
17
+ if (this.values.has(key.id)) {
18
+ return this.values.get(key.id);
19
+ }
20
+ return key.defaultValue;
21
+ }
22
+ /**
23
+ * Set a context value by key
24
+ */
25
+ set(key, value) {
26
+ this.values.set(key.id, value);
27
+ return this;
28
+ }
29
+ /**
30
+ * Delete a context value by key
31
+ */
32
+ delete(key) {
33
+ this.values.delete(key.id);
34
+ return this;
35
+ }
36
+ /**
37
+ * Iterate over all key-value pairs in the context
38
+ * Returns an iterator of [ContextKey, value] pairs
39
+ */
40
+ *entries() {
41
+ for (const [id, value] of this.values.entries()) {
42
+ yield [id, value];
43
+ }
44
+ }
45
+ }
46
+ exports.CustomContextValues = CustomContextValues;
47
+ /**
48
+ * Create a new CustomContextValues instance
49
+ */
50
+ function createCustomContextValues() {
51
+ return new CustomContextValues();
52
+ }
53
+ //# sourceMappingURL=context-values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-values.js","sourceRoot":"","sources":["../src/context-values.ts"],"names":[],"mappings":";;;AAiDA,8DAEC;AAjDD;;;GAGG;AACH,MAAa,mBAAmB;IAAhC;QACU,WAAM,GAAG,IAAI,GAAG,EAAmB,CAAC;IAqC9C,CAAC;IAnCC;;OAEG;IACH,GAAG,CAAI,GAAkB;QACvB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAM,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC,YAAY,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,GAAG,CAAI,GAAkB,EAAE,KAAQ;QACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAwB;QAC7B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,CAAC,OAAO;QACN,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;CACF;AAtCD,kDAsCC;AAED;;GAEG;AACH,SAAgB,yBAAyB;IACvC,OAAO,IAAI,mBAAmB,EAAE,CAAC;AACnC,CAAC"}
@@ -2,17 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerFastifyPlugin = registerFastifyPlugin;
4
4
  const connect_fastify_1 = require("@connectrpc/connect-fastify");
5
- const guards_1 = require("./guards");
6
5
  const helpers_1 = require("./helpers");
6
+ const interceptors_1 = require("./interceptors");
7
7
  const stores_1 = require("./stores");
8
8
  async function registerFastifyPlugin(server, options = {}) {
9
9
  // Create implementations from controller instances
10
10
  const implementations = new Map();
11
11
  for (const { instance, service } of stores_1.ControllersStore.values()) {
12
- const guards = (0, guards_1.getGuards)(instance);
13
- if (guards.length > 0) {
14
- helpers_1.logger.log(`Found ${guards.length} guards on controller ${instance.constructor.name}`);
15
- }
16
12
  const methodMappings = (0, helpers_1.discoverMethodMappings)(instance.__proto__, service);
17
13
  // Create the implementation object
18
14
  const implementation = {};
@@ -27,9 +23,7 @@ async function registerFastifyPlugin(server, options = {}) {
27
23
  if (controllerMethod) {
28
24
  // Bind the method with proper 'this' context
29
25
  const bindedMethod = controllerMethod.bind(instance);
30
- implementation[methodName] = (...args) => {
31
- return bindedMethod(...args);
32
- };
26
+ implementation[methodName] = bindedMethod;
33
27
  // Store route metadata for guards and interceptors
34
28
  stores_1.RouteMetadataStore.registerRoute(service.typeName, name, // PascalCase method name (e.g., "Say")
35
29
  instance.constructor, controllerMethod, controllerMethodName, instance);
@@ -61,6 +55,7 @@ async function registerFastifyPlugin(server, options = {}) {
61
55
  grpcWeb: false,
62
56
  connect: true,
63
57
  acceptCompression: options.acceptCompression ?? [],
58
+ interceptors: [interceptors_1.contextInterceptor],
64
59
  routes: routes,
65
60
  });
66
61
  helpers_1.logger.log('Ready');
@@ -1 +1 @@
1
- {"version":3,"file":"fastify-plugin.js","sourceRoot":"","sources":["../src/fastify-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fastify-plugin.js","sourceRoot":"","sources":["../src/fastify-plugin.ts"],"names":[],"mappings":"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"}
package/dist/helpers.d.ts CHANGED
@@ -11,3 +11,7 @@ export declare function discoverMethodMappings(prototype: any, service: GenServi
11
11
  export declare function convertMiddlewareToHook(middlewareInstance: any): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
12
12
  export declare let logger: Logger;
13
13
  export declare function setLogger(customLogger: Logger): void;
14
+ /**
15
+ * Generate a unique request ID
16
+ */
17
+ export declare function generateRequestId(): string;
package/dist/helpers.js CHANGED
@@ -4,6 +4,7 @@ exports.logger = void 0;
4
4
  exports.discoverMethodMappings = discoverMethodMappings;
5
5
  exports.convertMiddlewareToHook = convertMiddlewareToHook;
6
6
  exports.setLogger = setLogger;
7
+ exports.generateRequestId = generateRequestId;
7
8
  /**
8
9
  * Automatically discover method mappings by matching service methods to controller methods
9
10
  */
@@ -55,22 +56,28 @@ function convertMiddlewareToHook(middlewareInstance) {
55
56
  }
56
57
  exports.logger = {
57
58
  log: (...args) => {
58
- console.info(...args);
59
+ // console.info(...args);
59
60
  },
60
61
  error: (...args) => {
61
- console.error(...args);
62
+ // console.error(...args);
62
63
  },
63
64
  warn: (...args) => {
64
- console.warn(...args);
65
+ // console.warn(...args);
65
66
  },
66
67
  debug: (...args) => {
67
- console.debug(...args);
68
+ // console.debug(...args);
68
69
  },
69
70
  verbose: (...args) => {
70
- console.log(...args);
71
+ // console.log(...args);
71
72
  },
72
73
  };
73
74
  function setLogger(customLogger) {
74
75
  exports.logger = customLogger;
75
76
  }
77
+ /**
78
+ * Generate a unique request ID
79
+ */
80
+ function generateRequestId() {
81
+ return `req_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
82
+ }
76
83
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export declare function printMsg(): void;
2
2
  export { ConnectRPC } from './connectrpc';
3
+ export { CustomContextValues, createCustomContextValues, } from './context-values';
3
4
  export { middlewareConfig } from './interfaces';
4
- export type { ExecutionContext, Guard, Logger, Middleware, MiddlewareConfig, MiddlewareConfigUnion, Service, } from './interfaces';
5
- export { initGuards } from './guards';
5
+ export type { Logger, Middleware, MiddlewareConfig, MiddlewareConfigUnion, Service, } from './interfaces';
6
6
  export type { OmitConnectrpcFields } from './types';
7
+ export { getCustomContextValues } from './middlewares';
package/dist/index.js CHANGED
@@ -1,14 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initGuards = exports.middlewareConfig = exports.ConnectRPC = void 0;
3
+ exports.getCustomContextValues = exports.middlewareConfig = exports.createCustomContextValues = exports.CustomContextValues = exports.ConnectRPC = void 0;
4
4
  exports.printMsg = printMsg;
5
5
  function printMsg() {
6
- console.log('Thanks for using connectrpc-fastify!');
6
+ console.error('connectrpc-fastify is in development mode! not ready for production yet!');
7
7
  }
8
8
  var connectrpc_1 = require("./connectrpc");
9
9
  Object.defineProperty(exports, "ConnectRPC", { enumerable: true, get: function () { return connectrpc_1.ConnectRPC; } });
10
+ var context_values_1 = require("./context-values");
11
+ Object.defineProperty(exports, "CustomContextValues", { enumerable: true, get: function () { return context_values_1.CustomContextValues; } });
12
+ Object.defineProperty(exports, "createCustomContextValues", { enumerable: true, get: function () { return context_values_1.createCustomContextValues; } });
10
13
  var interfaces_1 = require("./interfaces");
11
14
  Object.defineProperty(exports, "middlewareConfig", { enumerable: true, get: function () { return interfaces_1.middlewareConfig; } });
12
- var guards_1 = require("./guards");
13
- Object.defineProperty(exports, "initGuards", { enumerable: true, get: function () { return guards_1.initGuards; } });
15
+ var middlewares_1 = require("./middlewares");
16
+ Object.defineProperty(exports, "getCustomContextValues", { enumerable: true, get: function () { return middlewares_1.getCustomContextValues; } });
14
17
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4BAEC;AAFD,SAAgB,QAAQ;IACtB,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AACtD,CAAC;AAED,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AAEnB,2CAAgD;AAAvC,8GAAA,gBAAgB,OAAA;AAYzB,mCAAsC;AAA7B,oGAAA,UAAU,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4BAIC;AAJD,SAAgB,QAAQ;IACtB,OAAO,CAAC,KAAK,CACX,0EAA0E,CAC3E,CAAC;AACJ,CAAC;AAED,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AAEnB,mDAG0B;AAFxB,qHAAA,mBAAmB,OAAA;AACnB,2HAAA,yBAAyB,OAAA;AAG3B,2CAAgD;AAAvC,8GAAA,gBAAgB,OAAA;AAYzB,6CAAuD;AAA9C,qHAAA,sBAAsB,OAAA"}
@@ -0,0 +1,7 @@
1
+ import type { Interceptor } from '@connectrpc/connect';
2
+ /**
3
+ * ContextInterceptor - copies context values from MiddlewareContextStore to HandlerContext
4
+ * This interceptor should be first in the chain to ensure context values are available
5
+ * to subsequent interceptors and controllers.
6
+ */
7
+ export declare const contextInterceptor: Interceptor;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.contextInterceptor = void 0;
4
+ const stores_1 = require("./stores");
5
+ /**
6
+ * ContextInterceptor - copies context values from MiddlewareContextStore to HandlerContext
7
+ * This interceptor should be first in the chain to ensure context values are available
8
+ * to subsequent interceptors and controllers.
9
+ */
10
+ const contextInterceptor = (next) => async (req) => {
11
+ // Get the request ID from headers
12
+ const requestId = req.header.get('x-server-request-id');
13
+ if (requestId) {
14
+ const middlewareContext = stores_1.MiddlewareContextStore.get(requestId);
15
+ if (middlewareContext) {
16
+ // Copy context values from middleware context to handler context
17
+ for (const [key, value] of middlewareContext.contextValues.entries()) {
18
+ req.contextValues.set({ id: key, defaultValue: undefined }, value);
19
+ }
20
+ }
21
+ }
22
+ // Continue with the next interceptor or handler
23
+ return await next(req);
24
+ };
25
+ exports.contextInterceptor = contextInterceptor;
26
+ //# sourceMappingURL=interceptors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptors.js","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":";;;AACA,qCAAkD;AAElD;;;;GAIG;AACI,MAAM,kBAAkB,GAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACrE,kCAAkC;IAClC,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAExD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,iBAAiB,GAAG,+BAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEhE,IAAI,iBAAiB,EAAE,CAAC;YACtB,iEAAiE;YACjE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;gBACrE,GAAG,CAAC,aAAa,CAAC,GAAG,CACnB,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAS,EAC3C,KAAK,CACN,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC,CAAC;AApBW,QAAA,kBAAkB,sBAoB7B"}
@@ -1,4 +1,5 @@
1
1
  import type { GenMessage, GenService } from '@bufbuild/protobuf/codegenv2';
2
+ import { HandlerContext } from '@connectrpc/connect';
2
3
  import { FastifyReply, FastifyRequest } from 'fastify';
3
4
  import { OmitConnectrpcFields } from './types';
4
5
  export interface Logger {
@@ -28,16 +29,19 @@ type ExtractOutput<T> = T extends {
28
29
  } ? M : never;
29
30
  /**
30
31
  * Convert a service method to a controller method signature
32
+ *
33
+ * Note: The context parameter receives a HandlerContext instance at runtime
34
+ * which provides access to headers, values, signal, and other request metadata.
31
35
  */
32
36
  type ServiceMethod<T> = T extends {
33
37
  methodKind: 'unary';
34
- } ? (request: ExtractInput<T>) => Promise<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
38
+ } ? (request: ExtractInput<T>, context?: HandlerContext) => Promise<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
35
39
  methodKind: 'server_streaming';
36
- } ? (request: ExtractInput<T>) => AsyncIterable<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
40
+ } ? (request: ExtractInput<T>, context?: HandlerContext) => AsyncIterable<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
37
41
  methodKind: 'client_streaming';
38
- } ? (request: AsyncIterable<ExtractInput<T>>) => Promise<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
42
+ } ? (request: AsyncIterable<ExtractInput<T>>, context?: HandlerContext) => Promise<OmitConnectrpcFields<ExtractOutput<T>>> : T extends {
39
43
  methodKind: 'bidi_streaming';
40
- } ? (request: AsyncIterable<ExtractInput<T>>) => AsyncIterable<OmitConnectrpcFields<ExtractOutput<T>>> : never;
44
+ } ? (request: AsyncIterable<ExtractInput<T>>, context?: HandlerContext) => AsyncIterable<OmitConnectrpcFields<ExtractOutput<T>>> : never;
41
45
  /**
42
46
  * Generic interface that maps a ConnectRPC service to controller methods
43
47
  *
@@ -106,20 +110,4 @@ export type MiddlewareConfigUnion = MiddlewareConfigGlobal | MiddlewareConfig<an
106
110
  * This ensures proper type inference for method names based on the service
107
111
  */
108
112
  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
113
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";;AA0IA,4CAUC;AAdD;;;GAGG;AACH,SAAgB,gBAAgB,CAC9B,GAAqB,EACrB,EAAM,EACN,OAAsC;IAEtC,OAAO;QACL,GAAG;QACH,EAAE;QACF,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";;AAkJA,4CAUC;AAdD;;;GAGG;AACH,SAAgB,gBAAgB,CAC9B,GAAqB,EACrB,EAAM,EACN,OAAsC;IAEtC,OAAO;QACL,GAAG;QACH,EAAE;QACF,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -1,3 +1,5 @@
1
- import { FastifyInstance } from 'fastify';
1
+ import { FastifyInstance, FastifyRequest } from 'fastify';
2
2
  import { MiddlewareConfigUnion } from './interfaces';
3
+ /** This method allows middleware to access custom context values associated with a request */
4
+ export declare function getCustomContextValues(req: FastifyRequest['raw']): import("./context-values").CustomContextValues | null;
3
5
  export declare function initMiddlewares(server: FastifyInstance, middlewareConfigs: MiddlewareConfigUnion[]): Promise<void>;
@@ -1,9 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCustomContextValues = getCustomContextValues;
3
4
  exports.initMiddlewares = initMiddlewares;
5
+ const context_values_1 = require("./context-values");
4
6
  const helpers_1 = require("./helpers");
5
7
  const stores_1 = require("./stores");
8
+ function setupCustomContextValues(req) {
9
+ const requestId = (0, helpers_1.generateRequestId)();
10
+ // Store the request ID in a custom header
11
+ req.headers['x-server-request-id'] = requestId;
12
+ // Create and store the middleware context with ContextValues
13
+ stores_1.MiddlewareContextStore.set(requestId, {
14
+ contextValues: (0, context_values_1.createCustomContextValues)(),
15
+ });
16
+ }
17
+ /** This method allows middleware to access custom context values associated with a request */
18
+ function getCustomContextValues(req) {
19
+ const requestId = req.headers['x-server-request-id'];
20
+ if (requestId) {
21
+ const middlewareContext = stores_1.MiddlewareContextStore.get(requestId);
22
+ if (middlewareContext) {
23
+ return middlewareContext.contextValues;
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+ function clearCustomContextValues(req) {
29
+ const requestId = req.headers['x-server-request-id'];
30
+ if (requestId) {
31
+ stores_1.MiddlewareContextStore.delete(requestId);
32
+ }
33
+ }
6
34
  async function initMiddlewares(server, middlewareConfigs) {
35
+ // Add context middleware first - this stores req/res and creates ContextValues for interceptors
36
+ server.addHook('onRequest', async (request, reply) => {
37
+ setupCustomContextValues(request.raw);
38
+ // Clean up the context when the response finishes
39
+ reply.raw.on('finish', () => {
40
+ clearCustomContextValues(request.raw);
41
+ });
42
+ });
43
+ helpers_1.logger.log('Applied context middleware for storing req/res objects and ContextValues');
7
44
  for (const config of middlewareConfigs) {
8
45
  // Convert method names to set with PascalCase
9
46
  const methods = new Set((config.methods || []).map((m) => m[0].toUpperCase() + m.slice(1)));
@@ -1 +1 @@
1
- {"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../src/middlewares.ts"],"names":[],"mappings":";;AAKA,0CAiEC;AArED,uCAA4D;AAE5D,qCAA2C;AAEpC,KAAK,UAAU,eAAe,CACnC,MAAuB,EACvB,iBAA0C;IAE1C,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;QACvC,8CAA8C;QAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACnE,CAAC;QAEF,6CAA6C;QAC7C,MAAM,kBAAkB,GAAG,wBAAe,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEnE,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,gBAAM,CAAC,IAAI,CACT,cAAc,MAAM,CAAC,GAAG,CAAC,IAAI,wJAAwJ,CACtL,CAAC;YACF,SAAS;QACX,CAAC;QAED,IAAI,OAAO,kBAAkB,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,IAAA,iCAAuB,EAAC,kBAAkB,CAAC,CAAC;YAEzD,wDAAwD;YACxD,MAAM,YAAY,GAAG,KAAK,EAAE,OAAY,EAAE,KAAU,EAAE,EAAE;gBACtD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAa,CAAC;gBAElC,0CAA0C;gBAC1C,0CAA0C;gBAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBAEhD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,+BAA+B;oBAC/B,OAAO;gBACT,CAAC;gBAED,MAAM,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC;gBAE1C,mDAAmD;gBACnD,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;oBACpD,OAAO;gBACT,CAAC;gBAED,kDAAkD;gBAClD,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7C,OAAO;gBACT,CAAC;gBAED,uBAAuB;gBACvB,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC7B,CAAC,CAAC;YAEF,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAE1C,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE;gBAC3B,CAAC,CAAC,eAAe,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACrC,CAAC,CAAC,kBAAkB,CAAC;YACvB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO;gBAC/B,CAAC,CAAC,aAAa,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBAC3C,CAAC,CAAC,cAAc,CAAC;YACnB,gBAAM,CAAC,GAAG,CACR,uBAAuB,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,WAAW,GAAG,UAAU,EAAE,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../src/middlewares.ts"],"names":[],"mappings":"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"}
package/dist/stores.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { GenService, GenServiceMethods } from '@bufbuild/protobuf/codegenv2';
2
- import { Guard, Middleware, Service, Type } from './interfaces';
2
+ import { CustomContextValues } from './context-values';
3
+ import { Middleware, Service, Type } from './interfaces';
3
4
  declare class ControllersStoreClass {
4
5
  private controllers;
5
6
  values(): {
@@ -7,6 +8,7 @@ declare class ControllersStoreClass {
7
8
  service: GenService<any>;
8
9
  target: Type<any>;
9
10
  }[];
11
+ clear(): void;
10
12
  registerInstance<T extends GenServiceMethods>(self: Service<GenService<T>>, service: GenService<T>, { allowMultipleInstances, }?: {
11
13
  allowMultipleInstances?: boolean;
12
14
  }): void;
@@ -17,6 +19,7 @@ export declare const ControllersStore: ControllersStoreClass;
17
19
  */
18
20
  declare class MiddlewareStoreClass {
19
21
  private middlewares;
22
+ clear(): void;
20
23
  /**
21
24
  * Register a middleware instance from its constructor
22
25
  */
@@ -34,6 +37,7 @@ export declare const MiddlewareStore: MiddlewareStoreClass;
34
37
  */
35
38
  declare class RouteMetadataStoreClass {
36
39
  private routes;
40
+ clear(): void;
37
41
  /**
38
42
  * Register route metadata for a specific service method
39
43
  * @param serviceName - The full service name (e.g., "connectrpc.eliza.v1.ElizaService")
@@ -69,24 +73,30 @@ declare class RouteMetadataStoreClass {
69
73
  }
70
74
  export declare const RouteMetadataStore: RouteMetadataStoreClass;
71
75
  /**
72
- * Store for guard classes and their instances
76
+ * Middleware context - contains both raw req/res and context values
73
77
  */
74
- declare class GuardsStoreClass {
75
- private guards;
78
+ export interface MiddlewareContext {
79
+ contextValues: CustomContextValues;
80
+ }
81
+ /**
82
+ * Store for middleware context - maps request IDs to middleware context
83
+ * This allows interceptors to access both raw request/response objects and context values
84
+ */
85
+ declare class MiddlewareContextStoreClass {
86
+ private contexts;
87
+ clear(): void;
76
88
  /**
77
- * Register a guard instance from its constructor
89
+ * Store middleware context by request ID
78
90
  */
79
- registerInstance(self: Guard, { allowMultipleInstances, }?: {
80
- allowMultipleInstances?: boolean;
81
- }): void;
91
+ set(requestId: string, context: MiddlewareContext): void;
82
92
  /**
83
- * Get a guard instance by its class
93
+ * Get middleware context by request ID
84
94
  */
85
- getInstance(guardClass: Type<Guard>): Guard | null;
95
+ get(requestId: string): MiddlewareContext | null;
86
96
  /**
87
- * Get all registered guards
97
+ * Delete middleware context by request ID
88
98
  */
89
- getAllGuards(): Guard[];
99
+ delete(requestId: string): void;
90
100
  }
91
- export declare const GuardsStore: GuardsStoreClass;
101
+ export declare const MiddlewareContextStore: MiddlewareContextStoreClass;
92
102
  export {};
package/dist/stores.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GuardsStore = exports.RouteMetadataStore = exports.MiddlewareStore = exports.ControllersStore = void 0;
3
+ exports.MiddlewareContextStore = exports.RouteMetadataStore = exports.MiddlewareStore = exports.ControllersStore = void 0;
4
4
  class ControllersStoreClass {
5
5
  constructor() {
6
6
  this.controllers = new Map();
@@ -11,6 +11,10 @@ class ControllersStoreClass {
11
11
  ...data,
12
12
  }));
13
13
  }
14
+ // For testing purposes
15
+ clear() {
16
+ this.controllers.clear();
17
+ }
14
18
  registerInstance(self, service, { allowMultipleInstances = false, } = {}) {
15
19
  const controllerClass = self.constructor;
16
20
  if (!allowMultipleInstances && this.controllers.has(controllerClass)) {
@@ -30,6 +34,10 @@ class MiddlewareStoreClass {
30
34
  constructor() {
31
35
  this.middlewares = new Map();
32
36
  }
37
+ // For testing purposes
38
+ clear() {
39
+ this.middlewares.clear();
40
+ }
33
41
  /**
34
42
  * Register a middleware instance from its constructor
35
43
  */
@@ -55,6 +63,10 @@ class RouteMetadataStoreClass {
55
63
  constructor() {
56
64
  this.routes = new Map();
57
65
  }
66
+ // For testing purposes
67
+ clear() {
68
+ this.routes.clear();
69
+ }
58
70
  /**
59
71
  * Register route metadata for a specific service method
60
72
  * @param serviceName - The full service name (e.g., "connectrpc.eliza.v1.ElizaService")
@@ -90,34 +102,35 @@ class RouteMetadataStoreClass {
90
102
  }
91
103
  exports.RouteMetadataStore = new RouteMetadataStoreClass();
92
104
  /**
93
- * Store for guard classes and their instances
105
+ * Store for middleware context - maps request IDs to middleware context
106
+ * This allows interceptors to access both raw request/response objects and context values
94
107
  */
95
- class GuardsStoreClass {
108
+ class MiddlewareContextStoreClass {
96
109
  constructor() {
97
- this.guards = new Map();
110
+ this.contexts = new Map();
111
+ }
112
+ // For testing purposes
113
+ clear() {
114
+ this.contexts.clear();
98
115
  }
99
116
  /**
100
- * Register a guard instance from its constructor
117
+ * Store middleware context by request ID
101
118
  */
102
- registerInstance(self, { allowMultipleInstances = false, } = {}) {
103
- const guardClass = self.constructor;
104
- if (!allowMultipleInstances && this.guards.has(guardClass)) {
105
- throw new Error(`Guard ${guardClass.name} is already registered! This may happen if you export guard as provider and also register it in some Nest module.`);
106
- }
107
- this.guards.set(guardClass, self);
119
+ set(requestId, context) {
120
+ this.contexts.set(requestId, context);
108
121
  }
109
122
  /**
110
- * Get a guard instance by its class
123
+ * Get middleware context by request ID
111
124
  */
112
- getInstance(guardClass) {
113
- return this.guards.get(guardClass) || null;
125
+ get(requestId) {
126
+ return this.contexts.get(requestId) || null;
114
127
  }
115
128
  /**
116
- * Get all registered guards
129
+ * Delete middleware context by request ID
117
130
  */
118
- getAllGuards() {
119
- return Array.from(this.guards.values());
131
+ delete(requestId) {
132
+ this.contexts.delete(requestId);
120
133
  }
121
134
  }
122
- exports.GuardsStore = new GuardsStoreClass();
135
+ exports.MiddlewareContextStore = new MiddlewareContextStoreClass();
123
136
  //# sourceMappingURL=stores.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stores.js","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stores.js","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,33 +1,36 @@
1
1
  {
2
2
  "name": "@funduck/connectrpc-fastify",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
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/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "build": "npx rimraf dist; tsc -p tsconfig.build.json",
10
- "compile-proto": "cd test && npx buf dep update; npx buf lint; npx buf generate",
11
- "test": "npm run compile-proto && cd test && DEBUG=true npx tsx e2e-demo.ts",
10
+ "compile-proto": "cd test/demo && npx buf dep update; npx buf lint; npx buf generate",
11
+ "test:demo": "npm run compile-proto && cd test/demo && DEBUG=true npx tsx e2e-demo.ts",
12
+ "test": "npm run compile-proto && jest --verbose",
13
+ "test:coverage": "npm run compile-proto && jest --coverage --runInBand",
12
14
  "publish:check": "npm test && npm run build && npm publish --tag latest --access public --dry-run",
13
15
  "publish:latest": "npm publish --tag latest --access public"
14
16
  },
15
17
  "license": "MIT",
16
- "dependencies": {
17
- "@connectrpc/connect-fastify": "^2.1.1",
18
- "type-fest": "^5.4.1"
19
- },
20
18
  "peerDependencies": {
21
19
  "@bufbuild/protobuf": "^2.10.2",
22
- "fastify": "^5.6.2"
20
+ "@connectrpc/connect-fastify": "^2.1.1",
21
+ "fastify": "^5.6.2",
22
+ "type-fest": "^5.4.1"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@bufbuild/buf": "^1.64.0",
26
26
  "@bufbuild/protoc-gen-es": "^2.10.2",
27
27
  "@connectrpc/connect": "^2.1.1",
28
28
  "@connectrpc/connect-node": "^2.1.1",
29
+ "@types/jest": "^30.0.0",
29
30
  "@types/node": "^25.0.9",
31
+ "jest": "^30.2.0",
30
32
  "prettier-plugin-organize-imports": "^4.3.0",
33
+ "ts-jest": "^29.4.6",
31
34
  "ts-node": "^10.9.2",
32
35
  "typescript": "^5.9.3"
33
36
  }
@@ -1,22 +0,0 @@
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
- }
@@ -1,40 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ManualExecutionContext = void 0;
4
- class ManualExecutionContext {
5
- constructor(request, response, next, args, constructorRef = null, handler = null) {
6
- this.request = request;
7
- this.response = response;
8
- this.next = next;
9
- this.args = args;
10
- this.constructorRef = constructorRef;
11
- this.handler = handler;
12
- }
13
- getClass() {
14
- return this.constructorRef;
15
- }
16
- getHandler() {
17
- return this.handler;
18
- }
19
- getArgs() {
20
- return this.args;
21
- }
22
- getArgByIndex(index) {
23
- return this.args[index];
24
- }
25
- switchToHttp() {
26
- return Object.assign(this, {
27
- getRequest: () => this.request,
28
- getResponse: () => this.response,
29
- getNext: () => this.next,
30
- });
31
- }
32
- switchToRpc() {
33
- throw new Error('Context switching to RPC is not supported.');
34
- }
35
- switchToWs() {
36
- throw new Error('Context switching to WebSockets is not supported.');
37
- }
38
- }
39
- exports.ManualExecutionContext = ManualExecutionContext;
40
- //# sourceMappingURL=execution-context.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../src/execution-context.ts"],"names":[],"mappings":";;;AAGA,MAAa,sBAAsB;IACjC,YACW,OAA8B,EAC9B,QAA6B,EAC7B,IAAsB,EACtB,IAAW,EACX,iBAAmC,IAAI,EACvC,UAA2B,IAAI;QAL/B,YAAO,GAAP,OAAO,CAAuB;QAC9B,aAAQ,GAAR,QAAQ,CAAqB;QAC7B,SAAI,GAAJ,IAAI,CAAkB;QACtB,SAAI,GAAJ,IAAI,CAAO;QACX,mBAAc,GAAd,cAAc,CAAyB;QACvC,YAAO,GAAP,OAAO,CAAwB;IACvC,CAAC;IAEJ,QAAQ;QACN,OAAO,IAAI,CAAC,cAAe,CAAC;IAC9B,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAQ,CAAC;IACvB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAS,CAAC;IACxB,CAAC;IAED,aAAa,CAAU,KAAa;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAM,CAAC;IAC/B,CAAC;IAED,YAAY;QACV,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YACzB,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO;YAC9B,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ;YAChC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI;SACzB,CAAC,CAAC;IACL,CAAC;IAED,WAAW;QACT,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,UAAU;QACR,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;CACF;AAzCD,wDAyCC"}
package/dist/guards.d.ts DELETED
@@ -1,11 +0,0 @@
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>;
package/dist/guards.js DELETED
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ManualGuardExecutor = void 0;
4
- exports.getGuards = getGuards;
5
- exports.initGuards = initGuards;
6
- const execution_context_1 = require("./execution-context");
7
- const helpers_1 = require("./helpers");
8
- const stores_1 = require("./stores");
9
- class ManualGuardExecutor {
10
- async executeGuard(guard, context) {
11
- const result = guard.canActivate(context);
12
- // Handle synchronous boolean result
13
- if (typeof result === 'boolean') {
14
- return result;
15
- }
16
- // Handle Promise result
17
- return await result;
18
- }
19
- async executeGuards(guards, context) {
20
- for (const guard of guards) {
21
- const canActivate = await this.executeGuard(guard, context);
22
- if (!canActivate) {
23
- return false;
24
- }
25
- }
26
- return true;
27
- }
28
- }
29
- exports.ManualGuardExecutor = ManualGuardExecutor;
30
- function getGuards(controller) {
31
- // Return all registered guards
32
- // In a more sophisticated implementation, you could filter guards
33
- // based on decorators on the controller or method
34
- return stores_1.GuardsStore.getAllGuards();
35
- }
36
- /**
37
- * Initialize guards middleware - this should be called after all other middlewares are registered
38
- */
39
- async function initGuards(server) {
40
- const guardExecutor = new ManualGuardExecutor();
41
- // Add a hook that runs after all other middlewares
42
- server.addHook('preHandler', async (request, reply) => {
43
- const url = request.url;
44
- // Parse the URL to get the route
45
- // Format: /package.ServiceName/MethodName
46
- const match = url.match(/^\/([^/]+)\/([^/]+)$/);
47
- if (!match) {
48
- // Not a ConnectRPC route, skip guard execution
49
- return;
50
- }
51
- // Get route metadata
52
- const routeMetadata = stores_1.RouteMetadataStore.getRouteMetadata(url);
53
- if (!routeMetadata) {
54
- // No metadata found for this route
55
- helpers_1.logger.warn(`No route metadata found for ${url}`);
56
- return;
57
- }
58
- const { controllerClass, controllerMethod, controllerMethodName, instance, } = routeMetadata;
59
- // Get guards for the controller
60
- const guards = getGuards(instance);
61
- if (guards.length === 0) {
62
- // No guards to execute
63
- return;
64
- }
65
- // Create execution context
66
- // Note: For ConnectRPC, we don't have the actual request arguments yet at this point
67
- // They will be deserialized later by the ConnectRPC handler
68
- const executionContext = new execution_context_1.ManualExecutionContext(request.raw, reply.raw, (() => undefined), [], // args will be populated later if needed
69
- controllerClass, controllerMethod);
70
- // Execute guards
71
- try {
72
- const canActivate = await guardExecutor.executeGuards(guards, executionContext);
73
- if (!canActivate) {
74
- // Guard rejected the request
75
- reply.code(403).send({
76
- code: 'permission_denied',
77
- message: 'Forbidden',
78
- });
79
- throw new Error('Guard rejected the request');
80
- }
81
- }
82
- catch (error) {
83
- // If guard throws an error, reject the request
84
- if (!reply.sent) {
85
- reply.code(403).send({
86
- code: 'permission_denied',
87
- message: error instanceof Error ? error.message : 'Forbidden',
88
- });
89
- }
90
- throw error;
91
- }
92
- });
93
- helpers_1.logger.log('Guards middleware initialized');
94
- }
95
- //# sourceMappingURL=guards.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guards.js","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"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"}