@momsfriendlydevco/cowboy 1.0.2 → 1.0.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.
package/README.md CHANGED
@@ -296,10 +296,10 @@ cors
296
296
  Inject simple CORS headers to allow websites to use the endpoint from the browser frontend.
297
297
 
298
298
 
299
- validate
300
- --------
301
- Validate the incoming `req` object using [Joyful](https://github.com/MomsFriendlyDevCo/Joyful).
302
- The only argument is the Joyful validator which is run against `req`.
299
+ validate(key, validator)
300
+ ------------------------
301
+ Validate the incoming `req.$KEY` object using [Joyful](https://github.com/MomsFriendlyDevCo/Joyful).
302
+ This function takes two arguments - the `req` subkey to examine and the validation function / object.
303
303
 
304
304
  ```javascript
305
305
  import cowboy from '@momsfriendlydevco/cowboy';
@@ -307,18 +307,16 @@ import cowboy from '@momsfriendlydevco/cowboy';
307
307
  // Shorthand with defaults - just specify the name
308
308
  cowboy()
309
309
  .get('/path',
310
- ['validate', joi => {
311
- body: {
312
- widget: joi.string().required().valid('froody', 'doodad'),
313
- size: joi.number().optional(),
314
- },
310
+ ['validate', 'body', joi => {
311
+ widget: joi.string().required().valid('froody', 'doodad'),
312
+ size: joi.number().optional(),
315
313
  })],
316
314
  (req, res) => /* ... */
317
315
  )
318
316
  ```
319
317
 
320
- validateBody
321
- ------------
318
+ validateBody(validator)
319
+ -----------------------
322
320
  Shorthand validator which runs validation on the `req.body` parameter only.
323
321
 
324
322
 
@@ -328,7 +326,7 @@ import cowboy from '@momsfriendlydevco/cowboy';
328
326
  // Shorthand with defaults - just specify the name
329
327
  cowboy()
330
328
  .get('/path',
331
- ['validateBody', joi => {
329
+ ['validateBody', joi => ({
332
330
  widget: joi.string().required().valid('froody', 'doodad'),
333
331
  size: joi.number().optional(),
334
332
  })],
@@ -337,8 +335,8 @@ cowboy()
337
335
  ```
338
336
 
339
337
 
340
- validateParams
341
- --------------
338
+ validateParams(validator)
339
+ -------------------------
342
340
  Shorthand validator which runs validation on the `req.params` parameter only.
343
341
 
344
342
 
@@ -356,8 +354,8 @@ cowboy()
356
354
  ```
357
355
 
358
356
 
359
- validateQuery
360
- -------------
357
+ validateQuery(validator)
358
+ ------------------------
361
359
  Shorthand validator which runs validation on the `req.query` parameter only.
362
360
 
363
361
 
package/lib/cowboy.js CHANGED
@@ -28,7 +28,7 @@ export class Cowboy {
28
28
  */
29
29
  settings = {
30
30
  pathTidy(path) {
31
- return path.replace(/^\/api\/\w+\//, '/');
31
+ return path.replace(/^\/api\/\w+/, '/');
32
32
  },
33
33
  };
34
34
 
@@ -114,6 +114,7 @@ export class Cowboy {
114
114
  let res = new CowboyResponse();
115
115
 
116
116
  // Exec all earlyMiddleware - every time
117
+ debug('Run middleware');
117
118
  await this.execMiddleware({req, res, middleware: this.earlyMiddleware});
118
119
 
119
120
  // Find matching route
@@ -147,7 +148,7 @@ export class Cowboy {
147
148
  let mFunc =
148
149
  typeof m == 'function' ? m // Already a function
149
150
  : typeof m == 'string' ? CowboyMiddleware[m]() // Lookup from middleware with defaults
150
- : Array.isArray(m) ? CowboyMiddleware[m[0]](m[1]) // Lookup from middleware with options
151
+ : Array.isArray(m) ? CowboyMiddleware[m[0]](...m.slice(1)) // Lookup from middleware with options
151
152
  : (()=> { throw new Error(`Unknown middleware type "${typeof m}"`) })()
152
153
 
153
154
  if (!mFunc) throw new Error('Cowboy Middleware must be a function, string or Record(name, options)');
@@ -155,14 +156,22 @@ export class Cowboy {
155
156
  });
156
157
 
157
158
  let response; // Response to eventually send
159
+ debug('Run middleware stack', middlewareStack);
158
160
  while (middlewareStack.length > 0) {
159
161
  let middleware = middlewareStack.shift();
160
- response = await middleware(req, res);
161
- if (response?.hasSent) { // Stop middleware chain as some intermediate has signalled the chain should end
162
- response = res;
162
+ try {
163
+ response = await middleware(req, res);
164
+ if (response?.hasSent) { // Stop middleware chain as some intermediate has signalled the chain should end
165
+ response = res;
166
+ break;
167
+ } else if (response && !(response instanceof CowboyResponse) && middlewareStack.length == 0) { // Last item in middleware chain returned something but it doesn't look like a regular response - wrap it
168
+ response = res.end(response);
169
+ }
170
+ } catch (e) {
171
+ debug('Error trace', e.trace);
172
+ res.status(500).send(e.toString());
173
+ response = null;
163
174
  break;
164
- } else if (response && !(response instanceof CowboyResponse) && middlewareStack.length == 0) { // Last item in middleware chain returned something but it doesn't look like a regular response - wrap it
165
- response = res.end(response);
166
175
  }
167
176
  }
168
177
  return response;
package/lib/response.js CHANGED
@@ -66,7 +66,11 @@ export default class CowboyResponse {
66
66
  */
67
67
  status(code) {
68
68
  this.code = code;
69
- if (!this.body) this.body = 'ok'; // Set body payload if we don't already have one
69
+ if (!this.body)
70
+ this.body = this.code >= 200 && this.code <= 299
71
+ ? 'ok' // Set body payload if we don't already have one
72
+ : `${this.code}: Fail`
73
+
70
74
  return this;
71
75
  }
72
76
 
@@ -11,8 +11,11 @@ export default function CowboyMiddlewareCORS(headers) {
11
11
  res.set(injectHeaders);
12
12
 
13
13
  // Handle hits to OPTIONS '/' endpoint
14
- req.router.options('/', (req, res) => {
15
- return res.sendStatus(200);
16
- });
14
+ if (!req.router.loadedCors) {
15
+ req.router.options('/', (req, res) => {
16
+ return res.sendStatus(200);
17
+ });
18
+ req.router.loadedCors = true; // Mark we've already done this so we don't keep tweaking the router
19
+ }
17
20
  }
18
21
  }
@@ -1,8 +1,10 @@
1
1
  import joyful from '@momsfriendlydevco/joyful';
2
2
 
3
- export default function CowboyMiddlewareValidate(validator) {
3
+ export default function CowboyMiddlewareValidate(subkey, validator) {
4
4
  return (req, res) => {
5
- let joyfulResult = joyful(req, validator, {throw: false});
5
+ let joyfulResult = joyful({
6
+ [subkey]: validator,
7
+ });
6
8
 
7
9
  if (joyfulResult !== true) { // Failed body validation?
8
10
  return res
@@ -1,7 +1,7 @@
1
1
  import CowboyMiddlewareValidate from '#middleware/validate';
2
2
 
3
3
  export default function CowboyMiddlewareValidateBody(validator) {
4
- return CowboyMiddlewareValidate({
4
+ return CowboyMiddlewareValidate('body', {
5
5
  body: validator,
6
6
  })
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import CowboyMiddlewareValidate from '#middleware/validate';
2
2
 
3
3
  export default function CowboyMiddlewareValidateParams(validator) {
4
- return CowboyMiddlewareValidate({
4
+ return CowboyMiddlewareValidate('params', {
5
5
  params: validator,
6
6
  })
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import CowboyMiddlewareValidate from '#middleware/validate';
2
2
 
3
3
  export default function CowboyMiddlewareValidateQuery(validator) {
4
- return CowboyMiddlewareValidate({
4
+ return CowboyMiddlewareValidate('query', {
5
5
  query: validator,
6
6
  })
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momsfriendlydevco/cowboy",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Wrapper around Cloudflare Wrangler to provide a more Express-like experience",
5
5
  "scripts": {
6
6
  "lint": "eslint ."
@@ -35,12 +35,12 @@
35
35
  "node": ">=20.x"
36
36
  },
37
37
  "dependencies": {
38
- "@momsfriendlydevco/joyful": "^1.0.0",
38
+ "@momsfriendlydevco/joyful": "^1.0.1",
39
39
  "toml": "^3.0.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@momsfriendlydevco/eslint-config": "^1.0.7",
43
- "eslint": "^8.50.0"
43
+ "eslint": "^8.51.0"
44
44
  },
45
45
  "eslintConfig": {
46
46
  "extends": "@momsfriendlydevco",