backend: Update nodemon and package scripts to generate OpenAPI documentation on restart and post-build

This commit is contained in:
Carlos Santos 2025-03-19 20:09:00 +01:00
parent cdf652acb8
commit 4e8c3ebcdf
5 changed files with 511 additions and 208 deletions

View File

@ -7,6 +7,6 @@
"ignore": ["node_modules", "dist", "src/typings", "public"], "ignore": ["node_modules", "dist", "src/typings", "public"],
"exec": "node --experimental-specifier-resolution=node --loader ts-node/esm ./src/server.ts", "exec": "node --experimental-specifier-resolution=node --loader ts-node/esm ./src/server.ts",
"events": { "events": {
"restart": "npm run typings:sync" "restart": "npm run typings:sync && npm run generate:openapi-doc"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,8 @@
], ],
"scripts": { "scripts": {
"build:prod": "tsc", "build:prod": "tsc",
"postbuild:prod": "cp -r openapi dist/openapi", "postbuild:prod": "npm run generate:openapi-doc",
"generate:openapi-doc": "mkdir -p public/openapi && npx openapi-generate-html -i openapi/openvidu-meet-api.yaml --ui=stoplight --theme=dark --title 'OpenVidu Meet REST API' --description 'OpenVidu Meet REST API' -o public/openapi/index.html",
"start:prod": "node dist/src/server.js", "start:prod": "node dist/src/server.js",
"start:dev": "nodemon", "start:dev": "nodemon",
"package:build": "npm run build:prod && npm pack", "package:build": "npm run build:prod && npm pack",
@ -54,9 +55,6 @@
"livekit-server-sdk": "2.6.2", "livekit-server-sdk": "2.6.2",
"ms": "2.1.3", "ms": "2.1.3",
"redlock": "git+https://github.com/mike-marcacci/node-redlock.git", "redlock": "git+https://github.com/mike-marcacci/node-redlock.git",
"reflect-metadata": "^0.2.2",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"uid": "^2.0.2", "uid": "^2.0.2",
"winston": "3.14.2", "winston": "3.14.2",
"yamljs": "^0.3.0", "yamljs": "^0.3.0",
@ -82,6 +80,7 @@
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-fetch-mock": "^3.0.3", "jest-fetch-mock": "^3.0.3",
"nodemon": "3.1.9", "nodemon": "3.1.9",
"openapi-generate-html": "^0.4.2",
"openapi-zod-client": "1.18.2", "openapi-zod-client": "1.18.2",
"prettier": "3.3.3", "prettier": "3.3.3",
"supertest": "^7.0.0", "supertest": "^7.0.0",

View File

@ -1,8 +1,6 @@
import express, { Request, Response, Express } from 'express'; import express, { Request, Response, Express } from 'express';
import cors from 'cors'; import cors from 'cors';
import chalk from 'chalk'; import chalk from 'chalk';
import YAML from 'yamljs';
import swaggerUi from 'swagger-ui-express';
import { registerDependencies, container } from './config/dependency-injector.config.js'; import { registerDependencies, container } from './config/dependency-injector.config.js';
import { import {
SERVER_PORT, SERVER_PORT,
@ -11,7 +9,7 @@ import {
MEET_API_BASE_PATH_V1, MEET_API_BASE_PATH_V1,
MEET_API_BASE_PATH MEET_API_BASE_PATH
} from './environment.js'; } from './environment.js';
import { getOpenApiSpecPath, indexHtmlPath, publicFilesPath, webcomponentBundlePath } from './utils/path-utils.js'; import { openapiHtmlPath, indexHtmlPath, publicFilesPath, webcomponentBundlePath } from './utils/path-utils.js';
import { authRouter, livekitRouter, preferencesRouter, recordingRouter, roomRouter } from './routes/index.js'; import { authRouter, livekitRouter, preferencesRouter, recordingRouter, roomRouter } from './routes/index.js';
import { GlobalPreferencesService, RoomService } from './services/index.js'; import { GlobalPreferencesService, RoomService } from './services/index.js';
import { participantsInternalRouter, participantsRouter } from './routes/participants.routes.js'; import { participantsInternalRouter, participantsRouter } from './routes/participants.routes.js';
@ -19,7 +17,6 @@ import cookieParser from 'cookie-parser';
const createApp = () => { const createApp = () => {
const app: Express = express(); const app: Express = express();
const openapiSpec = YAML.load(getOpenApiSpecPath());
// Enable CORS support // Enable CORS support
if (SERVER_CORS_ORIGIN) { if (SERVER_CORS_ORIGIN) {
@ -36,7 +33,7 @@ const createApp = () => {
app.use(express.json()); app.use(express.json());
app.use(cookieParser()); app.use(cookieParser());
app.use(`${MEET_API_BASE_PATH_V1}/docs`, swaggerUi.serve, swaggerUi.setup(openapiSpec)); app.use(`${MEET_API_BASE_PATH_V1}/docs`, (_req: Request, res: Response) => res.sendFile(openapiHtmlPath));
app.use(`${MEET_API_BASE_PATH_V1}/rooms`, /*mediaTypeValidatorMiddleware,*/ roomRouter); app.use(`${MEET_API_BASE_PATH_V1}/rooms`, /*mediaTypeValidatorMiddleware,*/ roomRouter);
app.use(`${MEET_API_BASE_PATH_V1}/recordings`, /*mediaTypeValidatorMiddleware,*/ recordingRouter); app.use(`${MEET_API_BASE_PATH_V1}/recordings`, /*mediaTypeValidatorMiddleware,*/ recordingRouter);
app.use(`${MEET_API_BASE_PATH_V1}/auth`, /*mediaTypeValidatorMiddleware,*/ authRouter); app.use(`${MEET_API_BASE_PATH_V1}/auth`, /*mediaTypeValidatorMiddleware,*/ authRouter);

View File

@ -1,6 +1,5 @@
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import path from 'path'; import path from 'path';
import * as fs from 'fs';
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
@ -11,19 +10,6 @@ const srcPath = path.resolve(__dirname, '..');
const publicFilesPath = path.join(srcPath, '../public'); const publicFilesPath = path.join(srcPath, '../public');
const webcomponentBundlePath = path.join(srcPath, '../public/webcomponent/openvidu-meet.bundle.min.js'); const webcomponentBundlePath = path.join(srcPath, '../public/webcomponent/openvidu-meet.bundle.min.js');
const indexHtmlPath = path.join(publicFilesPath, 'index.html'); const indexHtmlPath = path.join(publicFilesPath, 'index.html');
const openapiHtmlPath = path.join(publicFilesPath, 'openapi', 'index.html');
const getOpenApiSpecPath = () => { export { srcPath, publicFilesPath, indexHtmlPath, webcomponentBundlePath, openapiHtmlPath };
const prodPath = path.join('dist', 'openapi', 'openvidu-meet-api.yaml');
const devPath = path.join(process.cwd(), 'openapi', 'openvidu-meet-api.yaml');
if (fs.existsSync(prodPath)) {
return prodPath;
} else if (fs.existsSync(devPath)) {
return devPath;
} else {
console.warn(`OpenAPI spec not found in ${prodPath} or ${devPath}`);
throw new Error(`OpenAPI spec not found in ${prodPath} or ${devPath}`);
}
};
export { srcPath, publicFilesPath, indexHtmlPath, webcomponentBundlePath, getOpenApiSpecPath };