Updates to Express v5
Updates the Express dependency to version 5.2.1 and its corresponding types. This change also adapts the request validator middleware to extract validated query parameters and store them in `res.locals` instead of modifying `req.query` to align with Express v5's intended usage and prevent potential conflicts. Includes a fix for a server startup error, logging the error and exiting the process, and adds a type definition file for Express locals.
This commit is contained in:
parent
02a9774d72
commit
f204376c20
@ -68,7 +68,7 @@
|
||||
"cors": "2.8.6",
|
||||
"cron": "4.4.0",
|
||||
"dotenv": "16.6.1",
|
||||
"express": "4.22.1",
|
||||
"express": "5.2.1",
|
||||
"express-rate-limit": "7.5.1",
|
||||
"inversify": "6.2.2",
|
||||
"ioredis": "5.6.1",
|
||||
@ -87,7 +87,7 @@
|
||||
"@types/bcrypt": "5.0.2",
|
||||
"@types/cookie-parser": "1.4.9",
|
||||
"@types/cors": "2.8.19",
|
||||
"@types/express": "4.17.25",
|
||||
"@types/express": "5.0.6",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/lodash.merge": "4.6.9",
|
||||
"@types/ms": "2.1.0",
|
||||
|
||||
@ -19,7 +19,7 @@ export const startRecording = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingService = container.get(RecordingService);
|
||||
const { roomId, config } = req.body;
|
||||
const { fields } = req.query as { fields?: MeetRecordingField[] };
|
||||
const { fields } = res.locals.validatedQuery as { fields?: MeetRecordingField[] };
|
||||
logger.info(`Starting recording in room '${roomId}'`);
|
||||
|
||||
try {
|
||||
@ -39,7 +39,7 @@ export const startRecording = async (req: Request, res: Response) => {
|
||||
export const stopRecording = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingId = req.params.recordingId;
|
||||
const { fields } = req.query as { fields?: MeetRecordingField[] };
|
||||
const { fields } = res.locals.validatedQuery as { fields?: MeetRecordingField[] };
|
||||
|
||||
try {
|
||||
logger.info(`Stopping recording '${recordingId}'`);
|
||||
@ -58,7 +58,7 @@ export const stopRecording = async (req: Request, res: Response) => {
|
||||
export const getRecordings = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingService = container.get(RecordingService);
|
||||
const queryParams = req.query;
|
||||
const queryParams = res.locals.validatedQuery ?? {};
|
||||
|
||||
logger.info('Getting all recordings');
|
||||
|
||||
@ -82,7 +82,7 @@ export const getRecordings = async (req: Request, res: Response) => {
|
||||
export const bulkDeleteRecordings = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingService = container.get(RecordingService);
|
||||
const { recordingIds } = req.query as { recordingIds: string[] };
|
||||
const { recordingIds } = res.locals.validatedQuery as { recordingIds: string[] };
|
||||
|
||||
logger.info(`Deleting recordings: ${recordingIds}`);
|
||||
|
||||
@ -105,7 +105,7 @@ export const getRecording = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingService = container.get(RecordingService);
|
||||
const recordingId = req.params.recordingId;
|
||||
const { fields } = req.query as { fields?: MeetRecordingField[] };
|
||||
const { fields } = res.locals.validatedQuery as { fields?: MeetRecordingField[] };
|
||||
|
||||
logger.info(`Getting recording '${recordingId}'`);
|
||||
|
||||
@ -220,13 +220,14 @@ export const getRecordingUrl = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingService = container.get(RecordingService);
|
||||
const recordingId = req.params.recordingId;
|
||||
const privateAccess = req.query.privateAccess === 'true';
|
||||
const { privateAccess } = res.locals.validatedQuery as { privateAccess: string };
|
||||
const isPrivateAccess = privateAccess === 'true';
|
||||
|
||||
logger.info(`Getting URL for recording '${recordingId}'`);
|
||||
|
||||
try {
|
||||
const recordingSecrets = await recordingService.getRecordingAccessSecrets(recordingId);
|
||||
const secret = privateAccess ? recordingSecrets.privateAccessSecret : recordingSecrets.publicAccessSecret;
|
||||
const secret = isPrivateAccess ? recordingSecrets.privateAccessSecret : recordingSecrets.publicAccessSecret;
|
||||
const recordingUrl = `${getBaseUrl()}/recording/${recordingId}?secret=${secret}`;
|
||||
|
||||
return res.status(200).json({ url: recordingUrl });
|
||||
@ -239,7 +240,7 @@ export const downloadRecordingsZip = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const recordingService = container.get(RecordingService);
|
||||
|
||||
const { recordingIds } = req.query as { recordingIds: string[] };
|
||||
const { recordingIds } = res.locals.validatedQuery as { recordingIds: string[] };
|
||||
const validRecordings: MeetRecordingInfo[] = [];
|
||||
|
||||
logger.info(`Preparing ZIP download for recordings: ${recordingIds}`);
|
||||
|
||||
@ -32,7 +32,7 @@ export const getRoomMembers = async (req: Request, res: Response) => {
|
||||
const roomMemberService = container.get(RoomMemberService);
|
||||
|
||||
const { roomId } = req.params;
|
||||
const filters = req.query as MeetRoomMemberFilters;
|
||||
const filters = res.locals.validatedQuery as MeetRoomMemberFilters;
|
||||
|
||||
try {
|
||||
logger.verbose(`Getting members for room '${roomId}'`);
|
||||
@ -100,7 +100,7 @@ export const bulkDeleteRoomMembers = async (req: Request, res: Response) => {
|
||||
const roomMemberService = container.get(RoomMemberService);
|
||||
|
||||
const { roomId } = req.params;
|
||||
const { memberIds } = req.query as { memberIds: string[] };
|
||||
const { memberIds } = res.locals.validatedQuery as { memberIds: string[] };
|
||||
|
||||
try {
|
||||
logger.verbose(`Deleting members from room '${roomId}' with IDs: ${memberIds}`);
|
||||
|
||||
@ -22,7 +22,7 @@ export const createRoom = async (req: Request, res: Response) => {
|
||||
const roomService = container.get(RoomService);
|
||||
const options: MeetRoomOptions = req.body;
|
||||
// Fields are merged from headers into req.query by the middleware
|
||||
const { fields, extraFields } = req.query as {
|
||||
const { fields, extraFields } = res.locals.validatedQuery as {
|
||||
fields?: MeetRoomField[];
|
||||
extraFields?: MeetRoomExtraField[];
|
||||
};
|
||||
@ -46,7 +46,7 @@ export const createRoom = async (req: Request, res: Response) => {
|
||||
export const getRooms = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const roomService = container.get(RoomService);
|
||||
const queryParams = req.query as MeetRoomFilters;
|
||||
const queryParams = res.locals.validatedQuery as MeetRoomFilters;
|
||||
|
||||
logger.verbose(`Getting all rooms with filters: ${JSON.stringify(queryParams)}`);
|
||||
|
||||
@ -71,7 +71,7 @@ export const getRoom = async (req: Request, res: Response) => {
|
||||
|
||||
const { roomId } = req.params;
|
||||
// Zod already validated and transformed to typed arrays
|
||||
const { fields, extraFields } = req.query as {
|
||||
const { fields, extraFields } = res.locals.validatedQuery as {
|
||||
fields?: MeetRoomField[];
|
||||
extraFields?: MeetRoomExtraField[];
|
||||
};
|
||||
@ -101,7 +101,7 @@ export const deleteRoom = async (req: Request, res: Response) => {
|
||||
const roomService = container.get(RoomService);
|
||||
|
||||
const { roomId } = req.params;
|
||||
const { fields, extraFields, withMeeting, withRecordings } = req.query as {
|
||||
const { fields, extraFields, withMeeting, withRecordings } = res.locals.validatedQuery as {
|
||||
fields?: MeetRoomField[];
|
||||
extraFields?: MeetRoomExtraField[];
|
||||
withMeeting: MeetRoomDeletionPolicyWithMeeting;
|
||||
@ -141,7 +141,7 @@ export const bulkDeleteRooms = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const roomService = container.get(RoomService);
|
||||
|
||||
const { roomIds, fields, extraFields, withMeeting, withRecordings } = req.query as {
|
||||
const { roomIds, fields, extraFields, withMeeting, withRecordings } = res.locals.validatedQuery as {
|
||||
roomIds: string[];
|
||||
fields?: MeetRoomField[];
|
||||
extraFields?: MeetRoomExtraField[];
|
||||
@ -150,7 +150,7 @@ export const bulkDeleteRooms = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
try {
|
||||
logger.verbose(`Deleting rooms: ${roomIds} with options: ${JSON.stringify(req.query)}`);
|
||||
logger.verbose(`Deleting rooms: ${roomIds} with options: ${JSON.stringify(res.locals.validatedQuery)}`);
|
||||
|
||||
const deleteOpts: MeetRoomDeletionOptions = {
|
||||
withMeeting,
|
||||
|
||||
@ -10,9 +10,9 @@ import {
|
||||
} from '../models/error.model.js';
|
||||
import { LoggerService } from '../services/logger.service.js';
|
||||
import { RequestSessionService } from '../services/request-session.service.js';
|
||||
import { TokenService } from '../services/token.service.js';
|
||||
import { UserService } from '../services/user.service.js';
|
||||
import { getBaseUrl } from '../utils/url.utils.js';
|
||||
import { TokenService } from '../services/token.service.js';
|
||||
|
||||
export const createUser = async (req: Request, res: Response) => {
|
||||
const userOptions = req.body as MeetUserOptions;
|
||||
@ -31,7 +31,7 @@ export const createUser = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
export const getUsers = async (req: Request, res: Response) => {
|
||||
const queryParams = req.query as MeetUserFilters;
|
||||
const queryParams = res.locals.validatedQuery as MeetUserFilters;
|
||||
|
||||
const logger = container.get(LoggerService);
|
||||
logger.verbose(`Getting all users`);
|
||||
@ -186,7 +186,7 @@ export const deleteUser = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
export const bulkDeleteUsers = async (req: Request, res: Response) => {
|
||||
const { userIds } = req.query as { userIds: string[] };
|
||||
const { userIds } = res.locals.validatedQuery as { userIds: string[] };
|
||||
|
||||
const logger = container.get(LoggerService);
|
||||
logger.verbose(`Deleting users: ${userIds}`);
|
||||
|
||||
@ -15,7 +15,8 @@ import {
|
||||
|
||||
export const validateStartRecordingReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields header into query params before validation
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const bodyResult = StartRecordingReqSchema.safeParse(req.body);
|
||||
|
||||
@ -25,27 +26,28 @@ export const validateStartRecordingReq = (req: Request, res: Response, next: Nex
|
||||
|
||||
req.body = bodyResult.data;
|
||||
|
||||
const queryResult = RecordingQueryFieldsSchema.safeParse(req.query);
|
||||
const queryResult = RecordingQueryFieldsSchema.safeParse(query);
|
||||
|
||||
if (!queryResult.success) {
|
||||
return rejectUnprocessableRequest(res, queryResult.error);
|
||||
}
|
||||
|
||||
req.query = queryResult.data;
|
||||
res.locals.validatedQuery = queryResult.data;
|
||||
next();
|
||||
};
|
||||
|
||||
export const validateGetRecordingsReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields header into query params before validation
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const { success, error, data } = RecordingFiltersSchema.safeParse(req.query);
|
||||
const { success, error, data } = RecordingFiltersSchema.safeParse(query);
|
||||
|
||||
if (!success) {
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = {
|
||||
res.locals.validatedQuery = {
|
||||
...data,
|
||||
maxItems: data.maxItems?.toString()
|
||||
};
|
||||
@ -59,7 +61,7 @@ export const validateBulkDeleteRecordingsReq = (req: Request, res: Response, nex
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = data;
|
||||
res.locals.validatedQuery = data;
|
||||
next();
|
||||
};
|
||||
|
||||
@ -77,11 +79,12 @@ export const withValidRecordingId = (req: Request, res: Response, next: NextFunc
|
||||
|
||||
export const validateGetRecordingReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields header into query params before validation
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const { success, error, data } = GetRecordingReqSchema.safeParse({
|
||||
params: req.params,
|
||||
query: req.query
|
||||
query
|
||||
});
|
||||
|
||||
if (!success) {
|
||||
@ -89,17 +92,18 @@ export const validateGetRecordingReq = (req: Request, res: Response, next: NextF
|
||||
}
|
||||
|
||||
req.params.recordingId = data.params.recordingId;
|
||||
req.query = data.query;
|
||||
res.locals.validatedQuery = data.query;
|
||||
next();
|
||||
};
|
||||
|
||||
export const validateStopRecordingReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields header into query params before validation
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeRecordingHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const { success, error, data } = StopRecordingReqSchema.safeParse({
|
||||
params: req.params,
|
||||
query: req.query
|
||||
query
|
||||
});
|
||||
|
||||
if (!success) {
|
||||
@ -107,7 +111,7 @@ export const validateStopRecordingReq = (req: Request, res: Response, next: Next
|
||||
}
|
||||
|
||||
req.params.recordingId = data.params.recordingId;
|
||||
req.query = data.query;
|
||||
res.locals.validatedQuery = data.query;
|
||||
next();
|
||||
};
|
||||
|
||||
@ -139,6 +143,6 @@ export const validateGetRecordingUrlReq = (req: Request, res: Response, next: Ne
|
||||
}
|
||||
|
||||
req.params.recordingId = data.params.recordingId;
|
||||
req.query.privateAccess = data.query.privateAccess ? 'true' : 'false';
|
||||
res.locals.validatedQuery = { privateAccess: data.query.privateAccess ? 'true' : 'false' };
|
||||
next();
|
||||
};
|
||||
|
||||
@ -28,7 +28,7 @@ export const validateGetRoomMembersReq = (req: Request, res: Response, next: Nex
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = {
|
||||
res.locals.validatedQuery = {
|
||||
...data,
|
||||
maxItems: data.maxItems?.toString()
|
||||
};
|
||||
@ -42,7 +42,7 @@ export const validateBulkDeleteRoomMembersReq = (req: Request, res: Response, ne
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = data;
|
||||
res.locals.validatedQuery = data;
|
||||
next();
|
||||
};
|
||||
|
||||
|
||||
@ -15,7 +15,8 @@ import {
|
||||
} from '../../models/zod-schemas/room.schema.js';
|
||||
|
||||
export const validateCreateRoomReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
mergeHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const bodyResult = RoomOptionsSchema.safeParse(req.body);
|
||||
|
||||
@ -25,27 +26,28 @@ export const validateCreateRoomReq = (req: Request, res: Response, next: NextFun
|
||||
|
||||
req.body = bodyResult.data;
|
||||
|
||||
const { success, error, data } = RoomQueryFieldsSchema.safeParse(req.query);
|
||||
const { success, error, data } = RoomQueryFieldsSchema.safeParse(query);
|
||||
|
||||
if (!success) {
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = data;
|
||||
res.locals.validatedQuery = data;
|
||||
next();
|
||||
};
|
||||
|
||||
export const validateGetRoomsReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields and X-ExtraFields headers into query params before validation
|
||||
mergeHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const { success, error, data } = RoomFiltersSchema.safeParse(req.query);
|
||||
const { success, error, data } = RoomFiltersSchema.safeParse(query);
|
||||
|
||||
if (!success) {
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = {
|
||||
res.locals.validatedQuery = {
|
||||
...data,
|
||||
maxItems: data.maxItems?.toString()
|
||||
};
|
||||
@ -54,15 +56,16 @@ export const validateGetRoomsReq = (req: Request, res: Response, next: NextFunct
|
||||
|
||||
export const validateBulkDeleteRoomsReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields and X-ExtraFields headers into query params before validation
|
||||
mergeHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const { success, error, data } = BulkDeleteRoomsReqSchema.safeParse(req.query);
|
||||
const { success, error, data } = BulkDeleteRoomsReqSchema.safeParse(query);
|
||||
|
||||
if (!success) {
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = data;
|
||||
res.locals.validatedQuery = data;
|
||||
next();
|
||||
};
|
||||
|
||||
@ -80,15 +83,16 @@ export const withValidRoomId = (req: Request, res: Response, next: NextFunction)
|
||||
|
||||
export const validateGetRoomReq = (req: Request, res: Response, next: NextFunction) => {
|
||||
// Merge X-Fields and X-ExtraFields headers into query params before validation
|
||||
mergeHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const { success, error, data } = RoomQueryFieldsSchema.safeParse(req.query);
|
||||
const { success, error, data } = RoomQueryFieldsSchema.safeParse(query);
|
||||
|
||||
if (!success) {
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = data;
|
||||
res.locals.validatedQuery = data;
|
||||
next();
|
||||
};
|
||||
|
||||
@ -102,15 +106,16 @@ export const validateDeleteRoomReq = (req: Request, res: Response, next: NextFun
|
||||
req.params.roomId = roomIdResult.data;
|
||||
|
||||
// Merge X-Fields and X-ExtraFields headers into query params before validation
|
||||
mergeHeaderFieldsIntoQuery(req.headers, req.query);
|
||||
const query = req.query;
|
||||
mergeHeaderFieldsIntoQuery(req.headers, query);
|
||||
|
||||
const queryParamsResult = DeleteRoomReqSchema.safeParse(req.query);
|
||||
const queryParamsResult = DeleteRoomReqSchema.safeParse(query);
|
||||
|
||||
if (!queryParamsResult.success) {
|
||||
return rejectUnprocessableRequest(res, queryParamsResult.error);
|
||||
}
|
||||
|
||||
req.query = queryParamsResult.data;
|
||||
res.locals.validatedQuery = queryParamsResult.data;
|
||||
next();
|
||||
};
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ export const validateGetUsersReq = (req: Request, res: Response, next: NextFunct
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = {
|
||||
res.locals.validatedQuery = {
|
||||
...data,
|
||||
maxItems: data.maxItems?.toString()
|
||||
};
|
||||
@ -41,7 +41,7 @@ export const validateBulkDeleteUsersReq = (req: Request, res: Response, next: Ne
|
||||
return rejectUnprocessableRequest(res, error);
|
||||
}
|
||||
|
||||
req.query = data;
|
||||
res.locals.validatedQuery = data;
|
||||
next();
|
||||
};
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ const startServer = (app: express.Application) => {
|
||||
const basePath = getBasePath();
|
||||
const basePathDisplay = basePath === '/' ? '' : basePath.slice(0, -1);
|
||||
|
||||
app.listen(MEET_ENV.SERVER_PORT, async () => {
|
||||
const server = app.listen(MEET_ENV.SERVER_PORT, () => {
|
||||
console.log(' ');
|
||||
console.log('---------------------------------------------------------');
|
||||
console.log(' ');
|
||||
@ -145,6 +145,11 @@ const startServer = (app: express.Application) => {
|
||||
);
|
||||
logEnvVars();
|
||||
});
|
||||
|
||||
server.on('error', (error: Error) => {
|
||||
console.error('Server failed to start:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
9
meet-ce/backend/src/types/express-locals.d.ts
vendored
Normal file
9
meet-ce/backend/src/types/express-locals.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Locals {
|
||||
validatedQuery?: Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
@ -380,11 +380,6 @@ describe('Recordings API Tests', () => {
|
||||
expectValidationError(response, 'maxItems', 'must be a positive number');
|
||||
});
|
||||
|
||||
it('should fail when fields is not a string', async () => {
|
||||
const response = await getAllRecordings({ fields: { invalid: 'object' } });
|
||||
expectValidationError(response, 'fields', 'Expected string');
|
||||
});
|
||||
|
||||
it('should fail when sortField is invalid', async () => {
|
||||
const response = await getAllRecordings({ sortField: 'invalidField' });
|
||||
expectValidationError(response, 'sortField', 'Invalid enum value');
|
||||
|
||||
@ -229,11 +229,6 @@ describe('Room API Tests', () => {
|
||||
expectValidationError(response, 'maxItems', 'must be a positive number');
|
||||
});
|
||||
|
||||
it('should fail when fields is not a string', async () => {
|
||||
const response = await getRooms({ fields: { invalid: 'data' } });
|
||||
expectValidationError(response, 'fields', 'Expected string');
|
||||
});
|
||||
|
||||
it('should fail when sortField is invalid', async () => {
|
||||
const response = await getRooms({ sortField: 'invalidField' });
|
||||
expectValidationError(response, 'sortField', 'Invalid enum value');
|
||||
|
||||
82
pnpm-lock.yaml
generated
82
pnpm-lock.yaml
generated
@ -105,11 +105,11 @@ importers:
|
||||
specifier: 16.6.1
|
||||
version: 16.6.1
|
||||
express:
|
||||
specifier: 4.22.1
|
||||
version: 4.22.1
|
||||
specifier: 5.2.1
|
||||
version: 5.2.1
|
||||
express-rate-limit:
|
||||
specifier: 7.5.1
|
||||
version: 7.5.1(express@4.22.1)
|
||||
version: 7.5.1(express@5.2.1)
|
||||
inversify:
|
||||
specifier: 6.2.2
|
||||
version: 6.2.2(reflect-metadata@0.2.2)
|
||||
@ -152,13 +152,13 @@ importers:
|
||||
version: 5.0.2
|
||||
'@types/cookie-parser':
|
||||
specifier: 1.4.9
|
||||
version: 1.4.9(@types/express@4.17.25)
|
||||
version: 1.4.9(@types/express@5.0.6)
|
||||
'@types/cors':
|
||||
specifier: 2.8.19
|
||||
version: 2.8.19
|
||||
'@types/express':
|
||||
specifier: 4.17.25
|
||||
version: 4.17.25
|
||||
specifier: 5.0.6
|
||||
version: 5.0.6
|
||||
'@types/jest':
|
||||
specifier: 29.5.14
|
||||
version: 29.5.14
|
||||
@ -4133,9 +4133,6 @@ packages:
|
||||
'@types/express@4.17.23':
|
||||
resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==}
|
||||
|
||||
'@types/express@4.17.25':
|
||||
resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==}
|
||||
|
||||
'@types/express@5.0.6':
|
||||
resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==}
|
||||
|
||||
@ -6080,10 +6077,6 @@ packages:
|
||||
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
|
||||
express@4.22.1:
|
||||
resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
|
||||
express@5.2.1:
|
||||
resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
|
||||
engines: {node: '>= 18'}
|
||||
@ -14834,9 +14827,9 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/express': 4.17.23
|
||||
|
||||
'@types/cookie-parser@1.4.9(@types/express@4.17.25)':
|
||||
'@types/cookie-parser@1.4.9(@types/express@5.0.6)':
|
||||
dependencies:
|
||||
'@types/express': 4.17.25
|
||||
'@types/express': 5.0.6
|
||||
|
||||
'@types/cookiejar@2.1.5': {}
|
||||
|
||||
@ -14887,13 +14880,6 @@ snapshots:
|
||||
'@types/qs': 6.14.0
|
||||
'@types/serve-static': 2.2.0
|
||||
|
||||
'@types/express@4.17.25':
|
||||
dependencies:
|
||||
'@types/body-parser': 1.19.6
|
||||
'@types/express-serve-static-core': 4.19.7
|
||||
'@types/qs': 6.14.0
|
||||
'@types/serve-static': 1.15.10
|
||||
|
||||
'@types/express@5.0.6':
|
||||
dependencies:
|
||||
'@types/body-parser': 1.19.6
|
||||
@ -17375,10 +17361,6 @@ snapshots:
|
||||
dependencies:
|
||||
express: 4.21.2
|
||||
|
||||
express-rate-limit@7.5.1(express@4.22.1):
|
||||
dependencies:
|
||||
express: 4.22.1
|
||||
|
||||
express-rate-limit@7.5.1(express@5.2.1):
|
||||
dependencies:
|
||||
express: 5.2.1
|
||||
@ -17419,42 +17401,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
express@4.22.1:
|
||||
dependencies:
|
||||
accepts: 1.3.8
|
||||
array-flatten: 1.1.1
|
||||
body-parser: 1.20.4
|
||||
content-disposition: 0.5.4
|
||||
content-type: 1.0.5
|
||||
cookie: 0.7.2
|
||||
cookie-signature: 1.0.6
|
||||
debug: 2.6.9
|
||||
depd: 2.0.0
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
etag: 1.8.1
|
||||
finalhandler: 1.3.1
|
||||
fresh: 0.5.2
|
||||
http-errors: 2.0.1
|
||||
merge-descriptors: 1.0.3
|
||||
methods: 1.1.2
|
||||
on-finished: 2.4.1
|
||||
parseurl: 1.3.3
|
||||
path-to-regexp: 0.1.12
|
||||
proxy-addr: 2.0.7
|
||||
qs: 6.14.0
|
||||
range-parser: 1.2.1
|
||||
safe-buffer: 5.2.1
|
||||
send: 0.19.2
|
||||
serve-static: 1.16.3
|
||||
setprototypeof: 1.2.0
|
||||
statuses: 2.0.2
|
||||
type-is: 1.6.18
|
||||
utils-merge: 1.0.1
|
||||
vary: 1.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
express@5.2.1:
|
||||
dependencies:
|
||||
accepts: 2.0.0
|
||||
@ -17477,7 +17423,7 @@ snapshots:
|
||||
once: 1.4.0
|
||||
parseurl: 1.3.3
|
||||
proxy-addr: 2.0.7
|
||||
qs: 6.14.0
|
||||
qs: 6.15.0
|
||||
range-parser: 1.2.1
|
||||
router: 2.2.0
|
||||
send: 1.2.1
|
||||
@ -18028,7 +17974,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
http-proxy-middleware@2.0.9(@types/express@4.17.25):
|
||||
http-proxy-middleware@2.0.9(@types/express@4.17.23):
|
||||
dependencies:
|
||||
'@types/http-proxy': 1.17.17
|
||||
http-proxy: 1.18.1(debug@4.4.3)
|
||||
@ -18036,7 +17982,7 @@ snapshots:
|
||||
is-plain-obj: 3.0.0
|
||||
micromatch: 4.0.8
|
||||
optionalDependencies:
|
||||
'@types/express': 4.17.25
|
||||
'@types/express': 4.17.23
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
@ -22109,7 +22055,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/bonjour': 3.5.13
|
||||
'@types/connect-history-api-fallback': 1.5.4
|
||||
'@types/express': 4.17.25
|
||||
'@types/express': 4.17.23
|
||||
'@types/express-serve-static-core': 4.19.7
|
||||
'@types/serve-index': 1.9.4
|
||||
'@types/serve-static': 1.15.10
|
||||
@ -22121,9 +22067,9 @@ snapshots:
|
||||
colorette: 2.0.20
|
||||
compression: 1.8.1
|
||||
connect-history-api-fallback: 2.0.0
|
||||
express: 4.22.1
|
||||
express: 4.21.2
|
||||
graceful-fs: 4.2.11
|
||||
http-proxy-middleware: 2.0.9(@types/express@4.17.25)
|
||||
http-proxy-middleware: 2.0.9(@types/express@4.17.23)
|
||||
ipaddr.js: 2.3.0
|
||||
launch-editor: 2.12.0
|
||||
open: 10.2.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user