@furystack/rest-service 13.0.0 → 14.1.0

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 (311) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +47 -28
  3. package/esm/actions/error-action.d.ts +7 -2
  4. package/esm/actions/error-action.d.ts.map +1 -1
  5. package/esm/actions/error-action.js +7 -2
  6. package/esm/actions/error-action.js.map +1 -1
  7. package/esm/actions/get-current-user.d.ts +1 -4
  8. package/esm/actions/get-current-user.d.ts.map +1 -1
  9. package/esm/actions/get-current-user.js +1 -4
  10. package/esm/actions/get-current-user.js.map +1 -1
  11. package/esm/actions/get-current-user.spec.js +10 -6
  12. package/esm/actions/get-current-user.spec.js.map +1 -1
  13. package/esm/actions/is-authenticated.d.ts +3 -4
  14. package/esm/actions/is-authenticated.d.ts.map +1 -1
  15. package/esm/actions/is-authenticated.js +3 -4
  16. package/esm/actions/is-authenticated.js.map +1 -1
  17. package/esm/actions/is-authenticated.spec.js +10 -6
  18. package/esm/actions/is-authenticated.spec.js.map +1 -1
  19. package/esm/actions/logout-action.spec.js +11 -9
  20. package/esm/actions/logout-action.spec.js.map +1 -1
  21. package/esm/actions/logout.d.ts +2 -6
  22. package/esm/actions/logout.d.ts.map +1 -1
  23. package/esm/actions/logout.js +3 -7
  24. package/esm/actions/logout.js.map +1 -1
  25. package/esm/actions/not-found-action.d.ts +1 -3
  26. package/esm/actions/not-found-action.d.ts.map +1 -1
  27. package/esm/actions/not-found-action.js +1 -3
  28. package/esm/actions/not-found-action.js.map +1 -1
  29. package/esm/actions/password-login-action.d.ts +5 -12
  30. package/esm/actions/password-login-action.d.ts.map +1 -1
  31. package/esm/actions/password-login-action.js +6 -13
  32. package/esm/actions/password-login-action.js.map +1 -1
  33. package/esm/actions/password-login-action.spec.js +23 -28
  34. package/esm/actions/password-login-action.spec.js.map +1 -1
  35. package/esm/authenticate.d.ts +5 -11
  36. package/esm/authenticate.d.ts.map +1 -1
  37. package/esm/authenticate.js +6 -12
  38. package/esm/authenticate.js.map +1 -1
  39. package/esm/authenticate.spec.js +41 -33
  40. package/esm/authenticate.spec.js.map +1 -1
  41. package/esm/authentication-providers/authentication-provider.d.ts +17 -0
  42. package/esm/authentication-providers/authentication-provider.d.ts.map +1 -1
  43. package/esm/authentication-providers/basic-auth-provider.d.ts +7 -0
  44. package/esm/authentication-providers/basic-auth-provider.d.ts.map +1 -1
  45. package/esm/authentication-providers/basic-auth-provider.js +7 -0
  46. package/esm/authentication-providers/basic-auth-provider.js.map +1 -1
  47. package/esm/authentication-providers/cookie-auth-provider.d.ts.map +1 -1
  48. package/esm/authentication-providers/cookie-auth-provider.js +8 -0
  49. package/esm/authentication-providers/cookie-auth-provider.js.map +1 -1
  50. package/esm/authorize.d.ts +5 -17
  51. package/esm/authorize.d.ts.map +1 -1
  52. package/esm/authorize.js +5 -17
  53. package/esm/authorize.js.map +1 -1
  54. package/esm/authorize.spec.js +34 -29
  55. package/esm/authorize.spec.js.map +1 -1
  56. package/esm/endpoint-generators/create-delete-endpoint.d.ts +6 -11
  57. package/esm/endpoint-generators/create-delete-endpoint.d.ts.map +1 -1
  58. package/esm/endpoint-generators/create-delete-endpoint.js +7 -11
  59. package/esm/endpoint-generators/create-delete-endpoint.js.map +1 -1
  60. package/esm/endpoint-generators/create-delete-endpoint.spec.js +14 -21
  61. package/esm/endpoint-generators/create-delete-endpoint.spec.js.map +1 -1
  62. package/esm/endpoint-generators/create-get-collection-endpoint.d.ts +11 -11
  63. package/esm/endpoint-generators/create-get-collection-endpoint.d.ts.map +1 -1
  64. package/esm/endpoint-generators/create-get-collection-endpoint.js +13 -12
  65. package/esm/endpoint-generators/create-get-collection-endpoint.js.map +1 -1
  66. package/esm/endpoint-generators/create-get-collection-endpoint.spec.js +43 -70
  67. package/esm/endpoint-generators/create-get-collection-endpoint.spec.js.map +1 -1
  68. package/esm/endpoint-generators/create-get-entity-endpoint.d.ts +6 -11
  69. package/esm/endpoint-generators/create-get-entity-endpoint.d.ts.map +1 -1
  70. package/esm/endpoint-generators/create-get-entity-endpoint.js +7 -11
  71. package/esm/endpoint-generators/create-get-entity-endpoint.js.map +1 -1
  72. package/esm/endpoint-generators/create-get-entity-endpoint.spec.js +16 -33
  73. package/esm/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
  74. package/esm/endpoint-generators/create-get-openapi-document-action.d.ts +1 -1
  75. package/esm/endpoint-generators/create-get-openapi-document-action.d.ts.map +1 -1
  76. package/esm/endpoint-generators/create-get-openapi-document-action.js +1 -1
  77. package/esm/endpoint-generators/create-get-openapi-document-action.js.map +1 -1
  78. package/esm/endpoint-generators/create-get-schema-action.d.ts +1 -1
  79. package/esm/endpoint-generators/create-get-schema-action.d.ts.map +1 -1
  80. package/esm/endpoint-generators/create-get-schema-action.js.map +1 -1
  81. package/esm/endpoint-generators/create-patch-endpoint.d.ts +7 -13
  82. package/esm/endpoint-generators/create-patch-endpoint.d.ts.map +1 -1
  83. package/esm/endpoint-generators/create-patch-endpoint.js +8 -13
  84. package/esm/endpoint-generators/create-patch-endpoint.js.map +1 -1
  85. package/esm/endpoint-generators/create-patch-endpoint.spec.js +10 -17
  86. package/esm/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
  87. package/esm/endpoint-generators/create-post-endpoint.d.ts +7 -13
  88. package/esm/endpoint-generators/create-post-endpoint.d.ts.map +1 -1
  89. package/esm/endpoint-generators/create-post-endpoint.js +8 -13
  90. package/esm/endpoint-generators/create-post-endpoint.js.map +1 -1
  91. package/esm/endpoint-generators/create-post-endpoint.spec.js +41 -14
  92. package/esm/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
  93. package/esm/endpoint-generators/utils.d.ts +17 -2
  94. package/esm/endpoint-generators/utils.d.ts.map +1 -1
  95. package/esm/endpoint-generators/utils.js +33 -20
  96. package/esm/endpoint-generators/utils.js.map +1 -1
  97. package/esm/get-schema-from-api.d.ts +1 -1
  98. package/esm/get-schema-from-api.d.ts.map +1 -1
  99. package/esm/get-schema-from-api.js +1 -0
  100. package/esm/get-schema-from-api.js.map +1 -1
  101. package/esm/get-schema-from-api.spec.js.map +1 -1
  102. package/esm/helpers.d.ts +54 -88
  103. package/esm/helpers.d.ts.map +1 -1
  104. package/esm/helpers.js +90 -92
  105. package/esm/helpers.js.map +1 -1
  106. package/esm/helpers.spec.d.ts +2 -1
  107. package/esm/helpers.spec.d.ts.map +1 -1
  108. package/esm/helpers.spec.js +41 -38
  109. package/esm/helpers.spec.js.map +1 -1
  110. package/esm/http-authentication-settings.d.ts +56 -12
  111. package/esm/http-authentication-settings.d.ts.map +1 -1
  112. package/esm/http-authentication-settings.js +27 -29
  113. package/esm/http-authentication-settings.js.map +1 -1
  114. package/esm/http-server-pool.d.ts +64 -0
  115. package/esm/http-server-pool.d.ts.map +1 -0
  116. package/esm/http-server-pool.js +95 -0
  117. package/esm/http-server-pool.js.map +1 -0
  118. package/esm/http-server-pool.spec.d.ts +2 -0
  119. package/esm/http-server-pool.spec.d.ts.map +1 -0
  120. package/esm/http-server-pool.spec.js +193 -0
  121. package/esm/http-server-pool.spec.js.map +1 -0
  122. package/esm/http-user-context.d.ts +34 -44
  123. package/esm/http-user-context.d.ts.map +1 -1
  124. package/esm/http-user-context.js +75 -95
  125. package/esm/http-user-context.js.map +1 -1
  126. package/esm/http-user-context.spec.d.ts +8 -2
  127. package/esm/http-user-context.spec.d.ts.map +1 -1
  128. package/esm/http-user-context.spec.js +226 -332
  129. package/esm/http-user-context.spec.js.map +1 -1
  130. package/esm/identity-cache-keys.d.ts +28 -0
  131. package/esm/identity-cache-keys.d.ts.map +1 -0
  132. package/esm/identity-cache-keys.js +13 -0
  133. package/esm/identity-cache-keys.js.map +1 -0
  134. package/esm/identity-cache-keys.spec.d.ts +2 -0
  135. package/esm/identity-cache-keys.spec.d.ts.map +1 -0
  136. package/esm/identity-cache-keys.spec.js +21 -0
  137. package/esm/identity-cache-keys.spec.js.map +1 -0
  138. package/esm/identity-event-bus.d.ts +102 -0
  139. package/esm/identity-event-bus.d.ts.map +1 -0
  140. package/esm/identity-event-bus.js +151 -0
  141. package/esm/identity-event-bus.js.map +1 -0
  142. package/esm/identity-event-bus.spec.d.ts +2 -0
  143. package/esm/identity-event-bus.spec.d.ts.map +1 -0
  144. package/esm/identity-event-bus.spec.js +392 -0
  145. package/esm/identity-event-bus.spec.js.map +1 -0
  146. package/esm/index.d.ts +9 -4
  147. package/esm/index.d.ts.map +1 -1
  148. package/esm/index.js +9 -4
  149. package/esm/index.js.map +1 -1
  150. package/esm/login-response-strategy.d.ts +11 -10
  151. package/esm/login-response-strategy.d.ts.map +1 -1
  152. package/esm/login-response-strategy.js +7 -6
  153. package/esm/login-response-strategy.js.map +1 -1
  154. package/esm/login-response-strategy.spec.js +25 -29
  155. package/esm/login-response-strategy.spec.js.map +1 -1
  156. package/esm/openapi/generate-openapi-document.spec.js.map +1 -1
  157. package/esm/proxy-manager.spec.js +152 -176
  158. package/esm/proxy-manager.spec.js.map +1 -1
  159. package/esm/proxy-runtime.d.ts +27 -0
  160. package/esm/proxy-runtime.d.ts.map +1 -0
  161. package/esm/proxy-runtime.js +45 -0
  162. package/esm/proxy-runtime.js.map +1 -0
  163. package/esm/proxy-runtime.spec.d.ts +2 -0
  164. package/esm/proxy-runtime.spec.d.ts.map +1 -0
  165. package/esm/proxy-runtime.spec.js +39 -0
  166. package/esm/proxy-runtime.spec.js.map +1 -0
  167. package/esm/request-action-implementation.d.ts +25 -0
  168. package/esm/request-action-implementation.d.ts.map +1 -1
  169. package/esm/request-action-implementation.js +9 -0
  170. package/esm/request-action-implementation.js.map +1 -1
  171. package/esm/rest-api-runtime.d.ts +76 -0
  172. package/esm/rest-api-runtime.d.ts.map +1 -0
  173. package/esm/rest-api-runtime.js +131 -0
  174. package/esm/rest-api-runtime.js.map +1 -0
  175. package/esm/rest-api-runtime.spec.d.ts +2 -0
  176. package/esm/rest-api-runtime.spec.d.ts.map +1 -0
  177. package/esm/rest-api-runtime.spec.js +58 -0
  178. package/esm/rest-api-runtime.spec.js.map +1 -0
  179. package/esm/rest-service.integration.spec.d.ts +1 -1
  180. package/esm/rest-service.integration.spec.d.ts.map +1 -1
  181. package/esm/rest-service.integration.spec.js +57 -80
  182. package/esm/rest-service.integration.spec.js.map +1 -1
  183. package/esm/rest.integration.test.js +26 -84
  184. package/esm/rest.integration.test.js.map +1 -1
  185. package/esm/server-telemetry.d.ts +49 -0
  186. package/esm/server-telemetry.d.ts.map +1 -0
  187. package/esm/server-telemetry.js +25 -0
  188. package/esm/server-telemetry.js.map +1 -0
  189. package/esm/server-telemetry.spec.d.ts +2 -0
  190. package/esm/server-telemetry.spec.d.ts.map +1 -0
  191. package/esm/server-telemetry.spec.js +52 -0
  192. package/esm/server-telemetry.spec.js.map +1 -0
  193. package/esm/static-server-manager.spec.js +60 -125
  194. package/esm/static-server-manager.spec.js.map +1 -1
  195. package/esm/static-site-runtime.d.ts +21 -0
  196. package/esm/static-site-runtime.d.ts.map +1 -0
  197. package/esm/static-site-runtime.js +48 -0
  198. package/esm/static-site-runtime.js.map +1 -0
  199. package/esm/static-site-runtime.spec.d.ts +2 -0
  200. package/esm/static-site-runtime.spec.d.ts.map +1 -0
  201. package/esm/static-site-runtime.spec.js +30 -0
  202. package/esm/static-site-runtime.spec.js.map +1 -0
  203. package/esm/user-resolution-cache.d.ts +65 -0
  204. package/esm/user-resolution-cache.d.ts.map +1 -0
  205. package/esm/user-resolution-cache.js +101 -0
  206. package/esm/user-resolution-cache.js.map +1 -0
  207. package/esm/user-resolution-cache.spec.d.ts +2 -0
  208. package/esm/user-resolution-cache.spec.d.ts.map +1 -0
  209. package/esm/user-resolution-cache.spec.js +220 -0
  210. package/esm/user-resolution-cache.spec.js.map +1 -0
  211. package/esm/user-store.d.ts +39 -0
  212. package/esm/user-store.d.ts.map +1 -0
  213. package/esm/user-store.js +62 -0
  214. package/esm/user-store.js.map +1 -0
  215. package/esm/user-store.spec.d.ts +2 -0
  216. package/esm/user-store.spec.d.ts.map +1 -0
  217. package/esm/user-store.spec.js +72 -0
  218. package/esm/user-store.spec.js.map +1 -0
  219. package/esm/validate.d.ts +13 -12
  220. package/esm/validate.d.ts.map +1 -1
  221. package/esm/validate.integration.spec.js +27 -28
  222. package/esm/validate.integration.spec.js.map +1 -1
  223. package/esm/validate.js +12 -0
  224. package/esm/validate.js.map +1 -1
  225. package/package.json +14 -12
  226. package/src/actions/error-action.ts +7 -3
  227. package/src/actions/get-current-user.spec.ts +11 -10
  228. package/src/actions/get-current-user.ts +1 -4
  229. package/src/actions/is-authenticated.spec.ts +12 -7
  230. package/src/actions/is-authenticated.ts +3 -4
  231. package/src/actions/logout-action.spec.ts +12 -12
  232. package/src/actions/logout.ts +3 -7
  233. package/src/actions/not-found-action.ts +1 -3
  234. package/src/actions/password-login-action.spec.ts +30 -30
  235. package/src/actions/password-login-action.ts +6 -13
  236. package/src/authenticate.spec.ts +45 -51
  237. package/src/authenticate.ts +6 -12
  238. package/src/authentication-providers/authentication-provider.ts +17 -0
  239. package/src/authentication-providers/basic-auth-provider.ts +7 -0
  240. package/src/authentication-providers/cookie-auth-provider.ts +8 -0
  241. package/src/authorize.spec.ts +37 -39
  242. package/src/authorize.ts +6 -17
  243. package/src/endpoint-generators/create-delete-endpoint.spec.ts +16 -24
  244. package/src/endpoint-generators/create-delete-endpoint.ts +11 -17
  245. package/src/endpoint-generators/create-get-collection-endpoint.spec.ts +45 -78
  246. package/src/endpoint-generators/create-get-collection-endpoint.ts +17 -19
  247. package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +17 -33
  248. package/src/endpoint-generators/create-get-entity-endpoint.ts +11 -17
  249. package/src/endpoint-generators/create-get-openapi-document-action.ts +2 -2
  250. package/src/endpoint-generators/create-get-schema-action.ts +1 -1
  251. package/src/endpoint-generators/create-patch-endpoint.spec.ts +11 -18
  252. package/src/endpoint-generators/create-patch-endpoint.ts +12 -23
  253. package/src/endpoint-generators/create-post-endpoint.spec.ts +45 -14
  254. package/src/endpoint-generators/create-post-endpoint.ts +13 -23
  255. package/src/endpoint-generators/utils.ts +36 -28
  256. package/src/get-schema-from-api.spec.ts +1 -1
  257. package/src/get-schema-from-api.ts +2 -1
  258. package/src/helpers.spec.ts +51 -41
  259. package/src/helpers.ts +140 -109
  260. package/src/http-authentication-settings.ts +78 -24
  261. package/src/http-server-pool.spec.ts +220 -0
  262. package/src/http-server-pool.ts +169 -0
  263. package/src/http-user-context.spec.ts +246 -378
  264. package/src/http-user-context.ts +122 -92
  265. package/src/identity-cache-keys.spec.ts +24 -0
  266. package/src/identity-cache-keys.ts +31 -0
  267. package/src/identity-event-bus.spec.ts +285 -0
  268. package/src/identity-event-bus.ts +230 -0
  269. package/src/index.ts +9 -4
  270. package/src/login-response-strategy.spec.ts +32 -31
  271. package/src/login-response-strategy.ts +14 -12
  272. package/src/openapi/generate-openapi-document.spec.ts +2 -2
  273. package/src/proxy-manager.spec.ts +158 -188
  274. package/src/proxy-runtime.spec.ts +50 -0
  275. package/src/proxy-runtime.ts +75 -0
  276. package/src/request-action-implementation.ts +25 -0
  277. package/src/rest-api-runtime.spec.ts +77 -0
  278. package/src/rest-api-runtime.ts +204 -0
  279. package/src/rest-service.integration.spec.ts +65 -85
  280. package/src/rest.integration.test.ts +27 -87
  281. package/src/server-telemetry.spec.ts +56 -0
  282. package/src/server-telemetry.ts +43 -0
  283. package/src/static-server-manager.spec.ts +63 -151
  284. package/src/static-site-runtime.spec.ts +39 -0
  285. package/src/static-site-runtime.ts +75 -0
  286. package/src/user-resolution-cache.spec.ts +241 -0
  287. package/src/user-resolution-cache.ts +164 -0
  288. package/src/user-store.spec.ts +86 -0
  289. package/src/user-store.ts +69 -0
  290. package/src/validate.integration.spec.ts +40 -35
  291. package/src/validate.ts +14 -12
  292. package/esm/api-manager.d.ts +0 -104
  293. package/esm/api-manager.d.ts.map +0 -1
  294. package/esm/api-manager.js +0 -179
  295. package/esm/api-manager.js.map +0 -1
  296. package/esm/proxy-manager.d.ts +0 -53
  297. package/esm/proxy-manager.d.ts.map +0 -1
  298. package/esm/proxy-manager.js +0 -84
  299. package/esm/proxy-manager.js.map +0 -1
  300. package/esm/server-manager.d.ts +0 -48
  301. package/esm/server-manager.d.ts.map +0 -1
  302. package/esm/server-manager.js +0 -100
  303. package/esm/server-manager.js.map +0 -1
  304. package/esm/static-server-manager.d.ts +0 -19
  305. package/esm/static-server-manager.d.ts.map +0 -1
  306. package/esm/static-server-manager.js +0 -65
  307. package/esm/static-server-manager.js.map +0 -1
  308. package/src/api-manager.ts +0 -304
  309. package/src/proxy-manager.ts +0 -102
  310. package/src/server-manager.ts +0 -135
  311. package/src/static-server-manager.ts +0 -90
@@ -0,0 +1,164 @@
1
+ import type { User } from '@furystack/core'
2
+ import { Cache } from '@furystack/cache'
3
+ import { defineService, type Token } from '@furystack/inject'
4
+ import type { IncomingMessage } from 'http'
5
+ import type { AuthenticationProvider } from './authentication-providers/authentication-provider.js'
6
+ import {
7
+ DEFAULT_USER_CACHE_CAPACITY,
8
+ DEFAULT_USER_CACHE_TTL_MS,
9
+ HttpAuthenticationSettings,
10
+ } from './http-authentication-settings.js'
11
+ import type { HttpUserContext } from './http-user-context.js'
12
+ import { userCacheTag, type UserCacheTag } from './identity-cache-keys.js'
13
+
14
+ /**
15
+ * Singleton TTL cache that memoizes successful identity resolutions across
16
+ * requests within a single process.
17
+ *
18
+ * Cache keys are produced by the configured {@link AuthenticationProvider}s
19
+ * via their `getCacheKey` method (e.g. cookie-auth keys by session id). The
20
+ * cache's `load` callback runs the same provider chain that
21
+ * {@link HttpUserContext.authenticateRequest} would run — it is supplied via
22
+ * an internal "loader" registered when the {@link HttpUserContext} is
23
+ * resolved.
24
+ *
25
+ * Entries expire after `HttpAuthenticationSettings.userCacheTtlMs`; capacity
26
+ * is bounded by `HttpAuthenticationSettings.userCacheCapacity`. Setting the
27
+ * TTL to `0` disables caching (the loader runs on every call).
28
+ *
29
+ * **Multi-node note:** session invalidation on one instance does not
30
+ * propagate to siblings — the TTL bounds the staleness window. Apps that
31
+ * need stricter freshness must shorten the TTL or invalidate explicitly via
32
+ * {@link UserResolutionCache.invalidate} /
33
+ * {@link UserResolutionCache.invalidateByUser}.
34
+ */
35
+ export interface UserResolutionCache extends Disposable {
36
+ /**
37
+ * Returns the cached or freshly-resolved `User` for the supplied
38
+ * cache key. The `loader` is invoked on cache miss; concurrent calls for
39
+ * the same key dedupe to a single loader invocation.
40
+ */
41
+ resolve(cacheKey: string, loader: () => Promise<User>): Promise<User>
42
+ /** Drops a single cache entry. No-op when the key is unknown. */
43
+ invalidate(cacheKey: string): void
44
+ /**
45
+ * Drops every cached entry that resolved to `username`, regardless of
46
+ * which {@link AuthenticationProvider}'s key originally populated it.
47
+ * Backed by the cache's reverse tag index — no per-call O(n) scan.
48
+ *
49
+ * Use after role / password / account-state changes that must take
50
+ * effect immediately on the next request, instead of waiting for the
51
+ * TTL window to elapse.
52
+ */
53
+ invalidateByUser(username: string): void
54
+ /** Drops every cached entry. */
55
+ invalidateAll(): void
56
+ /** Returns the current entry count (for diagnostics / tests). */
57
+ readonly size: number
58
+ }
59
+
60
+ class UserResolutionCacheImpl implements UserResolutionCache {
61
+ private readonly loaders = new Map<string, () => Promise<User>>()
62
+ private readonly cache: Cache<User, [string], UserCacheTag> | null
63
+
64
+ constructor(ttlMs: number, capacity: number) {
65
+ if (ttlMs <= 0) {
66
+ this.cache = null
67
+ return
68
+ }
69
+ this.cache = new Cache<User, [string], UserCacheTag>({
70
+ load: (cacheKey) => {
71
+ const loader = this.loaders.get(cacheKey)
72
+ if (!loader) {
73
+ // The loader is only registered for the duration of a `resolve()`
74
+ // call. A reload triggered via `cache.get(key)` outside that call
75
+ // (e.g. from `getObservable`) would have no loader; refuse the
76
+ // load instead of caching `null`.
77
+ return Promise.reject(new Error(`No loader registered for cache key '${cacheKey}'`))
78
+ }
79
+ return loader()
80
+ },
81
+ cacheTimeMs: ttlMs,
82
+ capacity,
83
+ getKey: (cacheKey) => cacheKey,
84
+ getTags: (user) => [userCacheTag(user.username)],
85
+ })
86
+ }
87
+
88
+ public async resolve(cacheKey: string, loader: () => Promise<User>): Promise<User> {
89
+ if (!this.cache) {
90
+ return loader()
91
+ }
92
+ this.loaders.set(cacheKey, loader)
93
+ try {
94
+ return await this.cache.get(cacheKey)
95
+ } finally {
96
+ // Loader is per-request; clearing prevents the cache from re-running it
97
+ // out-of-band when the entry transitions to obsolete and a sibling call
98
+ // queries `getObservable`.
99
+ this.loaders.delete(cacheKey)
100
+ }
101
+ }
102
+
103
+ public invalidate(cacheKey: string): void {
104
+ this.cache?.remove(cacheKey)
105
+ }
106
+
107
+ public invalidateByUser(username: string): void {
108
+ this.cache?.removeByTag(userCacheTag(username))
109
+ }
110
+
111
+ public invalidateAll(): void {
112
+ this.cache?.flushAll()
113
+ }
114
+
115
+ public get size(): number {
116
+ return this.cache?.getCount() ?? 0
117
+ }
118
+
119
+ public [Symbol.dispose](): void {
120
+ this.cache?.[Symbol.dispose]()
121
+ this.loaders.clear()
122
+ }
123
+ }
124
+
125
+ /**
126
+ * DI token for the singleton {@link UserResolutionCache}. Resolved lazily
127
+ * by {@link HttpUserContext}; sized from {@link HttpAuthenticationSettings}.
128
+ */
129
+ export const UserResolutionCache: Token<UserResolutionCache, 'singleton'> = defineService({
130
+ name: 'furystack/rest-service/UserResolutionCache',
131
+ lifetime: 'singleton',
132
+ factory: ({ inject, onDispose }): UserResolutionCache => {
133
+ const settings = inject(HttpAuthenticationSettings)
134
+ const ttlMs = settings.userCacheTtlMs ?? DEFAULT_USER_CACHE_TTL_MS
135
+ const capacity = settings.userCacheCapacity ?? DEFAULT_USER_CACHE_CAPACITY
136
+ const impl = new UserResolutionCacheImpl(ttlMs, capacity)
137
+ onDispose(() => {
138
+ // eslint-disable-next-line furystack/prefer-using-wrapper -- onDispose is the teardown hook
139
+ impl[Symbol.dispose]()
140
+ })
141
+ return impl
142
+ },
143
+ })
144
+
145
+ /**
146
+ * Resolves the configured cache key for the supplied request by walking the
147
+ * authentication providers in order and returning the first non-null key.
148
+ *
149
+ * Returns `null` when no provider opts in to caching (e.g. Basic Auth, or
150
+ * an anonymous request). The caller should bypass the cache in that case.
151
+ *
152
+ * Exported so plugins / tests can derive the same key the cache uses.
153
+ */
154
+ export const resolveUserCacheKey = (
155
+ settings: HttpAuthenticationSettings,
156
+ request: Pick<IncomingMessage, 'headers'>,
157
+ ): string | null => {
158
+ for (const provider of settings.authenticationProviders) {
159
+ if (!provider.getCacheKey) continue
160
+ const key = provider.getCacheKey(request)
161
+ if (key) return key
162
+ }
163
+ return null
164
+ }
@@ -0,0 +1,86 @@
1
+ import { InMemoryStore, User } from '@furystack/core'
2
+ import { createInjector } from '@furystack/inject'
3
+ import { usingAsync } from '@furystack/utils'
4
+ import { describe, expect, it } from 'vitest'
5
+ import { DefaultSession } from './models/default-session.js'
6
+ import {
7
+ HttpAuthenticationStoreNotConfiguredError,
8
+ SessionDataSet,
9
+ SessionStore,
10
+ UserDataSet,
11
+ UserStore,
12
+ } from './user-store.js'
13
+
14
+ describe('UserStore', () => {
15
+ it('exposes the User model and username primary key on the token', () => {
16
+ expect(UserStore.model).toBe(User)
17
+ expect(UserStore.primaryKey).toBe('username')
18
+ expect(UserStore.lifetime).toBe('singleton')
19
+ })
20
+
21
+ it('throws HttpAuthenticationStoreNotConfiguredError when resolved without an override', async () => {
22
+ await usingAsync(createInjector(), async (injector) => {
23
+ expect(() => injector.get(UserStore)).toThrow(HttpAuthenticationStoreNotConfiguredError)
24
+ expect(() => injector.get(UserStore)).toThrow(/UserStore.*not been configured/)
25
+ })
26
+ })
27
+
28
+ it('returns the bound implementation after rebinding the token', async () => {
29
+ await usingAsync(createInjector(), async (injector) => {
30
+ const impl = new InMemoryStore({ model: User, primaryKey: 'username' })
31
+ injector.bind(UserStore, () => impl)
32
+ expect(injector.get(UserStore)).toBe(impl)
33
+ })
34
+ })
35
+ })
36
+
37
+ describe('SessionStore', () => {
38
+ it('exposes the DefaultSession model and sessionId primary key on the token', () => {
39
+ expect(SessionStore.model).toBe(DefaultSession)
40
+ expect(SessionStore.primaryKey).toBe('sessionId')
41
+ expect(SessionStore.lifetime).toBe('singleton')
42
+ })
43
+
44
+ it('throws HttpAuthenticationStoreNotConfiguredError when resolved without an override', async () => {
45
+ await usingAsync(createInjector(), async (injector) => {
46
+ expect(() => injector.get(SessionStore)).toThrow(HttpAuthenticationStoreNotConfiguredError)
47
+ expect(() => injector.get(SessionStore)).toThrow(/SessionStore.*not been configured/)
48
+ })
49
+ })
50
+
51
+ it('returns the bound implementation after rebinding the token', async () => {
52
+ await usingAsync(createInjector(), async (injector) => {
53
+ const impl = new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' })
54
+ injector.bind(SessionStore, () => impl)
55
+ expect(injector.get(SessionStore)).toBe(impl)
56
+ })
57
+ })
58
+ })
59
+
60
+ describe('UserDataSet / SessionDataSet', () => {
61
+ it('mirror the backing store metadata onto the data-set token', () => {
62
+ expect(UserDataSet.model).toBe(User)
63
+ expect(UserDataSet.primaryKey).toBe('username')
64
+ expect(SessionDataSet.model).toBe(DefaultSession)
65
+ expect(SessionDataSet.primaryKey).toBe('sessionId')
66
+ })
67
+
68
+ it('resolves through the bound store implementation', async () => {
69
+ await usingAsync(createInjector(), async (injector) => {
70
+ injector.bind(UserStore, () => new InMemoryStore({ model: User, primaryKey: 'username' }))
71
+ const dataSet = injector.get(UserDataSet)
72
+ await dataSet.add(injector, { username: 'alice', roles: [] })
73
+ const result = await dataSet.get(injector, 'alice')
74
+ expect(result?.username).toBe('alice')
75
+ })
76
+ })
77
+ })
78
+
79
+ describe('HttpAuthenticationStoreNotConfiguredError', () => {
80
+ it('embeds the store name in the message and sets the error name', () => {
81
+ const error = new HttpAuthenticationStoreNotConfiguredError('SomeStore')
82
+ expect(error.name).toBe('HttpAuthenticationStoreNotConfiguredError')
83
+ expect(error.message).toContain("'SomeStore'")
84
+ expect(error).toBeInstanceOf(Error)
85
+ })
86
+ })
@@ -0,0 +1,69 @@
1
+ import { defineStore, type StoreToken, User } from '@furystack/core'
2
+ import { defineDataSet, type DataSetToken } from '@furystack/repository'
3
+ import type { HttpUserContext } from './http-user-context.js'
4
+ import { DefaultSession } from './models/default-session.js'
5
+
6
+ /**
7
+ * Error thrown by the default factories of {@link UserStore} and
8
+ * {@link SessionStore} when they are resolved without a caller-provided
9
+ * override. Users and sessions must outlive a process restart, so the
10
+ * rest-service refuses to silently fall back to an in-memory store.
11
+ */
12
+ export class HttpAuthenticationStoreNotConfiguredError extends Error {
13
+ constructor(storeName: string) {
14
+ super(
15
+ `HTTP authentication store '${storeName}' has not been configured. Bind a persistent PhysicalStore before resolving the HttpUserContext.`,
16
+ )
17
+ this.name = 'HttpAuthenticationStoreNotConfiguredError'
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Store token for persisted {@link User} records. Applications must bind
23
+ * this token to a persistent implementation before resolving
24
+ * {@link HttpUserContext} (or any service that derives from it).
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * injector.bind(UserStore, () => myPersistentUserStore)
29
+ * ```
30
+ */
31
+ export const UserStore: StoreToken<User, 'username'> = defineStore({
32
+ name: 'furystack/rest-service/UserStore',
33
+ model: User,
34
+ primaryKey: 'username',
35
+ factory: () => {
36
+ throw new HttpAuthenticationStoreNotConfiguredError('UserStore')
37
+ },
38
+ })
39
+
40
+ /**
41
+ * Store token for persisted {@link DefaultSession} records. Shares the
42
+ * throw-by-default contract with {@link UserStore}.
43
+ */
44
+ export const SessionStore: StoreToken<DefaultSession, 'sessionId'> = defineStore({
45
+ name: 'furystack/rest-service/SessionStore',
46
+ model: DefaultSession,
47
+ primaryKey: 'sessionId',
48
+ factory: () => {
49
+ throw new HttpAuthenticationStoreNotConfiguredError('SessionStore')
50
+ },
51
+ })
52
+
53
+ /**
54
+ * Data set token over {@link UserStore}. Consumers of the authentication
55
+ * subsystem (cookie login, JWT authentication plugins, `HttpUserContext`)
56
+ * route all user I/O through this dataset.
57
+ */
58
+ export const UserDataSet: DataSetToken<User, 'username'> = defineDataSet({
59
+ name: 'furystack/rest-service/UserDataSet',
60
+ store: UserStore,
61
+ })
62
+
63
+ /**
64
+ * Data set token over {@link SessionStore}.
65
+ */
66
+ export const SessionDataSet: DataSetToken<DefaultSession, 'sessionId'> = defineDataSet({
67
+ name: 'furystack/rest-service/SessionDataSet',
68
+ store: SessionStore,
69
+ })
@@ -1,10 +1,17 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
- import { getStoreManager, InMemoryStore, User } from '@furystack/core'
2
+ /* eslint-disable @typescript-eslint/no-unnecessary-type-assertion -- false positives: `client` is typed for a narrow `RestApi`; casts to `ReturnType<typeof createClient<...>>` widen it so this test can exercise endpoints (e.g. `/openapi.json`) the production type intentionally hides */
3
+ import { InMemoryStore, User as UserModel } from '@furystack/core'
3
4
  import { getPort } from '@furystack/core/port-generator'
4
- import { Injector } from '@furystack/inject'
5
- import { getRepository } from '@furystack/repository'
5
+ import { createInjector } from '@furystack/inject'
6
6
  import type { OpenApiDocument, WithSchemaAction } from '@furystack/rest'
7
7
  import { createClient, ResponseError } from '@furystack/rest-client-fetch'
8
+ import {
9
+ PasswordCredential,
10
+ PasswordCredentialStore,
11
+ PasswordResetToken,
12
+ PasswordResetTokenStore,
13
+ usePasswordPolicy,
14
+ } from '@furystack/security'
8
15
  import { usingAsync } from '@furystack/utils'
9
16
  import type Ajv from 'ajv'
10
17
  import { describe, expect, it } from 'vitest'
@@ -13,10 +20,11 @@ import { createGetCollectionEndpoint } from './endpoint-generators/create-get-co
13
20
  import { createGetEntityEndpoint } from './endpoint-generators/create-get-entity-endpoint.js'
14
21
  import { createPatchEndpoint } from './endpoint-generators/create-patch-endpoint.js'
15
22
  import { createPostEndpoint } from './endpoint-generators/create-post-endpoint.js'
16
- import { MockClass } from './endpoint-generators/utils.js'
23
+ import { MockDataSet, setupContext } from './endpoint-generators/utils.js'
17
24
  import { useHttpAuthentication, useRestService } from './helpers.js'
18
25
  import { DefaultSession } from './models/default-session.js'
19
26
  import { JsonResult } from './request-action-implementation.js'
27
+ import { SessionStore, UserStore } from './user-store.js'
20
28
  import type { ValidationApi } from './validate.integration.schema.js'
21
29
  import schema from './validate.integration.spec.schema.json' with { type: 'json' }
22
30
  import { Validate } from './validate.js'
@@ -28,15 +36,12 @@ const description = crypto.randomUUID()
28
36
  const version = crypto.randomUUID()
29
37
 
30
38
  const createValidateApi = async (options = { enableGetSchema: false }) => {
31
- const injector = new Injector()
39
+ const injector = createInjector()
32
40
  const port = getPort()
33
41
 
34
- getStoreManager(injector).addStore(new InMemoryStore({ model: User, primaryKey: 'username' }))
35
- getStoreManager(injector).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
36
- getStoreManager(injector).addStore(new InMemoryStore({ model: MockClass, primaryKey: 'id' }))
37
- getRepository(injector).createDataSet(MockClass, 'id')
38
- getRepository(injector).createDataSet(User, 'username')
39
- getRepository(injector).createDataSet(DefaultSession, 'sessionId')
42
+ injector.bind(UserStore, () => new InMemoryStore({ model: UserModel, primaryKey: 'username' }))
43
+ injector.bind(SessionStore, () => new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
44
+ setupContext(injector)
40
45
 
41
46
  const api = await useRestService<ValidationApi>({
42
47
  injector,
@@ -61,11 +66,11 @@ const createValidateApi = async (options = { enableGetSchema: false }) => {
61
66
  '/mock': Validate({
62
67
  schema,
63
68
  schemaName: 'GetMockCollectionEndpoint',
64
- })(createGetCollectionEndpoint({ model: MockClass, primaryKey: 'id' })),
69
+ })(createGetCollectionEndpoint(MockDataSet)),
65
70
  '/mock/:id': Validate({
66
71
  schema,
67
72
  schemaName: 'GetMockEntityEndpoint',
68
- })(createGetEntityEndpoint({ model: MockClass, primaryKey: 'id' })),
73
+ })(createGetEntityEndpoint(MockDataSet)),
69
74
  },
70
75
  POST: {
71
76
  '/validate-body': Validate({
@@ -78,19 +83,19 @@ const createValidateApi = async (options = { enableGetSchema: false }) => {
78
83
  '/mock': Validate({
79
84
  schema,
80
85
  schemaName: 'PostMockEndpoint',
81
- })(createPostEndpoint({ model: MockClass, primaryKey: 'id' })),
86
+ })(createPostEndpoint(MockDataSet)),
82
87
  },
83
88
  PATCH: {
84
89
  '/mock/:id': Validate({
85
90
  schema,
86
91
  schemaName: 'PatchMockEndpoint',
87
- })(createPatchEndpoint({ model: MockClass, primaryKey: 'id' })),
92
+ })(createPatchEndpoint(MockDataSet)),
88
93
  },
89
94
  DELETE: {
90
95
  '/mock/:id': Validate({
91
96
  schema,
92
97
  schemaName: 'DeleteMockEndpoint',
93
- })(createDeleteEndpoint({ model: MockClass, primaryKey: 'id' })),
98
+ })(createDeleteEndpoint(MockDataSet)),
94
99
  },
95
100
  },
96
101
  port,
@@ -447,16 +452,22 @@ describe('Validation integration tests', () => {
447
452
 
448
453
  describe('OpenAPI security schemes from authentication providers', () => {
449
454
  const createApiWithAuth = async () => {
450
- const injector = new Injector()
455
+ const injector = createInjector()
451
456
  const port = getPort()
452
457
 
453
- getStoreManager(injector).addStore(new InMemoryStore({ model: User, primaryKey: 'username' }))
454
- getStoreManager(injector).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
455
- getStoreManager(injector).addStore(new InMemoryStore({ model: MockClass, primaryKey: 'id' }))
456
- getRepository(injector).createDataSet(MockClass, 'id')
457
- getRepository(injector).createDataSet(User, 'username')
458
- getRepository(injector).createDataSet(DefaultSession, 'sessionId')
459
-
458
+ injector.bind(UserStore, () => new InMemoryStore({ model: UserModel, primaryKey: 'username' }))
459
+ injector.bind(SessionStore, () => new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
460
+ injector.bind(
461
+ PasswordCredentialStore,
462
+ () => new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }),
463
+ )
464
+ injector.bind(
465
+ PasswordResetTokenStore,
466
+ () => new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }),
467
+ )
468
+ setupContext(injector)
469
+
470
+ usePasswordPolicy(injector)
460
471
  useHttpAuthentication(injector)
461
472
 
462
473
  await useRestService<ValidationApi>({
@@ -477,10 +488,10 @@ describe('Validation integration tests', () => {
477
488
  JsonResult({ ...headers }),
478
489
  ),
479
490
  '/mock': Validate({ schema, schemaName: 'GetMockCollectionEndpoint' })(
480
- createGetCollectionEndpoint({ model: MockClass, primaryKey: 'id' }),
491
+ createGetCollectionEndpoint(MockDataSet),
481
492
  ),
482
493
  '/mock/:id': Validate({ schema, schemaName: 'GetMockEntityEndpoint' })(
483
- createGetEntityEndpoint({ model: MockClass, primaryKey: 'id' }),
494
+ createGetEntityEndpoint(MockDataSet),
484
495
  ),
485
496
  },
486
497
  POST: {
@@ -488,19 +499,13 @@ describe('Validation integration tests', () => {
488
499
  const body = await getBody()
489
500
  return JsonResult({ ...body })
490
501
  }),
491
- '/mock': Validate({ schema, schemaName: 'PostMockEndpoint' })(
492
- createPostEndpoint({ model: MockClass, primaryKey: 'id' }),
493
- ),
502
+ '/mock': Validate({ schema, schemaName: 'PostMockEndpoint' })(createPostEndpoint(MockDataSet)),
494
503
  },
495
504
  PATCH: {
496
- '/mock/:id': Validate({ schema, schemaName: 'PatchMockEndpoint' })(
497
- createPatchEndpoint({ model: MockClass, primaryKey: 'id' }),
498
- ),
505
+ '/mock/:id': Validate({ schema, schemaName: 'PatchMockEndpoint' })(createPatchEndpoint(MockDataSet)),
499
506
  },
500
507
  DELETE: {
501
- '/mock/:id': Validate({ schema, schemaName: 'DeleteMockEndpoint' })(
502
- createDeleteEndpoint({ model: MockClass, primaryKey: 'id' }),
503
- ),
508
+ '/mock/:id': Validate({ schema, schemaName: 'DeleteMockEndpoint' })(createDeleteEndpoint(MockDataSet)),
504
509
  },
505
510
  },
506
511
  port,
package/src/validate.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import type { ActionResult, RequestAction, RequestActionOptions } from './request-action-implementation.js'
2
+ import type { SchemaValidationError } from './schema-validator/schema-validation-error.js'
2
3
  import { SchemaValidator } from './schema-validator/schema-validator.js'
3
4
 
4
- /**
5
- * Represents a JSON Schema definition structure
6
- */
7
5
  type JsonSchemaDefinition = {
8
6
  required?: string[]
9
7
  additionalProperties?: boolean
@@ -17,22 +15,26 @@ type JsonSchemaDefinition = {
17
15
  [key: string]: unknown
18
16
  }
19
17
 
20
- /**
21
- * Represents a JSON Schema with definitions
22
- */
23
18
  type JsonSchemaWithDefinitions = {
24
19
  definitions: Record<string, JsonSchemaDefinition>
25
20
  }
26
21
 
22
+ /**
23
+ * Wraps a {@link RequestAction} with JSON Schema validation. The wrapper
24
+ * pre-validates `query`, `body`, `url` and `headers` against the named
25
+ * schema entry, throws {@link SchemaValidationError} on failure (caught by
26
+ * `ErrorAction` to return 400), then forwards the validated values to the
27
+ * inner action.
28
+ *
29
+ * The wrapped function exposes `schema` and `schemaName` so OpenAPI
30
+ * generators can reflect on the action without re-parsing the source.
31
+ *
32
+ * `furystack/rest-action-validate-wrapper` enforces this on REST actions.
33
+ */
27
34
  export const Validate =
28
35
  <TSchema extends JsonSchemaWithDefinitions>(validationOptions: {
29
- /**
30
- * The Schema object
31
- */
32
36
  schema: TSchema
33
- /**
34
- * Entity key from the JSON Schema object
35
- */
37
+ /** Entry under `schema.definitions` describing this endpoint's request shape. */
36
38
  schemaName: keyof TSchema['definitions']
37
39
  }) =>
38
40
  <T extends { result: unknown }>(
@@ -1,104 +0,0 @@
1
- import type { Injector } from '@furystack/inject';
2
- import type { Method, RestApi } from '@furystack/rest';
3
- import type { MatchFunction } from 'path-to-regexp';
4
- import type { CorsOptions } from './models/cors-options.js';
5
- import type { RequestAction } from './request-action-implementation.js';
6
- import type { OnRequest } from './server-manager.js';
7
- import './server-response-extensions.js';
8
- export type RestApiImplementation<T extends RestApi> = {
9
- [TMethod in keyof T]: {
10
- [TUrl in keyof T[TMethod]]: T[TMethod][TUrl] extends {
11
- result: unknown;
12
- } ? RequestAction<T[TMethod][TUrl]> : never;
13
- };
14
- };
15
- export interface ImplementApiOptions<T extends RestApi> {
16
- /**
17
- * The structure of the implemented API.
18
- */
19
- api: RestApiImplementation<T>;
20
- /**
21
- * The Injector instance to use for dependency injection in the API actions.
22
- */
23
- injector: Injector;
24
- /**
25
- * The host name for the API Server. If not provided, the default host (ServerManager.DEFAULT_HOST) will be used.
26
- */
27
- hostName?: string;
28
- /**
29
- * The root path for the API. This will be prepended to all API paths.
30
- */
31
- root: string;
32
- /**
33
- * The port on which the API server will listen.
34
- */
35
- port: number;
36
- /**
37
- * CORS options to configure Cross-Origin Resource Sharing for the API.
38
- */
39
- cors?: CorsOptions;
40
- /**
41
- * An optional function to deserialize query parameters from the URL.
42
- * This function should take a query string (e.g., "?key=value") and return an object with the parsed parameters.
43
- * If not provided, the default deserialization will be used.
44
- */
45
- deserializeQueryParams?: (param: string) => any;
46
- /**
47
- * Adds an additional 'GET /schema' endpoint that returns the schema definitions of the API.
48
- * Also adds a 'GET /openapi.json' endpoint that returns the API schema in OpenAPI 3.1 format.
49
- */
50
- enableGetSchema?: boolean;
51
- /**
52
- * Optional name for the API, used in the generated schema.
53
- * This can be useful for documentation or identification purposes.
54
- */
55
- name?: string;
56
- /**
57
- * Optional description for the API, used in the generated schema.
58
- * This can provide additional context or information about the API's purpose.
59
- */
60
- description?: string;
61
- /**
62
- * Optional version for the API, used in the generated schema.
63
- * This can help in versioning the API and tracking changes over time.
64
- */
65
- version?: string;
66
- }
67
- export type NewCompiledApiEntry = {
68
- method: Method;
69
- fullPath: string;
70
- matcher: MatchFunction<Partial<Record<string, string | string[]>>>;
71
- action: RequestAction<any>;
72
- };
73
- export type NewCompiledApi = {
74
- [K in Method]?: NewCompiledApiEntry[];
75
- };
76
- export type OnRequestOptions = OnRequest & {
77
- compiledApi: NewCompiledApi;
78
- hostName?: string;
79
- port: number;
80
- rootApiPath: string;
81
- injector: Injector;
82
- cors?: CorsOptions;
83
- supportedMethods: string[];
84
- deserializeQueryParams?: (param: string) => Record<string, unknown>;
85
- };
86
- export declare class ApiManager {
87
- private getSuportedMethods;
88
- private compileApi;
89
- addApi<T extends RestApi>({ api, hostName, port, root, cors, injector, deserializeQueryParams, enableGetSchema, name, description, version, }: ImplementApiOptions<T>): Promise<{
90
- shouldExec: (msg: OnRequest) => boolean;
91
- onRequest: (msg: OnRequest) => Promise<void>;
92
- }>;
93
- shouldExecRequest(options: {
94
- method?: Method;
95
- url?: string;
96
- rootApiPath: string;
97
- supportedMethods: Method[];
98
- }): boolean;
99
- private getActionFromEndpoint;
100
- private executeAction;
101
- private onMessage;
102
- private readonly serverManager;
103
- }
104
- //# sourceMappingURL=api-manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"api-manager.d.ts","sourceRoot":"","sources":["../src/api-manager.ts"],"names":[],"mappings":"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"}