@furystack/rest-service 6.2.0 → 6.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/actions/error-action.js +5 -5
  2. package/dist/actions/error-action.js.map +1 -1
  3. package/dist/actions/error-action.spec.js +0 -3
  4. package/dist/actions/error-action.spec.js.map +1 -1
  5. package/dist/endpoint-generators/create-delete-endpoint.spec.js +4 -7
  6. package/dist/endpoint-generators/create-delete-endpoint.spec.js.map +1 -1
  7. package/dist/endpoint-generators/create-get-collection-endpoint.spec.js +15 -14
  8. package/dist/endpoint-generators/create-get-collection-endpoint.spec.js.map +1 -1
  9. package/dist/endpoint-generators/create-get-entity-endpoint.spec.js +12 -18
  10. package/dist/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
  11. package/dist/endpoint-generators/create-patch-endpoint.spec.js +4 -7
  12. package/dist/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
  13. package/dist/endpoint-generators/create-post-endpoint.spec.js +4 -7
  14. package/dist/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
  15. package/dist/rest-service.integration.spec.js +34 -24
  16. package/dist/rest-service.integration.spec.js.map +1 -1
  17. package/dist/rest.integration.test.js +11 -11
  18. package/dist/rest.integration.test.js.map +1 -1
  19. package/dist/static-server-manager.js +1 -1
  20. package/dist/static-server-manager.js.map +1 -1
  21. package/dist/static-server-manager.spec.js +80 -68
  22. package/dist/static-server-manager.spec.js.map +1 -1
  23. package/dist/validate.integration.spec.js +32 -37
  24. package/dist/validate.integration.spec.js.map +1 -1
  25. package/package.json +11 -12
  26. package/src/actions/error-action.spec.ts +0 -3
  27. package/src/actions/error-action.ts +6 -6
  28. package/src/endpoint-generators/create-delete-endpoint.spec.ts +4 -4
  29. package/src/endpoint-generators/create-get-collection-endpoint.spec.ts +17 -11
  30. package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +12 -16
  31. package/src/endpoint-generators/create-patch-endpoint.spec.ts +4 -4
  32. package/src/endpoint-generators/create-post-endpoint.spec.ts +4 -4
  33. package/src/rest-service.integration.spec.ts +36 -29
  34. package/src/rest.integration.test.ts +10 -10
  35. package/src/static-server-manager.spec.ts +86 -45
  36. package/src/static-server-manager.ts +3 -1
  37. package/src/validate.integration.spec.ts +31 -36
  38. package/types/actions/error-action.d.ts +0 -2
  39. package/types/actions/error-action.d.ts.map +1 -1
  40. package/types/static-server-manager.d.ts.map +1 -1
  41. package/types/validate.integration.spec.d.ts.map +1 -1
@@ -1,88 +1,126 @@
1
1
  import { Injector } from '@furystack/inject'
2
2
  import { sleepAsync, usingAsync } from '@furystack/utils'
3
- import got, { RequestError } from 'got'
4
3
  import { ServerManager } from './server-manager'
5
4
  import { StaticServerManager } from './static-server-manager'
6
5
 
6
+ /**
7
+ * Generator for an incremental port number
8
+ *
9
+ * @param initialPort The initial port number
10
+ * @yields a port for testing
11
+ * @returns The Port number
12
+ */
13
+ function* getPort(initialPort = 1234) {
14
+ let port = initialPort
15
+
16
+ while (true) {
17
+ yield port++
18
+ }
19
+ return port
20
+ }
21
+
7
22
  describe('StaticServerManager', () => {
23
+ const portGenerator = getPort()
24
+
8
25
  describe('Top level routing', () => {
9
26
  it('Should return a 404 without fallback', async () => {
10
27
  await usingAsync(new Injector(), async (injector) => {
11
28
  const staticServerManager = injector.getInstance(StaticServerManager)
29
+ const port = portGenerator.next().value
30
+ await staticServerManager.addStaticSite({
31
+ baseUrl: '/',
32
+ path: '.',
33
+ port,
34
+ })
35
+
36
+ const result = await fetch(`http://localhost:${port}/not-found.html`)
37
+ expect(result.ok).toBe(false)
38
+ expect(result.status).toBe(404)
39
+ expect(result?.headers.get('content-type')).toBe('text/plain')
40
+ const body = await result.text()
41
+ expect(body).toBe('Not found')
42
+ })
43
+ })
44
+
45
+ it('Should return a fallback', async () => {
46
+ await usingAsync(new Injector(), async (injector) => {
47
+ const staticServerManager = injector.getInstance(StaticServerManager)
48
+ const port = portGenerator.next().value
12
49
 
13
50
  await staticServerManager.addStaticSite({
14
51
  baseUrl: '/',
15
52
  path: '.',
16
- port: 1234,
53
+ fallback: 'package.json',
54
+ port,
55
+ headers: {
56
+ 'custom-header': 'custom-value',
57
+ },
17
58
  })
18
59
 
19
- try {
20
- await got.get('http://localhost:1234/not-found.html')
21
- } catch (error) {
22
- expect(error).toBeInstanceOf(RequestError)
23
- const requestError: RequestError = error as RequestError
60
+ const result = await fetch(`http://localhost:${port}/not-found.html`)
24
61
 
25
- expect(requestError.response?.statusCode).toBe(404)
26
- expect(requestError.response?.headers['content-type']).toBe('text/plain')
27
- expect(requestError.response?.body).toBe('Not found')
28
- }
62
+ expect(result.headers.get('content-type')).toBe('application/json')
63
+ expect(result.headers.get('custom-header')).toBe('custom-value')
29
64
  })
30
65
  })
31
66
 
32
- it('Should return a fallback', async () => {
67
+ it('Should return a fallback for root files', async () => {
33
68
  await usingAsync(new Injector(), async (injector) => {
34
69
  const staticServerManager = injector.getInstance(StaticServerManager)
70
+ const port = portGenerator.next().value
35
71
 
36
72
  await staticServerManager.addStaticSite({
37
73
  baseUrl: '/',
38
74
  path: '.',
39
75
  fallback: 'package.json',
40
- port: 1234,
76
+ port,
41
77
  headers: {
42
78
  'custom-header': 'custom-value',
43
79
  },
44
80
  })
45
81
 
46
- const result = await got.get('http://localhost:1234/not-found.html')
82
+ const result = await fetch(`http://localhost:${port}`)
47
83
 
48
- expect(result.headers['content-type']).toBe('application/json')
49
- expect(result.headers['custom-header']).toBe('custom-value')
84
+ expect(result.headers.get('content-type')).toBe('application/json')
85
+ expect(result.headers.get('custom-header')).toBe('custom-value')
50
86
  })
51
87
  })
52
88
 
53
89
  it('Should return a defined file from a root directory', async () => {
54
90
  await usingAsync(new Injector(), async (injector) => {
55
91
  const staticServerManager = injector.getInstance(StaticServerManager)
92
+ const port = portGenerator.next().value
56
93
 
57
94
  await staticServerManager.addStaticSite({
58
95
  baseUrl: '/',
59
96
  path: '.',
60
- port: 1234,
97
+ port,
61
98
  headers: {
62
99
  'custom-header': 'custom-value',
63
100
  },
64
101
  })
65
102
 
66
- const result = await got.get('http://localhost:1234/README.md')
103
+ const result = await fetch(`http://localhost:${port}/README.md`)
67
104
 
68
- expect(result.headers['content-type']).toBe('text/markdown')
69
- expect(result.headers['custom-header']).toBe('custom-value')
105
+ expect(result.headers.get('content-type')).toBe('text/markdown')
106
+ expect(result.headers.get('custom-header')).toBe('custom-value')
70
107
  })
71
108
  })
72
109
 
73
110
  it('Should return a defined file from a subdirectory', async () => {
74
111
  await usingAsync(new Injector(), async (injector) => {
75
112
  const staticServerManager = injector.getInstance(StaticServerManager)
113
+ const port = portGenerator.next().value
76
114
 
77
115
  await staticServerManager.addStaticSite({
78
116
  baseUrl: '/',
79
117
  path: '.',
80
- port: 1234,
118
+ port,
81
119
  })
82
120
 
83
- const result = await got.get('http://localhost:1234/packages/utils/README.md')
121
+ const result = await fetch(`http://localhost:${port}/packages/utils/README.md`)
84
122
 
85
- expect(result.headers['content-type']).toBe('text/markdown')
123
+ expect(result.headers.get('content-type')).toBe('text/markdown')
86
124
  })
87
125
  })
88
126
  })
@@ -91,18 +129,21 @@ describe('StaticServerManager', () => {
91
129
  it('Should not handle a request when the path is not matching', async () => {
92
130
  await usingAsync(new Injector(), async (injector) => {
93
131
  const staticServerManager = injector.getInstance(StaticServerManager)
132
+ const port = portGenerator.next().value
94
133
 
95
134
  await staticServerManager.addStaticSite({
96
135
  baseUrl: '/bundle',
97
136
  path: '.',
98
- port: 1234,
137
+ port,
99
138
  })
100
139
 
101
140
  const server = [...injector.getInstance(ServerManager).servers.values()][0]
102
141
 
103
142
  server.apis[0].onRequest = jest.fn()
104
143
 
105
- got.get('http://localhost:1234/bundleToAnotherFolder/not-found.html')
144
+ fetch(`http://localhost:${port}/bundleToAnotherFolder/not-found.html`).catch(() => {
145
+ /** should fall, ignore */
146
+ })
106
147
 
107
148
  await sleepAsync(100)
108
149
 
@@ -113,72 +154,72 @@ describe('StaticServerManager', () => {
113
154
  it('Should return a 404 without fallback', async () => {
114
155
  await usingAsync(new Injector(), async (injector) => {
115
156
  const staticServerManager = injector.getInstance(StaticServerManager)
157
+ const port = portGenerator.next().value
116
158
 
117
159
  await staticServerManager.addStaticSite({
118
160
  baseUrl: '/bundle',
119
161
  path: '.',
120
- port: 1234,
162
+ port,
121
163
  })
122
164
 
123
- try {
124
- await got.get('http://localhost:1234/bundle/not-found.html')
125
- } catch (error) {
126
- expect(error).toBeInstanceOf(RequestError)
127
- const requestError: RequestError = error as RequestError
128
-
129
- expect(requestError.response?.statusCode).toBe(404)
130
- expect(requestError.response?.headers['content-type']).toBe('text/plain')
131
- expect(requestError.response?.body).toBe('Not found')
132
- }
165
+ const result = await fetch(`http://localhost:${port}/bundle/not-found.html`)
166
+ expect(result.ok).toBe(false)
167
+ expect(result.status).toBe(404)
168
+ expect(result.headers.get('content-type')).toBe('text/plain')
169
+ const body = await result.text()
170
+ expect(body).toBe('Not found')
133
171
  })
134
172
  })
135
173
 
136
174
  it('Should return a fallback', async () => {
137
175
  await usingAsync(new Injector(), async (injector) => {
138
176
  const staticServerManager = injector.getInstance(StaticServerManager)
177
+ const port = portGenerator.next().value
139
178
 
140
179
  await staticServerManager.addStaticSite({
141
180
  baseUrl: '/bundle',
142
181
  path: '.',
143
182
  fallback: 'package.json',
144
- port: 1234,
183
+ port,
145
184
  })
146
185
 
147
- const result = await got.get('http://localhost:1234/bundle/not-found.html')
186
+ const result = await fetch(`http://localhost:${port}/bundle/not-found.html`)
148
187
 
149
- expect(result.headers['content-type']).toBe('application/json')
188
+ expect(result.headers.get('content-type')).toBe('application/json')
150
189
  })
151
190
  })
152
191
 
153
192
  it('Should return a defined file from a root directory', async () => {
154
193
  await usingAsync(new Injector(), async (injector) => {
155
194
  const staticServerManager = injector.getInstance(StaticServerManager)
195
+ const port = portGenerator.next().value
156
196
 
157
197
  await staticServerManager.addStaticSite({
158
198
  baseUrl: '/',
159
199
  path: '.',
160
- port: 1234,
200
+ port,
161
201
  })
162
202
 
163
- const result = await got.get('http://localhost:1234/README.md')
203
+ const result = await fetch(`http://localhost:${port}/README.md`)
164
204
 
165
- expect(result.headers['content-type']).toBe('text/markdown')
205
+ expect(result.headers.get('content-type')).toBe('text/markdown')
166
206
  })
167
207
  })
168
208
 
169
209
  it('Should return a defined file from a subdirectory', async () => {
170
210
  await usingAsync(new Injector(), async (injector) => {
171
211
  const staticServerManager = injector.getInstance(StaticServerManager)
212
+ const port = portGenerator.next().value
172
213
 
173
214
  await staticServerManager.addStaticSite({
174
215
  baseUrl: '/',
175
216
  path: '.',
176
- port: 1234,
217
+ port,
177
218
  })
178
219
 
179
- const result = await got.get('http://localhost:1234/packages/utils/README.md')
220
+ const result = await fetch(`http://localhost:${port}/packages/utils/README.md`)
180
221
 
181
- expect(result.headers['content-type']).toBe('text/markdown')
222
+ expect(result.headers.get('content-type')).toBe('text/markdown')
182
223
  })
183
224
  })
184
225
  })
@@ -38,7 +38,9 @@ export class StaticServerManager {
38
38
  }
39
39
 
40
40
  res.writeHead(200, head)
41
- createReadStream(fullPath, { autoClose: true }).pipe(res)
41
+ await new Promise<void>((resolve, reject) =>
42
+ createReadStream(fullPath, { autoClose: true }).once('finish', resolve).once('error', reject).pipe(res),
43
+ )
42
44
  }
43
45
 
44
46
  public shouldExec =
@@ -1,7 +1,6 @@
1
1
  import { Injector } from '@furystack/inject'
2
- import { createClient } from '@furystack/rest-client-got'
2
+ import { createClient, ResponseError } from '@furystack/rest-client-fetch'
3
3
  import { usingAsync } from '@furystack/utils'
4
- import { RequestError } from 'got/dist/source'
5
4
  import { JsonResult } from './request-action-implementation'
6
5
  import { Validate } from './validate'
7
6
  import './helpers'
@@ -75,10 +74,10 @@ describe('Validation integration tests', () => {
75
74
  query: undefined as any,
76
75
  })
77
76
  } catch (error) {
78
- if (error instanceof RequestError) {
79
- expect(error.message).toBe('Response code 400 (Bad Request)')
80
- expect(error.response?.statusCode).toBe(400)
81
- const responseJson = JSON.parse(error.response?.body as string)
77
+ if (error instanceof ResponseError) {
78
+ expect(error.message).toBe('Bad Request')
79
+ expect(error.response?.status).toBe(400)
80
+ const responseJson = await error.response.json()
82
81
  expect(responseJson.errors[0].params.missingProperty).toEqual('foo')
83
82
  expect(responseJson.errors[1].params.missingProperty).toEqual('bar')
84
83
  expect(responseJson.errors[2].params.missingProperty).toEqual('baz')
@@ -96,10 +95,10 @@ describe('Validation integration tests', () => {
96
95
  url: undefined as any,
97
96
  })
98
97
  } catch (error) {
99
- if (error instanceof RequestError) {
100
- expect(error.message).toBe('Response code 400 (Bad Request)')
101
- expect(error.response?.statusCode).toBe(400)
102
- const responseJson = JSON.parse(error.response?.body as string)
98
+ if (error instanceof ResponseError) {
99
+ expect(error.message).toBe('Bad Request')
100
+ expect(error.response?.status).toBe(400)
101
+ const responseJson = await error.response.json()
103
102
  expect(responseJson.errors[0].params.type).toEqual('number')
104
103
  expect(responseJson.errors[0].instancePath).toEqual('/url/id')
105
104
  }
@@ -116,10 +115,10 @@ describe('Validation integration tests', () => {
116
115
  headers: undefined as any,
117
116
  })
118
117
  } catch (error) {
119
- if (error instanceof RequestError) {
120
- expect(error.message).toBe('Response code 400 (Bad Request)')
121
- expect(error.response?.statusCode).toBe(400)
122
- const responseJson = JSON.parse(error.response?.body as string)
118
+ if (error instanceof ResponseError) {
119
+ expect(error.message).toBe('Bad Request')
120
+ expect(error.response?.status).toBe(400)
121
+ const responseJson = await error.response.json()
123
122
  expect(
124
123
  responseJson.errors.find((e: any) => e.keyword === 'required' && e.message.includes('foo')),
125
124
  ).toBeDefined()
@@ -137,10 +136,10 @@ describe('Validation integration tests', () => {
137
136
  body: undefined as any,
138
137
  })
139
138
  } catch (error) {
140
- if (error instanceof RequestError) {
141
- expect(error.message).toBe('Response code 400 (Bad Request)')
142
- expect(error.response?.statusCode).toBe(400)
143
- const responseJson = JSON.parse(error.response?.body as string)
139
+ if (error instanceof ResponseError) {
140
+ expect(error.message).toBe('Bad Request')
141
+ expect(error.response?.status).toBe(400)
142
+ const responseJson = await error.response.json()
144
143
  expect(responseJson.errors[0].params.missingProperty).toEqual('body')
145
144
  }
146
145
  }
@@ -160,11 +159,10 @@ describe('Validation integration tests', () => {
160
159
  baz: false,
161
160
  },
162
161
  })
163
- expect(result.response.statusCode).toBe(200)
164
- const responseJson = result.getJson()
165
- expect(responseJson.foo).toBe('foo')
166
- expect(responseJson.bar).toBe(2)
167
- expect(responseJson.baz).toBe(false)
162
+ expect(result.response.status).toBe(200)
163
+ expect(result.result.foo).toBe('foo')
164
+ expect(result.result.bar).toBe(2)
165
+ expect(result.result.baz).toBe(false)
168
166
  })
169
167
  })
170
168
  it('Should validate url', async () => {
@@ -174,9 +172,8 @@ describe('Validation integration tests', () => {
174
172
  action: '/validate-url/:id',
175
173
  url: { id: 3 },
176
174
  })
177
- expect(result.response.statusCode).toBe(200)
178
- const responseJson = result.getJson()
179
- expect(responseJson.id).toBe(3)
175
+ expect(result.response.status).toBe(200)
176
+ expect(result.result.id).toBe(3)
180
177
  })
181
178
  })
182
179
  it('Should validate headers', async () => {
@@ -190,11 +187,10 @@ describe('Validation integration tests', () => {
190
187
  baz: true,
191
188
  },
192
189
  })
193
- expect(result.response.statusCode).toBe(200)
194
- const responseJson = result.getJson()
195
- expect(responseJson.foo).toBe('foo')
196
- expect(responseJson.bar).toBe(42)
197
- expect(responseJson.baz).toBe(true)
190
+ expect(result.response.status).toBe(200)
191
+ expect(result.result.foo).toBe('foo')
192
+ expect(result.result.bar).toBe(42)
193
+ expect(result.result.baz).toBe(true)
198
194
  })
199
195
  })
200
196
  it('Should validate body', async () => {
@@ -209,11 +205,10 @@ describe('Validation integration tests', () => {
209
205
  },
210
206
  })
211
207
 
212
- expect(result.response.statusCode).toBe(200)
213
- const responseJson = result.getJson()
214
- expect(responseJson.foo).toBe('foo')
215
- expect(responseJson.bar).toBe(42)
216
- expect(responseJson.baz).toBe(true)
208
+ expect(result.response.status).toBe(200)
209
+ expect(result.result.foo).toBe('foo')
210
+ expect(result.result.bar).toBe(42)
211
+ expect(result.result.baz).toBe(true)
217
212
  })
218
213
  })
219
214
  })
@@ -7,8 +7,6 @@ export declare const ErrorAction: RequestAction<{
7
7
  body: unknown;
8
8
  result: {
9
9
  message: string;
10
- url?: string;
11
- stack?: string;
12
10
  };
13
11
  }>;
14
12
  //# sourceMappingURL=error-action.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-action.d.ts","sourceRoot":"","sources":["../../src/actions/error-action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAIrE;;;GAGG;AAEH,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC;IACtC,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1D,CAoBA,CAAA"}
1
+ {"version":3,"file":"error-action.d.ts","sourceRoot":"","sources":["../../src/actions/error-action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAIrE;;;GAGG;AAEH,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC;IACtC,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5B,CAoBA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"static-server-manager.d.ts","sourceRoot":"","sources":["../src/static-server-manager.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAkB,MAAM,MAAM,CAAA;AAKhF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAC9B;AAED,qBACa,mBAAmB;IAE9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;YAEhC,QAAQ;IAqBf,UAAU,YACL,MAAM;aACC,KAAK,eAAe,EAAE,KAAK,GAAG,QAAQ,CAAC;kBAK7C;IAEb,OAAO,CAAC,SAAS,CA0BhB;IAEY,aAAa,CAAC,OAAO,EAAE,mBAAmB;CAQxD"}
1
+ {"version":3,"file":"static-server-manager.d.ts","sourceRoot":"","sources":["../src/static-server-manager.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAkB,MAAM,MAAM,CAAA;AAKhF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAC9B;AAED,qBACa,mBAAmB;IAE9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;YAEhC,QAAQ;IAuBf,UAAU,YACL,MAAM;aACC,KAAK,eAAe,EAAE,KAAK,GAAG,QAAQ,CAAC;kBAK7C;IAEb,OAAO,CAAC,SAAS,CA0BhB;IAEY,aAAa,CAAC,OAAO,EAAE,mBAAmB;CAQxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.integration.spec.d.ts","sourceRoot":"","sources":["../src/validate.integration.spec.ts"],"names":[],"mappings":"AAMA,OAAO,WAAW,CAAA"}
1
+ {"version":3,"file":"validate.integration.spec.d.ts","sourceRoot":"","sources":["../src/validate.integration.spec.ts"],"names":[],"mappings":"AAKA,OAAO,WAAW,CAAA"}