@konker.dev/neverthrow-r-middleware 0.0.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 (303) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +26 -0
  3. package/dist/handler.d.ts +3 -0
  4. package/dist/handler.d.ts.map +1 -0
  5. package/dist/handler.js +2 -0
  6. package/dist/handler.js.map +1 -0
  7. package/dist/http/HttpApiError.d.ts +16 -0
  8. package/dist/http/HttpApiError.d.ts.map +1 -0
  9. package/dist/http/HttpApiError.js +60 -0
  10. package/dist/http/HttpApiError.js.map +1 -0
  11. package/dist/http/HttpApiError.test.d.ts +2 -0
  12. package/dist/http/HttpApiError.test.d.ts.map +1 -0
  13. package/dist/http/HttpApiError.test.js +45 -0
  14. package/dist/http/HttpApiError.test.js.map +1 -0
  15. package/dist/http/Rec.d.ts +13 -0
  16. package/dist/http/Rec.d.ts.map +1 -0
  17. package/dist/http/Rec.js +2 -0
  18. package/dist/http/Rec.js.map +1 -0
  19. package/dist/http/RequestResponseHandler.d.ts +7 -0
  20. package/dist/http/RequestResponseHandler.d.ts.map +1 -0
  21. package/dist/http/RequestResponseHandler.js +2 -0
  22. package/dist/http/RequestResponseHandler.js.map +1 -0
  23. package/dist/http/RequestW.d.ts +14 -0
  24. package/dist/http/RequestW.d.ts.map +1 -0
  25. package/dist/http/RequestW.js +17 -0
  26. package/dist/http/RequestW.js.map +1 -0
  27. package/dist/http/RequestW.test.d.ts +2 -0
  28. package/dist/http/RequestW.test.d.ts.map +1 -0
  29. package/dist/http/RequestW.test.js +26 -0
  30. package/dist/http/RequestW.test.js.map +1 -0
  31. package/dist/http/ResponseW.d.ts +11 -0
  32. package/dist/http/ResponseW.d.ts.map +1 -0
  33. package/dist/http/ResponseW.js +14 -0
  34. package/dist/http/ResponseW.js.map +1 -0
  35. package/dist/http/ResponseW.test.d.ts +2 -0
  36. package/dist/http/ResponseW.test.d.ts.map +1 -0
  37. package/dist/http/ResponseW.test.js +23 -0
  38. package/dist/http/ResponseW.test.js.map +1 -0
  39. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.d.ts +14 -0
  40. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.d.ts.map +1 -0
  41. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.js +26 -0
  42. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.js.map +1 -0
  43. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.test.d.ts +2 -0
  44. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.test.d.ts.map +1 -0
  45. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.test.js +76 -0
  46. package/dist/http/contrib/apiGatewayProxyEventV2Adapter.test.js.map +1 -0
  47. package/dist/http/contrib/base64BodyDecoder.d.ts +7 -0
  48. package/dist/http/contrib/base64BodyDecoder.d.ts.map +1 -0
  49. package/dist/http/contrib/base64BodyDecoder.js +15 -0
  50. package/dist/http/contrib/base64BodyDecoder.js.map +1 -0
  51. package/dist/http/contrib/base64BodyDecoder.test.d.ts +2 -0
  52. package/dist/http/contrib/base64BodyDecoder.test.d.ts.map +1 -0
  53. package/dist/http/contrib/base64BodyDecoder.test.js +47 -0
  54. package/dist/http/contrib/base64BodyDecoder.test.js.map +1 -0
  55. package/dist/http/contrib/basicAuthAuthenticator.d.ts +17 -0
  56. package/dist/http/contrib/basicAuthAuthenticator.d.ts.map +1 -0
  57. package/dist/http/contrib/basicAuthAuthenticator.js +30 -0
  58. package/dist/http/contrib/basicAuthAuthenticator.js.map +1 -0
  59. package/dist/http/contrib/basicAuthAuthenticator.test.d.ts +2 -0
  60. package/dist/http/contrib/basicAuthAuthenticator.test.d.ts.map +1 -0
  61. package/dist/http/contrib/basicAuthAuthenticator.test.js +64 -0
  62. package/dist/http/contrib/basicAuthAuthenticator.test.js.map +1 -0
  63. package/dist/http/contrib/basicAuthDecoder.d.ts +13 -0
  64. package/dist/http/contrib/basicAuthDecoder.d.ts.map +1 -0
  65. package/dist/http/contrib/basicAuthDecoder.js +23 -0
  66. package/dist/http/contrib/basicAuthDecoder.js.map +1 -0
  67. package/dist/http/contrib/basicAuthDecoder.test.d.ts +2 -0
  68. package/dist/http/contrib/basicAuthDecoder.test.d.ts.map +1 -0
  69. package/dist/http/contrib/basicAuthDecoder.test.js +31 -0
  70. package/dist/http/contrib/basicAuthDecoder.test.js.map +1 -0
  71. package/dist/http/contrib/bodyValidator.d.ts +11 -0
  72. package/dist/http/contrib/bodyValidator.d.ts.map +1 -0
  73. package/dist/http/contrib/bodyValidator.js +15 -0
  74. package/dist/http/contrib/bodyValidator.js.map +1 -0
  75. package/dist/http/contrib/bodyValidator.test.d.ts +2 -0
  76. package/dist/http/contrib/bodyValidator.test.d.ts.map +1 -0
  77. package/dist/http/contrib/bodyValidator.test.js +58 -0
  78. package/dist/http/contrib/bodyValidator.test.js.map +1 -0
  79. package/dist/http/contrib/envValidator.d.ts +10 -0
  80. package/dist/http/contrib/envValidator.d.ts.map +1 -0
  81. package/dist/http/contrib/envValidator.js +12 -0
  82. package/dist/http/contrib/envValidator.js.map +1 -0
  83. package/dist/http/contrib/envValidator.test.d.ts +2 -0
  84. package/dist/http/contrib/envValidator.test.d.ts.map +1 -0
  85. package/dist/http/contrib/envValidator.test.js +49 -0
  86. package/dist/http/contrib/envValidator.test.js.map +1 -0
  87. package/dist/http/contrib/headerSignatureAuthorizer/index.d.ts +13 -0
  88. package/dist/http/contrib/headerSignatureAuthorizer/index.d.ts.map +1 -0
  89. package/dist/http/contrib/headerSignatureAuthorizer/index.js +22 -0
  90. package/dist/http/contrib/headerSignatureAuthorizer/index.js.map +1 -0
  91. package/dist/http/contrib/headerSignatureAuthorizer/index.test.d.ts +2 -0
  92. package/dist/http/contrib/headerSignatureAuthorizer/index.test.d.ts.map +1 -0
  93. package/dist/http/contrib/headerSignatureAuthorizer/index.test.js +39 -0
  94. package/dist/http/contrib/headerSignatureAuthorizer/index.test.js.map +1 -0
  95. package/dist/http/contrib/headerSignatureAuthorizer/lib.d.ts +4 -0
  96. package/dist/http/contrib/headerSignatureAuthorizer/lib.d.ts.map +1 -0
  97. package/dist/http/contrib/headerSignatureAuthorizer/lib.js +13 -0
  98. package/dist/http/contrib/headerSignatureAuthorizer/lib.js.map +1 -0
  99. package/dist/http/contrib/headerSignatureAuthorizer/lib.test.d.ts +2 -0
  100. package/dist/http/contrib/headerSignatureAuthorizer/lib.test.d.ts.map +1 -0
  101. package/dist/http/contrib/headerSignatureAuthorizer/lib.test.js +9 -0
  102. package/dist/http/contrib/headerSignatureAuthorizer/lib.test.js.map +1 -0
  103. package/dist/http/contrib/headersNormalizer/index.d.ts +9 -0
  104. package/dist/http/contrib/headersNormalizer/index.d.ts.map +1 -0
  105. package/dist/http/contrib/headersNormalizer/index.js +8 -0
  106. package/dist/http/contrib/headersNormalizer/index.js.map +1 -0
  107. package/dist/http/contrib/headersNormalizer/index.test.d.ts +2 -0
  108. package/dist/http/contrib/headersNormalizer/index.test.d.ts.map +1 -0
  109. package/dist/http/contrib/headersNormalizer/index.test.js +38 -0
  110. package/dist/http/contrib/headersNormalizer/index.test.js.map +1 -0
  111. package/dist/http/contrib/headersNormalizer/lib.d.ts +11 -0
  112. package/dist/http/contrib/headersNormalizer/lib.d.ts.map +1 -0
  113. package/dist/http/contrib/headersNormalizer/lib.js +64 -0
  114. package/dist/http/contrib/headersNormalizer/lib.js.map +1 -0
  115. package/dist/http/contrib/headersNormalizer/lib.test.d.ts +2 -0
  116. package/dist/http/contrib/headersNormalizer/lib.test.d.ts.map +1 -0
  117. package/dist/http/contrib/headersNormalizer/lib.test.js +35 -0
  118. package/dist/http/contrib/headersNormalizer/lib.test.js.map +1 -0
  119. package/dist/http/contrib/headersNormalizer/types.d.ts +10 -0
  120. package/dist/http/contrib/headersNormalizer/types.d.ts.map +1 -0
  121. package/dist/http/contrib/headersNormalizer/types.js +2 -0
  122. package/dist/http/contrib/headersNormalizer/types.js.map +1 -0
  123. package/dist/http/contrib/headersValidator.d.ts +12 -0
  124. package/dist/http/contrib/headersValidator.d.ts.map +1 -0
  125. package/dist/http/contrib/headersValidator.js +15 -0
  126. package/dist/http/contrib/headersValidator.js.map +1 -0
  127. package/dist/http/contrib/headersValidator.test.d.ts +2 -0
  128. package/dist/http/contrib/headersValidator.test.d.ts.map +1 -0
  129. package/dist/http/contrib/headersValidator.test.js +46 -0
  130. package/dist/http/contrib/headersValidator.test.js.map +1 -0
  131. package/dist/http/contrib/helmetJsHeaders.d.ts +5 -0
  132. package/dist/http/contrib/helmetJsHeaders.d.ts.map +1 -0
  133. package/dist/http/contrib/helmetJsHeaders.js +25 -0
  134. package/dist/http/contrib/helmetJsHeaders.js.map +1 -0
  135. package/dist/http/contrib/helmetJsHeaders.test.d.ts +2 -0
  136. package/dist/http/contrib/helmetJsHeaders.test.d.ts.map +1 -0
  137. package/dist/http/contrib/helmetJsHeaders.test.js +18 -0
  138. package/dist/http/contrib/helmetJsHeaders.test.js.map +1 -0
  139. package/dist/http/contrib/honoAdapter.d.ts +16 -0
  140. package/dist/http/contrib/honoAdapter.d.ts.map +1 -0
  141. package/dist/http/contrib/honoAdapter.js +28 -0
  142. package/dist/http/contrib/honoAdapter.js.map +1 -0
  143. package/dist/http/contrib/honoAdapter.test.d.ts +2 -0
  144. package/dist/http/contrib/honoAdapter.test.d.ts.map +1 -0
  145. package/dist/http/contrib/honoAdapter.test.js +75 -0
  146. package/dist/http/contrib/honoAdapter.test.js.map +1 -0
  147. package/dist/http/contrib/identity.d.ts +4 -0
  148. package/dist/http/contrib/identity.d.ts.map +1 -0
  149. package/dist/http/contrib/identity.js +3 -0
  150. package/dist/http/contrib/identity.js.map +1 -0
  151. package/dist/http/contrib/identity.test.d.ts +2 -0
  152. package/dist/http/contrib/identity.test.d.ts.map +1 -0
  153. package/dist/http/contrib/identity.test.js +12 -0
  154. package/dist/http/contrib/identity.test.js.map +1 -0
  155. package/dist/http/contrib/index.d.ts +25 -0
  156. package/dist/http/contrib/index.d.ts.map +1 -0
  157. package/dist/http/contrib/index.js +25 -0
  158. package/dist/http/contrib/index.js.map +1 -0
  159. package/dist/http/contrib/jsonBodyParserRequest.d.ts +10 -0
  160. package/dist/http/contrib/jsonBodyParserRequest.d.ts.map +1 -0
  161. package/dist/http/contrib/jsonBodyParserRequest.js +22 -0
  162. package/dist/http/contrib/jsonBodyParserRequest.js.map +1 -0
  163. package/dist/http/contrib/jsonBodyParserRequest.test.d.ts +2 -0
  164. package/dist/http/contrib/jsonBodyParserRequest.test.d.ts.map +1 -0
  165. package/dist/http/contrib/jsonBodyParserRequest.test.js +37 -0
  166. package/dist/http/contrib/jsonBodyParserRequest.test.js.map +1 -0
  167. package/dist/http/contrib/jsonBodySerializerResponse.d.ts +9 -0
  168. package/dist/http/contrib/jsonBodySerializerResponse.d.ts.map +1 -0
  169. package/dist/http/contrib/jsonBodySerializerResponse.js +15 -0
  170. package/dist/http/contrib/jsonBodySerializerResponse.js.map +1 -0
  171. package/dist/http/contrib/jsonBodySerializerResponse.test.d.ts +2 -0
  172. package/dist/http/contrib/jsonBodySerializerResponse.test.d.ts.map +1 -0
  173. package/dist/http/contrib/jsonBodySerializerResponse.test.js +31 -0
  174. package/dist/http/contrib/jsonBodySerializerResponse.test.js.map +1 -0
  175. package/dist/http/contrib/jwtAuthenticator.d.ts +15 -0
  176. package/dist/http/contrib/jwtAuthenticator.d.ts.map +1 -0
  177. package/dist/http/contrib/jwtAuthenticator.js +28 -0
  178. package/dist/http/contrib/jwtAuthenticator.js.map +1 -0
  179. package/dist/http/contrib/jwtAuthenticator.test.d.ts +2 -0
  180. package/dist/http/contrib/jwtAuthenticator.test.d.ts.map +1 -0
  181. package/dist/http/contrib/jwtAuthenticator.test.js +88 -0
  182. package/dist/http/contrib/jwtAuthenticator.test.js.map +1 -0
  183. package/dist/http/contrib/jwtAuthenticatorRsa.d.ts +15 -0
  184. package/dist/http/contrib/jwtAuthenticatorRsa.d.ts.map +1 -0
  185. package/dist/http/contrib/jwtAuthenticatorRsa.js +28 -0
  186. package/dist/http/contrib/jwtAuthenticatorRsa.js.map +1 -0
  187. package/dist/http/contrib/jwtAuthenticatorRsa.test.d.ts +2 -0
  188. package/dist/http/contrib/jwtAuthenticatorRsa.test.d.ts.map +1 -0
  189. package/dist/http/contrib/jwtAuthenticatorRsa.test.js +88 -0
  190. package/dist/http/contrib/jwtAuthenticatorRsa.test.js.map +1 -0
  191. package/dist/http/contrib/jwtDecoder.d.ts +13 -0
  192. package/dist/http/contrib/jwtDecoder.d.ts.map +1 -0
  193. package/dist/http/contrib/jwtDecoder.js +23 -0
  194. package/dist/http/contrib/jwtDecoder.js.map +1 -0
  195. package/dist/http/contrib/jwtDecoder.test.d.ts +2 -0
  196. package/dist/http/contrib/jwtDecoder.test.d.ts.map +1 -0
  197. package/dist/http/contrib/jwtDecoder.test.js +76 -0
  198. package/dist/http/contrib/jwtDecoder.test.js.map +1 -0
  199. package/dist/http/contrib/pathParametersValidator.d.ts +12 -0
  200. package/dist/http/contrib/pathParametersValidator.d.ts.map +1 -0
  201. package/dist/http/contrib/pathParametersValidator.js +15 -0
  202. package/dist/http/contrib/pathParametersValidator.js.map +1 -0
  203. package/dist/http/contrib/pathParametersValidator.test.d.ts +2 -0
  204. package/dist/http/contrib/pathParametersValidator.test.d.ts.map +1 -0
  205. package/dist/http/contrib/pathParametersValidator.test.js +46 -0
  206. package/dist/http/contrib/pathParametersValidator.test.js.map +1 -0
  207. package/dist/http/contrib/pathTokenAuthorizer.d.ts +13 -0
  208. package/dist/http/contrib/pathTokenAuthorizer.d.ts.map +1 -0
  209. package/dist/http/contrib/pathTokenAuthorizer.js +19 -0
  210. package/dist/http/contrib/pathTokenAuthorizer.js.map +1 -0
  211. package/dist/http/contrib/pathTokenAuthorizer.test.d.ts +2 -0
  212. package/dist/http/contrib/pathTokenAuthorizer.test.d.ts.map +1 -0
  213. package/dist/http/contrib/pathTokenAuthorizer.test.js +29 -0
  214. package/dist/http/contrib/pathTokenAuthorizer.test.js.map +1 -0
  215. package/dist/http/contrib/queryStringValidator.d.ts +12 -0
  216. package/dist/http/contrib/queryStringValidator.d.ts.map +1 -0
  217. package/dist/http/contrib/queryStringValidator.js +15 -0
  218. package/dist/http/contrib/queryStringValidator.js.map +1 -0
  219. package/dist/http/contrib/queryStringValidator.test.d.ts +2 -0
  220. package/dist/http/contrib/queryStringValidator.test.d.ts.map +1 -0
  221. package/dist/http/contrib/queryStringValidator.test.js +46 -0
  222. package/dist/http/contrib/queryStringValidator.test.js.map +1 -0
  223. package/dist/http/contrib/requestResponseLogger.d.ts +5 -0
  224. package/dist/http/contrib/requestResponseLogger.d.ts.map +1 -0
  225. package/dist/http/contrib/requestResponseLogger.js +8 -0
  226. package/dist/http/contrib/requestResponseLogger.js.map +1 -0
  227. package/dist/http/contrib/requestResponseLogger.test.d.ts +2 -0
  228. package/dist/http/contrib/requestResponseLogger.test.d.ts.map +1 -0
  229. package/dist/http/contrib/requestResponseLogger.test.js +18 -0
  230. package/dist/http/contrib/requestResponseLogger.test.js.map +1 -0
  231. package/dist/http/contrib/responseProcessor.d.ts +8 -0
  232. package/dist/http/contrib/responseProcessor.d.ts.map +1 -0
  233. package/dist/http/contrib/responseProcessor.js +16 -0
  234. package/dist/http/contrib/responseProcessor.js.map +1 -0
  235. package/dist/http/contrib/responseProcessor.test.d.ts +2 -0
  236. package/dist/http/contrib/responseProcessor.test.d.ts.map +1 -0
  237. package/dist/http/contrib/responseProcessor.test.js +29 -0
  238. package/dist/http/contrib/responseProcessor.test.js.map +1 -0
  239. package/dist/http/contrib/standardRequestResponseAdapter.d.ts +16 -0
  240. package/dist/http/contrib/standardRequestResponseAdapter.d.ts.map +1 -0
  241. package/dist/http/contrib/standardRequestResponseAdapter.js +27 -0
  242. package/dist/http/contrib/standardRequestResponseAdapter.js.map +1 -0
  243. package/dist/http/contrib/standardRequestResponseAdapter.test.d.ts +2 -0
  244. package/dist/http/contrib/standardRequestResponseAdapter.test.d.ts.map +1 -0
  245. package/dist/http/contrib/standardRequestResponseAdapter.test.js +85 -0
  246. package/dist/http/contrib/standardRequestResponseAdapter.test.js.map +1 -0
  247. package/dist/http/contrib/trivial.d.ts +5 -0
  248. package/dist/http/contrib/trivial.d.ts.map +1 -0
  249. package/dist/http/contrib/trivial.js +9 -0
  250. package/dist/http/contrib/trivial.js.map +1 -0
  251. package/dist/http/contrib/trivial.test.d.ts +2 -0
  252. package/dist/http/contrib/trivial.test.d.ts.map +1 -0
  253. package/dist/http/contrib/trivial.test.js +14 -0
  254. package/dist/http/contrib/trivial.test.js.map +1 -0
  255. package/dist/http/index.d.ts +6 -0
  256. package/dist/http/index.d.ts.map +1 -0
  257. package/dist/http/index.js +6 -0
  258. package/dist/http/index.js.map +1 -0
  259. package/dist/index.d.ts +3 -0
  260. package/dist/index.d.ts.map +1 -0
  261. package/dist/index.js +3 -0
  262. package/dist/index.js.map +1 -0
  263. package/dist/lib/Logger.d.ts +23 -0
  264. package/dist/lib/Logger.d.ts.map +1 -0
  265. package/dist/lib/Logger.js +30 -0
  266. package/dist/lib/Logger.js.map +1 -0
  267. package/dist/lib/Logger.test.d.ts +2 -0
  268. package/dist/lib/Logger.test.d.ts.map +1 -0
  269. package/dist/lib/Logger.test.js +54 -0
  270. package/dist/lib/Logger.test.js.map +1 -0
  271. package/dist/lib/MiddlewareError.d.ts +10 -0
  272. package/dist/lib/MiddlewareError.d.ts.map +1 -0
  273. package/dist/lib/MiddlewareError.js +20 -0
  274. package/dist/lib/MiddlewareError.js.map +1 -0
  275. package/dist/lib/MiddlewareError.test.d.ts +2 -0
  276. package/dist/lib/MiddlewareError.test.d.ts.map +1 -0
  277. package/dist/lib/MiddlewareError.test.js +55 -0
  278. package/dist/lib/MiddlewareError.test.js.map +1 -0
  279. package/dist/lib/index.d.ts +4 -0
  280. package/dist/lib/index.d.ts.map +1 -0
  281. package/dist/lib/index.js +4 -0
  282. package/dist/lib/index.js.map +1 -0
  283. package/dist/lib/utils.d.ts +7 -0
  284. package/dist/lib/utils.d.ts.map +1 -0
  285. package/dist/lib/utils.js +11 -0
  286. package/dist/lib/utils.js.map +1 -0
  287. package/dist/lib/utils.test.d.ts +2 -0
  288. package/dist/lib/utils.test.d.ts.map +1 -0
  289. package/dist/lib/utils.test.js +47 -0
  290. package/dist/lib/utils.test.js.map +1 -0
  291. package/dist/test/kitchen-sink.test.d.ts +2 -0
  292. package/dist/test/kitchen-sink.test.d.ts.map +1 -0
  293. package/dist/test/kitchen-sink.test.js +76 -0
  294. package/dist/test/kitchen-sink.test.js.map +1 -0
  295. package/dist/test/round-trip.test.d.ts +2 -0
  296. package/dist/test/round-trip.test.d.ts.map +1 -0
  297. package/dist/test/round-trip.test.js +75 -0
  298. package/dist/test/round-trip.test.js.map +1 -0
  299. package/dist/test/test-common.d.ts +17 -0
  300. package/dist/test/test-common.d.ts.map +1 -0
  301. package/dist/test/test-common.js +25 -0
  302. package/dist/test/test-common.js.map +1 -0
  303. package/package.json +265 -0
@@ -0,0 +1,47 @@
1
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import { recordingLogger, sampleRequestW } from '../../test/test-common.js';
4
+ import { makeRequestW } from '../RequestW.js';
5
+ import { EMPTY_RESPONSE_W } from '../ResponseW.js';
6
+ import { middleware as base64BodyDecoder } from './base64BodyDecoder.js';
7
+ describe('base64BodyDecoder', () => {
8
+ it('decodes base64 when the predicate matches', async () => {
9
+ const { logger } = recordingLogger();
10
+ const wrapped = base64BodyDecoder(() => true)((req) => okAsyncR({
11
+ ...EMPTY_RESPONSE_W,
12
+ body: req.body,
13
+ }));
14
+ const input = makeRequestW(sampleRequestW, { body: Buffer.from('{"foo":"bar"}').toString('base64') });
15
+ const result = await wrapped(input)({ logger });
16
+ expect(result.isOk() && result.value.body).toBe('{"foo":"bar"}');
17
+ });
18
+ it('returns a MiddlewareError when decoding throws', async () => {
19
+ const spy = vi.spyOn(Buffer, 'from').mockImplementation(() => {
20
+ throw new Error('boom');
21
+ });
22
+ const { logger } = recordingLogger();
23
+ const wrapped = base64BodyDecoder(() => true)(() => okAsyncR(EMPTY_RESPONSE_W));
24
+ const result = await wrapped(makeRequestW(sampleRequestW, { body: 'abcd' }))({ logger });
25
+ expect(result.isErr() && result.error.message).toBe('boom');
26
+ spy.mockRestore();
27
+ });
28
+ it('passes the request through unchanged when not base64 encoded', async () => {
29
+ const { logger } = recordingLogger();
30
+ const wrapped = base64BodyDecoder(() => false)((req) => okAsyncR({
31
+ ...EMPTY_RESPONSE_W,
32
+ body: req.body,
33
+ }));
34
+ const result = await wrapped(makeRequestW(sampleRequestW, { body: 'plain-text' }))({ logger });
35
+ expect(result.isOk() && result.value.body).toBe('plain-text');
36
+ });
37
+ it('decodes an undefined body as an empty string when flagged as base64', async () => {
38
+ const { logger } = recordingLogger();
39
+ const wrapped = base64BodyDecoder(() => true)((req) => okAsyncR({
40
+ ...EMPTY_RESPONSE_W,
41
+ body: req.body,
42
+ }));
43
+ const result = await wrapped(sampleRequestW)({ logger });
44
+ expect(result.isOk() && result.value.body).toBe('');
45
+ });
46
+ });
47
+ //# sourceMappingURL=base64BodyDecoder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64BodyDecoder.test.js","sourceRoot":"","sources":["../../../src/http/contrib/base64BodyDecoder.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ValidBasicAuthCredentialSet } from '@konker.dev/neverthrow-r-auth-utils/basic-auth';
2
+ import type { Handler } from '../../handler.js';
3
+ import type { WithLogger } from '../../lib/Logger.js';
4
+ import type { HttpApiError } from '../HttpApiError.js';
5
+ import type { Rec } from '../Rec.js';
6
+ import { type RequestW } from '../RequestW.js';
7
+ import type { ResponseW } from '../ResponseW.js';
8
+ import type { WithNormalizedInputHeaders } from './headersNormalizer/types.js';
9
+ export declare const TAG = "basicAuthAuthenticator";
10
+ export type BasicAuthAuthenticatorDeps = {
11
+ readonly validBasicAuthCredentialSet: ValidBasicAuthCredentialSet;
12
+ };
13
+ export type WithUserId = {
14
+ readonly userId: string | undefined;
15
+ };
16
+ export declare const middleware: () => <I extends Rec, O extends Rec, E, R>(wrapped: Handler<RequestW<I & WithNormalizedInputHeaders & WithUserId>, R, ResponseW<O>, E>) => Handler<RequestW<I & WithNormalizedInputHeaders>, R & WithLogger & BasicAuthAuthenticatorDeps, ResponseW<O>, E | HttpApiError>;
17
+ //# sourceMappingURL=basicAuthAuthenticator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthAuthenticator.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthAuthenticator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAKlG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE/E,eAAO,MAAM,GAAG,2BAA2B,CAAC;AAE5C,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,2BAA2B,EAAE,2BAA2B,CAAC;CACnE,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,UAAU,SAEpB,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,0BAA0B,GAAG,UAAU,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAC1F,OAAO,CACR,QAAQ,CAAC,CAAC,GAAG,0BAA0B,CAAC,EACxC,CAAC,GAAG,UAAU,GAAG,0BAA0B,EAC3C,SAAS,CAAC,CAAC,CAAC,EACZ,CAAC,GAAG,YAAY,CAmCjB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { basicAuthDecodeHeaderValue, basicAuthVerifyCredentials } from '@konker.dev/neverthrow-r-auth-utils/basic-auth';
2
+ import { extractBasicAuthHeaderValue } from '@konker.dev/neverthrow-r-auth-utils/helpers';
3
+ import { errAsync } from 'neverthrow';
4
+ import { toHttpApiError } from '../HttpApiError.js';
5
+ import {} from '../RequestW.js';
6
+ export const TAG = 'basicAuthAuthenticator';
7
+ export const middleware = () => (wrapped) => (i) => (r) => {
8
+ r.logger.debug(`[${TAG}] IN`);
9
+ const authResult = extractBasicAuthHeaderValue(i.headers.authorization)(undefined)
10
+ .andThen((headerValue) => basicAuthDecodeHeaderValue(headerValue)(undefined))
11
+ .andThen((decoded) => basicAuthVerifyCredentials(r.validBasicAuthCredentialSet)(decoded)(undefined));
12
+ if (authResult.isErr()) {
13
+ const error = toHttpApiError(authResult.error, 401, `Invalid basic auth credentials: ${authResult.error instanceof Error ? authResult.error.message : String(authResult.error)}`);
14
+ r.logger.error(error);
15
+ return errAsync(error);
16
+ }
17
+ if (!authResult.value.verified) {
18
+ const error = toHttpApiError(undefined, 401, 'Invalid basic auth credentials');
19
+ r.logger.error(error);
20
+ return errAsync(error);
21
+ }
22
+ return wrapped({
23
+ ...i,
24
+ userId: authResult.value.userId,
25
+ })(r).map((res) => {
26
+ r.logger.debug(`[${TAG}] OUT`);
27
+ return res;
28
+ });
29
+ };
30
+ //# sourceMappingURL=basicAuthAuthenticator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthAuthenticator.js","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthAuthenticator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AACxH,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAiB,MAAM,gBAAgB,CAAC;AAI/C,MAAM,CAAC,MAAM,GAAG,GAAG,wBAAwB,CAAC;AAU5C,MAAM,CAAC,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAA2F,EAM3F,EAAE,CACJ,CAAC,CAAC,EAAE,EAAE,CACN,CAAC,CAAC,EAAE,EAAE;IACJ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IAE9B,MAAM,UAAU,GAAG,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC;SAC/E,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;SAC5E,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,0BAA0B,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAEvG,IAAI,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,cAAc,CAC1B,UAAU,CAAC,KAAK,EAChB,GAAG,EACH,mCACE,UAAU,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CACxF,EAAE,CACH,CAAC;QACF,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,QAAQ,CAAiC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,gCAAgC,CAAC,CAAC;QAC/E,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,QAAQ,CAAiC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,OAAO,CAAC;QACb,GAAG,CAAC;QACJ,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,MAAM;KACyB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACzE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=basicAuthAuthenticator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthAuthenticator.test.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthAuthenticator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,64 @@
1
+ import { errR, okAsyncR } from '@konker.dev/neverthrow-r/constructors';
2
+ import * as helpers from '@konker.dev/neverthrow-r-auth-utils/helpers';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+ import { recordingLogger, sampleRequestW } from '../../test/test-common.js';
5
+ import { makeRequestW } from '../RequestW.js';
6
+ import { EMPTY_RESPONSE_W } from '../ResponseW.js';
7
+ import { middleware as basicAuthAuthenticator } from './basicAuthAuthenticator.js';
8
+ describe('basicAuthAuthenticator', () => {
9
+ const validAuthorization = 'Basic dXNlcjA6c2VjcmV0LTA=';
10
+ const invalidAuthorization = 'Basic dXNlcjA6YmFkLXNlY3JldA==';
11
+ it('authenticates valid credentials', async () => {
12
+ const { logger } = recordingLogger();
13
+ const wrapped = basicAuthAuthenticator()((req) => okAsyncR({
14
+ ...EMPTY_RESPONSE_W,
15
+ body: req.userId,
16
+ }));
17
+ const input = makeRequestW(sampleRequestW, {
18
+ headers: { authorization: validAuthorization },
19
+ headersNormalizerRequestRaw: { Authorization: validAuthorization },
20
+ });
21
+ const result = await wrapped(input)({
22
+ logger,
23
+ validBasicAuthCredentialSet: [{ username: 'user0', passwords: ['secret-0'] }],
24
+ });
25
+ expect(result.isOk() && result.value.body).toBe('user0');
26
+ });
27
+ it('returns a 401 HttpApiError for invalid credentials', async () => {
28
+ const { logger } = recordingLogger();
29
+ const wrapped = basicAuthAuthenticator()(() => okAsyncR(EMPTY_RESPONSE_W));
30
+ const input = makeRequestW(sampleRequestW, {
31
+ headers: { authorization: invalidAuthorization },
32
+ headersNormalizerRequestRaw: { Authorization: invalidAuthorization },
33
+ });
34
+ const result = await wrapped(input)({
35
+ logger,
36
+ validBasicAuthCredentialSet: [{ username: 'user0', passwords: ['secret-0'] }],
37
+ });
38
+ expect(result.isErr() && result.error.statusCode).toBe(401);
39
+ });
40
+ it('returns a 401 HttpApiError when the auth header is missing', async () => {
41
+ const { logger } = recordingLogger();
42
+ const wrapped = basicAuthAuthenticator()(() => okAsyncR(EMPTY_RESPONSE_W));
43
+ const input = makeRequestW(sampleRequestW, {
44
+ headers: {},
45
+ headersNormalizerRequestRaw: {},
46
+ });
47
+ const result = await wrapped(input)({
48
+ logger,
49
+ validBasicAuthCredentialSet: [{ username: 'user0', passwords: ['secret-0'] }],
50
+ });
51
+ expect(result.isErr() && result.error.statusCode).toBe(401);
52
+ });
53
+ it('stringifies non-Error auth extraction failures', async () => {
54
+ vi.spyOn(helpers, 'extractBasicAuthHeaderValue').mockReturnValue(errR('boom'));
55
+ const { logger } = recordingLogger();
56
+ const wrapped = basicAuthAuthenticator()(() => okAsyncR(EMPTY_RESPONSE_W));
57
+ const result = await wrapped(makeRequestW(sampleRequestW, { headers: {}, headersNormalizerRequestRaw: {} }))({
58
+ logger,
59
+ validBasicAuthCredentialSet: [{ username: 'user0', passwords: ['secret-0'] }],
60
+ });
61
+ expect(result.isErr() && result.error.message).toContain('boom');
62
+ });
63
+ });
64
+ //# sourceMappingURL=basicAuthAuthenticator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthAuthenticator.test.js","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthAuthenticator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,OAAO,MAAM,6CAA6C,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,UAAU,IAAI,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAEnF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;IACxD,MAAM,oBAAoB,GAAG,gCAAgC,CAAC;IAE9D,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAC/C,QAAQ,CAAY;YAClB,GAAG,gBAAgB;YACnB,IAAI,EAAE,GAAG,CAAC,MAAM;SACJ,CAAC,CAChB,CAAC;QACF,MAAM,KAAK,GAAG,YAAY,CAAC,cAAc,EAAE;YACzC,OAAO,EAAE,EAAE,aAAa,EAAE,kBAAkB,EAAE;YAC9C,2BAA2B,EAAE,EAAE,aAAa,EAAE,kBAAkB,EAAE;SACnE,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM;YACN,2BAA2B,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAY,gBAAgB,CAAC,CAAC,CAAC;QACtF,MAAM,KAAK,GAAG,YAAY,CAAC,cAAc,EAAE;YACzC,OAAO,EAAE,EAAE,aAAa,EAAE,oBAAoB,EAAE;YAChD,2BAA2B,EAAE,EAAE,aAAa,EAAE,oBAAoB,EAAE;SACrE,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM;YACN,2BAA2B,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAY,gBAAgB,CAAC,CAAC,CAAC;QACtF,MAAM,KAAK,GAAG,YAAY,CAAC,cAAc,EAAE;YACzC,OAAO,EAAE,EAAE;YACX,2BAA2B,EAAE,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM;YACN,2BAA2B,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC,eAAe,CAAC,IAAI,CAAM,MAAM,CAAC,CAAC,CAAC;QACpF,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAY,gBAAgB,CAAC,CAAC,CAAC;QACtF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,2BAA2B,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAC3G,MAAM;YACN,2BAA2B,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Handler } from '../../handler.js';
2
+ import type { WithLogger } from '../../lib/Logger.js';
3
+ import type { MiddlewareError } from '../../lib/MiddlewareError.js';
4
+ import type { Override, Rec } from '../RequestResponseHandler.js';
5
+ import { type RequestW } from '../RequestW.js';
6
+ import type { ResponseW } from '../ResponseW.js';
7
+ import type { WithNormalizedInputHeaders } from './headersNormalizer/types.js';
8
+ export declare const TAG = "basicAuthDecoder";
9
+ export type WithUserId = {
10
+ readonly userId: string | undefined;
11
+ };
12
+ export declare const middleware: () => <I extends Rec, O extends Rec, E, R>(wrapped: Handler<RequestW<Override<I & WithNormalizedInputHeaders, WithUserId>>, R, ResponseW<O>, E>) => Handler<RequestW<I & WithNormalizedInputHeaders>, R & WithLogger, ResponseW<O>, E | MiddlewareError>;
13
+ //# sourceMappingURL=basicAuthDecoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthDecoder.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthDecoder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE/E,eAAO,MAAM,GAAG,qBAAqB,CAAC;AAEtC,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,UAAU,SAEpB,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,0BAA0B,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KACnG,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,0BAA0B,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,eAAe,CAsBrG,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { basicAuthDecodeHeaderValue } from '@konker.dev/neverthrow-r-auth-utils/basic-auth';
2
+ import { extractBasicAuthHeaderValue } from '@konker.dev/neverthrow-r-auth-utils/helpers';
3
+ import { errAsync } from 'neverthrow';
4
+ import { toMiddlewareError } from '../../lib/MiddlewareError.js';
5
+ import { makeRequestW } from '../RequestW.js';
6
+ export const TAG = 'basicAuthDecoder';
7
+ export const middleware = () => (wrapped) => (i) => (r) => {
8
+ r.logger.debug(`[${TAG}] IN`);
9
+ const decoded = extractBasicAuthHeaderValue(i.headers.authorization)(undefined)
10
+ .andThen((headerValue) => basicAuthDecodeHeaderValue(headerValue)(undefined))
11
+ .mapErr(toMiddlewareError);
12
+ if (decoded.isErr()) {
13
+ r.logger.error(decoded.error);
14
+ return errAsync(decoded.error);
15
+ }
16
+ return wrapped(makeRequestW(i, {
17
+ userId: decoded.value.username,
18
+ }))(r).map((res) => {
19
+ r.logger.debug(`[${TAG}] OUT`);
20
+ return res;
21
+ });
22
+ };
23
+ //# sourceMappingURL=basicAuthDecoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthDecoder.js","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthDecoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAiB,MAAM,gBAAgB,CAAC;AAI7D,MAAM,CAAC,MAAM,GAAG,GAAG,kBAAkB,CAAC;AAMtC,MAAM,CAAC,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAoG,EACE,EAAE,CAC1G,CAAC,CAAC,EAAE,EAAE,CACN,CAAC,CAAC,EAAE,EAAE;IACJ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IAE9B,MAAM,OAAO,GAAG,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC;SAC5E,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;SAC5E,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAE7B,IAAI,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACpB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,OAAO,CACZ,YAAY,CAAC,CAAC,EAAE;QACd,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ;KAC/B,CAAC,CACH,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=basicAuthDecoder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthDecoder.test.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthDecoder.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { recordingLogger, sampleRequestW } from '../../test/test-common.js';
4
+ import { makeRequestW } from '../RequestW.js';
5
+ import { EMPTY_RESPONSE_W } from '../ResponseW.js';
6
+ import { middleware as basicAuthDecoder } from './basicAuthDecoder.js';
7
+ describe('basicAuthDecoder', () => {
8
+ const authorization = 'Basic dXNlcjA6c2VjcmV0LTA=';
9
+ it('extracts the userId from a valid basic auth header', async () => {
10
+ const { logger } = recordingLogger();
11
+ const wrapped = basicAuthDecoder()((req) => okAsyncR({
12
+ ...EMPTY_RESPONSE_W,
13
+ body: req.userId,
14
+ }));
15
+ const input = makeRequestW(sampleRequestW, {
16
+ headers: { authorization },
17
+ headersNormalizerRequestRaw: { Authorization: authorization },
18
+ });
19
+ const result = await wrapped(input)({ logger });
20
+ expect(result.isOk() && result.value.body).toBe('user0');
21
+ });
22
+ it('returns a MiddlewareError when the header is missing', async () => {
23
+ const { logger } = recordingLogger();
24
+ const wrapped = basicAuthDecoder()(() => okAsyncR(EMPTY_RESPONSE_W));
25
+ const result = await wrapped(makeRequestW(sampleRequestW, {
26
+ headersNormalizerRequestRaw: {},
27
+ }))({ logger });
28
+ expect(result.isErr() && result.error.message).toBe('No token found');
29
+ });
30
+ });
31
+ //# sourceMappingURL=basicAuthDecoder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basicAuthDecoder.test.js","sourceRoot":"","sources":["../../../src/http/contrib/basicAuthDecoder.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEvE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,MAAM,aAAa,GAAG,4BAA4B,CAAC;IAEnD,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CACzC,QAAQ,CAAY;YAClB,GAAG,gBAAgB;YACnB,IAAI,EAAE,GAAG,CAAC,MAAM;SACJ,CAAC,CAChB,CAAC;QACF,MAAM,KAAK,GAAG,YAAY,CAAC,cAAc,EAAE;YACzC,OAAO,EAAE,EAAE,aAAa,EAAE;YAC1B,2BAA2B,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE;SAC9D,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAEhD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAY,gBAAgB,CAAC,CAAC,CAAC;QAChF,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,YAAY,CAAC,cAAc,EAAE;YAC3B,2BAA2B,EAAE,EAAE;SAChC,CAAC,CACH,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAEd,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import type { WithLogger } from '../../lib/Logger.js';
3
+ import type { MiddlewareError } from '../../lib/MiddlewareError.js';
4
+ import type { Override, Rec, RequestResponseHandler } from '../RequestResponseHandler.js';
5
+ export declare const TAG = "bodyValidator";
6
+ export type WithValidatedBody<V> = {
7
+ readonly body: V;
8
+ readonly bodyValidatorRaw: unknown;
9
+ };
10
+ export declare const middleware: <V>(schema: StandardSchemaV1<unknown, V>) => <I extends Rec, O extends Rec, E, R>(wrapped: RequestResponseHandler<Override<I, WithValidatedBody<V>>, R, O, E>) => RequestResponseHandler<I, R & WithLogger, O, E | MiddlewareError>;
11
+ //# sourceMappingURL=bodyValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bodyValidator.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/bodyValidator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAI1F,eAAO,MAAM,GAAG,kBAAkB,CAAC;AAEnC,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC,CAAC;AAKF,eAAO,MAAM,UAAU,GACpB,CAAC,EAAE,QAAQ,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,MACvC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,sBAAsB,CAAC,QAAQ,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC1E,sBAAsB,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,eAAe,CAgBhE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { andThenAsync, mapAsync, mapErrAsync } from '@konker.dev/neverthrow-r/async';
2
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
3
+ import { pipe } from '@konker.dev/neverthrow-r/pipe';
4
+ import { andThenParseAsyncR } from '@konker.dev/neverthrow-r-schema/async';
5
+ import { tapLogger } from '../../lib/Logger.js';
6
+ import { middlewareError } from '../../lib/MiddlewareError.js';
7
+ import { makeRequestW } from '../RequestW.js';
8
+ import { makeResponseW } from '../ResponseW.js';
9
+ export const TAG = 'bodyValidator';
10
+ const toMiddlewareError = (error) => middlewareError(error.message, error.cause === undefined ? error.issues : [error.cause, ...error.issues]);
11
+ export const middleware = (schema) => (wrapped) => (i) => pipe(okAsyncR(i.body), tapLogger('debug', `[${TAG}] IN`), andThenParseAsyncR(schema, { message: 'Body validation failed' }), mapErrAsync(toMiddlewareError), mapAsync((validatedBody) => makeRequestW(i, {
12
+ body: validatedBody,
13
+ bodyValidatorRaw: i.body,
14
+ })), andThenAsync(wrapped), mapAsync((res) => makeResponseW(res)), tapLogger('debug', `[${TAG}] OUT`));
15
+ //# sourceMappingURL=bodyValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bodyValidator.js","sourceRoot":"","sources":["../../../src/http/contrib/bodyValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAK3E,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAiB,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,CAAC,MAAM,GAAG,GAAG,eAAe,CAAC;AAOnC,MAAM,iBAAiB,GAAG,CAAC,KAA4B,EAAmB,EAAE,CAC1E,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAE5G,MAAM,CAAC,MAAM,UAAU,GACrB,CAAI,MAAoC,EAAE,EAAE,CAC5C,CACE,OAA2E,EACR,EAAE,CACvE,CAAC,CAAc,EAAE,EAAE,CACjB,IAAI,CACF,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAChB,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,CAAC,EACjC,kBAAkB,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,EACjE,WAAW,CAAC,iBAAiB,CAAC,EAC9B,QAAQ,CAAC,CAAC,aAAa,EAAE,EAAE,CACzB,YAAY,CAAC,CAAC,EAAE;IACd,IAAI,EAAE,aAAa;IACnB,gBAAgB,EAAE,CAAC,CAAC,IAAI;CACzB,CAAC,CACH,EACD,YAAY,CAAC,OAAO,CAAC,EACrB,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EACrC,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,CACnC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bodyValidator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bodyValidator.test.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/bodyValidator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { z } from 'zod';
4
+ import { recordingLogger, sampleRequestW } from '../../test/test-common.js';
5
+ import { makeRequestW } from '../RequestW.js';
6
+ import { EMPTY_RESPONSE_W } from '../ResponseW.js';
7
+ import { middleware as bodyValidator } from './bodyValidator.js';
8
+ const positiveNumberSchema = z.number().positive();
9
+ describe('bodyValidator', () => {
10
+ it('forwards a validated body to the wrapped handler', async () => {
11
+ const { logger } = recordingLogger();
12
+ const wrapped = bodyValidator(positiveNumberSchema)((req) => okAsyncR({
13
+ ...EMPTY_RESPONSE_W,
14
+ body: { received: req.body },
15
+ }));
16
+ const input = makeRequestW(sampleRequestW, { body: 42 });
17
+ const result = await wrapped(input)({ logger });
18
+ expect(result.isOk() && result.value.body).toEqual({ received: 42 });
19
+ });
20
+ it('fails with a MiddlewareError when validation fails', async () => {
21
+ const { logger } = recordingLogger();
22
+ const wrapped = bodyValidator(positiveNumberSchema)(() => okAsyncR(EMPTY_RESPONSE_W));
23
+ const input = makeRequestW(sampleRequestW, { body: -1 });
24
+ const result = await wrapped(input)({ logger });
25
+ expect(result.isErr() && result.error.message).toBe('Body validation failed');
26
+ });
27
+ it('supports schemas whose validate returns a Promise', async () => {
28
+ const asyncSchema = z.string().transform(async (input) => input);
29
+ const { logger } = recordingLogger();
30
+ const wrapped = bodyValidator(asyncSchema)((req) => okAsyncR({
31
+ ...EMPTY_RESPONSE_W,
32
+ body: { received: req.body },
33
+ }));
34
+ const input = makeRequestW(sampleRequestW, { body: 'hello' });
35
+ const result = await wrapped(input)({ logger });
36
+ expect(result.isOk() && result.value.body).toEqual({ received: 'hello' });
37
+ });
38
+ it('fails with a MiddlewareError when validation throws', async () => {
39
+ const cause = new Error('validator exploded');
40
+ const throwingSchema = {
41
+ '~standard': {
42
+ version: 1,
43
+ vendor: 'fixture',
44
+ validate: () => {
45
+ throw cause;
46
+ },
47
+ },
48
+ };
49
+ const { logger } = recordingLogger();
50
+ const wrapped = bodyValidator(throwingSchema)(() => okAsyncR(EMPTY_RESPONSE_W));
51
+ const result = await wrapped(sampleRequestW)({ logger });
52
+ expect(result.isErr() && result.error).toMatchObject({
53
+ message: 'Schema validation threw',
54
+ internal: [cause],
55
+ });
56
+ });
57
+ });
58
+ //# sourceMappingURL=bodyValidator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bodyValidator.test.js","sourceRoot":"","sources":["../../../src/http/contrib/bodyValidator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import type { WithLogger } from '../../lib/Logger.js';
3
+ import type { MiddlewareError } from '../../lib/MiddlewareError.js';
4
+ import type { Override, Rec, RequestResponseHandler } from '../RequestResponseHandler.js';
5
+ export declare const TAG = "envValidator";
6
+ export type WithValidatedEnv<V> = {
7
+ readonly validatedEnv: V;
8
+ };
9
+ export declare const middleware: <V>(schema: StandardSchemaV1<unknown, V>) => <I extends Rec, O extends Rec, E, R>(wrapped: RequestResponseHandler<Override<I, WithValidatedEnv<V>>, R, O, E>) => RequestResponseHandler<I, R & WithLogger, O, E | MiddlewareError>;
10
+ //# sourceMappingURL=envValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envValidator.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/envValidator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAI1F,eAAO,MAAM,GAAG,iBAAiB,CAAC;AAElC,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;CAC1B,CAAC;AAKF,eAAO,MAAM,UAAU,GACpB,CAAC,EAAE,QAAQ,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,MACvC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,sBAAsB,CAAC,QAAQ,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KACzE,sBAAsB,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,eAAe,CAWhE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { andThenAsync, mapAsync, mapErrAsync } from '@konker.dev/neverthrow-r/async';
2
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
3
+ import { pipe } from '@konker.dev/neverthrow-r/pipe';
4
+ import { andThenParseAsyncR } from '@konker.dev/neverthrow-r-schema/async';
5
+ import { tapLogger } from '../../lib/Logger.js';
6
+ import { middlewareError } from '../../lib/MiddlewareError.js';
7
+ import { makeRequestW } from '../RequestW.js';
8
+ import { makeResponseW } from '../ResponseW.js';
9
+ export const TAG = 'envValidator';
10
+ const toMiddlewareError = (error) => middlewareError(error.message, error.cause === undefined ? error.issues : [error.cause, ...error.issues]);
11
+ export const middleware = (schema) => (wrapped) => (i) => pipe(okAsyncR(process.env), tapLogger('debug', `[${TAG}] IN`), andThenParseAsyncR(schema, { message: 'Environment validation failed' }), mapErrAsync(toMiddlewareError), mapAsync((validatedEnv) => makeRequestW(i, { validatedEnv })), andThenAsync(wrapped), mapAsync((res) => makeResponseW(res)), tapLogger('debug', `[${TAG}] OUT`));
12
+ //# sourceMappingURL=envValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envValidator.js","sourceRoot":"","sources":["../../../src/http/contrib/envValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAK3E,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAiB,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,CAAC,MAAM,GAAG,GAAG,cAAc,CAAC;AAMlC,MAAM,iBAAiB,GAAG,CAAC,KAA4B,EAAmB,EAAE,CAC1E,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAE5G,MAAM,CAAC,MAAM,UAAU,GACrB,CAAI,MAAoC,EAAE,EAAE,CAC5C,CACE,OAA0E,EACP,EAAE,CACvE,CAAC,CAAc,EAAE,EAAE,CACjB,IAAI,CACF,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EACrB,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,CAAC,EACjC,kBAAkB,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC,EACxE,WAAW,CAAC,iBAAiB,CAAC,EAC9B,QAAQ,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,EAC7D,YAAY,CAAC,OAAO,CAAC,EACrB,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EACrC,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,CACnC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=envValidator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envValidator.test.d.ts","sourceRoot":"","sources":["../../../src/http/contrib/envValidator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { z } from 'zod';
4
+ import { recordingLogger, sampleRequestW } from '../../test/test-common.js';
5
+ import { EMPTY_RESPONSE_W } from '../ResponseW.js';
6
+ import { middleware as envValidator } from './envValidator.js';
7
+ describe('envValidator', () => {
8
+ const schema = z.object({
9
+ TEST_ENV_VALUE: z.literal('hello'),
10
+ TEST_ENV_NUM: z.coerce.number(),
11
+ });
12
+ it('injects validated env into the wrapped handler', async () => {
13
+ const oldEnv = process.env;
14
+ process.env = { ...oldEnv, TEST_ENV_VALUE: 'hello', TEST_ENV_NUM: '42' };
15
+ const { logger } = recordingLogger();
16
+ const wrapped = envValidator(schema)((req) => okAsyncR({
17
+ ...EMPTY_RESPONSE_W,
18
+ body: req.validatedEnv,
19
+ }));
20
+ const result = await wrapped(sampleRequestW)({ logger });
21
+ process.env = oldEnv;
22
+ expect(result.isOk() && result.value.body).toEqual({ TEST_ENV_VALUE: 'hello', TEST_ENV_NUM: 42 });
23
+ });
24
+ it('returns a MiddlewareError on invalid env', async () => {
25
+ const oldEnv = process.env;
26
+ process.env = { TEST_ENV_VALUE: 'bad' };
27
+ const { logger } = recordingLogger();
28
+ const wrapped = envValidator(schema)((_req) => okAsyncR(EMPTY_RESPONSE_W));
29
+ const result = await wrapped(sampleRequestW)({ logger });
30
+ process.env = oldEnv;
31
+ expect(result.isErr() && result.error.message).toBe('Environment validation failed');
32
+ });
33
+ it('keeps a thrown validator cause in internal details', async () => {
34
+ const schema = {
35
+ '~standard': {
36
+ version: 1,
37
+ vendor: 'fixture',
38
+ validate: () => {
39
+ throw new Error('validator exploded');
40
+ },
41
+ },
42
+ };
43
+ const { logger } = recordingLogger();
44
+ const wrapped = envValidator(schema)(() => okAsyncR(EMPTY_RESPONSE_W));
45
+ const result = await wrapped(sampleRequestW)({ logger });
46
+ expect(result.isErr() && result.error.internal?.length).toBeGreaterThan(0);
47
+ });
48
+ });
49
+ //# sourceMappingURL=envValidator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envValidator.test.js","sourceRoot":"","sources":["../../../src/http/contrib/envValidator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Handler } from '../../../handler.js';
2
+ import type { WithLogger } from '../../../lib/Logger.js';
3
+ import { HttpApiError } from '../../HttpApiError.js';
4
+ import type { Rec } from '../../Rec.js';
5
+ import type { RequestW } from '../../RequestW.js';
6
+ import type { ResponseW } from '../../ResponseW.js';
7
+ export declare const TAG = "headerSignatureAuthorizer";
8
+ export type HeaderSignatureAuthorizerDeps = {
9
+ readonly secret: string;
10
+ readonly signatureHeaderName: string;
11
+ };
12
+ export declare const middleware: () => <I extends Rec, O extends Rec, E, R>(wrapped: Handler<RequestW<I>, R, ResponseW<O>, E>) => Handler<RequestW<I>, R & WithLogger & HeaderSignatureAuthorizerDeps, ResponseW<O>, E | HttpApiError>;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/http/contrib/headerSignatureAuthorizer/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD,eAAO,MAAM,GAAG,8BAA8B,CAAC;AAE/C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,UAAU,SAEpB,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAChD,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,GAAG,6BAA6B,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,CAqBrG,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { errAsync } from 'neverthrow';
2
+ import { HttpApiError } from '../../HttpApiError.js';
3
+ import { validateHeaderSignature } from './lib.js';
4
+ export const TAG = 'headerSignatureAuthorizer';
5
+ export const middleware = () => (wrapped) => (i) => (r) => {
6
+ r.logger.debug(`[${TAG}] IN`);
7
+ const gateResult = validateHeaderSignature(i.headers[r.signatureHeaderName], i.body, r.secret)(undefined);
8
+ if (gateResult.isErr()) {
9
+ r.logger.error(gateResult.error);
10
+ return errAsync(gateResult.error);
11
+ }
12
+ if (!gateResult.value) {
13
+ const error = new HttpApiError({ statusCode: 401, message: 'Invalid signature' });
14
+ r.logger.error(error);
15
+ return errAsync(error);
16
+ }
17
+ return wrapped(i)(r).map((res) => {
18
+ r.logger.debug(`[${TAG}] OUT`);
19
+ return res;
20
+ });
21
+ };
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/http/contrib/headerSignatureAuthorizer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,CAAC,MAAM,GAAG,GAAG,2BAA2B,CAAC;AAO/C,MAAM,CAAC,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAiD,EACqD,EAAE,CAC1G,CAAC,CAAC,EAAE,EAAE,CACN,CAAC,CAAC,EAAE,EAAE;IACJ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IAE9B,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;IAC1G,IAAI,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,QAAQ,CAA6B,UAAU,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAClF,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,QAAQ,CAA6B,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/B,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../src/http/contrib/headerSignatureAuthorizer/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,39 @@
1
+ import { errR } from '@konker.dev/neverthrow-r/constructors';
2
+ import { okAsyncR } from '@konker.dev/neverthrow-r/constructors';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+ import { recordingLogger, sampleRequestW } from '../../../test/test-common.js';
5
+ import { HttpApiError } from '../../HttpApiError.js';
6
+ import { makeRequestW } from '../../RequestW.js';
7
+ import { EMPTY_RESPONSE_W } from '../../ResponseW.js';
8
+ import { middleware as headerSignatureAuthorizer } from './index.js';
9
+ import * as lib from './lib.js';
10
+ describe('headerSignatureAuthorizer', () => {
11
+ it('authorizes when the signature matches the body', async () => {
12
+ const { logger } = recordingLogger();
13
+ const wrapped = headerSignatureAuthorizer()(() => okAsyncR(EMPTY_RESPONSE_W));
14
+ const input = makeRequestW(sampleRequestW, {
15
+ body: 'payload',
16
+ headers: { 'x-signature': 'b82fcb791acec57859b989b430a826488ce2e479fdf92326bd0a2e8375a42ba4' },
17
+ });
18
+ const result = await wrapped(input)({ logger, secret: 'secret', signatureHeaderName: 'x-signature' });
19
+ expect(result.isOk()).toBe(true);
20
+ });
21
+ it('returns a 401 HttpApiError when the signature is invalid', async () => {
22
+ const { logger } = recordingLogger();
23
+ const wrapped = headerSignatureAuthorizer()(() => okAsyncR(EMPTY_RESPONSE_W));
24
+ const input = makeRequestW(sampleRequestW, {
25
+ body: 'payload',
26
+ headers: { 'x-signature': 'bad' },
27
+ });
28
+ const result = await wrapped(input)({ logger, secret: 'secret', signatureHeaderName: 'x-signature' });
29
+ expect(result.isErr() && result.error.statusCode).toBe(401);
30
+ });
31
+ it('returns the validation error when signature calculation fails', async () => {
32
+ vi.spyOn(lib, 'validateHeaderSignature').mockReturnValue(errR(new HttpApiError({ statusCode: 500, message: 'boom' })));
33
+ const { logger } = recordingLogger();
34
+ const wrapped = headerSignatureAuthorizer()(() => okAsyncR(EMPTY_RESPONSE_W));
35
+ const result = await wrapped(sampleRequestW)({ logger, secret: 'secret', signatureHeaderName: 'x-signature' });
36
+ expect(result.isErr() && result.error.message).toBe('boom');
37
+ });
38
+ });
39
+ //# sourceMappingURL=index.test.js.map