@furystack/rest-service 9.0.0 → 9.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/actions/login.d.ts +0 -1
- package/esm/actions/login.d.ts.map +1 -1
- package/esm/actions/login.js +0 -1
- package/esm/actions/login.js.map +1 -1
- package/esm/add-cors-header.d.ts +14 -0
- package/esm/add-cors-header.d.ts.map +1 -0
- package/esm/add-cors-header.js +23 -0
- package/esm/add-cors-header.js.map +1 -0
- package/esm/add-cors-header.spec.js +7 -8
- package/esm/add-cors-header.spec.js.map +1 -1
- package/esm/api-manager.d.ts.map +1 -1
- package/esm/api-manager.js +4 -5
- package/esm/api-manager.js.map +1 -1
- package/esm/endpoint-generators/create-delete-endpoint.d.ts +0 -1
- package/esm/endpoint-generators/create-delete-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-delete-endpoint.js +0 -1
- package/esm/endpoint-generators/create-delete-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-delete-endpoint.spec.js +4 -2
- package/esm/endpoint-generators/create-delete-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.d.ts +0 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.js +0 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.spec.js +16 -10
- package/esm/endpoint-generators/create-get-collection-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.d.ts +0 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.js +0 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.spec.js +10 -6
- package/esm/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.d.ts +0 -1
- package/esm/endpoint-generators/create-patch-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.js +2 -2
- package/esm/endpoint-generators/create-patch-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.spec.js +4 -2
- package/esm/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.d.ts +0 -1
- package/esm/endpoint-generators/create-post-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.js +2 -2
- package/esm/endpoint-generators/create-post-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.spec.js +4 -2
- package/esm/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/utils.d.ts.map +1 -1
- package/esm/endpoint-generators/utils.js +0 -2
- package/esm/endpoint-generators/utils.js.map +1 -1
- package/esm/helpers.d.ts.map +1 -1
- package/esm/helpers.js +1 -1
- package/esm/helpers.js.map +1 -1
- package/esm/http-authentication-settings.d.ts +1 -1
- package/esm/http-authentication-settings.d.ts.map +1 -1
- package/esm/http-authentication-settings.js.map +1 -1
- package/esm/http-user-context.d.ts +7 -6
- package/esm/http-user-context.d.ts.map +1 -1
- package/esm/http-user-context.js +17 -5
- package/esm/http-user-context.js.map +1 -1
- package/esm/http-user-context.spec.js +60 -2
- package/esm/http-user-context.spec.js.map +1 -1
- package/esm/incoming-message-extensions.d.ts +0 -2
- package/esm/incoming-message-extensions.d.ts.map +1 -1
- package/esm/incoming-message-extensions.js +1 -10
- package/esm/incoming-message-extensions.js.map +1 -1
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -2
- package/esm/index.js.map +1 -1
- package/esm/models/default-session.d.ts.map +1 -1
- package/esm/models/default-session.js +0 -8
- package/esm/models/default-session.js.map +1 -1
- package/esm/read-post-body.d.ts +12 -0
- package/esm/read-post-body.d.ts.map +1 -0
- package/esm/read-post-body.js +33 -0
- package/esm/read-post-body.js.map +1 -0
- package/esm/request-action-implementation.d.ts +4 -4
- package/esm/request-action-implementation.d.ts.map +1 -1
- package/esm/rest-service.integration.spec.js +24 -33
- package/esm/rest-service.integration.spec.js.map +1 -1
- package/esm/rest.integration.test.js +1 -1
- package/esm/static-server-manager.d.ts.map +1 -1
- package/esm/static-server-manager.js +0 -1
- package/esm/static-server-manager.js.map +1 -1
- package/esm/static-server-manager.spec.js +2 -15
- package/esm/static-server-manager.spec.js.map +1 -1
- package/esm/validate.d.ts +3 -1
- package/esm/validate.d.ts.map +1 -1
- package/esm/validate.integration.spec.js +6 -2
- package/esm/validate.integration.spec.js.map +1 -1
- package/package.json +13 -13
- package/src/actions/login.ts +0 -1
- package/src/add-cors-header.spec.ts +7 -8
- package/src/add-cors-header.ts +32 -0
- package/src/api-manager.ts +5 -5
- package/src/endpoint-generators/create-delete-endpoint.spec.ts +4 -2
- package/src/endpoint-generators/create-delete-endpoint.ts +0 -1
- package/src/endpoint-generators/create-get-collection-endpoint.spec.ts +16 -10
- package/src/endpoint-generators/create-get-collection-endpoint.ts +0 -1
- package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +10 -6
- package/src/endpoint-generators/create-get-entity-endpoint.ts +0 -1
- package/src/endpoint-generators/create-patch-endpoint.spec.ts +4 -2
- package/src/endpoint-generators/create-patch-endpoint.ts +2 -2
- package/src/endpoint-generators/create-post-endpoint.spec.ts +4 -2
- package/src/endpoint-generators/create-post-endpoint.ts +2 -2
- package/src/endpoint-generators/utils.ts +2 -2
- package/src/helpers.ts +1 -1
- package/src/http-authentication-settings.ts +1 -2
- package/src/http-user-context.spec.ts +79 -2
- package/src/http-user-context.ts +29 -10
- package/src/incoming-message-extensions.ts +0 -15
- package/src/index.ts +2 -2
- package/src/models/default-session.ts +2 -2
- package/src/read-post-body.ts +36 -0
- package/src/rest-service.integration.spec.ts +24 -38
- package/src/rest.integration.test.ts +1 -1
- package/src/static-server-manager.spec.ts +2 -18
- package/src/static-server-manager.ts +1 -1
- package/src/validate.integration.spec.ts +9 -2
- package/esm/incoming-message-extensions.spec.d.ts +0 -2
- package/esm/incoming-message-extensions.spec.d.ts.map +0 -1
- package/esm/incoming-message-extensions.spec.js +0 -38
- package/esm/incoming-message-extensions.spec.js.map +0 -1
- package/esm/utils.d.ts +0 -25
- package/esm/utils.d.ts.map +0 -1
- package/esm/utils.js +0 -70
- package/esm/utils.js.map +0 -1
- package/src/incoming-message-extensions.spec.ts +0 -42
- package/src/utils.ts +0 -68
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
import http from 'http'
|
|
2
|
-
import { Utils } from './utils.js'
|
|
3
|
-
|
|
4
1
|
declare module 'http' {
|
|
5
2
|
export interface IncomingMessage {
|
|
6
|
-
readPostBodyRaw: () => Promise<string>
|
|
7
|
-
readPostBody: <T>() => Promise<T>
|
|
8
3
|
postBody: unknown
|
|
9
4
|
}
|
|
10
5
|
}
|
|
11
|
-
|
|
12
|
-
http.IncomingMessage.prototype.readPostBody = async function <T>() {
|
|
13
|
-
const utils = new Utils()
|
|
14
|
-
return await utils.readPostBody<T>(this)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
http.IncomingMessage.prototype.readPostBodyRaw = async function () {
|
|
18
|
-
const utils = new Utils()
|
|
19
|
-
return await utils.readPostBodyRaw(this)
|
|
20
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
export * from './helpers.js'
|
|
2
|
+
export * from './add-cors-header.js'
|
|
2
3
|
export * from './api-manager.js'
|
|
3
4
|
export * from './actions/index.js'
|
|
4
5
|
export * from './authenticate.js'
|
|
5
6
|
export * from './authorize.js'
|
|
6
7
|
export * from './http-authentication-settings.js'
|
|
7
8
|
export * from './http-user-context.js'
|
|
8
|
-
export * from './incoming-message-extensions.js'
|
|
9
9
|
export * from './server-manager.js'
|
|
10
10
|
export * from './server-response-extensions.js'
|
|
11
|
-
export * from './utils.js'
|
|
12
11
|
export * from './models/index.js'
|
|
13
12
|
export * from './endpoint-generators/index.js'
|
|
14
13
|
export * from './schema-validator/index.js'
|
|
15
14
|
export * from './request-action-implementation.js'
|
|
16
15
|
export * from './validate.js'
|
|
17
16
|
export * from './mime-types.js'
|
|
17
|
+
export * from './read-post-body.js'
|
|
18
18
|
export * from './static-server-manager.js'
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'http'
|
|
2
|
+
import './incoming-message-extensions.js'
|
|
3
|
+
|
|
4
|
+
export const readPostBodyRaw = async (incomingMessage: IncomingMessage) => {
|
|
5
|
+
if (!incomingMessage.readable) {
|
|
6
|
+
throw Error('Incoming message is not readable')
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let body = ''
|
|
10
|
+
await new Promise<void>((resolve, reject) => {
|
|
11
|
+
incomingMessage.on('readable', () => {
|
|
12
|
+
const data = incomingMessage.read()
|
|
13
|
+
if (data) {
|
|
14
|
+
body += data
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
incomingMessage.on('end', () => {
|
|
18
|
+
resolve()
|
|
19
|
+
})
|
|
20
|
+
incomingMessage.on('error', (err) => {
|
|
21
|
+
reject(err)
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
return body
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Reads the post's body and returns a promise with a parsed value
|
|
29
|
+
* @param incomingMessage The incoming message instance
|
|
30
|
+
* @returns the parsed object from the post body
|
|
31
|
+
*/
|
|
32
|
+
export const readPostBody = async <T>(incomingMessage: IncomingMessage): Promise<T> => {
|
|
33
|
+
const body = incomingMessage.postBody || JSON.parse(await readPostBodyRaw(incomingMessage))
|
|
34
|
+
incomingMessage.postBody = body
|
|
35
|
+
return body
|
|
36
|
+
}
|
|
@@ -11,10 +11,6 @@ import { describe, it, expect } from 'vitest'
|
|
|
11
11
|
import { serializeValue } from '@furystack/rest'
|
|
12
12
|
import { getPort } from '@furystack/core/port-generator'
|
|
13
13
|
|
|
14
|
-
class UserWithPassword extends User {
|
|
15
|
-
password!: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
14
|
interface IntegrationTestApi extends RestApi {
|
|
19
15
|
GET: {
|
|
20
16
|
'/isAuthenticated': { result: { isAuthenticated: boolean } }
|
|
@@ -29,23 +25,22 @@ interface IntegrationTestApi extends RestApi {
|
|
|
29
25
|
}
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
const
|
|
28
|
+
const createIntegrationApi = async () => {
|
|
29
|
+
const i = new Injector()
|
|
33
30
|
const port = getPort()
|
|
34
|
-
const hostName = 'localhost'
|
|
35
31
|
const root = 'test-api'
|
|
36
32
|
|
|
37
33
|
addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
|
|
38
34
|
new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
|
|
39
35
|
)
|
|
40
36
|
useHttpAuthentication(i, {
|
|
41
|
-
getUserStore: (sm) => sm.getStoreFor(
|
|
37
|
+
getUserStore: (sm) => sm.getStoreFor(User, 'username'),
|
|
42
38
|
getSessionStore: (sm) => sm.getStoreFor(DefaultSession, 'sessionId'),
|
|
43
39
|
})
|
|
44
40
|
await useRestService<IntegrationTestApi>({
|
|
45
41
|
injector: i,
|
|
46
42
|
root,
|
|
47
|
-
port
|
|
48
|
-
hostName,
|
|
43
|
+
port,
|
|
49
44
|
cors: {
|
|
50
45
|
credentials: true,
|
|
51
46
|
origins: ['http://localhost:8080'],
|
|
@@ -71,23 +66,22 @@ const prepareInjector = async (i: Injector) => {
|
|
|
71
66
|
})
|
|
72
67
|
|
|
73
68
|
return {
|
|
74
|
-
apiUrl: `http
|
|
69
|
+
apiUrl: `http://127.0.0.1:${port}/${root}`,
|
|
75
70
|
port,
|
|
76
|
-
|
|
71
|
+
dispose: i.dispose.bind(i),
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
74
|
|
|
80
75
|
describe('@furystack/rest-service inregration tests', () => {
|
|
81
76
|
it('Should be started and disposed', async () => {
|
|
82
|
-
await usingAsync(
|
|
83
|
-
await prepareInjector(i)
|
|
84
|
-
})
|
|
77
|
+
await usingAsync(await createIntegrationApi(), async () => {})
|
|
85
78
|
})
|
|
86
79
|
|
|
87
80
|
it('Should respond with 404 when a route is not found', async () => {
|
|
88
|
-
await usingAsync(
|
|
89
|
-
const
|
|
90
|
-
|
|
81
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
82
|
+
const result = await fetch(PathHelper.joinPaths(apiUrl, 'some-route-that-does-not-exists'), {
|
|
83
|
+
method: 'GET',
|
|
84
|
+
})
|
|
91
85
|
expect(result.ok).toBe(false)
|
|
92
86
|
expect(result.status).toBe(404)
|
|
93
87
|
const responseText = await result.json()
|
|
@@ -96,8 +90,7 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
96
90
|
})
|
|
97
91
|
|
|
98
92
|
it('Should respond with 401 for unauthorized request errors', async () => {
|
|
99
|
-
await usingAsync(
|
|
100
|
-
const { apiUrl } = await prepareInjector(i)
|
|
93
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
101
94
|
const result = await fetch(PathHelper.joinPaths(apiUrl, 'currentUser'))
|
|
102
95
|
expect(result.ok).toBe(false)
|
|
103
96
|
expect(result.status).toBe(401)
|
|
@@ -107,8 +100,7 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
107
100
|
})
|
|
108
101
|
|
|
109
102
|
it('Should respond with 401 for unauthorized request errors', async () => {
|
|
110
|
-
await usingAsync(
|
|
111
|
-
const { apiUrl } = await prepareInjector(i)
|
|
103
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
112
104
|
const result = await fetch(PathHelper.joinPaths(apiUrl, 'currentUser'))
|
|
113
105
|
expect(result.ok).toBe(false)
|
|
114
106
|
expect(result.status).toBe(401)
|
|
@@ -118,8 +110,7 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
118
110
|
})
|
|
119
111
|
|
|
120
112
|
it('Should respond with the correct result body', async () => {
|
|
121
|
-
await usingAsync(
|
|
122
|
-
const { apiUrl } = await prepareInjector(i)
|
|
113
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
123
114
|
const response = await fetch(PathHelper.joinPaths(apiUrl, 'isAuthenticated'))
|
|
124
115
|
expect(response.status).toBe(200)
|
|
125
116
|
const result = await response.json()
|
|
@@ -128,9 +119,8 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
128
119
|
})
|
|
129
120
|
|
|
130
121
|
it('Should be able to read query parameters', async () => {
|
|
131
|
-
await usingAsync(
|
|
132
|
-
|
|
133
|
-
|
|
122
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
123
|
+
console.log('apiUrl', apiUrl)
|
|
134
124
|
const response = await fetch(PathHelper.joinPaths(apiUrl, `testQuery?param1=${serializeValue('foo')}`))
|
|
135
125
|
expect(response.status).toBe(200)
|
|
136
126
|
const result = await response.json()
|
|
@@ -139,9 +129,7 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
139
129
|
})
|
|
140
130
|
|
|
141
131
|
it('Should be able to read url parameters', async () => {
|
|
142
|
-
await usingAsync(
|
|
143
|
-
const { apiUrl } = await prepareInjector(i)
|
|
144
|
-
|
|
132
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
145
133
|
const response = await fetch(PathHelper.joinPaths(apiUrl, 'testUrlParams/bar'))
|
|
146
134
|
expect(response.status).toBe(200)
|
|
147
135
|
const result = await response.json()
|
|
@@ -150,9 +138,7 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
150
138
|
})
|
|
151
139
|
|
|
152
140
|
it('Should be able to read post body', async () => {
|
|
153
|
-
await usingAsync(
|
|
154
|
-
const { apiUrl } = await prepareInjector(i)
|
|
155
|
-
|
|
141
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
156
142
|
const response = await fetch(PathHelper.joinPaths(apiUrl, 'testPostBody'), {
|
|
157
143
|
method: 'POST',
|
|
158
144
|
body: JSON.stringify({ value: 'baz' }),
|
|
@@ -164,20 +150,20 @@ describe('@furystack/rest-service inregration tests', () => {
|
|
|
164
150
|
})
|
|
165
151
|
|
|
166
152
|
it('Should respond with OK to OPTIONS requests', async () => {
|
|
167
|
-
await usingAsync(
|
|
168
|
-
const { apiUrl } = await prepareInjector(i)
|
|
169
|
-
|
|
153
|
+
await usingAsync(await createIntegrationApi(), async ({ apiUrl }) => {
|
|
170
154
|
const response = await fetch(PathHelper.joinPaths(apiUrl, 'testPostBody'), {
|
|
171
155
|
method: 'OPTIONS',
|
|
156
|
+
}).catch((e) => {
|
|
157
|
+
console.log(e)
|
|
158
|
+
throw e
|
|
172
159
|
})
|
|
173
160
|
expect(response.status).toBe(200)
|
|
174
161
|
})
|
|
175
162
|
})
|
|
176
163
|
|
|
177
164
|
it('Should reject requests outside of the API Root', async () => {
|
|
178
|
-
await usingAsync(
|
|
179
|
-
|
|
180
|
-
await expect(fetch(PathHelper.joinPaths(`http://${hostName}:${port}`, 'not-my-api-root'))).rejects.toThrowError(
|
|
165
|
+
await usingAsync(await createIntegrationApi(), async ({ port }) => {
|
|
166
|
+
await expect(fetch(PathHelper.joinPaths(`http://127.0.0.1:${port}`, 'not-my-api-root'))).rejects.toThrowError(
|
|
181
167
|
'fetch failed',
|
|
182
168
|
)
|
|
183
169
|
})
|
|
@@ -3,23 +3,7 @@ import { sleepAsync, usingAsync } from '@furystack/utils'
|
|
|
3
3
|
import { ServerManager } from './server-manager.js'
|
|
4
4
|
import { StaticServerManager } from './static-server-manager.js'
|
|
5
5
|
import { describe, it, expect, vi } from 'vitest'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Generator for an incremental port number
|
|
9
|
-
* @param initialPort The initial port number
|
|
10
|
-
* @yields a port for testing
|
|
11
|
-
* @returns The Port number
|
|
12
|
-
*/
|
|
13
|
-
function* portGenerator(initialPort = 17000) {
|
|
14
|
-
let port = initialPort
|
|
15
|
-
|
|
16
|
-
while (true) {
|
|
17
|
-
yield port++
|
|
18
|
-
}
|
|
19
|
-
return port
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const getPort = () => portGenerator().next().value
|
|
6
|
+
import { getPort } from '@furystack/core/port-generator'
|
|
23
7
|
|
|
24
8
|
describe('StaticServerManager', () => {
|
|
25
9
|
describe('Top level routing', () => {
|
|
@@ -33,7 +17,7 @@ describe('StaticServerManager', () => {
|
|
|
33
17
|
port,
|
|
34
18
|
})
|
|
35
19
|
|
|
36
|
-
const result = await fetch(`http://
|
|
20
|
+
const result = await fetch(`http://127.0.0.1:${port}/not-found.html`)
|
|
37
21
|
expect(result.ok).toBe(false)
|
|
38
22
|
expect(result.status).toBe(404)
|
|
39
23
|
expect(result?.headers.get('content-type')).toBe('text/plain')
|
|
@@ -18,7 +18,7 @@ export interface StaticServerOptions {
|
|
|
18
18
|
@Injectable({ lifetime: 'singleton' })
|
|
19
19
|
export class StaticServerManager {
|
|
20
20
|
@Injected(ServerManager)
|
|
21
|
-
private readonly serverManager
|
|
21
|
+
private declare readonly serverManager: ServerManager
|
|
22
22
|
|
|
23
23
|
private async sendFile({
|
|
24
24
|
fullPath,
|
|
@@ -8,13 +8,19 @@ import type { ValidationApi } from './validate.integration.schema.js'
|
|
|
8
8
|
import { useRestService } from './helpers.js'
|
|
9
9
|
import { describe, it, expect } from 'vitest'
|
|
10
10
|
import { getPort } from '@furystack/core/port-generator'
|
|
11
|
+
import { getStoreManager, InMemoryStore, User } from '@furystack/core'
|
|
12
|
+
import { DefaultSession } from './models/default-session.js'
|
|
11
13
|
|
|
12
14
|
// To recreate: yarn ts-json-schema-generator -f tsconfig.json --no-type-check -p packages/rest-service/src/validate.integration.schema.ts -o packages/rest-service/src/validate.integration.spec.schema.json
|
|
13
15
|
|
|
14
16
|
const createValidateApi = async () => {
|
|
15
17
|
const injector = new Injector()
|
|
16
18
|
const port = getPort()
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
getStoreManager(injector).addStore(new InMemoryStore({ model: User, primaryKey: 'username' }))
|
|
21
|
+
getStoreManager(injector).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
|
|
22
|
+
|
|
23
|
+
await useRestService<ValidationApi>({
|
|
18
24
|
injector,
|
|
19
25
|
api: {
|
|
20
26
|
GET: {
|
|
@@ -54,8 +60,9 @@ const createValidateApi = async () => {
|
|
|
54
60
|
root: '/api',
|
|
55
61
|
})
|
|
56
62
|
const client = createClient<ValidationApi>({
|
|
57
|
-
endpointUrl: `http://
|
|
63
|
+
endpointUrl: `http://127.0.0.1:${port}/api`,
|
|
58
64
|
})
|
|
65
|
+
|
|
59
66
|
return {
|
|
60
67
|
dispose: injector.dispose.bind(injector),
|
|
61
68
|
client,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"incoming-message-extensions.spec.d.ts","sourceRoot":"","sources":["../src/incoming-message-extensions.spec.ts"],"names":[],"mappings":"AACA,OAAO,+BAA+B,CAAA"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage } from 'http';
|
|
2
|
-
import './incoming-message-extensions';
|
|
3
|
-
import { Socket } from 'net';
|
|
4
|
-
import { describe, it, expect } from 'vitest';
|
|
5
|
-
describe('IncomingMessage extensions', () => {
|
|
6
|
-
describe('readPostBody', () => {
|
|
7
|
-
it('Should be extended', () => {
|
|
8
|
-
const socket = new Socket();
|
|
9
|
-
const msg = new IncomingMessage(socket);
|
|
10
|
-
expect(typeof msg.readPostBody).toBe('function');
|
|
11
|
-
});
|
|
12
|
-
it('Should read the raw post body', async () => {
|
|
13
|
-
const exampleValue = { value: Math.random().toString() };
|
|
14
|
-
const socket = new Socket();
|
|
15
|
-
const msg = new IncomingMessage(socket);
|
|
16
|
-
setTimeout(() => {
|
|
17
|
-
msg.read = () => JSON.stringify(exampleValue);
|
|
18
|
-
msg.emit('readable');
|
|
19
|
-
msg.emit('end');
|
|
20
|
-
}, 10);
|
|
21
|
-
const result = await msg.readPostBodyRaw();
|
|
22
|
-
expect(result).toEqual(JSON.stringify(exampleValue));
|
|
23
|
-
});
|
|
24
|
-
it('Should read the post body', async () => {
|
|
25
|
-
const exampleValue = { value: Math.random().toString() };
|
|
26
|
-
const socket = new Socket();
|
|
27
|
-
const msg = new IncomingMessage(socket);
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
msg.read = () => JSON.stringify(exampleValue);
|
|
30
|
-
msg.emit('readable');
|
|
31
|
-
msg.emit('end');
|
|
32
|
-
}, 10);
|
|
33
|
-
const result = await msg.readPostBody();
|
|
34
|
-
expect(result).toEqual(exampleValue);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
//# sourceMappingURL=incoming-message-extensions.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"incoming-message-extensions.spec.js","sourceRoot":"","sources":["../src/incoming-message-extensions.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AACtC,OAAO,+BAA+B,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE7C,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;YAC3B,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;YACvC,MAAM,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAA;YACxD,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;YAC3B,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;YACvC,UAAU,CAAC,GAAG,EAAE;gBACd,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;gBAC7C,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBACpB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,CAAC,EAAE,EAAE,CAAC,CAAA;YAEN,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAA;YAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAA;QACtD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAA;YACxD,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;YAC3B,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;YACvC,UAAU,CAAC,GAAG,EAAE;gBACd,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;gBAC7C,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBACpB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,CAAC,EAAE,EAAE,CAAC,CAAA;YAEN,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAA;YACvC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
package/esm/utils.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/// <reference path="server-response-extensions.d.ts" />
|
|
2
|
-
/// <reference path="incoming-message-extensions.d.ts" />
|
|
3
|
-
/// <reference types="node/http.js" />
|
|
4
|
-
import type { IncomingMessage, ServerResponse } from 'http';
|
|
5
|
-
import type { CorsOptions } from './models/cors-options.js';
|
|
6
|
-
/**
|
|
7
|
-
* A collection of various HTTP API related utilities
|
|
8
|
-
*/
|
|
9
|
-
export declare class Utils {
|
|
10
|
-
readPostBodyRaw(incomingMessage: IncomingMessage): Promise<string>;
|
|
11
|
-
/**
|
|
12
|
-
* Reads the post's body and returns a promise with a parsed value
|
|
13
|
-
* @param incomingMessage The incoming message instance
|
|
14
|
-
* @returns the parsed object from the post body
|
|
15
|
-
*/
|
|
16
|
-
readPostBody<T>(incomingMessage: IncomingMessage): Promise<T>;
|
|
17
|
-
/**
|
|
18
|
-
* Adds the specified CORS headers to the response
|
|
19
|
-
* @param options The CORS Options object
|
|
20
|
-
* @param incomingMessage The incoming message instance
|
|
21
|
-
* @param serverResponse The outgoing response instance
|
|
22
|
-
*/
|
|
23
|
-
addCorsHeaders(options: CorsOptions, incomingMessage: IncomingMessage, serverResponse: ServerResponse): void;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=utils.d.ts.map
|
package/esm/utils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D;;GAEG;AACH,qBACa,KAAK;IACH,eAAe,CAAC,eAAe,EAAE,eAAe;IAuB7D;;;;OAIG;IACU,YAAY,CAAC,CAAC,EAAE,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,CAAC,CAAC;IAM1E;;;;;OAKG;IACI,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc;CAkB7G"}
|
package/esm/utils.js
DELETED
|
@@ -1,70 +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
|
-
import { Injectable } from '@furystack/inject';
|
|
8
|
-
/**
|
|
9
|
-
* A collection of various HTTP API related utilities
|
|
10
|
-
*/
|
|
11
|
-
let Utils = class Utils {
|
|
12
|
-
async readPostBodyRaw(incomingMessage) {
|
|
13
|
-
if (!incomingMessage.readable) {
|
|
14
|
-
throw Error('Incoming message is not readable');
|
|
15
|
-
}
|
|
16
|
-
let body = '';
|
|
17
|
-
await new Promise((resolve, reject) => {
|
|
18
|
-
incomingMessage.on('readable', () => {
|
|
19
|
-
const data = incomingMessage.read();
|
|
20
|
-
if (data) {
|
|
21
|
-
body += data;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
incomingMessage.on('end', () => {
|
|
25
|
-
resolve();
|
|
26
|
-
});
|
|
27
|
-
incomingMessage.on('error', (err) => {
|
|
28
|
-
reject(err);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
return body;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Reads the post's body and returns a promise with a parsed value
|
|
35
|
-
* @param incomingMessage The incoming message instance
|
|
36
|
-
* @returns the parsed object from the post body
|
|
37
|
-
*/
|
|
38
|
-
async readPostBody(incomingMessage) {
|
|
39
|
-
const body = incomingMessage.postBody || JSON.parse(await this.readPostBodyRaw(incomingMessage));
|
|
40
|
-
incomingMessage.postBody = body;
|
|
41
|
-
return body;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Adds the specified CORS headers to the response
|
|
45
|
-
* @param options The CORS Options object
|
|
46
|
-
* @param incomingMessage The incoming message instance
|
|
47
|
-
* @param serverResponse The outgoing response instance
|
|
48
|
-
*/
|
|
49
|
-
addCorsHeaders(options, incomingMessage, serverResponse) {
|
|
50
|
-
if (incomingMessage.headers &&
|
|
51
|
-
incomingMessage.headers.origin !== incomingMessage.headers.host &&
|
|
52
|
-
options.origins.some((origin) => origin === incomingMessage.headers.origin)) {
|
|
53
|
-
serverResponse.setHeader('Access-Control-Allow-Origin', incomingMessage.headers.origin);
|
|
54
|
-
if (options.credentials) {
|
|
55
|
-
serverResponse.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
56
|
-
}
|
|
57
|
-
if (options.headers && options.headers.length) {
|
|
58
|
-
serverResponse.setHeader('Access-Control-Allow-Headers', options.headers.join(', '));
|
|
59
|
-
}
|
|
60
|
-
if (options.methods && options.methods.length) {
|
|
61
|
-
serverResponse.setHeader('Access-Control-Allow-Methods', options.methods.join(', '));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
Utils = __decorate([
|
|
67
|
-
Injectable({ lifetime: 'transient' })
|
|
68
|
-
], Utils);
|
|
69
|
-
export { Utils };
|
|
70
|
-
//# sourceMappingURL=utils.js.map
|
package/esm/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAG9C;;GAEG;AAEI,IAAM,KAAK,GAAX,MAAM,KAAK;IACT,KAAK,CAAC,eAAe,CAAC,eAAgC;QAC3D,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC,kCAAkC,CAAC,CAAA;QACjD,CAAC;QAED,IAAI,IAAI,GAAG,EAAE,CAAA;QACb,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;gBAClC,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,CAAA;gBACnC,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,IAAI,IAAI,CAAA;gBACd,CAAC;YACH,CAAC,CAAC,CAAA;YACF,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBAC7B,OAAO,EAAE,CAAA;YACX,CAAC,CAAC,CAAA;YACF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAClC,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,YAAY,CAAI,eAAgC;QAC3D,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAA;QAChG,eAAe,CAAC,QAAQ,GAAG,IAAI,CAAA;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;OAKG;IACI,cAAc,CAAC,OAAoB,EAAE,eAAgC,EAAE,cAA8B;QAC1G,IACE,eAAe,CAAC,OAAO;YACvB,eAAe,CAAC,OAAO,CAAC,MAAM,KAAK,eAAe,CAAC,OAAO,CAAC,IAAI;YAC/D,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3E,CAAC;YACD,cAAc,CAAC,SAAS,CAAC,6BAA6B,EAAE,eAAe,CAAC,OAAO,CAAC,MAAgB,CAAC,CAAA;YACjG,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,cAAc,CAAC,SAAS,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAA;YACtE,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC9C,cAAc,CAAC,SAAS,CAAC,8BAA8B,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YACtF,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC9C,cAAc,CAAC,SAAS,CAAC,8BAA8B,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YACtF,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA;AA3DY,KAAK;IADjB,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;GACzB,KAAK,CA2DjB"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage } from 'http'
|
|
2
|
-
import './incoming-message-extensions'
|
|
3
|
-
import { Socket } from 'net'
|
|
4
|
-
import { describe, it, expect } from 'vitest'
|
|
5
|
-
|
|
6
|
-
describe('IncomingMessage extensions', () => {
|
|
7
|
-
describe('readPostBody', () => {
|
|
8
|
-
it('Should be extended', () => {
|
|
9
|
-
const socket = new Socket()
|
|
10
|
-
const msg = new IncomingMessage(socket)
|
|
11
|
-
expect(typeof msg.readPostBody).toBe('function')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('Should read the raw post body', async () => {
|
|
15
|
-
const exampleValue = { value: Math.random().toString() }
|
|
16
|
-
const socket = new Socket()
|
|
17
|
-
const msg = new IncomingMessage(socket)
|
|
18
|
-
setTimeout(() => {
|
|
19
|
-
msg.read = () => JSON.stringify(exampleValue)
|
|
20
|
-
msg.emit('readable')
|
|
21
|
-
msg.emit('end')
|
|
22
|
-
}, 10)
|
|
23
|
-
|
|
24
|
-
const result = await msg.readPostBodyRaw()
|
|
25
|
-
expect(result).toEqual(JSON.stringify(exampleValue))
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('Should read the post body', async () => {
|
|
29
|
-
const exampleValue = { value: Math.random().toString() }
|
|
30
|
-
const socket = new Socket()
|
|
31
|
-
const msg = new IncomingMessage(socket)
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
msg.read = () => JSON.stringify(exampleValue)
|
|
34
|
-
msg.emit('readable')
|
|
35
|
-
msg.emit('end')
|
|
36
|
-
}, 10)
|
|
37
|
-
|
|
38
|
-
const result = await msg.readPostBody()
|
|
39
|
-
expect(result).toEqual(exampleValue)
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
})
|
package/src/utils.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import type { IncomingMessage, ServerResponse } from 'http'
|
|
2
|
-
import { Injectable } from '@furystack/inject'
|
|
3
|
-
import type { CorsOptions } from './models/cors-options.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A collection of various HTTP API related utilities
|
|
7
|
-
*/
|
|
8
|
-
@Injectable({ lifetime: 'transient' })
|
|
9
|
-
export class Utils {
|
|
10
|
-
public async readPostBodyRaw(incomingMessage: IncomingMessage) {
|
|
11
|
-
if (!incomingMessage.readable) {
|
|
12
|
-
throw Error('Incoming message is not readable')
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let body = ''
|
|
16
|
-
await new Promise<void>((resolve, reject) => {
|
|
17
|
-
incomingMessage.on('readable', () => {
|
|
18
|
-
const data = incomingMessage.read()
|
|
19
|
-
if (data) {
|
|
20
|
-
body += data
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
incomingMessage.on('end', () => {
|
|
24
|
-
resolve()
|
|
25
|
-
})
|
|
26
|
-
incomingMessage.on('error', (err) => {
|
|
27
|
-
reject(err)
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
return body
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Reads the post's body and returns a promise with a parsed value
|
|
35
|
-
* @param incomingMessage The incoming message instance
|
|
36
|
-
* @returns the parsed object from the post body
|
|
37
|
-
*/
|
|
38
|
-
public async readPostBody<T>(incomingMessage: IncomingMessage): Promise<T> {
|
|
39
|
-
const body = incomingMessage.postBody || JSON.parse(await this.readPostBodyRaw(incomingMessage))
|
|
40
|
-
incomingMessage.postBody = body
|
|
41
|
-
return body
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Adds the specified CORS headers to the response
|
|
46
|
-
* @param options The CORS Options object
|
|
47
|
-
* @param incomingMessage The incoming message instance
|
|
48
|
-
* @param serverResponse The outgoing response instance
|
|
49
|
-
*/
|
|
50
|
-
public addCorsHeaders(options: CorsOptions, incomingMessage: IncomingMessage, serverResponse: ServerResponse) {
|
|
51
|
-
if (
|
|
52
|
-
incomingMessage.headers &&
|
|
53
|
-
incomingMessage.headers.origin !== incomingMessage.headers.host &&
|
|
54
|
-
options.origins.some((origin) => origin === incomingMessage.headers.origin)
|
|
55
|
-
) {
|
|
56
|
-
serverResponse.setHeader('Access-Control-Allow-Origin', incomingMessage.headers.origin as string)
|
|
57
|
-
if (options.credentials) {
|
|
58
|
-
serverResponse.setHeader('Access-Control-Allow-Credentials', 'true')
|
|
59
|
-
}
|
|
60
|
-
if (options.headers && options.headers.length) {
|
|
61
|
-
serverResponse.setHeader('Access-Control-Allow-Headers', options.headers.join(', '))
|
|
62
|
-
}
|
|
63
|
-
if (options.methods && options.methods.length) {
|
|
64
|
-
serverResponse.setHeader('Access-Control-Allow-Methods', options.methods.join(', '))
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|