raffel 0.1.2 → 0.2.2

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.
Files changed (268) hide show
  1. package/README.md +314 -346
  2. package/dist/adapters/index.d.ts +3 -1
  3. package/dist/adapters/index.d.ts.map +1 -1
  4. package/dist/adapters/index.js +3 -1
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/adapters/s3db/adapter.d.ts.map +1 -1
  7. package/dist/adapters/s3db/adapter.js +0 -3
  8. package/dist/adapters/s3db/adapter.js.map +1 -1
  9. package/dist/adapters/udp.d.ts +83 -0
  10. package/dist/adapters/udp.d.ts.map +1 -0
  11. package/dist/adapters/udp.int.test.d.ts +5 -0
  12. package/dist/adapters/udp.int.test.d.ts.map +1 -0
  13. package/dist/adapters/udp.int.test.js +397 -0
  14. package/dist/adapters/udp.int.test.js.map +1 -0
  15. package/dist/adapters/udp.js +391 -0
  16. package/dist/adapters/udp.js.map +1 -0
  17. package/dist/cache/drivers/file.d.ts.map +1 -1
  18. package/dist/cache/drivers/file.js +13 -1
  19. package/dist/cache/drivers/file.js.map +1 -1
  20. package/dist/cache/drivers/memory.d.ts.map +1 -1
  21. package/dist/cache/drivers/memory.js +1 -0
  22. package/dist/cache/drivers/memory.js.map +1 -1
  23. package/dist/cache/types.d.ts +1 -0
  24. package/dist/cache/types.d.ts.map +1 -1
  25. package/dist/docs/generators/http-generator.d.ts.map +1 -1
  26. package/dist/docs/generators/http-generator.js +0 -1
  27. package/dist/docs/generators/http-generator.js.map +1 -1
  28. package/dist/graphql/graphql.int.test.d.ts +10 -0
  29. package/dist/graphql/graphql.int.test.d.ts.map +1 -0
  30. package/dist/graphql/graphql.int.test.js +698 -0
  31. package/dist/graphql/graphql.int.test.js.map +1 -0
  32. package/dist/graphql/schema-generator.d.ts.map +1 -1
  33. package/dist/graphql/schema-generator.js +20 -7
  34. package/dist/graphql/schema-generator.js.map +1 -1
  35. package/dist/http/auth.d.ts.map +1 -1
  36. package/dist/http/auth.js +15 -1
  37. package/dist/http/auth.js.map +1 -1
  38. package/dist/http/http.int.test.d.ts +7 -0
  39. package/dist/http/http.int.test.d.ts.map +1 -0
  40. package/dist/http/http.int.test.js +604 -0
  41. package/dist/http/http.int.test.js.map +1 -0
  42. package/dist/http/index.d.ts +2 -0
  43. package/dist/http/index.d.ts.map +1 -1
  44. package/dist/http/index.js +2 -0
  45. package/dist/http/index.js.map +1 -1
  46. package/dist/http/oauth2.d.ts.map +1 -1
  47. package/dist/http/oauth2.js +39 -0
  48. package/dist/http/oauth2.js.map +1 -1
  49. package/dist/http/oidc.d.ts.map +1 -1
  50. package/dist/http/oidc.js +9 -1
  51. package/dist/http/oidc.js.map +1 -1
  52. package/dist/http/session-redis.d.ts +187 -0
  53. package/dist/http/session-redis.d.ts.map +1 -0
  54. package/dist/http/session-redis.int.test.d.ts +8 -0
  55. package/dist/http/session-redis.int.test.d.ts.map +1 -0
  56. package/dist/http/session-redis.int.test.js +492 -0
  57. package/dist/http/session-redis.int.test.js.map +1 -0
  58. package/dist/http/session-redis.js +320 -0
  59. package/dist/http/session-redis.js.map +1 -0
  60. package/dist/index.d.ts +2 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +25 -0
  63. package/dist/index.js.map +1 -1
  64. package/dist/mcp/cli.js +2 -1
  65. package/dist/mcp/cli.js.map +1 -1
  66. package/dist/mcp/docs/adapters.d.ts.map +1 -1
  67. package/dist/mcp/docs/adapters.js +175 -145
  68. package/dist/mcp/docs/adapters.js.map +1 -1
  69. package/dist/mcp/docs/interceptors.d.ts +1 -1
  70. package/dist/mcp/docs/interceptors.d.ts.map +1 -1
  71. package/dist/mcp/docs/interceptors.js +231 -305
  72. package/dist/mcp/docs/interceptors.js.map +1 -1
  73. package/dist/mcp/docs/patterns.d.ts.map +1 -1
  74. package/dist/mcp/docs/patterns.js +20 -18
  75. package/dist/mcp/docs/patterns.js.map +1 -1
  76. package/dist/mcp/docs/quickstart.d.ts +1 -1
  77. package/dist/mcp/docs/quickstart.d.ts.map +1 -1
  78. package/dist/mcp/docs/quickstart.js +48 -46
  79. package/dist/mcp/docs/quickstart.js.map +1 -1
  80. package/dist/mcp/server.d.ts +1 -1
  81. package/dist/mcp/server.d.ts.map +1 -1
  82. package/dist/mcp/server.js +6 -7
  83. package/dist/mcp/server.js.map +1 -1
  84. package/dist/mcp/version.d.ts +7 -0
  85. package/dist/mcp/version.d.ts.map +1 -0
  86. package/dist/mcp/version.js +20 -0
  87. package/dist/mcp/version.js.map +1 -0
  88. package/dist/middleware/auth/oauth2.d.ts +294 -0
  89. package/dist/middleware/auth/oauth2.d.ts.map +1 -0
  90. package/dist/middleware/auth/oauth2.int.test.d.ts +2 -0
  91. package/dist/middleware/auth/oauth2.int.test.d.ts.map +1 -0
  92. package/dist/middleware/auth/oauth2.int.test.js +714 -0
  93. package/dist/middleware/auth/oauth2.int.test.js.map +1 -0
  94. package/dist/middleware/auth/oauth2.js +671 -0
  95. package/dist/middleware/auth/oauth2.js.map +1 -0
  96. package/dist/middleware/auth.d.ts +2 -0
  97. package/dist/middleware/auth.d.ts.map +1 -1
  98. package/dist/middleware/auth.js +16 -0
  99. package/dist/middleware/auth.js.map +1 -1
  100. package/dist/middleware/index.d.ts +5 -2
  101. package/dist/middleware/index.d.ts.map +1 -1
  102. package/dist/middleware/index.js +4 -0
  103. package/dist/middleware/index.js.map +1 -1
  104. package/dist/middleware/interceptors/circuit-breaker.d.ts.map +1 -1
  105. package/dist/middleware/interceptors/circuit-breaker.js +0 -1
  106. package/dist/middleware/interceptors/circuit-breaker.js.map +1 -1
  107. package/dist/middleware/interceptors/envelope.d.ts +176 -0
  108. package/dist/middleware/interceptors/envelope.d.ts.map +1 -0
  109. package/dist/middleware/interceptors/envelope.int.test.d.ts +5 -0
  110. package/dist/middleware/interceptors/envelope.int.test.d.ts.map +1 -0
  111. package/dist/middleware/interceptors/envelope.int.test.js +409 -0
  112. package/dist/middleware/interceptors/envelope.int.test.js.map +1 -0
  113. package/dist/middleware/interceptors/envelope.js +294 -0
  114. package/dist/middleware/interceptors/envelope.js.map +1 -0
  115. package/dist/middleware/interceptors/index.d.ts +2 -0
  116. package/dist/middleware/interceptors/index.d.ts.map +1 -1
  117. package/dist/middleware/interceptors/index.js +2 -0
  118. package/dist/middleware/interceptors/index.js.map +1 -1
  119. package/dist/middleware/types.d.ts +25 -0
  120. package/dist/middleware/types.d.ts.map +1 -1
  121. package/dist/rate-limit/drivers/drivers.int.test.d.ts +7 -0
  122. package/dist/rate-limit/drivers/drivers.int.test.d.ts.map +1 -0
  123. package/dist/rate-limit/drivers/drivers.int.test.js +466 -0
  124. package/dist/rate-limit/drivers/drivers.int.test.js.map +1 -0
  125. package/dist/server/builder.d.ts.map +1 -1
  126. package/dist/server/builder.int.test.js +41 -0
  127. package/dist/server/builder.int.test.js.map +1 -1
  128. package/dist/server/builder.js +72 -15
  129. package/dist/server/builder.js.map +1 -1
  130. package/dist/server/channel-utils.d.ts +4 -1
  131. package/dist/server/channel-utils.d.ts.map +1 -1
  132. package/dist/server/channel-utils.js +12 -2
  133. package/dist/server/channel-utils.js.map +1 -1
  134. package/dist/server/errors.d.ts.map +1 -1
  135. package/dist/server/errors.js +0 -22
  136. package/dist/server/errors.js.map +1 -1
  137. package/dist/server/fs-routes/watcher.js +1 -1
  138. package/dist/server/fs-routes/watcher.js.map +1 -1
  139. package/dist/server/index.d.ts +1 -1
  140. package/dist/server/index.d.ts.map +1 -1
  141. package/dist/server/index.js.map +1 -1
  142. package/dist/server/types.d.ts +37 -33
  143. package/dist/server/types.d.ts.map +1 -1
  144. package/dist/tracing/interceptor.d.ts.map +1 -1
  145. package/dist/tracing/interceptor.js +4 -5
  146. package/dist/tracing/interceptor.js.map +1 -1
  147. package/dist/types/envelope.d.ts +1 -1
  148. package/dist/types/envelope.d.ts.map +1 -1
  149. package/dist/types/envelope.js.map +1 -1
  150. package/dist/types/handlers.d.ts +8 -0
  151. package/dist/types/handlers.d.ts.map +1 -1
  152. package/dist/ui/core/index.d.ts +7 -0
  153. package/dist/ui/core/index.d.ts.map +1 -0
  154. package/dist/ui/docs/generators/content-types.d.ts +10 -0
  155. package/dist/ui/docs/generators/content-types.d.ts.map +1 -0
  156. package/dist/ui/docs/generators/errors-types.d.ts +409 -0
  157. package/dist/ui/docs/generators/errors-types.d.ts.map +1 -0
  158. package/dist/ui/docs/generators/errors.d.ts +88 -0
  159. package/dist/ui/docs/generators/errors.d.ts.map +1 -0
  160. package/dist/ui/docs/generators/grpc-generator.d.ts +53 -0
  161. package/dist/ui/docs/generators/grpc-generator.d.ts.map +1 -0
  162. package/dist/ui/docs/generators/http-generator.d.ts +49 -0
  163. package/dist/ui/docs/generators/http-generator.d.ts.map +1 -0
  164. package/dist/ui/docs/generators/index.d.ts +17 -0
  165. package/dist/ui/docs/generators/index.d.ts.map +1 -0
  166. package/dist/ui/docs/generators/jsonrpc-generator.d.ts +53 -0
  167. package/dist/ui/docs/generators/jsonrpc-generator.d.ts.map +1 -0
  168. package/dist/ui/docs/generators/schema-converter.d.ts +117 -0
  169. package/dist/ui/docs/generators/schema-converter.d.ts.map +1 -0
  170. package/dist/ui/docs/generators/streams-generator.d.ts +85 -0
  171. package/dist/ui/docs/generators/streams-generator.d.ts.map +1 -0
  172. package/dist/ui/docs/generators/tcp-generator.d.ts +133 -0
  173. package/dist/ui/docs/generators/tcp-generator.d.ts.map +1 -0
  174. package/dist/ui/docs/generators/udp-generator.d.ts +119 -0
  175. package/dist/ui/docs/generators/udp-generator.d.ts.map +1 -0
  176. package/dist/ui/docs/generators/usd-generator.d.ts +182 -0
  177. package/dist/ui/docs/generators/usd-generator.d.ts.map +1 -0
  178. package/dist/ui/docs/generators/websocket-generator.d.ts +49 -0
  179. package/dist/ui/docs/generators/websocket-generator.d.ts.map +1 -0
  180. package/dist/ui/docs/index.d.ts +31 -0
  181. package/dist/ui/docs/index.d.ts.map +1 -0
  182. package/dist/ui/docs/usd-middleware.d.ts +157 -0
  183. package/dist/ui/docs/usd-middleware.d.ts.map +1 -0
  184. package/dist/ui/errors/factories.d.ts +142 -0
  185. package/dist/ui/errors/factories.d.ts.map +1 -0
  186. package/dist/ui/errors/index.d.ts +9 -0
  187. package/dist/ui/errors/index.d.ts.map +1 -0
  188. package/dist/ui/server/fs-routes/index.d.ts +66 -0
  189. package/dist/ui/server/fs-routes/index.d.ts.map +1 -0
  190. package/dist/ui/server/fs-routes/loader.d.ts +28 -0
  191. package/dist/ui/server/fs-routes/loader.d.ts.map +1 -0
  192. package/dist/ui/server/fs-routes/middleware-processor.d.ts +19 -0
  193. package/dist/ui/server/fs-routes/middleware-processor.d.ts.map +1 -0
  194. package/dist/ui/server/fs-routes/resources/index.d.ts +8 -0
  195. package/dist/ui/server/fs-routes/resources/index.d.ts.map +1 -0
  196. package/dist/ui/server/fs-routes/resources/loader.d.ts +16 -0
  197. package/dist/ui/server/fs-routes/resources/loader.d.ts.map +1 -0
  198. package/dist/ui/server/fs-routes/resources/types.d.ts +256 -0
  199. package/dist/ui/server/fs-routes/resources/types.d.ts.map +1 -0
  200. package/dist/ui/server/fs-routes/rest/index.d.ts +8 -0
  201. package/dist/ui/server/fs-routes/rest/index.d.ts.map +1 -0
  202. package/dist/ui/server/fs-routes/rest/loader.d.ts +11 -0
  203. package/dist/ui/server/fs-routes/rest/loader.d.ts.map +1 -0
  204. package/dist/ui/server/fs-routes/rest/types.d.ts +288 -0
  205. package/dist/ui/server/fs-routes/rest/types.d.ts.map +1 -0
  206. package/dist/ui/server/fs-routes/tcp/index.d.ts +8 -0
  207. package/dist/ui/server/fs-routes/tcp/index.d.ts.map +1 -0
  208. package/dist/ui/server/fs-routes/tcp/loader.d.ts +15 -0
  209. package/dist/ui/server/fs-routes/tcp/loader.d.ts.map +1 -0
  210. package/dist/ui/server/fs-routes/tcp/types.d.ts +215 -0
  211. package/dist/ui/server/fs-routes/tcp/types.d.ts.map +1 -0
  212. package/dist/ui/server/fs-routes/types.d.ts +437 -0
  213. package/dist/ui/server/fs-routes/types.d.ts.map +1 -0
  214. package/dist/ui/server/fs-routes/udp/index.d.ts +8 -0
  215. package/dist/ui/server/fs-routes/udp/index.d.ts.map +1 -0
  216. package/dist/ui/server/fs-routes/udp/loader.d.ts +15 -0
  217. package/dist/ui/server/fs-routes/udp/loader.d.ts.map +1 -0
  218. package/dist/ui/server/fs-routes/udp/types.d.ts +164 -0
  219. package/dist/ui/server/fs-routes/udp/types.d.ts.map +1 -0
  220. package/dist/ui/server/fs-routes/watcher.d.ts +34 -0
  221. package/dist/ui/server/fs-routes/watcher.d.ts.map +1 -0
  222. package/dist/ui/types/envelope.d.ts +1 -1
  223. package/dist/ui/types/envelope.d.ts.map +1 -1
  224. package/dist/ui/types/handlers.d.ts +8 -0
  225. package/dist/ui/types/handlers.d.ts.map +1 -1
  226. package/dist/ui/usd/builder/document.d.ts.map +1 -1
  227. package/dist/ui/usd/export/openapi.d.ts.map +1 -1
  228. package/dist/ui/usd/parser/normalize.d.ts.map +1 -1
  229. package/dist/ui/usd/spec/types.d.ts +14 -20
  230. package/dist/ui/usd/spec/types.d.ts.map +1 -1
  231. package/dist/ui/usd/utils/refs.d.ts.map +1 -1
  232. package/dist/ui/usd/validator/index.d.ts.map +1 -1
  233. package/dist/ui/usd/validator/schema.d.ts.map +1 -1
  234. package/dist/ui/usd/validator/semantic.d.ts.map +1 -1
  235. package/dist/ui/utils/logger.d.ts +15 -0
  236. package/dist/ui/utils/logger.d.ts.map +1 -0
  237. package/dist/usd/builder/document.d.ts.map +1 -1
  238. package/dist/usd/builder/document.js.map +1 -1
  239. package/dist/usd/export/openapi.d.ts.map +1 -1
  240. package/dist/usd/export/openapi.js +2 -4
  241. package/dist/usd/export/openapi.js.map +1 -1
  242. package/dist/usd/parser/normalize.d.ts.map +1 -1
  243. package/dist/usd/parser/normalize.js +0 -1
  244. package/dist/usd/parser/normalize.js.map +1 -1
  245. package/dist/usd/usd.int.test.d.ts +10 -0
  246. package/dist/usd/usd.int.test.d.ts.map +1 -0
  247. package/dist/usd/usd.int.test.js +719 -0
  248. package/dist/usd/usd.int.test.js.map +1 -0
  249. package/dist/usd/utils/refs.d.ts.map +1 -1
  250. package/dist/usd/validator/index.d.ts.map +1 -1
  251. package/dist/usd/validator/index.js.map +1 -1
  252. package/dist/usd/validator/schema.d.ts.map +1 -1
  253. package/dist/usd/validator/schema.js.map +1 -1
  254. package/dist/usd/validator/semantic.d.ts.map +1 -1
  255. package/dist/usd/validator/semantic.js.map +1 -1
  256. package/package.json +1 -1
  257. package/dist/middleware/rate-limit.d.ts +0 -105
  258. package/dist/middleware/rate-limit.d.ts.map +0 -1
  259. package/dist/middleware/rate-limit.int.test.d.ts +0 -5
  260. package/dist/middleware/rate-limit.int.test.d.ts.map +0 -1
  261. package/dist/middleware/rate-limit.int.test.js +0 -350
  262. package/dist/middleware/rate-limit.int.test.js.map +0 -1
  263. package/dist/middleware/rate-limit.js +0 -206
  264. package/dist/middleware/rate-limit.js.map +0 -1
  265. package/dist/openapi/index.d.ts +0 -9
  266. package/dist/openapi/index.d.ts.map +0 -1
  267. package/dist/openapi/index.js +0 -9
  268. package/dist/openapi/index.js.map +0 -1
@@ -1,350 +0,0 @@
1
- /**
2
- * Rate Limiting Middleware Tests
3
- */
4
- import { describe, it, expect, vi } from 'vitest';
5
- import { createRateLimitMiddleware, createPerProcedureRateLimitMiddleware, createInMemoryStore, createSlidingWindowRateLimiter, } from './rate-limit.js';
6
- import { createContext } from '../types/index.js';
7
- // Helper to create test envelope
8
- function createTestEnvelope(procedure, metadata) {
9
- return {
10
- id: 'test-1',
11
- procedure,
12
- type: 'request',
13
- payload: {},
14
- metadata: metadata ?? {},
15
- context: createContext('test-1'),
16
- };
17
- }
18
- // Helper to create context with auth
19
- function createAuthenticatedContext(principal) {
20
- const ctx = createContext('test');
21
- ctx.auth = {
22
- authenticated: true,
23
- principal,
24
- claims: {},
25
- };
26
- return ctx;
27
- }
28
- describe('Rate Limiting Middleware', () => {
29
- describe('In-Memory Store', () => {
30
- it('should increment counter for new key', async () => {
31
- const store = createInMemoryStore();
32
- const result = await store.increment('user:test', 60000);
33
- expect(result.count).toBe(1);
34
- expect(result.resetAt).toBeGreaterThan(Date.now());
35
- });
36
- it('should increment counter for existing key', async () => {
37
- const store = createInMemoryStore();
38
- await store.increment('user:test', 60000);
39
- await store.increment('user:test', 60000);
40
- const result = await store.increment('user:test', 60000);
41
- expect(result.count).toBe(3);
42
- });
43
- it('should get current count', async () => {
44
- const store = createInMemoryStore();
45
- await store.increment('user:test', 60000);
46
- await store.increment('user:test', 60000);
47
- const result = await store.get('user:test');
48
- expect(result?.count).toBe(2);
49
- });
50
- it('should return null for non-existent key', async () => {
51
- const store = createInMemoryStore();
52
- const result = await store.get('non-existent');
53
- expect(result).toBeNull();
54
- });
55
- it('should reset key', async () => {
56
- const store = createInMemoryStore();
57
- await store.increment('user:test', 60000);
58
- await store.increment('user:test', 60000);
59
- await store.reset('user:test');
60
- const result = await store.get('user:test');
61
- expect(result).toBeNull();
62
- });
63
- it('should apply sliding window - remove old timestamps', async () => {
64
- const store = createInMemoryStore();
65
- const windowMs = 100; // 100ms window
66
- // Add a request
67
- await store.increment('user:test', windowMs);
68
- // Wait for window to expire
69
- await new Promise((resolve) => setTimeout(resolve, 150));
70
- // New request should be count 1 (old one expired)
71
- const result = await store.increment('user:test', windowMs);
72
- expect(result.count).toBe(1);
73
- });
74
- });
75
- describe('Rate Limit Middleware', () => {
76
- it('should allow requests within limit', async () => {
77
- const middleware = createRateLimitMiddleware({
78
- limit: 5,
79
- windowMs: 60000,
80
- });
81
- const envelope = createTestEnvelope('test');
82
- const ctx = createAuthenticatedContext('user-1');
83
- const next = vi.fn().mockResolvedValue({ ok: true });
84
- // Make 5 requests (all should pass)
85
- for (let i = 0; i < 5; i++) {
86
- await middleware(envelope, ctx, next);
87
- }
88
- expect(next).toHaveBeenCalledTimes(5);
89
- });
90
- it('should block requests over limit', async () => {
91
- const middleware = createRateLimitMiddleware({
92
- limit: 3,
93
- windowMs: 60000,
94
- });
95
- const envelope = createTestEnvelope('test');
96
- const ctx = createAuthenticatedContext('user-1');
97
- const next = vi.fn().mockResolvedValue({ ok: true });
98
- // Make 3 requests (all should pass)
99
- for (let i = 0; i < 3; i++) {
100
- await middleware(envelope, ctx, next);
101
- }
102
- // 4th request should be blocked
103
- await expect(middleware(envelope, ctx, next)).rejects.toThrow('Rate limit exceeded');
104
- expect(next).toHaveBeenCalledTimes(3);
105
- });
106
- it('should use principal for key extraction', async () => {
107
- const store = createInMemoryStore();
108
- const middleware = createRateLimitMiddleware({
109
- limit: 2,
110
- windowMs: 60000,
111
- store,
112
- });
113
- const envelope = createTestEnvelope('test');
114
- const ctx1 = createAuthenticatedContext('user-1');
115
- const ctx2 = createAuthenticatedContext('user-2');
116
- const next = vi.fn().mockResolvedValue({ ok: true });
117
- // User 1 makes 2 requests
118
- await middleware(envelope, ctx1, next);
119
- await middleware(envelope, ctx1, next);
120
- // User 1 blocked
121
- await expect(middleware(envelope, ctx1, next)).rejects.toThrow('Rate limit exceeded');
122
- // User 2 can still make requests
123
- await middleware(envelope, ctx2, next);
124
- expect(next).toHaveBeenCalledTimes(3);
125
- });
126
- it('should skip rate limiting for specified procedures', async () => {
127
- const middleware = createRateLimitMiddleware({
128
- limit: 1,
129
- windowMs: 60000,
130
- skipProcedures: ['health', 'status'],
131
- });
132
- const healthEnvelope = createTestEnvelope('health');
133
- const ctx = createAuthenticatedContext('user-1');
134
- const next = vi.fn().mockResolvedValue({ ok: true });
135
- // Health check should always pass
136
- await middleware(healthEnvelope, ctx, next);
137
- await middleware(healthEnvelope, ctx, next);
138
- await middleware(healthEnvelope, ctx, next);
139
- expect(next).toHaveBeenCalledTimes(3);
140
- });
141
- it('should use custom skip function', async () => {
142
- const middleware = createRateLimitMiddleware({
143
- limit: 1,
144
- windowMs: 60000,
145
- skip: (envelope) => envelope.procedure.startsWith('internal.'),
146
- });
147
- const internalEnvelope = createTestEnvelope('internal.sync');
148
- const ctx = createAuthenticatedContext('user-1');
149
- const next = vi.fn().mockResolvedValue({ ok: true });
150
- // Internal procedures should be skipped
151
- await middleware(internalEnvelope, ctx, next);
152
- await middleware(internalEnvelope, ctx, next);
153
- expect(next).toHaveBeenCalledTimes(2);
154
- });
155
- it('should call onLimitReached handler', async () => {
156
- const onLimitReached = vi.fn();
157
- const middleware = createRateLimitMiddleware({
158
- limit: 1,
159
- windowMs: 60000,
160
- onLimitReached,
161
- });
162
- const envelope = createTestEnvelope('test');
163
- const ctx = createAuthenticatedContext('user-1');
164
- const next = vi.fn().mockResolvedValue({ ok: true });
165
- await middleware(envelope, ctx, next);
166
- await expect(middleware(envelope, ctx, next)).rejects.toThrow('Rate limit exceeded');
167
- expect(onLimitReached).toHaveBeenCalledTimes(1);
168
- expect(onLimitReached).toHaveBeenCalledWith(envelope, ctx, expect.objectContaining({
169
- limit: 1,
170
- remaining: 0,
171
- exceeded: true,
172
- }));
173
- });
174
- it('should use custom key extractor', async () => {
175
- const middleware = createRateLimitMiddleware({
176
- limit: 2,
177
- windowMs: 60000,
178
- keyExtractor: (envelope) => `custom:${envelope.procedure}`,
179
- });
180
- const envelope1 = createTestEnvelope('proc1');
181
- const envelope2 = createTestEnvelope('proc2');
182
- const ctx = createAuthenticatedContext('user-1');
183
- const next = vi.fn().mockResolvedValue({ ok: true });
184
- // Different procedures = different keys
185
- await middleware(envelope1, ctx, next);
186
- await middleware(envelope1, ctx, next);
187
- await expect(middleware(envelope1, ctx, next)).rejects.toThrow();
188
- // proc2 should still work
189
- await middleware(envelope2, ctx, next);
190
- expect(next).toHaveBeenCalledTimes(3);
191
- });
192
- it('should use IP from x-forwarded-for header', async () => {
193
- const store = createInMemoryStore();
194
- const middleware = createRateLimitMiddleware({
195
- limit: 2,
196
- windowMs: 60000,
197
- store,
198
- });
199
- const envelope = createTestEnvelope('test', { 'x-forwarded-for': '192.168.1.1' });
200
- const ctx = createContext('test'); // No auth
201
- const next = vi.fn().mockResolvedValue({ ok: true });
202
- await middleware(envelope, ctx, next);
203
- await middleware(envelope, ctx, next);
204
- await expect(middleware(envelope, ctx, next)).rejects.toThrow('Rate limit exceeded');
205
- });
206
- it('should include retry-after in error', async () => {
207
- const middleware = createRateLimitMiddleware({
208
- limit: 1,
209
- windowMs: 60000,
210
- });
211
- const envelope = createTestEnvelope('test');
212
- const ctx = createAuthenticatedContext('user-1');
213
- const next = vi.fn().mockResolvedValue({ ok: true });
214
- await middleware(envelope, ctx, next);
215
- try {
216
- await middleware(envelope, ctx, next);
217
- expect.fail('Should have thrown');
218
- }
219
- catch (error) {
220
- expect(error.code).toBe('RATE_LIMITED');
221
- expect(error.details).toHaveProperty('retryAfter');
222
- expect(error.details.retryAfter).toBeGreaterThan(0);
223
- }
224
- });
225
- });
226
- describe('Per-Procedure Rate Limit Middleware', () => {
227
- it('should apply different limits per procedure', async () => {
228
- const middleware = createPerProcedureRateLimitMiddleware({
229
- limits: [
230
- { procedure: 'expensive', limit: 2, windowMs: 60000 },
231
- { procedure: 'cheap', limit: 10, windowMs: 60000 },
232
- ],
233
- });
234
- const expensiveEnvelope = createTestEnvelope('expensive');
235
- const cheapEnvelope = createTestEnvelope('cheap');
236
- const ctx = createAuthenticatedContext('user-1');
237
- const next = vi.fn().mockResolvedValue({ ok: true });
238
- // Expensive procedure limited to 2
239
- await middleware(expensiveEnvelope, ctx, next);
240
- await middleware(expensiveEnvelope, ctx, next);
241
- await expect(middleware(expensiveEnvelope, ctx, next)).rejects.toThrow();
242
- // Cheap procedure still works
243
- for (let i = 0; i < 5; i++) {
244
- await middleware(cheapEnvelope, ctx, next);
245
- }
246
- expect(next).toHaveBeenCalledTimes(7); // 2 expensive + 5 cheap
247
- });
248
- it('should match wildcard patterns', async () => {
249
- const middleware = createPerProcedureRateLimitMiddleware({
250
- limits: [{ procedure: 'admin.*', limit: 5, windowMs: 60000 }],
251
- defaultLimit: { limit: 100, windowMs: 60000 },
252
- });
253
- const adminEnvelope = createTestEnvelope('admin.users');
254
- const ctx = createAuthenticatedContext('user-1');
255
- const next = vi.fn().mockResolvedValue({ ok: true });
256
- // Admin namespace limited to 5
257
- for (let i = 0; i < 5; i++) {
258
- await middleware(adminEnvelope, ctx, next);
259
- }
260
- await expect(middleware(adminEnvelope, ctx, next)).rejects.toThrow();
261
- });
262
- it('should use default limit for unmatched procedures', async () => {
263
- const middleware = createPerProcedureRateLimitMiddleware({
264
- limits: [{ procedure: 'specific', limit: 1, windowMs: 60000 }],
265
- defaultLimit: { limit: 3, windowMs: 60000 },
266
- });
267
- const unknownEnvelope = createTestEnvelope('unknown');
268
- const ctx = createAuthenticatedContext('user-1');
269
- const next = vi.fn().mockResolvedValue({ ok: true });
270
- // Default limit of 3
271
- for (let i = 0; i < 3; i++) {
272
- await middleware(unknownEnvelope, ctx, next);
273
- }
274
- await expect(middleware(unknownEnvelope, ctx, next)).rejects.toThrow();
275
- });
276
- it('should pass through when no limit configured', async () => {
277
- const middleware = createPerProcedureRateLimitMiddleware({
278
- limits: [{ procedure: 'specific', limit: 1, windowMs: 60000 }],
279
- // No defaultLimit
280
- });
281
- const unknownEnvelope = createTestEnvelope('unknown');
282
- const ctx = createAuthenticatedContext('user-1');
283
- const next = vi.fn().mockResolvedValue({ ok: true });
284
- // Should pass through unlimited
285
- for (let i = 0; i < 100; i++) {
286
- await middleware(unknownEnvelope, ctx, next);
287
- }
288
- expect(next).toHaveBeenCalledTimes(100);
289
- });
290
- });
291
- describe('Sliding Window Rate Limiter', () => {
292
- it('should allow requests within limit', () => {
293
- const limiter = createSlidingWindowRateLimiter({
294
- limit: 5,
295
- windowMs: 60000,
296
- });
297
- for (let i = 0; i < 5; i++) {
298
- const result = limiter.check('user-1');
299
- expect(result.allowed).toBe(true);
300
- }
301
- });
302
- it('should block requests over limit', () => {
303
- const limiter = createSlidingWindowRateLimiter({
304
- limit: 3,
305
- windowMs: 60000,
306
- });
307
- // Use up limit
308
- for (let i = 0; i < 3; i++) {
309
- limiter.check('user-1');
310
- }
311
- // Should be blocked
312
- const result = limiter.check('user-1');
313
- expect(result.allowed).toBe(false);
314
- expect(result.remaining).toBe(0);
315
- });
316
- it('should track remaining correctly', () => {
317
- const limiter = createSlidingWindowRateLimiter({
318
- limit: 5,
319
- windowMs: 60000,
320
- });
321
- expect(limiter.check('user-1').remaining).toBe(4);
322
- expect(limiter.check('user-1').remaining).toBe(3);
323
- expect(limiter.check('user-1').remaining).toBe(2);
324
- });
325
- it('should reset key', () => {
326
- const limiter = createSlidingWindowRateLimiter({
327
- limit: 2,
328
- windowMs: 60000,
329
- });
330
- // Use up limit
331
- limiter.check('user-1');
332
- limiter.check('user-1');
333
- expect(limiter.check('user-1').allowed).toBe(false);
334
- // Reset
335
- limiter.reset('user-1');
336
- // Should work again
337
- expect(limiter.check('user-1').allowed).toBe(true);
338
- });
339
- it('should provide reset time', () => {
340
- const limiter = createSlidingWindowRateLimiter({
341
- limit: 5,
342
- windowMs: 60000,
343
- });
344
- const result = limiter.check('user-1');
345
- expect(result.resetAt).toBeGreaterThan(Date.now());
346
- expect(result.resetAt).toBeLessThanOrEqual(Date.now() + 60000);
347
- });
348
- });
349
- });
350
- //# sourceMappingURL=rate-limit.int.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rate-limit.int.test.js","sourceRoot":"","sources":["../../src/middleware/rate-limit.int.test.ts"],"names":[],"mappings":"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"}
@@ -1,206 +0,0 @@
1
- /**
2
- * Rate Limiting Middleware
3
- *
4
- * Protects services from abuse with configurable rate limiting.
5
- * Supports sliding window algorithm with in-memory or custom stores.
6
- */
7
- import { RaffelError } from '../core/index.js';
8
- /**
9
- * Create an in-memory rate limit store
10
- */
11
- export function createInMemoryStore() {
12
- const entries = new Map();
13
- // Clean up expired entries periodically
14
- const cleanupInterval = setInterval(() => {
15
- const now = Date.now();
16
- for (const [key, entry] of entries) {
17
- // Remove entries that haven't been touched in 5 minutes
18
- if (now - entry.lastClean > 300000) {
19
- entries.delete(key);
20
- }
21
- }
22
- }, 60000); // Run every minute
23
- // Make interval non-blocking
24
- if (cleanupInterval.unref) {
25
- cleanupInterval.unref();
26
- }
27
- return {
28
- async increment(key, windowMs) {
29
- const now = Date.now();
30
- const windowStart = now - windowMs;
31
- let entry = entries.get(key);
32
- if (!entry) {
33
- entry = { timestamps: [], lastClean: now };
34
- entries.set(key, entry);
35
- }
36
- // Remove timestamps outside the window (sliding window)
37
- entry.timestamps = entry.timestamps.filter((ts) => ts > windowStart);
38
- entry.lastClean = now;
39
- // Add current request
40
- entry.timestamps.push(now);
41
- // Calculate reset time (oldest timestamp + window, or now + window if fresh)
42
- const oldestInWindow = entry.timestamps[0] || now;
43
- const resetAt = oldestInWindow + windowMs;
44
- return {
45
- count: entry.timestamps.length,
46
- resetAt,
47
- };
48
- },
49
- async get(key) {
50
- const entry = entries.get(key);
51
- if (!entry || entry.timestamps.length === 0) {
52
- return null;
53
- }
54
- const oldestInWindow = entry.timestamps[0];
55
- return {
56
- count: entry.timestamps.length,
57
- resetAt: oldestInWindow + 60000, // Approximate, store doesn't track windowMs
58
- };
59
- },
60
- async reset(key) {
61
- entries.delete(key);
62
- },
63
- };
64
- }
65
- /**
66
- * Default key extractor - uses auth principal or falls back to a constant
67
- */
68
- function defaultKeyExtractor(envelope, ctx) {
69
- // Try to use authenticated principal
70
- if (ctx.auth?.principal) {
71
- return `user:${ctx.auth.principal}`;
72
- }
73
- // Try to use request ID as a proxy for connection
74
- if (envelope.metadata?.['x-forwarded-for']) {
75
- return `ip:${envelope.metadata['x-forwarded-for']}`;
76
- }
77
- if (envelope.metadata?.['x-real-ip']) {
78
- return `ip:${envelope.metadata['x-real-ip']}`;
79
- }
80
- // Fallback to a general key (not recommended for production)
81
- return `global:${envelope.procedure}`;
82
- }
83
- /**
84
- * Create rate limiting middleware
85
- */
86
- export function createRateLimitMiddleware(options) {
87
- const { limit, windowMs = 60000, keyExtractor = defaultKeyExtractor, store = createInMemoryStore(), onLimitReached, skip, skipProcedures = [], includeHeaders = false, } = options;
88
- return async (envelope, ctx, next) => {
89
- // Check if should skip
90
- if (skipProcedures.includes(envelope.procedure)) {
91
- return next();
92
- }
93
- if (skip && (await skip(envelope, ctx))) {
94
- return next();
95
- }
96
- // Extract key for rate limiting
97
- const key = keyExtractor(envelope, ctx);
98
- // Increment counter
99
- const { count, resetAt } = await store.increment(key, windowMs);
100
- const remaining = Math.max(0, limit - count);
101
- const exceeded = count > limit;
102
- const info = {
103
- limit,
104
- remaining,
105
- resetAt,
106
- exceeded,
107
- };
108
- // Add rate limit headers to context if configured
109
- if (includeHeaders) {
110
- ;
111
- ctx.rateLimitInfo = info;
112
- }
113
- // Check if exceeded
114
- if (exceeded) {
115
- if (onLimitReached) {
116
- await onLimitReached(envelope, ctx, info);
117
- }
118
- throw new RaffelError('RATE_LIMITED', `Rate limit exceeded. Try again in ${Math.ceil((resetAt - Date.now()) / 1000)} seconds.`, {
119
- limit,
120
- remaining: 0,
121
- resetAt,
122
- retryAfter: Math.ceil((resetAt - Date.now()) / 1000),
123
- });
124
- }
125
- return next();
126
- };
127
- }
128
- /**
129
- * Create rate limit middleware with different limits per procedure
130
- */
131
- export function createPerProcedureRateLimitMiddleware(options) {
132
- const { limits, defaultLimit, ...baseOptions } = options;
133
- const store = baseOptions.store ?? createInMemoryStore();
134
- // Compile procedure patterns
135
- const compiledLimits = limits.map((l) => ({
136
- ...l,
137
- pattern: l.procedure,
138
- matches: createMatcher(l.procedure),
139
- }));
140
- function createMatcher(pattern) {
141
- if (pattern === '*')
142
- return () => true;
143
- if (pattern.endsWith('.*')) {
144
- const prefix = pattern.slice(0, -2) + '.';
145
- return (p) => p.startsWith(prefix);
146
- }
147
- return (p) => p === pattern;
148
- }
149
- function findLimit(procedure) {
150
- for (const compiled of compiledLimits) {
151
- if (compiled.matches(procedure)) {
152
- return { limit: compiled.limit, windowMs: compiled.windowMs ?? 60000 };
153
- }
154
- }
155
- return defaultLimit ? { limit: defaultLimit.limit, windowMs: defaultLimit.windowMs ?? 60000 } : null;
156
- }
157
- return async (envelope, ctx, next) => {
158
- // Find applicable limit
159
- const procedureLimit = findLimit(envelope.procedure);
160
- // If no limit configured, pass through
161
- if (!procedureLimit) {
162
- return next();
163
- }
164
- // Create a rate limiter for this specific configuration
165
- const middleware = createRateLimitMiddleware({
166
- ...baseOptions,
167
- limit: procedureLimit.limit,
168
- windowMs: procedureLimit.windowMs,
169
- store,
170
- keyExtractor: (e, c) => {
171
- const baseKey = (baseOptions.keyExtractor ?? defaultKeyExtractor)(e, c);
172
- return `${baseKey}:${e.procedure}`;
173
- },
174
- });
175
- return middleware(envelope, ctx, next);
176
- };
177
- }
178
- /**
179
- * Sliding window rate limiter for more precise rate limiting
180
- */
181
- export function createSlidingWindowRateLimiter(options) {
182
- const { limit, windowMs } = options;
183
- const windows = new Map();
184
- return {
185
- check(key) {
186
- const now = Date.now();
187
- const windowStart = now - windowMs;
188
- let timestamps = windows.get(key) || [];
189
- timestamps = timestamps.filter((ts) => ts > windowStart);
190
- const count = timestamps.length;
191
- const remaining = Math.max(0, limit - count);
192
- const oldestInWindow = timestamps[0] || now;
193
- const resetAt = oldestInWindow + windowMs;
194
- if (count < limit) {
195
- timestamps.push(now);
196
- windows.set(key, timestamps);
197
- return { allowed: true, remaining: remaining - 1, resetAt };
198
- }
199
- return { allowed: false, remaining: 0, resetAt };
200
- },
201
- reset(key) {
202
- windows.delete(key);
203
- },
204
- };
205
- }
206
- //# sourceMappingURL=rate-limit.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- /**
2
- * OpenAPI Module
3
- *
4
- * @deprecated Import from 'raffel/docs/openapi' instead
5
- *
6
- * This re-exports from the new location for backward compatibility.
7
- */
8
- export * from '../docs/openapi/index.js';
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/openapi/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,0BAA0B,CAAA"}
@@ -1,9 +0,0 @@
1
- /**
2
- * OpenAPI Module
3
- *
4
- * @deprecated Import from 'raffel/docs/openapi' instead
5
- *
6
- * This re-exports from the new location for backward compatibility.
7
- */
8
- export * from '../docs/openapi/index.js';
9
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/openapi/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,0BAA0B,CAAA"}