@wooksjs/http-body 0.4.24 → 0.4.27

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
@@ -13,10 +13,10 @@ Wooks Body is composable body parser for [@wooksjs/event-http](https://github.co
13
13
 
14
14
  Supported content types:
15
15
 
16
- - ✅ application/json
17
- - ✅ text/\*
18
- - ✅ multipart/form-data
19
- - ✅ application/x-www-form-urlencoded
16
+ - ✅ application/json
17
+ - ✅ text/\*
18
+ - ✅ multipart/form-data
19
+ - ✅ application/x-www-form-urlencoded
20
20
 
21
21
  Body parser does not parse every request's body. The parsing happens only when you call `parseBody` function.
22
22
 
@@ -29,8 +29,8 @@ Body parser does not parse every request's body. The parsing happens only when y
29
29
  ```ts
30
30
  import { useBody } from '@wooksjs/http-body'
31
31
  app.post('test', async () => {
32
- const { parseBody } = useBody()
33
- const data = await parseBody()
32
+ const { parseBody } = useBody()
33
+ const data = await parseBody()
34
34
  })
35
35
  ```
36
36
 
@@ -39,27 +39,27 @@ app.post('test', async () => {
39
39
  ```ts
40
40
  import { useBody } from '@wooksjs/http-body'
41
41
  app.post('test', async () => {
42
- const {
43
- isJson, // checks if content-type is "application/json" : () => boolean;
44
- isHtml, // checks if content-type is "text/html" : () => boolean;
45
- isXml, // checks if content-type is "application/xml" : () => boolean;
46
- isText, // checks if content-type is "text/plain" : () => boolean;
47
- isBinary, // checks if content-type is binary : () => boolean;
48
- isFormData, // checks if content-type is "multipart/form-data" : () => boolean;
49
- isUrlencoded, // checks if content-type is "application/x-www-form-urlencoded" : () => boolean;
50
- isCompressed, // checks content-encoding : () => boolean | undefined;
51
- contentEncodings, // returns an array of encodings : () => string[];
52
- parseBody, // parses body according to content-type : <T = unknown>() => Promise<T>;
53
- rawBody, // returns raw body Buffer : () => Promise<Buffer>;
54
- } = useBody()
55
-
56
- // the handler got the control, but the body isn't loaded yet
57
- //...
58
-
59
- console.log(await parseBody())
60
-
61
- // after `await parseBody()` the body was loaded and parsed
62
- // ...
42
+ const {
43
+ isJson, // checks if content-type is "application/json" : () => boolean;
44
+ isHtml, // checks if content-type is "text/html" : () => boolean;
45
+ isXml, // checks if content-type is "application/xml" : () => boolean;
46
+ isText, // checks if content-type is "text/plain" : () => boolean;
47
+ isBinary, // checks if content-type is binary : () => boolean;
48
+ isFormData, // checks if content-type is "multipart/form-data" : () => boolean;
49
+ isUrlencoded, // checks if content-type is "application/x-www-form-urlencoded" : () => boolean;
50
+ isCompressed, // checks content-encoding : () => boolean | undefined;
51
+ contentEncodings, // returns an array of encodings : () => string[];
52
+ parseBody, // parses body according to content-type : <T = unknown>() => Promise<T>;
53
+ rawBody, // returns raw body Buffer : () => Promise<Buffer>;
54
+ } = useBody()
55
+
56
+ // the handler got the control, but the body isn't loaded yet
57
+ //...
58
+
59
+ console.log(await parseBody())
60
+
61
+ // after `await parseBody()` the body was loaded and parsed
62
+ // ...
63
63
  })
64
64
  ```
65
65
 
package/dist/index.cjs CHANGED
@@ -4,17 +4,18 @@ var eventHttp = require('@wooksjs/event-http');
4
4
 
5
5
  const compressors = {
6
6
  identity: {
7
- compress: (v) => v,
8
- uncompress: (v) => v,
7
+ compress: v => v,
8
+ uncompress: v => v,
9
9
  },
10
10
  };
11
11
  async function uncompressBody(encodings, body) {
12
12
  let newBody = body;
13
13
  for (const e of encodings.reverse()) {
14
- if (!compressors[e]) {
14
+ const cmp = compressors[e];
15
+ if (!cmp) {
15
16
  throw new Error(`Usupported compression type "${e}".`);
16
17
  }
17
- newBody = await compressors[e].uncompress(body);
18
+ newBody = await cmp.uncompress(body);
18
19
  }
19
20
  return newBody;
20
21
  }
@@ -25,7 +26,7 @@ function useBody() {
25
26
  const { rawBody } = eventHttp.useRequest();
26
27
  const { 'content-type': contentType, 'content-encoding': contentEncoding } = eventHttp.useHeaders();
27
28
  function contentIs(type) {
28
- return (contentType || '').indexOf(type) >= 0;
29
+ return (contentType || '').includes(type);
29
30
  }
30
31
  const isJson = () => init('isJson', () => contentIs('application/json'));
31
32
  const isHtml = () => init('isHtml', () => contentIs('text/html'));
@@ -37,44 +38,50 @@ function useBody() {
37
38
  const isCompressed = () => init('isCompressed', () => {
38
39
  const parts = contentEncodings();
39
40
  for (const p of parts) {
40
- if (['deflate', 'gzip', 'br'].includes(p))
41
+ if (['deflate', 'gzip', 'br'].includes(p)) {
41
42
  return true;
43
+ }
42
44
  }
43
45
  return false;
44
46
  });
45
47
  const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
46
48
  .split(',')
47
- .map((p) => p.trim())
48
- .filter((p) => !!p));
49
- const parseBody = () => init('parsed', async () => {
49
+ .map(p => p.trim())
50
+ .filter(Boolean));
51
+ const parseBody = async () => init('parsed', async () => {
50
52
  const body = await uncompressBody(contentEncodings(), (await rawBody()).toString());
51
- if (isJson())
53
+ if (isJson()) {
52
54
  return jsonParser(body);
53
- else if (isFormData())
55
+ }
56
+ else if (isFormData()) {
54
57
  return formDataParser(body);
55
- else if (isUrlencoded())
58
+ }
59
+ else if (isUrlencoded()) {
56
60
  return urlEncodedParser(body);
57
- else if (isBinary())
61
+ }
62
+ else if (isBinary()) {
58
63
  return textParser(body);
59
- else
64
+ }
65
+ else {
60
66
  return textParser(body);
67
+ }
61
68
  });
62
69
  function jsonParser(v) {
63
70
  try {
64
71
  return JSON.parse(v);
65
72
  }
66
- catch (e) {
67
- throw new eventHttp.HttpError(400, e.message);
73
+ catch (error) {
74
+ throw new eventHttp.HttpError(400, error.message);
68
75
  }
69
76
  }
70
77
  function textParser(v) {
71
78
  return v;
72
79
  }
73
80
  function formDataParser(v) {
74
- const boundary = '--' +
75
- (/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1];
76
- if (!boundary)
81
+ const boundary = `--${(/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1]}`;
82
+ if (!boundary) {
77
83
  throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'form-data boundary not recognized');
84
+ }
78
85
  const parts = v.trim().split(boundary);
79
86
  const result = {};
80
87
  let key = '';
@@ -87,36 +94,36 @@ function useBody() {
87
94
  const lines = part
88
95
  .trim()
89
96
  .split(/\n/g)
90
- .map((s) => s.trim());
97
+ .map(s => s.trim());
91
98
  for (const line of lines) {
92
99
  if (valueMode) {
93
- if (!result[key]) {
94
- result[key] = line;
100
+ if (result[key]) {
101
+ result[key] += `\n${line}`;
95
102
  }
96
103
  else {
97
- result[key] += '\n' + line;
104
+ result[key] = line;
98
105
  }
99
106
  }
100
107
  else {
101
108
  if (!line || line === '--') {
102
- valueMode = !!key;
109
+ valueMode = Boolean(key);
103
110
  if (valueMode) {
104
111
  key = key.replace(/^["']/, '').replace(/["']$/, '');
105
112
  }
106
113
  continue;
107
114
  }
108
- if (line
109
- .toLowerCase()
110
- .startsWith('content-disposition: form-data;')) {
115
+ if (line.toLowerCase().startsWith('content-disposition: form-data;')) {
111
116
  key = (/name=([^;]+)/.exec(line) || [])[1];
112
- if (!key)
113
- throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'Could not read multipart name: ' + line);
117
+ if (!key) {
118
+ throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, `Could not read multipart name: ${line}`);
119
+ }
114
120
  continue;
115
121
  }
116
122
  if (line.toLowerCase().startsWith('content-type:')) {
117
123
  partContentType = (/content-type:\s?([^;]+)/i.exec(line) || [])[1];
118
- if (!partContentType)
119
- throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'Could not read content-type: ' + line);
124
+ if (!partContentType) {
125
+ throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, `Could not read content-type: ${line}`);
126
+ }
120
127
  continue;
121
128
  }
122
129
  }
@@ -124,10 +131,8 @@ function useBody() {
124
131
  }
125
132
  parsePart();
126
133
  function parsePart() {
127
- if (key) {
128
- if (partContentType.indexOf('application/json') >= 0) {
129
- result[key] = JSON.parse(result[key]);
130
- }
134
+ if (key && partContentType.includes('application/json')) {
135
+ result[key] = JSON.parse(result[key]);
131
136
  }
132
137
  }
133
138
  return result;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- type TBodyCompressor = {
1
+ interface TBodyCompressor {
2
2
  compress: (data: string) => string | Promise<string>;
3
3
  uncompress: (data: string) => string | Promise<string>;
4
- };
4
+ }
5
5
 
6
6
  declare function useBody(): {
7
7
  isJson: () => boolean;
package/dist/index.mjs CHANGED
@@ -2,17 +2,18 @@ import { useHttpContext, useRequest, useHeaders, HttpError, EHttpStatusCode, Woo
2
2
 
3
3
  const compressors = {
4
4
  identity: {
5
- compress: (v) => v,
6
- uncompress: (v) => v,
5
+ compress: v => v,
6
+ uncompress: v => v,
7
7
  },
8
8
  };
9
9
  async function uncompressBody(encodings, body) {
10
10
  let newBody = body;
11
11
  for (const e of encodings.reverse()) {
12
- if (!compressors[e]) {
12
+ const cmp = compressors[e];
13
+ if (!cmp) {
13
14
  throw new Error(`Usupported compression type "${e}".`);
14
15
  }
15
- newBody = await compressors[e].uncompress(body);
16
+ newBody = await cmp.uncompress(body);
16
17
  }
17
18
  return newBody;
18
19
  }
@@ -23,7 +24,7 @@ function useBody() {
23
24
  const { rawBody } = useRequest();
24
25
  const { 'content-type': contentType, 'content-encoding': contentEncoding } = useHeaders();
25
26
  function contentIs(type) {
26
- return (contentType || '').indexOf(type) >= 0;
27
+ return (contentType || '').includes(type);
27
28
  }
28
29
  const isJson = () => init('isJson', () => contentIs('application/json'));
29
30
  const isHtml = () => init('isHtml', () => contentIs('text/html'));
@@ -35,44 +36,50 @@ function useBody() {
35
36
  const isCompressed = () => init('isCompressed', () => {
36
37
  const parts = contentEncodings();
37
38
  for (const p of parts) {
38
- if (['deflate', 'gzip', 'br'].includes(p))
39
+ if (['deflate', 'gzip', 'br'].includes(p)) {
39
40
  return true;
41
+ }
40
42
  }
41
43
  return false;
42
44
  });
43
45
  const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
44
46
  .split(',')
45
- .map((p) => p.trim())
46
- .filter((p) => !!p));
47
- const parseBody = () => init('parsed', async () => {
47
+ .map(p => p.trim())
48
+ .filter(Boolean));
49
+ const parseBody = async () => init('parsed', async () => {
48
50
  const body = await uncompressBody(contentEncodings(), (await rawBody()).toString());
49
- if (isJson())
51
+ if (isJson()) {
50
52
  return jsonParser(body);
51
- else if (isFormData())
53
+ }
54
+ else if (isFormData()) {
52
55
  return formDataParser(body);
53
- else if (isUrlencoded())
56
+ }
57
+ else if (isUrlencoded()) {
54
58
  return urlEncodedParser(body);
55
- else if (isBinary())
59
+ }
60
+ else if (isBinary()) {
56
61
  return textParser(body);
57
- else
62
+ }
63
+ else {
58
64
  return textParser(body);
65
+ }
59
66
  });
60
67
  function jsonParser(v) {
61
68
  try {
62
69
  return JSON.parse(v);
63
70
  }
64
- catch (e) {
65
- throw new HttpError(400, e.message);
71
+ catch (error) {
72
+ throw new HttpError(400, error.message);
66
73
  }
67
74
  }
68
75
  function textParser(v) {
69
76
  return v;
70
77
  }
71
78
  function formDataParser(v) {
72
- const boundary = '--' +
73
- (/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1];
74
- if (!boundary)
79
+ const boundary = `--${(/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1]}`;
80
+ if (!boundary) {
75
81
  throw new HttpError(EHttpStatusCode.BadRequest, 'form-data boundary not recognized');
82
+ }
76
83
  const parts = v.trim().split(boundary);
77
84
  const result = {};
78
85
  let key = '';
@@ -85,36 +92,36 @@ function useBody() {
85
92
  const lines = part
86
93
  .trim()
87
94
  .split(/\n/g)
88
- .map((s) => s.trim());
95
+ .map(s => s.trim());
89
96
  for (const line of lines) {
90
97
  if (valueMode) {
91
- if (!result[key]) {
92
- result[key] = line;
98
+ if (result[key]) {
99
+ result[key] += `\n${line}`;
93
100
  }
94
101
  else {
95
- result[key] += '\n' + line;
102
+ result[key] = line;
96
103
  }
97
104
  }
98
105
  else {
99
106
  if (!line || line === '--') {
100
- valueMode = !!key;
107
+ valueMode = Boolean(key);
101
108
  if (valueMode) {
102
109
  key = key.replace(/^["']/, '').replace(/["']$/, '');
103
110
  }
104
111
  continue;
105
112
  }
106
- if (line
107
- .toLowerCase()
108
- .startsWith('content-disposition: form-data;')) {
113
+ if (line.toLowerCase().startsWith('content-disposition: form-data;')) {
109
114
  key = (/name=([^;]+)/.exec(line) || [])[1];
110
- if (!key)
111
- throw new HttpError(EHttpStatusCode.BadRequest, 'Could not read multipart name: ' + line);
115
+ if (!key) {
116
+ throw new HttpError(EHttpStatusCode.BadRequest, `Could not read multipart name: ${line}`);
117
+ }
112
118
  continue;
113
119
  }
114
120
  if (line.toLowerCase().startsWith('content-type:')) {
115
121
  partContentType = (/content-type:\s?([^;]+)/i.exec(line) || [])[1];
116
- if (!partContentType)
117
- throw new HttpError(EHttpStatusCode.BadRequest, 'Could not read content-type: ' + line);
122
+ if (!partContentType) {
123
+ throw new HttpError(EHttpStatusCode.BadRequest, `Could not read content-type: ${line}`);
124
+ }
118
125
  continue;
119
126
  }
120
127
  }
@@ -122,10 +129,8 @@ function useBody() {
122
129
  }
123
130
  parsePart();
124
131
  function parsePart() {
125
- if (key) {
126
- if (partContentType.indexOf('application/json') >= 0) {
127
- result[key] = JSON.parse(result[key]);
128
- }
132
+ if (key && partContentType.includes('application/json')) {
133
+ result[key] = JSON.parse(result[key]);
129
134
  }
130
135
  }
131
136
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wooksjs/http-body",
3
- "version": "0.4.24",
3
+ "version": "0.4.27",
4
4
  "description": "@wooksjs/http-body",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -39,7 +39,7 @@
39
39
  "url": "https://github.com/wooksjs/wooksjs/issues"
40
40
  },
41
41
  "peerDependencies": {
42
- "@wooksjs/event-http": "0.4.24"
42
+ "@wooksjs/event-http": "0.4.27"
43
43
  },
44
44
  "homepage": "https://github.com/wooksjs/wooksjs/tree/main/packages/http-body#readme"
45
45
  }