webhoster 0.3.2 → 0.3.4

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 (37) hide show
  1. package/.github/workflows/publish.yml +29 -0
  2. package/.test/index.js +1 -1
  3. package/README.md +4 -4
  4. package/data/CookieObject.js +1 -1
  5. package/{types/index.js → data/custom-types.js} +1 -1
  6. package/{types/typings.d.ts → data/middleware.d.ts} +1 -1
  7. package/helpers/HttpListener.js +20 -94
  8. package/helpers/RequestReader.js +1 -12
  9. package/helpers/ResponseHeaders.js +9 -10
  10. package/lib/HttpHandler.js +17 -7
  11. package/lib/HttpRequest.js +7 -4
  12. package/lib/HttpResponse.js +11 -5
  13. package/lib/HttpTransaction.js +2 -2
  14. package/middleware/AutoHeadersMiddleware.js +2 -2
  15. package/middleware/CORSMiddleware.js +3 -3
  16. package/middleware/CaseInsensitiveHeadersMiddleware.js +2 -2
  17. package/middleware/ContentDecoderMiddleware.js +12 -8
  18. package/middleware/ContentEncoderMiddleware.js +6 -5
  19. package/middleware/ContentLengthMiddleware.js +2 -2
  20. package/middleware/HashMiddleware.js +2 -2
  21. package/middleware/HeadMethodMiddleware.js +3 -3
  22. package/middleware/MethodMiddleware.js +3 -3
  23. package/middleware/PathMiddleware.js +4 -4
  24. package/middleware/ReadFormData.js +1 -1
  25. package/middleware/SendJsonMiddleware.js +4 -4
  26. package/middleware/SendStringMiddleware.js +3 -3
  27. package/package.json +20 -3
  28. package/templates/starter.js +2 -2
  29. package/tsconfig.json +18 -1
  30. package/utils/headers.js +1 -1
  31. package/errata/index.js +0 -1
  32. package/index.js +0 -4
  33. package/lib/index.js +0 -3
  34. package/middleware/ContentReaderMiddleware.js +0 -249
  35. package/middleware/ContentWriterMiddleware.js +0 -161
  36. package/middleware/SendHeadersMiddleware.js +0 -47
  37. package/middleware/index.js +0 -11
@@ -1,161 +0,0 @@
1
- import { Transform } from 'node:stream';
2
-
3
- /** @typedef {import('../types').IMiddleware} IMiddleware */
4
- /** @typedef {import('../types').MiddlewareFunction} MiddlewareFunction */
5
- /** @typedef {import('../types').MiddlewareFunctionParams} MiddlewareFunctionParams */
6
- /** @typedef {import('../types').MiddlewareFunctionResult} MiddlewareFunctionResult */
7
-
8
- /**
9
- * @typedef {Object} ContentWriterMiddlewareOptions
10
- * @prop {string} [defaultCharset='utf-8']
11
- * @prop {boolean} [setCharset=false]
12
- * Automatically applies charset in `Content-Type`
13
- * @prop {boolean} [setJSON=false]
14
- * Automatically applies `application/json` mediatype in `Content-Type`
15
- * @prop {boolean|string} [cache=false]
16
- * Caches content in res.local.content or res.local[cacheName]
17
- */
18
-
19
- /** @implements {IMiddleware} */
20
- export default class ContentWriterMiddleware {
21
- /** @param {ContentWriterMiddlewareOptions} [options] */
22
- constructor(options = {}) {
23
- this.defaultCharset = options.defaultCharset || 'utf-8';
24
- this.setCharset = options.setCharset === true;
25
- this.setJSON = options.setJSON === true;
26
- this.cache = options.cache;
27
- }
28
-
29
- /**
30
- * @param {string} charset
31
- * @return {BufferEncoding}
32
- */
33
- static charsetAsBufferEncoding(charset) {
34
- switch (charset) {
35
- case 'iso-8859-1':
36
- case 'ascii':
37
- case 'binary':
38
- case 'latin1':
39
- return 'latin1';
40
- case 'utf-16le':
41
- case 'ucs-2':
42
- case 'ucs2':
43
- case 'utf16le':
44
- return 'utf16le';
45
- case 'base64':
46
- case 'hex':
47
- return /** @type {BufferEncoding} */ (charset);
48
- case 'utf-8':
49
- case 'utf8':
50
- default:
51
- return 'utf-8';
52
- }
53
- }
54
-
55
- /**
56
- * @param {MiddlewareFunctionParams} params
57
- * @return {MiddlewareFunctionResult}
58
- */
59
- execute({ req, res }) {
60
- if (req.method === 'HEAD') {
61
- return 'continue';
62
- }
63
-
64
- /** @type {string} */
65
- let charset = null;
66
- /** @type {BufferEncoding} */
67
- let encoding = null;
68
- let hasSetJSON = false;
69
-
70
- /** @return {string} */
71
- const parseCharset = () => {
72
- if (charset) return charset;
73
- /** @type {string} */
74
- const contentType = (res.headers['content-type']);
75
- if (contentType) {
76
- contentType.split(';').some((directive) => {
77
- const parameters = directive.split('=');
78
- if (parameters[0].trim().toLowerCase() !== 'charset') {
79
- return false;
80
- }
81
- charset = parameters[1]?.trim().toLowerCase();
82
- const firstQuote = charset.indexOf('"');
83
- const lastQuote = charset.lastIndexOf('"');
84
- if (firstQuote !== -1 && lastQuote !== -1) {
85
- charset = charset.substring(firstQuote + 1, lastQuote);
86
- }
87
- return true;
88
- });
89
- }
90
- if (!charset) {
91
- charset = this.defaultCharset || 'utf-8';
92
- if (this.setCharset && !res.headersSent) {
93
- res.headers['content-type'] = `${contentType || ''};charset=${charset}`;
94
- }
95
- }
96
- return charset;
97
- };
98
-
99
- /** @return {void} */
100
- const setJSONMediaType = () => {
101
- if (hasSetJSON) return;
102
- /** @type {string} */
103
- const contentType = (res.headers['content-type']);
104
- res.headers['content-type'] = (contentType || '')
105
- .split(';')
106
- .map((directive) => {
107
- const isKeyPair = directive.includes('=');
108
- if (isKeyPair) return directive;
109
- return 'application/json';
110
- })
111
- .join(';');
112
-
113
- hasSetJSON = true;
114
- };
115
-
116
- const newWritable = new Transform({
117
- writableObjectMode: true,
118
- transform: (chunk, e, callback) => {
119
- if (Buffer.isBuffer(chunk)) {
120
- callback(null, chunk);
121
- return;
122
- }
123
- const cacheName = this.cache && (this.cache === true ? 'content' : this.cache);
124
- if (typeof chunk === 'string') {
125
- if (!encoding) {
126
- encoding = ContentWriterMiddleware.charsetAsBufferEncoding(parseCharset());
127
- }
128
- if (cacheName) {
129
- if (typeof res.locals[cacheName] === 'string') {
130
- res.locals[cacheName] += chunk;
131
- } else {
132
- res.locals[cacheName] = chunk;
133
- }
134
- }
135
- const callbackData = Buffer.from(chunk, encoding);
136
- callback(null, callbackData);
137
- return;
138
- }
139
- if (cacheName) {
140
- res.locals[cacheName] = chunk;
141
- }
142
- if (typeof chunk === 'object') {
143
- if (!encoding) {
144
- encoding = ContentWriterMiddleware.charsetAsBufferEncoding(parseCharset());
145
- }
146
- if (this.setJSON && !hasSetJSON && !res.headersSent) {
147
- setJSONMediaType();
148
- }
149
- callback(null, Buffer.from(JSON.stringify(chunk), encoding));
150
- return;
151
- }
152
-
153
- callback(null, chunk);
154
- },
155
- });
156
- const destination = res.replaceStream(newWritable);
157
- newWritable.pipe(destination);
158
-
159
- return 'continue';
160
- }
161
- }
@@ -1,47 +0,0 @@
1
- import { PassThrough } from 'stream';
2
-
3
- /** @typedef {import('../types').IMiddleware} IMiddleware */
4
- /** @typedef {import('../types').MiddlewareFunction} MiddlewareFunction */
5
- /** @typedef {import('../types').MiddlewareFunctionParams} MiddlewareFunctionParams */
6
- /** @typedef {import('../types').MiddlewareFunctionResult} MiddlewareFunctionResult */
7
-
8
- /**
9
- * @typedef {Object} SendHeadersMiddlewareOptions
10
- * @prop {boolean} [setStatus=false]
11
- * Automatically set `200` or `204` status if not set
12
- */
13
-
14
- /** @implements {IMiddleware} */
15
- export default class SendHeadersMiddleware {
16
- /** @param {SendHeadersMiddlewareOptions} options */
17
- constructor(options = {}) {
18
- this.setStatus = options.setStatus === true;
19
- }
20
-
21
- /**
22
- * @param {MiddlewareFunctionParams} params
23
- * @return {MiddlewareFunctionResult}
24
- */
25
- execute({ res }) {
26
- const newWritable = new PassThrough();
27
- const destination = res.replaceStream(newWritable);
28
- newWritable.once('data', () => {
29
- if (!res.headersSent) {
30
- if (this.setStatus && res.status == null) {
31
- res.status = 200;
32
- }
33
- res.sendHeaders(false);
34
- }
35
- });
36
- newWritable.on('end', () => {
37
- if (!res.headersSent) {
38
- if (this.setStatus && res.status == null) {
39
- res.status = 204;
40
- }
41
- res.sendHeaders(false);
42
- }
43
- });
44
- newWritable.pipe(destination);
45
- return 'continue';
46
- }
47
- }
@@ -1,11 +0,0 @@
1
- export { default as CaseInsensitiveHeadersMiddleware } from './CaseInsensitiveHeadersMiddleware.js';
2
- export { default as ContentDecoderMiddleware } from './ContentDecoderMiddleware.js';
3
- export { default as ContentEncoderMiddleware } from './ContentEncoderMiddleware.js';
4
- export { default as ContentLengthMiddleware } from './ContentLengthMiddleware.js';
5
- export { default as ContentReaderMiddleware } from './ContentReaderMiddleware.js';
6
- export { default as ContentWriterMiddleware } from './ContentWriterMiddleware.js';
7
- export { default as CorsMiddleware } from './CORSMiddleware.js';
8
- export { default as HashMiddleware } from './HashMiddleware.js';
9
- export { default as MethodMiddleware } from './MethodMiddleware.js';
10
- export { default as PathMiddleware } from './PathMiddleware.js';
11
- export { default as SendHeadersMiddleware } from './SendHeadersMiddleware.js';