webhoster 0.3.3 → 0.3.5

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 (157) hide show
  1. package/README.md +4 -4
  2. package/data/CookieObject.js +1 -1
  3. package/{types/index.js → data/custom-types.js} +1 -1
  4. package/{types/typings.d.ts → data/middleware.d.ts} +1 -1
  5. package/helpers/RequestReader.js +1 -1
  6. package/helpers/ResponseHeaders.js +9 -10
  7. package/lib/HttpHandler.js +4 -4
  8. package/lib/HttpRequest.js +2 -2
  9. package/lib/HttpResponse.js +2 -2
  10. package/lib/HttpTransaction.js +2 -2
  11. package/middleware/AutoHeadersMiddleware.js +2 -2
  12. package/middleware/CORSMiddleware.js +3 -3
  13. package/middleware/CaseInsensitiveHeadersMiddleware.js +2 -2
  14. package/middleware/ContentDecoderMiddleware.js +1 -1
  15. package/middleware/ContentEncoderMiddleware.js +2 -2
  16. package/middleware/ContentLengthMiddleware.js +2 -2
  17. package/middleware/HashMiddleware.js +2 -2
  18. package/middleware/HeadMethodMiddleware.js +3 -3
  19. package/middleware/MethodMiddleware.js +3 -3
  20. package/middleware/PathMiddleware.js +4 -4
  21. package/middleware/ReadFormData.js +1 -1
  22. package/middleware/SendJsonMiddleware.js +4 -4
  23. package/middleware/SendStringMiddleware.js +3 -3
  24. package/package.json +21 -4
  25. package/templates/starter.js +2 -2
  26. package/types/data/CookieObject.d.ts +34 -0
  27. package/types/data/CookieObject.d.ts.map +1 -0
  28. package/types/data/custom-types.d.ts +111 -0
  29. package/types/data/custom-types.d.ts.map +1 -0
  30. package/types/errata/socketio.d.ts +11 -0
  31. package/types/errata/socketio.d.ts.map +1 -0
  32. package/types/examples/starter.d.ts +2 -0
  33. package/types/examples/starter.d.ts.map +1 -0
  34. package/types/helpers/HeadersParser.d.ts +27 -0
  35. package/types/helpers/HeadersParser.d.ts.map +1 -0
  36. package/types/helpers/HttpListener.d.ts +84 -0
  37. package/types/helpers/HttpListener.d.ts.map +1 -0
  38. package/types/helpers/RequestHeaders.d.ts +25 -0
  39. package/types/helpers/RequestHeaders.d.ts.map +1 -0
  40. package/types/helpers/RequestReader.d.ts +52 -0
  41. package/types/helpers/RequestReader.d.ts.map +1 -0
  42. package/types/helpers/ResponseHeaders.d.ts +126 -0
  43. package/types/helpers/ResponseHeaders.d.ts.map +1 -0
  44. package/types/helpers/index.d.ts +6 -0
  45. package/types/helpers/index.d.ts.map +1 -0
  46. package/types/lib/HttpHandler.d.ts +79 -0
  47. package/types/lib/HttpHandler.d.ts.map +1 -0
  48. package/types/lib/HttpRequest.d.ts +175 -0
  49. package/types/lib/HttpRequest.d.ts.map +1 -0
  50. package/types/lib/HttpResponse.d.ts +117 -0
  51. package/types/lib/HttpResponse.d.ts.map +1 -0
  52. package/types/lib/HttpTransaction.d.ts +114 -0
  53. package/types/lib/HttpTransaction.d.ts.map +1 -0
  54. package/types/middleware/AutoHeadersMiddleware.d.ts +27 -0
  55. package/types/middleware/AutoHeadersMiddleware.d.ts.map +1 -0
  56. package/types/middleware/CORSMiddleware.d.ts +65 -0
  57. package/types/middleware/CORSMiddleware.d.ts.map +1 -0
  58. package/types/middleware/CaseInsensitiveHeadersMiddleware.d.ts +27 -0
  59. package/types/middleware/CaseInsensitiveHeadersMiddleware.d.ts.map +1 -0
  60. package/types/middleware/ContentDecoderMiddleware.d.ts +17 -0
  61. package/types/middleware/ContentDecoderMiddleware.d.ts.map +1 -0
  62. package/types/middleware/ContentEncoderMiddleware.d.ts +48 -0
  63. package/types/middleware/ContentEncoderMiddleware.d.ts.map +1 -0
  64. package/types/middleware/ContentLengthMiddleware.d.ts +38 -0
  65. package/types/middleware/ContentLengthMiddleware.d.ts.map +1 -0
  66. package/types/middleware/HashMiddleware.d.ts +28 -0
  67. package/types/middleware/HashMiddleware.d.ts.map +1 -0
  68. package/types/middleware/HeadMethodMiddleware.d.ts +12 -0
  69. package/types/middleware/HeadMethodMiddleware.d.ts.map +1 -0
  70. package/types/middleware/MethodMiddleware.d.ts +40 -0
  71. package/types/middleware/MethodMiddleware.d.ts.map +1 -0
  72. package/types/middleware/PathMiddleware.d.ts +81 -0
  73. package/types/middleware/PathMiddleware.d.ts.map +1 -0
  74. package/types/middleware/ReadFormData.d.ts +7 -0
  75. package/types/middleware/ReadFormData.d.ts.map +1 -0
  76. package/types/middleware/SendJsonMiddleware.d.ts +51 -0
  77. package/types/middleware/SendJsonMiddleware.d.ts.map +1 -0
  78. package/types/middleware/SendStringMiddleware.d.ts +35 -0
  79. package/types/middleware/SendStringMiddleware.d.ts.map +1 -0
  80. package/types/templates/starter.d.ts +15 -0
  81. package/types/templates/starter.d.ts.map +1 -0
  82. package/types/utils/AsyncObject.d.ts +38 -0
  83. package/types/utils/AsyncObject.d.ts.map +1 -0
  84. package/types/utils/CaseInsensitiveObject.d.ts +9 -0
  85. package/types/utils/CaseInsensitiveObject.d.ts.map +1 -0
  86. package/types/utils/function.d.ts +2 -0
  87. package/types/utils/function.d.ts.map +1 -0
  88. package/types/utils/headers.d.ts +7 -0
  89. package/types/utils/headers.d.ts.map +1 -0
  90. package/types/utils/qualityValues.d.ts +12 -0
  91. package/types/utils/qualityValues.d.ts.map +1 -0
  92. package/types/utils/stream.d.ts +6 -0
  93. package/types/utils/stream.d.ts.map +1 -0
  94. package/utils/headers.js +1 -1
  95. package/.eslintrc.json +0 -96
  96. package/.github/FUNDING.yml +0 -4
  97. package/.github/copilot-instructions.md +0 -100
  98. package/.github/workflows/publish.yml +0 -29
  99. package/.github/workflows/test-matrix.yml +0 -37
  100. package/.test/benchmark.js +0 -28
  101. package/.test/constants.js +0 -4
  102. package/.test/cookietester.js +0 -19
  103. package/.test/http2server.js +0 -35
  104. package/.test/httpserver.js +0 -32
  105. package/.test/index.js +0 -498
  106. package/.test/multipromise.js +0 -32
  107. package/.test/tls.js +0 -75
  108. package/.test/urlencoded.js +0 -54
  109. package/.vscode/launch.json +0 -35
  110. package/.vscode/settings.json +0 -5
  111. package/CHANGELOG.md +0 -10
  112. package/CODE_OF_CONDUCT.md +0 -76
  113. package/errata/index.js +0 -1
  114. package/examples/starter.js +0 -11
  115. package/index.js +0 -4
  116. package/jsconfig.json +0 -12
  117. package/lib/index.js +0 -3
  118. package/middleware/ContentReaderMiddleware.js +0 -249
  119. package/middleware/ContentWriterMiddleware.js +0 -161
  120. package/middleware/SendHeadersMiddleware.js +0 -47
  121. package/middleware/index.js +0 -11
  122. package/polyfill/FormData.js +0 -164
  123. package/rollup.config.js +0 -8
  124. package/scripts/check-teapot.mjs +0 -40
  125. package/scripts/test-all-sync.sh +0 -6
  126. package/scripts/test-all.sh +0 -7
  127. package/test/fixtures/stream.js +0 -68
  128. package/test/helpers/HttpListener/construct.js +0 -18
  129. package/test/helpers/HttpListener/customOptions.js +0 -22
  130. package/test/helpers/HttpListener/doubleCreate.js +0 -40
  131. package/test/helpers/HttpListener/events.js +0 -77
  132. package/test/helpers/HttpListener/http.js +0 -31
  133. package/test/helpers/HttpListener/http2.js +0 -41
  134. package/test/helpers/HttpListener/https.js +0 -38
  135. package/test/helpers/HttpListener/startAll.js +0 -31
  136. package/test/helpers/HttpListener/stopNotStarted.js +0 -23
  137. package/test/lib/HttpHandler/class.js +0 -8
  138. package/test/lib/HttpHandler/handleRequest.js +0 -11
  139. package/test/lib/HttpHandler/middleware.js +0 -941
  140. package/test/lib/HttpHandler/parse.js +0 -41
  141. package/test/lib/HttpRequest/class.js +0 -8
  142. package/test/lib/HttpRequest/downstream.js +0 -171
  143. package/test/lib/HttpRequest/properties.js +0 -101
  144. package/test/lib/HttpRequest/read.js +0 -518
  145. package/test/lib/HttpResponse/async-iterable-middleware.js +0 -37
  146. package/test/lib/HttpResponse/async-iterable.js +0 -31
  147. package/test/lib/HttpResponse/class.js +0 -8
  148. package/test/lib/HttpResponse/properties.js +0 -59
  149. package/test/lib/HttpResponse/send.js +0 -275
  150. package/test/lib/HttpTransaction/class.js +0 -8
  151. package/test/lib/HttpTransaction/ping.js +0 -50
  152. package/test/lib/HttpTransaction/push.js +0 -89
  153. package/test/middleware/SendJsonMiddleware.js +0 -222
  154. package/test/sanity.js +0 -10
  155. package/test/templates/error-teapot.js +0 -47
  156. package/test/templates/starter.js +0 -93
  157. package/tsconfig.json +0 -30
@@ -1,275 +0,0 @@
1
- import { PassThrough, pipeline } from 'node:stream';
2
-
3
- import test from 'ava';
4
-
5
- import HttpHandler from '../../../lib/HttpHandler.js';
6
- import HttpResponse from '../../../lib/HttpResponse.js';
7
-
8
- test('HttpResponse.sendStatusOnly() - header sent', async (t) => {
9
- const res = new HttpResponse({
10
- onHeadersSent: () => true,
11
- stream: new PassThrough(),
12
- });
13
- const error = await t.throwsAsync(() => res.sendStatusOnly(500));
14
- t.is(error.message, 'ERR_HEADER_SENT');
15
- });
16
-
17
- test('HttpResponse.sendStatusOnly() - not implemented', async (t) => {
18
- const res = new HttpResponse({
19
- onHeadersSent: () => false,
20
- stream: new PassThrough(),
21
- });
22
- const error = await t.throwsAsync(() => res.sendStatusOnly(500));
23
- t.is(error.message, 'NOT_IMPLEMENTED');
24
- });
25
-
26
- test('HttpResponse.sendStatusOnly() - not writable', async (t) => {
27
- const res = new HttpResponse({
28
- onHeadersSent: () => false,
29
- stream: new PassThrough(),
30
- });
31
- res.stream.destroy();
32
- const error = await t.throwsAsync(() => res.sendStatusOnly(500));
33
- t.is(error.message, 'NOT_WRITABLE');
34
- });
35
-
36
- test('HttpResponse.sendStatusOnly()', async (t) => {
37
- t.plan(3);
38
- const res = new HttpResponse({
39
- onHeadersSent: () => false,
40
- stream: new PassThrough(),
41
- onSendHeaders: (flush, end) => {
42
- t.true(end);
43
- },
44
- });
45
- const result = await res.sendStatusOnly(500);
46
- t.is(res.status, 500);
47
- t.is(result, HttpHandler.END);
48
- });
49
-
50
- test('HttpResponse.sendHeaders()', async (t) => {
51
- const res = new HttpResponse({
52
- stream: new PassThrough(),
53
- onSendHeaders: () => {},
54
- });
55
- t.false(res.headersSent);
56
- const result = await res.sendHeaders();
57
- t.true(res.headersSent);
58
- });
59
-
60
- test('HttpResponse.sendHeaders() - cannot resend', async (t) => {
61
- const res = new HttpResponse({
62
- stream: new PassThrough(),
63
- onSendHeaders: () => {},
64
- });
65
- t.false(res.headersSent);
66
- res.sendHeaders();
67
- t.true(res.headersSent);
68
- const error = t.throws(() => res.sendHeaders());
69
- t.is(error.message, 'HEADER_SENT');
70
- });
71
-
72
- test('HttpResponse.sendRaw()', async (t) => {
73
- const stream = new PassThrough();
74
- const reader = new PassThrough();
75
- stream.pipe(reader);
76
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
77
- t.false(stream.writableEnded);
78
- const result = await res.sendRaw(Buffer.from('foo'));
79
- t.is(result, HttpHandler.END);
80
- t.true(stream.writableEnded);
81
-
82
- for await (const chunk of reader) {
83
- t.is(chunk.toString(), 'foo');
84
- }
85
- });
86
-
87
- test('HttpResponse.send() - non-writable', async (t) => {
88
- const stream = new PassThrough();
89
- const reader = new PassThrough();
90
- stream.pipe(reader);
91
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
92
- t.false(stream.destroyed);
93
- stream.destroy();
94
- const error = await t.throwsAsync(() => res.send(Buffer.from('foo')));
95
- t.is(error.message, 'NOT_WRITABLE');
96
- });
97
-
98
- test('HttpResponse.send() - null', async (t) => {
99
- const stream = new PassThrough();
100
- const reader = new PassThrough();
101
- stream.pipe(reader);
102
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
103
- t.false(stream.writableEnded);
104
- const result = await res.send();
105
- t.is(result, HttpHandler.END);
106
- t.true(stream.writableEnded);
107
-
108
- for await (const chunk of reader) {
109
- t.fail();
110
- }
111
- });
112
-
113
- test('HttpResponse.send() - content-handler typeof string', async (t) => {
114
- const stream = new PassThrough();
115
- const reader = new PassThrough();
116
- stream.pipe(reader);
117
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
118
- response.finalizers.push((res) => {
119
- if (typeof res.body === 'string') {
120
- res.body = Buffer.from(res.body, 'latin1');
121
- }
122
- });
123
- t.false(stream.writableEnded);
124
- const result = await response.send('foo');
125
- t.is(result, HttpHandler.END);
126
- t.true(stream.writableEnded);
127
-
128
- for await (const chunk of reader) {
129
- t.true(Buffer.isBuffer(chunk));
130
- t.is(chunk.toString('latin1'), 'foo');
131
- }
132
- });
133
-
134
- test('HttpResponse.send() - content-handler instanceof Date', async (t) => {
135
- const stream = new PassThrough();
136
- const reader = new PassThrough();
137
- stream.pipe(reader);
138
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
139
- const d = new Date(0);
140
- response.finalizers.push((res) => {
141
- if (res.body instanceof Date) {
142
- res.body = Buffer.from(res.body.toISOString(), 'latin1');
143
- }
144
- });
145
- t.false(stream.writableEnded);
146
- const result = await response.send(d);
147
- t.is(result, HttpHandler.END);
148
- t.true(stream.writableEnded);
149
-
150
- for await (const chunk of reader) {
151
- t.true(Buffer.isBuffer(chunk));
152
- t.is(chunk.toString('latin1'), d.toISOString());
153
- }
154
- });
155
-
156
- test('HttpResponse.send()', async (t) => {
157
- const stream = new PassThrough();
158
- const reader = new PassThrough();
159
- stream.pipe(reader);
160
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
161
- t.false(stream.writableEnded);
162
- const result = await res.send(Buffer.from('foo'));
163
- t.is(result, HttpHandler.END);
164
- t.true(stream.writableEnded);
165
-
166
- for await (const chunk of reader) {
167
- t.true(Buffer.isBuffer(chunk));
168
- t.is(chunk.toString(), 'foo');
169
- }
170
- });
171
-
172
- test('HttpResponse.end() - non-writable', async (t) => {
173
- t.plan(7);
174
- const stream = new PassThrough();
175
- const reader = new PassThrough();
176
- pipeline(stream, reader, (err) => {
177
- if (err) t.pass();
178
- else t.fail();
179
- });
180
- // stream.pipe(reader);
181
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
182
- t.false(stream.destroyed);
183
- stream.destroy();
184
- t.true(stream.destroyed);
185
-
186
- const result = res.end(Buffer.from('foo'));
187
- t.is(result, HttpHandler.END);
188
- t.false(stream.writableEnded);
189
- t.true(stream.destroyed);
190
- try {
191
- for await (const chunk of reader) {
192
- t.fail();
193
- }
194
- } catch {
195
- // Cannot read from destroyed stream;
196
- t.pass();
197
- }
198
- });
199
-
200
- test('HttpResponse.end() - content-handler typeof string', async (t) => {
201
- const stream = new PassThrough();
202
- const reader = new PassThrough();
203
- stream.pipe(reader);
204
- const response = new HttpResponse({
205
- stream,
206
- onSendHeaders: () => {},
207
- });
208
- response.finalizers.push((res) => {
209
- if (typeof res.body === 'string') {
210
- res.body = Buffer.from(res.body, 'latin1');
211
- }
212
- });
213
- t.false(stream.writableEnded);
214
- const result = response.end('foo');
215
- t.is(result, HttpHandler.END);
216
- t.true(stream.writableEnded);
217
-
218
- for await (const chunk of reader) {
219
- t.true(Buffer.isBuffer(chunk));
220
- t.is(chunk.toString('latin1'), 'foo');
221
- }
222
- });
223
-
224
- test('HttpResponse.end() - content-handler instanceof Date', async (t) => {
225
- const stream = new PassThrough();
226
- const reader = new PassThrough();
227
- stream.pipe(reader);
228
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
229
- const d = new Date(0);
230
- response.finalizers.push((res) => {
231
- if (res.body instanceof Date) {
232
- res.body = Buffer.from(res.body.toISOString(), 'latin1');
233
- }
234
- });
235
- t.false(stream.writableEnded);
236
- const result = response.end(d);
237
- t.is(result, HttpHandler.END);
238
- t.true(stream.writableEnded);
239
-
240
- for await (const chunk of reader) {
241
- t.true(Buffer.isBuffer(chunk));
242
- t.is(chunk.toString('latin1'), d.toISOString());
243
- }
244
- });
245
-
246
- test('HttpResponse.end() - null', async (t) => {
247
- const stream = new PassThrough();
248
- const reader = new PassThrough();
249
- stream.pipe(reader);
250
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
251
- t.false(stream.writableEnded);
252
- const result = res.end();
253
- t.is(result, HttpHandler.END);
254
- t.true(stream.writableEnded);
255
-
256
- for await (const chunk of reader) {
257
- t.fail();
258
- }
259
- });
260
-
261
- test('HttpResponse.end()', async (t) => {
262
- const stream = new PassThrough();
263
- const reader = new PassThrough();
264
- stream.pipe(reader);
265
- const res = new HttpResponse({ stream, onSendHeaders: () => {} });
266
- t.false(stream.writableEnded);
267
- const result = res.end(Buffer.from('foo'));
268
- t.is(result, HttpHandler.END);
269
- t.true(stream.writableEnded);
270
-
271
- for await (const chunk of reader) {
272
- t.true(Buffer.isBuffer(chunk));
273
- t.is(chunk.toString(), 'foo');
274
- }
275
- });
@@ -1,8 +0,0 @@
1
- import test from 'ava';
2
-
3
- import HttpTransaction from '../../../lib/HttpTransaction.js';
4
-
5
- test('new HttpTransaction()', (t) => {
6
- const req = new HttpTransaction({});
7
- t.assert(req instanceof HttpTransaction);
8
- });
@@ -1,50 +0,0 @@
1
- import test from 'ava';
2
-
3
- import HttpTransaction from '../../../lib/HttpTransaction.js';
4
-
5
- test('HttpTransaction.canPing', (t) => {
6
- t.false(new HttpTransaction({}).canPing);
7
-
8
- t.true(new HttpTransaction({ canPing: true }).canPing);
9
-
10
- t.false(new HttpTransaction({ canPing: false }).canPing);
11
-
12
- t.false(new HttpTransaction({ canPing: () => false }).canPing);
13
-
14
- t.true(new HttpTransaction({ canPing: () => true }).canPing);
15
- });
16
-
17
- test('HttpTransaction.ping - not supported', async (t) => {
18
- const transaction = new HttpTransaction({});
19
- t.false(transaction.canPing);
20
- const error = await t.throwsAsync(async () => await transaction.ping());
21
- t.is(error.message, 'NOT_SUPPORTED');
22
- });
23
-
24
- test('HttpTransaction.ping - not implemented', async (t) => {
25
- const transaction = new HttpTransaction({ canPing: true });
26
- const error = await t.throwsAsync(async () => await transaction.ping());
27
- t.is(error.message, 'NOT_IMPLEMENTED');
28
- });
29
-
30
- test('HttpTransaction.ping - canPing guard ', async (t) => {
31
- let testValue = false;
32
- const transaction = new HttpTransaction({
33
- canPing: false,
34
- onPing() { testValue = true; },
35
- });
36
- t.false(testValue);
37
- await t.throwsAsync(async () => await transaction.ping());
38
- t.false(testValue);
39
- });
40
-
41
- test('HttpTransaction.ping', async (t) => {
42
- let testValue = false;
43
- const transaction = new HttpTransaction({
44
- canPing: true,
45
- onPing: () => { testValue = true; },
46
- });
47
- t.false(testValue);
48
- await transaction.ping();
49
- t.true(testValue);
50
- });
@@ -1,89 +0,0 @@
1
- import test from 'ava';
2
-
3
- import HttpTransaction from '../../../lib/HttpTransaction.js';
4
-
5
- test('HttpTransaction.canPushPath', (t) => {
6
- t.false(new HttpTransaction({}).canPushPath);
7
-
8
- t.true(new HttpTransaction({ canPushPath: true }).canPushPath);
9
-
10
- t.false(new HttpTransaction({ canPushPath: false }).canPushPath);
11
-
12
- t.false(new HttpTransaction({ canPushPath: () => false }).canPushPath);
13
-
14
- t.true(new HttpTransaction({ canPushPath: () => true }).canPushPath);
15
- });
16
-
17
- test('HttpTransaction.pushPath - not supported', async (t) => {
18
- const request = new HttpTransaction({});
19
- t.false(request.canPushPath);
20
- const error = await t.throwsAsync(() => request.pushPath());
21
- t.is(error.message, 'NOT_SUPPORTED');
22
- });
23
-
24
- test('HttpTransaction.pushPath - not implemented', async (t) => {
25
- const request = new HttpTransaction({ canPushPath: true });
26
- const error = await t.throwsAsync(() => request.pushPath());
27
- t.is(error.message, 'NOT_IMPLEMENTED');
28
- });
29
-
30
- test('HttpTransaction.pushPath - canPushPath guard ', async (t) => {
31
- let testValue = false;
32
- const request = new HttpTransaction({
33
- canPushPath: false,
34
- onPushPath() { testValue = true; },
35
- });
36
- t.false(testValue);
37
- await t.throwsAsync(() => request.pushPath());
38
- t.false(testValue);
39
- });
40
-
41
- test('HttpTransaction.pushPath - already pushed ', async (t) => {
42
- let testValue = false;
43
- const request = new HttpTransaction({
44
- canPushPath: true,
45
- onPushPath: (path) => { testValue = true; },
46
- });
47
- t.false(testValue);
48
- await request.pushPath('/styles.css');
49
- t.true(testValue);
50
- const error = await t.throwsAsync(() => request.pushPath('/styles.css'));
51
- t.is(error.message, 'ALREADY_PUSHED');
52
- });
53
-
54
- test('HttpTransaction.pushPath', async (t) => {
55
- let testValue = false;
56
- const request = new HttpTransaction({
57
- canPushPath: true,
58
- onPushPath: () => { testValue = true; },
59
- });
60
- t.false(testValue);
61
- await request.pushPath('/styles.css');
62
- t.true(testValue);
63
- await request.pushPath('/script.js');
64
- });
65
-
66
- test('HttpTransaction.pushPath - failure', async (t) => {
67
- const request = new HttpTransaction({
68
- canPushPath: true,
69
- onPushPath: (path) => {
70
- if (path === '/styles.css') throw new Error('TEST');
71
- },
72
- });
73
- t.deepEqual(request.pushedPaths, []);
74
- const error = await t.throwsAsync(() => request.pushPath('/styles.css'));
75
- t.is(error.message, 'TEST');
76
- await request.pushPath('/script.js');
77
- t.deepEqual(request.pushedPaths, ['/script.js']);
78
- });
79
-
80
- test('HttpTransaction.pushedPaths', async (t) => {
81
- const request = new HttpTransaction({
82
- canPushPath: true,
83
- onPushPath: () => {},
84
- });
85
- t.deepEqual(request.pushedPaths, []);
86
- await request.pushPath('/styles.css');
87
- await request.pushPath('/script.js');
88
- t.deepEqual(request.pushedPaths, ['/styles.css', '/script.js']);
89
- });
@@ -1,222 +0,0 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { PassThrough } from 'node:stream';
3
-
4
- import test from 'ava';
5
-
6
- import HttpResponse from '../../lib/HttpResponse.js';
7
- import SendJsonMiddleware from '../../middleware/SendJsonMiddleware.js';
8
-
9
- test('new SendJsonMiddleware()', (t) => {
10
- const instance = new SendJsonMiddleware();
11
- t.assert(instance instanceof SendJsonMiddleware);
12
- });
13
-
14
- test('SendJsonMiddleware.execute()', async (t) => {
15
- const stream = new PassThrough();
16
- const reader = new PassThrough();
17
- stream.pipe(reader);
18
- const response = new HttpResponse({
19
- stream,
20
- onSendHeaders: () => {},
21
- });
22
- const middleware = new SendJsonMiddleware();
23
- middleware.execute({ response });
24
-
25
- /** @type {any} */
26
- const jsonContent = {
27
- number: Math.floor(Math.random() * 10),
28
- date: new Date(Math.random() * Date.now()),
29
- string: randomBytes(48).toString('hex'),
30
- boolean: true,
31
- null: null,
32
- array: [
33
- 1,
34
- 2,
35
- ],
36
- object: {
37
- key: 'value',
38
- },
39
- };
40
-
41
- await response.send(jsonContent);
42
-
43
- for await (const chunk of reader) {
44
- const s = chunk.toString();
45
- const data = JSON.parse(s);
46
- t.deepEqual(data, {
47
- ...jsonContent,
48
- date: jsonContent.date.toISOString(),
49
- });
50
- }
51
-
52
- t.is(response.headers['content-type'], 'application/json;charset=utf-8');
53
- });
54
-
55
- test('SendJsonMiddleware.Execute() (static)', async (t) => {
56
- const stream = new PassThrough();
57
- const reader = new PassThrough();
58
- stream.pipe(reader);
59
- const response = new HttpResponse({
60
- stream,
61
- onSendHeaders: () => {},
62
- });
63
- SendJsonMiddleware.Execute({ response });
64
-
65
- /** @type {any} */
66
- const jsonContent = {
67
- number: Math.floor(Math.random() * 10),
68
- date: new Date(Math.random() * Date.now()),
69
- string: randomBytes(48).toString('hex'),
70
- boolean: true,
71
- null: null,
72
- array: [
73
- 1,
74
- 2,
75
- ],
76
- object: {
77
- key: 'value',
78
- },
79
- };
80
-
81
- await response.send(jsonContent);
82
-
83
- for await (const chunk of reader) {
84
- const s = chunk.toString();
85
- const data = JSON.parse(s);
86
- t.deepEqual(data, {
87
- ...jsonContent,
88
- date: jsonContent.date.toISOString(),
89
- });
90
- }
91
-
92
- t.is(response.headers['content-type'], 'application/json;charset=utf-8');
93
- });
94
-
95
- test('SendJsonMiddleware.charsetAsBufferEncoding covers all branches', (t) => {
96
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('utf-8'), 'utf-8');
97
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('utf8'), 'utf-8');
98
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('latin1'), 'latin1');
99
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('iso-8859-1'), 'latin1');
100
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('ascii'), 'latin1');
101
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('binary'), 'latin1');
102
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('utf16le'), 'utf16le');
103
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('utf-16le'), 'utf16le');
104
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('ucs-2'), 'utf16le');
105
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('ucs2'), 'utf16le');
106
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('base64'), 'base64');
107
- t.is(SendJsonMiddleware.charsetAsBufferEncoding('hex'), 'hex');
108
- });
109
-
110
- test('SendJsonMiddleware: setMediaType false but setCharset true appends charset only', async (t) => {
111
- const stream = new PassThrough();
112
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
113
- const middleware = new SendJsonMiddleware({ setMediaType: false });
114
- middleware.execute({ response });
115
- await response.send({ foo: 'bar' });
116
- t.is(response.headers['content-type'], ';charset=utf-8');
117
- });
118
-
119
- test('SendJsonMiddleware: setCharset false still sets application/json', async (t) => {
120
- const stream = new PassThrough();
121
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
122
- const middleware = new SendJsonMiddleware({ setCharset: false });
123
- middleware.execute({ response });
124
- await response.send({ foo: 'bar' });
125
- t.is(response.headers['content-type'], 'application/json');
126
- });
127
-
128
- test('SendJsonMiddleware: setMediaType false and setCharset false does not set content-type', async (t) => {
129
- const stream = new PassThrough();
130
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
131
- const middleware = new SendJsonMiddleware({ setMediaType: false, setCharset: false });
132
- middleware.execute({ response });
133
- await response.send({ foo: 'bar' });
134
- t.falsy(response.headers['content-type']);
135
- });
136
-
137
- test('SendJsonMiddleware: custom defaultCharset (latin1)', async (t) => {
138
- const stream = new PassThrough();
139
- const reader = new PassThrough();
140
- stream.pipe(reader);
141
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
142
- const middleware = new SendJsonMiddleware({ defaultCharset: 'latin1' });
143
- middleware.execute({ response });
144
- await response.send({ foo: 'bär' });
145
- t.regex(String(response.headers['content-type']), /charset=latin1/);
146
- for await (const chunk of reader) {
147
- t.is(chunk.toString('latin1'), JSON.stringify({ foo: 'bär' }));
148
- }
149
- });
150
-
151
- test('SendJsonMiddleware: respects existing content-type with charset', async (t) => {
152
- const stream = new PassThrough();
153
- const reader = new PassThrough();
154
- stream.pipe(reader);
155
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
156
- response.headers['content-type'] = 'application/json; charset=utf-16le';
157
- const middleware = new SendJsonMiddleware();
158
- middleware.execute({ response });
159
- await response.send({ foo: 'bar' });
160
- t.regex(String(response.headers['content-type']), /charset=utf-16le/);
161
- for await (const chunk of reader) {
162
- t.is(chunk.toString('utf16le'), JSON.stringify({ foo: 'bar' }));
163
- }
164
- });
165
-
166
- test('SendJsonMiddleware: adds charset if content-type is just "application/json"', async (t) => {
167
- const stream = new PassThrough();
168
- const reader = new PassThrough();
169
- stream.pipe(reader);
170
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
171
- response.headers['content-type'] = 'application/json';
172
- const middleware = new SendJsonMiddleware();
173
- middleware.execute({ response });
174
- await response.send({ foo: 'bar' });
175
- t.is(response.headers['content-type'], 'application/json;charset=utf-8');
176
- for await (const chunk of reader) {
177
- t.is(chunk.toString('utf-8'), JSON.stringify({ foo: 'bar' }));
178
- }
179
- });
180
-
181
- test('SendJsonMiddleware: quoted charset in content-type', async (t) => {
182
- const stream = new PassThrough();
183
- const reader = new PassThrough();
184
- stream.pipe(reader);
185
- const response = new HttpResponse({ stream, onSendHeaders: () => {} });
186
- response.headers['content-type'] = 'application/json; charset="utf-8"';
187
- const middleware = new SendJsonMiddleware();
188
- middleware.execute({ response });
189
- await response.send({ foo: 'bar' });
190
- t.regex(String(response.headers['content-type']), /charset="?utf-8"?/);
191
- for await (const chunk of reader) {
192
- t.is(chunk.toString('utf-8'), JSON.stringify({ foo: 'bar' }));
193
- }
194
- });
195
-
196
- test('SendJsonMiddleware: does nothing for streaming response', (t) => {
197
- const response = new HttpResponse({ stream: new PassThrough(), onSendHeaders: () => {} });
198
- response.isStreaming = true;
199
- const middleware = new SendJsonMiddleware();
200
- middleware.execute({ response });
201
- // Should not throw or modify body
202
- t.notThrows(() => { for (const function_ of response.finalizers) function_(response); });
203
- });
204
-
205
- test('SendJsonMiddleware: does nothing for Buffer body', (t) => {
206
- const response = new HttpResponse({ stream: new PassThrough(), onSendHeaders: () => {} });
207
- response.body = Buffer.from('foo');
208
- const middleware = new SendJsonMiddleware();
209
- middleware.execute({ response });
210
- t.notThrows(() => { for (const function_ of response.finalizers) function_(response); });
211
- t.true(Buffer.isBuffer(response.body));
212
- });
213
-
214
- test('SendJsonMiddleware: does nothing for null/undefined body', (t) => {
215
- const response = new HttpResponse({ stream: new PassThrough(), onSendHeaders: () => {} });
216
- response.body = null;
217
- const middleware = new SendJsonMiddleware();
218
- middleware.execute({ response });
219
- t.notThrows(() => { for (const function_ of response.finalizers) function_(response); });
220
- response.body = undefined;
221
- t.notThrows(() => { for (const function_ of response.finalizers) function_(response); });
222
- });
package/test/sanity.js DELETED
@@ -1,10 +0,0 @@
1
- import test from 'ava';
2
-
3
- test('sync test', (t) => {
4
- t.pass();
5
- });
6
-
7
- test('async test', async (t) => {
8
- const bar = Promise.resolve('bar');
9
- t.is(await bar, 'bar');
10
- });