objective-http 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,17 +15,14 @@ const {
15
15
  LoggedServer,
16
16
  endpoint: {
17
17
  Endpoint,
18
- LoggedEndpoint,
19
18
  Endpoints
20
19
  },
21
20
  request: {
22
21
  InputRequest,
23
- JsonInputRequest,
24
22
  LoggedInputRequest,
25
23
  },
26
24
  response: {
27
25
  OutputResponse,
28
- JsonOutputResponse,
29
26
  LoggedOutputResponse
30
27
  }
31
28
  } = require('objective-http').server;
@@ -33,13 +30,13 @@ const {
33
30
  new LoggedServer(
34
31
  new Server(
35
32
  new Endpoints([
36
- new LoggedEndpoint(new MyFirstEndpoint(), console),
37
- new LoggedEndpoint(new MySecondEndpoint(), console),
38
- new LoggedEndpoint(new MyThirdEndpoint(), console)
33
+ new MyFirstEndpoint(),
34
+ new MySecondEndpoint(),
35
+ new MyThirdEndpoint()
39
36
  ]),
40
37
  {port: server_port},
41
- new LoggedInputRequest(new JsonInputRequest(new InputRequest()), console),
42
- new LoggedOutputResponse(new JsonOutputResponse(new OutputResponse()), console),
38
+ new LoggedInputRequest(new InputRequest(), console),
39
+ new LoggedOutputResponse(new OutputResponse(), console),
43
40
  createServerFunction
44
41
  ),
45
42
  console
@@ -139,17 +136,14 @@ const {
139
136
  LoggedServer,
140
137
  endpoint: {
141
138
  Endpoint,
142
- LoggedEndpoint,
143
139
  Endpoints
144
140
  },
145
141
  request: {
146
142
  InputRequest,
147
- JsonInputRequest,
148
143
  LoggedInputRequest,
149
144
  },
150
145
  response: {
151
146
  OutputResponse,
152
- JsonOutputResponse,
153
147
  LoggedOutputResponse
154
148
  }
155
149
  } = require('objective-http').server;
@@ -157,13 +151,13 @@ const {
157
151
  new LoggedServer(
158
152
  new Server(
159
153
  new Endpoints([
160
- new LoggedEndpoint(new MyFirstEndpoint(), console),
161
- new LoggedEndpoint(new MySecondEndpoint(), console),
162
- new LoggedEndpoint(new MyThirdEndpoint(), console)
154
+ new MyFirstEndpoint(),
155
+ new MySecondEndpoint(),
156
+ new MyThirdEndpoint()
163
157
  ]),
164
158
  {port: server_port},
165
- new LoggedInputRequest(new JsonInputRequest(new InputRequest()), console),
166
- new LoggedOutputResponse(new JsonOutputResponse(new OutputResponse()), console),
159
+ new LoggedInputRequest(new InputRequest(), console),
160
+ new LoggedOutputResponse(new OutputResponse(), console),
167
161
  createServerFunction
168
162
  ),
169
163
  console
@@ -181,15 +175,12 @@ const {
181
175
  LoggedServer,
182
176
  endpoint: {
183
177
  Endpoint,
184
- LoggedEndpoint,
185
178
  Endpoints
186
179
  },
187
180
  request: {
188
- JsonInputRequest,
189
181
  LoggedInputRequest,
190
182
  },
191
183
  response: {
192
- JsonOutputResponse,
193
184
  LoggedOutputResponse
194
185
  }
195
186
  } = require('objective-http').server;
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"objective-http","version":"1.3.0","description":"Proxy classes for creating a http server","keywords":["web","web-server","http","http-server","oop"],"author":{"name":"volatilization","email":"volatilization@yandex.ru"},"repository":{"url":"git+https://github.com/volatilization/objective-http.git"},"license":"LGPL-3.0-only","main":"src/js/index.js"}
1
+ {"name":"objective-http","version":"1.4.0","description":"Proxy classes for creating a http server","keywords":["web","web-server","http","http-server","oop"],"author":{"name":"volatilization","email":"volatilization@yandex.ru"},"repository":{"url":"git+https://github.com/volatilization/objective-http.git"},"license":"LGPL-3.0-only","main":"src/js/index.js"}
@@ -12,16 +12,13 @@ module.exports = class Bunttp {
12
12
  }
13
13
 
14
14
  listen(options, cb) {
15
- const config = {...this.#serverConfig, port: options.port};
16
- const server = Bun.serve(config);
15
+ this.#server = Bun.serve({...this.#serverConfig, port: options.port});
17
16
  cb();
18
- return new Bunttp(config, server);
19
17
  }
20
18
 
21
19
  close(cb) {
22
- const server = this.#server.stop();
20
+ this.#server.stop();
23
21
  cb();
24
- return new Bunttp(this.#serverConfig, server);
25
22
  }
26
23
 
27
24
  request = fetch;
@@ -16,8 +16,10 @@ module.exports = class InputRequest {
16
16
  return new InputRequest(
17
17
  this.#inputStream,
18
18
  {
19
- method: this.#inputStream.method,
20
- path: new URL(this.#inputStream.url).pathname,
19
+ route: {
20
+ method: this.#inputStream.method,
21
+ path: new URL(this.#inputStream.url).pathname
22
+ },
21
23
  query: new URL(this.#inputStream.url).searchParams,
22
24
  headers: this.#inputStream.headers,
23
25
  body: Buffer.from(await (await this.#inputStream.blob()).arrayBuffer())
@@ -30,10 +32,7 @@ module.exports = class InputRequest {
30
32
  }
31
33
 
32
34
  route() {
33
- return {
34
- method: this.#options.method.toString().toUpperCase(),
35
- path: this.#options.path.toString().toLowerCase()
36
- }
35
+ return this.#options.route;
37
36
  }
38
37
 
39
38
  query() {
@@ -7,14 +7,10 @@ module.exports = class OutputResponse {
7
7
  this.#outputStream = outputStream;
8
8
  }
9
9
 
10
- copy(options = this.#options, outputStream = this.#outputStream) {
10
+ copy(outputStream = this.#outputStream, options = this.#options) {
11
11
  return new OutputResponse({...{statusCode: 200, headers: {}}, ...options}, outputStream);
12
12
  }
13
13
 
14
- update(options) {
15
- return new OutputResponse(this.#mergeOptions(this.#options, options), this.#outputStream);
16
- }
17
-
18
14
  flush() {
19
15
  try {
20
16
  return new Response(this.#options.body, {
@@ -26,24 +22,4 @@ module.exports = class OutputResponse {
26
22
  throw new Error(e.message, {cause: 'INVALID_RESPONSE'});
27
23
  }
28
24
  }
29
-
30
- #mergeOptions(existedOptions, newOptions) {
31
- if (newOptions == null) {
32
- return existedOptions;
33
- }
34
-
35
- if (newOptions.statusCode != null) {
36
- existedOptions.statusCode = newOptions.statusCode;
37
- }
38
-
39
- if (newOptions.body != null) {
40
- existedOptions.body = newOptions.body;
41
- }
42
-
43
- if (newOptions.headers != null) {
44
- existedOptions.headers = {...existedOptions.headers, ...newOptions.headers};
45
- }
46
-
47
- return existedOptions;
48
- }
49
25
  }
@@ -10,72 +10,44 @@ module.exports = class OutputRequest {
10
10
  }
11
11
 
12
12
  copy(options = this.#options, response = this.#response, http = this.#requestFunction) {
13
- return new OutputRequest(response, http, {method: 'GET', ...options});
13
+ return new OutputRequest(response, http, {method: 'GET', ...options});
14
14
  }
15
15
 
16
- async send() {
17
- try {
18
- return await new Promise((resolve, reject) => {
19
- this.#sendRequestOutputStream(
20
- this.#configureRequestOutputStream(this.#requestFunction, this.#response, this.#options, resolve, reject),
16
+ send() {
17
+ return new Promise((resolve, reject) => {
18
+ try {
19
+ const requestOutputStream = this.#requestFunction(
20
+ this.#options.url,
21
21
  this.#options,
22
- reject);
23
- });
24
-
25
- } catch (e) {
26
- if (e.cause == null) {
27
- throw new Error(e.message, {cause: 'INVALID_REQUEST'});
28
- }
22
+ async (responseInputStream) => {
23
+ try {
24
+ resolve(await this.#response
25
+ .copy(responseInputStream)
26
+ .flush());
27
+
28
+ } catch (e) {
29
+ reject(new Error(e.message, {cause: 'INVALID_REQUEST'}));
30
+ }
31
+ });
32
+
33
+ requestOutputStream.once('error', e => {
34
+ reject(new Error(e.message, {cause: 'INVALID_REQUEST'}));
35
+ });
29
36
 
30
- throw e;
31
- }
32
- }
37
+ if (this.#needToByWritten(this.#options)) {
38
+ requestOutputStream.write(this.#options.body);
39
+ }
33
40
 
34
- #sendRequestOutputStream(requestOutputStream, options, reject) {
35
- try {
36
- requestOutputStream.once('error', e => reject(e));
41
+ requestOutputStream.end();
37
42
 
38
- if (this.#needToByWritten(options)) {
39
- requestOutputStream.write(options.body);
43
+ } catch (e) {
44
+ reject(new Error(e.message, {cause: 'INVALID_REQUEST'}));
40
45
  }
41
-
42
- requestOutputStream.end();
43
-
44
- } catch (e) {
45
- reject(e);
46
- }
46
+ });
47
47
  }
48
48
 
49
49
  #needToByWritten(options) {
50
50
  return ['POST', 'PUT'].some(method => method === options.method.toString().toUpperCase())
51
51
  && (options.body != null && typeof options.body === 'string');
52
52
  }
53
-
54
- #configureRequestOutputStream(requestFunction, response, options, resolve, reject) {
55
- if (options.url != null) {
56
- return requestFunction(
57
- options.url,
58
- options,
59
- async (responseInputStream) => {
60
- await this.#flushResponseInputStream(responseInputStream, response, resolve, reject);
61
- });
62
- }
63
-
64
- return requestFunction(
65
- options,
66
- async (responseInputStream) => {
67
- await this.#flushResponseInputStream(responseInputStream, response, resolve, reject);
68
- });
69
- }
70
-
71
- async #flushResponseInputStream(responseInputStream, response, resolve, reject) {
72
- try {
73
- resolve(await response
74
- .copy(responseInputStream)
75
- .flush());
76
-
77
- } catch (e) {
78
- reject(e);
79
- }
80
- }
81
53
  };
@@ -24,35 +24,25 @@ module.exports = class InputResponse {
24
24
  }
25
25
 
26
26
  async flush() {
27
- try {
28
- return await new Promise((resolve, reject) => {
29
- this.#flushResponseInputStream(this.#inputStream, resolve, reject);
30
- });
31
-
32
- } catch (e) {
33
- throw new Error(e.message, {cause: 'INVALID_RESPONSE'});
34
- }
35
- }
36
-
37
- #flushResponseInputStream(inputStream, resolve, reject) {
38
- try {
39
- inputStream.once('error', (e) => reject(e));
40
-
41
- let chunks = [];
42
- inputStream.on('data', (chunk) => chunks.push(chunk));
43
- inputStream.on('end', () => resolve(
44
- new InputResponse(
45
- inputStream,
46
- {
47
- statusCode: inputStream.statusCode,
48
- headers: new Headers(inputStream.headers),
49
- body: Buffer.concat(chunks)
50
- }
51
- )
52
- ));
53
-
54
- } catch (e) {
55
- reject(e);
56
- }
27
+ return await new Promise((resolve, reject) => {
28
+ try {
29
+ this.#inputStream.once('error', (e) => reject(new Error(e.message, {cause: 'INVALID_RESPONSE'})));
30
+
31
+ let chunks = [];
32
+ this.#inputStream.on('data', (chunk) => chunks.push(chunk));
33
+ this.#inputStream.on('end', () => resolve(
34
+ new InputResponse(
35
+ this.#inputStream,
36
+ {
37
+ statusCode: this.#inputStream.statusCode,
38
+ headers: new Headers(this.#inputStream.headers),
39
+ body: Buffer.concat(chunks)
40
+ }
41
+ )
42
+ ));
43
+ } catch (e) {
44
+ throw new Error(e.message, {cause: 'INVALID_RESPONSE'});
45
+ }
46
+ });
57
47
  }
58
48
  };
package/src/js/index.js CHANGED
@@ -1,9 +1,5 @@
1
1
  module.exports = {
2
2
  server: require('./server'),
3
3
  client: require('./client'),
4
- bun: {
5
- server: {...require('./server'), ...require('./bun').server},
6
- client: {...require('./client'), ...require('./bun').client},
7
- bunttp: require('./bun').bunttp
8
- }
4
+ bun: require('./bun')
9
5
  }
@@ -7,10 +7,14 @@ module.exports = class LoggedServer {
7
7
  this.#logger = logger;
8
8
  }
9
9
 
10
+ options() {
11
+ return this.#origin.options();
12
+ }
13
+
10
14
  async start() {
11
15
  const server = await this.#origin.start();
12
16
 
13
- this.#logger.debug(`HttpServer is running at port: ${server.options().port}`);
17
+ this.#logger.debug(`HttpServer is running at port: ${this.#origin.options().port}`);
14
18
 
15
19
  return new LoggedServer(server, this.#logger);
16
20
  }
@@ -18,13 +22,8 @@ module.exports = class LoggedServer {
18
22
  async stop() {
19
23
  const server = await this.#origin.stop();
20
24
 
21
- this.#logger.debug(`HttpServer at port: ${server.options().port} is stopped`);
25
+ this.#logger.debug(`HttpServer at port: ${this.#origin.options().port} is stopped`);
22
26
 
23
27
  return new LoggedServer(server, this.#logger);
24
28
  }
25
-
26
-
27
- options() {
28
- return this.#origin.options();
29
- }
30
29
  }
@@ -15,31 +15,39 @@ module.exports = class Server {
15
15
  this.#server = server;
16
16
  }
17
17
 
18
+ options() {
19
+ return this.#options;
20
+ }
21
+
18
22
  start() {
19
23
  const server = this.#createServerFunction(async (requestStream, responseStream) => {
20
24
  try {
21
- return await (this.#response
22
- .copy(await this.#endpoints
23
- .handle(await (this.#request
24
- .copy(requestStream))
25
- .flush()), responseStream))
25
+ return await this.#response
26
+ .copy(responseStream,
27
+ await this.#endpoints
28
+ .handle(await this.#request
29
+ .copy(requestStream)
30
+ .flush()))
26
31
  .flush();
27
32
 
28
33
  } catch (e) {
29
34
  if (e.cause === 'INVALID_REQUEST') {
30
35
  return this.#response
31
- .copy({
32
- statusCode: 400,
33
- body: e.message
34
- }, responseStream)
36
+ .copy(responseStream,
37
+ {statusCode: 400, body: e.message})
38
+ .flush();
39
+ }
40
+
41
+ if (e.cause === 'HANDLER_NOT_FOUND') {
42
+ return this.#response
43
+ .copy(responseStream,
44
+ {statusCode: 501, body: e.message})
35
45
  .flush();
36
46
  }
37
47
 
38
48
  return this.#response
39
- .copy({
40
- statusCode: 500,
41
- body: 'Unexpected server error.'
42
- }, responseStream)
49
+ .copy(responseStream,
50
+ {statusCode: 500, body: 'Unexpected server error.'})
43
51
  .flush();
44
52
  }
45
53
  });
@@ -47,21 +55,21 @@ module.exports = class Server {
47
55
  return new Promise(resolve => {
48
56
  server.listen(
49
57
  this.#options,
50
- () => {
51
- resolve(new Server(
52
- this.#endpoints,
53
- this.#options,
54
- this.#request,
55
- this.#response,
56
- this.#createServerFunction,
57
- server));
58
- }
58
+ () => resolve(new Server(
59
+ this.#endpoints,
60
+ this.#options,
61
+ this.#request,
62
+ this.#response,
63
+ this.#createServerFunction,
64
+ server))
59
65
  );
60
66
  });
61
67
  }
62
68
 
63
69
  stop() {
64
70
  return new Promise(resolve => {
71
+ console.log('stop ', this.#server);
72
+
65
73
  this.#server.close(
66
74
  () => resolve(new Server(
67
75
  this.#endpoints,
@@ -72,8 +80,4 @@ module.exports = class Server {
72
80
  );
73
81
  });
74
82
  }
75
-
76
- options() {
77
- return this.#options;
78
- }
79
83
  };
@@ -1,24 +1,17 @@
1
1
  module.exports = class Endpoint {
2
- #method;
3
- #path;
2
+ #route;
4
3
 
5
- constructor(method, path) {
6
- this.#method = method;
7
- this.#path = path;
4
+ constructor(route) {
5
+ this.#route = route;
8
6
  }
9
7
 
10
- copy(method = this.#method, path = this.#path) {
11
- return new Endpoint(method, path);
8
+ route() {
9
+ return this.#route;
12
10
  }
13
11
 
14
- route() {
12
+ async handle() {
15
13
  return {
16
- method: this.#method.toString().toUpperCase(),
17
- path: this.#path.toString().toLowerCase()
14
+ statusCode: 200
18
15
  };
19
16
  }
20
-
21
- async handle(request) {
22
- return {};
23
- }
24
17
  }
@@ -1,26 +1,36 @@
1
1
  module.exports = class Endpoints {
2
- #collection;
2
+ #map;
3
3
 
4
- constructor(collection = []) {
5
- this.#collection = collection;
4
+ constructor(collection = [], map = new Map()) {
5
+ this.#map = map;
6
+ collection.forEach((endpoint) => {
7
+ if (!this.#map.has(endpoint.route().path.toString().toLowerCase())) {
8
+ this.#map.set(endpoint.route().path.toString().toLowerCase(), new Map());
9
+ }
10
+
11
+ this.#map
12
+ .get(endpoint.route().path.toString().toLowerCase())
13
+ .set(endpoint.route().method.toString().toUpperCase(),
14
+ endpoint);
15
+ });
6
16
  }
7
17
 
8
- copy(collection = this.#collection) {
9
- return new Endpoints(collection);
18
+ copy(collection, map = this.#map) {
19
+ return new Endpoints(collection, map);
10
20
  }
11
21
 
12
22
  async handle(request) {
13
- const endpoint = this.#collection
14
- .find(endpoint => endpoint.route().method === request.route().method
15
- && endpoint.route().path === request.route().path);
16
-
17
- if (endpoint == null) {
18
- return {
19
- statusCode: 501,
20
- body: 'There are no handler for request.'
21
- }
23
+ if (!this.#map.has(request.route().path.toString().toLowerCase())
24
+ || !this.#map
25
+ .get(request.route().path.toString().toLowerCase())
26
+ .has(request.route().method.toString().toUpperCase())
27
+ ) {
28
+ throw new Error('There are no handler for request.', {cause: 'HANDLER_NOT_FOUND'});
22
29
  }
23
30
 
24
- return await endpoint.handle(request);
31
+ return await this.#map
32
+ .get(request.route().path.toString().toLowerCase())
33
+ .get(request.route().method.toString().toUpperCase())
34
+ .handle(request);
25
35
  }
26
36
  }
@@ -1,5 +1,4 @@
1
1
  module.exports = {
2
2
  Endpoint: require('./Endpoint'),
3
- LoggedEndpoint: require('./LoggedEndpoint'),
4
3
  Endpoints: require('./Endpoints'),
5
4
  };
@@ -11,6 +11,22 @@ module.exports = class InputRequest {
11
11
  return new InputRequest(inputStream, options);
12
12
  }
13
13
 
14
+ route() {
15
+ return this.#options.route;
16
+ }
17
+
18
+ query() {
19
+ return this.#options.query;
20
+ }
21
+
22
+ body() {
23
+ return this.#options.body;
24
+ }
25
+
26
+ headers() {
27
+ return this.#options.headers;
28
+ }
29
+
14
30
  flush() {
15
31
  return new Promise((resolve, reject) => {
16
32
  try {
@@ -23,36 +39,19 @@ module.exports = class InputRequest {
23
39
  this.#inputStream.on('end', () => resolve(new InputRequest(
24
40
  this.#inputStream,
25
41
  {
26
- method: this.#inputStream.method,
27
- path: new URL(this.#inputStream.url, 'http://dummy').pathname,
28
- query: new URL(this.#inputStream.url, 'http://dummy').searchParams,
42
+ route: {
43
+ method: this.#inputStream.method,
44
+ path: new URL(this.#inputStream.url, 'http://url').pathname
45
+ },
46
+ query: new URL(this.#inputStream.url, 'http://url').searchParams,
29
47
  headers: new Headers(this.#inputStream.headers),
30
- body: Buffer.concat(chunks)
48
+ body: Buffer.concat(chunks),
31
49
  }
32
50
  )));
33
51
 
34
52
  } catch (e) {
35
- throw new Error(e.message, {cause: 'INVALID_REQUEST'});
53
+ reject(new Error(e.message, {cause: 'INVALID_REQUEST'}));
36
54
  }
37
55
  });
38
56
  }
39
-
40
- route() {
41
- return {
42
- method: this.#options.method.toString().toUpperCase(),
43
- path: this.#options.path.toString().toLowerCase()
44
- };
45
- }
46
-
47
- query() {
48
- return this.#options.query;
49
- }
50
-
51
- body() {
52
- return this.#options.body;
53
- }
54
-
55
- headers() {
56
- return this.#options.headers;
57
- }
58
57
  };
@@ -13,19 +13,6 @@ module.exports = class LoggedInputRequest {
13
13
  return new LoggedInputRequest(origin, logger, inputStream);
14
14
  }
15
15
 
16
- async flush() {
17
- this.#logger.debug(`HttpRequest: [${this.#inputStream.method}] ${this.#inputStream.url} ${JSON.stringify(this.#inputStream.headers)}`);
18
-
19
- try {
20
- return new LoggedInputRequest(await this.#origin.flush(), this.#logger);
21
-
22
- } catch (e) {
23
- this.#logger.error(`HttpRequest: [${this.#inputStream.method}] ${this.#inputStream.url} error: ${e.message}`, e);
24
-
25
- throw e;
26
- }
27
- }
28
-
29
16
  route() {
30
17
  return this.#origin.route();
31
18
  }
@@ -41,4 +28,17 @@ module.exports = class LoggedInputRequest {
41
28
  headers() {
42
29
  return this.#origin.headers();
43
30
  }
31
+
32
+ async flush() {
33
+ this.#logger.debug(`HttpRequest: [${this.#inputStream.method}] ${this.#inputStream.url} ${JSON.stringify(this.#inputStream.headers)}`);
34
+
35
+ try {
36
+ return new LoggedInputRequest(await this.#origin.flush(), this.#logger);
37
+
38
+ } catch (e) {
39
+ this.#logger.error(`HttpRequest: [${this.#inputStream.method}] ${this.#inputStream.url} error: ${e.message}`, e);
40
+
41
+ throw e;
42
+ }
43
+ }
44
44
  }
@@ -1,5 +1,4 @@
1
1
  module.exports = {
2
2
  InputRequest: require('./InputRequest'),
3
- JsonInputRequest: require('./JsonInputRequest'),
4
3
  LoggedInputRequest: require('./LoggedInputRequest')
5
4
  };
@@ -11,10 +11,6 @@ module.exports = class LoggedOutputResponse {
11
11
  return new LoggedOutputResponse(origin, logger);
12
12
  }
13
13
 
14
- update(options) {
15
- return new LoggedOutputResponse(this.#origin.update(options), this.#logger);
16
- }
17
-
18
14
  flush() {
19
15
  const outputStream = this.#loggedFlush();
20
16
 
@@ -7,14 +7,10 @@ module.exports = class OutputResponse {
7
7
  this.#outputStream = outputStream;
8
8
  }
9
9
 
10
- copy(options = this.#options, outputStream = this.#outputStream) {
10
+ copy(outputStream = this.#outputStream, options = this.#options) {
11
11
  return new OutputResponse({...{statusCode: 200, headers: {}}, ...options}, outputStream);
12
12
  }
13
13
 
14
- update(options) {
15
- return new OutputResponse(this.#mergeOptions(this.#options, options), this.#outputStream);
16
- }
17
-
18
14
  flush() {
19
15
  try {
20
16
  this.#outputStream.writeHead(this.#options.statusCode, this.#options.headers)
@@ -29,24 +25,4 @@ module.exports = class OutputResponse {
29
25
  this.#outputStream.end();
30
26
  }
31
27
  }
32
-
33
- #mergeOptions(existedOptions, newOptions) {
34
- if (newOptions == null) {
35
- return existedOptions;
36
- }
37
-
38
- if (newOptions.statusCode != null) {
39
- existedOptions.statusCode = newOptions.statusCode;
40
- }
41
-
42
- if (newOptions.body != null) {
43
- existedOptions.body = newOptions.body;
44
- }
45
-
46
- if (newOptions.headers != null) {
47
- existedOptions.headers = {...existedOptions.headers, ...newOptions.headers};
48
- }
49
-
50
- return existedOptions;
51
- }
52
28
  }
@@ -1,5 +1,4 @@
1
1
  module.exports = {
2
2
  OutputResponse: require('./OutputResponse'),
3
- JsonOutputResponse: require('./JsonOutputResponse'),
4
3
  LoggedOutputResponse: require('./LoggedOutputResponse')
5
4
  };
@@ -1,30 +0,0 @@
1
- module.exports = class LoggedEndpoint {
2
- #origin;
3
- #logger;
4
-
5
- constructor(origin, logger) {
6
- this.#origin = origin;
7
- this.#logger = logger;
8
- }
9
-
10
- copy(method, path, logger = this.#logger, origin = this.#origin.copy(method, path)) {
11
- return new LoggedEndpoint(origin, logger);
12
- }
13
-
14
- route() {
15
- return this.#origin.route();
16
- }
17
-
18
- async handle(request) {
19
- this.#logger.debug(`HttpEndpoint's handling [${request.route().method}] ${request.route().path}`);
20
-
21
- try {
22
- return await this.#origin.handle(request);
23
-
24
- } catch (e) {
25
- this.#logger.error(`HttpEndpoint's handling [${request.route().method}] ${request.route().path} error: ${e.message}`, e);
26
-
27
- throw e;
28
- }
29
- }
30
- }
@@ -1,51 +0,0 @@
1
- module.exports = class JsonInputRequest {
2
- #origin;
3
- #inputStream;
4
-
5
- constructor(origin, inputStream) {
6
- this.#origin = origin;
7
- this.#inputStream = inputStream;
8
- }
9
-
10
- copy(inputStream, options, origin = this.#origin.copy(inputStream, options)) {
11
- return new JsonInputRequest(origin, inputStream);
12
- }
13
-
14
- async flush() {
15
- if (this.#useChunkMethod(this.#inputStream.method) && !this.#validHeaders(new Headers(this.#inputStream.headers))) {
16
- throw new Error('Wrong content-type. Only application/json accepted.', {cause: 'INVALID_REQUEST'});
17
- }
18
-
19
- return new JsonInputRequest(await this.#origin.flush(), this.#inputStream);
20
- }
21
-
22
- route() {
23
- return this.#origin.route();
24
- }
25
-
26
- query() {
27
- return this.#origin.query();
28
- }
29
-
30
- body() {
31
- try {
32
- return JSON.parse(this.#origin.body().toString());
33
-
34
- } catch (e) {
35
- throw new Error('Wrong body format. Only JSON accepted.', {cause: 'INVALID_REQUEST'});
36
- }
37
- }
38
-
39
- headers() {
40
- return this.#origin.headers();
41
- }
42
-
43
- #useChunkMethod(requestMethod) {
44
- return ['POST', 'PUT'].some(method => method === requestMethod.toString().toUpperCase())
45
- }
46
-
47
- #validHeaders(requestHeaders) {
48
- return new Headers(requestHeaders).has('content-type')
49
- && new RegExp('^application\/json').test(new Headers(requestHeaders).get('content-type'));
50
- }
51
- }
@@ -1,45 +0,0 @@
1
- module.exports = class JsonOutputResponse {
2
- #origin;
3
- #options;
4
-
5
- constructor(origin, options) {
6
- this.#origin = origin;
7
- this.#options = options;
8
- }
9
-
10
- copy(options, outputStream, origin = this.#origin.copy(options, outputStream)) {
11
- return new JsonOutputResponse(origin, options);
12
- }
13
-
14
- update(options) {
15
- return new JsonOutputResponse(this.#origin.update(options));
16
- }
17
-
18
- flush() {
19
- const body = this.#options.body;
20
-
21
- if (body == null) {
22
- return this.#origin.flush();
23
- }
24
-
25
- if (typeof body === 'string') {
26
- try {
27
- JSON.parse(body);
28
-
29
- return this.#origin
30
- .update({headers: {'Content-Type': 'application/json; charset=utf-8'}})
31
- .flush();
32
-
33
- } catch (e) {
34
- return this.#origin.flush();
35
- }
36
- }
37
-
38
- return this.#origin
39
- .update({
40
- headers: {'Content-Type': 'application/json; charset=utf-8'},
41
- body: JSON.stringify(body)
42
- })
43
- .flush();
44
- }
45
- };