Browse Source

Merge remote-tracking branch 'origin/master' into imprv/brushup-group-select-ui

Tatsuya Ise 8 years ago
parent
commit
0247f42eb5
73 changed files with 538 additions and 380 deletions
  1. 4 0
      .eslintrc.js
  2. 7 1
      CHANGES.md
  3. 20 2
      app.js
  4. 2 2
      bin/search.js
  5. 2 2
      bin/util.js
  6. 1 16
      config/env.dev.js
  7. 3 5
      config/env.prod.js
  8. 13 0
      config/index.js
  9. 17 0
      config/logger/config.dev.js
  10. 3 0
      config/logger/config.prod.js
  11. 9 1
      config/webpack.common.js
  12. 1 1
      lib/crowi/dev.js
  13. 1 1
      lib/crowi/express-init.js
  14. 0 20
      lib/crowi/helpers.js
  15. 62 85
      lib/crowi/index.js
  16. 1 1
      lib/events/page.js
  17. 1 1
      lib/events/user.js
  18. 3 3
      lib/locales/en-US/sandbox.md
  19. 3 3
      lib/locales/ja/sandbox.md
  20. 1 1
      lib/models/attachment.js
  21. 1 1
      lib/models/bookmark.js
  22. 1 1
      lib/models/comment.js
  23. 1 1
      lib/models/config.js
  24. 1 1
      lib/models/external-account.js
  25. 1 1
      lib/models/page-group-relation.js
  26. 1 1
      lib/models/page.js
  27. 1 1
      lib/models/revision.js
  28. 1 1
      lib/models/updatePost.js
  29. 1 1
      lib/models/user-group-relation.js
  30. 1 1
      lib/models/user-group.js
  31. 1 1
      lib/models/user.js
  32. 3 4
      lib/plugins/plugin.service.js
  33. 1 1
      lib/routes/admin.js
  34. 1 1
      lib/routes/attachment.js
  35. 1 1
      lib/routes/bookmark.js
  36. 1 1
      lib/routes/comment.js
  37. 1 1
      lib/routes/installer.js
  38. 1 1
      lib/routes/login-passport.js
  39. 1 1
      lib/routes/login.js
  40. 1 1
      lib/routes/me.js
  41. 1 1
      lib/routes/page.js
  42. 1 1
      lib/routes/revision.js
  43. 1 1
      lib/routes/search.js
  44. 11 0
      lib/service/logger/alias-for-debug.js
  45. 48 0
      lib/service/logger/index.js
  46. 16 0
      lib/service/logger/stream.dev.js
  47. 20 0
      lib/service/logger/stream.prod.js
  48. 1 1
      lib/service/passport.js
  49. 1 1
      lib/util/fileUploader.js
  50. 1 1
      lib/util/googleAuth.js
  51. 9 9
      lib/util/interceptor-manager.js
  52. 1 1
      lib/util/mailer.js
  53. 1 1
      lib/util/middlewares.js
  54. 1 1
      lib/util/search.js
  55. 1 1
      lib/util/slack.js
  56. 1 1
      lib/util/swigFunctions.js
  57. 1 0
      lib/views/admin/customize.html
  58. 15 11
      lib/views/modal/unportalize.html
  59. 1 1
      local_modules/crowi-fileupload-aws/index.js
  60. 1 1
      local_modules/crowi-fileupload-local/index.js
  61. 1 1
      local_modules/crowi-fileupload-none/index.js
  62. 14 7
      package.json
  63. 3 0
      resource/js/components/PageEditor.js
  64. 12 2
      resource/js/components/PageEditor/Editor.js
  65. 13 16
      resource/js/components/PageEditor/EmojiAutoCompleteHelper.js
  66. 7 6
      resource/js/legacy/crowi.js
  67. 8 2
      resource/js/util/Crowi.js
  68. 3 3
      resource/js/util/markdown-it/emoji.js
  69. 6 17
      resource/js/util/markdown-it/toc-and-anchor.js
  70. 51 0
      resource/styles/agile-admin/inverse/colors/mono-blue.scss
  71. 8 0
      resource/styles/scss/theme/mono-blue.scss
  72. 3 1
      test/bootstrap.js
  73. 100 124
      yarn.lock

+ 4 - 0
.eslintrc.js

@@ -9,6 +9,10 @@ module.exports = {
     "eslint:recommended",
     "eslint:recommended",
     "plugin:react/recommended"
     "plugin:react/recommended"
   ],
   ],
+  "globals": {
+    "window": true,
+    "emojione": true
+  },
   "parserOptions": {
   "parserOptions": {
     "ecmaFeatures": {
     "ecmaFeatures": {
       "experimentalObjectRestSpread": true,
       "experimentalObjectRestSpread": true,

+ 7 - 1
CHANGES.md

@@ -3,7 +3,14 @@ CHANGES
 
 
 ## 3.0.13-RC
 ## 3.0.13-RC
 
 
+* Improvement: Add Vim/Emacs/Sublime-Text icons for keybindings menu
+* Improvement: Add 'mono-blue' theme
+* Fix: Unportalize process failed silently
+* Support: Switch the logger from 'pino' to 'bunyan'
+* Support: Set the alias for 'debug' to the debug function of 'bunyan'
 * Support: Translate /admin/security
 * Support: Translate /admin/security
+* Support: Optimize bundles
+    * upgrade 'markdown-it-toc-and-anchor-with-slugid' and omit 'uslug'
 
 
 ## 3.0.12
 ## 3.0.12
 
 
@@ -12,7 +19,6 @@ CHANGES
 * Improvement: Dynamic loading for CodeMirror theme files from CDN
 * Improvement: Dynamic loading for CodeMirror theme files from CDN
 * Improvement: Prevent XSS when move/redirect/duplicate
 * Improvement: Prevent XSS when move/redirect/duplicate
 
 
-
 ## 3.0.11
 ## 3.0.11
 
 
 * Fix: login.html is broken in iOS
 * Fix: login.html is broken in iOS

+ 20 - 2
app.js

@@ -5,7 +5,25 @@
  * @author  Yuki Takei <yuki@weseek.co.jp>
  * @author  Yuki Takei <yuki@weseek.co.jp>
  */
  */
 
 
-var growi = new (require('./lib/crowi'))(__dirname, process.env);
+require('module-alias/register');
+
+const logger = require('@alias/logger')('growi');
+const growi = new (require('./lib/crowi'))(__dirname, process.env);
+
+
+/************************************
+ *          Main Process
+ ***********************************/
+process.on('uncaughtException', (err) => {
+  logger.error('Uncaught Exception: ', err);
+});
+
+process.on('unhandledRejection', (reason, p) => {
+  logger.error('Unhandled Rejection: Promise:', p, 'Reason:', reason);
+});
 
 
 growi.start()
 growi.start()
-  .catch(growi.exitOnerror);
+  .catch(err => {
+    logger.error('An error occurred, unable to start the server');
+    logger.error(err);
+  });

+ 2 - 2
bin/search.js

@@ -1,6 +1,6 @@
 
 
 var program = require('commander')
 var program = require('commander')
-  , debug = require('debug')('crowi:console:search-util')
+  , debug = require('debug')('growi:console:search-util')
   , colors = require('colors')
   , colors = require('colors')
   , crowi = new (require('../lib/crowi'))(__dirname + '/../', process.env)
   , crowi = new (require('../lib/crowi'))(__dirname + '/../', process.env)
   ;
   ;
@@ -116,7 +116,7 @@ crowi.init()
 
 
     program.parse(process.argv);
     program.parse(process.argv);
 
 
-  }).catch(crowi.exitOnError);
+  });
 
 
 
 
 //program
 //program

+ 2 - 2
bin/util.js

@@ -1,5 +1,5 @@
 var program = require('commander')
 var program = require('commander')
-  , debug = require('debug')('crowi:console:util')
+  , debug = require('debug')('growi:console:util')
   , colors = require('colors')
   , colors = require('colors')
   , crowi = new (require('../lib/crowi'))(__dirname + '/../', process.env)
   , crowi = new (require('../lib/crowi'))(__dirname + '/../', process.env)
   ;
   ;
@@ -41,4 +41,4 @@ crowi.init()
       });
       });
 
 
     program.parse(process.argv);
     program.parse(process.argv);
-  }).catch(crowi.exitOnError);
+  });

+ 1 - 16
config/env.dev.js

@@ -7,19 +7,4 @@ module.exports = {
     // 'growi-plugin-lsx',
     // 'growi-plugin-lsx',
     // 'growi-plugin-pukiwiki-like-linker',
     // 'growi-plugin-pukiwiki-like-linker',
   ],
   ],
-  // filters for debug
-  DEBUG: [
-    // 'express:*',
-    // 'crowi:*',
-    'crowi:crowi',
-    // 'crowi:crowi:dev',
-    'crowi:crowi:express-init',
-    'crowi:models:external-account',
-    // 'crowi:routes:login',
-    'crowi:routes:login-passport',
-    'crowi:service:PassportService',
-    // 'crowi:routes:page',
-    // 'crowi:plugins:*',
-    // 'crowi:InterceptorManager',
-  ].join(),
-}
+};

+ 3 - 5
config/env.prod.js

@@ -1,6 +1,4 @@
 module.exports = {
 module.exports = {
-  // logging settings
-  DEBUG: [
-    'crowi:crowi',
-  ].join(),
-}
+  NODE_ENV: 'production',
+  // FORMAT_NODE_LOG: false,
+};

+ 13 - 0
config/index.js

@@ -0,0 +1,13 @@
+function envShortName() {
+  switch (process.env.NODE_ENV) {
+    case 'production':
+      return 'prod';
+    default:
+      return 'dev';
+  }
+}
+
+module.exports = {
+  env: require(`./env.${envShortName()}`),
+  logger: require(`./logger/config.${envShortName()}`),
+};

+ 17 - 0
config/logger/config.dev.js

@@ -0,0 +1,17 @@
+module.exports = {
+  default: 'info',
+
+  //// configure level for name
+  // 'express:*': 'debug',
+  // 'growi:*': 'debug',
+  'growi:crowi': 'debug',
+  // 'growi:crow:dev': 'debug',
+  'growi:crowi:express-init': 'debug',
+  'growi:models:external-account': 'debug',
+  // 'growi:routes:login': 'debug',
+  'growi:routes:login-passport': 'debug',
+  'growi:service:PassportService': 'debug',
+  // 'growi:routes:page': 'debug',
+  // 'growi-plugin:*': 'debug',
+  // 'growi:InterceptorManager': 'debug',
+};

+ 3 - 0
config/logger/config.prod.js

@@ -0,0 +1,3 @@
+module.exports = {
+  default: 'info',
+};

+ 9 - 1
config/webpack.common.js

@@ -3,6 +3,7 @@
  */
  */
 
 
 const webpack = require('webpack');
 const webpack = require('webpack');
+const path = require('path');
 const helpers = require('./helpers');
 const helpers = require('./helpers');
 
 
 /*
 /*
@@ -29,6 +30,7 @@ module.exports = function(options) {
       'style-theme-default':  './resource/styles/scss/theme/default.scss',
       'style-theme-default':  './resource/styles/scss/theme/default.scss',
       'style-theme-default-dark':  './resource/styles/scss/theme/default-dark.scss',
       'style-theme-default-dark':  './resource/styles/scss/theme/default-dark.scss',
       'style-theme-nature':   './resource/styles/scss/theme/nature.scss',
       'style-theme-nature':   './resource/styles/scss/theme/nature.scss',
+      'style-theme-mono-blue':   './resource/styles/scss/theme/mono-blue.scss',
       'style-presentation':   './resource/styles/scss/style-presentation.scss',
       'style-presentation':   './resource/styles/scss/style-presentation.scss',
     },
     },
     externals: {
     externals: {
@@ -41,6 +43,12 @@ module.exports = function(options) {
     resolve: {
     resolve: {
       extensions: ['.js', '.json'],
       extensions: ['.js', '.json'],
       modules: [helpers.root('src'), helpers.root('node_modules')],
       modules: [helpers.root('src'), helpers.root('node_modules')],
+      alias: {
+        '@root': path.resolve(__dirname, '../'),
+        '@alias/logger': path.resolve(__dirname, '../lib/service/logger'),
+        // replace bunyan
+        'bunyan': 'browser-bunyan',
+      }
     },
     },
     module: {
     module: {
       rules: [
       rules: [
@@ -111,4 +119,4 @@ module.exports = function(options) {
 
 
     ]
     ]
   };
   };
-}
+};

+ 1 - 1
lib/crowi/dev.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:crowi:dev');
+const debug = require('debug')('growi:crowi:dev');
 const fs = require('fs');
 const fs = require('fs');
 const path = require('path');
 const path = require('path');
 
 

+ 1 - 1
lib/crowi/express-init.js

@@ -1,7 +1,7 @@
 'use strict';
 'use strict';
 
 
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
-  var debug = require('debug')('crowi:crowi:express-init')
+  var debug = require('debug')('growi:crowi:express-init')
     , path           = require('path')
     , path           = require('path')
     , express        = require('express')
     , express        = require('express')
     , bodyParser     = require('body-parser')
     , bodyParser     = require('body-parser')

+ 0 - 20
lib/crowi/helpers.js

@@ -1,20 +0,0 @@
-/**
- * @author: @AngularClass
- * @author: Yuki Takei <yuki@weseek.co.jp>
- */
-
-var path = require('path');
-
-const EVENT = process.env.npm_lifecycle_event || '';
-
-// Helper functions
-var ROOT = path.resolve(__dirname, '..');
-
-function hasProcessFlag(flag) {
-  return process.argv.join('').indexOf(flag) > -1;
-}
-
-var root = path.join.bind(path, ROOT);
-
-exports.hasProcessFlag = hasProcessFlag;
-exports.root = root;

+ 62 - 85
lib/crowi/index.js

@@ -1,27 +1,22 @@
 'use strict';
 'use strict';
 
 
 
 
-var debug = require('debug')('crowi:crowi')
-  , pkg = require('../../package.json')
+var debug = require('debug')('growi:crowi')
+  , logger = require('@alias/logger')('growi:crowi')
+  , pkg = require('@root/package.json')
   , path = require('path')
   , path = require('path')
-  , fs = require('fs')
   , sep = path.sep
   , sep = path.sep
 
 
   , mongoose    = require('mongoose')
   , mongoose    = require('mongoose')
 
 
   , eazyLogger = require('eazy-logger')
   , eazyLogger = require('eazy-logger')
-  , helpers = require('./helpers')
   , models = require('../models')
   , models = require('../models')
   ;
   ;
 
 
-function Crowi (rootdir, env)
-{
+function Crowi(rootdir, env) {
   var self = this;
   var self = this;
-  // this.logger = easyLogger.Logger({
-  //   prefix: '[{green:GROWI}]'
-  // });
   this.logger = eazyLogger.Logger({
   this.logger = eazyLogger.Logger({
-    prefix: "[{green:GROWI}] ",
+    prefix: '[{green:GROWI}] ',
     useLevelPrefixes: false,
     useLevelPrefixes: false,
   });
   });
 
 
@@ -52,9 +47,6 @@ function Crowi (rootdir, env)
 
 
   this.env = env;
   this.env = env;
   this.node_env = this.env.NODE_ENV || 'development';
   this.node_env = this.env.NODE_ENV || 'development';
-  if (helpers.hasProcessFlag('prod') || helpers.hasProcessFlag('production')) {
-    this.node_env = process.env.NODE_ENV = 'production';
-  }
 
 
   this.port = this.env.PORT || 3000;
   this.port = this.env.PORT || 3000;
 
 
@@ -63,9 +55,7 @@ function Crowi (rootdir, env)
     page: new (require(self.eventsDir + 'page'))(this),
     page: new (require(self.eventsDir + 'page'))(this),
   };
   };
 
 
-  if (this.node_env == 'development') {
-  }
-};
+}
 
 
 function getMongoUrl(env) {
 function getMongoUrl(env) {
   return env.MONGOLAB_URI || // for B.C.
   return env.MONGOLAB_URI || // for B.C.
@@ -79,31 +69,31 @@ Crowi.prototype.init = function() {
   var self = this;
   var self = this;
 
 
   return Promise.resolve()
   return Promise.resolve()
-  .then(function() {
-    // setup database server and load all modesl
-    return self.setupDatabase();
-  }).then(function() {
-    return self.setupModels();
-  }).then(function() {
-    return self.setupSessionConfig();
-  }).then(function() {
-    return self.setupAppConfig();
-  }).then(function() {
-    return self.scanRuntimeVersions();
-  }).then(function() {
-    return self.setupPassport();
-  }).then(function() {
-    return self.setupSearcher();
-  }).then(function() {
-    return self.setupMailer();
-  }).then(function() {
-    return self.setupInterceptorManager();
-  }).then(function() {
-    return self.setupSlack();
-  }).then(function() {
-    return self.setupCsrf();
-  });
-}
+    .then(function() {
+      // setup database server and load all modesl
+      return self.setupDatabase();
+    }).then(function() {
+      return self.setupModels();
+    }).then(function() {
+      return self.setupSessionConfig();
+    }).then(function() {
+      return self.setupAppConfig();
+    }).then(function() {
+      return self.scanRuntimeVersions();
+    }).then(function() {
+      return self.setupPassport();
+    }).then(function() {
+      return self.setupSearcher();
+    }).then(function() {
+      return self.setupMailer();
+    }).then(function() {
+      return self.setupInterceptorManager();
+    }).then(function() {
+      return self.setupSlack();
+    }).then(function() {
+      return self.setupCsrf();
+    });
+};
 
 
 Crowi.prototype.isPageId = function(pageId) {
 Crowi.prototype.isPageId = function(pageId) {
   if (!pageId) {
   if (!pageId) {
@@ -157,8 +147,8 @@ Crowi.prototype.setupDatabase = function() {
   return mongoose.connect(mongoUri).then(
   return mongoose.connect(mongoUri).then(
     () => {},
     () => {},
     err => {
     err => {
-      debug('DB Connect Error: ', err);
-      debug('DB Connect Error: ', mongoUri);
+      logger.error('DB Connect Error: ', err);
+      logger.error('DB Connect Error: ', mongoUri);
     }
     }
   );
   );
 };
 };
@@ -217,7 +207,7 @@ Crowi.prototype.setupAppConfig = function() {
       return resolve();
       return resolve();
     });
     });
   });
   });
-}
+};
 
 
 Crowi.prototype.setupModels = function() {
 Crowi.prototype.setupModels = function() {
   var self = this
   var self = this
@@ -248,9 +238,9 @@ Crowi.prototype.scanRuntimeVersions = function() {
       }
       }
       self.runtimeVersions = result;
       self.runtimeVersions = result;
       resolve();
       resolve();
-    })
+    });
   });
   });
-}
+};
 
 
 Crowi.prototype.getSearcher = function() {
 Crowi.prototype.getSearcher = function() {
   return this.searcher;
   return this.searcher;
@@ -262,7 +252,7 @@ Crowi.prototype.getMailer = function() {
 
 
 Crowi.prototype.getInterceptorManager = function() {
 Crowi.prototype.getInterceptorManager = function() {
   return this.interceptorManager;
   return this.interceptorManager;
-}
+};
 
 
 Crowi.prototype.setupPassport = function() {
 Crowi.prototype.setupPassport = function() {
   const config = this.getConfig();
   const config = this.getConfig();
@@ -286,7 +276,7 @@ Crowi.prototype.setupPassport = function() {
   this.passportService.setupLdapStrategy();
   this.passportService.setupLdapStrategy();
 
 
   return Promise.resolve();
   return Promise.resolve();
-}
+};
 
 
 Crowi.prototype.setupSearcher = function() {
 Crowi.prototype.setupSearcher = function() {
   var self = this;
   var self = this;
@@ -299,8 +289,9 @@ Crowi.prototype.setupSearcher = function() {
     if (searcherUri) {
     if (searcherUri) {
       try {
       try {
         self.searcher = new (require(path.join(self.libDir, 'util', 'search')))(self, searcherUri);
         self.searcher = new (require(path.join(self.libDir, 'util', 'search')))(self, searcherUri);
-      } catch (e) {
-        debug('Error on setup searcher', e);
+      }
+      catch (e) {
+        logger.error('Error on setup searcher', e);
         self.searcher = null;
         self.searcher = null;
       }
       }
     }
     }
@@ -333,7 +324,8 @@ Crowi.prototype.setupSlack = function() {
   return new Promise(function(resolve, reject) {
   return new Promise(function(resolve, reject) {
     if (!Config.hasSlackConfig(config)) {
     if (!Config.hasSlackConfig(config)) {
       self.slack = {};
       self.slack = {};
-    } else {
+    }
+    else {
       self.slack = require('../util/slack')(self);
       self.slack = require('../util/slack')(self);
     }
     }
 
 
@@ -343,7 +335,7 @@ Crowi.prototype.setupSlack = function() {
 
 
 Crowi.prototype.setupCsrf = function() {
 Crowi.prototype.setupCsrf = function() {
   var Tokens = require('csrf');
   var Tokens = require('csrf');
-  var tokens = this.tokens = new Tokens();
+  this.tokens = new Tokens();
 
 
   return Promise.resolve();
   return Promise.resolve();
 };
 };
@@ -367,19 +359,19 @@ Crowi.prototype.start = function() {
 
 
   return Promise.resolve()
   return Promise.resolve()
     .then(function() {
     .then(function() {
-      return self.init()
+      return self.init();
     })
     })
     .then(function() {
     .then(function() {
       return self.buildServer();
       return self.buildServer();
     })
     })
     .then(function(app) {
     .then(function(app) {
       server = http.createServer(app).listen(self.port, function() {
       server = http.createServer(app).listen(self.port, function() {
-        debug(`[${self.node_env}] Express server listening on port ${self.port}`);
+        logger.info(`[${self.node_env}] Express server listening on port ${self.port}`);
 
 
         self.logger.info('{bold:Server URLs:}');
         self.logger.info('{bold:Server URLs:}');
-        self.logger.unprefixed('info','{grey:=======================================}');
-        self.logger.unprefixed('info',`         APP: {magenta:http://localhost:${self.port}}`);
-        self.logger.unprefixed('info','{grey:=======================================}');
+        self.logger.unprefixed('info', '{grey:=======================================}');
+        self.logger.unprefixed('info', `         APP: {magenta:http://localhost:${self.port}}`);
+        self.logger.unprefixed('info', '{grey:=======================================}');
 
 
         // setup for dev
         // setup for dev
         if (self.node_env === 'development') {
         if (self.node_env === 'development') {
@@ -388,7 +380,7 @@ Crowi.prototype.start = function() {
       });
       });
 
 
       io = require('socket.io')(server);
       io = require('socket.io')(server);
-      io.sockets.on('connection', function (socket) {
+      io.sockets.on('connection', function(socket) {
       });
       });
       self.io = io;
       self.io = io;
 
 
@@ -421,28 +413,21 @@ Crowi.prototype.buildServer = function() {
     }
     }
   }
   }
 
 
-  if (env == 'development') {
-    //swig.setDefaults({ cache: false });   // moved to dev.js -- 2017.07.09 Yuki Takei
+  // use bunyan
+  if (env == 'production') {
+    const expressBunyanLogger = require('express-bunyan-logger');
+    const logger = require('@alias/logger')('express');
+    app.use(expressBunyanLogger({
+      logger,
+      excludes: ['*'],
+    }));
+  }
+  // use morgan
+  else {
     const morgan = require('morgan');
     const morgan = require('morgan');
     app.use(morgan('dev'));
     app.use(morgan('dev'));
   }
   }
 
 
-  if (env == 'production') {
-    /*
-     * commented out morgan because of using pino  -- 2017.06.27 Yuki Takei
-     *
-    var oneYear = 31557600000;
-    app.use(morgan('combined'));
-    app.use(function (err, req, res, next) {
-      res.status(500);
-      res.render('500', { error: err });
-    });
-     */
-    const pino = require('pino')({extreme: true}, process.stdout);
-    const expressPino = require('express-pino-logger')({pino});
-    app.use(expressPino);
-  }
-
   return Promise.resolve(app);
   return Promise.resolve(app);
 };
 };
 
 
@@ -452,7 +437,7 @@ Crowi.prototype.buildServer = function() {
  */
  */
 Crowi.prototype.setupRoutesAtLast = function(app) {
 Crowi.prototype.setupRoutesAtLast = function(app) {
   require('../routes')(this, app);
   require('../routes')(this, app);
-}
+};
 
 
 /**
 /**
  * require API for plugins
  * require API for plugins
@@ -464,14 +449,6 @@ Crowi.prototype.setupRoutesAtLast = function(app) {
  */
  */
 Crowi.prototype.require = function(modulePath) {
 Crowi.prototype.require = function(modulePath) {
   return require(modulePath);
   return require(modulePath);
-}
-
-Crowi.prototype.exitOnError = function(err) {
-  debug('Critical error occured.');
-  console.error(err);
-  console.error(err.stack);
-  process.exit(1);
 };
 };
 
 
-
 module.exports = Crowi;
 module.exports = Crowi;

+ 1 - 1
lib/events/page.js

@@ -1,4 +1,4 @@
-var debug = require('debug')('crowi:events:page');
+var debug = require('debug')('growi:events:page');
 var util = require('util');
 var util = require('util');
 var events = require('events');
 var events = require('events');
 
 

+ 1 - 1
lib/events/user.js

@@ -1,4 +1,4 @@
-var debug = require('debug')('crowi:events:user');
+var debug = require('debug')('growi:events:user');
 var util = require('util');
 var util = require('util');
 var events = require('events');
 var events = require('events');
 
 

+ 3 - 3
lib/locales/en-US/sandbox.md

@@ -232,7 +232,7 @@ ___
 
 
 ```
 ```
 [/Sandbox]
 [/Sandbox]
-</user/admin1>
+&lt;/user/admin1>
 ```
 ```
 
 
 [/Sandbox]  
 [/Sandbox]  
@@ -240,8 +240,8 @@ ___
 
 
 ## Pukiwiki like linker
 ## Pukiwiki like linker
 
 
-(available by [weseek/crowi-plugin-pukiwiki-like-linker
-](https://github.com/weseek/crowi-plugin-pukiwiki-like-linker) )
+(available by [weseek/growi-plugin-pukiwiki-like-linker
+](https://github.com/weseek/growi-plugin-pukiwiki-like-linker) )
 
 
 最も柔軟な Linker です。  
 最も柔軟な Linker です。  
 記述中のページを基点とした相対リンクと、表示テキストに対するリンクを同時に実現できます。
 記述中のページを基点とした相対リンクと、表示テキストに対するリンクを同時に実現できます。

+ 3 - 3
lib/locales/ja/sandbox.md

@@ -232,7 +232,7 @@ ___
 
 
 ```
 ```
 [/Sandbox]
 [/Sandbox]
-</user/admin1>
+&lt;/user/admin1>
 ```
 ```
 
 
 [/Sandbox]  
 [/Sandbox]  
@@ -240,8 +240,8 @@ ___
 
 
 ## Pukiwiki like linker
 ## Pukiwiki like linker
 
 
-(available by [weseek/crowi-plugin-pukiwiki-like-linker
-](https://github.com/weseek/crowi-plugin-pukiwiki-like-linker) )
+(available by [weseek/growi-plugin-pukiwiki-like-linker
+](https://github.com/weseek/growi-plugin-pukiwiki-like-linker) )
 
 
 最も柔軟な Linker です。  
 最も柔軟な Linker です。  
 記述中のページを基点とした相対リンクと、表示テキストに対するリンクを同時に実現できます。
 記述中のページを基点とした相対リンクと、表示テキストに対するリンクを同時に実現できます。

+ 1 - 1
lib/models/attachment.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:attachment')
+  var debug = require('debug')('growi:models:attachment')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId
     , fileUploader = require('../util/fileUploader')(crowi)
     , fileUploader = require('../util/fileUploader')(crowi)

+ 1 - 1
lib/models/bookmark.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:bookmark')
+  var debug = require('debug')('growi:models:bookmark')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId
     , bookmarkSchema;
     , bookmarkSchema;

+ 1 - 1
lib/models/comment.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:comment')
+  var debug = require('debug')('growi:models:comment')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId
     , USER_PUBLIC_FIELDS = '_id image isGravatarEnabled googleId name username email status createdAt' // TODO: どこか別の場所へ...
     , USER_PUBLIC_FIELDS = '_id image isGravatarEnabled googleId name username email status createdAt' // TODO: どこか別の場所へ...

+ 1 - 1
lib/models/config.js

@@ -1,6 +1,6 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
   var mongoose = require('mongoose')
   var mongoose = require('mongoose')
-    , debug = require('debug')('crowi:models:config')
+    , debug = require('debug')('growi:models:config')
     , uglifycss = require('uglifycss')
     , uglifycss = require('uglifycss')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId
     , configSchema
     , configSchema

+ 1 - 1
lib/models/external-account.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:models:external-account');
+const debug = require('debug')('growi:models:external-account');
 const mongoose = require('mongoose');
 const mongoose = require('mongoose');
 const mongoosePaginate = require('mongoose-paginate');
 const mongoosePaginate = require('mongoose-paginate');
 const uniqueValidator = require('mongoose-unique-validator');
 const uniqueValidator = require('mongoose-unique-validator');

+ 1 - 1
lib/models/page-group-relation.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:models:pageGroupRelation');
+const debug = require('debug')('growi:models:pageGroupRelation');
 const mongoose = require('mongoose');
 const mongoose = require('mongoose');
 const mongoosePaginate = require('mongoose-paginate');
 const mongoosePaginate = require('mongoose-paginate');
 const ObjectId = mongoose.Schema.Types.ObjectId;
 const ObjectId = mongoose.Schema.Types.ObjectId;

+ 1 - 1
lib/models/page.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:page')
+  var debug = require('debug')('growi:models:page')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , escapeStringRegexp = require('escape-string-regexp')
     , escapeStringRegexp = require('escape-string-regexp')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId

+ 1 - 1
lib/models/revision.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:revision')
+  var debug = require('debug')('growi:models:revision')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , Xss = require('../util/xss')
     , Xss = require('../util/xss')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId

+ 1 - 1
lib/models/updatePost.js

@@ -2,7 +2,7 @@
  * This is the setting for notify to 3rd party tool (like Slack).
  * This is the setting for notify to 3rd party tool (like Slack).
  */
  */
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:updatePost')
+  var debug = require('debug')('growi:models:updatePost')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , ObjectId = mongoose.Schema.Types.ObjectId
   ;
   ;

+ 1 - 1
lib/models/user-group-relation.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:models:userGroupRelation');
+const debug = require('debug')('growi:models:userGroupRelation');
 const mongoose = require('mongoose');
 const mongoose = require('mongoose');
 const mongoosePaginate = require('mongoose-paginate');
 const mongoosePaginate = require('mongoose-paginate');
 const ObjectId = mongoose.Schema.Types.ObjectId;
 const ObjectId = mongoose.Schema.Types.ObjectId;

+ 1 - 1
lib/models/user-group.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:models:userGroup');
+const debug = require('debug')('growi:models:userGroup');
 const mongoose = require('mongoose');
 const mongoose = require('mongoose');
 const mongoosePaginate = require('mongoose-paginate');
 const mongoosePaginate = require('mongoose-paginate');
 const ObjectId = mongoose.Schema.Types.ObjectId;
 const ObjectId = mongoose.Schema.Types.ObjectId;

+ 1 - 1
lib/models/user.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
-  var debug = require('debug')('crowi:models:user')
+  var debug = require('debug')('growi:models:user')
     , mongoose = require('mongoose')
     , mongoose = require('mongoose')
     , mongoosePaginate = require('mongoose-paginate')
     , mongoosePaginate = require('mongoose-paginate')
     , uniqueValidator = require('mongoose-unique-validator')
     , uniqueValidator = require('mongoose-unique-validator')

+ 3 - 4
lib/plugins/plugin.service.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:plugins:PluginService');
+const logger = require('@alias/logger')('growi:plugins:PluginService');
 const PluginUtils = require('./plugin-utils');
 const PluginUtils = require('./plugin-utils');
 
 
 class PluginService {
 class PluginService {
@@ -34,12 +34,11 @@ class PluginService {
     switch (meta.pluginSchemaVersion) {
     switch (meta.pluginSchemaVersion) {
       // v1 is deprecated
       // v1 is deprecated
       case 1:
       case 1:
-        console.warn('pluginSchemaVersion 1 is deprecated');
-        debug('pluginSchemaVersion 1 is deprecated');
+        logger.warn('pluginSchemaVersion 1 is deprecated');
         break;
         break;
       // v2 or above
       // v2 or above
       default:
       default:
-        debug(`load plugin '${definition.name}'`);
+        logger.info(`load plugin '${definition.name}'`);
         definition.entries.forEach((entryPath) => {
         definition.entries.forEach((entryPath) => {
           const entry = require(entryPath);
           const entry = require(entryPath);
           entry(this.crowi, this.app);
           entry(this.crowi, this.app);

+ 1 - 1
lib/routes/admin.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:admin')
+  var debug = require('debug')('growi:routes:admin')
     , fs = require('fs')
     , fs = require('fs')
     , models = crowi.models
     , models = crowi.models
     , Page = models.Page
     , Page = models.Page

+ 1 - 1
lib/routes/attachment.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routs:attachment')
+  var debug = require('debug')('growi:routs:attachment')
     , Attachment = crowi.model('Attachment')
     , Attachment = crowi.model('Attachment')
     , User = crowi.model('User')
     , User = crowi.model('User')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')

+ 1 - 1
lib/routes/bookmark.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:bookmark')
+  var debug = require('debug')('growi:routes:bookmark')
     , Bookmark = crowi.model('Bookmark')
     , Bookmark = crowi.model('Bookmark')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')
     , User = crowi.model('User')
     , User = crowi.model('User')

+ 1 - 1
lib/routes/comment.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routs:comment')
+  var debug = require('debug')('growi:routs:comment')
     , Comment = crowi.model('Comment')
     , Comment = crowi.model('Comment')
     , User = crowi.model('User')
     , User = crowi.model('User')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')

+ 1 - 1
lib/routes/installer.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:installer')
+  var debug = require('debug')('growi:routes:installer')
     , path = require('path')
     , path = require('path')
     , fs = require('graceful-fs')
     , fs = require('graceful-fs')
     , models = crowi.models
     , models = crowi.models

+ 1 - 1
lib/routes/login-passport.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:login-passport')
+  var debug = require('debug')('growi:routes:login-passport')
     , passport = require('passport')
     , passport = require('passport')
     , config = crowi.getConfig()
     , config = crowi.getConfig()
     , Config = crowi.model('Config')
     , Config = crowi.model('Config')

+ 1 - 1
lib/routes/login.js

@@ -2,7 +2,7 @@ module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
   var googleapis = require('googleapis')
   var googleapis = require('googleapis')
-    , debug = require('debug')('crowi:routes:login')
+    , debug = require('debug')('growi:routes:login')
     , async    = require('async')
     , async    = require('async')
     , passport = require('passport')
     , passport = require('passport')
     , config = crowi.getConfig()
     , config = crowi.getConfig()

+ 1 - 1
lib/routes/me.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:me')
+  var debug = require('debug')('growi:routes:me')
     , fs = require('fs')
     , fs = require('fs')
     , models = crowi.models
     , models = crowi.models
     , config = crowi.getConfig()
     , config = crowi.getConfig()

+ 1 - 1
lib/routes/page.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:page')
+  var debug = require('debug')('growi:routes:page')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')
     , User = crowi.model('User')
     , User = crowi.model('User')
     , Config   = crowi.model('Config')
     , Config   = crowi.model('Config')

+ 1 - 1
lib/routes/revision.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:revision')
+  var debug = require('debug')('growi:routes:revision')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')
     , Revision = crowi.model('Revision')
     , Revision = crowi.model('Revision')
     , ApiResponse = require('../util/apiResponse')
     , ApiResponse = require('../util/apiResponse')

+ 1 - 1
lib/routes/search.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:routes:search')
+  var debug = require('debug')('growi:routes:search')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')
     , User = crowi.model('User')
     , User = crowi.model('User')
     , ApiResponse = require('../util/apiResponse')
     , ApiResponse = require('../util/apiResponse')

+ 11 - 0
lib/service/logger/alias-for-debug.js

@@ -0,0 +1,11 @@
+/**
+ * return 'debug' method of bunyan logger
+ *
+ * This is supposed to be used as an replacement of "require('debug')"
+ *
+ * @param {string} name
+ */
+module.exports = (name) => {
+  const bunyanLogger = require('./index')(name);
+  return bunyanLogger.debug.bind(bunyanLogger);
+};

+ 48 - 0
lib/service/logger/index.js

@@ -0,0 +1,48 @@
+const bunyan = require('bunyan');   // will be replaced to browser-bunyan on browser by webpack
+const minimatch = require('minimatch');
+
+const isBrowser = typeof window !== 'undefined';
+const isProd = process.env.NODE_ENV === 'production';
+
+const config = require('@root/config').logger;
+
+let stream = isProd ? require('./stream.prod') : require('./stream.dev');
+
+// logger store
+let loggers = {};
+
+/**
+ * determine logger level
+ * @param {string} name Logger name
+ */
+function determineLoggerLevel(name) {
+  if (isBrowser && isProd) {
+    'error';
+  }
+
+  let level = config.default;
+
+  // retrieve configured level
+  Object.keys(config).some(key => { // breakable forEach
+    // test whether 'name' matches to 'key'(blob)
+    if (minimatch(name, key)) {
+      level = config[key];
+      return;                       // break if match
+    }
+  });
+
+  return level;
+}
+
+module.exports = (name) => {
+  // create logger instance if absent
+  if (loggers[name] == null) {
+    loggers[name] = bunyan.createLogger({
+      name,
+      stream,
+      level: determineLoggerLevel(name),
+    });
+  }
+
+  return loggers[name];
+};

+ 16 - 0
lib/service/logger/stream.dev.js

@@ -0,0 +1,16 @@
+const isBrowser = typeof window !== 'undefined';
+
+let stream = undefined;
+
+// browser settings
+if (isBrowser) {
+  const ConsoleFormattedStream = require('@browser-bunyan/console-formatted-stream').ConsoleFormattedStream;
+  stream = new ConsoleFormattedStream();
+}
+// node settings
+else {
+  const bunyanFormat = require('bunyan-format');
+  stream = bunyanFormat({ outputMode: 'short' });
+}
+
+module.exports = stream;

+ 20 - 0
lib/service/logger/stream.prod.js

@@ -0,0 +1,20 @@
+const isBrowser = typeof window !== 'undefined';
+
+let stream = undefined;
+
+// browser settings
+if (isBrowser) {
+  const ConsoleFormattedStream = require('@browser-bunyan/console-formatted-stream').ConsoleFormattedStream;
+  stream = new ConsoleFormattedStream();
+}
+// node settings
+else {
+  const isFormat = !(process.env.FORMAT_NODE_LOG === 'false');
+
+  if (isFormat) {
+    const bunyanFormat = require('bunyan-format');
+    stream = bunyanFormat({ outputMode: 'long' });
+  }
+}
+
+module.exports = stream;

+ 1 - 1
lib/service/passport.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:service:PassportService');
+const debug = require('debug')('growi:service:PassportService');
 const passport = require('passport');
 const passport = require('passport');
 const LocalStrategy = require('passport-local').Strategy;
 const LocalStrategy = require('passport-local').Strategy;
 const LdapStrategy = require('passport-ldapauth');
 const LdapStrategy = require('passport-ldapauth');

+ 1 - 1
lib/util/fileUploader.js

@@ -5,7 +5,7 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:lib:fileUploader')
+  var debug = require('debug')('growi:lib:fileUploader')
     , method = crowi.env.FILE_UPLOAD || 'aws'
     , method = crowi.env.FILE_UPLOAD || 'aws'
     , lib = '../../local_modules/crowi-fileupload-' + method;
     , lib = '../../local_modules/crowi-fileupload-' + method;
 
 

+ 1 - 1
lib/util/googleAuth.js

@@ -7,7 +7,7 @@ module.exports = function(config) {
 
 
   const { GoogleApis } = require('googleapis');
   const { GoogleApis } = require('googleapis');
   var google = new GoogleApis()
   var google = new GoogleApis()
-    , debug = require('debug')('crowi:lib:googleAuth')
+    , debug = require('debug')('growi:lib:googleAuth')
     , lib = {}
     , lib = {}
     ;
     ;
 
 

+ 9 - 9
lib/util/interceptor-manager.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi:InterceptorManager')
+const logger = require('@alias/logger')('growi:InterceptorManager');
 
 
 /**
 /**
  * the manager class of Interceptor
  * the manager class of Interceptor
@@ -23,7 +23,7 @@ class InterceptorManager {
    */
    */
   addInterceptors(interceptors) {
   addInterceptors(interceptors) {
     const interceptorIds = interceptors.map((i) => i.getId());
     const interceptorIds = interceptors.map((i) => i.getId());
-    debug(`adding interceptors '${interceptorIds}'`);
+    logger.debug(`adding interceptors '${interceptorIds}'`);
     this.interceptors = this.interceptors.concat(interceptors);
     this.interceptors = this.interceptors.concat(interceptors);
   }
   }
 
 
@@ -34,7 +34,7 @@ class InterceptorManager {
    * @param {any} args
    * @param {any} args
    */
    */
   process(contextName, ...args) {
   process(contextName, ...args) {
-    debug(`processing the context '${contextName}'`);
+    logger.debug(`processing the context '${contextName}'`);
 
 
     // filter only contexts matches to specified 'contextName'
     // filter only contexts matches to specified 'contextName'
     const matchInterceptors = this.interceptors.filter((i) => i.isInterceptWhen(contextName));
     const matchInterceptors = this.interceptors.filter((i) => i.isInterceptWhen(contextName));
@@ -42,8 +42,8 @@ class InterceptorManager {
     const parallels = matchInterceptors.filter((i) => i.isProcessableParallel());
     const parallels = matchInterceptors.filter((i) => i.isProcessableParallel());
     const sequentials = matchInterceptors.filter((i) => !i.isProcessableParallel());
     const sequentials = matchInterceptors.filter((i) => !i.isProcessableParallel());
 
 
-    debug(`${parallels.length} parallel interceptors found.`);
-    debug(`${sequentials.length} sequencial interceptors found.`);
+    logger.debug(`${parallels.length} parallel interceptors found.`);
+    logger.debug(`${sequentials.length} sequencial interceptors found.`);
 
 
     return Promise.all(
     return Promise.all(
       // parallel
       // parallel
@@ -57,7 +57,7 @@ class InterceptorManager {
         }, Promise.resolve(...args)/* initial Promise */)
         }, Promise.resolve(...args)/* initial Promise */)
       ])
       ])
     ).then(() => {
     ).then(() => {
-      debug(`end processing the context '${contextName}'`);
+      logger.debug(`end processing the context '${contextName}'`);
       return;
       return;
     });
     });
   }
   }
@@ -65,12 +65,12 @@ class InterceptorManager {
   doProcess(interceptor, contextName, ...args) {
   doProcess(interceptor, contextName, ...args) {
     return interceptor.process(contextName, ...args)
     return interceptor.process(contextName, ...args)
       .then((...results) => {
       .then((...results) => {
-        debug(`processing '${interceptor.getId()}' in the context '${contextName}'`);
+        logger.debug(`processing '${interceptor.getId()}' in the context '${contextName}'`);
         return Promise.resolve(...results);
         return Promise.resolve(...results);
       })
       })
       .catch((reason) => {
       .catch((reason) => {
-        debug(`failed when processing '${interceptor.getId()}' in the context '${contextName}'`);
-        debug(reason);
+        logger.debug(`failed when processing '${interceptor.getId()}' in the context '${contextName}'`);
+        logger.debug(reason);
         return Promise.resolve(...args);
         return Promise.resolve(...args);
       });
       });
   }
   }

+ 1 - 1
lib/util/mailer.js

@@ -5,7 +5,7 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:lib:mailer')
+  var debug = require('debug')('growi:lib:mailer')
     , nodemailer = require('nodemailer')
     , nodemailer = require('nodemailer')
     , swig = require('swig-templates')
     , swig = require('swig-templates')
     , Config = crowi.model('Config')
     , Config = crowi.model('Config')

+ 1 - 1
lib/util/middlewares.js

@@ -1,4 +1,4 @@
-var debug = require('debug')('crowi:lib:middlewares');
+var debug = require('debug')('growi:lib:middlewares');
 var md5 = require('md5');
 var md5 = require('md5');
 
 
 exports.csrfKeyGenerator = function(crowi, app) {
 exports.csrfKeyGenerator = function(crowi, app) {

+ 1 - 1
lib/util/search.js

@@ -3,7 +3,7 @@
  */
  */
 
 
 var elasticsearch = require('elasticsearch'),
 var elasticsearch = require('elasticsearch'),
-  debug = require('debug')('crowi:lib:search');
+  debug = require('debug')('growi:lib:search');
 
 
 function SearchClient(crowi, esUri) {
 function SearchClient(crowi, esUri) {
   this.DEFAULT_OFFSET = 0;
   this.DEFAULT_OFFSET = 0;

+ 1 - 1
lib/util/slack.js

@@ -7,7 +7,7 @@ module.exports = function(crowi) {
 
 
   const SLACK_URL = 'https://slack.com';
   const SLACK_URL = 'https://slack.com';
 
 
-  const debug = require('debug')('crowi:util:slack'),
+  const debug = require('debug')('growi:util:slack'),
     config = crowi.getConfig(),
     config = crowi.getConfig(),
     Config = crowi.model('Config'),
     Config = crowi.model('Config'),
     Slack = require('slack-node'),
     Slack = require('slack-node'),

+ 1 - 1
lib/util/swigFunctions.js

@@ -1,5 +1,5 @@
 module.exports = function(crowi, app, req, locals) {
 module.exports = function(crowi, app, req, locals) {
-  var debug = require('debug')('crowi:lib:swigFunctions')
+  var debug = require('debug')('growi:lib:swigFunctions')
     , Page = crowi.model('Page')
     , Page = crowi.model('Page')
     , Config = crowi.model('Config')
     , Config = crowi.model('Config')
     , User = crowi.model('User')
     , User = crowi.model('User')

+ 1 - 0
lib/views/admin/customize.html

@@ -68,6 +68,7 @@
             <div class="d-flex">
             <div class="d-flex">
               {% include 'widget/theme-colorbox.html' with { name: 'default',  bg: '#ffffff', topbar: '#334455', theme: '#112744' } %}
               {% include 'widget/theme-colorbox.html' with { name: 'default',  bg: '#ffffff', topbar: '#334455', theme: '#112744' } %}
               {% include 'widget/theme-colorbox.html' with { name: 'nature',   bg: '#f9fff3', topbar: '#118050', theme: '#460039' } %}
               {% include 'widget/theme-colorbox.html' with { name: 'nature',   bg: '#f9fff3', topbar: '#118050', theme: '#460039' } %}
+              {% include 'widget/theme-colorbox.html' with { name: 'mono-blue',   bg: '#F7FBFD', topbar: '#00587A', theme: '#00587A' } %}
             </div>
             </div>
             {# Dark Themes #}
             {# Dark Themes #}
             <div class="d-flex">
             <div class="d-flex">

+ 15 - 11
lib/views/modal/unportalize.html

@@ -32,17 +32,21 @@
             </div>
             </div>
         </div>
         </div>
         <div class="modal-footer">
         <div class="modal-footer">
-          <p class="pull-left text-left">
-            <small id="newPageNameCheck"></small>
-            <br>
-            <span id="linkToNewPage"></span>
-          </p>
-          <input type="hidden" name="_csrf" value="{{ csrf() }}">
-          <input type="hidden" name="path" value="{{ page.path }}">
-          <input type="hidden" class="form-control" name="new_path" id="newPageName" value="{{ unportalizedPath }}">
-          <input type="hidden" name="page_id" value="{{ page._id.toString() }}">
-          <input type="hidden" name="revision_id" value="{{ page.revision._id.toString() }}">
-          <button type="submit" class="btn btn-warning">Unportalize</button>
+          <div class="d-flex justify-content-between">
+            <p>
+              <span class="text-danger msg-already-exists">
+                <strong><i class="icon-fw icon-ban"></i>{{ t('Page is already exists.') }}</strong>
+              </span>
+              <small id="linkToNewPage" class="msg-already-exists"></small>
+            </p>
+            <div>
+              <input type="hidden" name="_csrf" value="{{ csrf() }}">
+              <input type="hidden" name="path" value="{{ page.path }}">
+              <input type="hidden" class="form-control" name="new_path" id="newPageName" value="{{ unportalizedPath }}">
+              <input type="hidden" name="page_id" value="{{ page._id.toString() }}">
+              <input type="hidden" name="revision_id" value="{{ page.revision._id.toString() }}">
+              <button type="submit" class="btn btn-warning">Unportalize</button>
+            </div>
         </div>
         </div>
 
 
       </form>
       </form>

+ 1 - 1
local_modules/crowi-fileupload-aws/index.js

@@ -6,7 +6,7 @@ module.exports = function(crowi) {
   var aws = require('aws-sdk')
   var aws = require('aws-sdk')
     , fs = require('fs')
     , fs = require('fs')
     , path = require('path')
     , path = require('path')
-    , debug = require('debug')('crowi:lib:fileUploaderAws')
+    , debug = require('debug')('growi:lib:fileUploaderAws')
     , lib = {}
     , lib = {}
     , getAwsConfig = function() {
     , getAwsConfig = function() {
         var config = crowi.getConfig();
         var config = crowi.getConfig();

+ 1 - 1
local_modules/crowi-fileupload-local/index.js

@@ -3,7 +3,7 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:lib:fileUploaderLocal')
+  var debug = require('debug')('growi:lib:fileUploaderLocal')
     , fs = require('fs')
     , fs = require('fs')
     , path = require('path')
     , path = require('path')
     , mkdir = require('mkdirp')
     , mkdir = require('mkdirp')

+ 1 - 1
local_modules/crowi-fileupload-none/index.js

@@ -3,7 +3,7 @@
 module.exports = function(crowi) {
 module.exports = function(crowi) {
   'use strict';
   'use strict';
 
 
-  var debug = require('debug')('crowi:lib:fileUploaderNone')
+  var debug = require('debug')('growi:lib:fileUploaderNone')
     , Config = crowi.model('Config')
     , Config = crowi.model('Config')
     , config = crowi.getConfig()
     , config = crowi.getConfig()
     , lib = {};
     , lib = {};

+ 14 - 7
package.json

@@ -39,7 +39,7 @@
     "postserver:prod:container": "echo ---------------------------------------- && echo [WARNING] && echo   'server:prod:container' is deprecated. && echo   Please use 'sever:prod' && echo ----------------------------------------",
     "postserver:prod:container": "echo ---------------------------------------- && echo [WARNING] && echo   'server:prod:container' is deprecated. && echo   Please use 'sever:prod' && echo ----------------------------------------",
     "server:dev": "env-cmd config/env.dev.js node-dev --respawn app.js",
     "server:dev": "env-cmd config/env.dev.js node-dev --respawn app.js",
     "server:prod:container": "npm run server:prod",
     "server:prod:container": "npm run server:prod",
-    "server:prod": "env-cmd config/env.prod.js node app.js --production | pino-clf common",
+    "server:prod": "env-cmd config/env.prod.js node app.js",
     "server": "npm run server:dev",
     "server": "npm run server:dev",
     "start": "npm run server:prod",
     "start": "npm run server:prod",
     "test": "mocha --timeout 10000 -r test/bootstrap.js test/**/*.js",
     "test": "mocha --timeout 10000 -r test/bootstrap.js test/**/*.js",
@@ -61,6 +61,10 @@
     "body-parser": "^1.18.2",
     "body-parser": "^1.18.2",
     "bootstrap-sass": "~3.3.6",
     "bootstrap-sass": "~3.3.6",
     "bootstrap-select": "^1.12.4",
     "bootstrap-select": "^1.12.4",
+    "browser-bunyan": "^1.3.0",
+    "bunyan": "^1.8.12",
+    "bunyan-debug": "^2.0.0",
+    "bunyan-format": "^0.2.1",
     "check-node-version": "^3.1.1",
     "check-node-version": "^3.1.1",
     "codemirror": "^5.37.0",
     "codemirror": "^5.37.0",
     "connect-flash": "~0.1.1",
     "connect-flash": "~0.1.1",
@@ -72,7 +76,6 @@
     "css-loader": "^0.28.0",
     "css-loader": "^0.28.0",
     "csv-to-markdown-table": "^0.4.0",
     "csv-to-markdown-table": "^0.4.0",
     "date-fns": "^1.29.0",
     "date-fns": "^1.29.0",
-    "debug": "^3.1.0",
     "diff": "^3.3.0",
     "diff": "^3.3.0",
     "diff2html": "^2.3.3",
     "diff2html": "^2.3.3",
     "eazy-logger": "^3.0.2",
     "eazy-logger": "^3.0.2",
@@ -81,8 +84,8 @@
     "env-cmd": "^8.0.1",
     "env-cmd": "^8.0.1",
     "escape-string-regexp": "^1.0.5",
     "escape-string-regexp": "^1.0.5",
     "express": "^4.16.1",
     "express": "^4.16.1",
+    "express-bunyan-logger": "^1.3.3",
     "express-form": "~0.12.0",
     "express-form": "~0.12.0",
-    "express-pino-logger": "^3.0.1",
     "express-sanitizer": "^1.0.4",
     "express-sanitizer": "^1.0.4",
     "express-session": "~1.15.0",
     "express-session": "~1.15.0",
     "express-webpack-assets": "^0.1.0",
     "express-webpack-assets": "^0.1.0",
@@ -106,12 +109,13 @@
     "markdown-it-named-headers": "^0.0.4",
     "markdown-it-named-headers": "^0.0.4",
     "markdown-it-plantuml": "^1.0.0",
     "markdown-it-plantuml": "^1.0.0",
     "markdown-it-task-lists": "^2.1.0",
     "markdown-it-task-lists": "^2.1.0",
-    "markdown-it-toc-and-anchor-with-slugid": "^1.1.2",
+    "markdown-it-toc-and-anchor-with-slugid": "^1.1.3",
     "markdown-table": "^1.1.1",
     "markdown-table": "^1.1.1",
     "md5": "^2.2.1",
     "md5": "^2.2.1",
     "method-override": "^2.3.10",
     "method-override": "^2.3.10",
     "metismenu": "^2.7.4",
     "metismenu": "^2.7.4",
     "mkdirp": "~0.5.1",
     "mkdirp": "~0.5.1",
+    "module-alias": "^2.0.6",
     "mongoose": "^5.0.0",
     "mongoose": "^5.0.0",
     "mongoose-paginate": "^5.0.0",
     "mongoose-paginate": "^5.0.0",
     "mongoose-unique-validator": "^2.0.0",
     "mongoose-unique-validator": "^2.0.0",
@@ -125,7 +129,6 @@
     "passport": "^0.4.0",
     "passport": "^0.4.0",
     "passport-ldapauth": "^2.0.0",
     "passport-ldapauth": "^2.0.0",
     "passport-local": "^1.0.0",
     "passport-local": "^1.0.0",
-    "pino-clf": "^1.0.2",
     "plantuml-encoder": "^1.2.5",
     "plantuml-encoder": "^1.2.5",
     "postcss-loader": "^2.1.3",
     "postcss-loader": "^2.1.3",
     "react": "^16.2.0",
     "react": "^16.2.0",
@@ -148,7 +151,6 @@
     "toastr": "^2.1.2",
     "toastr": "^2.1.2",
     "uglifycss": "^0.0.29",
     "uglifycss": "^0.0.29",
     "url-join": "^4.0.0",
     "url-join": "^4.0.0",
-    "uslug": "^1.0.4",
     "webpack": "3.11.0",
     "webpack": "3.11.0",
     "webpack-bundle-analyzer": "^2.9.0",
     "webpack-bundle-analyzer": "^2.9.0",
     "webpack-merge": "~4.1.0",
     "webpack-merge": "~4.1.0",
@@ -164,13 +166,18 @@
     "eslint": "^4.19.1",
     "eslint": "^4.19.1",
     "eslint-plugin-react": "^7.7.0",
     "eslint-plugin-react": "^7.7.0",
     "mocha": "^5.0.0",
     "mocha": "^5.0.0",
-    "morgan": "^1.8.2",
+    "morgan": "^1.9.0",
     "node-dev": "^3.1.3",
     "node-dev": "^3.1.3",
     "on-headers": "^1.0.1",
     "on-headers": "^1.0.1",
     "sinon": "^5.0.2",
     "sinon": "^5.0.2",
     "sinon-chai": "^3.0.0",
     "sinon-chai": "^3.0.0",
     "webpack-dll-bundles-plugin": "^1.0.0-beta.5"
     "webpack-dll-bundles-plugin": "^1.0.0-beta.5"
   },
   },
+  "_moduleAliases": {
+    "@root": ".",
+    "@alias/logger": "lib/service/logger",
+    "debug": "lib/service/logger/alias-for-debug"
+  },
   "engines": {
   "engines": {
     "node": ">=6.11 <9",
     "node": ">=6.11 <9",
     "npm": ">=4",
     "npm": ">=4",

+ 3 - 0
resource/js/components/PageEditor.js

@@ -373,6 +373,8 @@ export default class PageEditor extends React.Component {
   }
   }
 
 
   render() {
   render() {
+    const emojiStrategy = this.props.crowi.getEmojiStrategy();
+
     return (
     return (
       <div className="row">
       <div className="row">
         <div className="col-md-6 col-sm-12 page-editor-editor-container">
         <div className="col-md-6 col-sm-12 page-editor-editor-container">
@@ -380,6 +382,7 @@ export default class PageEditor extends React.Component {
             editorOptions={this.state.editorOptions}
             editorOptions={this.state.editorOptions}
             isUploadable={this.state.isUploadable}
             isUploadable={this.state.isUploadable}
             isUploadableFile={this.state.isUploadableFile}
             isUploadableFile={this.state.isUploadableFile}
+            emojiStrategy={emojiStrategy}
             onScroll={this.onEditorScroll}
             onScroll={this.onEditorScroll}
             onScrollCursorIntoView={this.onEditorScrollCursorIntoView}
             onScrollCursorIntoView={this.onEditorScrollCursorIntoView}
             onChange={this.onMarkdownChanged}
             onChange={this.onMarkdownChanged}

+ 12 - 2
resource/js/components/PageEditor/Editor.js

@@ -30,7 +30,7 @@ require('codemirror/mode/gfm/gfm');
 import Dropzone from 'react-dropzone';
 import Dropzone from 'react-dropzone';
 
 
 import pasteHelper from './PasteHelper';
 import pasteHelper from './PasteHelper';
-import emojiAutoCompleteHelper from './EmojiAutoCompleteHelper';
+import EmojiAutoCompleteHelper from './EmojiAutoCompleteHelper';
 
 
 import InterceptorManager from '../../../../lib/util/interceptor-manager';
 import InterceptorManager from '../../../../lib/util/interceptor-manager';
 
 
@@ -53,6 +53,7 @@ export default class Editor extends React.Component {
     this.state = {
     this.state = {
       value: this.props.value,
       value: this.props.value,
       dropzoneActive: false,
       dropzoneActive: false,
+      isEnabledEmojiAutoComplete: false,
       isUploading: false,
       isUploading: false,
       isLoadingKeymap: false,
       isLoadingKeymap: false,
     };
     };
@@ -84,6 +85,12 @@ export default class Editor extends React.Component {
     this.renderLoadingKeymapOverlay = this.renderLoadingKeymapOverlay.bind(this);
     this.renderLoadingKeymapOverlay = this.renderLoadingKeymapOverlay.bind(this);
   }
   }
 
 
+  componentWillMount() {
+    if (this.props.emojiStrategy != null) {
+      this.emojiAutoCompleteHelper = new EmojiAutoCompleteHelper(this.props.emojiStrategy);
+      this.setState({isEnabledEmojiAutoComplete: true});
+    }
+  }
 
 
   componentDidMount() {
   componentDidMount() {
     // initialize caret line
     // initialize caret line
@@ -495,7 +502,9 @@ export default class Editor extends React.Component {
               }
               }
 
 
               // Emoji AutoComplete
               // Emoji AutoComplete
-              emojiAutoCompleteHelper.showHint(editor);
+              if (this.state.isEnabledEmojiAutoComplete) {
+                this.emojiAutoCompleteHelper.showHint(editor);
+              }
             }}
             }}
             onDragEnter={this.onDragEnterForCM}
             onDragEnter={this.onDragEnterForCM}
           />
           />
@@ -525,6 +534,7 @@ Editor.propTypes = {
   editorOptions: PropTypes.object,
   editorOptions: PropTypes.object,
   isUploadable: PropTypes.bool,
   isUploadable: PropTypes.bool,
   isUploadableFile: PropTypes.bool,
   isUploadableFile: PropTypes.bool,
+  emojiStrategy: PropTypes.object,
   onChange: PropTypes.func,
   onChange: PropTypes.func,
   onScroll: PropTypes.func,
   onScroll: PropTypes.func,
   onScrollCursorIntoView: PropTypes.func,
   onScrollCursorIntoView: PropTypes.func,

+ 13 - 16
resource/js/components/PageEditor/EmojiAutoCompleteHelper.js

@@ -1,19 +1,19 @@
-import emojiStrategy from '../../util/emojione/emoji_strategy_shrinked.json';
-
 class EmojiAutoCompleteHelper {
 class EmojiAutoCompleteHelper {
 
 
-  constructor() {
-    this.emojiShortnameImageMap = {}
+  constructor(emojiStrategy) {
+    this.emojiStrategy = emojiStrategy;
+
+    this.emojiShortnameImageMap = {};
 
 
     this.initEmojiImageMap = this.initEmojiImageMap.bind(this);
     this.initEmojiImageMap = this.initEmojiImageMap.bind(this);
     this.showHint = this.showHint.bind(this);
     this.showHint = this.showHint.bind(this);
 
 
-    this.initEmojiImageMap()
+    this.initEmojiImageMap();
   }
   }
 
 
   initEmojiImageMap() {
   initEmojiImageMap() {
-    for (let unicode in emojiStrategy) {
-      const data = emojiStrategy[unicode];
+    for (let unicode in this.emojiStrategy) {
+      const data = this.emojiStrategy[unicode];
       const shortname = data.shortname;
       const shortname = data.shortname;
       // add image tag
       // add image tag
       this.emojiShortnameImageMap[shortname] = emojione.shortnameToImage(shortname);
       this.emojiShortnameImageMap[shortname] = emojione.shortnameToImage(shortname);
@@ -26,7 +26,7 @@ class EmojiAutoCompleteHelper {
    */
    */
   showHint(editor) {
   showHint(editor) {
     // see https://regex101.com/r/gy3i03/1
     // see https://regex101.com/r/gy3i03/1
-    const pattern = /:[^:\s]+/
+    const pattern = /:[^:\s]+/;
 
 
     const currentPos = editor.getCursor();
     const currentPos = editor.getCursor();
     // find previous ':shortname'
     // find previous ':shortname'
@@ -77,7 +77,7 @@ class EmojiAutoCompleteHelper {
             `<div class="img-container">${this.emojiShortnameImageMap[shortname]}</div>` +
             `<div class="img-container">${this.emojiShortnameImageMap[shortname]}</div>` +
             `<span class="shortname-container">${shortname}</span>`;
             `<span class="shortname-container">${shortname}</span>`;
         }
         }
-      }
+      };
     });
     });
   }
   }
 
 
@@ -96,8 +96,8 @@ class EmojiAutoCompleteHelper {
     const countLen4 = () => { countLen3() + results4.length; }
     const countLen4 = () => { countLen3() + results4.length; }
     // TODO performance tune
     // TODO performance tune
     // when total length of all results is less than `maxLength`
     // when total length of all results is less than `maxLength`
-    for (let unicode in emojiStrategy) {
-      const data = emojiStrategy[unicode];
+    for (let unicode in this.emojiStrategy) {
+      const data = this.emojiStrategy[unicode];
 
 
       if (maxLength <= countLen1()) { break; }
       if (maxLength <= countLen1()) { break; }
       // prefix match to shortname
       // prefix match to shortname
@@ -122,7 +122,7 @@ class EmojiAutoCompleteHelper {
       else if ((data.keywords != null) && data.keywords.find(elem => elem.indexOf(term) > -1)) {
       else if ((data.keywords != null) && data.keywords.find(elem => elem.indexOf(term) > -1)) {
         results4.push(data.shortname);
         results4.push(data.shortname);
       }
       }
-    };
+    }
 
 
     let results = results1.concat(results2).concat(results3).concat(results4);
     let results = results1.concat(results2).concat(results3).concat(results4);
     results = results.slice(0, maxLength);
     results = results.slice(0, maxLength);
@@ -132,7 +132,4 @@ class EmojiAutoCompleteHelper {
 
 
 }
 }
 
 
-// singleton pattern
-const instance = new EmojiAutoCompleteHelper();
-Object.freeze(this);
-export default instance;
+export default EmojiAutoCompleteHelper;

+ 7 - 6
resource/js/legacy/crowi.js

@@ -238,10 +238,10 @@ $(function() {
     return false;
     return false;
   });
   });
 
 
-  // rename
-  $('#renamePage').on('shown.bs.modal', function (e) {
+  // rename/unportalize
+  $('#renamePage, #unportalize').on('shown.bs.modal', function(e) {
     $('#renamePage #newPageName').focus();
     $('#renamePage #newPageName').focus();
-    $('#renamePage .msg-already-exists').hide();
+    $('#renamePage .msg-already-exists, #unportalize .msg-already-exists').hide();
   });
   });
   $('#renamePageForm, #unportalize-form').submit(function(e) {
   $('#renamePageForm, #unportalize-form').submit(function(e) {
     // create name-value map
     // create name-value map
@@ -255,11 +255,12 @@ $(function() {
       url: '/_api/pages.rename',
       url: '/_api/pages.rename',
       data: $(this).serialize(),
       data: $(this).serialize(),
       dataType: 'json'
       dataType: 'json'
-    }).done(function(res) {
+    })
+    .done(function(res) {
       if (!res.ok) {
       if (!res.ok) {
         // if already exists
         // if already exists
-        $('#renamePage .msg-already-exists').show();
-        $('#renamePage #linkToNewPage').html(`
+        $('#renamePage .msg-already-exists, #unportalize .msg-already-exists').show();
+        $('#renamePage #linkToNewPage, #unportalize #linkToNewPage').html(`
           <a href="${nameValueMap.new_path}">${nameValueMap.new_path} <i class="icon-login"></i></a>
           <a href="${nameValueMap.new_path}">${nameValueMap.new_path} <i class="icon-login"></i></a>
         `);
         `);
       }
       }

+ 8 - 2
resource/js/util/Crowi.js

@@ -2,7 +2,9 @@
  * Crowi context class for client
  * Crowi context class for client
  */
  */
 
 
-import axios from 'axios'
+import axios from 'axios';
+
+import emojiStrategy from './emojione/emoji_strategy_shrinked.json';
 import InterceptorManager from '../../../lib/util/interceptor-manager';
 import InterceptorManager from '../../../lib/util/interceptor-manager';
 
 
 import {
 import {
@@ -54,7 +56,7 @@ export default class Crowi {
   }
   }
 
 
   getContext() {
   getContext() {
-    return context;
+    return this.context;
   }
   }
 
 
   setConfig(config) {
   setConfig(config) {
@@ -69,6 +71,10 @@ export default class Crowi {
     this.pageEditor = pageEditor;
     this.pageEditor = pageEditor;
   }
   }
 
 
+  getEmojiStrategy() {
+    return emojiStrategy;
+  }
+
   recoverData() {
   recoverData() {
     const keys = [
     const keys = [
       'userByName',
       'userByName',

+ 3 - 3
resource/js/util/markdown-it/emoji.js

@@ -1,5 +1,3 @@
-import emojiStrategy from '../emojione/emoji_strategy_shrinked.json';
-
 export default class EmojiConfigurer {
 export default class EmojiConfigurer {
 
 
   constructor(crowi) {
   constructor(crowi) {
@@ -7,11 +5,13 @@ export default class EmojiConfigurer {
   }
   }
 
 
   configure(md) {
   configure(md) {
+    const emojiStrategy = this.crowi.getEmojiStrategy();
+
     const emojiShortnameUnicodeMap = {};
     const emojiShortnameUnicodeMap = {};
 
 
     for (let unicode in emojiStrategy) {
     for (let unicode in emojiStrategy) {
       const data = emojiStrategy[unicode];
       const data = emojiStrategy[unicode];
-      const shortname = data.shortname.replace(/\:/g, '');
+      const shortname = data.shortname.replace(/:/g, '');
       emojiShortnameUnicodeMap[shortname] = String.fromCharCode(unicode);
       emojiShortnameUnicodeMap[shortname] = String.fromCharCode(unicode);
     }
     }
 
 

+ 6 - 17
resource/js/util/markdown-it/toc-and-anchor.js

@@ -1,5 +1,3 @@
-import uslug from 'uslug';
-
 export default class TocAndAnchorConfigurer {
 export default class TocAndAnchorConfigurer {
 
 
   constructor(crowi, renderToc) {
   constructor(crowi, renderToc) {
@@ -9,14 +7,12 @@ export default class TocAndAnchorConfigurer {
 
 
   configure(md) {
   configure(md) {
     md.use(require('markdown-it-toc-and-anchor-with-slugid').default, {
     md.use(require('markdown-it-toc-and-anchor-with-slugid').default, {
-        tocLastLevel: 3,
-        anchorLinkBefore: false,
-        anchorLinkSymbol: '',
-        anchorLinkSymbolClassName: 'icon-link',
-        anchorClassName: 'revision-head-link',
-        slugify: this.customSlugify,
-      })
-      ;
+      tocLastLevel: 3,
+      anchorLinkBefore: false,
+      anchorLinkSymbol: '',
+      anchorLinkSymbolClassName: 'icon-link',
+      anchorClassName: 'revision-head-link',
+    });
 
 
     // set toc render function
     // set toc render function
     if (this.renderToc != null) {
     if (this.renderToc != null) {
@@ -28,11 +24,4 @@ export default class TocAndAnchorConfigurer {
     }
     }
   }
   }
 
 
-  /**
-   * create Base64 encoded id
-   * @param {string} header
-   */
-  customSlugify(header) {
-    return encodeURIComponent(uslug(header.trim()));
-  }
 }
 }

+ 51 - 0
resource/styles/agile-admin/inverse/colors/mono-blue.scss

@@ -0,0 +1,51 @@
+@import '../variables';
+
+$themecolor: #00587A;
+$themelight: #F7FBFD;
+$subthemecolor: #186718;
+
+
+$topbar: $themecolor;
+$sidebar: $themelight;
+$bodycolor: $themelight;
+
+$headingtext: $themecolor;
+$bodytext: $themecolor;
+$linktext: lighten($themecolor,5%);
+$linktext-hover: lighten($linktext, 12%);
+$sidebar-text: $themecolor;
+
+$primary: $themecolor;
+$info: lighten($themecolor,20%);
+
+$logo-mark-fill: lighten(desaturate($topbar, 30%), 20%);
+$wikilinktext: lighten($themecolor, 20%);
+$wikilinktext-hover: lighten($wikilinktext, 20%);
+
+@import 'apply-colors';
+@import 'apply-colors-light';
+
+
+// change color of inline-code (default: red)
+:not(.hljs) > code:not(.hljs) {
+  background-color: lighten($subthemecolor,70%);
+  color: $subthemecolor;
+}
+
+// change color of highlighted header in wiki (default: orange)
+.wiki {
+  .code-line.revision-head.highlighted {
+    background-color: lighten($themecolor,20%);
+    color: $themelight;
+  }
+}
+
+// change color of surrounding border of theme option icon at admin/customize (default: green)
+.admin-page {
+  #themeOptions {
+    a.active {
+      background-color: lighten($themecolor,20%);
+      border-color: lighten($themecolor,20%);
+    }
+  }
+}

+ 8 - 0
resource/styles/scss/theme/mono-blue.scss

@@ -0,0 +1,8 @@
+// import colors
+@import '../../agile-admin/inverse/colors/mono-blue';
+
+// apply agile-admin theme
+@import '../../agile-admin/inverse/style';
+
+// override
+@import 'override-agileadmin';

+ 3 - 1
test/bootstrap.js

@@ -2,6 +2,8 @@
 
 
 process.env.NODE_ENV = 'test';
 process.env.NODE_ENV = 'test';
 
 
+require('module-alias/register');
+
 var express = require('express')
 var express = require('express')
   , ROOT_DIR = __dirname + '/..'
   , ROOT_DIR = __dirname + '/..'
   , MODEL_DIR = __dirname + '/../lib/models'
   , MODEL_DIR = __dirname + '/../lib/models'
@@ -9,7 +11,7 @@ var express = require('express')
   ;
   ;
 
 
 testDBUtil = {
 testDBUtil = {
-  generateFixture: function (conn, model, fixture) {
+  generateFixture: function(conn, model, fixture) {
     if (conn.readyState == 0) {
     if (conn.readyState == 0) {
       return Promise.reject();
       return Promise.reject();
     }
     }

+ 100 - 124
yarn.lock

@@ -2,6 +2,22 @@
 # yarn lockfile v1
 # yarn lockfile v1
 
 
 
 
+"@browser-bunyan/console-formatted-stream@^1.3.0":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-formatted-stream/-/console-formatted-stream-1.3.0.tgz#3dc059aa5c1b2a7a1f26e2706e2bdeb9a09bbe57"
+  dependencies:
+    "@browser-bunyan/levels" "^1.3.0"
+
+"@browser-bunyan/console-raw-stream@^1.3.0":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-raw-stream/-/console-raw-stream-1.3.0.tgz#ccf24b56f2265058297c6517fbecea84ebb7818c"
+  dependencies:
+    "@browser-bunyan/levels" "^1.3.0"
+
+"@browser-bunyan/levels@^1.3.0":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@browser-bunyan/levels/-/levels-1.3.0.tgz#a052303ae5d1a1f9b63eeb3a94495a2f429f4831"
+
 "@sinonjs/formatio@^2.0.0":
 "@sinonjs/formatio@^2.0.0":
   version "2.0.0"
   version "2.0.0"
   resolved "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
   resolved "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
@@ -201,6 +217,10 @@ ansicolors@~0.2.1:
   version "0.2.1"
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef"
   resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef"
 
 
+ansistyles@~0.1.1:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539"
+
 anymatch@^1.3.0:
 anymatch@^1.3.0:
   version "1.3.2"
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
   resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@@ -1045,10 +1065,6 @@ basic-auth-connect@~1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz#fdb0b43962ca7b40456a7c2bb48fe173da2d2122"
   resolved "https://registry.yarnpkg.com/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz#fdb0b43962ca7b40456a7c2bb48fe173da2d2122"
 
 
-basic-auth@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884"
-
 basic-auth@~2.0.0:
 basic-auth@~2.0.0:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba"
   resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba"
@@ -1167,6 +1183,14 @@ brorand@^1.0.1:
   version "1.1.0"
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
   resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
 
 
+browser-bunyan@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/browser-bunyan/-/browser-bunyan-1.3.0.tgz#26378dc58d7a98002cc9bfcfba2ea5d712449992"
+  dependencies:
+    "@browser-bunyan/console-formatted-stream" "^1.3.0"
+    "@browser-bunyan/console-raw-stream" "^1.3.0"
+    "@browser-bunyan/levels" "^1.3.0"
+
 browser-stdout@1.3.0:
 browser-stdout@1.3.0:
   version "1.3.0"
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
   resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
@@ -1323,7 +1347,22 @@ builtin-status-codes@^3.0.0:
   version "3.0.0"
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
   resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
 
 
-bunyan@^1.8.3:
+bunyan-debug@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/bunyan-debug/-/bunyan-debug-2.0.0.tgz#15ba1bdb5d3158781cdd4b9aee70eb80d4c2c81a"
+  dependencies:
+    chalk "^1.1.3"
+    event-stream "^3.3.2"
+
+bunyan-format@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/bunyan-format/-/bunyan-format-0.2.1.tgz#a4b3b0d80070a865279417269e3f00ff02fbcb47"
+  dependencies:
+    ansicolors "~0.2.1"
+    ansistyles "~0.1.1"
+    xtend "~2.1.1"
+
+bunyan@^1.8.12, bunyan@^1.8.3:
   version "1.8.12"
   version "1.8.12"
   resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
   resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
   optionalDependencies:
   optionalDependencies:
@@ -1524,10 +1563,6 @@ classnames@^2.2.0, classnames@^2.2.5:
   version "2.2.5"
   version "2.2.5"
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
 
 
-clf-date@0.0.4:
-  version "0.0.4"
-  resolved "https://registry.yarnpkg.com/clf-date/-/clf-date-0.0.4.tgz#34eec7757095c7b03bd59aa1c3d5120d5f27f39f"
-
 cli-cursor@^2.1.0:
 cli-cursor@^2.1.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
   resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
@@ -2331,12 +2366,6 @@ encoding@^0.1.11:
   dependencies:
   dependencies:
     iconv-lite "~0.4.13"
     iconv-lite "~0.4.13"
 
 
-end-of-stream@^1.1.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
-  dependencies:
-    once "^1.4.0"
-
 engine.io-client@~3.1.0:
 engine.io-client@~3.1.0:
   version "3.1.4"
   version "3.1.4"
   resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.4.tgz#4fcf1370b47163bd2ce9be2733972430350d4ea1"
   resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.4.tgz#4fcf1370b47163bd2ce9be2733972430350d4ea1"
@@ -2626,7 +2655,7 @@ event-emitter@~0.3.5:
     d "1"
     d "1"
     es5-ext "~0.10.14"
     es5-ext "~0.10.14"
 
 
-event-stream@~3.3.0:
+event-stream@^3.3.2, event-stream@~3.3.0:
   version "3.3.4"
   version "3.3.4"
   resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
   resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
   dependencies:
   dependencies:
@@ -2681,6 +2710,16 @@ expand-range@^1.8.1:
   dependencies:
   dependencies:
     fill-range "^2.1.0"
     fill-range "^2.1.0"
 
 
+express-bunyan-logger@^1.3.3:
+  version "1.3.3"
+  resolved "https://registry.yarnpkg.com/express-bunyan-logger/-/express-bunyan-logger-1.3.3.tgz#e76d9b3d598ca83a69b692a9839c7453d01b5010"
+  dependencies:
+    bunyan "^1.8.12"
+    lodash.has "^4.5.2"
+    lodash.set "^4.3.2"
+    useragent "^2.2.1"
+    uuid "^3.1.0"
+
 express-form@~0.12.0:
 express-form@~0.12.0:
   version "0.12.6"
   version "0.12.6"
   resolved "https://registry.yarnpkg.com/express-form/-/express-form-0.12.6.tgz#0fb1049abecba747dbfd2e8e1b1a5a20395715ac"
   resolved "https://registry.yarnpkg.com/express-form/-/express-form-0.12.6.tgz#0fb1049abecba747dbfd2e8e1b1a5a20395715ac"
@@ -2689,12 +2728,6 @@ express-form@~0.12.0:
     object-additions "^0.5.1"
     object-additions "^0.5.1"
     validator "^2.1.0"
     validator "^2.1.0"
 
 
-express-pino-logger@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/express-pino-logger/-/express-pino-logger-3.0.1.tgz#31befe82ed4f1d685d90eeb035923c0c79fe95cc"
-  dependencies:
-    pino-http "^3.0.1"
-
 express-sanitizer@^1.0.4:
 express-sanitizer@^1.0.4:
   version "1.0.4"
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/express-sanitizer/-/express-sanitizer-1.0.4.tgz#5331a12de6577582901a6581e91e38a8b99a6ee2"
   resolved "https://registry.yarnpkg.com/express-sanitizer/-/express-sanitizer-1.0.4.tgz#5331a12de6577582901a6581e91e38a8b99a6ee2"
@@ -2798,10 +2831,6 @@ fast-deep-equal@^1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
   resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
 
 
-fast-json-parse@^1.0.2, fast-json-parse@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d"
-
 fast-json-stable-stringify@^2.0.0:
 fast-json-stable-stringify@^2.0.0:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
   resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
@@ -2810,10 +2839,6 @@ fast-levenshtein@~2.0.4:
   version "2.0.6"
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
 
 
-fast-safe-stringify@^1.0.8, fast-safe-stringify@^1.2.1:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-1.2.2.tgz#eab31cd4dd0dbaa09f64ac6b77e7e7eb9b4a142b"
-
 fastparse@^1.1.1:
 fastparse@^1.1.1:
   version "1.1.1"
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
   resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
@@ -2930,10 +2955,6 @@ flat-cache@^1.2.1:
     graceful-fs "^4.1.2"
     graceful-fs "^4.1.2"
     write "^0.2.1"
     write "^0.2.1"
 
 
-flatstr@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.5.tgz#5b451b08cbd48e2eac54a2bbe0bf46165aa14be3"
-
 flatten@^1.0.2:
 flatten@^1.0.2:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
   resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
@@ -3888,7 +3909,7 @@ json-stable-stringify@^1.0.1:
   dependencies:
   dependencies:
     jsonify "~0.0.0"
     jsonify "~0.0.0"
 
 
-json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
+json-stringify-safe@~5.0.1:
   version "5.0.1"
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
 
 
@@ -4196,6 +4217,10 @@ lodash.get@4.4.2, lodash.get@^4.0.2, lodash.get@^4.4.2:
   version "4.4.2"
   version "4.4.2"
   resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
   resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
 
 
+lodash.has@^4.5.2:
+  version "4.5.2"
+  resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
+
 lodash.isarguments@^3.0.0:
 lodash.isarguments@^3.0.0:
   version "3.1.0"
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
   resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
@@ -4271,6 +4296,10 @@ lodash.restparam@^3.0.0:
   version "3.6.1"
   version "3.6.1"
   resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
   resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
 
 
+lodash.set@^4.3.2:
+  version "4.3.2"
+  resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
+
 lodash.tail@^4.1.1:
 lodash.tail@^4.1.1:
   version "4.1.1"
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
   resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
@@ -4335,6 +4364,13 @@ loud-rejection@^1.0.0:
     currently-unhandled "^0.4.1"
     currently-unhandled "^0.4.1"
     signal-exit "^3.0.0"
     signal-exit "^3.0.0"
 
 
+lru-cache@4.1.x:
+  version "4.1.3"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c"
+  dependencies:
+    pseudomap "^1.0.2"
+    yallist "^2.1.2"
+
 lru-cache@^4.0.1, lru-cache@^4.0.2, lru-cache@^4.1.1:
 lru-cache@^4.0.1, lru-cache@^4.0.2, lru-cache@^4.1.1:
   version "4.1.1"
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
@@ -4396,9 +4432,9 @@ markdown-it-task-lists@^2.1.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.0.tgz#4594f750f70df053d1dad68024388007c1d20783"
   resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.0.tgz#4594f750f70df053d1dad68024388007c1d20783"
 
 
-markdown-it-toc-and-anchor-with-slugid@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/markdown-it-toc-and-anchor-with-slugid/-/markdown-it-toc-and-anchor-with-slugid-1.1.2.tgz#14d293ee530891107a13575407ede0376fb3666e"
+markdown-it-toc-and-anchor-with-slugid@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/markdown-it-toc-and-anchor-with-slugid/-/markdown-it-toc-and-anchor-with-slugid-1.1.3.tgz#31eed7da97c3fc06961a16f07cbffa469cc1a288"
   dependencies:
   dependencies:
     clone "^2.1.0"
     clone "^2.1.0"
     uslug "^1.0.4"
     uslug "^1.0.4"
@@ -4630,6 +4666,10 @@ mocha@^5.0.0:
     mkdirp "0.5.1"
     mkdirp "0.5.1"
     supports-color "4.4.0"
     supports-color "4.4.0"
 
 
+module-alias@^2.0.6:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.0.6.tgz#abb2cfa07014f503514ad5061c6f03d79b591889"
+
 moment@^2.10.6:
 moment@^2.10.6:
   version "2.20.1"
   version "2.20.1"
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
@@ -4695,7 +4735,7 @@ mongoose@^5.0.0:
     regexp-clone "0.0.1"
     regexp-clone "0.0.1"
     sliced "1.0.1"
     sliced "1.0.1"
 
 
-morgan@^1.8.2:
+morgan@^1.9.0:
   version "1.9.0"
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051"
   resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051"
   dependencies:
   dependencies:
@@ -4771,15 +4811,6 @@ ncp@~2.0.0:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
   resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
 
 
-ndjson@^1.4.3:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/ndjson/-/ndjson-1.5.0.tgz#ae603b36b134bcec347b452422b0bf98d5832ec8"
-  dependencies:
-    json-stringify-safe "^5.0.1"
-    minimist "^1.2.0"
-    split2 "^2.1.0"
-    through2 "^2.0.3"
-
 negotiator@0.6.1:
 negotiator@0.6.1:
   version "0.6.1"
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@@ -5062,6 +5093,10 @@ object-keys@~0.2.0:
     indexof "~0.0.1"
     indexof "~0.0.1"
     is "~0.2.6"
     is "~0.2.6"
 
 
+object-keys@~0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336"
+
 object-path@^0.9.0:
 object-path@^0.9.0:
   version "0.9.2"
   version "0.9.2"
   resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5"
   resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5"
@@ -5092,7 +5127,7 @@ on-headers@^1.0.1, on-headers@~1.0.1:
   version "1.0.1"
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7"
   resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7"
 
 
-once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0:
+once@^1.3.0, once@^1.3.3, once@^1.4.0:
   version "1.4.0"
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
   dependencies:
   dependencies:
@@ -5399,45 +5434,6 @@ pinkie@^2.0.0:
   version "2.0.4"
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
 
 
-pino-clf@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/pino-clf/-/pino-clf-1.0.2.tgz#3e8ffea2f4bd07f794570c2daa1e012c17cff6bb"
-  dependencies:
-    fast-json-parse "^1.0.2"
-    minimist "^1.2.0"
-    pino-toke "^1.0.0"
-    pump "^1.0.2"
-    through2 "^2.0.3"
-
-pino-http@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-3.0.1.tgz#015376250968b22f709e1260dcb516b691e27c6d"
-  dependencies:
-    pino "^4.10.2"
-
-pino-toke@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/pino-toke/-/pino-toke-1.0.0.tgz#9c072e17c30dcf564cd560ac392b22a929bf2297"
-  dependencies:
-    basic-auth "^1.1.0"
-    clf-date "0.0.4"
-    minimist "^1.2.0"
-    ndjson "^1.4.3"
-    pump "^1.0.2"
-    through2 "^2.0.1"
-
-pino@^4.10.2:
-  version "4.10.3"
-  resolved "https://registry.yarnpkg.com/pino/-/pino-4.10.3.tgz#d46030524f2294fe43a2e2247ce1a7ef028c46bc"
-  dependencies:
-    chalk "^2.3.0"
-    fast-json-parse "^1.0.3"
-    fast-safe-stringify "^1.2.1"
-    flatstr "^1.0.5"
-    pump "^2.0.0"
-    quick-format-unescaped "^1.1.1"
-    split2 "^2.2.0"
-
 pkg-dir@^2.0.0:
 pkg-dir@^2.0.0:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
   resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
@@ -5843,20 +5839,6 @@ public-encrypt@^4.0.0:
     parse-asn1 "^5.0.0"
     parse-asn1 "^5.0.0"
     randombytes "^2.0.1"
     randombytes "^2.0.1"
 
 
-pump@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
-  dependencies:
-    end-of-stream "^1.1.0"
-    once "^1.3.1"
-
-pump@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.0.tgz#7946da1c8d622b098e2ceb2d3476582470829c9d"
-  dependencies:
-    end-of-stream "^1.1.0"
-    once "^1.3.1"
-
 punycode@1.3.2:
 punycode@1.3.2:
   version "1.3.2"
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
@@ -5900,12 +5882,6 @@ querystring@0.2.0:
   version "0.2.0"
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
 
 
-quick-format-unescaped@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-1.1.1.tgz#e77555ef3e66e105d4039e13ef79201284fee916"
-  dependencies:
-    fast-safe-stringify "^1.0.8"
-
 random-bytes@~1.0.0:
 random-bytes@~1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b"
   resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b"
@@ -6118,7 +6094,7 @@ readable-stream@2.2.7:
     string_decoder "~1.0.0"
     string_decoder "~1.0.0"
     util-deprecate "~1.0.1"
     util-deprecate "~1.0.1"
 
 
-readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.3.3:
+readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.3.3:
   version "2.3.3"
   version "2.3.3"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
   dependencies:
   dependencies:
@@ -6858,12 +6834,6 @@ spdx-license-ids@^1.0.2:
   version "1.2.2"
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
   resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
 
 
-split2@^2.1.0, split2@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493"
-  dependencies:
-    through2 "^2.0.2"
-
 split@0.3:
 split@0.3:
   version "0.3.3"
   version "0.3.3"
   resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
   resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
@@ -7136,13 +7106,6 @@ throttle-debounce@^1.0.1:
   version "1.0.1"
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-1.0.1.tgz#dad0fe130f9daf3719fdea33dc36a8e6ba7f30b5"
   resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-1.0.1.tgz#dad0fe130f9daf3719fdea33dc36a8e6ba7f30b5"
 
 
-through2@^2.0.1, through2@^2.0.2, through2@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
-  dependencies:
-    readable-stream "^2.1.5"
-    xtend "~4.0.1"
-
 through@2, through@^2.3.6, through@~2.3, through@~2.3.1:
 through@2, through@^2.3.6, through@~2.3, through@~2.3.1:
   version "2.3.8"
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -7157,7 +7120,7 @@ tiny-emitter@^2.0.0:
   version "2.0.2"
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
   resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
 
 
-tmp@^0.0.33:
+tmp@0.0.x, tmp@^0.0.33:
   version "0.0.33"
   version "0.0.33"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
   dependencies:
   dependencies:
@@ -7376,6 +7339,13 @@ url@^0.11.0:
     punycode "1.3.2"
     punycode "1.3.2"
     querystring "0.2.0"
     querystring "0.2.0"
 
 
+useragent@^2.2.1:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972"
+  dependencies:
+    lru-cache "4.1.x"
+    tmp "0.0.x"
+
 uslug@^1.0.4:
 uslug@^1.0.4:
   version "1.0.4"
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/uslug/-/uslug-1.0.4.tgz#b9a22f0914e0a86140633dacc302e5f4fa450677"
   resolved "https://registry.yarnpkg.com/uslug/-/uslug-1.0.4.tgz#b9a22f0914e0a86140633dacc302e5f4fa450677"
@@ -7662,7 +7632,7 @@ xss@^0.3.5:
     commander "^2.9.0"
     commander "^2.9.0"
     cssfilter "0.0.10"
     cssfilter "0.0.10"
 
 
-xtend@^4.0.0, xtend@~4.0.1:
+xtend@^4.0.0:
   version "4.0.1"
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
 
 
@@ -7673,6 +7643,12 @@ xtend@~2.0.6:
     is-object "~0.1.2"
     is-object "~0.1.2"
     object-keys "~0.2.0"
     object-keys "~0.2.0"
 
 
+xtend@~2.1.1:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b"
+  dependencies:
+    object-keys "~0.4.0"
+
 y18n@^3.2.0, y18n@^3.2.1:
 y18n@^3.2.0, y18n@^3.2.1:
   version "3.2.1"
   version "3.2.1"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"