objective-http 1.4.0 → 2.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.

Potentially problematic release.


This version of objective-http might be problematic. Click here for more details.

Files changed (55) hide show
  1. package/README.md +102 -182
  2. package/package.json +44 -1
  3. package/src/js/client/index.js +2 -2
  4. package/src/js/client/request/chunk/ChunkClientRequest.js +67 -0
  5. package/src/js/client/request/chunk/JsonClientRequest.js +55 -0
  6. package/src/js/client/request/chunk/index.js +4 -0
  7. package/src/js/client/request/index.js +2 -2
  8. package/src/js/client/response/chunk/ChunkClientResponse.js +75 -0
  9. package/src/js/client/response/chunk/JsonClientResponse.js +62 -0
  10. package/src/js/client/response/chunk/index.js +4 -0
  11. package/src/js/client/response/index.js +2 -2
  12. package/src/js/index.js +1 -2
  13. package/src/js/server/Server.js +40 -62
  14. package/src/js/server/handler/endpoint/EndpointHandler.js +35 -0
  15. package/src/js/server/handler/endpoint/EndpointHandlers.js +22 -0
  16. package/src/js/server/handler/endpoint/EndpointsHandler.js +42 -0
  17. package/src/js/server/handler/endpoint/EndpontRequiredHandler.js +22 -0
  18. package/src/js/server/handler/endpoint/index.js +6 -0
  19. package/src/js/server/handler/error/HandlerNotFoundErrorHandler.js +27 -0
  20. package/src/js/server/handler/error/InvalidRequestErrorHandler.js +27 -0
  21. package/src/js/server/handler/error/LogErrorHandler.js +21 -0
  22. package/src/js/server/handler/error/UnexpectedErrorHandler.js +23 -0
  23. package/src/js/server/handler/error/index.js +6 -0
  24. package/src/js/server/handler/index.js +4 -0
  25. package/src/js/server/index.js +3 -4
  26. package/src/js/server/request/chunk/ChunkServerRequest.js +87 -0
  27. package/src/js/server/request/chunk/JsonServerRequest.js +67 -0
  28. package/src/js/server/request/chunk/index.js +4 -0
  29. package/src/js/server/request/index.js +2 -3
  30. package/src/js/server/response/chunk/ChunkServerResponse.js +53 -0
  31. package/src/js/server/response/chunk/JsonServerResponse.js +50 -0
  32. package/src/js/server/response/chunk/index.js +4 -0
  33. package/src/js/server/response/index.js +2 -3
  34. package/src/js/bun/Bunttp.js +0 -25
  35. package/src/js/bun/client/index.js +0 -4
  36. package/src/js/bun/client/request/OutputRequest.js +0 -26
  37. package/src/js/bun/client/request/index.js +0 -3
  38. package/src/js/bun/client/response/InputResponse.js +0 -40
  39. package/src/js/bun/client/response/index.js +0 -3
  40. package/src/js/bun/index.js +0 -5
  41. package/src/js/bun/server/index.js +0 -4
  42. package/src/js/bun/server/request/InputRequest.js +0 -49
  43. package/src/js/bun/server/request/index.js +0 -3
  44. package/src/js/bun/server/response/OutputResponse.js +0 -25
  45. package/src/js/bun/server/response/index.js +0 -3
  46. package/src/js/client/request/OutputRequest.js +0 -53
  47. package/src/js/client/response/InputResponse.js +0 -48
  48. package/src/js/server/LoggedServer.js +0 -29
  49. package/src/js/server/endpoint/Endpoint.js +0 -17
  50. package/src/js/server/endpoint/Endpoints.js +0 -36
  51. package/src/js/server/endpoint/index.js +0 -4
  52. package/src/js/server/request/InputRequest.js +0 -57
  53. package/src/js/server/request/LoggedInputRequest.js +0 -44
  54. package/src/js/server/response/LoggedOutputResponse.js +0 -32
  55. package/src/js/server/response/OutputResponse.js +0 -28
@@ -1,25 +0,0 @@
1
- module.exports = class Bunttp {
2
- #serverConfig;
3
- #server;
4
-
5
- constructor(serverConfig = {}, server = {}) {
6
- this.#serverConfig = serverConfig;
7
- this.#server = server;
8
- }
9
-
10
- createServer(cb) {
11
- return new Bunttp({fetch: cb});
12
- }
13
-
14
- listen(options, cb) {
15
- this.#server = Bun.serve({...this.#serverConfig, port: options.port});
16
- cb();
17
- }
18
-
19
- close(cb) {
20
- this.#server.stop();
21
- cb();
22
- }
23
-
24
- request = fetch;
25
- }
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- request: require('./request'),
3
- response: require('./response')
4
- }
@@ -1,26 +0,0 @@
1
- module.exports = class OutputRequest {
2
- #response;
3
- #requestFunction;
4
- #options;
5
-
6
- constructor(response, requestFunction, options) {
7
- this.#response = response;
8
- this.#requestFunction = requestFunction;
9
- this.#options = options;
10
- }
11
-
12
- copy(options = this.#options, response = this.#response, requestFunction = this.#requestFunction) {
13
- return new OutputRequest(response, requestFunction, options);
14
- }
15
-
16
- async send() {
17
- try {
18
- return await (this.#response
19
- .copy(await this.#requestFunction(this.#options.url, this.#options)))
20
- .flush()
21
-
22
- } catch (e) {
23
- throw new Error(e.message, {cause: 'INVALID_REQUEST'});
24
- }
25
- }
26
- }
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- OutputRequest: require('./OutputRequest')
3
- };
@@ -1,40 +0,0 @@
1
- module.exports = class InputResponse {
2
- #inputStream;
3
- #options;
4
-
5
- constructor(inputStream, options) {
6
- this.#inputStream = inputStream;
7
- this.#options = options;
8
- }
9
-
10
- copy(inputStream = this.#inputStream, options = this.#options) {
11
- return new InputResponse(inputStream, options);
12
- }
13
-
14
- async flush() {
15
- try {
16
- return new InputResponse(this.#inputStream,
17
- {
18
- statusCode: this.#inputStream.status,
19
- headers: this.#inputStream.headers,
20
- body: Buffer.from(await (await this.#inputStream.blob()).arrayBuffer())
21
- }
22
- );
23
-
24
- } catch (e) {
25
- throw new Error(e.message, {cause: 'INVALID_RESPONSE'});
26
- }
27
- }
28
-
29
- statusCode() {
30
- return this.#options.statusCode;
31
- }
32
-
33
- headers() {
34
- return this.#options.headers;
35
- }
36
-
37
- body() {
38
- return this.#options.body;
39
- }
40
- }
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- InputResponse: require('./InputResponse')
3
- };
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- server: require('./server'),
3
- client: require('./client'),
4
- bunttp: new (require('./Bunttp'))()
5
- }
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- request: require('./request'),
3
- response: require('./response')
4
- }
@@ -1,49 +0,0 @@
1
- module.exports = class InputRequest {
2
- #inputStream;
3
- #options;
4
-
5
- constructor(inputStream, options) {
6
- this.#inputStream = inputStream;
7
- this.#options = options;
8
- }
9
-
10
- copy(inputStream = this.#inputStream, options = this.#options) {
11
- return new InputRequest(inputStream, options);
12
- }
13
-
14
- async flush() {
15
- try {
16
- return new InputRequest(
17
- this.#inputStream,
18
- {
19
- route: {
20
- method: this.#inputStream.method,
21
- path: new URL(this.#inputStream.url).pathname
22
- },
23
- query: new URL(this.#inputStream.url).searchParams,
24
- headers: this.#inputStream.headers,
25
- body: Buffer.from(await (await this.#inputStream.blob()).arrayBuffer())
26
- }
27
- );
28
-
29
- } catch (e) {
30
- throw new Error(e.message, {cause: 'INVALID_REQUEST'});
31
- }
32
- }
33
-
34
- route() {
35
- return this.#options.route;
36
- }
37
-
38
- query() {
39
- return this.#options.query;
40
- }
41
-
42
- body() {
43
- return this.#options.body;
44
- }
45
-
46
- headers() {
47
- return this.#options.headers;
48
- }
49
- }
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- InputRequest: require('./InputRequest')
3
- };
@@ -1,25 +0,0 @@
1
- module.exports = class OutputResponse {
2
- #options;
3
- #outputStream;
4
-
5
- constructor(options, outputStream) {
6
- this.#options = {...{statusCode: 200, headers: {}}, ...options};
7
- this.#outputStream = outputStream;
8
- }
9
-
10
- copy(outputStream = this.#outputStream, options = this.#options) {
11
- return new OutputResponse({...{statusCode: 200, headers: {}}, ...options}, outputStream);
12
- }
13
-
14
- flush() {
15
- try {
16
- return new Response(this.#options.body, {
17
- status: this.#options.statusCode,
18
- headers: this.#options.headers
19
- });
20
-
21
- } catch (e) {
22
- throw new Error(e.message, {cause: 'INVALID_RESPONSE'});
23
- }
24
- }
25
- }
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- OutputResponse: require('./OutputResponse')
3
- };
@@ -1,53 +0,0 @@
1
- module.exports = class OutputRequest {
2
- #response;
3
- #requestFunction;
4
- #options;
5
-
6
- constructor(response, requestFunction, options) {
7
- this.#response = response;
8
- this.#requestFunction = requestFunction;
9
- this.#options = {method: 'GET', ...options};
10
- }
11
-
12
- copy(options = this.#options, response = this.#response, http = this.#requestFunction) {
13
- return new OutputRequest(response, http, {method: 'GET', ...options});
14
- }
15
-
16
- send() {
17
- return new Promise((resolve, reject) => {
18
- try {
19
- const requestOutputStream = this.#requestFunction(
20
- this.#options.url,
21
- this.#options,
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
- });
36
-
37
- if (this.#needToByWritten(this.#options)) {
38
- requestOutputStream.write(this.#options.body);
39
- }
40
-
41
- requestOutputStream.end();
42
-
43
- } catch (e) {
44
- reject(new Error(e.message, {cause: 'INVALID_REQUEST'}));
45
- }
46
- });
47
- }
48
-
49
- #needToByWritten(options) {
50
- return ['POST', 'PUT'].some(method => method === options.method.toString().toUpperCase())
51
- && (options.body != null && typeof options.body === 'string');
52
- }
53
- };
@@ -1,48 +0,0 @@
1
- module.exports = class InputResponse {
2
- #inputStream;
3
- #options;
4
-
5
- constructor(inputStream, options) {
6
- this.#inputStream = inputStream;
7
- this.#options = options;
8
- }
9
-
10
- copy(inputStream = this.#inputStream, options = this.#options) {
11
- return new InputResponse(inputStream, options);
12
- }
13
-
14
- statusCode() {
15
- return this.#options.statusCode;
16
- }
17
-
18
- headers() {
19
- return this.#options.headers;
20
- }
21
-
22
- body() {
23
- return this.#options.body;
24
- }
25
-
26
- async flush() {
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
- });
47
- }
48
- };
@@ -1,29 +0,0 @@
1
- module.exports = class LoggedServer {
2
- #origin;
3
- #logger;
4
-
5
- constructor(origin, logger) {
6
- this.#origin = origin;
7
- this.#logger = logger;
8
- }
9
-
10
- options() {
11
- return this.#origin.options();
12
- }
13
-
14
- async start() {
15
- const server = await this.#origin.start();
16
-
17
- this.#logger.debug(`HttpServer is running at port: ${this.#origin.options().port}`);
18
-
19
- return new LoggedServer(server, this.#logger);
20
- }
21
-
22
- async stop() {
23
- const server = await this.#origin.stop();
24
-
25
- this.#logger.debug(`HttpServer at port: ${this.#origin.options().port} is stopped`);
26
-
27
- return new LoggedServer(server, this.#logger);
28
- }
29
- }
@@ -1,17 +0,0 @@
1
- module.exports = class Endpoint {
2
- #route;
3
-
4
- constructor(route) {
5
- this.#route = route;
6
- }
7
-
8
- route() {
9
- return this.#route;
10
- }
11
-
12
- async handle() {
13
- return {
14
- statusCode: 200
15
- };
16
- }
17
- }
@@ -1,36 +0,0 @@
1
- module.exports = class Endpoints {
2
- #map;
3
-
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
- });
16
- }
17
-
18
- copy(collection, map = this.#map) {
19
- return new Endpoints(collection, map);
20
- }
21
-
22
- async handle(request) {
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'});
29
- }
30
-
31
- return await this.#map
32
- .get(request.route().path.toString().toLowerCase())
33
- .get(request.route().method.toString().toUpperCase())
34
- .handle(request);
35
- }
36
- }
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- Endpoint: require('./Endpoint'),
3
- Endpoints: require('./Endpoints'),
4
- };
@@ -1,57 +0,0 @@
1
- module.exports = class InputRequest {
2
- #inputStream;
3
- #options;
4
-
5
- constructor(inputStream, options) {
6
- this.#inputStream = inputStream;
7
- this.#options = options;
8
- }
9
-
10
- copy(inputStream = this.#inputStream, options = this.#options) {
11
- return new InputRequest(inputStream, options);
12
- }
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
-
30
- flush() {
31
- return new Promise((resolve, reject) => {
32
- try {
33
- this.#inputStream.once('error', (e) =>
34
- reject(new Error(e.message, {cause: 'INVALID_REQUEST'}))
35
- );
36
-
37
- let chunks = [];
38
- this.#inputStream.on('data', (chunk) => chunks.push(chunk));
39
- this.#inputStream.on('end', () => resolve(new InputRequest(
40
- this.#inputStream,
41
- {
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,
47
- headers: new Headers(this.#inputStream.headers),
48
- body: Buffer.concat(chunks),
49
- }
50
- )));
51
-
52
- } catch (e) {
53
- reject(new Error(e.message, {cause: 'INVALID_REQUEST'}));
54
- }
55
- });
56
- }
57
- };
@@ -1,44 +0,0 @@
1
- module.exports = class LoggedInputRequest {
2
- #origin;
3
- #inputStream;
4
- #logger;
5
-
6
- constructor(origin, logger, inputStream) {
7
- this.#origin = origin;
8
- this.#logger = logger;
9
- this.#inputStream = inputStream;
10
- }
11
-
12
- copy(inputStream, options, logger = this.#logger, origin = this.#origin.copy(inputStream, options)) {
13
- return new LoggedInputRequest(origin, logger, inputStream);
14
- }
15
-
16
- route() {
17
- return this.#origin.route();
18
- }
19
-
20
- query() {
21
- return this.#origin.query();
22
- }
23
-
24
- body() {
25
- return this.#origin.body();
26
- }
27
-
28
- headers() {
29
- return this.#origin.headers();
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
- }
@@ -1,32 +0,0 @@
1
- module.exports = class LoggedOutputResponse {
2
- #origin;
3
- #logger;
4
-
5
- constructor(origin, logger) {
6
- this.#origin = origin;
7
- this.#logger = logger;
8
- }
9
-
10
- copy(options, outputStream, logger = this.#logger, origin = this.#origin.copy(options, outputStream)) {
11
- return new LoggedOutputResponse(origin, logger);
12
- }
13
-
14
- flush() {
15
- const outputStream = this.#loggedFlush();
16
-
17
- this.#logger.debug(`HttpResponse: [${outputStream.req.method}] ${outputStream.req.url} - ${outputStream.statusCode}`);
18
-
19
- return outputStream;
20
- }
21
-
22
- #loggedFlush() {
23
- try {
24
- return this.#origin.flush();
25
-
26
- } catch (e) {
27
- this.#logger.error(`HttpResponse error: ${e.message}`, e);
28
-
29
- throw e;
30
- }
31
- }
32
- }
@@ -1,28 +0,0 @@
1
- module.exports = class OutputResponse {
2
- #options;
3
- #outputStream;
4
-
5
- constructor(options, outputStream) {
6
- this.#options = {...{statusCode: 200, headers: {}}, ...options};
7
- this.#outputStream = outputStream;
8
- }
9
-
10
- copy(outputStream = this.#outputStream, options = this.#options) {
11
- return new OutputResponse({...{statusCode: 200, headers: {}}, ...options}, outputStream);
12
- }
13
-
14
- flush() {
15
- try {
16
- this.#outputStream.writeHead(this.#options.statusCode, this.#options.headers)
17
-
18
- if (this.#options.body != null) {
19
- this.#outputStream.write(this.#options.body);
20
- }
21
-
22
- return this.#outputStream;
23
-
24
- } finally {
25
- this.#outputStream.end();
26
- }
27
- }
28
- }