npm package: @navarrotech/servefunctions
Description: If you're used to writing serverless functions in individual files, but need to write them on an express.js app, this package makes that easy.
Author: Alex Navarro
Latest version: 1.0.11

# Express.js functionality for serverless-like functions folder structure
If you're used to writing serverless functions in individual files, but need to write them on an express.js app, this package makes that easy.

### Quick Start
```
const serveFunctions = require('@navarrotech/servefunctions')

const app = express()
const options = {
  path: './functions'
  defaultMethod: 'post',
  autoTryCatch: true,
  middleware: [
    {
      match: /index\.js$/i,
      method: 'post',
      pre: [
        function(req, res, next){
          console.log("Pre middleware 1!")
          next()
        },
        function(req, res, next){
          console.log("Pre middleware 2!")
          next()
        }
      ],
      post: [
        function(req, res, next){
          console.log("Post middleware 3!")
          next()
        }
      ]
    }
  ]
}

serveFunctions(app, options)
```

### What a sample directory looks like:
```
index.js <-- Put the serveFunctions init here
functions/
  | 
  + > api/
      | 
      + > index.js <-- Resolves to POST /
      |
      + > :id.js <-- Resolves to POST /api/:id
      | 
      \ > update.js <-- Resolves to POST /api/update
  |
  \ > index.js <!-- Resolves to POST /
package.json
```

### Sample file in the functions directory: 

If this file was at: /functions/get.js, then sending a POST request to "/get" will return a momentjs formatted timestamp.
```
const moment = require('moment')

module.exports = function(req, res){
  res.send(moment().format('MMMM Do YYYY [at] h:mma'))
}
```

## Options
Additional options are available to improve quality of life

#### path
A path to your a directory with functions to init.
Must be relative to your app's working directory

Type: String

**Default: "./function"**

#### defaultMethod
Specify the default method that you want your app to handle.
If set to "post" then your app will only accept your routes when you run post requests to them.

Options: [
  "put",
  "post",
  "get",
  "delete",
  "all"
]
Type: String

**Default: "post"**

#### verbose
When your app starts, get notified about how many files and directories were initialized.

Type: Boolean

**Default: false**

#### autoTryCatch
Wrap your function in a try/catch automatically. 
If your function crashes and the headers are not sent, then express will attempt to catch it and emit a 500 status.

Type: Boolean

**Default: false**

#### auto500Message
If you have autoTryCatch enabled, you can use a default static message to send when your function crashes.
If option is set to null, undefined, false, or another invalid value then express will only send the status.

Type: String, Int or JSON

**Default: "Something went wrong, please try again later."**

#### middleware
You can use `app.use(/regex/)` to match your function routes, or you can pass in parameters to specify overrides.

**Note:** If you have multiple middleware objects that match the same route, then ALL pre and post middleware will be used.
The first method override found will be used, and override any other overrides. ("First variable wins")

Type: Array of Objects

**Default: []**

#### middleware[x].match
A regex function that matches the rule to your route, and will apply any settings to urls that match.

Example:
```
{
  match: /create.js$/i
}
```

Will match the routes:
/create
/users/create
/deep/nested/api/values/:foo/:baz/create

And will not match the routes:
/index
/you/get/the/point

Routes that are matched will apply any method overrides or pre/post middlewares that are given.

Type: Regex

**Default: undefined**

#### middleware[x].method
Specify a specific method that you want your app to use when it matches a route with `middleware[x].match`.

Useful if you have all your routes set to POST, but you have one or two routes you want to set as GET or DELETE.

Options: [
  "put",
  "post",
  "get",
  "delete",
  "all"
]

Type: String

**Default: undefined**

#### middleware[x].pre and middleware[x].post
Specify middlewares you want to have called before or after your function is called.

For example:
```
{
  match: /\/public\//i,
  method: 'post',
  pre: [
    cors(),
    express.json()
  ],
  post: [
    function logVisits(req, res){
      console.log("We were just visited!")
    }
  ]
}
```

This would be the 100% equivalent of writing:
```
app.post('/public/*', cors(), express.json(), functionFromFile, logVisits)
```

And is also the equivalent of writing:
```
app.use(/\/public\//i, cors(), express.json())
app.post('/public/path', functionFromFile)
app.use(/\/public\//i, logVisits)
```

Functions in the pre list run BEFORE your function in the file is called.
Functions in the post list run AFTER your function in the file is called.

Type: Array of middleware functions

**Default: []**

### Navarrotech by Alex Navarro