New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

lambda-api

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lambda-api - npm Package Compare versions

Comparing version 0.6.0 to 0.7.0

55

index.js

@@ -1,2 +0,2 @@

'use strict';
'use strict'

@@ -6,3 +6,3 @@ /**

* @author Jeremy Daly <jeremy@jeremydaly.com>
* @version 0.6.0
* @version 0.7.0
* @license MIT

@@ -35,3 +35,5 @@ */

// Default callback
this._cb = function(err,res) { console.log('No callback specified') }
this._cb = function() {
console.log('No callback specified') // eslint-disable-line no-console
}

@@ -111,3 +113,3 @@ // Middleware stack

path: '/'+this._prefix.concat(parsedPath).join('/') }
} : {}),
} : {}),
route.slice(0,i+1)

@@ -130,3 +132,3 @@ )

this._event = event
this._context = context
this._context = this.context = context
this._cb = cb

@@ -147,5 +149,24 @@

if (response._state !== 'processing') break
// Init for matching routes
let matched = false
// Test paths if they are supplied
for (const path of mw[0]) {
if (
path === request.path || // If exact path match
path === request.route || // If exact route match
// If a wildcard match
(path.substr(-1) === '*' && new RegExp('^' + path.slice(0, -1) + '.*$').test(request.route))
) {
matched = true
break
}
}
if (mw[0].length > 0 && !matched) continue
// Promisify middleware
await new Promise(r => {
let rtn = mw(request,response,() => { r() })
let rtn = mw[1](request,response,() => { r() })
if (rtn) response.send(rtn)

@@ -178,3 +199,3 @@ })

let message;
let message

@@ -184,6 +205,6 @@ if (e instanceof Error) {

message = e.message
!this._test && console.log(e)
!this._test && console.log(e) // eslint-disable-line no-console
} else {
message = e
!this._test && console.log('API Error:',e)
!this._test && console.log('API Error:',e) // eslint-disable-line no-console
}

@@ -232,5 +253,9 @@

// Middleware handler
use(fn) {
use(path,handler) {
let fn = typeof path === 'function' ? path : handler
let routes = typeof path === 'string' ? Array.of(path) : (Array.isArray(path) ? path : [])
if (fn.length === 3) {
this._middleware.push(fn)
this._middleware.push([routes,fn])
} else if (fn.length === 4) {

@@ -261,4 +286,4 @@ this._errors.push(fn)

setRoute(obj, value, path) {
if (typeof path === "string") {
let path = path.split('.')
if (typeof path === 'string') {
let path = path.split('.')
}

@@ -292,3 +317,3 @@

} catch(e) {
console.error(e.message)
console.error(e.message) // eslint-disable-line no-console
}

@@ -330,3 +355,3 @@ }

if (format) {
prettyPrint(routes)
console.log(prettyPrint(routes)) // eslint-disable-line no-console
} else {

@@ -333,0 +358,0 @@ return routes

@@ -35,3 +35,2 @@ 'use strict'

xml: 'application/xml',
xls: 'application/xml',

@@ -38,0 +37,0 @@ // other binary

@@ -10,15 +10,25 @@ 'use strict'

module.exports = routes => {
let out = ''
// Calculate column widths
let widths = routes.reduce((acc,row) => {
return [Math.max(acc[0],row[0].length),Math.max(acc[1],row[1].length)]
return [
Math.max(acc[0],Math.max(6,row[0].length)),
Math.max(acc[1],Math.max(5,row[1].length))
]
},[0,0])
console.log('╔══' + ''.padEnd(widths[0],'═') + '══╤══' + ''.padEnd(widths[1],'═') + '══╗')
console.log('║ ' + "\u001b[1m" + 'METHOD'.padEnd(widths[0]) + "\u001b[0m" + ' │ ' + "\u001b[1m" + 'ROUTE'.padEnd(widths[1]) + "\u001b[0m" + ' ║')
console.log('╟──' + ''.padEnd(widths[0],'─') + '──┼──' + ''.padEnd(widths[1],'─') + '──╢')
out += '╔══' + ''.padEnd(widths[0],'═') + '══╤══' + ''.padEnd(widths[1],'═') + '══╗\n'
out += '║ ' + '\u001b[1m' + 'METHOD'.padEnd(widths[0]) + '\u001b[0m' + ' │ ' + '\u001b[1m' + 'ROUTE'.padEnd(widths[1]) + '\u001b[0m' + ' ║\n'
out += '╟──' + ''.padEnd(widths[0],'─') + '──┼──' + ''.padEnd(widths[1],'─') + '──╢\n'
routes.forEach((route,i) => {
console.log('║ ' + route[0].padEnd(widths[0]) + ' │ ' + route[1].padEnd(widths[1]) + ' ║')
if (i < routes.length-1) { console.log('╟──' + ''.padEnd(widths[0],'─') + '──┼──' + ''.padEnd(widths[1],'─') + '──╢') }
out += '║ ' + route[0].padEnd(widths[0]) + ' │ ' + route[1].padEnd(widths[1]) + ' ║\n'
if (i < routes.length-1) {
out += '╟──' + ''.padEnd(widths[0],'─') + '──┼──' + ''.padEnd(widths[1],'─') + '──╢\n'
} // end if
})
console.log('╚══' + ''.padEnd(widths[0],'═') + '══╧══' + ''.padEnd(widths[1],'═') + '══╝')
out += '╚══' + ''.padEnd(widths[0],'═') + '══╧══' + ''.padEnd(widths[1],'═') + '══╝'
return out
}

@@ -21,3 +21,5 @@ 'use strict'

// Init and default the handler
this._handler = function() { console.log('No handler specified') }
this._handler = function() {
console.log('No handler specified') // eslint-disable-line no-console
}

@@ -72,2 +74,8 @@ // Expose Namespaces

// Parse id from context
this.id = this.app.context.awsRequestId ? this.app.context.awsRequestId : null
// Add context
this.context = typeof this.app.context === 'object' ? this.app.context : {}
// Capture the raw body

@@ -80,3 +88,3 @@ this.rawBody = this.app._event.body

// Set the body
if (this.headers['content-type'] && this.headers['content-type'].includes("application/x-www-form-urlencoded")) {
if (this.headers['content-type'] && this.headers['content-type'].includes('application/x-www-form-urlencoded')) {
this.body = QS.parse(this.body)

@@ -119,7 +127,7 @@ } else if (typeof this.body === 'object') {

let route = routes['__'+this.method] ? routes['__'+this.method] :
(routes['__ANY'] ? routes['__ANY'] :
(wildcard && wildcard['__'+this.method] ? wildcard['__'+this.method] :
(wildcard && wildcard['__ANY'] ? wildcard['__ANY'] :
(this.method === 'HEAD' && routes['__GET'] ? routes['__GET'] :
undefined))))
(routes['__ANY'] ? routes['__ANY'] :
(wildcard && wildcard['__'+this.method] ? wildcard['__'+this.method] :
(wildcard && wildcard['__ANY'] ? wildcard['__ANY'] :
(this.method === 'HEAD' && routes['__GET'] ? routes['__GET'] :
undefined))))

@@ -126,0 +134,0 @@ // Check for the requested method

@@ -34,3 +34,3 @@ 'use strict'

// Set the Content-Type by default
"content-type": "application/json" //charset=UTF-8
'content-type': 'application/json' //charset=UTF-8
}

@@ -132,3 +132,3 @@

// Set the name and value of the cookie
let cookieString = (typeof name !== 'String' ? name.toString() : name)
let cookieString = (typeof name !== 'string' ? name.toString() : name)
+ '=' + encodeURIComponent(UTILS.encodeBody(value))

@@ -135,0 +135,0 @@

@@ -9,12 +9,12 @@ 'use strict'

const QS = require('querystring') // Require the querystring library
const crypto = require('crypto') // Require Node.js crypto library
const QS = require('querystring') // Require the querystring library
const crypto = require('crypto') // Require Node.js crypto library
const entityMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': '&quot;',
"'": '&#39;'
}
const entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;'
}

@@ -46,3 +46,3 @@ module.exports.escapeHtml = html => html.replace(/[&<>"']/g, s => entityMap[s])

} catch(e) {
return body;
return body
}

@@ -56,10 +56,13 @@ }

switch (type) {
case 'Basic':
case 'Basic': {
let creds = Buffer.from(value, 'base64').toString().split(':')
return { type, value, username: creds[0], password: creds[1] ? creds[1] : null }
case 'OAuth':
}
case 'OAuth': {
let params = QS.parse(value.replace(/",\s*/g,'&').replace(/"/g,'').trim())
return Object.assign({ type, value }, params)
default:
}
default: {
return { type, value }
}
}

@@ -111,2 +114,2 @@ }

module.exports.generateEtag = data =>
crypto.createHash('sha256').update(encodeBody(data)).digest("hex").substr(0,32)
crypto.createHash('sha256').update(encodeBody(data)).digest('hex').substr(0,32)
{
"name": "lambda-api",
"version": "0.6.0",
"version": "0.7.0",
"description": "Lightweight web framework for your serverless applications",
"main": "index.js",
"scripts": {
"test": "mocha"
"test": "mocha --check-leaks --recursive",
"test-cov": "nyc --reporter=lcov mocha --check-leaks --recursive",
"test-ci": "nyc npm test && nyc report --reporter=text-lcov | ./node_modules/coveralls/bin/coveralls.js",
"lint": "eslint ."
},

@@ -36,5 +39,18 @@ "repository": {

"chai": "^4.1.2",
"coveralls": "^3.0.1",
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.12.0",
"istanbul": "^0.4.5",
"mocha": "^4.0.1",
"mocha-lcov-reporter": "^1.3.0",
"nyc": "^11.8.0",
"sinon": "^4.5.0"
},
"files": [
"LICENSE",
"README.md",
"index.js",
"lib/"
],
"engines": {

@@ -41,0 +57,0 @@ "node": ">= 8.10.0"

@@ -6,2 +6,3 @@ [![Lambda API](https://www.jeremydaly.com/wp-content/uploads/2018/03/lambda-api-logo.svg)](https://serverless-api.com/)

[![npm](https://img.shields.io/npm/l/lambda-api.svg)](https://www.npmjs.com/package/lambda-api)
[![Coverage Status](https://coveralls.io/repos/github/jeremydaly/lambda-api/badge.svg?branch=master)](https://coveralls.io/github/jeremydaly/lambda-api?branch=master)

@@ -113,2 +114,5 @@ ### Lightweight web framework for your serverless applications

### v0.7: Restrict middleware execution to certain paths
Middleware now supports an optional path parameter that supports multiple paths, wildcards, and parameter matching to better control middleware execution. See [middleware](#middleware) for more information.
### v0.6: Support for both `callback-style` and `async-await`

@@ -325,2 +329,3 @@ In additional to `res.send()`, you can now simply `return` the body from your route and middleware functions. See [Returning Responses](#returning-responses) for more information.

- `version`: The version set at initialization
- `id`: The awsRequestId from the Lambda `context`
- `params`: Dynamic path parameters parsed from the path (see [path parameters](#path-parameters))

@@ -342,2 +347,3 @@ - `method`: The HTTP method of the request

- `cookies`: An object containing cookies sent from the browser (see the [cookie](#cookiename-value-options) `RESPONSE` method)
- `context`: Reference to the `context` passed into the Lambda handler function

@@ -649,3 +655,3 @@ The request object can be used to pass additional information through the processing chain. For example, if you are using a piece of authentication middleware, you can add additional keys to the `REQUEST` object with information about the user. See [middleware](#middleware) for more information.

## Middleware
The API supports middleware to preprocess requests before they execute their matching routes. Middleware is defined using the `use` method and require a function with three parameters for the `REQUEST`, `RESPONSE`, and `next` callback. For example:
The API supports middleware to preprocess requests before they execute their matching routes. Middleware is defined using the `use` method and requires a function with three parameters for the `REQUEST`, `RESPONSE`, and `next` callback. For example:

@@ -675,4 +681,28 @@ ```javascript

**NOTE:** Middleware can use either callbacks like `res.send()` or `return` to trigger a response to the user. Please note that calling either one of these from within a middleware function will terminate execution and return the response immediately.
**NOTE:** Middleware can use either callbacks like `res.send()` or `return` to trigger a response to the user. Please note that calling either one of these from within a middleware function will return the response immediately.
### Restricting middleware execution to certain path(s)
By default, middleware will execute on every path. If you only need it to execute for specific paths, pass the path (or array of paths) as the first parameter to the `use` function.
```javascript
// Single path
api.use('/users', (req,res,next) => { next() })
// Wildcard path
api.use('/users/*', (req,res,next) => { next() })
// Multiple path
api.use(['/users','/posts'], (req,res,next) => { next() })
// Parameterized paths
api.use('/users/:userId',(req,res,next) => { next() })
// Multiple paths with parameters and wildcards
api.use(['/comments','/users/:userId','/posts/*'],(req,res,next) => { next() })
```
Path matching checks both the supplied `path` and the defined `route`. This means that parameterized paths can be matched by either the parameter (e.g. `/users/:param1`) or by an exact matching path (e.g. `/users/123`).
## Clean Up

@@ -823,2 +853,2 @@ The API has a built-in clean up method called 'finally()' that will execute after all middleware and routes have been completed, but before execution is complete. This can be used to close database connections or to perform other clean up functions. A clean up function can be defined using the `finally` method and requires a function with two parameters for the REQUEST and the RESPONSE as its only argument. For example:

## Contributions
Contributions, ideas and bug reports are welcome and greatly appreciated. Please add [issues](https://github.com/jeremydaly/lambda-api/issues) for suggestions and bug reports.
Contributions, ideas and bug reports are welcome and greatly appreciated. Please add [issues](https://github.com/jeremydaly/lambda-api/issues) for suggestions and bug reports or create a pull request.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc