From d4ddd20b9ade0e68281736bfebf56f17c94c4fd2 Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Fri, 19 Jun 2020 11:14:40 -0400 Subject: [PATCH] Add extensions service and routes --- .env.example | 2 ++ src/app.ts | 2 ++ src/error.ts | 8 ++++++-- src/routes/extensions.ts | 28 ++++++++++++++++++++++++++++ src/services/extensions.ts | 18 ++++++++++++++++++ src/utils/list-folders.ts | 25 +++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 src/routes/extensions.ts create mode 100644 src/services/extensions.ts create mode 100644 src/utils/list-folders.ts diff --git a/.env.example b/.env.example index c3da0aec83..aa23c26ca3 100644 --- a/.env.example +++ b/.env.example @@ -6,3 +6,5 @@ DB_PORT=5432 DB_NAME="directus" DB_USER="postgres" DB_PASSWORD="psql1234" + +EXTENSIONS_PATH="./extensions" diff --git a/src/app.ts b/src/app.ts index 07be3a4975..7244dd3826 100644 --- a/src/app.ts +++ b/src/app.ts @@ -13,6 +13,7 @@ import relationsRouter from './routes/relations'; import revisionsRouter from './routes/revisions'; import rolesRouter from './routes/roles'; import usersRouter from './routes/users'; +import extensionsRouter from './routes/extensions'; import notFoundHandler from './routes/not-found'; const app = express() @@ -27,6 +28,7 @@ const app = express() .use('/revisions', revisionsRouter) .use('/roles', rolesRouter) .use('/users', usersRouter) + .use('/extensions', extensionsRouter) .use(notFoundHandler) .use(errorHandler); diff --git a/src/error.ts b/src/error.ts index c962d09229..5dc3242008 100644 --- a/src/error.ts +++ b/src/error.ts @@ -5,12 +5,16 @@ export enum ErrorCode { NOT_FOUND = 'NOT_FOUND', FIELD_NOT_FOUND = 'FIELD_NOT_FOUND', INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR', + ENOENT = 'ENOENT', + EXTENSION_ILLEGAL_TYPE = 'EXTENSION_ILLEGAL_TYPE', } enum HTTPStatus { NOT_FOUND = 404, FIELD_NOT_FOUND = 400, INTERNAL_SERVER_ERROR = 500, + ENOENT = 501, + EXTENSION_ILLEGAL_TYPE = 400, } export const errorHandler: ErrorRequestHandler = (error: APIError | Error, req, res, next) => { @@ -38,12 +42,12 @@ export const errorHandler: ErrorRequestHandler = (error: APIError | Error, req, }, }; - if ((process.env.NODE_ENV = 'development')) { + if (process.env.NODE_ENV === 'development') { response.error.message = error.message; } } - if ((process.env.NODE_ENV = 'development')) { + if (process.env.NODE_ENV === 'development') { response.error.stack = error.stack; } diff --git a/src/routes/extensions.ts b/src/routes/extensions.ts new file mode 100644 index 0000000000..1e973bfcaf --- /dev/null +++ b/src/routes/extensions.ts @@ -0,0 +1,28 @@ +import { Router } from 'express'; +import asyncHandler from 'express-async-handler'; +import * as ExtensionsService from '../services/extensions'; +import APIError, { ErrorCode } from '../error'; + +const router = Router(); + +router.get( + '/:type', + asyncHandler(async (req, res) => { + const typeAllowList = ['interfaces', 'layouts', 'displays', 'modules']; + + if (typeAllowList.includes(req.params.type) === false) { + throw new APIError( + ErrorCode.EXTENSION_ILLEGAL_TYPE, + `${req.params.type} is not an extension type.` + ); + } + + const interfaces = await ExtensionsService.listExtensions(req.params.type); + + return res.json({ + data: interfaces, + }); + }) +); + +export default router; diff --git a/src/services/extensions.ts b/src/services/extensions.ts new file mode 100644 index 0000000000..edde0634b4 --- /dev/null +++ b/src/services/extensions.ts @@ -0,0 +1,18 @@ +import listFolders from '../utils/list-folders'; +import path from 'path'; +import APIError, { ErrorCode } from '../error'; + +export async function listExtensions(type: string) { + const extensionsPath = process.env.EXTENSIONS_PATH; + const location = path.join(extensionsPath, type); + + try { + return await listFolders(location); + } catch (err) { + if (err.code === 'ENOENT') { + throw new APIError(ErrorCode.ENOENT, `The ${type} folder doesn't exist.`); + } + + throw err; + } +} diff --git a/src/utils/list-folders.ts b/src/utils/list-folders.ts new file mode 100644 index 0000000000..705d9b181a --- /dev/null +++ b/src/utils/list-folders.ts @@ -0,0 +1,25 @@ +import fs from 'fs'; +import path from 'path'; +import { promisify } from 'util'; +import APIError, { ErrorCode } from '../error'; + +const readdir = promisify(fs.readdir); +const stat = promisify(fs.stat); + +export default async function listFolders(location: string) { + const fullPath = path.join(process.cwd(), location); + const files = await readdir(fullPath); + + const directories: string[] = []; + + for (const file of files) { + const filePath = path.join(fullPath, file); + const stats = await stat(filePath); + + if (stats.isDirectory()) { + directories.push(file); + } + } + + return directories; +}