Updates to Express v5 (#7)
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
78060c0cdf
commit
177134d2a6
@ -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