2015-10-01 00:30:16 +02:00
|
|
|
'use strict';
|
|
|
|
|
2017-07-24 19:58:03 +02:00
|
|
|
// Dependencies.
|
2017-07-25 17:12:18 +02:00
|
|
|
const http = require('http');
|
|
|
|
const path = require('path');
|
2019-06-14 18:13:25 +02:00
|
|
|
const fse = require('fs-extra');
|
2018-05-04 17:02:27 +02:00
|
|
|
const Koa = require('koa');
|
2019-08-21 11:05:33 +02:00
|
|
|
const Router = require('koa-router');
|
2019-04-05 16:11:09 +02:00
|
|
|
const _ = require('lodash');
|
2019-10-15 16:21:59 +02:00
|
|
|
const chalk = require('chalk');
|
|
|
|
const CLITable = require('cli-table3');
|
2020-05-28 11:17:59 +02:00
|
|
|
const { logger, models, getAbsoluteAdminUrl, getAbsoluteServerUrl } = require('strapi-utils');
|
2020-03-27 15:30:03 +01:00
|
|
|
const { createDatabaseManager } = require('strapi-database');
|
2019-10-15 16:21:59 +02:00
|
|
|
|
2018-05-04 17:02:27 +02:00
|
|
|
const utils = require('./utils');
|
2020-01-16 11:01:33 +01:00
|
|
|
const loadModules = require('./core/load-modules');
|
2020-04-06 11:00:33 +02:00
|
|
|
const loadConfiguration = require('./core/app-configuration');
|
2020-01-16 11:01:33 +01:00
|
|
|
const bootstrap = require('./core/bootstrap');
|
2017-07-24 19:58:03 +02:00
|
|
|
const initializeMiddlewares = require('./middlewares');
|
|
|
|
const initializeHooks = require('./hooks');
|
2019-04-10 18:11:55 +02:00
|
|
|
const createStrapiFs = require('./core/fs');
|
2019-12-17 10:35:04 +01:00
|
|
|
const createEventHub = require('./services/event-hub');
|
2019-12-17 11:24:14 +01:00
|
|
|
const createWebhookRunner = require('./services/webhook-runner');
|
2020-03-02 15:18:08 +01:00
|
|
|
const { webhookModel, createWebhookStore } = require('./services/webhook-store');
|
2019-12-17 11:24:14 +01:00
|
|
|
const { createCoreStore, coreStoreModel } = require('./services/core-store');
|
2020-01-08 11:12:41 +01:00
|
|
|
const createEntityService = require('./services/entity-service');
|
2020-02-17 11:31:34 +01:00
|
|
|
const createEntityValidator = require('./services/entity-validator');
|
2020-03-27 15:30:03 +01:00
|
|
|
const createTelemetry = require('./services/metrics');
|
2019-12-17 10:35:04 +01:00
|
|
|
|
2015-10-01 00:30:16 +02:00
|
|
|
/**
|
|
|
|
* Construct an Strapi instance.
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
|
2020-03-27 10:30:43 +01:00
|
|
|
class Strapi {
|
2020-01-10 12:25:41 +01:00
|
|
|
constructor(opts = {}) {
|
2017-08-02 13:17:40 +02:00
|
|
|
this.reload = this.reload();
|
|
|
|
|
2016-07-06 15:51:52 +02:00
|
|
|
// Expose `koa`.
|
2016-11-04 16:00:19 +01:00
|
|
|
this.app = new Koa();
|
2019-08-21 11:05:33 +02:00
|
|
|
this.router = new Router();
|
2016-07-06 15:51:52 +02:00
|
|
|
|
2017-08-10 15:38:08 +02:00
|
|
|
// Logger.
|
|
|
|
this.log = logger;
|
|
|
|
|
2017-09-12 17:58:31 +02:00
|
|
|
// Utils.
|
|
|
|
this.utils = {
|
2018-05-18 14:22:24 +02:00
|
|
|
models,
|
2017-09-12 17:58:31 +02:00
|
|
|
};
|
|
|
|
|
2019-12-17 10:35:04 +01:00
|
|
|
this.dir = opts.dir || process.cwd();
|
2017-07-28 18:34:13 +02:00
|
|
|
this.admin = {};
|
|
|
|
this.plugins = {};
|
2020-04-03 22:31:20 +02:00
|
|
|
this.config = loadConfiguration(this.dir, opts);
|
2020-05-05 14:21:23 +02:00
|
|
|
this.isLoaded = false;
|
2020-04-03 22:31:20 +02:00
|
|
|
|
2019-12-17 10:35:04 +01:00
|
|
|
// internal services.
|
|
|
|
this.fs = createStrapiFs(this);
|
|
|
|
this.eventHub = createEventHub();
|
|
|
|
|
|
|
|
this.requireProjectBootstrap();
|
|
|
|
}
|
2017-07-28 18:34:13 +02:00
|
|
|
|
2019-06-14 18:13:25 +02:00
|
|
|
requireProjectBootstrap() {
|
2020-03-02 15:18:08 +01:00
|
|
|
const bootstrapPath = path.resolve(this.dir, 'config/functions/bootstrap.js');
|
2019-06-14 18:13:25 +02:00
|
|
|
|
|
|
|
if (fse.existsSync(bootstrapPath)) {
|
|
|
|
require(bootstrapPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-15 16:21:59 +02:00
|
|
|
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': '' },
|
|
|
|
});
|
|
|
|
|
|
|
|
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],
|
2020-04-03 22:31:20 +02:00
|
|
|
[chalk.blue('Version'), `${this.config.info.strapi} (node ${process.version})`]
|
2019-10-15 16:21:59 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
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(
|
2020-03-02 15:18:08 +01:00
|
|
|
chalk.grey('Create your first administrator 💻 by going to the administration panel at:')
|
2019-10-15 16:21:59 +02:00
|
|
|
);
|
|
|
|
console.log();
|
|
|
|
|
|
|
|
const addressTable = new CLITable();
|
2020-05-28 11:17:59 +02:00
|
|
|
|
|
|
|
const adminUrl = getAbsoluteAdminUrl(strapi.config);
|
|
|
|
addressTable.push([chalk.bold(adminUrl)]);
|
|
|
|
|
2019-10-15 16:21:59 +02:00
|
|
|
console.log(`${addressTable.toString()}`);
|
|
|
|
console.log();
|
|
|
|
}
|
|
|
|
|
|
|
|
logStartupMessage() {
|
|
|
|
this.logStats();
|
|
|
|
|
|
|
|
console.log(chalk.bold('Welcome back!'));
|
|
|
|
|
|
|
|
if (this.config.serveAdminPanel === true) {
|
2020-03-02 15:18:08 +01:00
|
|
|
console.log(chalk.grey('To manage your project 🚀, go to the administration panel at:'));
|
2020-05-28 11:17:59 +02:00
|
|
|
const adminUrl = getAbsoluteAdminUrl(strapi.config);
|
|
|
|
console.log(chalk.bold(adminUrl));
|
2019-10-15 16:21:59 +02:00
|
|
|
console.log();
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(chalk.grey('To access the server ⚡️, go to:'));
|
2020-05-28 11:17:59 +02:00
|
|
|
const serverUrl = getAbsoluteServerUrl(strapi.config);
|
|
|
|
console.log(chalk.bold(serverUrl));
|
2019-10-15 16:21:59 +02:00
|
|
|
console.log();
|
|
|
|
}
|
|
|
|
|
2019-04-26 16:19:08 +02:00
|
|
|
async start(cb) {
|
2017-07-24 19:58:03 +02:00
|
|
|
try {
|
2020-05-05 14:21:23 +02:00
|
|
|
if (!this.isLoaded) {
|
|
|
|
await this.load();
|
|
|
|
}
|
2019-04-30 14:47:49 +02:00
|
|
|
|
2019-08-21 11:05:33 +02:00
|
|
|
this.app.use(this.router.routes()).use(this.router.allowedMethods());
|
|
|
|
|
2017-07-25 17:12:18 +02:00
|
|
|
// Launch server.
|
2020-03-14 17:35:25 +01:00
|
|
|
this.listen(cb);
|
2018-03-16 11:42:17 +01:00
|
|
|
} catch (err) {
|
2019-04-05 16:11:09 +02:00
|
|
|
this.stopWithError(err);
|
2017-07-24 19:58:03 +02:00
|
|
|
}
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2019-04-05 16:11:09 +02:00
|
|
|
/**
|
|
|
|
* Add behaviors to the server
|
|
|
|
*/
|
2020-03-14 17:35:25 +01:00
|
|
|
async listen(cb) {
|
|
|
|
// Mount the HTTP server.
|
|
|
|
this.server = http.createServer(this.app.callback());
|
|
|
|
|
2019-04-05 16:11:09 +02:00
|
|
|
// handle port in use cleanly
|
|
|
|
this.server.on('error', err => {
|
|
|
|
if (err.code === 'EADDRINUSE') {
|
2020-03-02 15:18:08 +01:00
|
|
|
return this.stopWithError(`The port ${err.port} is already used by another application.`);
|
2019-04-05 16:11:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.log.error(err);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Close current connections to fully destroy the server
|
2017-07-25 17:12:18 +02:00
|
|
|
const connections = {};
|
2017-07-28 16:14:50 +02:00
|
|
|
|
2017-07-25 17:12:18 +02:00
|
|
|
this.server.on('connection', conn => {
|
|
|
|
const key = conn.remoteAddress + ':' + conn.remotePort;
|
|
|
|
connections[key] = conn;
|
2016-07-26 11:57:50 +02:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
conn.on('close', function() {
|
2018-05-04 17:02:27 +02:00
|
|
|
delete connections[key];
|
2017-07-25 17:12:18 +02:00
|
|
|
});
|
|
|
|
});
|
2016-07-26 11:57:50 +02:00
|
|
|
|
2017-07-25 17:12:18 +02:00
|
|
|
this.server.destroy = cb => {
|
|
|
|
this.server.close(cb);
|
2016-07-26 11:57:50 +02:00
|
|
|
|
2017-07-25 17:12:18 +02:00
|
|
|
for (let key in connections) {
|
|
|
|
connections[key].destroy();
|
2018-05-04 17:02:27 +02:00
|
|
|
}
|
2017-07-25 17:12:18 +02:00
|
|
|
};
|
2020-03-14 17:35:25 +01:00
|
|
|
|
|
|
|
const onListen = async err => {
|
|
|
|
if (err) return this.stopWithError(err);
|
|
|
|
|
|
|
|
// Is the project initialised?
|
|
|
|
const isInitialised = await utils.isInitialised(this);
|
|
|
|
|
|
|
|
if (!isInitialised) {
|
|
|
|
this.logFirstStartupMessage();
|
|
|
|
} else {
|
|
|
|
this.logStartupMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emit started event.
|
2020-03-30 16:00:24 +02:00
|
|
|
await this.telemetry.send('didStartServer');
|
2020-03-14 17:35:25 +01:00
|
|
|
|
|
|
|
if (cb && typeof cb === 'function') {
|
|
|
|
cb();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
(this.config.environment === 'development' &&
|
2020-04-06 11:00:33 +02:00
|
|
|
this.config.get('server.admin.autoOpen', true) !== false) ||
|
2020-03-14 17:35:25 +01:00
|
|
|
!isInitialised
|
|
|
|
) {
|
|
|
|
await utils.openBrowser.call(this);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-04-03 22:31:20 +02:00
|
|
|
this.server.listen(this.config.get('server.port'), this.config.get('server.host'), err =>
|
|
|
|
onListen(err).catch(err => this.stopWithError(err))
|
|
|
|
);
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2020-03-12 16:05:39 +01:00
|
|
|
stopWithError(err, customMessage) {
|
2019-04-05 16:11:09 +02:00
|
|
|
this.log.debug(`⛔️ Server wasn't able to start properly.`);
|
2020-03-12 16:05:39 +01:00
|
|
|
if (customMessage) {
|
|
|
|
this.log.error(customMessage);
|
|
|
|
}
|
2019-04-05 16:11:09 +02:00
|
|
|
this.log.error(err);
|
|
|
|
return this.stop();
|
|
|
|
}
|
|
|
|
|
2019-12-28 17:09:00 +01:00
|
|
|
stop(exitCode = 1) {
|
2017-07-25 17:12:18 +02:00
|
|
|
// Destroy server and available connections.
|
2020-03-19 16:46:27 +01:00
|
|
|
if (_.has(this, 'server.destroy')) {
|
|
|
|
this.server.destroy();
|
|
|
|
}
|
2017-09-04 15:38:29 +02:00
|
|
|
|
2019-05-13 17:32:52 +02:00
|
|
|
if (this.config.autoReload) {
|
2017-10-02 14:17:44 +02:00
|
|
|
process.send('stop');
|
|
|
|
}
|
2017-09-04 15:38:29 +02:00
|
|
|
|
2017-07-25 17:12:18 +02:00
|
|
|
// Kill process.
|
2019-12-28 17:09:00 +01:00
|
|
|
process.exit(exitCode);
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2017-07-24 19:58:03 +02:00
|
|
|
async load() {
|
2017-10-02 14:17:44 +02:00
|
|
|
this.app.use(async (ctx, next) => {
|
2017-09-07 16:35:12 +02:00
|
|
|
if (ctx.request.url === '/_health' && ctx.request.method === 'HEAD') {
|
2018-03-14 13:18:05 +01:00
|
|
|
ctx.set('strapi', 'You are so French!');
|
2017-10-02 14:17:44 +02:00
|
|
|
ctx.status = 204;
|
2017-09-06 11:06:18 +02:00
|
|
|
} else {
|
|
|
|
await next();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-01-16 11:01:33 +01:00
|
|
|
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;
|
2019-05-02 17:51:58 +02:00
|
|
|
|
2019-04-11 09:32:16 +02:00
|
|
|
await bootstrap(this);
|
2019-05-02 17:51:58 +02:00
|
|
|
|
2020-01-10 12:42:57 +01:00
|
|
|
// init webhook runner
|
|
|
|
this.webhookRunner = createWebhookRunner({
|
|
|
|
eventHub: this.eventHub,
|
|
|
|
logger: this.log,
|
2020-04-03 22:31:20 +02:00
|
|
|
configuration: this.config.get('server.webhooks', {}),
|
2020-01-10 12:42:57 +01:00
|
|
|
});
|
|
|
|
|
2018-04-24 12:30:43 +02:00
|
|
|
// Init core store
|
2020-04-07 16:31:44 +02:00
|
|
|
this.models['core_store'] = coreStoreModel(this.config);
|
|
|
|
this.models['strapi_webhooks'] = webhookModel(this.config);
|
2019-05-02 17:51:58 +02:00
|
|
|
|
2019-09-20 12:44:24 +02:00
|
|
|
this.db = createDatabaseManager(this);
|
|
|
|
await this.db.initialize();
|
|
|
|
|
2019-12-17 11:24:14 +01:00
|
|
|
this.store = createCoreStore({
|
|
|
|
environment: this.config.environment,
|
|
|
|
db: this.db,
|
|
|
|
});
|
|
|
|
|
|
|
|
this.webhookStore = createWebhookStore({ db: this.db });
|
|
|
|
|
2019-12-17 20:59:57 +01:00
|
|
|
await this.startWebhooks();
|
|
|
|
|
2020-02-17 11:31:34 +01:00
|
|
|
this.entityValidator = createEntityValidator({
|
|
|
|
strapi: this,
|
|
|
|
});
|
|
|
|
|
2020-01-08 11:12:41 +01:00
|
|
|
this.entityService = createEntityService({
|
|
|
|
db: this.db,
|
|
|
|
eventHub: this.eventHub,
|
2020-02-17 11:31:34 +01:00
|
|
|
entityValidator: this.entityValidator,
|
2020-01-08 11:12:41 +01:00
|
|
|
});
|
|
|
|
|
2020-03-27 15:30:03 +01:00
|
|
|
this.telemetry = createTelemetry(this);
|
2020-03-27 10:30:43 +01:00
|
|
|
|
2017-07-25 17:12:18 +02:00
|
|
|
// Initialize hooks and middlewares.
|
2019-08-21 11:05:33 +02:00
|
|
|
await initializeMiddlewares.call(this);
|
|
|
|
await initializeHooks.call(this);
|
2020-05-05 14:21:23 +02:00
|
|
|
|
|
|
|
await this.runBootstrapFunctions();
|
|
|
|
await this.freeze();
|
2020-05-12 12:47:23 +02:00
|
|
|
|
|
|
|
this.isLoaded = true;
|
|
|
|
|
2020-05-07 18:49:44 +02:00
|
|
|
return this;
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 20:59:57 +01:00
|
|
|
async startWebhooks() {
|
|
|
|
const webhooks = await this.webhookStore.findWebhooks();
|
2019-12-18 16:10:42 +01:00
|
|
|
webhooks.forEach(webhook => this.webhookRunner.add(webhook));
|
2019-12-17 20:59:57 +01:00
|
|
|
}
|
|
|
|
|
2017-08-02 11:25:18 +02:00
|
|
|
reload() {
|
2018-03-28 20:13:09 +02:00
|
|
|
const state = {
|
2019-04-09 12:09:03 +02:00
|
|
|
shouldReload: 0,
|
2018-03-28 20:13:09 +02:00
|
|
|
};
|
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
const reload = function() {
|
2018-08-31 13:47:10 +02:00
|
|
|
if (state.shouldReload > 0) {
|
2018-07-15 15:51:30 +02:00
|
|
|
// Reset the reloading state
|
2018-08-31 13:47:10 +02:00
|
|
|
state.shouldReload -= 1;
|
2018-07-15 15:51:30 +02:00
|
|
|
reload.isReloading = false;
|
2018-03-28 20:13:09 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-13 17:32:52 +02:00
|
|
|
if (this.config.autoReload) {
|
2019-03-11 10:42:43 +01:00
|
|
|
this.server.close();
|
2018-01-04 16:03:34 +01:00
|
|
|
process.send('reload');
|
|
|
|
}
|
2017-08-02 11:25:18 +02:00
|
|
|
};
|
|
|
|
|
2018-03-28 20:13:09 +02:00
|
|
|
Object.defineProperty(reload, 'isWatching', {
|
|
|
|
configurable: true,
|
|
|
|
enumerable: true,
|
2018-05-18 14:22:24 +02:00
|
|
|
set: value => {
|
2018-03-28 20:13:09 +02:00
|
|
|
// Special state when the reloader is disabled temporarly (see GraphQL plugin example).
|
2018-08-31 13:47:10 +02:00
|
|
|
if (state.isWatching === false && value === true) {
|
|
|
|
state.shouldReload += 1;
|
|
|
|
}
|
2018-03-28 20:13:09 +02:00
|
|
|
state.isWatching = value;
|
2018-05-02 22:16:13 +02:00
|
|
|
},
|
|
|
|
get: () => {
|
|
|
|
return state.isWatching;
|
2018-05-18 14:22:24 +02:00
|
|
|
},
|
2018-03-28 20:13:09 +02:00
|
|
|
});
|
|
|
|
|
2017-08-02 11:25:18 +02:00
|
|
|
reload.isReloading = false;
|
|
|
|
reload.isWatching = true;
|
|
|
|
|
|
|
|
return reload;
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2019-04-09 15:29:17 +02:00
|
|
|
async runBootstrapFunctions() {
|
2019-08-12 15:35:40 +02:00
|
|
|
const timeoutMs = this.config.bootstrapTimeout || 3500;
|
|
|
|
const warnOnTimeout = () =>
|
|
|
|
setTimeout(() => {
|
|
|
|
this.log.warn(
|
|
|
|
`The bootstrap function is taking unusually long to execute (${timeoutMs} miliseconds).`
|
|
|
|
);
|
|
|
|
this.log.warn('Make sure you call it?');
|
|
|
|
}, timeoutMs);
|
|
|
|
|
2020-02-26 18:34:45 +01:00
|
|
|
const execBootstrap = async fn => {
|
2019-08-12 15:35:40 +02:00
|
|
|
if (!fn) return;
|
|
|
|
|
|
|
|
const timer = warnOnTimeout();
|
|
|
|
try {
|
2020-02-28 09:06:26 +01:00
|
|
|
await fn();
|
2019-08-12 15:35:40 +02:00
|
|
|
} finally {
|
|
|
|
clearTimeout(timer);
|
|
|
|
}
|
2020-02-26 18:34:45 +01:00
|
|
|
};
|
2019-08-12 15:35:40 +02:00
|
|
|
|
2020-06-02 17:59:57 +02:00
|
|
|
const adminBootstrap = _.get(this.admin.config, 'functions.bootstrap');
|
|
|
|
await execBootstrap(adminBootstrap).catch(err => {
|
|
|
|
strapi.log.error(`Bootstrap function in admin failed`);
|
|
|
|
strapi.log.error(err);
|
|
|
|
strapi.stop();
|
|
|
|
});
|
|
|
|
|
2019-08-12 15:35:40 +02:00
|
|
|
const pluginBoostraps = Object.keys(this.plugins).map(plugin => {
|
2020-03-02 15:18:08 +01:00
|
|
|
return execBootstrap(_.get(this.plugins[plugin], 'config.functions.bootstrap')).catch(err => {
|
2019-08-12 15:35:40 +02:00
|
|
|
strapi.log.error(`Bootstrap function in plugin "${plugin}" failed`);
|
|
|
|
strapi.log.error(err);
|
|
|
|
strapi.stop();
|
2019-04-05 16:11:09 +02:00
|
|
|
});
|
2019-08-12 15:35:40 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
await Promise.all(pluginBoostraps);
|
2019-04-05 16:11:09 +02:00
|
|
|
|
2019-08-12 15:35:40 +02:00
|
|
|
return execBootstrap(_.get(this.config, ['functions', 'bootstrap']));
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2017-07-31 11:35:57 +02:00
|
|
|
async freeze() {
|
2019-12-18 16:10:42 +01:00
|
|
|
Object.freeze(this.config);
|
|
|
|
Object.freeze(this.dir);
|
|
|
|
Object.freeze(this.admin);
|
|
|
|
Object.freeze(this.plugins);
|
|
|
|
Object.freeze(this.api);
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
2017-08-29 19:34:34 +02:00
|
|
|
|
2019-07-22 14:36:46 +02:00
|
|
|
getModel(modelKey, plugin) {
|
2019-10-24 17:24:14 +02:00
|
|
|
return this.db.getModel(modelKey, plugin);
|
2019-07-22 12:15:54 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 21:37:45 +02:00
|
|
|
/**
|
|
|
|
* Binds queries with a specific model
|
|
|
|
* @param {string} entity - entity name
|
|
|
|
* @param {string} plugin - plugin name or null
|
|
|
|
*/
|
2019-07-15 15:33:42 +02:00
|
|
|
query(entity, plugin) {
|
2019-09-20 12:44:24 +02:00
|
|
|
return this.db.query(entity, plugin);
|
2017-08-29 19:34:34 +02:00
|
|
|
}
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2019-04-11 09:32:16 +02:00
|
|
|
module.exports = options => {
|
|
|
|
const strapi = new Strapi(options);
|
|
|
|
global.strapi = strapi;
|
|
|
|
return strapi;
|
|
|
|
};
|