UNPKG

we-core

Version:

We.js is a node.js framework for build real time applications, sites or blogs!

474 lines (458 loc) 14.5 kB
/** * We.js core plugin main file */ module.exports = function loadPlugin (projectPath, Plugin) { const plugin = new Plugin(__dirname); // folder for fallback templates plugin.tplFolder = projectPath + '/node_modules/we-plugin-view/server/templates/'; // set plugin configs plugin.setConfigs({ // select how bootstrap functions will run // values: full || install bootstrapMode: null, // enable suport to parse req.query.where to sequelize query enableQueryWhere: false, // update route methods updateMethods: ['POST', 'PUT', 'PATCH'], // default find limit queryDefaultLimit: 25, queryMaxLimit: 300, // map reponseType response types, used by Accept headers in response selection // this is set automaticaly after add new response types responseTypes: [ 'application/json', 'application/vnd.api+json' ], defaultResponseType: 'application/json', // send nested models in response sendNestedModels: true, port: process.env.PORT || '4000', hostname: process.env.APP_HOSTNAME || 'http://localhost:' + ( process.env.PORT || '4000' ), // default favicon, change in your project config/local.js favicon: __dirname + '/files/public/core-favicon.ico', appName: process.env.APP_NAME || 'We.js app', appLogo: null, robotsTXT: __dirname + '/files/robots.txt', log: { level: 'debug' }, // set false to disable request log in dev env enableRequestLog: process.env.APP_ENABLE_REQUEST_LOG || true, enable404Log: true, session: { secret: 'setASecreteKeyInYourAppConfig', resave: false, saveUninitialized: true, name: 'wejs.sid', rolling: false, cookie: { path: '/', httpOnly: true, secure: false, maxAge: 86400000*15 // 15 days } }, // body parser settings to use in bodyParser.json() bodyParser: { limit: 20000000 }, // external services API keys apiKeys: {}, // node-i18n configs i18n: { // setup some locales - other locales default to en silently locales:[], // you may alter a site wide default locale defaultLocale: process.env.APP_DEFAULT_LOCALE || 'en-us', // sets a custom cookie name to parse locale settings from - defaults to NULL cookie: 'i18n', queryParameter: 'lang', // where to store json files - defaults to './locales' relative to modules directory directory: projectPath + '/config/locales', // whether to write new locale information to disk - defaults to true updateFiles: false, // what to use as the indentation unit - defaults to "\t" indent: '\t', // setting extension of json files - defaults to '.json' // (you might want to set this to '.js' according to webtranslateit) extension: '.json', // setting prefix of json files name - default to none '' // (in case you use different locale files naming scheme // (webapp-en.json), rather then just en.json) prefix: '', // enable object notation objectNotation: false }, clientside: { // client side logs log: {}, // publivars publicVars: { // set to true to enable the page.js partial loader dynamicLayout: false } }, metadata: {}, // default db config database: { resetAllData: false, prod: { uri: process.env.DATABASE_URL, dialect: process.env.DB_DIALECT, protocol: process.env.DB_PROTOCOL, database: process.env.DB_NAME, username: process.env.DB_USER, password: process.env.DB_PASSWORD, host: process.env.DB_HOST, port: process.env.DB_PORT, // by default log to info logging: plugin.we.log.debug }, dev: { uri: process.env.DATABASE_URL, dialect: process.env.DB_DIALECT, protocol: process.env.DB_PROTOCOL, database: process.env.DB_NAME, username: process.env.DB_USER, password: process.env.DB_PASSWORD, host: process.env.DB_HOST, port: process.env.DB_PORT, // by default log to info logging: plugin.we.log.debug }, test: { uri: process.env.TEST_DATABASE_URL, dialect: process.env.TEST_DB_DIALECT, protocol: process.env.TEST_DB_PROTOCOL, database: process.env.TEST_DB_NAME, username: process.env.TEST_DB_USER, password: process.env.TEST_DB_PASSWORD, port: process.env.TEST_DB_PORT, // by default log to info logging: plugin.we.log.debug } }, // services register // { url: '', oauthCallback: '', name: ''} services: {}, date: { defaultFormat: process.env.APP_DATE_FORMAT || 'L HH:mm' }, // cache configs cache: { // resource cache, Last-Modified cache resourceCacheActions: 'findOne', skipResourceCache: false, //Cache-Control: public, max-age=[maxage] maxage: 86400000*15 // 15 days }, security: { // see https://github.com/expressjs/cors#configuration-options for configuration options // This may be override by every route configs CORS: { // block all CORS requests by default origin: function(origin, cb){ cb(null, false); }, // default methods methods: ['GET', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'Accept'] }, sanitizer: { allowedTags: [ // text blocks 'p', 'pre', 'code', 'blockquote', 'br', 'a', 'img', 'hr', 'mention', 'iframe', 'div', // table: 'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', // text format 'b', 'i', 'em', 'strong', 'u', 'h1', 'h2', 'h3', 'h4', 'h5','h6', // list 'ul', 'ol', 'nl', 'li', // form: 'form', 'button', 'datalist', 'legend', 'label', 'select', 'optgroup', 'option', 'textarea', 'keygen', 'fieldset', 'output', 'progress', 'meter', 'input', // figure tags: 'figure', 'figcaption', // video tags: 'object', 'param', 'embed', 'video', 'source', // audio 'audio', 'track' ], selfClosing: [ 'br', 'img', 'hr', 'input' ], allowedAttributes: { '*': [ 'id', 'style', 'align', 'alt', 'center', 'bgcolor', 'data-*', 'we-*', 'width', 'height', 'class', 'type', 'name', 'autocomplete', 'autofocus', 'required', 'value', 'disabled', 'src', 'tabindex', 'placeholder', 'type', 'multiple', 'rows', 'cols' ], 'a': ['href', 'target', 'type'], 'img': ['src'], 'iframe': ['src', 'frameborder'], 'form': ['action', 'method', 'accept', 'accept-charset', 'autocomplete', 'enctype', 'target' ], 'input': [ 'accept', 'checked', 'maxlength', 'size', 'minlength' ], 'video': ['controls'], 'audio': ['controls'], 'embed': ['allowscriptaccess', 'allowfullscreen'], 'track': ['kind', 'srclang', 'label'] }, allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ], allowProtocolRelative: true } }, router: { pluralize: false }, JSONApi: { sendSubRecordAttributes: process.env.APP_SUB_RECORD_ATTRIBUTES || false }, /** * Resource routes, add or remove routes generated to your resource * * @type {Object} */ resourceRoutes: { // apis createAPI(we, cfg, opts) { // set post create on list for APIS we.routes['post '+opts.rootRoute] = we.utils._.merge( { resourceName: opts.namePrefix+opts.name, action: 'create', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, permission: 'create_' + opts.name, breadcrumbHandler: 'create' }, opts.create, we.routes['post '+opts.rootRoute] || {} ); }, findAll(we, cfg, opts) { we.routes['get ' + opts.rootRoute] = we.utils._.merge( { resourceName: opts.namePrefix+opts.name, layoutName: opts.layoutName, // null = default layout name: opts.namePrefix + opts.name + '.find', action: 'find', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, template: opts.templateFolderPrefix + opts.name + '/find', fallbackTemplate: plugin.tplFolder + 'default/find.hbs', permission: 'find_' + opts.name, titleHandler: 'i18n', titleI18n: opts.name + '.find', routeQuery: opts.routeQuery, // default search search: { // since search is avaible in findAll by default since: { parser: 'since', target: { type: 'field', field: 'createdAt' } } }, breadcrumbHandler: 'find' }, opts.findAll, we.routes['get ' + opts.rootRoute] || {} ); }, findOne(we, cfg, opts, Model) { we.routes['get '+opts.itemRoute] = we.utils._.merge( { layoutName: opts.layoutName, // null = default layout resourceName: opts.namePrefix+opts.name, name: opts.namePrefix + opts.name + '.findOne', action: 'findOne', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, template: opts.templateFolderPrefix + opts.name + '/findOne', fallbackTemplate: plugin.tplFolder + 'default/findOne.hbs', permission: 'find_' + opts.name, titleHandler: opts.itemTitleHandler, titleField: Model.options.titleField, titleI18n: opts.name + '.findOne', breadcrumbHandler: 'findOne' }, opts.findOne, we.routes['get '+opts.itemRoute] || {} ); }, updateAPI(we, cfg, opts) { // pipe put and patch will be handled in same controller, action as update we.routes['put '+opts.itemRoute] = we.utils._.merge( { resourceName: opts.namePrefix+opts.name, action: 'edit', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, permission: 'update_' + opts.name }, opts.edit, we.routes['put '+opts.itemRoute] || {} ); we.routes['patch '+opts.itemRoute] = we.utils._.merge( { resourceName: opts.namePrefix+opts.name, action: 'edit', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, permission: 'update_' + opts.name }, opts.edit, we.routes['patch '+opts.itemRoute] || {} ); }, deleteAPI(we, cfg, opts) { we.routes['delete '+opts.itemRoute] = we.utils._.merge( { resourceName: opts.namePrefix+opts.name, action: 'delete', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, permission: 'delete_' + opts.name }, opts.delete, we.routes['delete '+opts.itemRoute] || {} ); }, countAPI(we, cfg, opts) { we.routes[`get ${opts.rootRoute}/count`] = we.utils._.merge( { resourceName: opts.namePrefix+opts.name, name: opts.namePrefix + opts.name + '.count', action: 'count', controller: cfg.controller, model: cfg.model, paramIdName: opts.paramIdName, permission: 'find_' + opts.name, routeQuery: opts.routeQuery, search: { since: { parser: 'since', target: { type: 'field', field: 'createdAt' } } } }, opts.count, we.routes[`get ${opts.rootRoute}/count`] || {} ); } } }); plugin.fastLoader = function fastLoader(we, done) { /** * MainController * * @module Controller */ we.controllers.main = new we.class.Controller({ /** * Index page route / */ index(req, res) { res.locals.title = null; // dont show duplicated titles res.ok(); }, }); /** * t controller * Controller for core translations API * @type {Controller} */ we.controllers.t = new we.class.Controller({}); we.controllers.syshealth = new we.class.Controller({ /** * Health check router * * @param {Object} req Express request * @param {Object} res Express request * @api [get] /health * description: "Get app health" * responses: * "200": * description: "Return a simple online: true json data." * schema: * type: object * properties: * online: * type: boolean * example: true */ status(req, res) { res.send({ online: true }); } }); done(); }; plugin.setResource({ name: 't' }); plugin.setRoutes({ 'get /': { 'controller': 'main', 'action': 'index', 'template' : 'home/index', 'layoutName' : 'home', titleHandler(req, res, next) { res.locals.title = ''; /// remove default duplicated title: return next(); } }, 'get /health': { controller: 'syshealth', action: 'status', responseType: 'json', permission: true }, }); return plugin; };