2015-10-01 00:30:16 +02:00
|
|
|
'use strict';
|
|
|
|
|
2022-03-03 18:06:59 +01:00
|
|
|
const path = require('path');
|
2019-04-05 16:11:09 +02:00
|
|
|
const _ = require('lodash');
|
2021-10-08 11:42:13 +02:00
|
|
|
const { isFunction } = require('lodash/fp');
|
2021-05-20 08:55:18 +02:00
|
|
|
const { createLogger } = require('@strapi/logger');
|
2021-05-10 15:36:09 +02:00
|
|
|
const { Database } = require('@strapi/database');
|
2021-09-13 12:03:12 +02:00
|
|
|
const { createAsyncParallelHook } = require('@strapi/utils').hooks;
|
2019-10-15 16:21:59 +02:00
|
|
|
|
2021-08-03 09:12:58 +02:00
|
|
|
const loadConfiguration = require('./core/app-configuration');
|
2021-08-05 13:59:40 +02:00
|
|
|
|
2021-08-05 12:24:48 +02:00
|
|
|
const { createContainer } = require('./container');
|
2021-08-05 11:32:56 +02:00
|
|
|
const utils = require('./utils');
|
2021-08-23 22:12:16 +02:00
|
|
|
const createStrapiFs = require('./services/fs');
|
2019-12-17 10:35:04 +01:00
|
|
|
const createEventHub = require('./services/event-hub');
|
2021-09-02 22:09:17 +02:00
|
|
|
const { createServer } = require('./services/server');
|
2019-12-17 11:24:14 +01:00
|
|
|
const createWebhookRunner = require('./services/webhook-runner');
|
2021-07-08 11:20:13 +02:00
|
|
|
const { webhookModel, createWebhookStore } = require('./services/webhook-store');
|
|
|
|
const { createCoreStore, coreStoreModel } = require('./services/core-store');
|
2020-01-08 11:12:41 +01:00
|
|
|
const createEntityService = require('./services/entity-service');
|
2021-09-23 10:40:17 +02:00
|
|
|
const createCronService = require('./services/cron');
|
2020-09-22 12:31:26 +02:00
|
|
|
const entityValidator = require('./services/entity-validator');
|
2020-03-27 15:30:03 +01:00
|
|
|
const createTelemetry = require('./services/metrics');
|
2021-09-08 16:16:16 +02:00
|
|
|
const createAuth = require('./services/auth');
|
2022-07-21 10:45:33 +02:00
|
|
|
const createContentAPI = require('./services/content-api');
|
2020-11-04 18:26:26 +01:00
|
|
|
const createUpdateNotifier = require('./utils/update-notifier');
|
2021-08-03 09:12:58 +02:00
|
|
|
const createStartupLogger = require('./utils/startup-logger');
|
2022-06-07 16:07:39 +02:00
|
|
|
const { LIFECYCLES } = require('./utils/lifecycles');
|
2020-07-01 09:43:28 +02:00
|
|
|
const ee = require('./utils/ee');
|
2021-08-06 18:09:49 +02:00
|
|
|
const contentTypesRegistry = require('./core/registries/content-types');
|
|
|
|
const servicesRegistry = require('./core/registries/services');
|
|
|
|
const policiesRegistry = require('./core/registries/policies');
|
|
|
|
const middlewaresRegistry = require('./core/registries/middlewares');
|
2021-09-13 12:03:12 +02:00
|
|
|
const hooksRegistry = require('./core/registries/hooks');
|
2021-08-06 18:09:49 +02:00
|
|
|
const controllersRegistry = require('./core/registries/controllers');
|
|
|
|
const modulesRegistry = require('./core/registries/modules');
|
2021-08-20 13:12:37 +02:00
|
|
|
const pluginsRegistry = require('./core/registries/plugins');
|
2021-08-06 18:09:49 +02:00
|
|
|
const createConfigProvider = require('./core/registries/config');
|
2021-08-27 14:31:58 +02:00
|
|
|
const apisRegistry = require('./core/registries/apis');
|
2021-08-24 17:56:49 +02:00
|
|
|
const bootstrap = require('./core/bootstrap');
|
|
|
|
const loaders = require('./core/loaders');
|
2021-10-08 11:42:13 +02:00
|
|
|
const { destroyOnSignal } = require('./utils/signals');
|
2022-04-21 00:29:26 +09:00
|
|
|
const sanitizersRegistry = require('./core/registries/sanitizers');
|
2019-12-17 10:35:04 +01:00
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
// TODO: move somewhere else
|
|
|
|
const draftAndPublishSync = require('./migrations/draft-publish');
|
|
|
|
|
2022-03-15 11:02:00 +01:00
|
|
|
/**
|
|
|
|
* Resolve the working directories based on the instance options.
|
|
|
|
*
|
|
|
|
* Behavior:
|
|
|
|
* - `appDir` is the directory where Strapi will write every file (schemas, generated APIs, controllers or services)
|
|
|
|
* - `distDir` is the directory where Strapi will read configurations, schemas and any compiled code
|
|
|
|
*
|
|
|
|
* Default values:
|
|
|
|
* - If `appDir` is `undefined`, it'll be set to `process.cwd()`
|
|
|
|
* - If `distDir` is `undefined`, it'll be set to `appDir`
|
|
|
|
*/
|
2022-08-08 23:33:39 +02:00
|
|
|
const resolveWorkingDirectories = (opts) => {
|
2022-03-15 11:02:00 +01:00
|
|
|
const cwd = process.cwd();
|
|
|
|
|
|
|
|
const appDir = opts.appDir ? path.resolve(cwd, opts.appDir) : cwd;
|
|
|
|
const distDir = opts.distDir ? path.resolve(cwd, opts.distDir) : appDir;
|
|
|
|
|
2022-03-15 11:02:00 +01:00
|
|
|
return { app: appDir, dist: distDir };
|
2021-02-16 12:23:51 +01:00
|
|
|
};
|
|
|
|
|
2022-05-09 18:23:52 +02:00
|
|
|
/** @implements {import('@strapi/strapi').Strapi} */
|
2020-03-27 10:30:43 +01:00
|
|
|
class Strapi {
|
2020-01-10 12:25:41 +01:00
|
|
|
constructor(opts = {}) {
|
2021-10-08 14:45:48 +02:00
|
|
|
destroyOnSignal(this);
|
2022-03-15 11:02:00 +01:00
|
|
|
|
2022-03-15 11:02:00 +01:00
|
|
|
const rootDirs = resolveWorkingDirectories(opts);
|
2022-03-15 11:02:00 +01:00
|
|
|
|
|
|
|
// Load the app configuration from the dist directory
|
2022-04-04 17:08:09 +02:00
|
|
|
const appConfig = loadConfiguration({ appDir: rootDirs.app, distDir: rootDirs.dist }, opts);
|
2022-03-15 11:02:00 +01:00
|
|
|
|
|
|
|
// Instanciate the Strapi container
|
2021-08-06 18:09:49 +02:00
|
|
|
this.container = createContainer(this);
|
2022-03-15 11:02:00 +01:00
|
|
|
|
|
|
|
// Register every Strapi registry in the container
|
2021-08-06 18:09:49 +02:00
|
|
|
this.container.register('config', createConfigProvider(appConfig));
|
|
|
|
this.container.register('content-types', contentTypesRegistry(this));
|
|
|
|
this.container.register('services', servicesRegistry(this));
|
|
|
|
this.container.register('policies', policiesRegistry(this));
|
|
|
|
this.container.register('middlewares', middlewaresRegistry(this));
|
2021-09-13 12:03:12 +02:00
|
|
|
this.container.register('hooks', hooksRegistry(this));
|
2021-08-06 18:09:49 +02:00
|
|
|
this.container.register('controllers', controllersRegistry(this));
|
|
|
|
this.container.register('modules', modulesRegistry(this));
|
2021-08-20 13:12:37 +02:00
|
|
|
this.container.register('plugins', pluginsRegistry(this));
|
2021-08-27 14:31:58 +02:00
|
|
|
this.container.register('apis', apisRegistry(this));
|
2021-09-08 16:16:16 +02:00
|
|
|
this.container.register('auth', createAuth(this));
|
2022-07-21 10:45:33 +02:00
|
|
|
this.container.register('content-api', createContentAPI(this));
|
2022-04-21 00:29:26 +09:00
|
|
|
this.container.register('sanitizers', sanitizersRegistry(this));
|
2021-08-05 11:32:56 +02:00
|
|
|
|
2022-03-15 11:02:00 +01:00
|
|
|
// Create a mapping of every useful directory (for the app, dist and static directories)
|
|
|
|
this.dirs = utils.getDirs(rootDirs, { strapi: this });
|
2022-02-21 11:59:30 +01:00
|
|
|
|
2022-03-15 11:02:00 +01:00
|
|
|
// Strapi state management variables
|
2021-08-06 18:09:49 +02:00
|
|
|
this.isLoaded = false;
|
2017-08-02 13:17:40 +02:00
|
|
|
this.reload = this.reload();
|
2022-03-15 11:02:00 +01:00
|
|
|
|
|
|
|
// Instanciate the Koa app & the HTTP server
|
2021-09-01 19:55:16 +02:00
|
|
|
this.server = createServer(this);
|
2021-09-01 16:00:24 +02:00
|
|
|
|
2022-03-15 11:02:00 +01:00
|
|
|
// Strapi utils instanciation
|
2019-12-17 10:35:04 +01:00
|
|
|
this.fs = createStrapiFs(this);
|
|
|
|
this.eventHub = createEventHub();
|
2021-08-03 09:12:58 +02:00
|
|
|
this.startupLogger = createStartupLogger(this);
|
2021-08-06 18:09:49 +02:00
|
|
|
this.log = createLogger(this.config.get('logger', {}));
|
2021-09-23 15:30:55 +02:00
|
|
|
this.cron = createCronService();
|
2021-10-07 13:06:40 +02:00
|
|
|
this.telemetry = createTelemetry(this);
|
2020-10-30 17:16:09 +01:00
|
|
|
|
2020-11-04 18:26:26 +01:00
|
|
|
createUpdateNotifier(this).notify();
|
2019-12-17 10:35:04 +01:00
|
|
|
}
|
2017-07-28 18:34:13 +02:00
|
|
|
|
2021-08-06 18:09:49 +02:00
|
|
|
get config() {
|
|
|
|
return this.container.get('config');
|
|
|
|
}
|
|
|
|
|
2020-07-03 17:59:06 +02:00
|
|
|
get EE() {
|
2022-03-14 17:54:35 +01:00
|
|
|
return ee({ dir: this.dirs.dist.root, logger: this.log });
|
2020-07-03 17:59:06 +02:00
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get services() {
|
|
|
|
return this.container.get('services').getAll();
|
|
|
|
}
|
|
|
|
|
2021-08-11 10:05:20 +02:00
|
|
|
service(uid) {
|
|
|
|
return this.container.get('services').get(uid);
|
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get controllers() {
|
|
|
|
return this.container.get('controllers').getAll();
|
|
|
|
}
|
|
|
|
|
2021-08-23 21:50:13 +02:00
|
|
|
controller(uid) {
|
|
|
|
return this.container.get('controllers').get(uid);
|
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get contentTypes() {
|
|
|
|
return this.container.get('content-types').getAll();
|
|
|
|
}
|
|
|
|
|
2021-08-23 21:50:13 +02:00
|
|
|
contentType(name) {
|
2021-08-23 22:25:31 +02:00
|
|
|
return this.container.get('content-types').get(name);
|
2021-08-23 21:50:13 +02:00
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get policies() {
|
|
|
|
return this.container.get('policies').getAll();
|
2021-08-23 21:50:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
policy(name) {
|
|
|
|
return this.container.get('policies').get(name);
|
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get middlewares() {
|
|
|
|
return this.container.get('middlewares').getAll();
|
|
|
|
}
|
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
middleware(name) {
|
|
|
|
return this.container.get('middlewares').get(name);
|
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get plugins() {
|
|
|
|
return this.container.get('plugins').getAll();
|
|
|
|
}
|
|
|
|
|
2021-08-06 18:09:49 +02:00
|
|
|
plugin(name) {
|
2021-08-20 13:12:37 +02:00
|
|
|
return this.container.get('plugins').get(name);
|
2021-08-06 18:09:49 +02:00
|
|
|
}
|
|
|
|
|
2021-09-29 09:34:37 +02:00
|
|
|
get hooks() {
|
|
|
|
return this.container.get('hooks').getAll();
|
2021-08-06 18:09:49 +02:00
|
|
|
}
|
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
hook(name) {
|
|
|
|
return this.container.get('hooks').get(name);
|
|
|
|
}
|
|
|
|
|
2021-08-27 14:31:58 +02:00
|
|
|
// api(name) {
|
|
|
|
// return this.container.get('apis').get(name);
|
|
|
|
// }
|
|
|
|
|
|
|
|
get api() {
|
|
|
|
return this.container.get('apis').getAll();
|
|
|
|
}
|
|
|
|
|
2021-09-13 10:48:26 +02:00
|
|
|
get auth() {
|
|
|
|
return this.container.get('auth');
|
|
|
|
}
|
|
|
|
|
2022-07-21 10:45:33 +02:00
|
|
|
get contentAPI() {
|
|
|
|
return this.container.get('content-api');
|
|
|
|
}
|
|
|
|
|
2022-04-21 00:29:26 +09:00
|
|
|
get sanitizers() {
|
|
|
|
return this.container.get('sanitizers');
|
|
|
|
}
|
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
async start() {
|
2020-09-01 14:59:08 +02:00
|
|
|
try {
|
|
|
|
if (!this.isLoaded) {
|
|
|
|
await this.load();
|
|
|
|
}
|
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
await this.listen();
|
|
|
|
|
|
|
|
return this;
|
|
|
|
} catch (error) {
|
2021-08-17 19:28:10 +02:00
|
|
|
return this.stopWithError(error);
|
2020-09-01 14:59:08 +02:00
|
|
|
}
|
|
|
|
}
|
2020-03-14 17:35:25 +01:00
|
|
|
|
2020-11-10 14:15:31 +01:00
|
|
|
async destroy() {
|
2021-08-09 20:13:05 +02:00
|
|
|
await this.server.destroy();
|
2020-11-25 17:22:41 +01:00
|
|
|
|
2021-10-08 11:42:13 +02:00
|
|
|
await this.runLifecyclesFunctions(LIFECYCLES.DESTROY);
|
2020-11-25 18:27:01 +01:00
|
|
|
|
2020-11-25 17:22:41 +01:00
|
|
|
this.eventHub.removeAllListeners();
|
|
|
|
|
2020-11-30 14:23:03 +01:00
|
|
|
if (_.has(this, 'db')) {
|
|
|
|
await this.db.destroy();
|
|
|
|
}
|
|
|
|
|
2021-03-29 12:33:08 +02:00
|
|
|
this.telemetry.destroy();
|
2021-09-23 10:40:17 +02:00
|
|
|
this.cron.destroy();
|
2021-03-29 12:33:08 +02:00
|
|
|
|
2021-10-20 17:30:05 +02:00
|
|
|
process.removeAllListeners();
|
|
|
|
|
2020-11-25 17:22:41 +01:00
|
|
|
delete global.strapi;
|
2020-11-10 14:15:31 +01:00
|
|
|
}
|
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
sendStartupTelemetry() {
|
|
|
|
// Emit started event.
|
|
|
|
// do not await to avoid slower startup
|
|
|
|
this.telemetry.send('didStartServer', {
|
2021-12-06 16:13:10 +01:00
|
|
|
database: strapi.config.get('database.connection.client'),
|
|
|
|
plugins: Object.keys(strapi.plugins),
|
|
|
|
// TODO: to add back
|
|
|
|
// providers: this.config.installedProviders,
|
2021-08-09 20:13:05 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async openAdmin({ isInitialized }) {
|
|
|
|
const shouldOpenAdmin =
|
2021-08-26 18:44:11 +02:00
|
|
|
this.config.get('environment') === 'development' &&
|
2021-10-26 12:07:57 +02:00
|
|
|
this.config.get('admin.autoOpen', true) !== false;
|
2021-08-09 20:13:05 +02:00
|
|
|
|
2021-09-15 12:25:09 +02:00
|
|
|
if (shouldOpenAdmin && !isInitialized) {
|
2022-03-02 19:02:31 +01:00
|
|
|
try {
|
|
|
|
await utils.openBrowser(this.config);
|
|
|
|
this.telemetry.send('didOpenTab');
|
|
|
|
} catch (e) {
|
|
|
|
this.telemetry.send('didNotOpenTab');
|
|
|
|
}
|
2021-08-09 20:13:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async postListen() {
|
|
|
|
const isInitialized = await utils.isInitialized(this);
|
|
|
|
|
|
|
|
this.startupLogger.logStartupMessage({ isInitialized });
|
|
|
|
|
|
|
|
this.sendStartupTelemetry();
|
|
|
|
this.openAdmin({ isInitialized });
|
|
|
|
}
|
|
|
|
|
2020-09-01 14:59:08 +02:00
|
|
|
/**
|
|
|
|
* Add behaviors to the server
|
|
|
|
*/
|
2021-08-09 20:13:05 +02:00
|
|
|
async listen() {
|
|
|
|
return new Promise((resolve, reject) => {
|
2022-08-08 23:33:39 +02:00
|
|
|
const onListen = async (error) => {
|
2021-08-09 20:13:05 +02:00
|
|
|
if (error) {
|
|
|
|
return reject(error);
|
2020-07-16 09:01:08 +02:00
|
|
|
}
|
2021-04-19 14:44:35 +02:00
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
try {
|
|
|
|
await this.postListen();
|
2020-03-14 17:35:25 +01:00
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
resolve();
|
|
|
|
} catch (error) {
|
|
|
|
reject(error);
|
|
|
|
}
|
|
|
|
};
|
2020-03-14 17:35:25 +01:00
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
const listenSocket = this.config.get('server.socket');
|
2021-08-03 09:12:58 +02:00
|
|
|
|
2021-08-09 20:13:05 +02:00
|
|
|
if (listenSocket) {
|
2022-08-09 18:31:14 +02:00
|
|
|
this.server.listen(listenSocket, onListen);
|
|
|
|
} else {
|
|
|
|
const { host, port } = this.config.get('server');
|
|
|
|
this.server.listen(port, host, onListen);
|
2021-08-03 09:12:58 +02:00
|
|
|
}
|
2021-08-09 20:13:05 +02:00
|
|
|
});
|
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);
|
|
|
|
}
|
2021-06-17 16:17:15 +02:00
|
|
|
|
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) {
|
2021-10-13 16:13:46 +02:00
|
|
|
this.destroy();
|
2017-09-04 15:38:29 +02:00
|
|
|
|
2021-07-08 11:20:13 +02:00
|
|
|
if (this.config.get('autoReload')) {
|
2017-10-02 14:17:44 +02:00
|
|
|
process.send('stop');
|
|
|
|
}
|
2017-09-04 15:38:29 +02:00
|
|
|
|
2021-03-29 12:33:08 +02:00
|
|
|
// Kill process
|
2019-12-28 17:09:00 +01:00
|
|
|
process.exit(exitCode);
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
async loadAdmin() {
|
|
|
|
await loaders.loadAdmin(this);
|
|
|
|
}
|
2021-08-03 09:12:58 +02:00
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
async loadPlugins() {
|
|
|
|
await loaders.loadPlugins(this);
|
|
|
|
}
|
2021-08-23 21:50:13 +02:00
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
async loadPolicies() {
|
|
|
|
await loaders.loadPolicies(this);
|
2021-08-03 09:12:58 +02:00
|
|
|
}
|
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
async loadAPIs() {
|
2021-08-27 14:31:58 +02:00
|
|
|
await loaders.loadAPIs(this);
|
2021-08-24 17:56:49 +02:00
|
|
|
}
|
2021-08-20 13:12:37 +02:00
|
|
|
|
2021-08-24 17:56:49 +02:00
|
|
|
async loadComponents() {
|
|
|
|
this.components = await loaders.loadComponents(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
async loadMiddlewares() {
|
2021-09-27 22:43:31 +02:00
|
|
|
await loaders.loadMiddlewares(this);
|
2021-08-20 13:12:37 +02:00
|
|
|
}
|
|
|
|
|
2021-09-23 15:30:55 +02:00
|
|
|
async loadApp() {
|
|
|
|
this.app = await loaders.loadSrcIndex(this);
|
|
|
|
}
|
|
|
|
|
2022-05-07 17:04:12 +09:00
|
|
|
async loadSanitizers() {
|
|
|
|
await loaders.loadSanitizers(this);
|
|
|
|
}
|
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
registerInternalHooks() {
|
2021-09-29 09:34:37 +02:00
|
|
|
this.container.get('hooks').set('strapi::content-types.beforeSync', createAsyncParallelHook());
|
|
|
|
this.container.get('hooks').set('strapi::content-types.afterSync', createAsyncParallelHook());
|
2021-09-13 12:03:12 +02:00
|
|
|
|
|
|
|
this.hook('strapi::content-types.beforeSync').register(draftAndPublishSync.disable);
|
|
|
|
this.hook('strapi::content-types.afterSync').register(draftAndPublishSync.enable);
|
|
|
|
}
|
|
|
|
|
2021-10-07 13:06:40 +02:00
|
|
|
async register() {
|
2021-08-24 17:56:49 +02:00
|
|
|
await Promise.all([
|
2021-09-23 15:30:55 +02:00
|
|
|
this.loadApp(),
|
2022-05-07 17:04:12 +09:00
|
|
|
this.loadSanitizers(),
|
2021-08-24 17:56:49 +02:00
|
|
|
this.loadPlugins(),
|
|
|
|
this.loadAdmin(),
|
|
|
|
this.loadAPIs(),
|
|
|
|
this.loadComponents(),
|
|
|
|
this.loadMiddlewares(),
|
|
|
|
this.loadPolicies(),
|
|
|
|
]);
|
2021-07-08 11:20:13 +02:00
|
|
|
|
2021-09-28 16:54:07 +02:00
|
|
|
await bootstrap({ strapi: 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
|
|
|
});
|
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
this.registerInternalHooks();
|
|
|
|
|
2021-10-07 13:06:40 +02:00
|
|
|
this.telemetry.register();
|
|
|
|
|
2021-02-16 12:23:51 +01:00
|
|
|
await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
|
2021-07-19 16:47:24 +02:00
|
|
|
|
2021-10-07 13:06:40 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
async bootstrap() {
|
2021-06-17 16:17:15 +02:00
|
|
|
const contentTypes = [
|
2021-05-17 16:34:19 +02:00
|
|
|
coreStoreModel,
|
|
|
|
webhookModel,
|
2021-07-19 16:47:24 +02:00
|
|
|
...Object.values(strapi.contentTypes),
|
2021-05-17 16:34:19 +02:00
|
|
|
...Object.values(strapi.components),
|
|
|
|
];
|
|
|
|
|
2021-06-28 12:34:29 +02:00
|
|
|
this.db = await Database.init({
|
2021-05-17 16:34:19 +02:00
|
|
|
...this.config.get('database'),
|
2021-06-17 16:17:15 +02:00
|
|
|
models: Database.transformContentTypes(contentTypes),
|
2021-05-17 16:34:19 +02:00
|
|
|
});
|
2021-02-12 12:52:29 +01:00
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
this.store = createCoreStore({ db: this.db });
|
2021-07-08 11:20:13 +02:00
|
|
|
this.webhookStore = createWebhookStore({ db: this.db });
|
2019-12-17 11:24:14 +01:00
|
|
|
|
2020-09-22 12:31:26 +02:00
|
|
|
this.entityValidator = entityValidator;
|
2020-01-08 11:12:41 +01:00
|
|
|
this.entityService = createEntityService({
|
2021-07-19 19:36:40 +02:00
|
|
|
strapi: this,
|
2020-01-08 11:12:41 +01:00
|
|
|
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
|
|
|
});
|
|
|
|
|
2022-07-22 17:28:51 +02:00
|
|
|
if (strapi.config.get('server.cron.enabled', true)) {
|
|
|
|
const cronTasks = this.config.get('server.cron.tasks', {});
|
|
|
|
this.cron.add(cronTasks);
|
|
|
|
}
|
2021-09-23 10:40:17 +02:00
|
|
|
|
2021-10-07 13:06:40 +02:00
|
|
|
this.telemetry.bootstrap();
|
2020-03-27 10:30:43 +01:00
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
let oldContentTypes;
|
2021-11-10 19:42:03 +01:00
|
|
|
if (await this.db.getSchemaConnection().hasTable(coreStoreModel.collectionName)) {
|
2021-09-13 12:03:12 +02:00
|
|
|
oldContentTypes = await this.store.get({
|
|
|
|
type: 'strapi',
|
|
|
|
name: 'content_types',
|
|
|
|
key: 'schema',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.hook('strapi::content-types.beforeSync').call({
|
|
|
|
oldContentTypes,
|
|
|
|
contentTypes: strapi.contentTypes,
|
|
|
|
});
|
|
|
|
|
|
|
|
await this.db.schema.sync();
|
|
|
|
|
|
|
|
await this.hook('strapi::content-types.afterSync').call({
|
|
|
|
oldContentTypes,
|
|
|
|
contentTypes: strapi.contentTypes,
|
|
|
|
});
|
|
|
|
|
|
|
|
await this.store.set({
|
|
|
|
type: 'strapi',
|
|
|
|
name: 'content_types',
|
|
|
|
key: 'schema',
|
|
|
|
value: strapi.contentTypes,
|
|
|
|
});
|
|
|
|
|
|
|
|
await this.startWebhooks();
|
|
|
|
|
2021-09-27 22:43:31 +02:00
|
|
|
await this.server.initMiddlewares();
|
2021-09-27 19:27:08 +02:00
|
|
|
await this.server.initRouting();
|
|
|
|
|
2022-08-23 16:02:45 +02:00
|
|
|
await this.contentAPI.permissions.registerActions();
|
2022-07-21 10:45:33 +02:00
|
|
|
|
2022-08-29 17:32:41 +02:00
|
|
|
await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
|
|
|
|
|
2022-08-17 09:48:35 +02:00
|
|
|
this.cron.start();
|
|
|
|
|
2021-10-07 13:06:40 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
async load() {
|
|
|
|
await this.register();
|
|
|
|
await this.bootstrap();
|
|
|
|
|
2020-05-12 12:47:23 +02:00
|
|
|
this.isLoaded = true;
|
2021-09-03 11:11:37 +02:00
|
|
|
|
2020-05-07 18:49:44 +02:00
|
|
|
return this;
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2021-07-08 11:20:13 +02:00
|
|
|
async startWebhooks() {
|
|
|
|
const webhooks = await this.webhookStore.findWebhooks();
|
2022-08-08 23:33:39 +02:00
|
|
|
webhooks.forEach((webhook) => this.webhookRunner.add(webhook));
|
2021-07-08 11:20:13 +02:00
|
|
|
}
|
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
|
|
|
};
|
|
|
|
|
2022-08-08 23:33:39 +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;
|
|
|
|
}
|
|
|
|
|
2021-08-13 15:35:19 +02:00
|
|
|
if (this.config.get('autoReload')) {
|
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,
|
2021-09-13 12:03:12 +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
|
|
|
},
|
2021-09-13 12:03:12 +02:00
|
|
|
get() {
|
2018-05-02 22:16:13 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-02-16 12:23:51 +01:00
|
|
|
async runLifecyclesFunctions(lifecycleName) {
|
|
|
|
// plugins
|
2021-08-20 15:23:02 +02:00
|
|
|
await this.container.get('modules')[lifecycleName]();
|
2019-04-05 16:11:09 +02:00
|
|
|
|
2021-02-16 12:23:51 +01:00
|
|
|
// user
|
2021-11-19 13:24:59 +01:00
|
|
|
const userLifecycleFunction = this.app && this.app[lifecycleName];
|
2021-10-08 11:42:13 +02:00
|
|
|
if (isFunction(userLifecycleFunction)) {
|
|
|
|
await userLifecycleFunction({ strapi: this });
|
2021-09-23 09:14:09 +02:00
|
|
|
}
|
2020-06-08 15:13:26 +02:00
|
|
|
|
2021-02-16 12:23:51 +01:00
|
|
|
// admin
|
2021-11-19 13:24:59 +01:00
|
|
|
const adminLifecycleFunction = this.admin && this.admin[lifecycleName];
|
2021-10-08 11:42:13 +02:00
|
|
|
if (isFunction(adminLifecycleFunction)) {
|
|
|
|
await adminLifecycleFunction({ strapi: this });
|
2021-10-04 16:44:03 +02:00
|
|
|
}
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2021-06-28 22:37:19 +02:00
|
|
|
getModel(uid) {
|
2021-07-01 13:52:01 +02:00
|
|
|
return this.contentTypes[uid] || this.components[uid];
|
2019-07-22 12:15:54 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 21:37:45 +02:00
|
|
|
/**
|
|
|
|
* Binds queries with a specific model
|
2021-06-30 20:00:03 +02:00
|
|
|
* @param {string} uid
|
2019-05-16 21:37:45 +02:00
|
|
|
*/
|
2021-06-30 20:00:03 +02:00
|
|
|
query(uid) {
|
|
|
|
return this.db.query(uid);
|
2017-08-29 19:34:34 +02:00
|
|
|
}
|
2016-07-26 11:57:50 +02:00
|
|
|
}
|
|
|
|
|
2022-08-08 23:33:39 +02:00
|
|
|
module.exports = (options) => {
|
2021-07-20 12:12:30 +02:00
|
|
|
const strapi = new Strapi(options);
|
2019-04-11 09:32:16 +02:00
|
|
|
global.strapi = strapi;
|
|
|
|
return strapi;
|
|
|
|
};
|
2021-06-30 20:00:03 +02:00
|
|
|
|
|
|
|
module.exports.Strapi = Strapi;
|