Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8f8c219
version bump
jeremydaly Mar 27, 2018
4e0063e
update lambda api image inclusion method for npm fix
jeremydaly Mar 27, 2018
bc2a00b
add register function to close #11, rework base property
jeremydaly Mar 28, 2018
bfa26be
update tests with new base config and add register tests
jeremydaly Mar 28, 2018
75284c5
add base64 body parsing if isBase64Encoded header is available
jeremydaly Mar 28, 2018
49476ab
add support for root paths
jeremydaly Mar 28, 2018
074ee79
add notes for root paths and binary support
jeremydaly Mar 28, 2018
0a6de47
additional notes about binary support
jeremydaly Mar 28, 2018
6b0d2d8
add mimeLookup and mimemap
jeremydaly Mar 30, 2018
7926f21
add mimeLookup tests
jeremydaly Mar 30, 2018
96a64d7
add basic attachment() method tests
jeremydaly Mar 30, 2018
f62eb12
update tests to support default isBase64Encoded flag
jeremydaly Mar 30, 2018
e8f6686
add custom mimeTypes config option
jeremydaly Mar 30, 2018
9a73b68
add attachment() method and basic sendFile
jeremydaly Mar 30, 2018
928c7e3
add txt to mimemap
jeremydaly Mar 30, 2018
91eea99
add auto reset of isBase64 on error
jeremydaly Mar 30, 2018
a0f8a78
add initial sendFile() functionality
jeremydaly Mar 30, 2018
e27c672
add tests for sendFile and test.txt file
jeremydaly Mar 30, 2018
229b93f
initial documentation for sendFile and new config options
jeremydaly Mar 31, 2018
9012dc6
close #18 by adding patch() convenience method
jeremydaly Mar 31, 2018
71316e9
add patch() documentation
jeremydaly Mar 31, 2018
7e5ee40
documentation cleanup
jeremydaly Mar 31, 2018
8530199
add register() documentation
jeremydaly Mar 31, 2018
aa9bcaa
add attachment() documentation
jeremydaly Mar 31, 2018
6c745d6
add download() method
jeremydaly Mar 31, 2018
3643713
add tests for download() method
jeremydaly Mar 31, 2018
f86af2d
add additional attachment tests
jeremydaly Mar 31, 2018
86c0a17
add strip headers on error
jeremydaly Mar 31, 2018
aed99f6
additional documentation for download/sendfile and other updates
jeremydaly Mar 31, 2018
591da6d
add aws-sdk as dev dependency
jeremydaly Apr 1, 2018
28b9c33
add s3 getObject support w/ tests
jeremydaly Apr 1, 2018
eaa3634
clean up comments
jeremydaly Apr 1, 2018
e42739f
add binary support documentation
jeremydaly Apr 2, 2018
0127fb8
additional documentation and cleanup
jeremydaly Apr 2, 2018
0516b7b
doc tweaks
jeremydaly Apr 2, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 161 additions & 24 deletions README.md

Large diffs are not rendered by default.

64 changes: 47 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ class API {

// Set the version and base paths
this._version = props && props.version ? props.version : 'v1'
this._base = props && props.base ? props.base.trim() : ''
this._base = props && props.base && typeof props.base === 'string' ? props.base.trim() : ''
this._callbackName = props && props.callback ? props.callback.trim() : 'callback'
this._mimeTypes = props && props.mimeTypes && typeof props.mimeTypes === 'object' ? props.mimeTypes : {}

// Prefix stack w/ base
this._prefix = this.parseRoute(this._base)

// Stores timers for debugging
this._timers = {}
Expand Down Expand Up @@ -56,6 +60,7 @@ class API {

// Testing flag
this._test = false

} // end constructor

// GET: convenience method
Expand All @@ -73,6 +78,11 @@ class API {
this.METHOD('PUT', path, handler)
}

// PATCH: convenience method
patch(path, handler) {
this.METHOD('PATCH', path, handler)
}

// DELETE: convenience method
delete(path, handler) {
this.METHOD('DELETE', path, handler)
Expand All @@ -86,8 +96,14 @@ class API {
// METHOD: Adds method and handler to routes
METHOD(method, path, handler) {

// Parse the path
let parsedPath = this.parseRoute(path)

// Split the route and clean it up
let route = path.trim().replace(/^\/(.*?)(\/)*$/,'$1').split('/')
let route = this._prefix.concat(parsedPath)

// For root path support
if (route.length === 0) { route.push('')}

// Keep track of path variables
let pathVars = {}
Expand All @@ -106,7 +122,7 @@ class API {
// Add the route to the global _routes
this.setRoute(
this._routes,
(i === route.length-1 ? { ['__'+method.toUpperCase()]: { vars: pathVars, handler: handler, route: path } } : {}),
(i === route.length-1 ? { ['__'+method.toUpperCase()]: { vars: pathVars, handler: handler, route: '/'+parsedPath.join('/') } } : {}),
route.slice(0,i+1)
);

Expand Down Expand Up @@ -141,6 +157,12 @@ class API {

}).catch((e) => {

// Error messages should never be base64 encoded
response._isBase64 = false

// Strip the headers (TODO: find a better way to handle this)
response._headers = {}

let message;

if (e instanceof Error) {
Expand Down Expand Up @@ -298,20 +320,11 @@ class API {
// UTILITY FUNCTIONS
//-------------------------------------------------------------------------//

deepFind(obj, path) {
let paths = path//.split('.'),
let current = obj

for (let i = 0; i < paths.length; ++i) {
if (current[paths[i]] == undefined) {
return undefined
} else {
current = current[paths[i]]
}
}
return current
parseRoute(path) {
return path.trim().replace(/^\/(.*?)(\/)*$/,'$1').split('/').filter(x => x.trim() !== '')
}


setRoute(obj, value, path) {
if (typeof path === "string") {
let path = path.split('.')
Expand Down Expand Up @@ -354,9 +367,26 @@ class API {
return this._app
}


// Register routes with options
register(fn,options) {

// Extract Prefix
let prefix = options.prefix && options.prefix.toString().trim() !== '' ?
this.parseRoute(options.prefix) : []

// Concat to existing prefix
this._prefix = this._prefix.concat(prefix)

// Execute the routing function
fn(this,options)

// Remove the last prefix
this._prefix = this._prefix.slice(0,-(prefix.length))

} // end register

} // end API class

// Export the API class
module.exports = opts => new API(opts)

// console.error('DEPRECATED: constructor method. Use require(\'lambda-api\')({ version: \'v1.0\', base: \'v1\' }) to initialize the framework instead')
74 changes: 74 additions & 0 deletions mimemap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use strict'

/**
* Lightweight web framework for your serverless applications
* @author Jeremy Daly <jeremy@jeremydaly.com>
* @license MIT
*/

// Minimal mime map for common file types

module.exports = {
// images
gif: 'image/gif',
ico: 'image/x-icon',
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
png: 'image/png',
svg: 'image/svg+xml',
svgz: 'image/svg+xml',

// text
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
html: 'text/html',
htm: 'text/html',
js: 'application/javascript',
json: 'application/json',
map: 'application/json',
rdf: 'application/rdf+xml',
rss: 'application/rss+xml',
txt: 'text/plain',
webmanifest: 'application/manifest+json',
xml: 'application/xml',
xls: 'application/xml',

// other binary
gz: 'application/gzip',
pdf: 'application/pdf',
zip: 'application/zip',

// fonts
woff: 'application/font-woff',

// MS file Types
doc: 'application/msword',
dot: 'application/msword',
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
dotx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
docm: 'application/vnd.ms-word.document.macroEnabled.12',
dotm: 'application/vnd.ms-word.template.macroEnabled.12',
xls: 'application/vnd.ms-excel',
xlt: 'application/vnd.ms-excel',
xla: 'application/vnd.ms-excel',
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
xltx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
xlsm: 'application/vnd.ms-excel.sheet.macroEnabled.12',
xltm: 'application/vnd.ms-excel.template.macroEnabled.12',
xlam: 'application/vnd.ms-excel.addin.macroEnabled.12',
xlsb: 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
ppt: 'application/vnd.ms-powerpoint',
pot: 'application/vnd.ms-powerpoint',
pps: 'application/vnd.ms-powerpoint',
ppa: 'application/vnd.ms-powerpoint',
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
potx: 'application/vnd.openxmlformats-officedocument.presentationml.template',
ppsx: 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
ppam: 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
pptm: 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
potm: 'application/vnd.ms-powerpoint.template.macroEnabled.12',
ppsm: 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
mdb: 'application/vnd.ms-access'

}
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lambda-api",
"version": "0.3.1",
"version": "0.4.0",
"description": "Lightweight web framework for your serverless applications",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -32,8 +32,10 @@
"bluebird": "^3.5.1"
},
"devDependencies": {
"aws-sdk": "^2.218.1",
"chai": "^4.1.2",
"mocha": "^4.0.1"
"mocha": "^4.0.1",
"sinon": "^4.5.0"
},
"engines": {
"node": ">= 6.10.0"
Expand Down
19 changes: 10 additions & 9 deletions request.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,24 @@ class REQUEST {
// Set the requestContext
this.requestContext = app._event.requestContext

// Capture the raw body
this.rawBody = app._event.body

// Set the body (decode it if base64 encoded)
this.body = app._event.isBase64Encoded ? Buffer.from(app._event.body, 'base64').toString() : app._event.body

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

// Extract path from event (strip querystring just in case)
let path = app._event.path.trim().split('?')[0].replace(/^\/(.*?)(\/)*$/,'$1').split('/')

// Remove base if it exists
if (app._base && app._base === path[0]) {
path.shift()
} // end remove base

// Init the route
this.route = null

Expand Down
Loading