@momsfriendlydevco/cowboy 1.0.9 → 1.0.11

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
@@ -9,6 +9,7 @@ Features:
9
9
  * Express-like `req` + `res` object for routes
10
10
  * Built in middleware + request validation via [Joi](https://joi.dev)
11
11
  * Built-in debug support for testkits + Wrangler
12
+ * Built-in JSON / Multipart (or FormData) / Plain text decoding and population of `req.body`
12
13
 
13
14
 
14
15
  Examples
package/lib/cowboy.js CHANGED
@@ -123,17 +123,7 @@ export class Cowboy {
123
123
  pathTidy: this.settings.pathTidy,
124
124
  });
125
125
 
126
- // Decode input if we're expecting JSON
127
- if (cfReq.body) {
128
- try {
129
- req.body = await cfReq.json();
130
- } catch (e) {
131
- if (debug.enabled) {
132
- debug('Failed to decode request body as JSON: [[[' + cfReq.body.toString() + ']]]');
133
- }
134
- throw new Error('Invalid JSON body');
135
- }
136
- }
126
+ await req.parseBody();
137
127
 
138
128
  let res = new CowboyResponse();
139
129
  debug('Incoming request:', req.toString());
package/lib/request.js CHANGED
@@ -1,3 +1,5 @@
1
+ import debug from '#lib/debug';
2
+
1
3
  /**
2
4
  * Tiny wrapper around Wrangler to wrap its default Request object in an Express-like structure
3
5
  * @extends CloudflareRequest
@@ -16,6 +18,21 @@ export default class CowboyRequest {
16
18
  hostname;
17
19
 
18
20
 
21
+ /**
22
+ * Extracted URL query parameters
23
+ * @type {Object}
24
+ */
25
+ query = {};
26
+
27
+
28
+ /**
29
+ * Raw body payload provided by cfReq
30
+ * This gets translated into a usable object after a call to `parseBody()`
31
+ * @type {*}
32
+ */
33
+ body = null;
34
+
35
+
19
36
  constructor(cfReq, props) {
20
37
  // Copy all cfReq keys locally as a shallow copy
21
38
  Object.assign(
@@ -35,6 +52,64 @@ export default class CowboyRequest {
35
52
  let url = new URL(cfReq.url);
36
53
  this.path = this.pathTidy(url.pathname);
37
54
  this.hostname = url.hostname;
55
+ this.query = Object.fromEntries(url.searchParams);
56
+
57
+ // Slurp the headers
58
+ this.headers = Object.fromEntries(cfReq.headers.entries());
59
+
60
+ // Hold the body element - this wont be decoded until parseBody() is called
61
+ this.body = {
62
+ json: cfReq.json.bind(cfReq),
63
+ formData: cfReq.formData.bind(cfReq),
64
+ text: cfReq.text.bind(cfReq),
65
+ };
66
+ }
67
+
68
+
69
+ /**
70
+ * Parse the body of an incoming request
71
+ *
72
+ * @param {String} [forceType] Whether to force a specific mime-type instead of using the header supplied format
73
+ * @returns {Promise} A promise which will resolve when the body has been parsed
74
+ */
75
+ async parseBody(forceType) {
76
+ let type = (forceType || this.headers['content-type'])
77
+ .replace(/^([a-z\-\/]+).*$/, '$1'); // Scrap everything after the mime
78
+
79
+ switch (type) {
80
+ case 'json':
81
+ case 'application/json':
82
+ try {
83
+ this.body = await this.body.json();
84
+ break;
85
+ } catch (e) {
86
+ if (debug.enabled) debug('Failed to decode request body as JSON:', e.toString());
87
+ throw new Error('Invalid JSON body');
88
+ }
89
+ case 'formData':
90
+ case 'multipart/form-data': // Decode as multi-part
91
+ case 'application/x-www-form-urlencoded': // Decode as multi-part
92
+ try {
93
+ let formData = await this.body.formData();
94
+ this.body = Object.fromEntries(formData.entries());
95
+ break;
96
+ } catch (e) {
97
+ if (debug.enabled) debug('Failed to decode multi-part body:', e.toString());
98
+ throw new Error('Invalid multi-part encoded body');
99
+ }
100
+ case 'text':
101
+ case 'text/plain': // Decode as plain text
102
+ try {
103
+ this.body = await this.body.text();
104
+ break;
105
+ } catch (e) {
106
+ if (debug.enabled) debug('Failed to decode plain-text body:', e.toString());
107
+ throw new Error('Invalid text body');
108
+ }
109
+ default:
110
+ debug('EMPTY BODY PAYLOAD');
111
+ this.body = {};
112
+ }
38
113
  }
39
114
 
40
115
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momsfriendlydevco/cowboy",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Wrapper around Cloudflare Wrangler to provide a more Express-like experience",
5
5
  "scripts": {
6
6
  "lint": "eslint ."