@furystack/rest-service 5.0.3 → 6.0.1

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 (203) hide show
  1. package/dist/actions/get-current-user.js +2 -1
  2. package/dist/actions/get-current-user.js.map +1 -1
  3. package/dist/actions/is-authenticated.js +3 -2
  4. package/dist/actions/is-authenticated.js.map +1 -1
  5. package/dist/actions/login.js +1 -1
  6. package/dist/actions/login.js.map +1 -1
  7. package/dist/authenticate.js +4 -4
  8. package/dist/authenticate.js.map +1 -1
  9. package/dist/authorize.js +2 -1
  10. package/dist/authorize.js.map +1 -1
  11. package/dist/endpoint-generators/create-delete-endpoint.js +2 -1
  12. package/dist/endpoint-generators/create-delete-endpoint.js.map +1 -1
  13. package/dist/endpoint-generators/create-delete-endpoint.spec.js +7 -4
  14. package/dist/endpoint-generators/create-delete-endpoint.spec.js.map +1 -1
  15. package/dist/endpoint-generators/create-get-collection-endpoint.js +2 -1
  16. package/dist/endpoint-generators/create-get-collection-endpoint.js.map +1 -1
  17. package/dist/endpoint-generators/create-get-collection-endpoint.spec.js +23 -16
  18. package/dist/endpoint-generators/create-get-collection-endpoint.spec.js.map +1 -1
  19. package/dist/endpoint-generators/create-get-entity-endpoint.js +2 -1
  20. package/dist/endpoint-generators/create-get-entity-endpoint.js.map +1 -1
  21. package/dist/endpoint-generators/create-get-entity-endpoint.spec.js +10 -5
  22. package/dist/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
  23. package/dist/endpoint-generators/create-patch-endpoint.js +2 -1
  24. package/dist/endpoint-generators/create-patch-endpoint.js.map +1 -1
  25. package/dist/endpoint-generators/create-patch-endpoint.spec.js +7 -4
  26. package/dist/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
  27. package/dist/endpoint-generators/create-post-endpoint.js +2 -1
  28. package/dist/endpoint-generators/create-post-endpoint.js.map +1 -1
  29. package/dist/endpoint-generators/create-post-endpoint.spec.js +5 -2
  30. package/dist/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
  31. package/dist/endpoint-generators/utils.js +5 -4
  32. package/dist/endpoint-generators/utils.js.map +1 -1
  33. package/dist/helpers.js +25 -0
  34. package/dist/helpers.js.map +1 -0
  35. package/dist/helpers.spec.js +19 -0
  36. package/dist/helpers.spec.js.map +1 -0
  37. package/dist/http-user-context.js +2 -2
  38. package/dist/http-user-context.js.map +1 -1
  39. package/dist/http-user-context.spec.js +4 -6
  40. package/dist/http-user-context.spec.js.map +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/rest-service.integration.spec.js +33 -32
  44. package/dist/rest-service.integration.spec.js.map +1 -1
  45. package/dist/rest.integration.test.js +7 -6
  46. package/dist/rest.integration.test.js.map +1 -1
  47. package/dist/validate.integration.spec.js +4 -2
  48. package/dist/validate.integration.spec.js.map +1 -1
  49. package/package.json +14 -15
  50. package/src/actions/get-current-user.ts +2 -2
  51. package/src/actions/is-authenticated.ts +3 -2
  52. package/src/actions/login.ts +1 -1
  53. package/src/authenticate.ts +4 -4
  54. package/src/authorize.ts +2 -1
  55. package/src/endpoint-generators/create-delete-endpoint.spec.ts +7 -4
  56. package/src/endpoint-generators/create-delete-endpoint.ts +2 -1
  57. package/src/endpoint-generators/create-get-collection-endpoint.spec.ts +23 -16
  58. package/src/endpoint-generators/create-get-collection-endpoint.ts +2 -1
  59. package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +10 -5
  60. package/src/endpoint-generators/create-get-entity-endpoint.ts +2 -1
  61. package/src/endpoint-generators/create-patch-endpoint.spec.ts +7 -4
  62. package/src/endpoint-generators/create-patch-endpoint.ts +2 -1
  63. package/src/endpoint-generators/create-post-endpoint.spec.ts +5 -2
  64. package/src/endpoint-generators/create-post-endpoint.ts +2 -1
  65. package/src/endpoint-generators/utils.ts +23 -23
  66. package/src/helpers.spec.ts +24 -0
  67. package/src/helpers.ts +28 -0
  68. package/src/http-user-context.spec.ts +6 -10
  69. package/src/http-user-context.ts +3 -3
  70. package/src/index.ts +1 -1
  71. package/src/rest-service.integration.spec.ts +36 -36
  72. package/src/rest.integration.test.ts +7 -6
  73. package/src/validate.integration.spec.ts +5 -3
  74. package/{dist → types}/actions/error-action.d.ts +0 -0
  75. package/{dist → types}/actions/error-action.d.ts.map +0 -0
  76. package/{dist → types}/actions/error-action.spec.d.ts +0 -0
  77. package/{dist → types}/actions/error-action.spec.d.ts.map +0 -0
  78. package/{dist → types}/actions/get-current-user.d.ts +0 -0
  79. package/types/actions/get-current-user.d.ts.map +1 -0
  80. package/{dist → types}/actions/get-current-user.spec.d.ts +0 -0
  81. package/{dist → types}/actions/get-current-user.spec.d.ts.map +0 -0
  82. package/{dist → types}/actions/index.d.ts +0 -0
  83. package/{dist → types}/actions/index.d.ts.map +0 -0
  84. package/{dist → types}/actions/is-authenticated.d.ts +0 -0
  85. package/{dist → types}/actions/is-authenticated.d.ts.map +1 -1
  86. package/{dist → types}/actions/is-authenticated.spec.d.ts +0 -0
  87. package/{dist → types}/actions/is-authenticated.spec.d.ts.map +0 -0
  88. package/{dist → types}/actions/login-action.spec.d.ts +0 -0
  89. package/{dist → types}/actions/login-action.spec.d.ts.map +0 -0
  90. package/{dist → types}/actions/login.d.ts +1 -1
  91. package/types/actions/login.d.ts.map +1 -0
  92. package/{dist → types}/actions/logout-action.spec.d.ts +0 -0
  93. package/{dist → types}/actions/logout-action.spec.d.ts.map +0 -0
  94. package/{dist → types}/actions/logout.d.ts +0 -0
  95. package/{dist → types}/actions/logout.d.ts.map +0 -0
  96. package/{dist → types}/actions/not-found-action.d.ts +0 -0
  97. package/{dist → types}/actions/not-found-action.d.ts.map +0 -0
  98. package/{dist → types}/actions/not-found-action.spec.d.ts +0 -0
  99. package/{dist → types}/actions/not-found-action.spec.d.ts.map +0 -0
  100. package/{dist → types}/add-cors-header.spec.d.ts +0 -0
  101. package/{dist → types}/add-cors-header.spec.d.ts.map +0 -0
  102. package/{dist → types}/api-manager.d.ts +0 -0
  103. package/{dist → types}/api-manager.d.ts.map +0 -0
  104. package/{dist → types}/authenticate.d.ts +0 -0
  105. package/{dist → types}/authenticate.d.ts.map +1 -1
  106. package/{dist → types}/authenticate.spec.d.ts +0 -0
  107. package/{dist → types}/authenticate.spec.d.ts.map +0 -0
  108. package/{dist → types}/authorize.d.ts +0 -0
  109. package/{dist → types}/authorize.d.ts.map +1 -1
  110. package/{dist → types}/authorize.spec.d.ts +0 -0
  111. package/{dist → types}/authorize.spec.d.ts.map +0 -0
  112. package/{dist → types}/endpoint-generators/create-delete-endpoint.d.ts +0 -0
  113. package/{dist → types}/endpoint-generators/create-delete-endpoint.d.ts.map +1 -1
  114. package/{dist → types}/endpoint-generators/create-delete-endpoint.spec.d.ts +0 -0
  115. package/{dist → types}/endpoint-generators/create-delete-endpoint.spec.d.ts.map +0 -0
  116. package/{dist → types}/endpoint-generators/create-get-collection-endpoint.d.ts +0 -0
  117. package/{dist → types}/endpoint-generators/create-get-collection-endpoint.d.ts.map +1 -1
  118. package/{dist → types}/endpoint-generators/create-get-collection-endpoint.spec.d.ts +0 -0
  119. package/{dist → types}/endpoint-generators/create-get-collection-endpoint.spec.d.ts.map +0 -0
  120. package/{dist → types}/endpoint-generators/create-get-entity-endpoint.d.ts +0 -0
  121. package/{dist → types}/endpoint-generators/create-get-entity-endpoint.d.ts.map +1 -1
  122. package/{dist → types}/endpoint-generators/create-get-entity-endpoint.spec.d.ts +0 -0
  123. package/{dist → types}/endpoint-generators/create-get-entity-endpoint.spec.d.ts.map +0 -0
  124. package/{dist → types}/endpoint-generators/create-patch-endpoint.d.ts +0 -0
  125. package/{dist → types}/endpoint-generators/create-patch-endpoint.d.ts.map +1 -1
  126. package/{dist → types}/endpoint-generators/create-patch-endpoint.spec.d.ts +0 -0
  127. package/{dist → types}/endpoint-generators/create-patch-endpoint.spec.d.ts.map +0 -0
  128. package/{dist → types}/endpoint-generators/create-post-endpoint.d.ts +0 -0
  129. package/{dist → types}/endpoint-generators/create-post-endpoint.d.ts.map +1 -1
  130. package/{dist → types}/endpoint-generators/create-post-endpoint.spec.d.ts +0 -0
  131. package/{dist → types}/endpoint-generators/create-post-endpoint.spec.d.ts.map +0 -0
  132. package/{dist → types}/endpoint-generators/index.d.ts +0 -0
  133. package/{dist → types}/endpoint-generators/index.d.ts.map +0 -0
  134. package/{dist → types}/endpoint-generators/utils.d.ts +1 -1
  135. package/{dist → types}/endpoint-generators/utils.d.ts.map +1 -1
  136. package/types/helpers.d.ts +21 -0
  137. package/types/helpers.d.ts.map +1 -0
  138. package/types/helpers.spec.d.ts +2 -0
  139. package/types/helpers.spec.d.ts.map +1 -0
  140. package/{dist → types}/http-authentication-settings.d.ts +0 -0
  141. package/{dist → types}/http-authentication-settings.d.ts.map +0 -0
  142. package/{dist → types}/http-user-context.d.ts +1 -1
  143. package/{dist → types}/http-user-context.d.ts.map +1 -1
  144. package/{dist → types}/http-user-context.spec.d.ts +0 -1
  145. package/{dist → types}/http-user-context.spec.d.ts.map +1 -1
  146. package/{dist → types}/incoming-message-extensions.d.ts +0 -0
  147. package/{dist → types}/incoming-message-extensions.d.ts.map +0 -0
  148. package/{dist → types}/incoming-message-extensions.spec.d.ts +0 -0
  149. package/{dist → types}/incoming-message-extensions.spec.d.ts.map +0 -0
  150. package/{dist → types}/index.d.ts +1 -1
  151. package/types/index.d.ts.map +1 -0
  152. package/{dist → types}/models/cors-options.d.ts +0 -0
  153. package/{dist → types}/models/cors-options.d.ts.map +0 -0
  154. package/{dist → types}/models/default-session.d.ts +0 -0
  155. package/{dist → types}/models/default-session.d.ts.map +0 -0
  156. package/{dist → types}/models/index.d.ts +0 -0
  157. package/{dist → types}/models/index.d.ts.map +0 -0
  158. package/{dist → types}/request-action-implementation.d.ts +0 -0
  159. package/{dist → types}/request-action-implementation.d.ts.map +0 -0
  160. package/types/rest-service.integration.spec.d.ts +2 -0
  161. package/{dist → types}/rest-service.integration.spec.d.ts.map +1 -1
  162. package/{dist → types}/rest.integration.test.d.ts +1 -1
  163. package/types/rest.integration.test.d.ts.map +1 -0
  164. package/{dist → types}/schema-validator/index.d.ts +0 -0
  165. package/{dist → types}/schema-validator/index.d.ts.map +0 -0
  166. package/{dist → types}/schema-validator/schema-validation-error.d.ts +0 -0
  167. package/{dist → types}/schema-validator/schema-validation-error.d.ts.map +0 -0
  168. package/{dist → types}/schema-validator/schema-validator.d.ts +0 -0
  169. package/{dist → types}/schema-validator/schema-validator.d.ts.map +0 -0
  170. package/{dist → types}/schema-validator/schema-validator.test.d.ts +0 -0
  171. package/{dist → types}/schema-validator/schema-validator.test.d.ts.map +0 -0
  172. package/{dist → types}/schema-validator/validate-examples.d.ts +0 -0
  173. package/{dist → types}/schema-validator/validate-examples.d.ts.map +0 -0
  174. package/{dist → types}/server-manager.d.ts +0 -0
  175. package/{dist → types}/server-manager.d.ts.map +0 -0
  176. package/{dist → types}/server-response-extensions.d.ts +0 -0
  177. package/{dist → types}/server-response-extensions.d.ts.map +0 -0
  178. package/{dist → types}/server-response-extensions.spec.d.ts +0 -0
  179. package/{dist → types}/server-response-extensions.spec.d.ts.map +0 -0
  180. package/{dist → types}/utils.d.ts +0 -0
  181. package/{dist → types}/utils.d.ts.map +0 -0
  182. package/{dist → types}/validate.d.ts +0 -0
  183. package/{dist → types}/validate.d.ts.map +0 -0
  184. package/{dist → types}/validate.integration.schema.d.ts +0 -0
  185. package/{dist → types}/validate.integration.schema.d.ts.map +0 -0
  186. package/types/validate.integration.spec.d.ts +2 -0
  187. package/{dist → types}/validate.integration.spec.d.ts.map +1 -1
  188. package/dist/actions/get-current-user.d.ts.map +0 -1
  189. package/dist/actions/login.d.ts.map +0 -1
  190. package/dist/index.d.ts.map +0 -1
  191. package/dist/injector-extensions.d.ts +0 -21
  192. package/dist/injector-extensions.d.ts.map +0 -1
  193. package/dist/injector-extensions.js +0 -14
  194. package/dist/injector-extensions.js.map +0 -1
  195. package/dist/injector-extensions.spec.d.ts +0 -2
  196. package/dist/injector-extensions.spec.d.ts.map +0 -1
  197. package/dist/injector-extensions.spec.js +0 -19
  198. package/dist/injector-extensions.spec.js.map +0 -1
  199. package/dist/rest-service.integration.spec.d.ts +0 -2
  200. package/dist/rest.integration.test.d.ts.map +0 -1
  201. package/dist/validate.integration.spec.d.ts +0 -2
  202. package/src/injector-extensions.spec.ts +0 -19
  203. package/src/injector-extensions.ts +0 -35
@@ -4,12 +4,15 @@ import { DeleteEndpoint } from '@furystack/rest'
4
4
  import { createDeleteEndpoint } from './create-delete-endpoint'
5
5
  import got from 'got'
6
6
  import { MockClass, setupContext } from './utils'
7
+ import { useRestService } from '../helpers'
8
+ import { getDataSetFor } from '@furystack/repository'
7
9
 
8
10
  describe('createDeleteEndpoint', () => {
9
11
  it('Should delete the entity and report the success', async () => {
10
12
  await usingAsync(new Injector(), async (i) => {
11
13
  setupContext(i)
12
- await i.useRestService<{ DELETE: { '/:id': DeleteEndpoint<MockClass, 'id'> } }>({
14
+ await useRestService<{ DELETE: { '/:id': DeleteEndpoint<MockClass, 'id'> } }>({
15
+ injector: i,
13
16
  root: '/api',
14
17
  port: 1111,
15
18
  api: {
@@ -18,16 +21,16 @@ describe('createDeleteEndpoint', () => {
18
21
  },
19
22
  },
20
23
  })
21
- await i.getDataSetFor(MockClass, 'id').add(i, { id: 'mock', value: 'mock' })
24
+ await getDataSetFor(i, MockClass, 'id').add(i, { id: 'mock', value: 'mock' })
22
25
 
23
- const countBeforeDelete = await i.getDataSetFor(MockClass, 'id').count(i)
26
+ const countBeforeDelete = await getDataSetFor(i, MockClass, 'id').count(i)
24
27
  expect(countBeforeDelete).toBe(1)
25
28
 
26
29
  const response = await got('http://127.0.0.1:1111/api/mock', { method: 'DELETE' })
27
30
  expect(response.statusCode).toBe(204)
28
31
  expect(response.body).toBe('')
29
32
 
30
- const countAfterDelete = await i.getDataSetFor(MockClass, 'id').count(i)
33
+ const countAfterDelete = await getDataSetFor(i, MockClass, 'id').count(i)
31
34
  expect(countAfterDelete).toBe(0)
32
35
  })
33
36
  })
@@ -2,6 +2,7 @@ import { Constructable } from '@furystack/inject'
2
2
  import { DeleteEndpoint } from '@furystack/rest'
3
3
  import '@furystack/repository'
4
4
  import { JsonResult, RequestAction } from '../request-action-implementation'
5
+ import { getRepository } from '@furystack/repository'
5
6
 
6
7
  /**
7
8
  * Creates a DELETE endpoint for removing entities
@@ -17,7 +18,7 @@ export const createDeleteEndpoint = <T extends object, TPrimaryKey extends keyof
17
18
  }) => {
18
19
  const endpoint: RequestAction<DeleteEndpoint<T, TPrimaryKey>> = async ({ injector, getUrlParams }) => {
19
20
  const { id } = getUrlParams()
20
- const dataSet = injector.getDataSetFor(options.model, options.primaryKey)
21
+ const dataSet = getRepository(injector).getDataSetFor(options.model, options.primaryKey)
21
22
  await dataSet.remove(injector, id)
22
23
  return JsonResult({}, 204)
23
24
  }
@@ -5,9 +5,11 @@ import { MockClass, setupContext } from './utils'
5
5
  import { createGetCollectionEndpoint } from './create-get-collection-endpoint'
6
6
  import { GetCollectionEndpoint, GetCollectionResult, serializeToQueryString } from '@furystack/rest'
7
7
  import { FindOptions } from '@furystack/core'
8
+ import { getDataSetFor, getRepository } from '@furystack/repository'
9
+ import { useRestService } from '../helpers'
8
10
 
9
11
  const addMockEntities = async (i: Injector) =>
10
- await i
12
+ await getRepository(i)
11
13
  .getDataSetFor(MockClass, 'id')
12
14
  .add(
13
15
  i,
@@ -21,7 +23,8 @@ describe('createGetCollectionEndpoint', () => {
21
23
  it('Should return the collection without filter / order', async () => {
22
24
  await usingAsync(new Injector(), async (i) => {
23
25
  setupContext(i)
24
- await i.useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
26
+ await useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
27
+ injector: i,
25
28
  root: '/api',
26
29
  port: 1112,
27
30
  api: {
@@ -32,8 +35,8 @@ describe('createGetCollectionEndpoint', () => {
32
35
  })
33
36
  await addMockEntities(i)
34
37
 
35
- const count = await i.getDataSetFor(MockClass, 'id').count(i)
36
- const allEntities = await i.getDataSetFor(MockClass, 'id').find(i, {})
38
+ const count = await getDataSetFor(i, MockClass, 'id').count(i)
39
+ const allEntities = await getDataSetFor(i, MockClass, 'id').find(i, {})
37
40
 
38
41
  const response = await got('http://127.0.0.1:1112/api/entities', { method: 'GET' })
39
42
  const json: GetCollectionResult<MockClass> = JSON.parse(response.body)
@@ -45,7 +48,8 @@ describe('createGetCollectionEndpoint', () => {
45
48
  it('Should return entities in order', async () => {
46
49
  await usingAsync(new Injector(), async (i) => {
47
50
  setupContext(i)
48
- await i.useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
51
+ await useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
52
+ injector: i,
49
53
  root: '/api',
50
54
  port: 1113,
51
55
  api: {
@@ -56,8 +60,8 @@ describe('createGetCollectionEndpoint', () => {
56
60
  })
57
61
  await addMockEntities(i)
58
62
  const findOptions: FindOptions<MockClass, Array<keyof MockClass>> = { order: { value: 'ASC' } }
59
- const count = await i.getDataSetFor(MockClass, 'id').count(i, findOptions.filter)
60
- const orderedEntities = await i.getDataSetFor(MockClass, 'id').find(i, findOptions)
63
+ const count = await getDataSetFor(i, MockClass, 'id').count(i, findOptions.filter)
64
+ const orderedEntities = await getDataSetFor(i, MockClass, 'id').find(i, findOptions)
61
65
  const response = await got(`http://127.0.0.1:1113/api/entities?${serializeToQueryString({ findOptions })}`, {
62
66
  method: 'GET',
63
67
  })
@@ -70,7 +74,8 @@ describe('createGetCollectionEndpoint', () => {
70
74
  it('Should return entities with filtering', async () => {
71
75
  await usingAsync(new Injector(), async (i) => {
72
76
  setupContext(i)
73
- await i.useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
77
+ await useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
78
+ injector: i,
74
79
  root: '/api',
75
80
  port: 1113,
76
81
  api: {
@@ -84,8 +89,8 @@ describe('createGetCollectionEndpoint', () => {
84
89
  filter: { id: { $ne: 'mock2' } },
85
90
  }
86
91
 
87
- const count = await i.getDataSetFor(MockClass, 'id').count(i, findOptions.filter)
88
- const filteredEntities = await i.getDataSetFor(MockClass, 'id').find(i, findOptions)
92
+ const count = await getDataSetFor(i, MockClass, 'id').count(i, findOptions.filter)
93
+ const filteredEntities = await getDataSetFor(i, MockClass, 'id').find(i, findOptions)
89
94
 
90
95
  expect(filteredEntities).not.toContainEqual({ id: 'mock2', value: '3' })
91
96
 
@@ -101,7 +106,8 @@ describe('createGetCollectionEndpoint', () => {
101
106
  it('Should return entities with selecting specific fields', async () => {
102
107
  await usingAsync(new Injector(), async (i) => {
103
108
  setupContext(i)
104
- await i.useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
109
+ await useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
110
+ injector: i,
105
111
  root: '/api',
106
112
  port: 1113,
107
113
  api: {
@@ -115,8 +121,8 @@ describe('createGetCollectionEndpoint', () => {
115
121
  select: ['id'],
116
122
  }
117
123
 
118
- const count = await i.getDataSetFor(MockClass, 'id').count(i, findOptions.filter)
119
- const selectedEntities = await i.getDataSetFor(MockClass, 'id').find(i, findOptions)
124
+ const count = await getDataSetFor(i, MockClass, 'id').count(i, findOptions.filter)
125
+ const selectedEntities = await getDataSetFor(i, MockClass, 'id').find(i, findOptions)
120
126
 
121
127
  selectedEntities.forEach((e) => expect(e.value).toBeUndefined())
122
128
 
@@ -132,7 +138,8 @@ describe('createGetCollectionEndpoint', () => {
132
138
  it('Should return entities with top/skip', async () => {
133
139
  await usingAsync(new Injector(), async (i) => {
134
140
  setupContext(i)
135
- await i.useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
141
+ await useRestService<{ GET: { '/entities': GetCollectionEndpoint<MockClass> } }>({
142
+ injector: i,
136
143
  root: '/api',
137
144
  port: 1113,
138
145
  api: {
@@ -147,8 +154,8 @@ describe('createGetCollectionEndpoint', () => {
147
154
  top: 2,
148
155
  }
149
156
 
150
- const count = await i.getDataSetFor(MockClass, 'id').count(i, findOptions.filter)
151
- const topSkipEntities = await i.getDataSetFor(MockClass, 'id').find(i, findOptions)
157
+ const count = await getDataSetFor(i, MockClass, 'id').count(i, findOptions.filter)
158
+ const topSkipEntities = await getDataSetFor(i, MockClass, 'id').find(i, findOptions)
152
159
 
153
160
  expect(topSkipEntities).not.toContainEqual({ id: 'mock1', value: '4' })
154
161
  expect(topSkipEntities).not.toContainEqual({ id: 'mock4', value: '1' })
@@ -2,6 +2,7 @@ import { Constructable } from '@furystack/inject'
2
2
  import { GetCollectionEndpoint } from '@furystack/rest'
3
3
  import '@furystack/repository'
4
4
  import { JsonResult, RequestAction } from '../request-action-implementation'
5
+ import { getRepository } from '@furystack/repository'
5
6
 
6
7
  /**
7
8
  * Creates a GetCollection endpoint for the given model. The model should have a Repository DataSet
@@ -17,7 +18,7 @@ export const createGetCollectionEndpoint = <T, TPrimaryKey extends keyof T>(opti
17
18
  }) => {
18
19
  const endpoint: RequestAction<GetCollectionEndpoint<T>> = async ({ injector, getQuery }) => {
19
20
  const { findOptions } = getQuery()
20
- const dataSet = injector.getDataSetFor(options.model, options.primaryKey)
21
+ const dataSet = getRepository(injector).getDataSetFor(options.model, options.primaryKey)
21
22
  const entriesPromise = dataSet.find<any>(injector, findOptions || {})
22
23
  const countPromise = dataSet.count(injector, findOptions?.filter)
23
24
  const [entries, count] = await Promise.all([entriesPromise, countPromise])
@@ -4,12 +4,15 @@ import { GetEntityEndpoint, serializeToQueryString } from '@furystack/rest'
4
4
  import got, { HTTPError } from 'got'
5
5
  import { MockClass, setupContext } from './utils'
6
6
  import { createGetEntityEndpoint } from './create-get-entity-endpoint'
7
+ import { getDataSetFor } from '@furystack/repository'
8
+ import { useRestService } from '../helpers'
7
9
 
8
10
  describe('createGetEntityEndpoint', () => {
9
11
  it('Should return the entity', async () => {
10
12
  await usingAsync(new Injector(), async (i) => {
11
13
  setupContext(i)
12
- await i.useRestService<{ GET: { '/:id': GetEntityEndpoint<MockClass, 'id'> } }>({
14
+ await useRestService<{ GET: { '/:id': GetEntityEndpoint<MockClass, 'id'> } }>({
15
+ injector: i,
13
16
  root: '/api',
14
17
  port: 1113,
15
18
  api: {
@@ -19,7 +22,7 @@ describe('createGetEntityEndpoint', () => {
19
22
  },
20
23
  })
21
24
  const mockEntity: MockClass = { id: 'mock', value: 'mock' }
22
- await i.getDataSetFor(MockClass, 'id').add(i, mockEntity)
25
+ await getDataSetFor(i, MockClass, 'id').add(i, mockEntity)
23
26
 
24
27
  const response = await got('http://127.0.0.1:1113/api/mock', { method: 'GET' })
25
28
  expect(JSON.parse(response.body)).toStrictEqual(mockEntity)
@@ -29,7 +32,8 @@ describe('createGetEntityEndpoint', () => {
29
32
  it('Should return the entity with the selected fields', async () => {
30
33
  await usingAsync(new Injector(), async (i) => {
31
34
  setupContext(i)
32
- await i.useRestService<{ GET: { '/:id': GetEntityEndpoint<MockClass, 'id'> } }>({
35
+ await useRestService<{ GET: { '/:id': GetEntityEndpoint<MockClass, 'id'> } }>({
36
+ injector: i,
33
37
  root: '/api',
34
38
  port: 1114,
35
39
  api: {
@@ -39,7 +43,7 @@ describe('createGetEntityEndpoint', () => {
39
43
  },
40
44
  })
41
45
  const mockEntity: MockClass = { id: 'mock', value: 'mock' }
42
- await i.getDataSetFor(MockClass, 'id').add(i, mockEntity)
46
+ await getDataSetFor(i, MockClass, 'id').add(i, mockEntity)
43
47
 
44
48
  const response = await got(`http://127.0.0.1:1114/api/mock?${serializeToQueryString({ select: ['id'] })}`, {
45
49
  method: 'GET',
@@ -51,7 +55,8 @@ describe('createGetEntityEndpoint', () => {
51
55
  it('Should return 404 if no entity has been found', async () => {
52
56
  await usingAsync(new Injector(), async (i) => {
53
57
  setupContext(i)
54
- await i.useRestService<{ GET: { '/:id': GetEntityEndpoint<MockClass, 'id'> } }>({
58
+ await useRestService<{ GET: { '/:id': GetEntityEndpoint<MockClass, 'id'> } }>({
59
+ injector: i,
55
60
  root: '/api',
56
61
  port: 1115,
57
62
  api: {
@@ -2,6 +2,7 @@ import { Constructable } from '@furystack/inject'
2
2
  import { RequestError, GetEntityEndpoint } from '@furystack/rest'
3
3
  import '@furystack/repository'
4
4
  import { JsonResult, RequestAction } from '../request-action-implementation'
5
+ import { getRepository } from '@furystack/repository'
5
6
 
6
7
  /**
7
8
  * Creates a simple Get Entity endpoint for a specified model.
@@ -18,7 +19,7 @@ export const createGetEntityEndpoint = <T extends object, TPrimaryKey extends ke
18
19
  const endpoint: RequestAction<GetEntityEndpoint<T, TPrimaryKey>> = async ({ injector, getUrlParams, getQuery }) => {
19
20
  const { id } = getUrlParams()
20
21
  const { select } = getQuery()
21
- const dataSet = injector.getDataSetFor(options.model, options.primaryKey)
22
+ const dataSet = getRepository(injector).getDataSetFor(options.model, options.primaryKey)
22
23
  const entry = await dataSet.get(injector, id, select)
23
24
  if (!entry) {
24
25
  throw new RequestError('Entity not found', 404)
@@ -4,12 +4,15 @@ import { PatchEndpoint } from '@furystack/rest'
4
4
  import { createPatchEndpoint } from './create-patch-endpoint'
5
5
  import got from 'got'
6
6
  import { MockClass, setupContext } from './utils'
7
+ import { getDataSetFor } from '@furystack/repository'
8
+ import { useRestService } from '../helpers'
7
9
 
8
10
  describe('createPatchEndpoint', () => {
9
11
  it('Should update the entity and report the success', async () => {
10
12
  await usingAsync(new Injector(), async (i) => {
11
13
  setupContext(i)
12
- await i.useRestService<{ PATCH: { '/:id': PatchEndpoint<MockClass, 'id'> } }>({
14
+ await useRestService<{ PATCH: { '/:id': PatchEndpoint<MockClass, 'id'> } }>({
15
+ injector: i,
13
16
  root: '/api',
14
17
  port: 1116,
15
18
  api: {
@@ -18,9 +21,9 @@ describe('createPatchEndpoint', () => {
18
21
  },
19
22
  },
20
23
  })
21
- await i.getDataSetFor(MockClass, 'id').add(i, { id: 'mock', value: 'mock' })
24
+ await getDataSetFor(i, MockClass, 'id').add(i, { id: 'mock', value: 'mock' })
22
25
 
23
- const countBeforeDelete = await i.getDataSetFor(MockClass, 'id').count(i)
26
+ const countBeforeDelete = await getDataSetFor(i, MockClass, 'id').count(i)
24
27
  expect(countBeforeDelete).toBe(1)
25
28
 
26
29
  const response = await got('http://127.0.0.1:1116/api/mock', {
@@ -29,7 +32,7 @@ describe('createPatchEndpoint', () => {
29
32
  })
30
33
  expect(response.statusCode).toBe(200)
31
34
  expect(response.body).toBe('{}')
32
- const updated = await i.getDataSetFor(MockClass, 'id').get(i, 'mock')
35
+ const updated = await getDataSetFor(i, MockClass, 'id').get(i, 'mock')
33
36
  expect(updated?.value).toBe('updated')
34
37
  })
35
38
  })
@@ -3,6 +3,7 @@ import { PatchEndpoint } from '@furystack/rest'
3
3
  import '@furystack/repository'
4
4
  import '../incoming-message-extensions'
5
5
  import { JsonResult, RequestAction } from '../request-action-implementation'
6
+ import { getRepository } from '@furystack/repository'
6
7
 
7
8
  /**
8
9
  * Creates a PATCH endpoint for updating entities
@@ -19,7 +20,7 @@ export const createPatchEndpoint = <T extends object, TPrimaryKey extends keyof
19
20
  const endpoint: RequestAction<PatchEndpoint<T, TPrimaryKey>> = async ({ injector, request, getUrlParams }) => {
20
21
  const { id } = getUrlParams()
21
22
  const patchData = await request.readPostBody<T>()
22
- const dataSet = injector.getDataSetFor(options.model, options.primaryKey)
23
+ const dataSet = getRepository(injector).getDataSetFor(options.model, options.primaryKey)
23
24
  await dataSet.update(injector, id, patchData)
24
25
  return JsonResult({})
25
26
  }
@@ -4,12 +4,15 @@ import { PostEndpoint } from '@furystack/rest'
4
4
  import { createPostEndpoint } from './create-post-endpoint'
5
5
  import got from 'got'
6
6
  import { MockClass, setupContext } from './utils'
7
+ import { useRestService } from '../helpers'
8
+ import { getDataSetFor } from '@furystack/repository'
7
9
 
8
10
  describe('createPostEndpoint', () => {
9
11
  it('Should create the entity and report the success', async () => {
10
12
  await usingAsync(new Injector(), async (i) => {
11
13
  setupContext(i)
12
- await i.useRestService<{ POST: { '/:id': PostEndpoint<MockClass, 'id'> } }>({
14
+ await useRestService<{ POST: { '/:id': PostEndpoint<MockClass, 'id'> } }>({
15
+ injector: i,
13
16
  root: '/api',
14
17
  port: 1117,
15
18
  api: {
@@ -25,7 +28,7 @@ describe('createPostEndpoint', () => {
25
28
  })
26
29
  expect(response.statusCode).toBe(201)
27
30
  expect(JSON.parse(response.body)).toStrictEqual(entityToPost)
28
- const posted = await i.getDataSetFor(MockClass, 'id').get(i, entityToPost.id)
31
+ const posted = await getDataSetFor(i, MockClass, 'id').get(i, entityToPost.id)
29
32
  expect(posted?.value).toBe('posted')
30
33
  })
31
34
  })
@@ -4,6 +4,7 @@ import '@furystack/repository'
4
4
  import '../incoming-message-extensions'
5
5
  import { JsonResult, RequestAction } from '../request-action-implementation'
6
6
  import { WithOptionalId } from '@furystack/core'
7
+ import { getRepository } from '@furystack/repository'
7
8
  /**
8
9
  * Creates a POST endpoint for updating entities
9
10
  *
@@ -17,7 +18,7 @@ export const createPostEndpoint = <T extends object, TPrimaryKey extends keyof T
17
18
  primaryKey: TPrimaryKey
18
19
  }) => {
19
20
  const endpoint: RequestAction<PostEndpoint<T, TPrimaryKey>> = async ({ injector, request }) => {
20
- const dataSet = injector.getDataSetFor(options.model, options.primaryKey)
21
+ const dataSet = getRepository(injector).getDataSetFor(options.model, options.primaryKey)
21
22
 
22
23
  const entityToCreate = await request.readPostBody<WithOptionalId<T, typeof dataSet['primaryKey']>>()
23
24
  const { created } = await dataSet.add(injector, entityToCreate)
@@ -1,8 +1,9 @@
1
1
  import { Injector } from '@furystack/inject'
2
- import { InMemoryStore, User } from '@furystack/core'
2
+ import { addStore, InMemoryStore, User } from '@furystack/core'
3
3
  import { DefaultSession } from '../models/default-session'
4
4
  import '@furystack/repository'
5
- import '../injector-extensions'
5
+ import '../helpers'
6
+ import { getRepository } from '@furystack/repository'
6
7
 
7
8
  export class MockClass {
8
9
  id!: string
@@ -10,25 +11,24 @@ export class MockClass {
10
11
  }
11
12
 
12
13
  export const setupContext = (i: Injector) => {
13
- i.setupStores((b) =>
14
- b
15
- .addStore(
16
- new InMemoryStore({
17
- model: MockClass,
18
- primaryKey: 'id',
19
- }),
20
- )
21
- .addStore(
22
- new InMemoryStore({
23
- model: User,
24
- primaryKey: 'username',
25
- }),
26
- )
27
- .addStore(
28
- new InMemoryStore({
29
- model: DefaultSession,
30
- primaryKey: 'sessionId',
31
- }),
32
- ),
33
- ).setupRepository((r) => r.createDataSet(MockClass, 'id'))
14
+ addStore(
15
+ i,
16
+ new InMemoryStore({
17
+ model: MockClass,
18
+ primaryKey: 'id',
19
+ }),
20
+ )
21
+ .addStore(
22
+ new InMemoryStore({
23
+ model: User,
24
+ primaryKey: 'username',
25
+ }),
26
+ )
27
+ .addStore(
28
+ new InMemoryStore({
29
+ model: DefaultSession,
30
+ primaryKey: 'sessionId',
31
+ }),
32
+ )
33
+ getRepository(i).createDataSet(MockClass, 'id')
34
34
  }
@@ -0,0 +1,24 @@
1
+ import { Injector } from '@furystack/inject'
2
+ import { usingAsync } from '@furystack/utils'
3
+ import { useHttpAuthentication } from './helpers'
4
+
5
+ describe('Injector extensions', () => {
6
+ describe('useHttpAuthentication', () => {
7
+ it('Should set up HTTP Authentication', async () => {
8
+ await usingAsync(new Injector(), async (i) => {
9
+ useHttpAuthentication(i)
10
+ // TODO: Check if HTTP Auth has been set up
11
+ })
12
+ })
13
+ })
14
+
15
+ describe('useRestService()', () => {
16
+ it.todo(
17
+ 'Should set up a REST service',
18
+ // await usingAsync(new Injector(), async (i) => {
19
+ // useRestService({ injector: i, api: {}, })
20
+ // TODO: Assert if REST service has been set up
21
+ // })
22
+ )
23
+ })
24
+ })
package/src/helpers.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { User } from '@furystack/core'
2
+ import { Injector } from '@furystack/inject'
3
+ import { HttpAuthenticationSettings } from './http-authentication-settings'
4
+ import { RestApi } from '@furystack/rest'
5
+ import { ApiManager, ImplementApiOptions } from './api-manager'
6
+ import { DefaultSession } from './models/default-session'
7
+
8
+ /**
9
+ * Sets up the @furystack/rest-service with the provided settings
10
+ *
11
+ * @param api The API implementation details
12
+ */
13
+ export const useRestService = async <T extends RestApi>(api: ImplementApiOptions<T>) => {
14
+ await api.injector.getInstance(ApiManager).addApi({ ...api })
15
+ return this
16
+ }
17
+
18
+ /**
19
+ * Sets up the HTTP Authentication
20
+ *
21
+ * @param injector The Injector instance
22
+ * @param settings Settings for HTTP Authentication
23
+ * @returns void
24
+ */
25
+ export const useHttpAuthentication = <TUser extends User, TSession extends DefaultSession>(
26
+ injector: Injector,
27
+ settings?: Partial<HttpAuthenticationSettings<TUser, TSession>>,
28
+ ) => injector.setExplicitInstance({ ...new HttpAuthenticationSettings(), ...settings }, HttpAuthenticationSettings)
@@ -1,22 +1,18 @@
1
1
  import { IncomingMessage, ServerResponse } from 'http'
2
2
  import { usingAsync } from '@furystack/utils'
3
3
  import { Injector } from '@furystack/inject'
4
- import { User, StoreManager, InMemoryStore } from '@furystack/core'
4
+ import { User, StoreManager, InMemoryStore, addStore } from '@furystack/core'
5
5
  import { DefaultSession } from './models/default-session'
6
6
  import { HttpUserContext } from './http-user-context'
7
- import './injector-extensions'
8
7
  import { PasswordAuthenticator, PasswordCredential, UnauthenticatedError } from '@furystack/security'
8
+ import { useHttpAuthentication } from './helpers'
9
9
 
10
10
  export const prepareInjector = async (i: Injector) => {
11
- i.setupStores((sm) =>
12
- sm
13
- .addStore(new InMemoryStore({ model: User, primaryKey: 'username' }))
14
- .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
15
- .addStore(new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' })),
16
- )
11
+ addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' }))
12
+ .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
13
+ .addStore(new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }))
17
14
 
18
- i.useHttpAuthentication()
19
- // await i.getInstance(ServerManager).getOrCreate({ port: 19999 })
15
+ useHttpAuthentication(i)
20
16
  }
21
17
 
22
18
  const setupUser = async (i: Injector, userName: string, password: string) => {
@@ -1,10 +1,10 @@
1
1
  import { IncomingMessage, ServerResponse } from 'http'
2
2
  import { User, StoreManager } from '@furystack/core'
3
3
  import { Injectable } from '@furystack/inject'
4
- import { v1 } from 'uuid'
5
4
  import { HttpAuthenticationSettings } from './http-authentication-settings'
6
- import { DefaultSession } from 'models/default-session'
5
+ import { DefaultSession } from './models/default-session'
7
6
  import { PasswordAuthenticator, UnauthenticatedError } from '@furystack/security'
7
+ import { randomBytes } from 'crypto'
8
8
 
9
9
  /**
10
10
  * Injectable UserContext for FuryStack HTTP Api
@@ -142,7 +142,7 @@ export class HttpUserContext {
142
142
  * @returns the current User
143
143
  */
144
144
  public async cookieLogin(user: User, serverResponse: ServerResponse): Promise<User> {
145
- const sessionId = v1()
145
+ const sessionId = randomBytes(32).toString('hex')
146
146
  await this.getSessionStore().add({ sessionId, username: user.username })
147
147
  serverResponse.setHeader('Set-Cookie', `${this.authentication.cookieName}=${sessionId}; Path=/; HttpOnly`)
148
148
  this.user = user
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import './injector-extensions'
1
+ export * from './helpers'
2
2
  export * from './api-manager'
3
3
  export * from './actions'
4
4
  export * from './authenticate'
@@ -1,12 +1,13 @@
1
1
  import { Injector } from '@furystack/inject'
2
- import './injector-extensions'
2
+ import './helpers'
3
3
  import { usingAsync, PathHelper } from '@furystack/utils'
4
4
  import { GetCurrentUser, IsAuthenticated, LoginAction, LogoutAction } from './actions'
5
5
  import { RestApi } from '@furystack/rest'
6
- import { User, InMemoryStore } from '@furystack/core'
6
+ import { User, InMemoryStore, addStore } from '@furystack/core'
7
7
  import { DefaultSession } from './models/default-session'
8
8
  import got from 'got'
9
9
  import { JsonResult } from './request-action-implementation'
10
+ import { useHttpAuthentication, useRestService } from './helpers'
10
11
 
11
12
  class UserWithPassword extends User {
12
13
  password!: string
@@ -30,43 +31,42 @@ const port = 19090
30
31
  const hostName = 'localhost'
31
32
  const root = 'test-api'
32
33
 
33
- const prepareInjector = (i: Injector) =>
34
- i
35
- .setupStores((sm) =>
36
- sm
37
- .addStore(new InMemoryStore({ model: User, primaryKey: 'username' }))
38
- .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' })),
39
- )
40
- .useHttpAuthentication({
41
- getUserStore: (sm) => sm.getStoreFor(UserWithPassword, 'username'),
42
- getSessionStore: (sm) => sm.getStoreFor(DefaultSession, 'sessionId'),
43
- })
44
- .useRestService<IntegrationTestApi>({
45
- root,
46
- port,
47
- hostName,
48
- cors: {
49
- credentials: true,
50
- origins: ['http://localhost:8080'],
51
- headers: ['cache', 'content-type'],
34
+ const prepareInjector = async (i: Injector) => {
35
+ addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
36
+ new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
37
+ )
38
+ useHttpAuthentication(i, {
39
+ getUserStore: (sm) => sm.getStoreFor(UserWithPassword, 'username'),
40
+ getSessionStore: (sm) => sm.getStoreFor(DefaultSession, 'sessionId'),
41
+ })
42
+ await useRestService<IntegrationTestApi>({
43
+ injector: i,
44
+ root,
45
+ port,
46
+ hostName,
47
+ cors: {
48
+ credentials: true,
49
+ origins: ['http://localhost:8080'],
50
+ headers: ['cache', 'content-type'],
51
+ },
52
+ api: {
53
+ GET: {
54
+ '/currentUser': GetCurrentUser,
55
+ '/isAuthenticated': IsAuthenticated,
56
+ '/testQuery': async (options) => JsonResult({ param1Value: options.getQuery().param1 }),
57
+ '/testUrlParams/:urlParam': async (options) => JsonResult({ urlParamValue: options.getUrlParams().urlParam }),
52
58
  },
53
- api: {
54
- GET: {
55
- '/currentUser': GetCurrentUser,
56
- '/isAuthenticated': IsAuthenticated,
57
- '/testQuery': async (options) => JsonResult({ param1Value: options.getQuery().param1 }),
58
- '/testUrlParams/:urlParam': async (options) => JsonResult({ urlParamValue: options.getUrlParams().urlParam }),
59
- },
60
- POST: {
61
- '/login': LoginAction,
62
- '/logout': LogoutAction,
63
- '/testPostBody': async (options) => {
64
- const body = await options.getBody()
65
- return JsonResult({ bodyValue: body.value })
66
- },
59
+ POST: {
60
+ '/login': LoginAction,
61
+ '/logout': LogoutAction,
62
+ '/testPostBody': async (options) => {
63
+ const body = await options.getBody()
64
+ return JsonResult({ bodyValue: body.value })
67
65
  },
68
66
  },
69
- })
67
+ },
68
+ })
69
+ }
70
70
 
71
71
  const apiUrl = PathHelper.joinPaths(`http://${hostName}:${port}`, root)
72
72