@furystack/rest-service 13.0.0 → 14.0.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 (224) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +47 -28
  3. package/esm/actions/get-current-user.spec.js +10 -6
  4. package/esm/actions/get-current-user.spec.js.map +1 -1
  5. package/esm/actions/is-authenticated.spec.js +10 -6
  6. package/esm/actions/is-authenticated.spec.js.map +1 -1
  7. package/esm/actions/logout-action.spec.js +11 -9
  8. package/esm/actions/logout-action.spec.js.map +1 -1
  9. package/esm/actions/logout.js +1 -1
  10. package/esm/actions/logout.js.map +1 -1
  11. package/esm/actions/password-login-action.js +1 -1
  12. package/esm/actions/password-login-action.js.map +1 -1
  13. package/esm/actions/password-login-action.spec.js +23 -28
  14. package/esm/actions/password-login-action.spec.js.map +1 -1
  15. package/esm/authenticate.js +1 -1
  16. package/esm/authenticate.js.map +1 -1
  17. package/esm/authenticate.spec.js +41 -33
  18. package/esm/authenticate.spec.js.map +1 -1
  19. package/esm/authorize.spec.js +34 -29
  20. package/esm/authorize.spec.js.map +1 -1
  21. package/esm/endpoint-generators/create-delete-endpoint.d.ts +6 -11
  22. package/esm/endpoint-generators/create-delete-endpoint.d.ts.map +1 -1
  23. package/esm/endpoint-generators/create-delete-endpoint.js +7 -11
  24. package/esm/endpoint-generators/create-delete-endpoint.js.map +1 -1
  25. package/esm/endpoint-generators/create-delete-endpoint.spec.js +14 -21
  26. package/esm/endpoint-generators/create-delete-endpoint.spec.js.map +1 -1
  27. package/esm/endpoint-generators/create-get-collection-endpoint.d.ts +11 -11
  28. package/esm/endpoint-generators/create-get-collection-endpoint.d.ts.map +1 -1
  29. package/esm/endpoint-generators/create-get-collection-endpoint.js +13 -12
  30. package/esm/endpoint-generators/create-get-collection-endpoint.js.map +1 -1
  31. package/esm/endpoint-generators/create-get-collection-endpoint.spec.js +43 -70
  32. package/esm/endpoint-generators/create-get-collection-endpoint.spec.js.map +1 -1
  33. package/esm/endpoint-generators/create-get-entity-endpoint.d.ts +6 -11
  34. package/esm/endpoint-generators/create-get-entity-endpoint.d.ts.map +1 -1
  35. package/esm/endpoint-generators/create-get-entity-endpoint.js +7 -11
  36. package/esm/endpoint-generators/create-get-entity-endpoint.js.map +1 -1
  37. package/esm/endpoint-generators/create-get-entity-endpoint.spec.js +16 -33
  38. package/esm/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
  39. package/esm/endpoint-generators/create-get-openapi-document-action.d.ts +1 -1
  40. package/esm/endpoint-generators/create-get-openapi-document-action.d.ts.map +1 -1
  41. package/esm/endpoint-generators/create-get-openapi-document-action.js +1 -1
  42. package/esm/endpoint-generators/create-get-openapi-document-action.js.map +1 -1
  43. package/esm/endpoint-generators/create-get-schema-action.d.ts +1 -1
  44. package/esm/endpoint-generators/create-get-schema-action.d.ts.map +1 -1
  45. package/esm/endpoint-generators/create-get-schema-action.js.map +1 -1
  46. package/esm/endpoint-generators/create-patch-endpoint.d.ts +7 -13
  47. package/esm/endpoint-generators/create-patch-endpoint.d.ts.map +1 -1
  48. package/esm/endpoint-generators/create-patch-endpoint.js +8 -13
  49. package/esm/endpoint-generators/create-patch-endpoint.js.map +1 -1
  50. package/esm/endpoint-generators/create-patch-endpoint.spec.js +10 -17
  51. package/esm/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
  52. package/esm/endpoint-generators/create-post-endpoint.d.ts +7 -13
  53. package/esm/endpoint-generators/create-post-endpoint.d.ts.map +1 -1
  54. package/esm/endpoint-generators/create-post-endpoint.js +8 -13
  55. package/esm/endpoint-generators/create-post-endpoint.js.map +1 -1
  56. package/esm/endpoint-generators/create-post-endpoint.spec.js +41 -14
  57. package/esm/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
  58. package/esm/endpoint-generators/utils.d.ts +17 -2
  59. package/esm/endpoint-generators/utils.d.ts.map +1 -1
  60. package/esm/endpoint-generators/utils.js +33 -20
  61. package/esm/endpoint-generators/utils.js.map +1 -1
  62. package/esm/get-schema-from-api.d.ts +1 -1
  63. package/esm/get-schema-from-api.d.ts.map +1 -1
  64. package/esm/get-schema-from-api.spec.js.map +1 -1
  65. package/esm/helpers.d.ts +53 -87
  66. package/esm/helpers.d.ts.map +1 -1
  67. package/esm/helpers.js +91 -92
  68. package/esm/helpers.js.map +1 -1
  69. package/esm/helpers.spec.d.ts +2 -1
  70. package/esm/helpers.spec.d.ts.map +1 -1
  71. package/esm/helpers.spec.js +41 -38
  72. package/esm/helpers.spec.js.map +1 -1
  73. package/esm/http-authentication-settings.d.ts +35 -12
  74. package/esm/http-authentication-settings.d.ts.map +1 -1
  75. package/esm/http-authentication-settings.js +21 -29
  76. package/esm/http-authentication-settings.js.map +1 -1
  77. package/esm/http-server-pool.d.ts +64 -0
  78. package/esm/http-server-pool.d.ts.map +1 -0
  79. package/esm/http-server-pool.js +95 -0
  80. package/esm/http-server-pool.js.map +1 -0
  81. package/esm/http-server-pool.spec.d.ts +2 -0
  82. package/esm/http-server-pool.spec.d.ts.map +1 -0
  83. package/esm/http-server-pool.spec.js +193 -0
  84. package/esm/http-server-pool.spec.js.map +1 -0
  85. package/esm/http-user-context.d.ts +31 -44
  86. package/esm/http-user-context.d.ts.map +1 -1
  87. package/esm/http-user-context.js +76 -95
  88. package/esm/http-user-context.js.map +1 -1
  89. package/esm/http-user-context.spec.d.ts +8 -2
  90. package/esm/http-user-context.spec.d.ts.map +1 -1
  91. package/esm/http-user-context.spec.js +189 -337
  92. package/esm/http-user-context.spec.js.map +1 -1
  93. package/esm/index.d.ts +6 -4
  94. package/esm/index.d.ts.map +1 -1
  95. package/esm/index.js +6 -4
  96. package/esm/index.js.map +1 -1
  97. package/esm/login-response-strategy.d.ts +11 -10
  98. package/esm/login-response-strategy.d.ts.map +1 -1
  99. package/esm/login-response-strategy.js +7 -6
  100. package/esm/login-response-strategy.js.map +1 -1
  101. package/esm/login-response-strategy.spec.js +25 -29
  102. package/esm/login-response-strategy.spec.js.map +1 -1
  103. package/esm/proxy-manager.spec.js +152 -176
  104. package/esm/proxy-manager.spec.js.map +1 -1
  105. package/esm/proxy-runtime.d.ts +27 -0
  106. package/esm/proxy-runtime.d.ts.map +1 -0
  107. package/esm/proxy-runtime.js +45 -0
  108. package/esm/proxy-runtime.js.map +1 -0
  109. package/esm/proxy-runtime.spec.d.ts +2 -0
  110. package/esm/proxy-runtime.spec.d.ts.map +1 -0
  111. package/esm/proxy-runtime.spec.js +39 -0
  112. package/esm/proxy-runtime.spec.js.map +1 -0
  113. package/esm/rest-api-runtime.d.ts +76 -0
  114. package/esm/rest-api-runtime.d.ts.map +1 -0
  115. package/esm/rest-api-runtime.js +131 -0
  116. package/esm/rest-api-runtime.js.map +1 -0
  117. package/esm/rest-api-runtime.spec.d.ts +2 -0
  118. package/esm/rest-api-runtime.spec.d.ts.map +1 -0
  119. package/esm/rest-api-runtime.spec.js +58 -0
  120. package/esm/rest-api-runtime.spec.js.map +1 -0
  121. package/esm/rest-service.integration.spec.d.ts +1 -1
  122. package/esm/rest-service.integration.spec.d.ts.map +1 -1
  123. package/esm/rest-service.integration.spec.js +57 -80
  124. package/esm/rest-service.integration.spec.js.map +1 -1
  125. package/esm/rest.integration.test.js +26 -84
  126. package/esm/rest.integration.test.js.map +1 -1
  127. package/esm/server-telemetry.d.ts +57 -0
  128. package/esm/server-telemetry.d.ts.map +1 -0
  129. package/esm/server-telemetry.js +26 -0
  130. package/esm/server-telemetry.js.map +1 -0
  131. package/esm/server-telemetry.spec.d.ts +2 -0
  132. package/esm/server-telemetry.spec.d.ts.map +1 -0
  133. package/esm/server-telemetry.spec.js +52 -0
  134. package/esm/server-telemetry.spec.js.map +1 -0
  135. package/esm/static-server-manager.spec.js +60 -125
  136. package/esm/static-server-manager.spec.js.map +1 -1
  137. package/esm/static-site-runtime.d.ts +21 -0
  138. package/esm/static-site-runtime.d.ts.map +1 -0
  139. package/esm/static-site-runtime.js +48 -0
  140. package/esm/static-site-runtime.js.map +1 -0
  141. package/esm/static-site-runtime.spec.d.ts +2 -0
  142. package/esm/static-site-runtime.spec.d.ts.map +1 -0
  143. package/esm/static-site-runtime.spec.js +30 -0
  144. package/esm/static-site-runtime.spec.js.map +1 -0
  145. package/esm/user-store.d.ts +39 -0
  146. package/esm/user-store.d.ts.map +1 -0
  147. package/esm/user-store.js +62 -0
  148. package/esm/user-store.js.map +1 -0
  149. package/esm/user-store.spec.d.ts +2 -0
  150. package/esm/user-store.spec.d.ts.map +1 -0
  151. package/esm/user-store.spec.js +72 -0
  152. package/esm/user-store.spec.js.map +1 -0
  153. package/esm/validate.integration.spec.js +26 -28
  154. package/esm/validate.integration.spec.js.map +1 -1
  155. package/package.json +8 -8
  156. package/src/actions/get-current-user.spec.ts +11 -10
  157. package/src/actions/is-authenticated.spec.ts +12 -7
  158. package/src/actions/logout-action.spec.ts +12 -12
  159. package/src/actions/logout.ts +1 -1
  160. package/src/actions/password-login-action.spec.ts +30 -30
  161. package/src/actions/password-login-action.ts +1 -1
  162. package/src/authenticate.spec.ts +45 -51
  163. package/src/authenticate.ts +1 -1
  164. package/src/authorize.spec.ts +37 -39
  165. package/src/endpoint-generators/create-delete-endpoint.spec.ts +16 -24
  166. package/src/endpoint-generators/create-delete-endpoint.ts +11 -17
  167. package/src/endpoint-generators/create-get-collection-endpoint.spec.ts +45 -78
  168. package/src/endpoint-generators/create-get-collection-endpoint.ts +17 -19
  169. package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +17 -33
  170. package/src/endpoint-generators/create-get-entity-endpoint.ts +11 -17
  171. package/src/endpoint-generators/create-get-openapi-document-action.ts +2 -2
  172. package/src/endpoint-generators/create-get-schema-action.ts +1 -1
  173. package/src/endpoint-generators/create-patch-endpoint.spec.ts +11 -18
  174. package/src/endpoint-generators/create-patch-endpoint.ts +12 -23
  175. package/src/endpoint-generators/create-post-endpoint.spec.ts +45 -14
  176. package/src/endpoint-generators/create-post-endpoint.ts +13 -23
  177. package/src/endpoint-generators/utils.ts +36 -28
  178. package/src/get-schema-from-api.spec.ts +1 -1
  179. package/src/get-schema-from-api.ts +1 -1
  180. package/src/helpers.spec.ts +51 -41
  181. package/src/helpers.ts +140 -109
  182. package/src/http-authentication-settings.ts +51 -25
  183. package/src/http-server-pool.spec.ts +220 -0
  184. package/src/http-server-pool.ts +169 -0
  185. package/src/http-user-context.spec.ts +203 -383
  186. package/src/http-user-context.ts +114 -91
  187. package/src/index.ts +6 -4
  188. package/src/login-response-strategy.spec.ts +32 -31
  189. package/src/login-response-strategy.ts +13 -12
  190. package/src/proxy-manager.spec.ts +152 -182
  191. package/src/proxy-runtime.spec.ts +50 -0
  192. package/src/proxy-runtime.ts +75 -0
  193. package/src/rest-api-runtime.spec.ts +77 -0
  194. package/src/rest-api-runtime.ts +204 -0
  195. package/src/rest-service.integration.spec.ts +65 -85
  196. package/src/rest.integration.test.ts +27 -87
  197. package/src/server-telemetry.spec.ts +56 -0
  198. package/src/server-telemetry.ts +51 -0
  199. package/src/static-server-manager.spec.ts +63 -151
  200. package/src/static-site-runtime.spec.ts +39 -0
  201. package/src/static-site-runtime.ts +75 -0
  202. package/src/user-store.spec.ts +86 -0
  203. package/src/user-store.ts +68 -0
  204. package/src/validate.integration.spec.ts +39 -35
  205. package/esm/api-manager.d.ts +0 -104
  206. package/esm/api-manager.d.ts.map +0 -1
  207. package/esm/api-manager.js +0 -179
  208. package/esm/api-manager.js.map +0 -1
  209. package/esm/proxy-manager.d.ts +0 -53
  210. package/esm/proxy-manager.d.ts.map +0 -1
  211. package/esm/proxy-manager.js +0 -84
  212. package/esm/proxy-manager.js.map +0 -1
  213. package/esm/server-manager.d.ts +0 -48
  214. package/esm/server-manager.d.ts.map +0 -1
  215. package/esm/server-manager.js +0 -100
  216. package/esm/server-manager.js.map +0 -1
  217. package/esm/static-server-manager.d.ts +0 -19
  218. package/esm/static-server-manager.d.ts.map +0 -1
  219. package/esm/static-server-manager.js +0 -65
  220. package/esm/static-server-manager.js.map +0 -1
  221. package/src/api-manager.ts +0 -304
  222. package/src/proxy-manager.ts +0 -102
  223. package/src/server-manager.ts +0 -135
  224. package/src/static-server-manager.ts +0 -90
@@ -1,10 +1,16 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
- import { getStoreManager, InMemoryStore, User } from '@furystack/core'
2
+ import { InMemoryStore, User as UserModel } from '@furystack/core'
3
3
  import { getPort } from '@furystack/core/port-generator'
4
- import { Injector } from '@furystack/inject'
5
- import { getRepository } from '@furystack/repository'
4
+ import { createInjector } from '@furystack/inject'
6
5
  import type { OpenApiDocument, WithSchemaAction } from '@furystack/rest'
7
6
  import { createClient, ResponseError } from '@furystack/rest-client-fetch'
7
+ import {
8
+ PasswordCredential,
9
+ PasswordCredentialStore,
10
+ PasswordResetToken,
11
+ PasswordResetTokenStore,
12
+ usePasswordPolicy,
13
+ } from '@furystack/security'
8
14
  import { usingAsync } from '@furystack/utils'
9
15
  import type Ajv from 'ajv'
10
16
  import { describe, expect, it } from 'vitest'
@@ -13,10 +19,11 @@ import { createGetCollectionEndpoint } from './endpoint-generators/create-get-co
13
19
  import { createGetEntityEndpoint } from './endpoint-generators/create-get-entity-endpoint.js'
14
20
  import { createPatchEndpoint } from './endpoint-generators/create-patch-endpoint.js'
15
21
  import { createPostEndpoint } from './endpoint-generators/create-post-endpoint.js'
16
- import { MockClass } from './endpoint-generators/utils.js'
22
+ import { MockDataSet, setupContext } from './endpoint-generators/utils.js'
17
23
  import { useHttpAuthentication, useRestService } from './helpers.js'
18
24
  import { DefaultSession } from './models/default-session.js'
19
25
  import { JsonResult } from './request-action-implementation.js'
26
+ import { SessionStore, UserStore } from './user-store.js'
20
27
  import type { ValidationApi } from './validate.integration.schema.js'
21
28
  import schema from './validate.integration.spec.schema.json' with { type: 'json' }
22
29
  import { Validate } from './validate.js'
@@ -28,15 +35,12 @@ const description = crypto.randomUUID()
28
35
  const version = crypto.randomUUID()
29
36
 
30
37
  const createValidateApi = async (options = { enableGetSchema: false }) => {
31
- const injector = new Injector()
38
+ const injector = createInjector()
32
39
  const port = getPort()
33
40
 
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')
41
+ injector.bind(UserStore, () => new InMemoryStore({ model: UserModel, primaryKey: 'username' }))
42
+ injector.bind(SessionStore, () => new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
43
+ setupContext(injector)
40
44
 
41
45
  const api = await useRestService<ValidationApi>({
42
46
  injector,
@@ -61,11 +65,11 @@ const createValidateApi = async (options = { enableGetSchema: false }) => {
61
65
  '/mock': Validate({
62
66
  schema,
63
67
  schemaName: 'GetMockCollectionEndpoint',
64
- })(createGetCollectionEndpoint({ model: MockClass, primaryKey: 'id' })),
68
+ })(createGetCollectionEndpoint(MockDataSet)),
65
69
  '/mock/:id': Validate({
66
70
  schema,
67
71
  schemaName: 'GetMockEntityEndpoint',
68
- })(createGetEntityEndpoint({ model: MockClass, primaryKey: 'id' })),
72
+ })(createGetEntityEndpoint(MockDataSet)),
69
73
  },
70
74
  POST: {
71
75
  '/validate-body': Validate({
@@ -78,19 +82,19 @@ const createValidateApi = async (options = { enableGetSchema: false }) => {
78
82
  '/mock': Validate({
79
83
  schema,
80
84
  schemaName: 'PostMockEndpoint',
81
- })(createPostEndpoint({ model: MockClass, primaryKey: 'id' })),
85
+ })(createPostEndpoint(MockDataSet)),
82
86
  },
83
87
  PATCH: {
84
88
  '/mock/:id': Validate({
85
89
  schema,
86
90
  schemaName: 'PatchMockEndpoint',
87
- })(createPatchEndpoint({ model: MockClass, primaryKey: 'id' })),
91
+ })(createPatchEndpoint(MockDataSet)),
88
92
  },
89
93
  DELETE: {
90
94
  '/mock/:id': Validate({
91
95
  schema,
92
96
  schemaName: 'DeleteMockEndpoint',
93
- })(createDeleteEndpoint({ model: MockClass, primaryKey: 'id' })),
97
+ })(createDeleteEndpoint(MockDataSet)),
94
98
  },
95
99
  },
96
100
  port,
@@ -447,16 +451,22 @@ describe('Validation integration tests', () => {
447
451
 
448
452
  describe('OpenAPI security schemes from authentication providers', () => {
449
453
  const createApiWithAuth = async () => {
450
- const injector = new Injector()
454
+ const injector = createInjector()
451
455
  const port = getPort()
452
456
 
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
-
457
+ injector.bind(UserStore, () => new InMemoryStore({ model: UserModel, primaryKey: 'username' }))
458
+ injector.bind(SessionStore, () => new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
459
+ injector.bind(
460
+ PasswordCredentialStore,
461
+ () => new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }),
462
+ )
463
+ injector.bind(
464
+ PasswordResetTokenStore,
465
+ () => new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }),
466
+ )
467
+ setupContext(injector)
468
+
469
+ usePasswordPolicy(injector)
460
470
  useHttpAuthentication(injector)
461
471
 
462
472
  await useRestService<ValidationApi>({
@@ -477,10 +487,10 @@ describe('Validation integration tests', () => {
477
487
  JsonResult({ ...headers }),
478
488
  ),
479
489
  '/mock': Validate({ schema, schemaName: 'GetMockCollectionEndpoint' })(
480
- createGetCollectionEndpoint({ model: MockClass, primaryKey: 'id' }),
490
+ createGetCollectionEndpoint(MockDataSet),
481
491
  ),
482
492
  '/mock/:id': Validate({ schema, schemaName: 'GetMockEntityEndpoint' })(
483
- createGetEntityEndpoint({ model: MockClass, primaryKey: 'id' }),
493
+ createGetEntityEndpoint(MockDataSet),
484
494
  ),
485
495
  },
486
496
  POST: {
@@ -488,19 +498,13 @@ describe('Validation integration tests', () => {
488
498
  const body = await getBody()
489
499
  return JsonResult({ ...body })
490
500
  }),
491
- '/mock': Validate({ schema, schemaName: 'PostMockEndpoint' })(
492
- createPostEndpoint({ model: MockClass, primaryKey: 'id' }),
493
- ),
501
+ '/mock': Validate({ schema, schemaName: 'PostMockEndpoint' })(createPostEndpoint(MockDataSet)),
494
502
  },
495
503
  PATCH: {
496
- '/mock/:id': Validate({ schema, schemaName: 'PatchMockEndpoint' })(
497
- createPatchEndpoint({ model: MockClass, primaryKey: 'id' }),
498
- ),
504
+ '/mock/:id': Validate({ schema, schemaName: 'PatchMockEndpoint' })(createPatchEndpoint(MockDataSet)),
499
505
  },
500
506
  DELETE: {
501
- '/mock/:id': Validate({ schema, schemaName: 'DeleteMockEndpoint' })(
502
- createDeleteEndpoint({ model: MockClass, primaryKey: 'id' }),
503
- ),
507
+ '/mock/:id': Validate({ schema, schemaName: 'DeleteMockEndpoint' })(createDeleteEndpoint(MockDataSet)),
504
508
  },
505
509
  },
506
510
  port,
@@ -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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"}
@@ -1,179 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- import { IdentityContext } from '@furystack/core';
11
- import { Injectable, Injected } from '@furystack/inject';
12
- import { RequestError, deserializeQueryString } from '@furystack/rest';
13
- import { PathHelper, usingAsync } from '@furystack/utils';
14
- import { match } from 'path-to-regexp';
15
- import { ErrorAction } from './actions/error-action.js';
16
- import { NotFoundAction } from './actions/not-found-action.js';
17
- import { addCorsHeaders } from './add-cors-header.js';
18
- import { CreateGetSchemaAction } from './endpoint-generators/create-get-schema-action.js';
19
- import { CreateGetOpenApiDocumentAction } from './endpoint-generators/create-get-openapi-document-action.js';
20
- import { HttpUserContext } from './http-user-context.js';
21
- import { readPostBody } from './read-post-body.js';
22
- import { ServerManager } from './server-manager.js';
23
- import './server-response-extensions.js';
24
- let ApiManager = class ApiManager {
25
- getSuportedMethods(api) {
26
- return Object.keys(api);
27
- }
28
- compileApi(api, root) {
29
- const supportedMethods = this.getSuportedMethods(api);
30
- const compiledApi = {};
31
- supportedMethods.forEach((method) => {
32
- compiledApi[method] = [
33
- ...Object.entries(api[method]).map(([path, action]) => {
34
- const fullPath = `/${PathHelper.normalize(PathHelper.joinPaths(root, path))}`;
35
- const matcher = match(fullPath, { decode: decodeURIComponent });
36
- return { method, fullPath, matcher, action: action };
37
- }),
38
- ];
39
- });
40
- return compiledApi;
41
- }
42
- async addApi({ api, hostName, port, root, cors, injector, deserializeQueryParams, enableGetSchema, name, description, version, }) {
43
- const extendedApi = enableGetSchema
44
- ? {
45
- ...api,
46
- GET: {
47
- ...api.GET,
48
- '/schema': CreateGetSchemaAction(api, name, description, version),
49
- '/openapi.json': CreateGetOpenApiDocumentAction(api, name, description, version),
50
- },
51
- }
52
- : api;
53
- const supportedMethods = this.getSuportedMethods(extendedApi);
54
- const rootApiPath = PathHelper.normalize(root);
55
- const server = await this.serverManager.getOrCreate({ hostName, port });
56
- const compiledApi = this.compileApi(extendedApi, root);
57
- const serverApi = {
58
- shouldExec: (msg) => this.shouldExecRequest({
59
- ...msg,
60
- method: msg.req.method?.toUpperCase(),
61
- rootApiPath,
62
- supportedMethods,
63
- url: PathHelper.normalize(msg.req.url || ''),
64
- }),
65
- onRequest: (msg) => this.onMessage({
66
- ...msg,
67
- compiledApi,
68
- rootApiPath,
69
- port,
70
- supportedMethods,
71
- cors,
72
- injector,
73
- hostName,
74
- deserializeQueryParams,
75
- }),
76
- };
77
- server.apis.push(serverApi);
78
- return serverApi;
79
- }
80
- shouldExecRequest(options) {
81
- return options.method &&
82
- options.url &&
83
- (options.supportedMethods.includes(options.method) || options.method === 'OPTIONS') &&
84
- PathHelper.matchesBaseUrl(options.url, options.rootApiPath)
85
- ? true
86
- : false;
87
- }
88
- getActionFromEndpoint(compiledEndpoint, fullUrl, method) {
89
- let resolvedParams;
90
- const action = compiledEndpoint[method]?.find((route) => {
91
- const result = route.matcher(fullUrl.pathname);
92
- if (result) {
93
- resolvedParams = result.params;
94
- }
95
- return result;
96
- });
97
- return (action && {
98
- ...action,
99
- params: resolvedParams,
100
- });
101
- }
102
- async executeAction({ injector, req, res, fullUrl, action, deserializeQueryParams, params, }) {
103
- await usingAsync(injector.createChild({ owner: action }), async (i) => {
104
- const httpUserContext = i.getInstance(HttpUserContext);
105
- i.setExplicitInstance({
106
- getCurrentUser: () => httpUserContext.getCurrentUser(req),
107
- isAuthorized: (...roles) => httpUserContext.isAuthorized(req, ...roles),
108
- isAuthenticated: () => httpUserContext.isAuthenticated(req),
109
- }, IdentityContext);
110
- try {
111
- const actionResult = await action({
112
- request: req,
113
- response: res,
114
- injector: i,
115
- getBody: () => readPostBody(req),
116
- headers: req.headers,
117
- getQuery: () => deserializeQueryParams ? deserializeQueryParams(fullUrl.search) : deserializeQueryString(fullUrl.search),
118
- getUrlParams: () => {
119
- return params;
120
- },
121
- });
122
- res.sendActionResult(actionResult);
123
- }
124
- catch (error) {
125
- const errorActionResult = await ErrorAction({
126
- request: req,
127
- response: res,
128
- injector: i,
129
- getBody: async () => error,
130
- });
131
- res.sendActionResult(errorActionResult);
132
- }
133
- return;
134
- });
135
- }
136
- async onMessage(options) {
137
- const protocol = 'http://';
138
- const host = `${options.hostName || ServerManager.DEFAULT_HOST}:${options.port}`;
139
- const fullUrl = new URL(PathHelper.joinUrl(`${protocol}${host}`, options.req.url));
140
- if (options.cors) {
141
- addCorsHeaders(options.cors, options.req, options.res);
142
- }
143
- if (options.req.method === 'OPTIONS') {
144
- options.res.writeHead(200);
145
- options.res.end();
146
- return;
147
- }
148
- let action;
149
- try {
150
- action = this.getActionFromEndpoint(options.compiledApi, fullUrl, options.req.method?.toUpperCase());
151
- }
152
- catch (error) {
153
- const responseError = error instanceof URIError ? new RequestError('Failed to decode URL path parameter', 400) : error;
154
- const errorActionResult = await ErrorAction({
155
- request: options.req,
156
- response: options.res,
157
- injector: options.injector,
158
- getBody: async () => responseError,
159
- });
160
- options.res.sendActionResult(errorActionResult);
161
- return;
162
- }
163
- if (action) {
164
- await this.executeAction({ ...options, ...action, fullUrl });
165
- }
166
- else {
167
- options.res.sendActionResult(await NotFoundAction({ injector: options.injector, request: options.req, response: options.res }));
168
- }
169
- }
170
- };
171
- __decorate([
172
- Injected(ServerManager),
173
- __metadata("design:type", ServerManager)
174
- ], ApiManager.prototype, "serverManager", void 0);
175
- ApiManager = __decorate([
176
- Injectable({ lifetime: 'singleton' })
177
- ], ApiManager);
178
- export { ApiManager };
179
- //# sourceMappingURL=api-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"api-manager.js","sourceRoot":"","sources":["../src/api-manager.ts"],"names":[],"mappings":"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"}
@@ -1,53 +0,0 @@
1
- import { EventHub, type ListenerErrorPayload } from '@furystack/utils';
2
- import type { IncomingMessage, OutgoingHttpHeaders } from 'http';
3
- export interface ProxyOptions {
4
- sourceBaseUrl: string;
5
- targetBaseUrl: string;
6
- pathRewrite?: (sourcePath: string) => string;
7
- sourceHostName?: string;
8
- sourcePort: number;
9
- headers?: (originalHeaders: OutgoingHttpHeaders) => OutgoingHttpHeaders;
10
- cookies?: (originalCookies: string[]) => string[];
11
- responseCookies?: (responseCookies: string[]) => string[];
12
- timeout?: number;
13
- enableWebsockets?: boolean;
14
- }
15
- /**
16
- * Manages HTTP and WebSocket proxy configurations and routing
17
- */
18
- export declare class ProxyManager extends EventHub<{
19
- onProxyFailed: {
20
- from: string;
21
- to: string;
22
- error: unknown;
23
- };
24
- onWebSocketProxyFailed: {
25
- from: string;
26
- to: string;
27
- error: unknown;
28
- };
29
- onListenerError: ListenerErrorPayload;
30
- }> {
31
- private readonly serverManager;
32
- private readonly pathProcessor;
33
- /**
34
- * Creates a function that determines if a request should be handled by this proxy
35
- */
36
- shouldExec: (sourceBaseUrl: string) => ({ req }: {
37
- req: Pick<IncomingMessage, "url" | "method">;
38
- }) => boolean;
39
- /**
40
- * Creates an HTTP request handler for the proxy
41
- */
42
- private createRequestHandler;
43
- /**
44
- * Creates a WebSocket upgrade handler for the proxy
45
- */
46
- private createUpgradeHandler;
47
- /**
48
- * Adds a new proxy configuration
49
- * @throws Error if targetBaseUrl is invalid or uses non-HTTP/HTTPS protocol
50
- */
51
- addProxy(options: ProxyOptions): Promise<void>;
52
- }
53
- //# sourceMappingURL=proxy-manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../src/proxy-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAc,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAkB,MAAM,MAAM,CAAA;AAOhF,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAA;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,mBAAmB,KAAK,mBAAmB,CAAA;IACvE,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA;IACjD,eAAe,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA;IACzD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;GAEG;AACH,qBACa,YAAa,SAAQ,QAAQ,CAAC;IACzC,aAAa,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IAC3D,sBAAsB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IACpE,eAAe,EAAE,oBAAoB,CAAA;CACtC,CAAC;IACA,iBACyB,aAAa,CAAe;IAErD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IAEpD;;OAEG;IACI,UAAU,GACd,eAAe,MAAM,MACrB,SAAS;QAAE,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAA;KAAE,aACW;IAEvE;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;;OAGG;IACU,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAe5D"}
@@ -1,84 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- import { Injectable, Injected } from '@furystack/inject';
11
- import { EventHub, PathHelper } from '@furystack/utils';
12
- import { HttpProxyHandler } from './http-proxy-handler.js';
13
- import { PathProcessor } from './path-processor.js';
14
- import { ServerManager } from './server-manager.js';
15
- import { WebSocketProxyHandler } from './websocket-proxy-handler.js';
16
- /**
17
- * Manages HTTP and WebSocket proxy configurations and routing
18
- */
19
- let ProxyManager = class ProxyManager extends EventHub {
20
- pathProcessor = new PathProcessor();
21
- /**
22
- * Creates a function that determines if a request should be handled by this proxy
23
- */
24
- shouldExec = (sourceBaseUrl) => ({ req }) => req.url ? PathHelper.matchesBaseUrl(req.url, sourceBaseUrl) : false;
25
- /**
26
- * Creates an HTTP request handler for the proxy
27
- */
28
- createRequestHandler(options) {
29
- const handler = new HttpProxyHandler({
30
- sourceBaseUrl: options.sourceBaseUrl,
31
- targetBaseUrl: options.targetBaseUrl,
32
- pathRewrite: options.pathRewrite,
33
- headers: options.headers,
34
- cookies: options.cookies,
35
- responseCookies: options.responseCookies,
36
- timeout: options.timeout,
37
- onError: (error) => this.emit('onProxyFailed', error),
38
- });
39
- return async ({ req, res }) => {
40
- await handler.handle(req, res);
41
- };
42
- }
43
- /**
44
- * Creates a WebSocket upgrade handler for the proxy
45
- */
46
- createUpgradeHandler(options) {
47
- const handler = new WebSocketProxyHandler({
48
- sourceBaseUrl: options.sourceBaseUrl,
49
- targetBaseUrl: options.targetBaseUrl,
50
- pathRewrite: options.pathRewrite,
51
- headers: options.headers,
52
- timeout: options.timeout,
53
- onError: (error) => this.emit('onWebSocketProxyFailed', error),
54
- });
55
- return async ({ req, socket, head }) => {
56
- await handler.handle(req, socket, head);
57
- };
58
- }
59
- /**
60
- * Adds a new proxy configuration
61
- * @throws Error if targetBaseUrl is invalid or uses non-HTTP/HTTPS protocol
62
- */
63
- async addProxy(options) {
64
- // Validate targetBaseUrl format
65
- const url = this.pathProcessor.validateUrl(options.targetBaseUrl, 'targetBaseUrl');
66
- this.pathProcessor.validateHttpProtocol(url);
67
- const server = await this.serverManager.getOrCreate({ hostName: options.sourceHostName, port: options.sourcePort });
68
- const api = {
69
- shouldExec: this.shouldExec(options.sourceBaseUrl),
70
- onRequest: this.createRequestHandler(options),
71
- ...(options.enableWebsockets ? { onUpgrade: this.createUpgradeHandler(options) } : {}),
72
- };
73
- server.apis.push(api);
74
- }
75
- };
76
- __decorate([
77
- Injected(ServerManager),
78
- __metadata("design:type", ServerManager)
79
- ], ProxyManager.prototype, "serverManager", void 0);
80
- ProxyManager = __decorate([
81
- Injectable({ lifetime: 'singleton' })
82
- ], ProxyManager);
83
- export { ProxyManager };
84
- //# sourceMappingURL=proxy-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"proxy-manager.js","sourceRoot":"","sources":["../src/proxy-manager.ts"],"names":[],"mappings":"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"}
@@ -1,48 +0,0 @@
1
- import { EventHub, type ListenerErrorPayload } from '@furystack/utils';
2
- import type { IncomingMessage, Server, ServerResponse } from 'http';
3
- import type { Duplex } from 'stream';
4
- export interface ServerOptions {
5
- hostName?: string;
6
- port: number;
7
- }
8
- export interface OnRequest {
9
- req: IncomingMessage;
10
- res: ServerResponse;
11
- }
12
- export interface OnUpgrade {
13
- req: IncomingMessage;
14
- socket: Duplex;
15
- head: Buffer;
16
- }
17
- export interface ServerApi {
18
- shouldExec: (options: OnRequest) => boolean;
19
- onRequest: (options: OnRequest) => Promise<void>;
20
- onUpgrade?: (options: OnUpgrade) => Promise<void>;
21
- }
22
- export interface ServerRecord {
23
- server: Server;
24
- apis: ServerApi[];
25
- }
26
- export declare class ServerManager extends EventHub<{
27
- onRequestFailed: [unknown, IncomingMessage, ServerResponse<IncomingMessage>];
28
- onServerListening: {
29
- url: string;
30
- port: number;
31
- hostName?: string;
32
- };
33
- onServerClosed: {
34
- url: string;
35
- };
36
- onListenerError: ListenerErrorPayload;
37
- }> implements AsyncDisposable {
38
- static DEFAULT_HOST: string;
39
- servers: Map<string, ServerRecord>;
40
- private openedSockets;
41
- private readonly pendingCreates;
42
- private getHostUrl;
43
- private onConnection;
44
- [Symbol.asyncDispose](): Promise<void>;
45
- getOrCreate(options: ServerOptions): Promise<ServerRecord>;
46
- private createServer;
47
- }
48
- //# sourceMappingURL=server-manager.d.ts.map