mirror of
https://github.com/directus/directus.git
synced 2026-01-23 23:18:10 -05:00
130 lines
3.4 KiB
TypeScript
130 lines
3.4 KiB
TypeScript
import listFolders from './utils/list-folders';
|
|
import path from 'path';
|
|
import env from './env';
|
|
import { ServiceUnavailableException } from './exceptions';
|
|
import express, { Router } from 'express';
|
|
import emitter from './emitter';
|
|
import logger from './logger';
|
|
import { HookRegisterFunction, EndpointRegisterFunction } from './types';
|
|
import { ensureDir } from 'fs-extra';
|
|
|
|
import * as exceptions from './exceptions';
|
|
import * as services from './services';
|
|
import database from './database';
|
|
|
|
export async function ensureFoldersExist() {
|
|
const folders = ['endpoints', 'hooks', 'interfaces', 'modules', 'layouts', 'displays'];
|
|
|
|
for (const folder of folders) {
|
|
const folderPath = path.resolve(env.EXTENSIONS_PATH, folder);
|
|
try {
|
|
await ensureDir(folderPath);
|
|
} catch (err) {
|
|
logger.warn(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function listExtensions(type: string) {
|
|
const extensionsPath = env.EXTENSIONS_PATH as string;
|
|
const location = path.join(extensionsPath, type);
|
|
|
|
try {
|
|
return await listFolders(location);
|
|
} catch (err) {
|
|
if (err.code === 'ENOENT') {
|
|
throw new ServiceUnavailableException(
|
|
`Extension folder "extensions/${type}" couldn't be opened`,
|
|
{
|
|
service: 'extensions',
|
|
}
|
|
);
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
export async function registerExtensions(router: Router) {
|
|
await ensureFoldersExist();
|
|
let hooks: string[] = [];
|
|
let endpoints: string[] = [];
|
|
|
|
try {
|
|
hooks = await listExtensions('hooks');
|
|
registerHooks(hooks);
|
|
} catch (err) {
|
|
logger.warn(err);
|
|
}
|
|
|
|
try {
|
|
endpoints = await listExtensions('endpoints');
|
|
registerEndpoints(endpoints, router);
|
|
} catch (err) {
|
|
logger.warn(err);
|
|
}
|
|
}
|
|
|
|
function registerHooks(hooks: string[]) {
|
|
const extensionsPath = env.EXTENSIONS_PATH as string;
|
|
|
|
for (const hook of hooks) {
|
|
try {
|
|
registerHook(hook);
|
|
} catch (error) {
|
|
logger.warn(`Couldn't register hook "${hook}"`);
|
|
logger.warn(error);
|
|
}
|
|
}
|
|
|
|
function registerHook(hook: string) {
|
|
const hookPath = path.resolve(extensionsPath, 'hooks', hook, 'index.js');
|
|
const hookInstance:
|
|
| HookRegisterFunction
|
|
| { default?: HookRegisterFunction } = require(hookPath);
|
|
|
|
let register: HookRegisterFunction = hookInstance as HookRegisterFunction;
|
|
if (typeof hookInstance !== 'function') {
|
|
if (hookInstance.default) {
|
|
register = hookInstance.default;
|
|
}
|
|
}
|
|
|
|
let events = register({ services, exceptions, env, database });
|
|
for (const [event, handler] of Object.entries(events)) {
|
|
emitter.on(event, handler);
|
|
}
|
|
}
|
|
}
|
|
|
|
function registerEndpoints(endpoints: string[], router: Router) {
|
|
const extensionsPath = env.EXTENSIONS_PATH as string;
|
|
|
|
for (const endpoint of endpoints) {
|
|
try {
|
|
registerEndpoint(endpoint);
|
|
} catch (error) {
|
|
logger.warn(`Couldn't register endpoint "${endpoint}"`);
|
|
logger.warn(error);
|
|
}
|
|
}
|
|
|
|
function registerEndpoint(endpoint: string) {
|
|
const endpointPath = path.resolve(extensionsPath, 'endpoints', endpoint, 'index.js');
|
|
const endpointInstance:
|
|
| EndpointRegisterFunction
|
|
| { default?: EndpointRegisterFunction } = require(endpointPath);
|
|
|
|
let register: EndpointRegisterFunction = endpointInstance as EndpointRegisterFunction;
|
|
if (typeof endpointInstance !== 'function') {
|
|
if (endpointInstance.default) {
|
|
register = endpointInstance.default;
|
|
}
|
|
}
|
|
|
|
const scopedRouter = express.Router();
|
|
router.use(`/${endpoint}/`, scopedRouter);
|
|
|
|
register(scopedRouter, { services, exceptions, env, database });
|
|
}
|
|
}
|