Skip to content

half-6/linkfuture-boot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Linkfuture boot

NPM version NPM Download NPM Status License

An simple way to boot express.

Prerequisites

  • nodejs 8.0 +
  • npm 5.0 +

How to use it

const $consign = require('consign');
const $path = require('path');
//use lf boot
const $meta = {
    root:[optional,default is application root],
    resourceroot:[optional,default is under /<root>/src/resource/],
    webroot:[optional,default is under /<root>/src/webapp/],
}
const $lf_boot =require("@linkfuture/boot")($meta)
const $lf_boot_web =require("@linkfuture/boot").web({beforeSetup:beforeSetupFun,afterSetup:afterSetupFun});

//beforeSetupFun, useful for connect-history-api-fallback
const app = $lf_boot_web.app;
//setup view engine 
app.set('views', $path.join(__dirname, './views'));
app.set('view engine', 'ejs');

/*auto scan routers, binding all pages and apis by using consign*/
$consign({logger:$lf.$logger})
    .include("src/bin/repository")
    .then("src/bin/service")
    .then("src/bin/controller")
    .into(app);

//forward all requests to external service you configed at $lf.$config.config.service
//option = {beforeForward(apiPath, configName, option, req),afterForward(apiPath, configName, option, req)} 
$lf.$forward.forwardAll("/api",option); 

//boot application
$lf_boot.boot();

//for Mocha unit test only
module.exports = app;

How to run build

    "build": "node -e \"require('@linkfuture/boot')().build().build(['js','css'],false)\"",  //default compress is true, you can set false 
    "build SQL": "node -e \"require('@linkfuture/boot')().build().build(['sql'])\"",

Global object

After init linkfuture-boot, you can use below global object directly, no need require("")

//Boot only
$lf._               //call lodash directly, 
$lf.$m              //call moment directly, 
$lf.$config.config  //read config file
$lf.$util           //utility method
$lf.$request        //promise request with retry
$lf.$cache          //store value into redis or static
$lf.$logger.silly   //write log by using winston 
$lf.$repository     //generate async function as repository base on configuration node "service", set serviceToRepository = false to off that feature
                    //example: $lf.$repository.test.h400({qs:{a:1,b:2}})
//Web Boot only
$lf.$auth           //auth model
$lf.$siteInfo       //get basic site information
$lf.$md             //an middleware to specific auth required or is it api response and setup cache time, 

How to use middleware module for auth and cache

app.get("/admin/",$ lf.$md(
        {
            min:0, // cache time in min
            key: function (req) { //optional, cache key, required redis setup,default value is following
                return `${req.method}_${req.getUrl}`;
            },
            api:false, //specific response type, JSON API or page, default is page
            auth:true, //is this page behind the authenciation or not, default is false
            roles:["admin"]  //array type, which role can access this page, required set auth=true,and req.user.roles = []
        }),(req,res,next)=>{
           res.send("Hello world");
        })

Config.json

  • config file can either JS or JSON format
  • must under resource root folder. default resource root folder is under //src/resource/
  • it will always read and merge two config files. config.json and config..json.
{
  //Optional, default value is base on NODE_ENV!='prod'
  "debug": true,
  "env":"${NODE_ENV}" //node env variable support, by using ${*}
  //Optional for static, default value is following
  "static": {
    "minify":false,
    "jsHttp": "/static/js/",
    "cssHttp": "/static/css/",
    "jsBuildFile":"/static/js/build.json",
    "cssBuildFile":"/static/css/build.json"
  },
   /*
    * Optional,all configuration is same with request npm,
    * but add following options
    *    apiForward:for disable auto api forward, default is true
    *    apiMethod: overwrite default api method, default is request method
    *    apiPath: overwrite default api path, default is /{base API Url}/test/r200
    *    repository: default is true, for disable auto repository
    * */
    "service":{
        "test":{
            "baseUrl": "https://httpstat.us/",
            "h400":{
                "url": "400",
                "method": "get",
                "json": true,
                "apiForward":false
                "apiPath":"my-path",   //this api path is /{base API Url}/my-path, overwrite default path /{base API Url}/test/h400
            },
            "h200":{
                "url": "200",
                "method": "get",
                "apiMethod":["get","post"],
                "json": true,
                "qs":{
                    "sleep":1000
                }
            }
        }
    },
  "serviceToRepository":true, //default is true
  //optional
  "cache":{
    //if you want to use redis, then need following node
    "redis": {
      "options": {
        "url": "redis://[redis URL]:6379",
        "disable_resubscribing": true
      },
      "prefix": "__LF.NODE__"
    }
    "method": "redis" //redis or local,default is local
  },
  //optional
  "auth":{
      "login": "/login",  //optional
      "info": "/info",  //optional
      "logout": "/logout", //optional
      "loginSuccessURL": "/", //optional
      "logoutSuccessURL": "/", //optional
      "cookieOptions":{       //optional
        "httpOnly": true,
        "cookieAge": 7200000, // 2hr no need, as JWT will expired
        "secure": false, //true if url is https, otherwise false
        "expires": 0 //browser session only cookie
      },
      //use jwt to encrypt the cookie base token
      "jwt": {
        "secret": {
          "public": "./test/resource/public.key",
          "private": "./test/resource/private.key"
        },
        "options": {
          "expiresIn": "2h",
          "header": {
            "author": "LF"
          },
          "subject": "@LinkFuture/Boot",
          "audience": "browser",
          "algorithm": "RS256",
          "issuer": "LINK FUTURE LLC"
        }
      },
      "event":{ //optional
          "onLoginSuccess":function (res, user) {
              $lf.$logger.silly("onLoginSuccess");
          },
          "onLogoutSuccess":function (res, user) {
              $lf.$logger.silly("onLogoutSuccess");
          }
      },
     "method": "form",   //form or auth0 or null
     "auth0": {  //need append this if use auth0 as auth
        "clientID": "[auth0 clientID]",
        "domain": "[auth0 domain]",
        "clientSecret": "[auth0 clientSecret]",
        "responseType": "code",
        "scope": "openid profile",
        "audience": "[auth0 audience]",
        "callbackURL": "/callback"
      }
  },
  //Optional
  "mappings": [
    {"pattern": "/admin/*", "auth":true, "roles": ["ETA Dashboard"], "method": ["GET", "POST"]},
    {"pattern": "/api/db", "api":false,"auth":true},
    {"pattern": "/api/login", "api":true,"auth":false},
    {"pattern": "/api/*", "api":true,"auth":true,"min":10, "roles": ["ETA Dashboard"]}
  ],
  //Optional
  "helmet":{
    "frameguard": false
  },
  //Optional for logger, default value is following
  "log":{
    "logFolder":"logs"
    ,"logLevel":"silly"
    ,"showDate":true
  },
  //Optional for api/config, default value is following
  "lf_admin":{
    "username":"admin"
   ,"password":"[admin password]"
  },
  //Optional for api/config, default value is following
  "error":{
    "error400":"error400",
    "error500":"error500"
  },
  //Optional for retry
  "retryOptions":{
    "retries": 3,
    "minTimeout": 1000,
    "maxTimeout": 3000,
    "randomize": true
  },
  //Optional for request
  "requestOptions":{
      "timeout": 15000,
  },
   //Optional, url proxy, forward request to target url.
   "proxy":[
     {
       "url":"/api/proxy/*",
       "forwardBaseUrl":"http://<domain>/api/",
       "headers":{}, //optional
       "query":{}, //optional
       "body":{} //optional
     }
   ],
   //single application history mode
   //reference connect-history-api-fallback for configuration detail
   "history":{
        "disableDotRule": false,
        "verbose": false,
        "htmlAcceptHeaders": ["text/html", "application/xhtml+xml"]
   }
}

How to read config

//read config by default NODE_ENV
$lf.$config.config.XXX 
//read config by pass env
const $config = $lf.$config.readEnvConfig('prod', $meta);
$config.config.XXX

Releases

No releases published

Packages

No packages published