@opra/core 0.33.13 → 1.0.0-alpha.10

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 (155) hide show
  1. package/cjs/augmentation/18n.augmentation.js +18 -5
  2. package/cjs/augmentation/http-controller.augmentation.js +25 -0
  3. package/cjs/constants.js +5 -0
  4. package/cjs/execution-context.js +24 -12
  5. package/cjs/{services → helpers}/logger.js +1 -2
  6. package/cjs/{services/api-service.js → helpers/service-base.js} +8 -8
  7. package/cjs/http/express-adapter.js +153 -0
  8. package/cjs/http/http-adapter.js +27 -0
  9. package/cjs/http/http-context.js +119 -0
  10. package/cjs/http/impl/asset-cache.js +21 -0
  11. package/cjs/http/impl/http-handler.js +584 -0
  12. package/cjs/http/{http-server-request.js → impl/http-incoming.host.js} +24 -49
  13. package/cjs/http/{http-server-response.js → impl/http-outgoing.host.js} +9 -28
  14. package/cjs/http/{helpers/multipart-helper.js → impl/multipart-reader.js} +23 -27
  15. package/cjs/http/impl/{http-incoming-message.host.js → node-incoming-message.host.js} +18 -57
  16. package/cjs/http/impl/{http-outgoing-message.host.js → node-outgoing-message.host.js} +11 -14
  17. package/cjs/http/interfaces/http-incoming.interface.js +25 -0
  18. package/cjs/http/interfaces/http-outgoing.interface.js +22 -0
  19. package/cjs/http/interfaces/node-incoming-message.interface.js +64 -0
  20. package/cjs/http/interfaces/node-outgoing-message.interface.js +15 -0
  21. package/cjs/http/utils/body-reader.js +217 -0
  22. package/cjs/http/{helpers → utils}/common.js +2 -1
  23. package/cjs/http/{helpers → utils}/convert-to-raw-headers.js +1 -2
  24. package/cjs/http/{helpers → utils}/match-known-fields.js +11 -9
  25. package/cjs/http/utils/wrap-exception.js +34 -0
  26. package/cjs/index.js +26 -26
  27. package/cjs/platform-adapter.js +21 -0
  28. package/cjs/type-guards.js +23 -0
  29. package/esm/augmentation/18n.augmentation.js +20 -7
  30. package/esm/augmentation/http-controller.augmentation.js +23 -0
  31. package/esm/constants.js +2 -0
  32. package/esm/execution-context.js +24 -13
  33. package/esm/{services → helpers}/logger.js +1 -2
  34. package/esm/{services/api-service.js → helpers/service-base.js} +6 -6
  35. package/esm/http/express-adapter.js +148 -0
  36. package/esm/http/http-adapter.js +23 -0
  37. package/esm/http/http-context.js +114 -0
  38. package/esm/http/impl/asset-cache.js +17 -0
  39. package/esm/http/impl/http-handler.js +579 -0
  40. package/esm/http/{http-server-request.js → impl/http-incoming.host.js} +20 -46
  41. package/esm/http/{http-server-response.js → impl/http-outgoing.host.js} +7 -27
  42. package/esm/http/{helpers/multipart-helper.js → impl/multipart-reader.js} +21 -25
  43. package/esm/http/impl/{http-incoming-message.host.js → node-incoming-message.host.js} +16 -55
  44. package/esm/http/impl/{http-outgoing-message.host.js → node-outgoing-message.host.js} +9 -12
  45. package/esm/http/interfaces/http-incoming.interface.js +22 -0
  46. package/esm/http/interfaces/http-outgoing.interface.js +19 -0
  47. package/esm/http/interfaces/node-incoming-message.interface.js +61 -0
  48. package/esm/http/interfaces/node-outgoing-message.interface.js +12 -0
  49. package/esm/http/utils/body-reader.js +212 -0
  50. package/esm/http/{helpers → utils}/common.js +2 -1
  51. package/esm/http/{helpers → utils}/convert-to-headers.js +1 -1
  52. package/esm/http/{helpers → utils}/convert-to-raw-headers.js +2 -3
  53. package/esm/http/{helpers → utils}/match-known-fields.js +11 -9
  54. package/esm/http/utils/wrap-exception.js +30 -0
  55. package/esm/index.js +26 -27
  56. package/esm/platform-adapter.js +19 -1
  57. package/esm/type-guards.js +16 -0
  58. package/package.json +31 -13
  59. package/types/augmentation/18n.augmentation.d.ts +31 -1
  60. package/types/augmentation/http-controller.augmentation.d.ts +21 -0
  61. package/types/constants.d.ts +2 -0
  62. package/types/execution-context.d.ts +22 -26
  63. package/types/helpers/service-base.d.ts +10 -0
  64. package/types/http/express-adapter.d.ts +13 -0
  65. package/types/http/http-adapter.d.ts +27 -0
  66. package/types/http/http-context.d.ts +44 -0
  67. package/types/http/impl/asset-cache.d.ts +5 -0
  68. package/types/http/impl/http-handler.d.ts +73 -0
  69. package/types/http/impl/http-incoming.host.d.ts +23 -0
  70. package/types/http/impl/http-outgoing.host.d.ts +17 -0
  71. package/types/http/{helpers/multipart-helper.d.ts → impl/multipart-reader.d.ts} +8 -6
  72. package/types/http/impl/{http-incoming-message.host.d.ts → node-incoming-message.host.d.ts} +10 -23
  73. package/types/http/impl/{http-outgoing-message.host.d.ts → node-outgoing-message.host.d.ts} +11 -27
  74. package/types/http/{http-server-request.d.ts → interfaces/http-incoming.interface.d.ts} +28 -17
  75. package/types/http/{http-server-response.d.ts → interfaces/http-outgoing.interface.d.ts} +17 -10
  76. package/types/http/interfaces/node-incoming-message.interface.d.ts +38 -0
  77. package/types/http/interfaces/node-outgoing-message.interface.d.ts +29 -0
  78. package/types/http/utils/body-reader.d.ts +41 -0
  79. package/types/http/utils/wrap-exception.d.ts +2 -0
  80. package/types/index.d.ts +25 -27
  81. package/types/platform-adapter.d.ts +20 -48
  82. package/types/type-guards.d.ts +8 -0
  83. package/cjs/augmentation/collection.augmentation.js +0 -2
  84. package/cjs/augmentation/container.augmentation.js +0 -2
  85. package/cjs/augmentation/resource.augmentation.js +0 -26
  86. package/cjs/augmentation/singleton.augmentation.js +0 -2
  87. package/cjs/augmentation/storage.augmentation.js +0 -2
  88. package/cjs/execution-context.host.js +0 -46
  89. package/cjs/http/adapters/express-adapter.host.js +0 -34
  90. package/cjs/http/adapters/express-adapter.js +0 -14
  91. package/cjs/http/adapters/node-http-adapter.host.js +0 -70
  92. package/cjs/http/adapters/node-http-adapter.js +0 -14
  93. package/cjs/http/helpers/json-body-loader.js +0 -29
  94. package/cjs/http/helpers/query-parsers.js +0 -16
  95. package/cjs/http/http-adapter-host.js +0 -715
  96. package/cjs/interfaces/interceptor.interface.js +0 -2
  97. package/cjs/interfaces/request-handler.interface.js +0 -2
  98. package/cjs/platform-adapter.host.js +0 -154
  99. package/cjs/request-context.js +0 -25
  100. package/cjs/request.host.js +0 -24
  101. package/cjs/request.js +0 -2
  102. package/cjs/response.host.js +0 -22
  103. package/cjs/response.js +0 -2
  104. package/esm/augmentation/collection.augmentation.js +0 -1
  105. package/esm/augmentation/container.augmentation.js +0 -1
  106. package/esm/augmentation/resource.augmentation.js +0 -24
  107. package/esm/augmentation/singleton.augmentation.js +0 -1
  108. package/esm/augmentation/storage.augmentation.js +0 -1
  109. package/esm/execution-context.host.js +0 -42
  110. package/esm/http/adapters/express-adapter.host.js +0 -30
  111. package/esm/http/adapters/express-adapter.js +0 -11
  112. package/esm/http/adapters/node-http-adapter.host.js +0 -65
  113. package/esm/http/adapters/node-http-adapter.js +0 -11
  114. package/esm/http/helpers/json-body-loader.js +0 -24
  115. package/esm/http/helpers/query-parsers.js +0 -12
  116. package/esm/http/http-adapter-host.js +0 -710
  117. package/esm/interfaces/interceptor.interface.js +0 -1
  118. package/esm/interfaces/request-handler.interface.js +0 -1
  119. package/esm/platform-adapter.host.js +0 -149
  120. package/esm/request-context.js +0 -22
  121. package/esm/request.host.js +0 -20
  122. package/esm/request.js +0 -1
  123. package/esm/response.host.js +0 -18
  124. package/esm/response.js +0 -1
  125. package/types/augmentation/collection.augmentation.d.ts +0 -146
  126. package/types/augmentation/container.augmentation.d.ts +0 -14
  127. package/types/augmentation/resource.augmentation.d.ts +0 -38
  128. package/types/augmentation/singleton.augmentation.d.ts +0 -83
  129. package/types/augmentation/storage.augmentation.d.ts +0 -50
  130. package/types/execution-context.host.d.ts +0 -25
  131. package/types/http/adapters/express-adapter.d.ts +0 -15
  132. package/types/http/adapters/express-adapter.host.d.ts +0 -12
  133. package/types/http/adapters/node-http-adapter.d.ts +0 -17
  134. package/types/http/adapters/node-http-adapter.host.d.ts +0 -19
  135. package/types/http/helpers/json-body-loader.d.ts +0 -5
  136. package/types/http/helpers/query-parsers.d.ts +0 -1
  137. package/types/http/http-adapter-host.d.ts +0 -34
  138. package/types/interfaces/interceptor.interface.d.ts +0 -2
  139. package/types/interfaces/request-handler.interface.d.ts +0 -4
  140. package/types/platform-adapter.host.d.ts +0 -43
  141. package/types/request-context.d.ts +0 -13
  142. package/types/request.d.ts +0 -14
  143. package/types/request.host.d.ts +0 -27
  144. package/types/response.d.ts +0 -22
  145. package/types/response.host.d.ts +0 -22
  146. package/types/services/api-service.d.ts +0 -10
  147. /package/cjs/http/{helpers → utils}/concat-readable.js +0 -0
  148. /package/cjs/http/{helpers → utils}/convert-to-headers.js +0 -0
  149. /package/esm/http/{helpers → utils}/concat-readable.js +0 -0
  150. /package/types/{services → helpers}/logger.d.ts +0 -0
  151. /package/types/http/{helpers → utils}/common.d.ts +0 -0
  152. /package/types/http/{helpers → utils}/concat-readable.d.ts +0 -0
  153. /package/types/http/{helpers → utils}/convert-to-headers.d.ts +0 -0
  154. /package/types/http/{helpers → utils}/convert-to-raw-headers.d.ts +0 -0
  155. /package/types/http/{helpers → utils}/match-known-fields.d.ts +0 -0
@@ -2,6 +2,7 @@
2
2
  Some parts of this file contains codes from open source express library
3
3
  https://github.com/expressjs
4
4
  */
5
+ import { HttpStatusCode } from '@opra/common';
5
6
  import contentDisposition from 'content-disposition';
6
7
  import contentType from 'content-type';
7
8
  import cookie from 'cookie';
@@ -11,23 +12,8 @@ import mime from 'mime-types';
11
12
  import path from 'path';
12
13
  import { toString } from 'putil-varhelpers';
13
14
  import vary from 'vary';
14
- import { HttpStatusCode, isStream, mergePrototype } from '@opra/common';
15
- import { HttpOutgoingMessageHost } from './impl/http-outgoing-message.host.js';
16
15
  const charsetRegExp = /;\s*charset\s*=/;
17
- function isHttpIncomingMessage(v) {
18
- return v && typeof v.getHeaders === 'function' && isStream(v);
19
- }
20
- export var HttpServerResponse;
21
- (function (HttpServerResponse) {
22
- function from(instance) {
23
- if (!isHttpIncomingMessage(instance))
24
- instance = new HttpOutgoingMessageHost(instance);
25
- mergePrototype(instance, HttpServerResponseHost.prototype);
26
- return instance;
27
- }
28
- HttpServerResponse.from = from;
29
- })(HttpServerResponse || (HttpServerResponse = {}));
30
- class HttpServerResponseHost {
16
+ export class HttpOutgoingHost {
31
17
  attachment(filename) {
32
18
  if (filename)
33
19
  this.contentType(path.extname(filename));
@@ -35,9 +21,7 @@ class HttpServerResponseHost {
35
21
  return this;
36
22
  }
37
23
  contentType(type) {
38
- const ct = type.indexOf('/') === -1
39
- ? mime.lookup(type)
40
- : type;
24
+ const ct = type.indexOf('/') === -1 ? mime.lookup(type) : type;
41
25
  this.setHeader('Content-Type', ct);
42
26
  return this;
43
27
  }
@@ -50,9 +34,7 @@ class HttpServerResponseHost {
50
34
  return this;
51
35
  }
52
36
  const fieldLower = field.toLowerCase();
53
- let value = Array.isArray(val)
54
- ? val.map(String)
55
- : (val ? String(val) : '');
37
+ let value = Array.isArray(val) ? val.map(String) : val ? String(val) : '';
56
38
  // add charset to content-type
57
39
  if (fieldLower === 'content-type') {
58
40
  if (Array.isArray(value)) {
@@ -71,15 +53,13 @@ class HttpServerResponseHost {
71
53
  const opts = {
72
54
  expires: new Date(1),
73
55
  path: '/',
74
- ...options
56
+ ...options,
75
57
  };
76
58
  return this.cookie(name, '', opts);
77
59
  }
78
60
  cookie(name, value, options) {
79
61
  const opts = { ...options };
80
- let val = typeof value === 'object'
81
- ? 'j:' + JSON.stringify(value)
82
- : String(value);
62
+ let val = typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value);
83
63
  if (opts.signed) {
84
64
  const secret = opts.secret || this.req?.secret;
85
65
  if (!secret)
@@ -180,7 +160,7 @@ class HttpServerResponseHost {
180
160
  if (req?.fresh)
181
161
  this.statusCode = 304;
182
162
  // strip irrelevant headers
183
- if (204 === this.statusCode || 304 === this.statusCode) {
163
+ if (this.statusCode === 204 || this.statusCode === 304) {
184
164
  this.removeHeader('Content-Type');
185
165
  this.removeHeader('Content-Length');
186
166
  this.removeHeader('Transfer-Encoding');
@@ -1,34 +1,36 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import formidable from 'formidable';
3
3
  import fs from 'fs/promises';
4
- export class MultipartIterator extends EventEmitter {
5
- constructor(options) {
4
+ export class MultipartReader extends EventEmitter {
5
+ constructor(incoming, options) {
6
6
  super();
7
+ this._started = false;
7
8
  this._cancelled = false;
8
9
  this._items = [];
9
10
  this._stack = [];
10
11
  this.setMaxListeners(1000);
11
- const form = this._form = formidable({
12
+ this._incoming = incoming;
13
+ const form = (this._form = formidable({
12
14
  ...options,
13
- filter: (part) => {
14
- return !this._cancelled && (!options?.filter || options.filter(part));
15
- }
16
- });
15
+ filter: (part) => !this._cancelled && (!options?.filter || options.filter(part)),
16
+ }));
17
17
  form.once('error', () => {
18
18
  this._cancelled = true;
19
19
  if (this.listenerCount('error') > 0)
20
20
  this.emit('error');
21
21
  });
22
- form.on('field', (field, value) => {
23
- const item = { field, value };
22
+ form.on('field', (fieldName, value) => {
23
+ const item = { fieldName, type: 'field', value };
24
24
  this._items.push(item);
25
25
  this._stack.push(item);
26
+ this.emit('field', item);
26
27
  this.emit('item', item);
27
28
  });
28
- form.on('file', (field, file) => {
29
- const item = { field, file };
29
+ form.on('file', (fieldName, file) => {
30
+ const item = { fieldName, type: 'file', file };
30
31
  this._items.push(item);
31
32
  this._stack.push(item);
33
+ this.emit('file', item);
32
34
  this.emit('item', item);
33
35
  });
34
36
  }
@@ -44,7 +46,7 @@ export class MultipartIterator extends EventEmitter {
44
46
  if (this._form.ended)
45
47
  return resolve(undefined);
46
48
  this.once('item', () => resolve(this._stack.shift()));
47
- this.once('error', (e) => reject(e));
49
+ this.once('error', e => reject(e));
48
50
  });
49
51
  }
50
52
  getAll() {
@@ -64,6 +66,8 @@ export class MultipartIterator extends EventEmitter {
64
66
  this.resume();
65
67
  }
66
68
  resume() {
69
+ if (!this._started)
70
+ this._form.parse(this._incoming, () => undefined);
67
71
  if (this._form.req)
68
72
  this._form.resume();
69
73
  }
@@ -71,10 +75,9 @@ export class MultipartIterator extends EventEmitter {
71
75
  if (this._form.req)
72
76
  this._form.pause();
73
77
  }
74
- async deleteFiles() {
78
+ async deleteTempFiles() {
75
79
  const promises = [];
76
- this._items
77
- .forEach(item => {
80
+ this._items.forEach(item => {
78
81
  if (!item.file)
79
82
  return;
80
83
  const file = item.file;
@@ -82,17 +85,10 @@ export class MultipartIterator extends EventEmitter {
82
85
  if (file._writeStream.closed)
83
86
  return resolve();
84
87
  file._writeStream.once('close', resolve);
85
- }).then(() => {
86
- return fs.unlink(file.filepath);
87
- }).then(() => {
88
- return 0;
89
- }));
88
+ })
89
+ .then(() => fs.unlink(file.filepath))
90
+ .then(() => 0));
90
91
  });
91
92
  return Promise.allSettled(promises);
92
93
  }
93
- static async create(incoming, options) {
94
- const out = new MultipartIterator(options);
95
- await out._form.parse(incoming);
96
- return out;
97
- }
98
94
  }
@@ -1,23 +1,18 @@
1
- /*
2
- This file contains code blocks from open source NodeJs project
3
- https://github.com/nodejs/
4
- */
5
- import { Duplex, Readable } from 'stream';
6
- import { HTTPParser } from '@browsery/http-parser';
7
1
  import { isAsyncIterable, isIterable } from '@opra/common';
8
- import { concatReadable } from '../helpers/concat-readable.js';
9
- import { convertToHeaders, convertToHeadersDistinct } from '../helpers/convert-to-headers.js';
10
- import { convertToRawHeaders } from '../helpers/convert-to-raw-headers.js';
2
+ import { Duplex, Readable } from 'stream';
3
+ import { convertToHeaders, convertToHeadersDistinct } from '../utils/convert-to-headers.js';
4
+ import { convertToRawHeaders } from '../utils/convert-to-raw-headers.js';
11
5
  export const CRLF = Buffer.from('\r\n');
12
6
  export const kHeaders = Symbol.for('kHeaders');
13
7
  export const kHeadersDistinct = Symbol.for('kHeadersDistinct');
14
8
  export const kTrailers = Symbol.for('kTrailers');
15
9
  export const kTrailersDistinct = Symbol.for('kTrailersDistinct');
10
+ export const kHttpParser = Symbol.for('kHttpParser');
16
11
  /**
17
12
  *
18
- * @class HttpIncomingMessageHost
13
+ * @class NodeIncomingMessageHost
19
14
  */
20
- export class HttpIncomingMessageHost extends Duplex {
15
+ export class NodeIncomingMessageHost extends Duplex {
21
16
  constructor(init) {
22
17
  super();
23
18
  this.rawHeaders = [];
@@ -38,20 +33,24 @@ export class HttpIncomingMessageHost extends Duplex {
38
33
  else
39
34
  this.body = Buffer.from(JSON.stringify(init.body), 'utf-8');
40
35
  }
41
- if (init.headers)
36
+ if (init.headers) {
42
37
  this.rawHeaders = Array.isArray(init.headers) ? init.headers : convertToRawHeaders(init.headers);
43
- if (init.trailers)
38
+ }
39
+ if (init.trailers) {
44
40
  this.rawTrailers = Array.isArray(init.trailers) ? init.trailers : convertToRawHeaders(init.trailers);
41
+ }
45
42
  this.ip = init.ip || '';
46
43
  this.ips = init.ips || (this.ip ? [this.ip] : []);
47
44
  if (this.body && !this.headers['content-length'])
48
45
  this.headers['content-length'] = String(this.body.length);
46
+ if (init.params)
47
+ this.params = init.params;
48
+ if (init.cookies)
49
+ this.cookies = init.cookies;
49
50
  }
50
51
  }
51
52
  get httpVersion() {
52
- return this.httpVersionMajor
53
- ? this.httpVersionMajor + '.' + this.httpVersionMinor
54
- : '';
53
+ return this.httpVersionMajor ? this.httpVersionMajor + '.' + this.httpVersionMinor : '';
55
54
  }
56
55
  get headers() {
57
56
  if (!this[kHeaders])
@@ -95,50 +94,12 @@ export class HttpIncomingMessageHost extends Duplex {
95
94
  }
96
95
  const chunk = this._readStream.read(size);
97
96
  this.push(chunk);
98
- // this.push(null);s
99
97
  }
100
98
  _write(chunk, encoding, callback) {
101
- const error = this._httpParser?.execute(chunk);
99
+ const error = this[kHttpParser]?.execute(chunk);
102
100
  if (error && typeof error === 'object')
103
101
  callback(error);
104
102
  else
105
103
  callback();
106
104
  }
107
- static from(iterable) {
108
- if (typeof iterable === 'object' && !(isIterable(iterable) || isAsyncIterable(iterable)))
109
- return new HttpIncomingMessageHost(iterable);
110
- const msg = new HttpIncomingMessageHost();
111
- const parser = msg._httpParser = new HTTPParser(HTTPParser.REQUEST);
112
- let bodyChunks;
113
- parser[HTTPParser.kOnHeadersComplete] = (info) => {
114
- msg.httpVersionMajor = info.versionMajor;
115
- msg.httpVersionMinor = info.versionMinor;
116
- msg.rawHeaders = info.headers;
117
- msg.method = HTTPParser.methods[info.method];
118
- msg.url = info.url;
119
- };
120
- parser[HTTPParser.kOnHeaders] = (trailers) => {
121
- msg.rawTrailers = trailers;
122
- };
123
- parser[HTTPParser.kOnBody] = (chunk, offset, length) => {
124
- bodyChunks = bodyChunks || [];
125
- bodyChunks.push(chunk.subarray(offset, offset + length));
126
- };
127
- parser[HTTPParser.kOnMessageComplete] = () => {
128
- msg.complete = true;
129
- if (bodyChunks)
130
- msg.body = Buffer.concat(bodyChunks);
131
- };
132
- const readable = concatReadable(Readable.from(iterable), Readable.from(CRLF));
133
- msg.once('finish', () => parser.finish());
134
- readable.pipe(msg);
135
- return msg;
136
- }
137
- static async fromAsync(iterable) {
138
- return new Promise((resolve, reject) => {
139
- const msg = this.from(iterable);
140
- msg.once('finish', () => resolve(msg));
141
- msg.once('error', (error) => reject(error));
142
- });
143
- }
144
105
  }
@@ -3,15 +3,15 @@
3
3
  https://github.com/nodejs/
4
4
  */
5
5
  import { Duplex } from 'stream';
6
- import { validateHeaderName, validateHeaderValue, validateString } from '../helpers/common.js';
6
+ import { validateHeaderName, validateHeaderValue, validateString } from '../utils/common.js';
7
7
  export const kOutHeaders = Symbol.for('kOutHeaders');
8
8
  export const kOutTrailers = Symbol.for('kOutTrailers');
9
9
  // noinspection JSUnusedLocalSymbols
10
10
  /**
11
11
  *
12
- * @class HttpOutgoingMessageHost
12
+ * @class NodeOutgoingMessageHost
13
13
  */
14
- export class HttpOutgoingMessageHost extends Duplex {
14
+ export class NodeOutgoingMessageHost extends Duplex {
15
15
  constructor(init) {
16
16
  super();
17
17
  this._headersSent = false;
@@ -64,8 +64,7 @@ export class HttpOutgoingMessageHost extends Duplex {
64
64
  }
65
65
  addTrailers(headers) {
66
66
  if (headers && typeof headers === 'object') {
67
- const entries = typeof headers.entries === 'function'
68
- ? headers.entries() : Object.entries(headers);
67
+ const entries = typeof headers.entries === 'function' ? headers.entries() : Object.entries(headers);
69
68
  let trailers = this[kOutTrailers];
70
69
  if (trailers == null)
71
70
  this[kOutTrailers] = trailers = { __proto__: null };
@@ -78,6 +77,9 @@ export class HttpOutgoingMessageHost extends Duplex {
78
77
  }
79
78
  throw new TypeError('Invalid "headers" argument. Value must be an object or raw headers array');
80
79
  }
80
+ flushHeaders() {
81
+ // nothing to do
82
+ }
81
83
  setHeader(name, value) {
82
84
  if (this.headersSent)
83
85
  throw new Error(`Cannot set headers after they are sent to the client`);
@@ -93,8 +95,7 @@ export class HttpOutgoingMessageHost extends Duplex {
93
95
  if (this.headersSent)
94
96
  throw new Error(`Cannot set headers after they are sent to the client`);
95
97
  if (headers && typeof headers === 'object' && !Array.isArray(headers)) {
96
- const entries = typeof headers.entries === 'function'
97
- ? headers.entries() : Object.entries(headers);
98
+ const entries = typeof headers.entries === 'function' ? headers.entries() : Object.entries(headers);
98
99
  for (const entry of entries) {
99
100
  this.setHeader(entry[0], entry[1]);
100
101
  }
@@ -142,8 +143,7 @@ export class HttpOutgoingMessageHost extends Duplex {
142
143
  }
143
144
  hasHeader(name) {
144
145
  validateString(name);
145
- return this[kOutHeaders] != null &&
146
- !!this[kOutHeaders][name.toLowerCase()];
146
+ return this[kOutHeaders] != null && !!this[kOutHeaders][name.toLowerCase()];
147
147
  }
148
148
  removeHeader(name) {
149
149
  validateString(name);
@@ -188,7 +188,4 @@ export class HttpOutgoingMessageHost extends Duplex {
188
188
  //
189
189
  return this;
190
190
  }
191
- static from(init) {
192
- return new HttpOutgoingMessageHost(init);
193
- }
194
191
  }
@@ -0,0 +1,22 @@
1
+ import { mergePrototype } from '@opra/common';
2
+ import { isHttpIncoming, isNodeIncomingMessage } from '../../type-guards.js';
3
+ import { HttpIncomingHost } from '../impl/http-incoming.host.js';
4
+ import { NodeIncomingMessage } from './node-incoming-message.interface.js';
5
+ /**
6
+ * @namespace HttpIncoming
7
+ */
8
+ export var HttpIncoming;
9
+ (function (HttpIncoming) {
10
+ function from(instance) {
11
+ if (isHttpIncoming(instance))
12
+ return instance;
13
+ if (!isNodeIncomingMessage(instance))
14
+ instance = NodeIncomingMessage.from(instance);
15
+ mergePrototype(instance, HttpIncomingHost.prototype);
16
+ const req = instance;
17
+ req.baseUrl = req.baseUrl || '';
18
+ req.params = req.params || {};
19
+ return req;
20
+ }
21
+ HttpIncoming.from = from;
22
+ })(HttpIncoming || (HttpIncoming = {}));
@@ -0,0 +1,19 @@
1
+ import { mergePrototype } from '@opra/common';
2
+ import { isHttpOutgoing, isNodeOutgoingMessage } from '../../type-guards.js';
3
+ import { HttpOutgoingHost } from '../impl/http-outgoing.host.js';
4
+ import { NodeOutgoingMessage } from './node-outgoing-message.interface.js';
5
+ /**
6
+ * @namespace HttpIncoming
7
+ */
8
+ export var HttpOutgoing;
9
+ (function (HttpOutgoing) {
10
+ function from(instance) {
11
+ if (isHttpOutgoing(instance))
12
+ return instance;
13
+ if (!isNodeOutgoingMessage(instance))
14
+ instance = NodeOutgoingMessage.from(instance);
15
+ mergePrototype(instance, HttpOutgoingHost.prototype);
16
+ return instance;
17
+ }
18
+ HttpOutgoing.from = from;
19
+ })(HttpOutgoing || (HttpOutgoing = {}));
@@ -0,0 +1,61 @@
1
+ import { HTTPParser } from '@browsery/http-parser';
2
+ import { isAsyncIterable, isIterable } from '@opra/common';
3
+ import { Readable } from 'stream';
4
+ import { CRLF, kHttpParser, NodeIncomingMessageHost } from '../impl/node-incoming-message.host.js';
5
+ import { concatReadable } from '../utils/concat-readable.js';
6
+ /**
7
+ *
8
+ * @namespace NodeIncomingMessage
9
+ */
10
+ export var NodeIncomingMessage;
11
+ (function (NodeIncomingMessage) {
12
+ /**
13
+ * Creates a new NodeIncomingMessage from given argument
14
+ * @param iterable
15
+ */
16
+ function from(iterable) {
17
+ if (typeof iterable === 'object' && !(isIterable(iterable) || isAsyncIterable(iterable))) {
18
+ return new NodeIncomingMessageHost(iterable);
19
+ }
20
+ const msg = new NodeIncomingMessageHost();
21
+ const parser = (msg[kHttpParser] = new HTTPParser(HTTPParser.REQUEST));
22
+ let bodyChunks;
23
+ parser[HTTPParser.kOnHeadersComplete] = (info) => {
24
+ msg.httpVersionMajor = info.versionMajor;
25
+ msg.httpVersionMinor = info.versionMinor;
26
+ msg.rawHeaders = info.headers;
27
+ msg.method = HTTPParser.methods[info.method];
28
+ msg.url = info.url;
29
+ msg.emit('headers');
30
+ };
31
+ parser[HTTPParser.kOnHeaders] = (trailers) => {
32
+ msg.rawTrailers = trailers;
33
+ };
34
+ parser[HTTPParser.kOnBody] = (chunk, offset, length) => {
35
+ bodyChunks = bodyChunks || [];
36
+ bodyChunks.push(chunk.subarray(offset, offset + length));
37
+ };
38
+ const readable = concatReadable(Readable.from(iterable), Readable.from(CRLF));
39
+ msg.once('finish', () => {
40
+ parser.finish();
41
+ msg.complete = true;
42
+ if (bodyChunks)
43
+ msg.body = Buffer.concat(bodyChunks);
44
+ });
45
+ readable.pipe(msg);
46
+ return msg;
47
+ }
48
+ NodeIncomingMessage.from = from;
49
+ /**
50
+ * Creates a new NodeIncomingMessage from given argument
51
+ * @param iterable
52
+ */
53
+ async function fromAsync(iterable) {
54
+ return new Promise((resolve, reject) => {
55
+ const msg = from(iterable);
56
+ msg.once('finish', () => resolve(msg));
57
+ msg.once('error', error => reject(error));
58
+ });
59
+ }
60
+ NodeIncomingMessage.fromAsync = fromAsync;
61
+ })(NodeIncomingMessage || (NodeIncomingMessage = {}));
@@ -0,0 +1,12 @@
1
+ import { NodeOutgoingMessageHost } from '../impl/node-outgoing-message.host.js';
2
+ /**
3
+ *
4
+ * @namespace NodeOutgoingMessage
5
+ */
6
+ export var NodeOutgoingMessage;
7
+ (function (NodeOutgoingMessage) {
8
+ function from(init) {
9
+ return new NodeOutgoingMessageHost(init);
10
+ }
11
+ NodeOutgoingMessage.from = from;
12
+ })(NodeOutgoingMessage || (NodeOutgoingMessage = {}));