芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/app.optimyar.com/backend/node_modules/strapi/lib/Strapi.js
'use strict'; const http = require('http'); const path = require('path'); const fse = require('fs-extra'); const Koa = require('koa'); const Router = require('koa-router'); const _ = require('lodash'); const chalk = require('chalk'); const CLITable = require('cli-table3'); const { logger, models, getAbsoluteAdminUrl, getAbsoluteServerUrl } = require('strapi-utils'); const { createDatabaseManager } = require('strapi-database'); const loadConfiguration = require('./core/app-configuration'); const utils = require('./utils'); const loadModules = require('./core/load-modules'); const bootstrap = require('./core/bootstrap'); const initializeMiddlewares = require('./middlewares'); const initializeHooks = require('./hooks'); const createStrapiFs = require('./core/fs'); const createEventHub = require('./services/event-hub'); const createWebhookRunner = require('./services/webhook-runner'); const { webhookModel, createWebhookStore } = require('./services/webhook-store'); const { createCoreStore, coreStoreModel } = require('./services/core-store'); const createEntityService = require('./services/entity-service'); const entityValidator = require('./services/entity-validator'); const createTelemetry = require('./services/metrics'); const createUpdateNotifier = require('./utils/update-notifier'); const ee = require('./utils/ee'); /** * Construct an Strapi instance. * * @constructor */ class Strapi { constructor(opts = {}) { this.reload = this.reload(); // Expose `koa`. this.app = new Koa(); this.router = new Router(); this.initServer(); // Logger. this.log = logger; // Utils. this.utils = { models, }; this.dir = opts.dir || process.cwd(); this.admin = {}; this.plugins = {}; this.config = loadConfiguration(this.dir, opts); this.app.proxy = this.config.get('server.proxy'); this.isLoaded = false; // internal services. this.fs = createStrapiFs(this); this.eventHub = createEventHub(); this.requireProjectBootstrap(); createUpdateNotifier(this).notify(); } get EE() { return ee({ dir: this.dir, logger }); } handleRequest(req, res) { if (!this.requestHandler) { this.requestHandler = this.app.callback(); } return this.requestHandler(req, res); } requireProjectBootstrap() { const bootstrapPath = path.resolve(this.dir, 'config/functions/bootstrap.js'); if (fse.existsSync(bootstrapPath)) { require(bootstrapPath); } } logStats() { const columns = Math.min(process.stderr.columns, 80) - 2; console.log(); console.log(chalk.black.bgWhite(_.padEnd(' Project information', columns))); console.log(); const infoTable = new CLITable({ colWidths: [20, 50], chars: { mid: '', 'left-mid': '', 'mid-mid': '', 'right-mid': '' }, }); const isEE = strapi.EE === true && ee.isEE === true; infoTable.push( [chalk.blue('Time'), `${new Date()}`], [chalk.blue('Launched in'), Date.now() - this.config.launchedAt + ' ms'], [chalk.blue('Environment'), this.config.environment], [chalk.blue('Process PID'), process.pid], [chalk.blue('Version'), `${this.config.info.strapi} (node ${process.version})`], [chalk.blue('Edition'), isEE ? 'Enterprise' : 'Community'] ); console.log(infoTable.toString()); console.log(); console.log(chalk.black.bgWhite(_.padEnd(' Actions available', columns))); console.log(); } logFirstStartupMessage() { this.logStats(); console.log(chalk.bold('One more thing...')); console.log( chalk.grey('Create your first administrator 💻 by going to the administration panel at:') ); console.log(); const addressTable = new CLITable(); const adminUrl = getAbsoluteAdminUrl(strapi.config); addressTable.push([chalk.bold(adminUrl)]); console.log(`${addressTable.toString()}`); console.log(); } logStartupMessage() { this.logStats(); console.log(chalk.bold('Welcome back!')); if (this.config.serveAdminPanel === true) { console.log(chalk.grey('To manage your project 🚀, go to the administration panel at:')); const adminUrl = getAbsoluteAdminUrl(strapi.config); console.log(chalk.bold(adminUrl)); console.log(); } console.log(chalk.grey('To access the server ⚡️, go to:')); const serverUrl = getAbsoluteServerUrl(strapi.config); console.log(chalk.bold(serverUrl)); console.log(); } initServer() { this.server = http.createServer(this.handleRequest.bind(this)); // handle port in use cleanly this.server.on('error', err => { if (err.code === 'EADDRINUSE') { return this.stopWithError(`The port ${err.port} is already used by another application.`); } this.log.error(err); }); // Close current connections to fully destroy the server const connections = {}; this.server.on('connection', conn => { const key = conn.remoteAddress + ':' + conn.remotePort; connections[key] = conn; conn.on('close', function() { delete connections[key]; }); }); this.server.destroy = cb => { this.server.close(cb); for (let key in connections) { connections[key].destroy(); } }; } async start(cb) { try { if (!this.isLoaded) { await this.load(); } this.app.use(this.router.routes()).use(this.router.allowedMethods()); // Launch server. this.listen(cb); } catch (err) { this.stopWithError(err); } } async destroy() { if (_.has(this, 'server.destroy')) { this.server.destroy(); } await Promise.all( Object.values(this.plugins).map(plugin => { if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') { return plugin.destroy(); } }) ); if (_.has(this, 'admin')) { await this.admin.destroy(); } this.eventHub.removeAllListeners(); if (_.has(this, 'db')) { await this.db.destroy(); } delete global.strapi; } /** * Add behaviors to the server */ async listen(cb) { const onListen = async err => { if (err) return this.stopWithError(err); // Is the project initialised? const isInitialised = await utils.isInitialised(this); // Should the startup message be displayed? const hideStartupMessage = process.env.STRAPI_HIDE_STARTUP_MESSAGE ? process.env.STRAPI_HIDE_STARTUP_MESSAGE === 'true' : false; if (hideStartupMessage === false) { if (!isInitialised) { this.logFirstStartupMessage(); } else { this.logStartupMessage(); } } // Emit started event. const databaseClients = _.map(this.config.get('connections'), _.property('settings.client')); await this.telemetry.send('didStartServer', { database: databaseClients }); if (cb && typeof cb === 'function') { cb(); } if ( (this.config.environment === 'development' && this.config.get('server.admin.autoOpen', true) !== false) || !isInitialised ) { await utils.openBrowser.call(this); } }; const listenSocket = this.config.get('server.socket'); const listenErrHandler = err => onListen(err).catch(err => this.stopWithError(err)); if (listenSocket) { this.server.listen(listenSocket, listenErrHandler); } else { this.server.listen( this.config.get('server.port'), this.config.get('server.host'), listenErrHandler ); } } stopWithError(err, customMessage) { this.log.debug(`⛔️ Server wasn't able to start properly.`); if (customMessage) { this.log.error(customMessage); } this.log.error(err); return this.stop(); } stop(exitCode = 1) { // Destroy server and available connections. if (_.has(this, 'server.destroy')) { this.server.destroy(); } if (this.config.autoReload) { process.send('stop'); } // Kill process. process.exit(exitCode); } async load() { this.app.use(async (ctx, next) => { if (ctx.request.url === '/_health' && ['HEAD', 'GET'].includes(ctx.request.method)) { ctx.set('strapi', 'You are so French!'); ctx.status = 204; } else { await next(); } }); const modules = await loadModules(this); this.api = modules.api; this.admin = modules.admin; this.components = modules.components; this.plugins = modules.plugins; this.middleware = modules.middlewares; this.hook = modules.hook; await bootstrap(this); // init webhook runner this.webhookRunner = createWebhookRunner({ eventHub: this.eventHub, logger: this.log, configuration: this.config.get('server.webhooks', {}), }); // Init core store this.models['core_store'] = coreStoreModel(this.config); this.models['strapi_webhooks'] = webhookModel(this.config); this.db = createDatabaseManager(this); await this.db.initialize(); this.store = createCoreStore({ environment: this.config.environment, db: this.db, }); this.webhookStore = createWebhookStore({ db: this.db }); await this.startWebhooks(); this.entityValidator = entityValidator; this.entityService = createEntityService({ db: this.db, eventHub: this.eventHub, entityValidator: this.entityValidator, }); this.telemetry = createTelemetry(this); // Initialize hooks and middlewares. await initializeMiddlewares.call(this); await initializeHooks.call(this); await this.runBootstrapFunctions(); await this.freeze(); this.isLoaded = true; return this; } async startWebhooks() { const webhooks = await this.webhookStore.findWebhooks(); webhooks.forEach(webhook => this.webhookRunner.add(webhook)); } reload() { const state = { shouldReload: 0, }; const reload = function() { if (state.shouldReload > 0) { // Reset the reloading state state.shouldReload -= 1; reload.isReloading = false; return; } if (this.config.autoReload) { this.server.close(); process.send('reload'); } }; Object.defineProperty(reload, 'isWatching', { configurable: true, enumerable: true, set: value => { // Special state when the reloader is disabled temporarly (see GraphQL plugin example). if (state.isWatching === false && value === true) { state.shouldReload += 1; } state.isWatching = value; }, get: () => { return state.isWatching; }, }); reload.isReloading = false; reload.isWatching = true; return reload; } async runBootstrapFunctions() { const execBootstrap = async fn => { if (!fn) return; return fn(); }; // plugins bootstrap const pluginBoostraps = Object.keys(this.plugins).map(plugin => { return execBootstrap(_.get(this.plugins[plugin], 'config.functions.bootstrap')).catch(err => { strapi.log.error(`Bootstrap function in plugin "${plugin}" failed`); strapi.log.error(err); strapi.stop(); }); }); await Promise.all(pluginBoostraps); // user bootstrap await execBootstrap(_.get(this.config, ['functions', 'bootstrap'])); // admin bootstrap : should always run after the others const adminBootstrap = _.get(this.admin.config, 'functions.bootstrap'); return execBootstrap(adminBootstrap).catch(err => { strapi.log.error(`Bootstrap function in admin failed`); strapi.log.error(err); strapi.stop(); }); } async freeze() { Object.freeze(this.config); Object.freeze(this.dir); Object.freeze(this.admin); Object.freeze(this.plugins); Object.freeze(this.api); } getModel(modelKey, plugin) { return this.db.getModel(modelKey, plugin); } /** * Binds queries with a specific model * @param {string} entity - entity name * @param {string} plugin - plugin name or null */ query(entity, plugin) { return this.db.query(entity, plugin); } } module.exports = options => { const strapi = new Strapi(options); global.strapi = strapi; return strapi; };