diff --git a/config/sequelize.js b/config/sequelize.js index e05c59446f10b30fdd187e34a81af5761f0a5536..e5c3861df8cc9ad5417b2947b0cb3369c3634c0e 100644 --- a/config/sequelize.js +++ b/config/sequelize.js @@ -1,16 +1,19 @@ -// src/config/sequelize.js - +// config/sequelize.js const { Sequelize } = require('sequelize'); require('dotenv').config(); const isTest = process.env.NODE_ENV === 'test'; const sequelize = isTest - ? new Sequelize('sqlite::memory:', { logging: false }) // �뚯뒪�� �섍꼍�� �몃찓紐⑤━ DB + ? new Sequelize({ + dialect: 'sqlite', + storage: ':memory:', + logging: false, + }) // �뚯뒪�� �섍꼍�� �몃찓紐⑤━ DB : new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, { host: process.env.DB_HOST, - dialect: 'mysql', - logging: false, + dialect: 'mysql', + logging: false, }); -module.exports = sequelize; \ No newline at end of file +module.exports = sequelize; diff --git a/controllers/friendController.js b/controllers/friendController.js index 6dc37400fcfea24164af27d46070059b70cd3784..8f385c7cf1a01cdfbf55ab5afea27df9a193ecbe 100644 --- a/controllers/friendController.js +++ b/controllers/friendController.js @@ -4,9 +4,6 @@ class friendController { /** * 移쒓뎄 �붿껌 蹂대궡湲� * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� �꾩넚 - * @param {Object} req - Express �붿껌 媛앹껜 - * @param {Object} res - Express �묐떟 媛앹껜 - * @param {Function} next - Express next 誘몃뱾�⑥뼱 �⑥닔 */ async sendFriendRequest(req, res, next) { const { userId, email } = req.body; @@ -140,13 +137,12 @@ class friendController { /** * 移쒓뎄 紐⑸줉 議고쉶 - * GET /api/friend/all + * GET /api/friend/all/:offset */ async getFriendList(req, res) { try { const userId = req.user.id; - const friends = await FriendService.getFriendList(userId); - + const friends = await FriendService.getFriendList(userId,20,req.param); return res.status(200).json({ success: true, data: friends diff --git a/controllers/inviteController.js b/controllers/inviteController.js new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/controllers/meetingController.js b/controllers/meetingController.js index 182c25b277daad4229d8edb3b636b06fa8de5773..d85e78864e0106b054239c6cc3946d19daaa656b 100644 --- a/controllers/meetingController.js +++ b/controllers/meetingController.js @@ -1,5 +1,4 @@ // controllers/meetingController.js - const MeetingService = require('../services/meetingService'); const CreateMeetingRequestDTO = require('../dtos/CreateMeetingRequestDTO'); @@ -7,13 +6,25 @@ class MeetingController { /** * 踰덇컻 紐⑥엫 �앹꽦 * POST /api/meetings + * + * �꾨줎�몄뿏�� �낅젰 �곗씠�� �뺤떇 �덉떆: + * { + * "title": "�� �숆린�� 誘명똿", + * "description": "�붽컙 �� �숆린�� �뚯쓽�낅땲��.", + * "time_idx_start": 40, // ��: 10:00 AM + * "time_idx_end": 42, // ��: 10:30 AM + * "location": "�뚯쓽�� A", + * "deadline": "2024-04-25T23:59:59Z", + * "type": "OPEN" // "OPEN" �먮뒗 "CLOSE" + * } */ async createMeeting(req, res) { try { - const userId = req.userId; // �몄쬆 誘몃뱾�⑥뼱瑜� �듯빐 �ㅼ젙�� �ъ슜�� ID - const meetingData = { ...req.body, created_by: userId }; - - // CreateMeetingRequestDTO瑜� �ъ슜�섏뿬 �붿껌 �곗씠�� 寃�利� + const userId = req.user.id; + const meetingData = { + ...req.body, + created_by: userId + }; const createMeetingDTO = new CreateMeetingRequestDTO(meetingData); createMeetingDTO.validate(); @@ -31,8 +42,7 @@ class MeetingController { */ async getMeetings(req, res) { try { - const userId = req.userId; // �몄쬆 誘몃뱾�⑥뼱瑜� �듯빐 �ㅼ젙�� �ъ슜�� ID - + const userId = req.user.id; // �몄쬆 誘몃뱾�⑥뼱瑜� �듯빐 �ㅼ젙�� �ъ슜�� ID const meetings = await MeetingService.getMeetings(userId); res.status(200).json(meetings); } catch (err) { @@ -43,11 +53,10 @@ class MeetingController { /** * 踰덇컻 紐⑥엫 留덇컧 - * PATCH /api/meetings/:meetingId/close + * PATCH /api/meetings/:meetingId/close (URL �뚮씪誘명꽣濡� meetingId �꾨떖) */ async closeMeeting(req, res) { const { meetingId } = req.params; - try { const meeting = await MeetingService.closeMeeting(meetingId); res.status(200).json({ message: '紐⑥엫�� 留덇컧�섏뿀�듬땲��.', meeting }); @@ -60,13 +69,15 @@ class MeetingController { /** * 踰덇컻 紐⑥엫 李멸� * POST /api/meetings/:meetingId/join + * (URL �뚮씪誘명꽣濡� meetingId �꾨떖) */ async joinMeeting(req, res) { try { const { meetingId } = req.params; - const userId = req.userId; // �몄쬆 誘몃뱾�⑥뼱瑜� �듯빐 �ㅼ젙�� �ъ슜�� ID + const userId = req.user.id; // �몄쬆 誘몃뱾�⑥뼱瑜� �듯빐 �ㅼ젙�� �ъ슜�� ID await MeetingService.joinMeeting(meetingId, userId); + res.status(200).json({ message: '紐⑥엫 諛� 梨꾪똿諛� 李멸� �꾨즺' }); } catch (err) { console.error('紐⑥엫 李멸� �ㅻ쪟:', err); @@ -77,10 +88,10 @@ class MeetingController { /** * 踰덇컻 紐⑥엫 �곸꽭 議고쉶 * GET /api/meetings/:meetingId + (URL �뚮씪誘명꽣濡� meetingId �꾨떖) */ async getMeetingDetail(req, res) { const { meetingId } = req.params; - try { const meetingDetail = await MeetingService.getMeetingDetail(meetingId); res.status(200).json(meetingDetail); diff --git a/controllers/scheduleController.js b/controllers/scheduleController.js index 0d3f1c9245de937ecbe90ec5913f460a1940e95d..4d43ee118a980c6ddf536eff25592f0cf734a66c 100644 --- a/controllers/scheduleController.js +++ b/controllers/scheduleController.js @@ -6,28 +6,46 @@ class scheduleController { /** * �ㅼ�以� �앹꽦 * POST /api/schedule + * �대떦 �ъ슜�� id�� auth 誘몃뱾�⑥뼱�먯꽌 �ㅼ젙�� �ъ슜�� �뺣낫 �댁슜 + * req.user = User 紐⑤뜽�� �몄뒪�댁뒪 + * �붿껌 蹂몃Ц �덉떆: + * { + * title: 'Schedule Title', + * is_fixed: true, + * events: [ + * { time_idx: 36 }, + * { time_idx: 37 }, + * // ... + * ] + * } */ async createSchedule(req, res) { try { const userId = req.user.id; const scheduleRequestDTO = new ScheduleRequestDTO(req.body); - const validatedData = scheduleRequestDTO.validate('create'); + const validatedData = scheduleRequestDTO.validate('create'); // 'create' ���� 寃�利� - const scheduleDTO = await ScheduleService.createSchedule({ + const { title, is_fixed, events } = validatedData; + + const schedules = await ScheduleService.createSchedules({ userId, - ...validatedData + title, + is_fixed, + events }); return res.status(201).json({ success: true, - data: scheduleDTO + data: { + schedules + } }); } catch (error) { return res.status(400).json({ success: false, error: { - message: error.message.includes('Validation error') ? error.message : 'SCHEDULE_CREATE_ERROR', - code: error.message.includes('Validation error') ? 'VALIDATION_ERROR' : 'SCHEDULE_CREATE_ERROR' + message: error.message, + code: 'SCHEDULE_CREATE_ERROR' } }); } @@ -35,23 +53,35 @@ class scheduleController { /** * �ㅼ�以� �섏젙 - * PUT /api/schedule/:id + * PUT /api/schedule + * Bulk update 吏��� + * �붿껌 蹂몃Ц �덉떆: + * { + * updates: [ + * { time_idx: 36, title: 'New Title', is_fixed: true }, + * { time_idx: 44, title: 'Another Title' }, + * // ... + * ] + * } */ - async updateSchedule(req, res) { + async updateSchedules(req, res) { try { - const { id } = req.params; const userId = req.user.id; const scheduleRequestDTO = new ScheduleRequestDTO(req.body); - const validatedData = scheduleRequestDTO.validate('update'); + const validatedData = scheduleRequestDTO.validate('bulk_update'); // 'bulk_update' ���� 寃�利� + + const { updates } = validatedData; - const scheduleDTO = await ScheduleService.updateSchedule(id, userId, validatedData); + const updatedSchedules = await ScheduleService.updateSchedules(userId, updates); return res.status(200).json({ success: true, - data: scheduleDTO + data: { + schedules: updatedSchedules + } }); } catch (error) { - if (error.message === 'Schedule not found') { + if (error.code === 'SCHEDULE_NOT_FOUND') { return res.status(404).json({ success: false, error: { @@ -59,14 +89,6 @@ class scheduleController { code: 'SCHEDULE_NOT_FOUND' } }); - } else if (error.message.includes('Validation error')) { - return res.status(400).json({ - success: false, - error: { - message: error.message, - code: 'VALIDATION_ERROR' - } - }); } return res.status(400).json({ success: false, @@ -80,34 +102,36 @@ class scheduleController { /** * �ㅼ�以� ��젣 - * DELETE /api/schedule/:id + * DELETE /api/schedule + * Bulk delete 吏��� + * �붿껌 蹂몃Ц �덉떆: + * { + * time_idxs: [36, 44, ...] + * } */ - async deleteSchedule(req, res) { + async deleteSchedules(req, res) { try { - const { id } = req.params; const userId = req.user.id; + const scheduleRequestDTO = new ScheduleRequestDTO(req.body); + const validatedData = scheduleRequestDTO.validate('bulk_delete'); // 'bulk_delete' ���� 寃�利� + + const { time_idxs } = validatedData; - const deleteResult = await ScheduleService.deleteSchedule(id, userId); + const result = await ScheduleService.deleteSchedules(userId, time_idxs); return res.status(200).json({ success: true, - data: deleteResult + data: { + message: 'Schedules successfully deleted', + deleted_time_idxs: result.deleted_time_idxs + } }); } catch (error) { - if (error.message === 'Schedule not found') { - return res.status(404).json({ - success: false, - error: { - message: error.message, - code: 'SCHEDULE_NOT_FOUND' - } - }); - } - return res.status(500).json({ + return res.status(404).json({ success: false, error: { - message: 'Failed to delete schedule', - code: 'DELETE_ERROR' + message: error.message, + code: 'SCHEDULE_DELETE_ERROR' } }); } @@ -120,11 +144,11 @@ class scheduleController { async getAllSchedules(req, res) { try { const userId = req.user.id; - const schedulesDTO = await ScheduleService.getAllSchedules(userId); + const schedules = await ScheduleService.getAllSchedules(userId); return res.status(200).json({ success: true, - data: schedulesDTO + data: schedules }); } catch (error) { return res.status(500).json({ @@ -139,17 +163,19 @@ class scheduleController { /** * �대떦 �ъ슜�� �뱀젙 �ㅼ�以� 議고쉶 - * GET /api/schedule/:id + * GET /api/schedule/:time_idx + * ��: GET /api/schedule/36 */ - async getScheduleById(req, res) { + async getScheduleByTimeIdx(req, res) { try { - const { id } = req.params; + const { time_idx } = req.params; const userId = req.user.id; - const scheduleDTO = await ScheduleService.getScheduleById(id, userId); + + const schedule = await ScheduleService.getScheduleByTimeIdx(userId, parseInt(time_idx, 10)); return res.status(200).json({ success: true, - data: scheduleDTO + data: schedule }); } catch (error) { if (error.message === 'Schedule not found') { diff --git a/dtos/CreateMeetingRequestDTO.js b/dtos/CreateMeetingRequestDTO.js index fa3801d7f52ca68f0c251bdc464f24aa9ac0272f..c61b0691683a7b2bdd7e96de219c732072065ec1 100644 --- a/dtos/CreateMeetingRequestDTO.js +++ b/dtos/CreateMeetingRequestDTO.js @@ -1,34 +1,36 @@ // dtos/CreateMeetingRequestDTO.js - const Joi = require('joi'); class CreateMeetingRequestDTO { - constructor({ title, description, start_time, end_time, location, deadline, type, created_by }) { - this.title = title; - this.description = description; - this.start_time = start_time; - this.end_time = end_time; - this.location = location; - this.deadline = deadline; - this.type = type; - this.created_by = created_by; + constructor({ title, description, time_idx_start, time_idx_end, location, time_idx_deadline, type, created_by }) { + this.data = { + title, + description, + time_idx_start, + time_idx_end, + location, + time_idx_deadline, + type, + created_by, + }; } + validate() { const schema = Joi.object({ title: Joi.string().min(1).max(255).required(), description: Joi.string().allow('', null).optional(), - start_time: Joi.date().iso().required(), - end_time: Joi.date().iso().greater(Joi.ref('start_time')).required(), + time_idx_start: Joi.number().integer().min(0).required(), + time_idx_end: Joi.number().integer().greater(Joi.ref('time_idx_start')).required(), location: Joi.string().allow('', null).optional(), - deadline: Joi.date().iso().greater(Joi.ref('start_time')).optional(), + time_idx_deadline: Joi.number().integer().min(0).less(Joi.ref('time_idx_start')).optional(), type: Joi.string().valid('OPEN', 'CLOSE').required(), - created_by: Joi.number().integer().positive().required() + created_by: Joi.number().integer().positive().required(), }); - const { error } = schema.validate(this, { abortEarly: false }); + const { error } = schema.validate(this.data, { abortEarly: false }); if (error) { - const errorMessages = error.details.map(detail => detail.message).join(', '); + const errorMessages = error.details.map((detail) => detail.message).join(', '); throw new Error(`Validation error: ${errorMessages}`); } diff --git a/dtos/FriendListDTO.js b/dtos/FriendListDTO.js index 1768c74ab1aff6bc45ebf8aaae62e0dbb49ee809..3dd8b22ba40b3930fa1e3e61b74d524efc965a01 100644 --- a/dtos/FriendListDTO.js +++ b/dtos/FriendListDTO.js @@ -1,10 +1,7 @@ // dto/FriendListDTO.js class FriendListDTO { - /** - * @param {object} friend - Friend relationship object retrieved from the database. - * @param {number} userId - The ID of the user whose friend list is being retrieved. - */ + constructor(friend, userId) { this.id = friend.id; this.status = friend.status; diff --git a/dtos/FriendResponseDTO.js b/dtos/FriendResponseDTO.js index 8a7f365a320a3451a3c9f5252b4ddc7463d63391..050786a3f6977e326d04d5d0f9d1389327b3f372 100644 --- a/dtos/FriendResponseDTO.js +++ b/dtos/FriendResponseDTO.js @@ -1,25 +1,23 @@ -// dto/FriendRequestDTO.js +// dto/FriendResponseDTO.js -class FriendRequestDTO { - /** - * @param {object} friendRequest - Friend request object retrieved from the database. - */ - constructor(friendRequest) { - this.id = friendRequest.id; +class FriendResponseDTO { + + constructor(friendResponse) { + this.id = friendResponse.id; this.requester = { - id: friendRequest.requester.id, - name: friendRequest.requester.name, - email: friendRequest.requester.email + id: friendResponse.requester.id, + name: friendResponse.requester.name, + email: friendResponse.requester.email }; this.receiver = { - id: friendRequest.receiver.id, - name: friendRequest.receiver.name, - email: friendRequest.receiver.email + id: friendResponse.receiver.id, + name: friendResponse.receiver.name, + email: friendResponse.receiver.email }; - this.status = friendRequest.status; - this.createdAt = friendRequest.createdAt; - this.updatedAt = friendRequest.updatedAt; + this.status = friendResponse.status; + this.createdAt = friendResponse.createdAt; + this.updatedAt = friendResponse.updatedAt; } } -module.exports = FriendRequestDTO; +module.exports = FriendResponseDTO; diff --git a/dtos/MeetingDetailResponseDTO.js b/dtos/MeetingDetailResponseDTO.js index 33a55823d87f04fd96d000d136964f8923fce4e8..5d4ac75f7dbc729ccc4235e5d27abe247ddf4c3f 100644 --- a/dtos/MeetingDetailResponseDTO.js +++ b/dtos/MeetingDetailResponseDTO.js @@ -1,14 +1,13 @@ -// dtos/MeetingDetailResponseDTO.js - +// dtos/MeetingResponseDTO.js class MeetingDetailResponseDTO { constructor(meeting) { this.id = meeting.id; this.title = meeting.title; this.description = meeting.description; - this.startTime = meeting.start_time; - this.endTime = meeting.end_time; + this.timeIdxStart = meeting.time_idx_start; + this.timeIdxEnd = meeting.time_idx_end; this.location = meeting.location; - this.deadline = meeting.deadline; + this.time_idx_deadline = meeting.time_idx_deadline; this.type = meeting.type; this.creatorName = meeting.creator ? meeting.creator.name : 'Unknown'; this.participants = meeting.participants.map(participant => ({ @@ -19,4 +18,4 @@ class MeetingDetailResponseDTO { } } -module.exports = MeetingDetailResponseDTO; +module.exports = MeetingDetailResponseDTO; \ No newline at end of file diff --git a/dtos/MeetingResponseDTO.js b/dtos/MeetingResponseDTO.js index a456d6992c6f9aaf19d0dc66b8a22fb032f94731..67c31719c512c3d4df31e07e19f1f9e6d3b44c8b 100644 --- a/dtos/MeetingResponseDTO.js +++ b/dtos/MeetingResponseDTO.js @@ -1,14 +1,15 @@ -// dtos/MeetingResponseDTO.js +// dtos/MeetingDetailResponseDTO.js + class MeetingResponseDTO { constructor(meeting, isParticipant, isScheduleConflict, creatorName) { this.id = meeting.id; this.title = meeting.title; this.description = meeting.description; - this.startTime = meeting.start_time; - this.endTime = meeting.end_time; + this.timeIdxStart = meeting.time_idx_start; + this.timeIdxEnd = meeting.time_idx_end; this.location = meeting.location; - this.deadline = meeting.deadline; + this.time_idx_deadline = meeting.time_idx_deadline; this.type = meeting.type; this.creatorName = creatorName; this.isParticipant = isParticipant; @@ -16,4 +17,4 @@ class MeetingResponseDTO { } } -module.exports = MeetingResponseDTO; +module.exports = MeetingResponseDTO; \ No newline at end of file diff --git a/dtos/ScheduleRequestDTO.js b/dtos/ScheduleRequestDTO.js index a3325346fec86e243296b6eb7b2c7188c9115da5..854bd3f124ebe293fe781924683ed0d9b0a4c168 100644 --- a/dtos/ScheduleRequestDTO.js +++ b/dtos/ScheduleRequestDTO.js @@ -1,39 +1,49 @@ // dtos/ScheduleRequestDTO.js - const Joi = require('joi'); class ScheduleRequestDTO { constructor(data) { this.data = data; } + validate(type = 'create') { - // 湲곕낯 �ㅽ궎留� �뺤쓽 - let schema = Joi.object({ - title: Joi.string().min(1).max(255).required(), - start_time: Joi.date().iso().required(), - end_time: Joi.date().iso().required(), - is_fixed: Joi.boolean().required() - }); + let schema; - // 'update' ���낆쓽 寃쎌슦 紐⑤뱺 �꾨뱶瑜� �꾩닔濡� �섏� �딆쓣 �� �덉쓬 - if (type === 'update') { + if (type === 'create') { + schema = Joi.object({ + title: Joi.string().min(1).max(255).required(), + is_fixed: Joi.boolean().required(), + events: Joi.array().items( + Joi.object({ + time_idx: Joi.number().integer().min(0).max(671).required(), + }) + ).min(1).required() + }); + } else if (type === 'bulk_update') { + schema = Joi.object({ + updates: Joi.array().items( + Joi.object({ + time_idx: Joi.number().integer().min(0).max(671).required(), + title: Joi.string().min(1).max(255).optional(), + is_fixed: Joi.boolean().optional(), + }) + ).min(1).required() + }); + } else if (type === 'bulk_delete') { schema = Joi.object({ - title: Joi.string().min(1).max(255).optional(), - start_time: Joi.date().iso().optional(), - end_time: Joi.date().iso().optional(), - is_fixed: Joi.boolean().optional() - }).or('title', 'start_time', 'end_time', 'is_fixed'); // 理쒖냼 �� 媛� �댁긽�� �꾨뱶媛� �꾩슂 + time_idxs: Joi.array().items( + Joi.number().integer().min(0).max(671).required() + ).min(1).required() + }); } const { error, value } = schema.validate(this.data, { abortEarly: false }); if (error) { - // 紐⑤뱺 �먮윭 硫붿떆吏�瑜� �섎굹�� 臾몄옄�대줈 寃고빀 const errorMessages = error.details.map(detail => detail.message).join(', '); throw new Error(`Validation error: ${errorMessages}`); } - // 寃�利앸맂 �곗씠�곕� 諛섑솚 return value; } } diff --git a/dtos/ScheduleResponseDTO.js b/dtos/ScheduleResponseDTO.js index b8717cf44890ac0233f1505e902213d002f4fc1e..a75316e65e13999800b70b4e23e9c40203dccee8 100644 --- a/dtos/ScheduleResponseDTO.js +++ b/dtos/ScheduleResponseDTO.js @@ -3,12 +3,10 @@ class ScheduleResponseDTO { constructor(schedule) { this.id = schedule.id; - this.user_id = schedule.user_id; + this.user_id = schedule.user_id; this.title = schedule.title; - this.start_time = schedule.start_time; - this.end_time = schedule.end_time; + this.time_idx = schedule.time_idx; // �덈줈�� time_idx �꾨뱶 異붽� this.is_fixed = schedule.is_fixed; - this.expiry_date = schedule.expiry_date; this.createdAt = schedule.createdAt; this.updatedAt = schedule.updatedAt; } diff --git a/middlewares/auth.js b/middlewares/auth.js index 8ae9be046f8afd9efcacc14ed35648cad6fb1206..afc74eaad5520ace4dbb2b36a9a644cec88e8387 100644 --- a/middlewares/auth.js +++ b/middlewares/auth.js @@ -1,13 +1,13 @@ // middlewares/auth.js -exports.isLoggedIn = (req, res, next) => { +exports.isLoggedIn = (req, res, next) => { //濡쒓렇�몃맂 �ъ슜�먯옄留� �묎렐�덉슜 if (req.isAuthenticated()) { return next(); } res.redirect('/auth/login'); }; -exports.isNotLoggedIn = (req, res, next) => { +exports.isNotLoggedIn = (req, res, next) => { //濡쒓렇�� �덈릺硫� 由щ떎�대젆�� if (!req.isAuthenticated()) { return next(); } diff --git a/models/Friend.js b/models/Friend.js index 6354113249d63e690a6be307d9825e47e475ece2..ed0921267e995ac8bf4a85eace2f3b369f13a8db 100644 --- a/models/Friend.js +++ b/models/Friend.js @@ -2,7 +2,7 @@ const { DataTypes } = require('sequelize'); const sequelize = require('../config/sequelize'); -const User = require('./User'); +const User = require('./user'); const Friend = sequelize.define('Friend', { status: { @@ -25,11 +25,4 @@ const Friend = sequelize.define('Friend', { ] }); -// 愿�怨� �ㅼ젙 -Friend.belongsTo(User, { foreignKey: 'requester_id', as: 'requester' }); // 移쒓뎄 �붿껌�� 蹂대궦 �ъ슜�� -Friend.belongsTo(User, { foreignKey: 'receiver_id', as: 'receiver' }); // 移쒓뎄 �붿껌�� 諛쏆� �ъ슜�� - -User.hasMany(Friend, { foreignKey: 'requester_id', as: 'sentRequests' }); // 移쒓뎄 �붿껌�� 蹂대궦 紐⑸줉 -User.hasMany(Friend, { foreignKey: 'receiver_id', as: 'receivedRequests' }); // 移쒓뎄 �붿껌�� 諛쏆� 紐⑸줉 - module.exports = Friend; diff --git a/models/Invite.js b/models/Invite.js new file mode 100644 index 0000000000000000000000000000000000000000..a49c264ba83c345a06cd6e0000f425d354a411e2 --- /dev/null +++ b/models/Invite.js @@ -0,0 +1,37 @@ +// models/Invite.js +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/sequelize'); +const User = require('./User'); +const Meeting = require('./Meeting'); + +const Invite = sequelize.define('Invite', { + status: { + type: DataTypes.ENUM('PENDING', 'ACCEPTED', 'DECLINED'), + allowNull: false, + defaultValue: 'PENDING', + }, +}, { + tableName: 'Invites', + timestamps: true, + underscored: true, + indexes: [ + { + unique: true, + fields: ['meeting_id', 'invitee_id'] + }, + { + fields: ['status'] + } + ] +}); + +// 愿�怨� �ㅼ젙 +// Invite.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' }); +// Invite.belongsTo(User, { foreignKey: 'inviter_id', as: 'inviter' }); // 珥덈��� �ъ슜�� +// Invite.belongsTo(User, { foreignKey: 'invitee_id', as: 'invitee' }); // 珥덈�諛쏆� �ъ슜�� + +// User.hasMany(Invite, { foreignKey: 'inviter_id', as: 'sentInvites' }); // 蹂대궦 珥덈� 紐⑸줉 +// User.hasMany(Invite, { foreignKey: 'invitee_id', as: 'receivedInvites' }); // 諛쏆� 珥덈� 紐⑸줉 +// Meeting.hasMany(Invite, { foreignKey: 'meeting_id', as: 'invites' }); // �대떦 誘명똿�� 紐⑤뱺 珥덈� + +module.exports = Invite; \ No newline at end of file diff --git a/models/index.js b/models/index.js index b9b463f42b06012734157c7f6bb132fb585f55e3..9ad167a836d1ae5924d17bfd1d1f4671a2ab8916 100644 --- a/models/index.js +++ b/models/index.js @@ -1,15 +1,43 @@ // models/index.js const sequelize = require('../config/sequelize'); - -const User = require('./User'); +const User = require('./user'); +const Friend = require('./Friend'); const Schedule = require('./Schedule'); const Meeting = require('./Meeting'); const MeetingParticipant = require('./MeetingParticipant'); //�대뜑紐낆닔�� const Friend = require('./Friend'); const FcmToken = require('./fcmToken'); +const MeetingParticipant = require('./MeetingParticipant'); +const ChatRooms = require('./ChatRooms'); + +// 愿�怨� �ㅼ젙 +Friend.belongsTo(User, { foreignKey: 'requester_id', as: 'requester' }); // 移쒓뎄 �붿껌�� 蹂대궦 �ъ슜�� +Friend.belongsTo(User, { foreignKey: 'receiver_id', as: 'receiver' }); // 移쒓뎄 �붿껌�� 諛쏆� �ъ슜�� + +User.hasMany(Friend, { foreignKey: 'requester_id', as: 'sentRequests' }); // 移쒓뎄 �붿껌�� 蹂대궦 紐⑸줉 +User.hasMany(Friend, { foreignKey: 'receiver_id', as: 'receivedRequests' }); // 移쒓뎄 �붿껌�� 諛쏆� 紐⑸줉 +// �곌� 愿�怨� �ㅼ젙 +Meeting.belongsTo(User, { foreignKey: 'created_by', as: 'creator' }); +User.hasMany(Meeting, { foreignKey: 'created_by', as: 'meetings' }); + +MeetingParticipant.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' }); +Meeting.hasMany(MeetingParticipant, { foreignKey: 'meeting_id', as: 'participants' }); + +MeetingParticipant.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); +User.hasMany(MeetingParticipant, { foreignKey: 'user_id', as: 'meetingParticipations' }); + +Schedule.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); +User.hasMany(Schedule, { foreignKey: 'user_id', as: 'schedules' }); module.exports = { + sequelize, + User, + Friend, + Schedule, + Meeting, + MeetingParticipant, + ChatRooms, sequelize, User, Schedule, diff --git a/models/meeting.js b/models/meeting.js index 68c08137a6998277c4f83e76ec0f9cb75f5a6a2f..9946d1e2c6e9c0fef889c0e848e6be5a1fe4b55d 100644 --- a/models/meeting.js +++ b/models/meeting.js @@ -1,52 +1,53 @@ // models/Meeting.js - const { DataTypes } = require('sequelize'); -const sequelize = require('../config/sequelize'); +const sequelize = require('../config/sequelize'); const User = require('./User'); const Meeting = sequelize.define('Meeting', { - title: { - type: DataTypes.STRING, - allowNull: false, - }, - description: { - type: DataTypes.TEXT, - }, - start_time: { - type: DataTypes.DATE, - allowNull: false, - }, - end_time: { - type: DataTypes.DATE, - allowNull: false, - }, - location: { - type: DataTypes.STRING, - }, - deadline: { - type: DataTypes.DATE, - }, - type: { - type: DataTypes.ENUM('OPEN', 'CLOSE'), - allowNull: false, - }, - created_by: { - type: DataTypes.INTEGER, - allowNull: false, - }, - chatRoomId: { // �덈줈�� �꾨뱶 異붽� - type: DataTypes.STRING, - allowNull: false, - }, + title: { + type: DataTypes.STRING, + allowNull: false, + }, + description: { + type: DataTypes.TEXT, + }, + time_idx_start: { + type: DataTypes.INTEGER, + allowNull: false, + }, + time_idx_end: { + type: DataTypes.INTEGER, + allowNull: false, + }, + location: { + type: DataTypes.STRING, + }, + time_idx_deadline: { + type: DataTypes.INTEGER, + }, + type: { + type: DataTypes.ENUM('OPEN', 'CLOSE'), + allowNull: false, + defaultValue: 'OPEN', + }, + chatRoomId: { + type: DataTypes.UUID, + allowNull: false, + }, + max_num: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 10, // 湲곕낯媛� �ㅼ젙 (�꾩슂�� �곕씪 議곗젙) + }, + cur_num: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 1, // �앹꽦�� �먯떊 �ы븿 + }, }, { - tableName: 'Meetings', - timestamps: false, + tableName: 'Meetings', + timestamps: true, + underscored: true, }); - -// �곌� 愿�怨� �ㅼ젙 -Meeting.belongsTo(User, { foreignKey: 'created_by', as: 'creator' }); -User.hasMany(Meeting, { foreignKey: 'created_by', as: 'meetings' }); - module.exports = Meeting; - diff --git a/models/meetingParticipant.js b/models/meetingParticipant.js index c069ec6c68cd1060094f9f2f0ddcabf710c6fe6a..a12d6951fcf1654a86886c31ca3b6d250617975d 100644 --- a/models/meetingParticipant.js +++ b/models/meetingParticipant.js @@ -1,30 +1,27 @@ -// models/MeetingParticipant.js - const { DataTypes } = require('sequelize'); -const sequelize = require('../config/sequelize'); -const Meeting =require('./Meeting'); -const User = require('./User'); - +const sequelize = require('../config/sequelize'); -const MeetingParticipant = sequelize.define('MeetingParticipant', { - meeting_id: { - type: DataTypes.INTEGER, - allowNull: false +const MeetingParticipant = sequelize.define( + 'MeetingParticipant', + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + meeting_id: { + type: DataTypes.INTEGER, + allowNull: false, + }, + user_id: { + type: DataTypes.INTEGER, + allowNull: false, + }, }, - user_id: { - type: DataTypes.INTEGER, - allowNull: false + { + tableName: 'MeetingParticipants', // �뚯씠釉� �대쫫 �ㅼ젙 + timestamps: false, // createdAt, updatedAt �꾨뱶 鍮꾪솢�깊솕 } -}, { - tableName: 'MeetingParticipants', - timestamps: false, -}); - -MeetingParticipant.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' }); -Meeting.hasMany(MeetingParticipant, { foreignKey: 'meeting_id', as: 'participants' }); - -MeetingParticipant.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); -User.hasMany(MeetingParticipant, { foreignKey: 'user_id', as: 'meetingParticipations' }); - +); module.exports = MeetingParticipant; diff --git a/models/schedule.js b/models/schedule.js index 19a78b28216454f4ebe2eceefbcdabb2047082d3..48dcec42477e6681b77928ed3dc84d62963fcb7f 100644 --- a/models/schedule.js +++ b/models/schedule.js @@ -1,36 +1,40 @@ // models/Schedule.js const { DataTypes } = require('sequelize'); const sequelize = require('../config/sequelize'); -const User = require('./User'); +const User = require('./user'); const Schedule = sequelize.define('Schedule', { title: { type: DataTypes.STRING, allowNull: false, }, - start_time: { - type: DataTypes.DATE, - allowNull: false, - }, - end_time: { - type: DataTypes.DATE, + time_idx: { // �쇱<�쇱쓣 15遺� �⑥쐞濡� �섎늿 �쒓컙 �몃뜳�� + type: DataTypes.INTEGER, allowNull: false, + validate: { + min: 0, + max: 671, // 7�� * 24�쒓컙 * 4 (15遺� �⑥쐞) - 1 + }, }, is_fixed: { type: DataTypes.BOOLEAN, allowNull: false, - defaultValue: false + defaultValue: false, }, - expiry_date: { - type: DataTypes.DATE, - allowNull: true - } }, { tableName: 'Schedules', - timestamps: true, // created_at怨� updated_at �먮룞 愿�由� + timestamps: true, // createdAt怨� updatedAt �먮룞 愿�由� + indexes: [ + { + unique: true, + fields: ['user_id', 'time_idx'], + name: 'unique_schedule_per_user_time', + }, + { + fields: ['time_idx'], + }, + ], }); -Schedule.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); -User.hasMany(Schedule, { foreignKey: 'user_id', as: 'schedules' }); -module.exports = Schedule; \ No newline at end of file +module.exports = Schedule; diff --git a/models/user.js b/models/user.js index bd35bfe461e6f0fb3c7818f2d10dfa5cd29f9af0..7ed604344d59621f069499da5cc892f5594784c9 100644 --- a/models/user.js +++ b/models/user.js @@ -5,11 +5,11 @@ const sequelize = require('../config/sequelize'); const User = sequelize.define('User', { name: { - type: DataTypes.STRING, // VARCHAR + type: DataTypes.STRING, allowNull: false, }, email: { - type: DataTypes.STRING, // VARCHAR + type: DataTypes.STRING, allowNull: false, unique: true, validate: { diff --git a/package-lock.json b/package-lock.json index 037ec06ad91a38be1f2290e5f470efba1ac4bc6f..0d88e6dd404804a6a24730ef20bf0a8275b47975 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,6 @@ "firebase-admin": "^13.0.1", "jest": "^29.7.0", "joi": "^17.13.3", - "mongoose": "^8.8.1", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", "mysql2": "^3.11.4", @@ -32,7 +31,11 @@ "devDependencies": { "artillery": "^2.0.21", "cross-env": "^7.0.3", - "nodemon": "^3.1.7" + "jest": "^29.7.0", + "jest-mock": "^29.7.0", + "mongoose": "^8.8.2", + "nodemon": "^3.1.7", + "sequelize-mock": "^0.10.2" } }, "node_modules/@alcalzone/ansi-tokenize": { @@ -66,6 +69,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -79,6 +83,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -204,7 +209,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", @@ -220,7 +225,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -233,7 +238,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", @@ -247,7 +252,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", @@ -261,7 +266,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", @@ -276,7 +281,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -286,7 +291,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.222.0", @@ -298,7 +303,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -311,7 +316,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", @@ -325,7 +330,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", @@ -394,7 +399,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.693.0.tgz", "integrity": "sha512-WfycTcylmrSOnCN8x/xeIjHa4gIV4UhG85LWLZ3M4US8+HJQ8l4c4WUf+pUoTaSxN86vhbXlz0iRvA89nF854Q==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -447,7 +452,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.693.0.tgz", "integrity": "sha512-QEynrBC26x6TG9ZMzApR/kZ3lmt4lEIs2D+cHuDxt6fDGzahBUsQFBwJqhizzsM97JJI5YvmJhmihoYjdSSaXA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -497,7 +502,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.693.0.tgz", "integrity": "sha512-UEDbYlYtK/e86OOMyFR4zEPyenIxDzO2DRdz3fwVW7RzZ94wfmSwBh/8skzPTuY1G7sI064cjHW0b0QG01Sdtg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -551,7 +556,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.693.0.tgz", "integrity": "sha512-4S2y7VEtvdnjJX4JPl4kDQlslxXEZFnC50/UXVUYSt/AMc5A/GgspFNA5FVz4E3Gwpfobbf23hR2NBF8AGvYoQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -603,7 +608,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.693.0.tgz", "integrity": "sha512-v6Z/kWmLFqRLDPEwl9hJGhtTgIFHjZugSfF1Yqffdxf4n1AWgtHS7qSegakuMyN5pP4K2tvUD8qHJ+gGe2Bw2A==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -626,7 +631,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.693.0.tgz", "integrity": "sha512-hlpV3tkOhpFl87aToH6Q6k7JBNNuARBPk+irPMtgE8ZqpYRP9tJ/RXftirzZ7CqSzc7NEWe/mnbJzRXw7DfgVQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-cognito-identity": "3.693.0", @@ -643,7 +648,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.693.0.tgz", "integrity": "sha512-hMUZaRSF7+iBKZfBHNLihFs9zvpM1CB8MBOTnTp5NGCVkRYF3SB2LH+Kcippe0ats4qCyB1eEoyQX99rERp2iQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -660,7 +665,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.693.0.tgz", "integrity": "sha512-sL8MvwNJU7ZpD7/d2VVb3by1GknIJUxzTIgYtVkDVA/ojo+KRQSSHxcj0EWWXF5DTSh2Tm+LrEug3y1ZyKHsDA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -682,7 +687,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.693.0.tgz", "integrity": "sha512-kvaa4mXhCCOuW7UQnBhYqYfgWmwy7WSBSDClutwSLPZvgrhYj2l16SD2lN4IfYdxARYMJJ1lFYp3/jJG/9Yk4Q==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -709,7 +714,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.693.0.tgz", "integrity": "sha512-42WMsBjTNnjYxYuM3qD/Nq+8b7UdMopUq5OduMDxoM3mFTV6PXMMnfI4Z1TNnR4tYRvPXAnuNltF6xmjKbSJRA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.693.0", @@ -733,7 +738,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.693.0.tgz", "integrity": "sha512-cvxQkrTWHHjeHrPlj7EWXPnFSq8x7vMx+Zn1oTsMpCY445N9KuzjfJTkmNGwU2GT6rSZI9/0MM02aQvl5bBBTQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -751,7 +756,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.693.0.tgz", "integrity": "sha512-479UlJxY+BFjj3pJFYUNC0DCMrykuG7wBAXfsvZqQxKUa83DnH5Q1ID/N2hZLkxjGd4ZW0AC3lTOMxFelGzzpQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-sso": "3.693.0", @@ -771,7 +776,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.693.0.tgz", "integrity": "sha512-8LB210Pr6VeCiSb2hIra+sAH4KUBLyGaN50axHtIgufVK8jbKIctTZcVY5TO9Se+1107TsruzeXS7VeqVdJfFA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -791,7 +796,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.693.0.tgz", "integrity": "sha512-0CCH8GuH1E41Kpq52NujErbUIRewDWLkdbYO8UJGybDbUQ8KC5JG1tP7K20tKYHmVgJGXDHo+XUIG7ogHD6/JA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-cognito-identity": "3.693.0", @@ -820,7 +825,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.693.0.tgz", "integrity": "sha512-BCki6sAZ5jYwIN/t3ElCiwerHad69ipHwPsDCxJQyeiOnJ8HG+lEpnVIfrnI8A0fLQNSF3Gtx6ahfBpKiv1Oug==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -836,7 +841,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.693.0.tgz", "integrity": "sha512-dXnXDPr+wIiJ1TLADACI1g9pkSB21KkMIko2u4CJ2JCBoxi5IqeTnVoa6YcC8GdFNVRl+PorZ3Zqfmf1EOTC6w==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -851,7 +856,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.693.0.tgz", "integrity": "sha512-0LDmM+VxXp0u3rG0xQRWD/q6Ubi7G8I44tBPahevD5CaiDZTkmNTrVUf0VEJgVe0iCKBppACMBDkLB0/ETqkFw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -867,7 +872,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.693.0.tgz", "integrity": "sha512-/KUq/KEpFFbQmNmpp7SpAtFAdViquDfD2W0QcG07zYBfz9MwE2ig48ALynXm5sMpRmnG7sJXjdvPtTsSVPfkiw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -886,7 +891,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.693.0.tgz", "integrity": "sha512-YLUkMsUY0GLW/nfwlZ69cy1u07EZRmsv8Z9m0qW317/EZaVx59hcvmcvb+W4bFqj5E8YImTjoGfE4cZ0F9mkyw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -904,7 +909,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.693.0.tgz", "integrity": "sha512-nDBTJMk1l/YmFULGfRbToOA2wjf+FkQT4dMgYCv+V9uSYsMzQj8A7Tha2dz9yv4vnQgYaEiErQ8d7HVyXcVEoA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -924,7 +929,7 @@ "version": "3.692.0", "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.692.0.tgz", "integrity": "sha512-RpNvzD7zMEhiKgmlxGzyXaEcg2khvM7wd5sSHVapOcrde1awQSOMGI4zKBQ+wy5TnDfrm170ROz/ERLYtrjPZA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.0", @@ -938,7 +943,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.693.0.tgz", "integrity": "sha512-eo4F6DRQ/kxS3gxJpLRv+aDNy76DxQJL5B3DPzpr9Vkq0ygVoi4GT5oIZLVaAVIJmi6k5qq9dLsYZfWLUxJJSg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -954,7 +959,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz", "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -967,7 +972,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.693.0.tgz", "integrity": "sha512-6EUfuKOujtddy18OLJUaXfKBgs+UcbZ6N/3QV4iOkubCUdeM1maIqs++B9bhCbWeaeF5ORizJw5FTwnyNjE/mw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -980,7 +985,7 @@ "version": "3.693.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.693.0.tgz", "integrity": "sha512-td0OVX8m5ZKiXtecIDuzY3Y3UZIzvxEr57Hp21NOwieqKCG2UeyQWWeGPv0FQaU7dpTkvFmVNI+tx9iB8V/Nhg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/middleware-user-agent": "3.693.0", @@ -1457,6 +1462,7 @@ "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", @@ -1471,6 +1477,7 @@ "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1480,6 +1487,7 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -1510,6 +1518,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1527,12 +1536,14 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -1542,6 +1553,7 @@ "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.2", @@ -1558,6 +1570,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1568,6 +1581,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.25.9", @@ -1584,6 +1598,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -1593,6 +1608,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -1602,12 +1618,14 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, "license": "ISC" }, "node_modules/@babel/helper-module-imports": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -1621,6 +1639,7 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -1638,6 +1657,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1647,6 +1667,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1656,6 +1677,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1665,6 +1687,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1674,6 +1697,7 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.25.9", @@ -1687,6 +1711,7 @@ "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.26.0" @@ -1702,6 +1727,7 @@ "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1714,6 +1740,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1726,6 +1753,7 @@ "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" @@ -1738,6 +1766,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1753,6 +1782,7 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1768,6 +1798,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1780,6 +1811,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1792,6 +1824,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1807,6 +1840,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1819,6 +1853,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1831,6 +1866,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1843,6 +1879,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1855,6 +1892,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1867,6 +1905,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1879,6 +1918,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1894,6 +1934,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1909,6 +1950,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1924,6 +1966,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.9", @@ -1938,6 +1981,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.9", @@ -1956,6 +2000,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1973,12 +2018,14 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/@babel/types": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1999,6 +2046,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, "license": "MIT" }, "node_modules/@colors/colors": { @@ -2813,6 +2861,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -2829,6 +2878,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -2842,6 +2892,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -2854,6 +2905,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -2869,6 +2921,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -2881,6 +2934,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2890,6 +2944,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -2907,6 +2962,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2922,6 +2978,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2938,6 +2995,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2947,6 +3005,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2959,6 +3018,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -3006,6 +3066,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3015,6 +3076,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3030,6 +3092,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3046,6 +3109,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, "funding": [ { "type": "github", @@ -3061,6 +3125,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3070,6 +3135,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -3082,6 +3148,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3094,6 +3161,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", @@ -3109,6 +3177,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, "license": "MIT", "dependencies": { "expect": "^29.7.0", @@ -3122,6 +3191,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -3134,6 +3204,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -3151,6 +3222,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -3166,6 +3238,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -3209,6 +3282,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3219,6 +3293,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3228,6 +3303,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3243,6 +3319,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -3253,6 +3330,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3270,6 +3348,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -3290,6 +3369,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3299,6 +3379,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -3311,6 +3392,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -3324,6 +3406,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -3336,6 +3419,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3348,6 +3432,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -3360,6 +3445,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -3374,6 +3460,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3384,6 +3471,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -3399,6 +3487,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -3414,6 +3503,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -3440,6 +3530,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3450,6 +3541,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3465,6 +3557,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3481,6 +3574,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3490,6 +3584,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3502,6 +3597,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -3519,6 +3615,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3534,6 +3631,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3550,6 +3648,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3559,6 +3658,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3571,6 +3671,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -3585,6 +3686,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3595,6 +3697,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3604,6 +3707,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3613,6 +3717,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -3667,6 +3772,7 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "dev": true, "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" @@ -5426,6 +5532,7 @@ "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, "license": "MIT" }, "node_modules/@sindresorhus/is": { @@ -5445,6 +5552,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -5454,6 +5562,7 @@ "version": "10.3.0", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -5463,7 +5572,7 @@ "version": "3.1.8", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5477,7 +5586,7 @@ "version": "3.0.12", "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.11", @@ -5494,7 +5603,7 @@ "version": "2.5.3", "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.3.tgz", "integrity": "sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/middleware-serde": "^3.0.10", @@ -5514,7 +5623,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.11", @@ -5531,7 +5640,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^4.1.7", @@ -5545,7 +5654,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5561,7 +5670,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5572,7 +5681,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5607,7 +5716,7 @@ "version": "3.0.12", "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^4.1.7", @@ -5622,7 +5731,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz", "integrity": "sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^2.5.3", @@ -5642,7 +5751,7 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz", "integrity": "sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.11", @@ -5663,7 +5772,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "devOptional": true, + "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -5677,7 +5786,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5691,7 +5800,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5705,7 +5814,7 @@ "version": "3.1.11", "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^3.1.10", @@ -5721,7 +5830,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.8", @@ -5738,7 +5847,7 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5752,7 +5861,7 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5766,7 +5875,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5781,7 +5890,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5795,7 +5904,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1" @@ -5808,7 +5917,7 @@ "version": "3.1.11", "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -5822,7 +5931,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", @@ -5842,7 +5951,7 @@ "version": "3.4.4", "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.4.tgz", "integrity": "sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^2.5.3", @@ -5861,7 +5970,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5874,7 +5983,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/querystring-parser": "^3.0.10", @@ -5886,7 +5995,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^3.0.0", @@ -5901,7 +6010,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5911,7 +6020,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5924,7 +6033,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", @@ -5938,7 +6047,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5951,7 +6060,7 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz", "integrity": "sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^3.1.10", @@ -5968,7 +6077,7 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz", "integrity": "sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/config-resolver": "^3.0.12", @@ -5987,7 +6096,7 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.11", @@ -6002,7 +6111,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6015,7 +6124,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.1", @@ -6029,7 +6138,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^3.0.10", @@ -6044,7 +6153,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/fetch-http-handler": "^4.1.1", @@ -6064,7 +6173,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6077,7 +6186,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^3.0.0", @@ -6828,6 +6937,7 @@ "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -6841,6 +6951,7 @@ "version": "7.6.8", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -6850,6 +6961,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -6860,6 +6972,7 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" @@ -6941,6 +7054,7 @@ "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -6963,12 +7077,14 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" @@ -6978,6 +7094,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" @@ -7106,6 +7223,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, "license": "MIT" }, "node_modules/@types/tough-cookie": { @@ -7125,12 +7243,14 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "dev": true, "license": "MIT" }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/webidl-conversions": "*" @@ -7140,6 +7260,7 @@ "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, "license": "MIT", "dependencies": { "@types/yargs-parser": "*" @@ -7149,6 +7270,7 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, "license": "MIT" }, "node_modules/@typescript-eslint/types": { @@ -7393,6 +7515,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -7442,6 +7565,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -7621,6 +7745,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" @@ -8306,6 +8431,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", @@ -8327,6 +8453,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8342,6 +8469,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8358,6 +8486,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8367,6 +8496,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8379,6 +8509,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -8395,6 +8526,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -8411,6 +8543,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8420,6 +8553,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -8435,6 +8569,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -8461,6 +8596,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", @@ -8654,7 +8790,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/brace-expansion": { @@ -8670,6 +8806,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -8689,6 +8826,7 @@ "version": "4.24.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -8721,6 +8859,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" @@ -8730,6 +8869,7 @@ "version": "6.9.0", "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=16.20.1" @@ -9021,6 +9161,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9030,6 +9171,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9039,6 +9181,7 @@ "version": "1.0.30001680", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -9104,6 +9247,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -9214,6 +9358,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true, "license": "MIT" }, "node_modules/clean-stack": { @@ -9539,6 +9684,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, "license": "MIT", "engines": { "iojs": ">= 1.0.0", @@ -9562,6 +9708,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, "license": "MIT" }, "node_modules/color-convert": { @@ -9649,6 +9796,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "devOptional": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -9716,6 +9864,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, "license": "MIT" }, "node_modules/convert-to-spaces": { @@ -9830,6 +9979,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -9851,6 +10001,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9866,6 +10017,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9882,6 +10034,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9891,6 +10044,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10031,6 +10185,7 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -10064,6 +10219,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10196,6 +10352,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10330,6 +10487,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -10539,12 +10697,14 @@ "version": "1.5.63", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.63.tgz", "integrity": "sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==", + "dev": true, "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -10753,6 +10913,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -10941,6 +11102,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -11030,6 +11192,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -11053,6 +11216,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -11065,12 +11229,14 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, "license": "ISC" }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -11088,6 +11254,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -11263,6 +11430,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -11279,7 +11447,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "devOptional": true, + "dev": true, "funding": [ { "type": "github", @@ -11334,6 +11502,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" @@ -11406,6 +11575,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -11633,12 +11803,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "devOptional": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -11855,6 +12027,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -11913,6 +12086,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -11992,6 +12166,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -12315,6 +12490,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, "license": "MIT" }, "node_modules/htmlparser2": { @@ -12475,6 +12651,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -12542,6 +12719,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -12561,6 +12739,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -12597,6 +12776,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "devOptional": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -12853,6 +13033,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, "license": "MIT" }, "node_modules/is-binary-path": { @@ -12964,6 +13145,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -13029,6 +13211,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -13087,6 +13270,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13180,6 +13364,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -13189,6 +13374,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", @@ -13205,6 +13391,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -13219,6 +13406,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13228,6 +13416,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13240,6 +13429,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -13254,6 +13444,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -13271,12 +13462,14 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/istanbul-reports": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -13411,6 +13604,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -13437,6 +13631,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, "license": "MIT", "dependencies": { "execa": "^5.0.0", @@ -13451,6 +13646,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -13482,6 +13678,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -13497,6 +13694,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -13513,6 +13711,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13522,6 +13721,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13534,6 +13734,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -13567,6 +13768,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13576,6 +13778,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -13591,6 +13794,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -13607,6 +13811,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -13621,12 +13826,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13636,6 +13843,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -13650,6 +13858,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -13662,6 +13871,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13674,6 +13884,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -13691,6 +13902,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -13709,6 +13921,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -13718,6 +13931,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -13763,6 +13977,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -13778,6 +13993,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -13788,6 +14004,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -13804,6 +14021,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, "funding": [ { "type": "github", @@ -13820,6 +14038,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -13840,6 +14059,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13849,6 +14069,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -13861,6 +14082,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13873,6 +14095,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13885,6 +14108,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -13900,6 +14124,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -13915,6 +14140,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -13931,6 +14157,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -13940,6 +14167,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13952,6 +14180,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -13964,6 +14193,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -13980,6 +14210,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -13995,6 +14226,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14011,6 +14243,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14020,6 +14253,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14032,6 +14266,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -14049,6 +14284,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -14058,6 +14294,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14083,6 +14320,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", @@ -14096,6 +14334,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -14111,6 +14350,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14126,6 +14366,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14142,6 +14383,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14151,6 +14393,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14163,6 +14406,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", @@ -14183,6 +14427,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14198,6 +14443,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14214,6 +14460,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14223,6 +14470,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14235,6 +14483,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14249,6 +14498,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -14266,6 +14516,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -14275,6 +14526,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -14295,6 +14547,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", @@ -14308,6 +14561,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14323,6 +14577,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14339,6 +14594,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14348,6 +14604,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14360,6 +14617,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -14392,6 +14650,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14407,6 +14666,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14423,6 +14683,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14432,6 +14693,7 @@ "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -14442,6 +14704,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14454,6 +14717,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -14487,6 +14751,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14502,6 +14767,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -14512,6 +14778,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14529,6 +14796,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -14549,6 +14817,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14558,6 +14827,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -14570,6 +14840,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14579,6 +14850,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14591,6 +14863,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -14622,6 +14895,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14637,6 +14911,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14653,6 +14928,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14662,6 +14938,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14674,6 +14951,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14691,6 +14969,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14706,6 +14985,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14722,6 +15002,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, "funding": [ { "type": "github", @@ -14737,6 +15018,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14746,6 +15028,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14758,6 +15041,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14775,6 +15059,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14790,6 +15075,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -14802,6 +15088,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14818,6 +15105,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14827,6 +15115,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14839,6 +15128,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -14858,6 +15148,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14867,6 +15158,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14882,6 +15174,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14898,6 +15191,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14907,6 +15201,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -14920,6 +15215,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -14932,6 +15228,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14944,6 +15241,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -14959,6 +15257,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14968,6 +15267,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -15045,12 +15345,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -15081,6 +15383,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -15119,6 +15422,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -15282,6 +15586,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.0.0" @@ -15301,6 +15606,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -15323,6 +15629,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -15383,6 +15690,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, "license": "MIT" }, "node_modules/locate-path": { @@ -15598,6 +15906,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -15644,6 +15953,7 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" @@ -15715,6 +16025,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "dev": true, "license": "MIT" }, "node_modules/merge-descriptors": { @@ -15730,6 +16041,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, "license": "MIT" }, "node_modules/merge2": { @@ -15755,6 +16067,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -15801,6 +16114,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -16199,6 +16513,7 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", @@ -16245,6 +16560,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@types/whatwg-url": "^11.0.2", @@ -16252,9 +16568,10 @@ } }, "node_modules/mongoose": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz", - "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.2.tgz", + "integrity": "sha512-jCTSqDANfRzk909v4YoZQi7jlGRB2MTvgG+spVBc/BA4tOs1oWJr//V6yYujqNq9UybpOtsSfBqxI0dSOEFJHQ==", + "dev": true, "license": "MIT", "dependencies": { "bson": "^6.7.0", @@ -16277,6 +16594,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/morgan": { @@ -16311,6 +16629,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -16320,6 +16639,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dev": true, "license": "MIT", "dependencies": { "debug": "4.x" @@ -16332,6 +16652,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -16349,6 +16670,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/ms": { @@ -16473,6 +16795,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, "license": "MIT" }, "node_modules/negotiator": { @@ -16626,12 +16949,14 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, "license": "MIT" }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, "license": "MIT" }, "node_modules/node-source-walk": { @@ -16759,6 +17084,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16882,6 +17208,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -16991,6 +17318,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -17170,6 +17498,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -17217,6 +17546,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -17265,6 +17595,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -17283,6 +17614,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, "license": "MIT" }, "node_modules/parse5": { @@ -17406,6 +17738,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17415,6 +17748,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17488,12 +17822,14 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -17506,6 +17842,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17515,6 +17852,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -17527,6 +17865,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -17540,6 +17879,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -17552,6 +17892,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -17567,6 +17908,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -17769,6 +18111,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -17783,6 +18126,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -17899,6 +18243,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -17986,6 +18331,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -17995,6 +18341,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, "funding": [ { "type": "individual", @@ -18181,6 +18528,7 @@ "version": "18.1.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "dev": true, "license": "MIT" }, "node_modules/react-reconciler": { @@ -18353,6 +18701,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -18375,6 +18724,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18401,6 +18751,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -18728,6 +19079,18 @@ "node": ">=10.0.0" } }, + "node_modules/sequelize-mock": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/sequelize-mock/-/sequelize-mock-0.10.2.tgz", + "integrity": "sha512-Vu95by/Bmhcx9PHKlZe+w7/7zw1AycV/SeevxQ5lDokAb50H7Kaf2SkjK5mqKxHWX6y/ICZ8JEfyMOg0nd1M2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.4.6", + "inflection": "^1.10.0", + "lodash": "^4.16.4" + } + }, "node_modules/sequelize-pool": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", @@ -18848,6 +19211,7 @@ "version": "17.1.3", "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "dev": true, "license": "MIT" }, "node_modules/signal-exit": { @@ -18942,12 +19306,14 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -19140,6 +19506,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -19181,6 +19548,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dev": true, "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" @@ -19226,6 +19594,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/sqlite3": { @@ -19691,6 +20060,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" @@ -19703,6 +20073,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -19909,6 +20280,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -19927,7 +20299,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/stubs": { @@ -20391,6 +20763,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -20405,6 +20778,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -20416,6 +20790,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -20436,6 +20811,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -20584,12 +20960,14 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -20640,6 +21018,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, "license": "MIT", "dependencies": { "punycode": "^2.3.0" @@ -20761,6 +21140,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, "license": "0BSD" }, "node_modules/tsutils": { @@ -20848,6 +21228,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -20857,6 +21238,7 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -21015,6 +21397,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, "funding": [ { "type": "opencollective", @@ -21108,6 +21491,7 @@ "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -21122,6 +21506,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -21189,6 +21574,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" @@ -21208,6 +21594,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -21276,6 +21663,7 @@ "version": "13.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dev": true, "license": "MIT", "dependencies": { "tr46": "^4.1.1", @@ -21550,6 +21938,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -21563,6 +21952,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, "license": "ISC" }, "node_modules/ws": { @@ -21750,6 +22140,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" diff --git a/package.json b/package.json index 87d652d754d14f81403193d40eb8690b9843d4b6..346adb30a86ed84f9edfcd1e3b6b4bc2acc37c0f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "firebase-admin": "^13.0.1", "jest": "^29.7.0", "joi": "^17.13.3", - "mongoose": "^8.8.1", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", "mysql2": "^3.11.4", @@ -36,6 +35,10 @@ "devDependencies": { "artillery": "^2.0.21", "cross-env": "^7.0.3", - "nodemon": "^3.1.7" + "jest": "^29.7.0", + "jest-mock": "^29.7.0", + "mongoose": "^8.8.2", + "nodemon": "^3.1.7", + "sequelize-mock": "^0.10.2" } } diff --git a/routes/inviteRoutes.js b/routes/inviteRoutes.js new file mode 100644 index 0000000000000000000000000000000000000000..cef8ad9a65e62f1112487bb1cc20973782c4cea1 --- /dev/null +++ b/routes/inviteRoutes.js @@ -0,0 +1,32 @@ +// routes/inviteRoutes.js +const express = require('express'); +const router = express.Router(); +const inviteController = require('../controllers/inviteController'); +const { isLoggedIn } = require('../middlewares/auth'); + + +router.use(isLoggedIn); +// 珥덈� �묐떟 +router.post('/respond', async (req, res) => { + const { inviteId, response } = req.body; + const userId = req.user.id; // �몄쬆�� �ъ슜�� ID + try { + const result = await inviteController.respondToInvite(inviteId, userId, response); + res.status(200).json({ success: true, result }); + } catch (error) { + res.status(400).json({ success: false, message: error.message }); + } +}); + +// 諛쏆� 珥덈� 議고쉶 +router.get('/received', async (req, res) => { + const userId = req.user.id; // �몄쬆�� �ъ슜�� ID + try { + const invites = await inviteController.getReceivedInvites(userId); + res.status(200).json({ success: true, invites }); + } catch (error) { + res.status(400).json({ success: false, message: error.message }); + } +}); + +module.exports = router; diff --git a/services/chatService.js b/services/chatService.js index c5e3a3cbe37f6d985544a7eb56ed8d1e2eb8fdc2..e53ceaa0c5dd4e4c329fe5d6765de8de7efd6c99 100644 --- a/services/chatService.js +++ b/services/chatService.js @@ -1,4 +1,4 @@ -const ChatRoom = require('../models/chatRooms'); +const ChatRoom = require('../models/ChatRooms'); const { v4: uuidv4 } = require('uuid'); class ChatService { diff --git a/services/friendService.js b/services/friendService.js index 3f18b768e8848057d8efc6019324248d6e1205c7..bb995bb9ef69f4221f2ff40dbc452f21ba75fba4 100644 --- a/services/friendService.js +++ b/services/friendService.js @@ -1,8 +1,7 @@ // services/friendService.js const { Op } = require('sequelize'); -const Friend = require('../models/Friend'); -const User = require('../models/User'); +const { Friend,User} = require('../models'); const sequelize = require('../config/sequelize'); // DTO �꾪룷�� diff --git a/services/friendService.test.js b/services/friendService.test.js index fe70afc57ed6929f1642889a884b99a9c046bb82..02394ee0066ee60c52fada5fc48149148c0e1bad 100644 --- a/services/friendService.test.js +++ b/services/friendService.test.js @@ -1,8 +1,9 @@ // test/friendService.test.js const sequelize = require('../config/sequelize'); // Sequelize �몄뒪�댁뒪 �꾪룷�� -const User = require('../models/User'); -const Friend = require('../models/Friend'); +// const User = require('../models/User'); +// const Friend = require('../models/Friend'); +const { Friend,User} = require('../models'); const friendService = require('./friendService'); // FriendService �꾪룷�� // Sequelize�� Op瑜� 媛��몄삤湲� �꾪빐 異붽� diff --git a/test/friendrelation.test.js b/services/friendrelation.test.js similarity index 97% rename from test/friendrelation.test.js rename to services/friendrelation.test.js index 4c5c1ede7371f09d7b6dc5a47f05f5b94e9d0dd5..d94267ceb8c37659160427813f6bb9ff571ded0d 100644 --- a/test/friendrelation.test.js +++ b/services/friendrelation.test.js @@ -1,8 +1,7 @@ // test/friend.test.js const sequelize = require('../config/sequelize'); // �섍꼍 蹂��섏뿉 �곕씪 �ㅻⅨ �몄뒪�댁뒪 �ъ슜 -const User = require('../models/User'); -const Friend = require('../models/Friend'); +const { Friend,User} = require('../models'); beforeAll(async () => { // �곗씠�곕쿋�댁뒪 �숆린�� diff --git a/services/meetingService.js b/services/meetingService.js index caa098863a36fffe10634775356b02f2f3ed4307..d7b6023a2ecfebfe98d55ca4a7d43496c3bf3f2b 100644 --- a/services/meetingService.js +++ b/services/meetingService.js @@ -2,6 +2,12 @@ const { Meeting, MeetingParticipant, User, Schedule } = require('../models'); const ChatRoom = require('../models/chatRooms'); const FcmToken = require('../models/fcmToken'); +// services/meetingService.js +const { v4: uuidv4 } = require('uuid'); +const { Op } = require('sequelize'); +const sequelize = require('../config/sequelize'); // �몃옖��뀡 愿�由щ� �꾪빐 sequelize �몄뒪�댁뒪 �꾩슂 +const { Meeting, MeetingParticipant, User, Schedule, Invite, Friend } = require('../models'); +const ChatRooms = require('../models/ChatRooms'); const MeetingResponseDTO = require('../dtos/MeetingResponseDTO'); const MeetingDetailResponseDTO = require('../dtos/MeetingDetailResponseDTO'); const CreateMeetingRequestDTO = require('../dtos/CreateMeetingRequestDTO'); @@ -10,14 +16,36 @@ const chatService = require('./chatService'); class MeetingService { /** - * 踰덇컻 紐⑥엫 �앹꽦 - * @returns �앹꽦�� 紐⑥엫 ID�� 梨꾪똿諛� ID + * �꾩옱 �쒓컙�� time_idx濡� 蹂��섑븯�� �좏떥由ы떚 �⑥닔 + * �붿슂�쇰��� �쇱슂�쇨퉴吏� 15遺� �⑥쐞濡� ���� �몃뜳�ㅻ� �좊떦 + * �꾩옱 �쒓컙�� ���� �몃뜳�� (0 ~ 671) */ + getCurrentTimeIdx() { + const today = new Date(); + const jsDayOfWeek = today.getDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday + const adjustedDayOfWeek = (jsDayOfWeek + 6) % 7; // 0=Monday, ..., 6=Sunday + const hours = today.getHours(); + const minutes = today.getMinutes(); + const timeIdx = hours * 4 + Math.floor(minutes / 15); // 15遺� �⑥쐞 �몃뜳�� + const totalIdx = adjustedDayOfWeek * 96 + timeIdx; // 二� �꾩껜 �몃뜳�� + return totalIdx; + } + async createMeeting(meetingData) { const createMeetingDTO = new CreateMeetingRequestDTO(meetingData); createMeetingDTO.validate(); - const { title, description, start_time, end_time, location, deadline, type, created_by } = meetingData; + const { + title, + description, + time_idx_start, + time_idx_end, + location, + time_idx_deadline, + type, + created_by, + max_num, + } = meetingData; // �ъ슜�먯� FCM �좏겙 議고쉶 const user = await this._findUserWithFcmTokens(created_by); @@ -45,23 +73,55 @@ class MeetingService { const chatRoomId = chatRoomResponse.chatRoomId; - const newMeeting = await Meeting.create({ - title, - description, - start_time, - end_time, - location, - deadline, - type, - created_by, - chatRoomId, - }, { transaction }); + // 紐⑥엫 �앹꽦 + const newMeeting = await Meeting.create( + { + title, + description, + time_idx_start, + time_idx_end, + location, + time_idx_deadline, + type, + created_by, + chatRoomId, + max_num, // max_num 異붽� + cur_num: 1, // �앹꽦�� �먯떊 �ы븿 + }, + { transaction } + ); - await MeetingParticipant.create({ - meeting_id: newMeeting.id, - user_id: created_by, - }, { transaction }); + // 紐⑥엫 李멸��� 異붽� (�앹꽦�� �먯떊) + await MeetingParticipant.create( + { + meeting_id: newMeeting.id, + user_id: created_by, + }, + { transaction } + ); + // �ㅼ�以� �앹꽦 (紐⑥엫 �쒓컙 踰붿쐞 �� 紐⑤뱺 time_idx�� ���� �앹꽦) + const events = []; + for (let idx = time_idx_start; idx <= time_idx_end; idx++) { + events.push({ time_idx: idx }); + } + await ScheduleService.createSchedules( + { + userId: created_by, + title: `踰덇컻 紐⑥엫: ${title}`, + is_fixed: false, + events: events, + }, + transaction + ); + + // 移쒓뎄 珥덈� 濡쒖쭅 �몄텧 + const invitedFriendIds = await this.sendInvites({ + meetingId: newMeeting.id, + creatorId: created_by, + time_idx_start, + time_idx_end, + }, transaction); await ScheduleService.createSchedule({ userId: created_by, title: `踰덇컻 紐⑥엫: ${title}`, @@ -77,70 +137,284 @@ class MeetingService { this._addParticipantToChatRoom(chatRoom, user, userFcmTokens); } - return { meeting_id: newMeeting.id, chatRoomId }; + return { meeting_id: newMeeting.id, chatRoomId, invitedFriendIds }; }); } - /** - * 踰덇컻 紐⑥엫 紐⑸줉 議고쉶 - * @return 紐⑥엫 紐⑸줉 DTO 諛곗뿴 - */ + async sendInvites({ meetingId, creatorId, time_idx_start, time_idx_end }, transaction) { + // 1. 移쒓뎄 紐⑸줉 媛��몄삤湲� (ACCEPTED �곹깭) + const friends = await Friend.findAll({ + where: { + [Op.or]: [ + { requester_id: creatorId, status: 'ACCEPTED' }, + { receiver_id: creatorId, status: 'ACCEPTED' }, + ], + }, + transaction, + }); + + const friendIds = friends.map(friend => + friend.requester_id === creatorId ? friend.receiver_id : friend.requester_id + ); + + if (friendIds.length === 0) { + // 移쒓뎄媛� �녾굅�� 紐⑤뱺 移쒓뎄媛� 珥덈�諛쏆� 紐삵븿 + return []; + } + const schedules = await Schedule.findAll({ + where: { + user_id: { [Op.in]: friendIds }, + time_idx: { + [Op.between]: [time_idx_start, time_idx_end], + }, + }, + transaction, + }); + + // �ㅼ�以꾩씠 寃뱀튂�� 移쒓뎄 ID瑜� 異붿텧 + const conflictedFriendIds = schedules.map(schedule => schedule.user_id); + + // �ㅼ�以꾩씠 寃뱀튂吏� �딅뒗 移쒓뎄 ID �꾪꽣留� + const availableFriendIds = friendIds.filter(friendId => !conflictedFriendIds.includes(friendId)); + + if (availableFriendIds.length === 0) { + // �ㅼ�以꾩씠 寃뱀튂�� 移쒓뎄媛� 紐⑤몢 �덉쓬 + return []; + } + const invitePromises = availableFriendIds.map(inviteeId => { + return Invite.create({ + meeting_id: meetingId, + inviter_id: creatorId, + invitee_id: inviteeId, + status: 'PENDING', + }, { transaction }); + }); + + await Promise.all(invitePromises); + + return availableFriendIds; + } + + + async joinMeeting(meetingId, userId) { + const meeting = await Meeting.findByPk(meetingId); + console.log(`李몄뿬�섎젮�� 紐⑥엫: ${JSON.stringify(meeting)}`); + if (!meeting) { + throw new Error('紐⑥엫�� 李얠쓣 �� �놁뒿�덈떎.'); + } + if (meeting.type === 'CLOSE') { + throw new Error('�대� 留덇컧�� 紐⑥엫�낅땲��.'); + } + if (meeting.time_idx_deadline !== undefined) { + const currentTimeIdx = this.getCurrentTimeIdx(); // �꾩옱 �쒓컙 �몃뜳�� + if (currentTimeIdx >= meeting.time_idx_deadline) { + throw new Error('李멸� �좎껌�� 留덇컧�섏뿀�듬땲��.'); + } + } + const existingParticipant = await MeetingParticipant.findOne({ + where: { meeting_id: meetingId, user_id: userId }, + }); + if (existingParticipant) { + throw new Error('�대� 李멸��� �ъ슜�먯엯�덈떎.'); + } + + // �몃옖��뀡�� �ъ슜�섏뿬 李멸��� 異붽� 諛� �ㅼ�以� �낅뜲�댄듃瑜� �먯옄�곸쑝濡� 泥섎━ + await sequelize.transaction(async (transaction) => { + if (meeting.cur_num >= meeting.max_num) { + throw new Error("紐⑥엫 �몄썝�� 紐⑤몢 李쇱뒿�덈떎."); + } + // �ㅼ�以� 異⑸룎 �뺤씤 + const hasConflict = await ScheduleService.checkScheduleOverlapByTime( + userId, + meeting.time_idx_start, + meeting.time_idx_end, + transaction + ); + console.log(`�ㅼ�以� 異⑸룎 寃곌낵: ${hasConflict}`); + if (hasConflict) { + throw new Error("�ㅼ�以꾩씠 寃뱀묩�덈떎. �ㅻⅨ 紐⑥엫�� 李멸��섏꽭��."); + } + + await MeetingParticipant.create( + { meeting_id: meetingId, user_id: userId }, + { transaction } + ); + + // �ㅼ�以� �앹꽦 (紐⑥엫 �쒓컙 踰붿쐞 �� 紐⑤뱺 time_idx�� ���� �앹꽦) + const events = []; + for ( + let idx = meeting.time_idx_start; + idx <= meeting.time_idx_end; + idx++ + ) { + events.push({ time_idx: idx }); + } + await ScheduleService.createSchedules( + { + userId: userId, + title: `踰덇컻 紐⑥엫: ${meeting.title}`, + is_fixed: true, + events: events, + }, + transaction + ); + + // 梨꾪똿諛� 李멸� (MongoDB) + const user = await User.findOne({ + where: { id: userId }, + transaction, + }); + const chatRoom = await ChatRooms.findOne({ + chatRoomId: meeting.chatRoomId, + }); + if (chatRoom && !chatRoom.participants.includes(user.name)) { + chatRoom.participants.push(user.name); + chatRoom.isOnline.set(user.name, true); + chatRoom.lastReadAt.set(user.name, new Date()); + chatRoom.lastReadLogId.set(user.name, null); + await chatRoom.save(); + } + + // �꾩옱 �몄썝 �� 利앷� + await meeting.increment("cur_num", { by: 1, transaction }); + }); + } + + async getMeetings(userId) { const meetings = await Meeting.findAll({ - attributes: ['id', 'title', 'description', 'start_time', 'end_time', 'location', 'deadline', 'type'], + attributes: [ + 'id', + 'title', + 'description', + 'time_idx_start', + 'time_idx_end', + 'location', + 'time_idx_deadline', + 'type', + 'max_num', + 'cur_num', + ], include: [ - { - model: User, - as: 'creator', - attributes: ['name'], - }, { model: MeetingParticipant, as: 'participants', - attributes: ['user_id'], + where: { user_id: userId }, // userId�� 留ㅽ븨�� 誘명똿留� 媛��몄샂 + attributes: [], + }, + { + model: User, + as: 'creator', + attributes: ['name'], // 誘명똿 �앹꽦�먯쓽 �대쫫留� �꾩슂 }, ], }); return meetings.map((meeting) => { const creatorName = meeting.creator ? meeting.creator.name : 'Unknown'; - const isParticipant = meeting.participants.some(participant => participant.user_id === parseInt(userId, 10)); - - return new MeetingResponseDTO( - meeting, - isParticipant, - false, // isScheduleConflict: �꾩슂 �� 異붽� 濡쒖쭅 援ы쁽 - creatorName - ); + return new MeetingResponseDTO(meeting, true, false, creatorName); }); } - /** - * 踰덇컻 紐⑥엫 李멸� - */ - async joinMeeting(meetingId, userId) { + + async closeMeeting(meetingId) { const meeting = await Meeting.findByPk(meetingId); - if (!meeting) { throw new Error('紐⑥엫�� 李얠쓣 �� �놁뒿�덈떎.'); } - if (meeting.type === 'CLOSE') { throw new Error('�대� 留덇컧�� 紐⑥엫�낅땲��.'); } + meeting.type = 'CLOSE'; + await meeting.save(); + return meeting; + } - if (new Date() > new Date(meeting.deadline)) { - throw new Error('李멸� �좎껌�� 留덇컧�섏뿀�듬땲��.'); + + async joinMeeting(meetingId, userId) { + const meeting = await Meeting.findByPk(meetingId); + console.log(`李몄뿬�섎젮�� 紐⑥엫: ${JSON.stringify(meeting)}`); + if (!meeting) { + throw new Error('紐⑥엫�� 李얠쓣 �� �놁뒿�덈떎.'); } - - const existingParticipant = await MeetingParticipant.findOne({ - where: { meeting_id: meetingId, user_id: userId } + if (meeting.type === 'CLOSE') { + throw new Error('�대� 留덇컧�� 紐⑥엫�낅땲��.'); + } + if (meeting.time_idx_deadline !== undefined) { + const currentTimeIdx = this.getCurrentTimeIdx(); // �꾩옱 �쒓컙 �몃뜳�� + if (currentTimeIdx >= meeting.time_idx_deadline) { + throw new Error('李멸� �좎껌�� 留덇컧�섏뿀�듬땲��.'); + } + } + const existingParticipant = await MeetingParticipant.findOne({ + where: { meeting_id: meetingId, user_id: userId }, }); - if (existingParticipant) { throw new Error('�대� 李멸��� �ъ슜�먯엯�덈떎.'); } + // �몃옖��뀡�� �ъ슜�섏뿬 李멸��� 異붽� 諛� �ㅼ�以� �낅뜲�댄듃瑜� �먯옄�곸쑝濡� 泥섎━ + await sequelize.transaction(async (transaction) => { + // �ㅼ�以� 異⑸룎 �뺤씤 + // �꾩옱 �몄썝 �� �뺤씤 + if (meeting.cur_num >= meeting.max_num) { + throw new Error("紐⑥엫 �몄썝�� 紐⑤몢 李쇱뒿�덈떎."); + } + + const hasConflict = await ScheduleService.checkScheduleOverlapByTime( + userId, + meeting.time_idx_start, + meeting.time_idx_end, + transaction + ); + console.log(`�ㅼ�以� 異⑸룎 寃곌낵: ${hasConflict}`); + if (hasConflict) { + throw new Error("�ㅼ�以꾩씠 寃뱀묩�덈떎. �ㅻⅨ 紐⑥엫�� 李멸��섏꽭��."); + } + + // 李멸��� 異붽� + await MeetingParticipant.create( + { meeting_id: meetingId, user_id: userId }, + { transaction } + ); + + // �ㅼ�以� �앹꽦 (紐⑥엫 �쒓컙 踰붿쐞 �� 紐⑤뱺 time_idx�� ���� �앹꽦) + const events = []; + for ( + let idx = meeting.time_idx_start; + idx <= meeting.time_idx_end; + idx++ + ) { + events.push({ time_idx: idx }); + } + await ScheduleService.createSchedules( + { + userId: userId, + title: `踰덇컻 紐⑥엫: ${meeting.title}`, + is_fixed: true, + events: events, + }, + transaction + ); + + // 梨꾪똿諛� 李멸� (MongoDB) + const user = await User.findOne({ + where: { id: userId }, + transaction, + }); + const chatRoom = await ChatRooms.findOne({ + chatRoomId: meeting.chatRoomId, + }); + if (chatRoom && !chatRoom.participants.includes(user.name)) { + chatRoom.participants.push(user.name); + chatRoom.isOnline.set(user.name, true); + chatRoom.lastReadAt.set(user.name, new Date()); + chatRoom.lastReadLogId.set(user.name, null); + await chatRoom.save(); + } + + // �꾩옱 �몄썝 �� 利앷� + await meeting.increment("cur_num", { by: 1, transaction }); await Meeting.sequelize.transaction(async (transaction) => { const hasConflict = await ScheduleService.checkScheduleOverlap( userId, @@ -172,28 +446,27 @@ class MeetingService { this._addParticipantToChatRoom(chatRoom, user, userFcmTokens); } }); + }); } + - /** - * 踰덇컻 紐⑥엫 �곸꽭 議고쉶 - * @return 紐⑥엫 �곸꽭 DTO - */ + async getMeetingDetail(meetingId) { const meeting = await Meeting.findByPk(meetingId, { include: [ { model: User, - as: 'creator', - attributes: ['name'], + as: "creator", + attributes: ["name"], }, { model: MeetingParticipant, - as: 'participants', + as: "participants", include: [ { model: User, - as: 'participantUser', - attributes: ['name', 'email'], + as: "user", // 'participantUser'�먯꽌 'user'濡� �섏젙 + attributes: ["name", "email"], }, ], }, @@ -201,7 +474,7 @@ class MeetingService { }); if (!meeting) { - throw new Error('紐⑥엫�� 李얠쓣 �� �놁뒿�덈떎.'); + throw new Error("紐⑥엫�� 李얠쓣 �� �놁뒿�덈떎."); } return new MeetingDetailResponseDTO(meeting); diff --git a/services/meetingService.test.js b/services/meetingService.test.js new file mode 100644 index 0000000000000000000000000000000000000000..1dc2f055a01fe2e263cdbe8715a14f75189ab008 --- /dev/null +++ b/services/meetingService.test.js @@ -0,0 +1,497 @@ +// test/meetingService.test.js +const sequelize = require('../config/sequelize'); +const { Op } = require('sequelize'); +const { Meeting, MeetingParticipant, User, Schedule } = require('../models'); +const MeetingService = require('../services/meetingService'); +const ScheduleService = require('../services/scheduleService'); +const ChatRooms = require('../models/ChatRooms'); +const CreateMeetingRequestDTO = require('../dtos/CreateMeetingRequestDTO'); +const MeetingResponseDTO = require('../dtos/MeetingResponseDTO'); +const MeetingDetailResponseDTO = require('../dtos/MeetingDetailResponseDTO'); + + + +beforeAll(async () => { + // �곗씠�곕쿋�댁뒪 珥덇린�� 諛� �숆린�� + await sequelize.sync({ force: true }); +}); + +beforeEach(async () => { + // �몃옒 �� �쒖꽌�� �곕씪 �곗씠�� ��젣 + await MeetingParticipant.destroy({ where: {}, truncate: true }); + await Meeting.destroy({ where: {}, truncate: true }); + await Schedule.destroy({ where: {}, truncate: true }); + await User.destroy({ where: {}, truncate: true }); + + // �붾� �ъ슜�� �곗씠�� �쎌엯 + await User.bulkCreate([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' }, + { id: 3, name: 'Charlie', email: 'charlie@example.com' }, + ]); + + // ChatRooms Mock �ㅼ젙 + jest.spyOn(ChatRooms.prototype, 'save').mockResolvedValue(undefined); + jest.spyOn(ChatRooms, 'findOne').mockResolvedValue({ + participants: [], + isOnline: new Map(), + lastReadAt: new Map(), + lastReadLogId: new Map(), + save: jest.fn().mockResolvedValue(true), + }); +}); + +afterEach(() => { + // Mock 蹂듭썝 諛� 珥덇린�� + jest.restoreAllMocks(); + jest.clearAllMocks(); +}); + +afterAll(async () => { + // �곗씠�곕쿋�댁뒪 �곌껐 醫낅즺 + await sequelize.close(); +}); + +describe('MeetingService - getMeetings', () => { + beforeEach(async () => { + await MeetingParticipant.destroy({ where: {} }); + await Meeting.destroy({ where: {} }); + await Schedule.destroy({ where: {} }); + await User.destroy({ where: {} }); + + // Create dummy users + await User.bulkCreate([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' }, + { id: 3, name: 'Charlie', email: 'charlie@example.com' }, + ]); + }); + + test('should retrieve meetings where the user is a participant', async () => { + const meetingData = { + title: 'Meeting with Alice', + description: 'Discuss project.', + time_idx_start: 10, + time_idx_end: 20, + location: 'Room A', + time_idx_deadline: 8, + type: 'OPEN', + created_by: 1, + }; + + const createdMeeting = await MeetingService.createMeeting(meetingData); + + await MeetingParticipant.create({ + meeting_id: createdMeeting.meeting_id, + user_id: 2, + }); + + const meetings = await MeetingService.getMeetings(2); // Bob's user ID + + expect(meetings).toBeDefined(); + expect(Array.isArray(meetings)).toBe(true); + expect(meetings.length).toBe(1); + + const [meeting] = meetings; + expect(meeting.title).toBe('Meeting with Alice'); + expect(meeting.creatorName).toBe('Alice'); + expect(meeting.isParticipant).toBe(true); + }); + + test('should retrieve meetings where the user is the creator', async () => { + const meetingData = { + title: 'Alice-created Meeting', + description: 'Team discussion.', + time_idx_start: 15, + time_idx_end: 25, + location: 'Room B', + time_idx_deadline: 12, + type: 'OPEN', + created_by: 1, + }; + + await MeetingService.createMeeting(meetingData); + + const meetings = await MeetingService.getMeetings(1); // Alice's user ID + + expect(meetings).toBeDefined(); + expect(Array.isArray(meetings)).toBe(true); + expect(meetings.length).toBe(1); + + const [meeting] = meetings; + expect(meeting.title).toBe('Alice-created Meeting'); + expect(meeting.creatorName).toBe('Alice'); + expect(meeting.isParticipant).toBe(true); + }); + + test('should not include meetings where the user is neither a participant nor the creator', async () => { + const meetingData = { + title: 'Meeting with Bob', + description: 'General discussion.', + time_idx_start: 30, + time_idx_end: 40, + location: 'Room C', + time_idx_deadline: 28, + type: 'OPEN', + created_by: 2, + }; + + await MeetingService.createMeeting(meetingData); + + const meetings = await MeetingService.getMeetings(1); // Alice's user ID + + expect(meetings).toBeDefined(); + expect(Array.isArray(meetings)).toBe(true); + expect(meetings.length).toBe(0); // Alice is not a participant or the creator + }); + + test('should retrieve multiple meetings correctly', async () => { + const meetingData1 = { + title: 'Meeting 1', + description: 'First meeting.', + time_idx_start: 50, + time_idx_end: 60, + location: 'Room D', + time_idx_deadline: 48, + type: 'OPEN', + created_by: 1, + }; + + const meetingData2 = { + title: 'Meeting 2', + description: 'Second meeting.', + time_idx_start: 70, + time_idx_end: 80, + location: 'Room E', + time_idx_deadline: 68, + type: 'OPEN', + created_by: 2, + }; + + await MeetingService.createMeeting(meetingData1); + const meeting2 = await MeetingService.createMeeting(meetingData2); + + + await MeetingParticipant.create({ + meeting_id: meeting2.meeting_id, + user_id: 1, + }); + + const meetings = await MeetingService.getMeetings(1); // Alice's user ID + + expect(meetings).toBeDefined(); + expect(Array.isArray(meetings)).toBe(true); + expect(meetings.length).toBe(2); // Alice is either the creator or a participant in two meetings + + const meetingTitles = meetings.map((m) => m.title); + expect(meetingTitles).toContain('Meeting 1'); + expect(meetingTitles).toContain('Meeting 2'); + }); + + test('should return an empty array if the user has no meetings', async () => { + const meetings = await MeetingService.getMeetings(3); + expect(meetings).toBeDefined(); + expect(Array.isArray(meetings)).toBe(true); + expect(meetings.length).toBe(0); + }); +}); + + +describe('MeetingService - Integration: createMeeting, joinMeeting, getMeetings', () => { + beforeEach(async () => { + await MeetingParticipant.destroy({ where: {} }); + await Meeting.destroy({ where: {} }); + await Schedule.destroy({ where: {} }); + await User.destroy({ where: {} }); + + // Create dummy users + await User.bulkCreate([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' }, + { id: 3, name: 'Charlie', email: 'charlie@example.com' }, + ]); + }); + + test('should create a meeting, allow multiple users to join, and retrieve them correctly', async () => { + // Step 1: Create a meeting + const meetingData = { + title: 'Integration Test Meeting', + description: 'Test meeting for integration.', + time_idx_start: 10, + time_idx_end: 20, + location: 'Conference Room A', + time_idx_deadline: 8, + type: 'OPEN', + created_by: 1, + }; + + const createdMeeting = await MeetingService.createMeeting(meetingData); + + expect(createdMeeting).toBeDefined(); + expect(createdMeeting.meeting_id).toBeDefined(); + expect(createdMeeting.chatRoomId).toBeDefined(); + + // Step 2: Bob and Charlie join the meeting + jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(5); // Ensure deadline is not passed + await MeetingService.joinMeeting(createdMeeting.meeting_id, 2); // Bob joins + await MeetingService.joinMeeting(createdMeeting.meeting_id, 3); // Charlie joins + + // Step 3: Retrieve meetings for Alice (creator) + const aliceMeetings = await MeetingService.getMeetings(1); + expect(aliceMeetings).toBeDefined(); + expect(aliceMeetings.length).toBe(1); + + const aliceMeeting = aliceMeetings[0]; + expect(aliceMeeting.title).toBe('Integration Test Meeting'); + expect(aliceMeeting.creatorName).toBe('Alice'); + expect(aliceMeeting.isParticipant).toBe(true); + + // Step 4: Retrieve meetings for Bob (participant) + const bobMeetings = await MeetingService.getMeetings(2); + expect(bobMeetings).toBeDefined(); + expect(bobMeetings.length).toBe(1); + + const bobMeeting = bobMeetings[0]; + expect(bobMeeting.title).toBe('Integration Test Meeting'); + expect(bobMeeting.creatorName).toBe('Alice'); + expect(bobMeeting.isParticipant).toBe(true); + + // Step 5: Retrieve meetings for Charlie (participant) + const charlieMeetings = await MeetingService.getMeetings(3); + expect(charlieMeetings).toBeDefined(); + expect(charlieMeetings.length).toBe(1); + + const charlieMeeting = charlieMeetings[0]; + expect(charlieMeeting.title).toBe('Integration Test Meeting'); + expect(charlieMeeting.creatorName).toBe('Alice'); + expect(charlieMeeting.isParticipant).toBe(true); + }); + + test('should not allow joining a meeting after the deadline', async () => { + const meetingData = { + title: 'Deadline Test Meeting', + description: 'Meeting to test deadlines.', + time_idx_start: 30, + time_idx_end: 40, + location: 'Conference Room B', + time_idx_deadline: 25, + type: 'OPEN', + created_by: 1, // Alice creates the meeting + }; + + const createdMeeting = await MeetingService.createMeeting(meetingData); + + jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(26); // Simulate time after the deadline + + await expect( + MeetingService.joinMeeting(createdMeeting.meeting_id, 2) + ).rejects.toThrow('李멸� �좎껌�� 留덇컧�섏뿀�듬땲��.'); + }); + + test('should prevent duplicate joining of a meeting', async () => { + const meetingData = { + title: 'Duplicate Join Test Meeting', + description: 'Meeting to test duplicate join handling.', + time_idx_start: 50, + time_idx_end: 60, + location: 'Conference Room C', + time_idx_deadline: 48, + type: 'OPEN', + created_by: 1, // Alice creates the meeting + }; + + const createdMeeting = await MeetingService.createMeeting(meetingData); + + jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(45); // Ensure deadline is not passed + await MeetingService.joinMeeting(createdMeeting.meeting_id, 2); // Bob joins + + // Attempt duplicate join + await expect( + MeetingService.joinMeeting(createdMeeting.meeting_id, 2) + ).rejects.toThrow('�대� 李멸��� �ъ슜�먯엯�덈떎.'); + }); + + test('should prevent joining when schedule conflicts', async () => { + const meetingData = { + title: 'Conflict Test Meeting', + description: 'Meeting to test schedule conflict.', + time_idx_start: 70, + time_idx_end: 80, + location: 'Conference Room D', + time_idx_deadline: 68, + type: 'OPEN', + created_by: 1, // Alice creates the meeting + }; + + const createdMeeting = await MeetingService.createMeeting(meetingData); + + // Step 1: Virtually set current time before the deadline + jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(65); // �꾩옱 �쒓컙�� �곕뱶�쇱씤蹂대떎 �묒쓬 + + // Step 2: Simulate schedule conflict + jest.spyOn(ScheduleService, 'checkScheduleOverlapByTime').mockResolvedValue(true); // �ㅼ�以� 異⑸룎 諛쒖깮 + + // Step 3: Expect schedule conflict error + await expect( + MeetingService.joinMeeting(createdMeeting.meeting_id, 2) + ).rejects.toThrow('�ㅼ�以꾩씠 寃뱀묩�덈떎. �ㅻⅨ 紐⑥엫�� 李멸��섏꽭��.'); +}); + +}); + +describe('MeetingService2', () => { + beforeEach(async () => { + // �곗씠�곕쿋�댁뒪 珥덇린�� + await MeetingParticipant.destroy({ where: {} }); + await Meeting.destroy({ where: {} }); + await Schedule.destroy({ where: {} }); + await User.destroy({ where: {} }); + + // �붾� �ъ슜�� �앹꽦 + await User.bulkCreate([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' }, + { id: 3, name: 'Charlie', email: 'charlie@example.com' }, + ]); + }); + + test('�ъ슜�먭� �щ윭 紐⑥엫�� 李몄뿬�섍퀬 �대� �뺥솗�� 議고쉶�� �� �덉뼱�� �쒕떎', async () => { + // 1�④퀎: 寃뱀튂吏� �딅뒗 �쒓컙���� 紐⑥엫 �앹꽦 + const meetingData1 = { + title: 'Morning Meeting', + description: 'Morning planning meeting.', + time_idx_start: 10, + time_idx_end: 20, + location: 'Room A', + time_idx_deadline: 8, + type: 'OPEN', + created_by: 1, // Alice媛� 紐⑥엫 �앹꽦 + }; + + const meetingData2 = { + title: 'Lunch Meeting', + description: 'Lunch and discussion.', + time_idx_start: 30, + time_idx_end: 40, + location: 'Room B', + time_idx_deadline: 28, + type: 'OPEN', + created_by: 2, // Bob�� 紐⑥엫 �앹꽦 + }; + + const meeting1 = await MeetingService.createMeeting(meetingData1); + const meeting2 = await MeetingService.createMeeting(meetingData2); + + // 紐⑥엫 �앹꽦 �뺤씤 + expect(meeting1).toBeDefined(); + expect(meeting2).toBeDefined(); + + // 2�④퀎: Charlie媛� �� 紐⑥엫�� 李몄뿬 + jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(5); // 留덇컧 �쒓컙�� 珥덇낵�섏� �딅룄濡� �ㅼ젙 + await MeetingService.joinMeeting(meeting1.meeting_id, 3); // Charlie媛� Morning Meeting 李몄뿬 + await MeetingService.joinMeeting(meeting2.meeting_id, 3); // Charlie媛� Lunch Meeting 李몄뿬 + + // 3�④퀎: Charlie�� 李몄뿬 紐⑥엫 議고쉶 + const charlieMeetings = await MeetingService.getMeetings(3); // Charlie�� �ъ슜�� ID + expect(charlieMeetings).toBeDefined(); + expect(Array.isArray(charlieMeetings)).toBe(true); + expect(charlieMeetings.length).toBe(2); // Charlie�� 2媛쒖쓽 紐⑥엫�� 李몄뿬 + + // 媛� 紐⑥엫�� �몃� �뺣낫 �뺤씤 + const morningMeeting = charlieMeetings.find(meeting => meeting.title === 'Morning Meeting'); + const lunchMeeting = charlieMeetings.find(meeting => meeting.title === 'Lunch Meeting'); + + expect(morningMeeting).toBeDefined(); + expect(morningMeeting.creatorName).toBe('Alice'); + expect(morningMeeting.isParticipant).toBe(true); + + expect(lunchMeeting).toBeDefined(); + expect(lunchMeeting.creatorName).toBe('Bob'); + expect(lunchMeeting.isParticipant).toBe(true); + + // 異붽� 寃�利�: 媛� 紐⑥엫�� ���� Charlie�� �ㅼ�以꾩씠 �щ컮瑜닿쾶 �앹꽦�섏뿀�붿� �뺤씤 + const charlieSchedules = await Schedule.findAll({ where: { user_id: 3 } }); + expect(charlieSchedules.length).toBe(2 * (20 - 10 + 1)); // �� 紐⑥엫, 媛� 紐⑥엫留덈떎 11媛쒖쓽 �ㅼ�以� (10~20, 30~40) + + // 以묐났 �ㅼ�以꾩씠 �녿뒗吏� �뺤씤 + const timeIndicesMorning = charlieSchedules + .filter(schedule => schedule.title === `踰덇컻 紐⑥엫: ${meetingData1.title}`) + .map(schedule => schedule.time_idx); + const timeIndicesLunch = charlieSchedules + .filter(schedule => schedule.title === `踰덇컻 紐⑥엫: ${meetingData2.title}`) + .map(schedule => schedule.time_idx); + + // Morning Meeting�� �쒓컙�� �뺤씤 + for (let i = 10; i <= 20; i++) { + expect(timeIndicesMorning).toContain(i); + } + + // Lunch Meeting�� �쒓컙�� �뺤씤 + for (let i = 30; i <= 40; i++) { + expect(timeIndicesLunch).toContain(i); + } + }); + + test('媛� �ъ슜�먯쓽 紐⑥엫�� �뺥솗�� 議고쉶�댁빞 �쒕떎', async () => { + // 1�④퀎: 寃뱀튂吏� �딅뒗 �쒓컙���� 紐⑥엫 �앹꽦 + const meetingData1 = { + title: 'Morning Meeting', + description: 'Morning planning meeting.', + time_idx_start: 10, + time_idx_end: 20, + location: 'Room A', + time_idx_deadline: 8, + type: 'OPEN', + created_by: 1, // Alice媛� 紐⑥엫 �앹꽦 + }; + + const meetingData2 = { + title: 'Lunch Meeting', + description: 'Lunch and discussion.', + time_idx_start: 30, + time_idx_end: 40, + location: 'Room B', + time_idx_deadline: 28, + type: 'OPEN', + created_by: 2, // Bob�� 紐⑥엫 �앹꽦 + }; + + const meeting1 = await MeetingService.createMeeting(meetingData1); + const meeting2 = await MeetingService.createMeeting(meetingData2); + + // 2�④퀎: Charlie媛� �� 紐⑥엫�� 李몄뿬 + jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(5); // 留덇컧 �쒓컙�� 珥덇낵�섏� �딅룄濡� �ㅼ젙 + await MeetingService.joinMeeting(meeting1.meeting_id, 3); // Charlie媛� Morning Meeting 李몄뿬 + await MeetingService.joinMeeting(meeting2.meeting_id, 3); // Charlie媛� Lunch Meeting 李몄뿬 + + // 3�④퀎: Alice�� 紐⑥엫 議고쉶 + const aliceMeetings = await MeetingService.getMeetings(1); // Alice�� �ъ슜�� ID + expect(aliceMeetings.length).toBe(1); // Alice�� �섎굹�� 紐⑥엫 �앹꽦 + expect(aliceMeetings[0].title).toBe('Morning Meeting'); + expect(aliceMeetings[0].isParticipant).toBe(true); + + // 4�④퀎: Bob�� 紐⑥엫 議고쉶 + const bobMeetings = await MeetingService.getMeetings(2); // Bob�� �ъ슜�� ID + expect(bobMeetings.length).toBe(1); // Bob�� �섎굹�� 紐⑥엫 �앹꽦 + expect(bobMeetings[0].title).toBe('Lunch Meeting'); + expect(bobMeetings[0].isParticipant).toBe(true); + + // 5�④퀎: Charlie�� 紐⑥엫 議고쉶 + const charlieMeetings = await MeetingService.getMeetings(3); // Charlie�� �ъ슜�� ID + expect(charlieMeetings.length).toBe(2); // Charlie�� �� 紐⑥엫�� 李몄뿬 + const meetingTitles = charlieMeetings.map(meeting => meeting.title); + expect(meetingTitles).toContain('Morning Meeting'); + expect(meetingTitles).toContain('Lunch Meeting'); + + // 異붽� 寃�利�: 媛� �ъ슜�먯쓽 �ㅼ�以꾩쓣 �뺤씤�섏뿬 異⑸룎�� �녿뒗吏� �뺤씤 + const aliceSchedules = await Schedule.findAll({ where: { user_id: 1 } }); + expect(aliceSchedules.length).toBe(11); // Morning Meeting: 10-20 + + const bobSchedules = await Schedule.findAll({ where: { user_id: 2 } }); + expect(bobSchedules.length).toBe(11); // Lunch Meeting: 30-40 + + const charlieSchedules = await Schedule.findAll({ where: { user_id: 3 } }); + expect(charlieSchedules.length).toBe(22); // �� 紐⑥엫, 媛� 紐⑥엫留덈떎 11媛쒖쓽 �ㅼ�以� (10~20, 30~40) + }); +}); + diff --git a/services/schedule.test.js b/services/schedule.test.js index d1cc0f220d0f908d8f5ab4dddd5b814262de0e78..373d1e5b67bb78e5e043483ed798a012bbb1f114 100644 --- a/services/schedule.test.js +++ b/services/schedule.test.js @@ -1,244 +1,366 @@ -// test/schedule.test.js - -const sequelize = require('../config/sequelize'); -const User = require('../models/User'); -const Friend = require('../models/Friend'); -const Schedule = require('../models/Schedule'); -const scheduleService = require('./scheduleService'); +// test/scheduleService.test.js +const sequelize = require('../config/sequelize'); // �ㅼ젣 寃쎈줈�� 留욊쾶 �섏젙 +const { Schedule, User } = require('../models'); +const ScheduleService = require('../services/scheduleService'); // Uppercase 'S'濡� 媛��몄삤湲� +const ScheduleResponseDTO = require('../dtos/ScheduleResponseDTO'); beforeAll(async () => { - await sequelize.sync({ force: true }); - // �붾� �ъ슜�� �앹꽦 - await User.bulkCreate([ - { id: 1, name: 'Alice', email: 'alice@example.com' }, - { id: 2, name: 'Bob', email: 'bob@example.com' }, - ]); - - // �붾� 移쒓뎄 愿�怨� �앹꽦 - await Friend.create({ - id: 1, - requester_id: 1, - receiver_id: 2, - status: 'ACCEPTED', - }); - - // �붾� �ㅼ�以� �앹꽦 - await Schedule.create({ - id: 1, - user_id: 1, - title: 'Alice\'s Fixed Schedule', - start_time: new Date('2024-05-01T09:00:00Z'), - end_time: new Date('2024-05-01T10:00:00Z'), - is_fixed: true, - expiry_date: null, - }); - - await Schedule.create({ - id: 2, - user_id: 1, - title: 'Alice\'s Flexible Schedule', - start_time: new Date('2024-05-02T11:00:00Z'), - end_time: new Date('2024-05-02T12:00:00Z'), - is_fixed: false, - expiry_date: new Date('2024-05-08T00:00:00Z'), // �ㅼ쓬 �붿슂�� - }); + // �뚯뒪�� �ㅼ쐞�멸� �쒖옉�섍린 �꾩뿉 �곗씠�곕쿋�댁뒪瑜� �숆린�뷀빀�덈떎. + await sequelize.sync({ force: true }); +}); + +beforeEach(async () => { + // 媛� �뚯뒪�멸� �쒖옉�섍린 �꾩뿉 湲곗〈 �곗씠�곕� ��젣�⑸땲��. + await Schedule.destroy({ where: {} }); + await User.destroy({ where: {} }); + + // �붾� �ъ슜�� �앹꽦 + await User.bulkCreate([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' }, + { id: 3, name: 'Charlie', email: 'charlie@example.com' }, + ]); + + // �붾� �ㅼ�以� �앹꽦 + await Schedule.bulkCreate([ + { id: 1, user_id: 1, title: 'Alice Fixed Schedule 1', time_idx: 36, is_fixed: true }, + { id: 2, user_id: 1, title: 'Alice Flexible Schedule 1', time_idx: 44, is_fixed: false }, + { id: 3, user_id: 2, title: 'Bob Fixed Schedule 1', time_idx: 60, is_fixed: true }, + { id: 4, user_id: 2, title: 'Bob Flexible Schedule 1', time_idx: 61, is_fixed: false }, + { id: 5, user_id: 3, title: 'Charlie Fixed Schedule 1', time_idx: 100, is_fixed: true }, + ]); }); afterAll(async () => { - // �곗씠�곕쿋�댁뒪 �곌껐 醫낅즺 - await sequelize.close(); + await sequelize.close(); }); -describe('Schedule Service', () => { - describe('createSchedule', () => { - test('should create a new fixed schedule successfully', async () => { - const scheduleData = { - userId: 2, - title: 'Bob\'s Fixed Schedule', - start_time: new Date('2024-05-03T14:00:00Z'), - end_time: new Date('2024-05-03T15:00:00Z'), - is_fixed: true, - }; - - const schedule = await scheduleService.createSchedule(scheduleData); - - - expect(schedule).toBeDefined(); - expect(schedule.user_id).toBe(2); - expect(schedule.title).toBe('Bob\'s Fixed Schedule'); - expect(schedule.is_fixed).toBe(true); - expect(schedule.expiry_date).toBeNull(); - }); +describe('ScheduleService', () => { + describe('createSchedules', () => { + test('should create multiple new fixed schedules successfully', async () => { + const scheduleData = { + userId: 1, + title: 'Alice Fixed Schedule Bulk', + is_fixed: true, + events: [ + { time_idx: 50 }, // Valid time_idx + { time_idx: 51 }, + ], + }; + + const schedules = await ScheduleService.createSchedules(scheduleData); + + expect(schedules).toBeDefined(); + expect(Array.isArray(schedules)).toBe(true); + expect(schedules.length).toBe(2); + + schedules.forEach((schedule, index) => { + expect(schedule.user_id).toBe(1); + expect(schedule.title).toBe('Alice Fixed Schedule Bulk'); + expect(schedule.is_fixed).toBe(true); + expect(schedule.time_idx).toBe(scheduleData.events[index].time_idx); + }); + + // �곗씠�곕쿋�댁뒪�� �ㅼ젣濡� 異붽��섏뿀�붿� �뺤씤 + const dbSchedules = await Schedule.findAll({ + where: { user_id: 1, title: 'Alice Fixed Schedule Bulk' }, + }); + expect(dbSchedules.length).toBe(2); + }); - test('should create a new flexible schedule with expiry date', async () => { - const scheduleData = { - userId: 2, - title: 'Bob\'s Flexible Schedule', - start_time: new Date('2024-05-04T16:00:00Z'), - end_time: new Date('2024-05-04T17:00:00Z'), - is_fixed: false, - }; - - const schedule = await scheduleService.createSchedule(scheduleData); - - expect(schedule).toBeDefined(); - expect(schedule.user_id).toBe(2); - expect(schedule.title).toBe('Bob\'s Flexible Schedule'); - expect(schedule.is_fixed).toBe(false); - expect(schedule.expiry_date).toBeInstanceOf(Date); - - // expiry_date媛� �ㅼ쓬 �붿슂�쇰줈 �ㅼ젙�섏뿀�붿� �뺤씤 - const expectedExpiryDate = new Date('2024-05-06T00:00:00Z'); // 2024-05-06�� �ㅼ쓬 �붿슂�� - expect(schedule.expiry_date.toISOString()).toBe(expectedExpiryDate.toISOString()); - }); + test('should create multiple new flexible schedules successfully', async () => { + const scheduleData = { + userId: 2, + title: 'Bob Flexible Schedule Bulk', + is_fixed: false, + events: [ + { time_idx: 62 }, + { time_idx: 63 }, + ], + }; + + const schedules = await ScheduleService.createSchedules(scheduleData); + + expect(schedules).toBeDefined(); + expect(Array.isArray(schedules)).toBe(true); + expect(schedules.length).toBe(2); + + schedules.forEach((schedule, index) => { + expect(schedule.user_id).toBe(2); + expect(schedule.title).toBe('Bob Flexible Schedule Bulk'); + expect(schedule.is_fixed).toBe(false); + expect(schedule.time_idx).toBe(scheduleData.events[index].time_idx); + }); + + // �곗씠�곕쿋�댁뒪�� �ㅼ젣濡� 異붽��섏뿀�붿� �뺤씤 + const dbSchedules = await Schedule.findAll({ + where: { user_id: 2, title: 'Bob Flexible Schedule Bulk' }, + }); + expect(dbSchedules.length).toBe(2); + }); - test('should throw error when schedule times overlap with existing schedule', async () => { - const scheduleData = { - userId: 1, - title: 'Alice\'s Overlapping Schedule', - start_time: new Date('2024-05-01T09:30:00Z'), // 湲곗〈 �ㅼ�以꾧낵 寃뱀묠 - end_time: new Date('2024-05-01T10:30:00Z'), - is_fixed: false, - }; + test('should throw error when creating schedules with overlapping time_idx', async () => { + const scheduleData = { + userId: 1, + title: 'Alice Overlapping Schedule', + is_fixed: false, + events: [ + { time_idx: 36 }, // Existing schedule for Alice + ], + }; + + await expect(ScheduleService.createSchedules(scheduleData)) + .rejects + .toThrow('Schedule overlaps with existing schedule at time_idx 36'); + }); - await expect(scheduleService.createSchedule(scheduleData)).rejects.toThrow('Schedule overlaps with existing schedule'); + test('should throw error when creating schedules with invalid time_idx', async () => { + const scheduleData = { + userId: 1, + title: 'Alice Invalid Schedule', + is_fixed: false, + events: [ + { time_idx: 700 }, // Invalid time_idx + ], + }; + + await expect(ScheduleService.createSchedules(scheduleData)) + .rejects + .toThrow('Validation error: Validation max on time_idx failed'); + }); }); - test('should throw error when start_time is after end_time', async () => { - const scheduleData = { - userId: 1, - title: 'Invalid Schedule', - start_time: new Date('2024-05-05T18:00:00Z'), - end_time: new Date('2024-05-05T17:00:00Z'), // start_time�� �� �섏쨷 - is_fixed: false, - }; + describe('updateSchedules', () => { + test('should update multiple existing schedules successfully', async () => { + const updateData = { + updates: [ + { time_idx: 36, title: 'Alice Updated Fixed Schedule', is_fixed: true }, + { time_idx: 44, title: 'Alice Updated Flexible Schedule', is_fixed: false }, + ], + }; + + const updatedSchedules = await ScheduleService.updateSchedules(1, updateData.updates); + + expect(updatedSchedules).toBeDefined(); + expect(Array.isArray(updatedSchedules)).toBe(true); + expect(updatedSchedules.length).toBe(2); + + updatedSchedules.forEach((schedule, index) => { + expect(schedule.title).toBe(updateData.updates[index].title); + expect(schedule.is_fixed).toBe(updateData.updates[index].is_fixed); + expect(schedule.time_idx).toBe(updateData.updates[index].time_idx); + }); + + // �곗씠�곕쿋�댁뒪�먯꽌 �낅뜲�댄듃 �뺤씤 + const dbSchedule1 = await Schedule.findOne({ where: { user_id: 1, time_idx: 36 } }); + const dbSchedule2 = await Schedule.findOne({ where: { user_id: 1, time_idx: 44 } }); + + expect(dbSchedule1.title).toBe('Alice Updated Fixed Schedule'); + expect(dbSchedule2.title).toBe('Alice Updated Flexible Schedule'); + }); - await expect(scheduleService.createSchedule(scheduleData)).rejects.toThrow('Start time must be before end time'); - }); - }); - - describe('updateSchedule', () => { - test('should update an existing schedule successfully', async () => { - const updateData = { - title: 'Alice\'s Updated Flexible Schedule', - start_time: new Date('2024-05-02T11:30:00Z'), - end_time: new Date('2024-05-02T12:30:00Z'), - }; - - const updatedSchedule = await scheduleService.updateSchedule(2, 1, updateData); - - expect(updatedSchedule).toBeDefined(); - expect(updatedSchedule.title).toBe('Alice\'s Updated Flexible Schedule'); - expect(updatedSchedule.start_time.toISOString()).toBe(new Date('2024-05-02T11:30:00Z').toISOString()); - expect(updatedSchedule.end_time.toISOString()).toBe(new Date('2024-05-02T12:30:00Z').toISOString()); - expect(updatedSchedule.expiry_date).toBeInstanceOf(Date); - }); + test('should throw error when updating a non-existing schedule', async () => { + const updateData = { + updates: [ + { time_idx: 999, title: 'Non-existing Schedule' }, + ], + }; - test('should throw error when updating a non-existing schedule', async () => { - const updateData = { - title: 'Non-existing Schedule', - start_time: new Date('2024-05-06T10:00:00Z'), - end_time: new Date('2024-05-06T11:00:00Z'), - }; + await expect(ScheduleService.updateSchedules(1, updateData.updates)) + .rejects + .toMatchObject({ message: 'Schedule not found at time_idx 999' }); + }); - await expect(scheduleService.updateSchedule(999, 1, updateData)).rejects.toThrow('Schedule not found'); + test('should throw error when creating schedules with overlapping time_idx', async () => { + // 癒쇱�, �덈줈�� �ㅼ�以꾩쓣 �앹꽦�섏뿬 time_idx 50�� �ъ슜 + await ScheduleService.createSchedules({ + userId: 1, + title: 'Alice Another Schedule', + is_fixed: false, + events: [ + { time_idx: 50 }, + ], + }); + + // �숈씪�� time_idx濡� �ㅼ�以꾩쓣 �앹꽦�섎젮 �� �� �ㅻ쪟媛� 諛쒖깮�섎뒗吏� �뚯뒪�� + const scheduleData = { + userId: 1, + title: 'Alice Overlapping Schedule', + is_fixed: false, + events: [ + { time_idx: 50 }, // �대� 議댁옱�섎뒗 time_idx + ], + }; + + await expect(ScheduleService.createSchedules(scheduleData)) + .rejects + .toThrow('Schedule overlaps with existing schedule at time_idx 50'); + }); }); - test('should throw error when updated schedule overlaps with existing schedule', async () => { - const updateData = { - title: 'Alice\'s Overlapping Update', - start_time: new Date('2024-05-01T09:30:00Z'), // 湲곗〈 �ㅼ�以꾧낵 寃뱀묠 - end_time: new Date('2024-05-01T10:30:00Z'), - }; + describe('deleteSchedules', () => { + test('should delete multiple existing schedules successfully', async () => { + // 癒쇱�, �ㅼ�以� �앹꽦 + await ScheduleService.createSchedules({ + userId: 1, + title: 'Alice Bulk Delete Schedule 1', + is_fixed: false, + events: [ + { time_idx: 70 }, + { time_idx: 71 }, + ], + }); + + const deleteData = { + time_idxs: [70, 71], + }; + + const result = await ScheduleService.deleteSchedules(1, deleteData.time_idxs); + + expect(result).toBeDefined(); + expect(result.deleted_time_idxs).toContain(70); + expect(result.deleted_time_idxs).toContain(71); + + // �곗씠�곕쿋�댁뒪�먯꽌 ��젣 �뺤씤 + const dbSchedule1 = await Schedule.findOne({ where: { user_id: 1, time_idx: 70 } }); + const dbSchedule2 = await Schedule.findOne({ where: { user_id: 1, time_idx: 71 } }); + + expect(dbSchedule1).toBeNull(); + expect(dbSchedule2).toBeNull(); + }); - await expect(scheduleService.updateSchedule(2, 1, updateData)).rejects.toThrow('Schedule overlaps with existing schedule'); - }); - }); + test('should throw error when deleting a non-existing schedule', async () => { + const deleteData = { + time_idxs: [999], + }; - describe('deleteSchedule', () => { - test('should delete an existing schedule successfully', async () => { - const result = await scheduleService.deleteSchedule(2, 1); + await expect(ScheduleService.deleteSchedules(1, deleteData.time_idxs)) + .rejects + .toThrow('Schedule not found at time_idx 999'); + }); + }); - expect(result).toEqual({ message: 'Schedule successfully deleted' }); + describe('getAllSchedules', () => { + test('should retrieve all schedules for a user', async () => { + // Update schedules first + const updateData = { + updates: [ + { time_idx: 36, title: 'Alice Updated Fixed Schedule', is_fixed: true }, + { time_idx: 44, title: 'Alice Updated Flexible Schedule', is_fixed: false }, + ], + }; - // ��젣�� �ㅼ�以꾩씠 �ㅼ젣濡� ��젣�섏뿀�붿� �뺤씤 - const schedule = await Schedule.findByPk(2); - expect(schedule).toBeNull(); - }); + await ScheduleService.updateSchedules(1, updateData.updates); - test('should throw error when deleting a non-existing schedule', async () => { - await expect(scheduleService.deleteSchedule(999, 1)).rejects.toThrow('Schedule not found'); - }); -}); + const schedules = await ScheduleService.getAllSchedules(1); - describe('getAllSchedules', () => { - test('should retrieve all valid schedules for a user', async () => { - // �ъ슜�� Alice�� 紐⑤뱺 �ㅼ�以� 議고쉶 - const schedules = await scheduleService.getAllSchedules(1); + expect(schedules).toBeDefined(); + expect(Array.isArray(schedules)).toBe(true); - expect(schedules.length).toBe(1); // id=1 �ㅼ�以꾩� is_fixed=true - expect(schedules[0].title).toBe('Alice\'s Fixed Schedule'); - }); - }); + // �꾩옱 Alice�� id=1, time_idx=36 (fixed), time_idx=44 (flexible)�� 議댁옱 + expect(schedules.length).toBe(2); - describe('getScheduleById', () => { - test('should retrieve a specific schedule by ID', async () => { - const schedule = await scheduleService.getScheduleById(1, 1); + const schedule1 = schedules.find(s => s.time_idx === 36); + const schedule2 = schedules.find(s => s.time_idx === 44); - expect(schedule).toBeDefined(); - expect(schedule.title).toBe('Alice\'s Fixed Schedule'); - }); + expect(schedule1).toBeDefined(); + expect(schedule1.title).toBe('Alice Updated Fixed Schedule'); - test('should throw error when retrieving a non-existing schedule', async () => { - await expect(scheduleService.getScheduleById(999, 1)).rejects.toThrow('Schedule not found'); - }); - }); - // test/schedule.test.js - - describe('cleanExpiredSchedules', () => { - test('should delete expired flexible schedules', async () => { - // �꾩옱 �좎쭨瑜� 湲곗��쇰줈 留뚮즺�� �ㅼ�以꾧낵 留뚮즺�섏� �딆� �ㅼ�以� �앹꽦 - const now = new Date('2024-05-07T00:00:00Z'); // �뚯뒪�몃� �꾪븳 怨좎젙�� �꾩옱 �좎쭨 - - // Jest�� Fake Timers瑜� �ъ슜�섏뿬 Date瑜� 怨좎젙 - jest.useFakeTimers('modern'); - jest.setSystemTime(now); - - // 留뚮즺�� �좊룞 �ㅼ�以� �앹꽦 - await Schedule.create({ - user_id: 1, - title: 'Expired Flexible Schedule', - start_time: new Date('2024-04-25T10:00:00Z'), - end_time: new Date('2024-04-25T11:00:00Z'), - is_fixed: false, - expiry_date: new Date('2024-05-06T00:00:00Z'), // �대� 留뚮즺�� + expect(schedule2).toBeDefined(); + expect(schedule2.title).toBe('Alice Updated Flexible Schedule'); }); - // 留뚮즺�섏� �딆� �좊룞 �ㅼ�以� �앹꽦 - await Schedule.create({ - user_id: 1, - title: 'Valid Flexible Schedule', - start_time: new Date('2024-05-07T10:00:00Z'), - end_time: new Date('2024-05-07T11:00:00Z'), - is_fixed: false, - expiry_date: new Date('2024-05-14T00:00:00Z'), // �꾩쭅 留뚮즺�섏� �딆쓬 + test('should retrieve one schedule when user has only one', async () => { + const schedules = await ScheduleService.getAllSchedules(3); + + expect(schedules).toBeDefined(); + expect(Array.isArray(schedules)).toBe(true); + expect(schedules.length).toBe(1); + + expect(schedules[0].title).toBe('Charlie Fixed Schedule 1'); }); + }); - // 留뚮즺�� �ㅼ�以� �뺣━ - await scheduleService.cleanExpiredSchedules(); + describe('getScheduleByTimeIdx', () => { + test('should retrieve a specific schedule by time_idx', async () => { + // Update schedule first + const updateData = { + updates: [ + { time_idx: 36, title: 'Alice Updated Fixed Schedule', is_fixed: true }, + ], + }; - // 留뚮즺�� �ㅼ�以꾩씠 ��젣�섏뿀�붿� �뺤씤 - const expiredSchedule = await Schedule.findOne({ where: { title: 'Expired Flexible Schedule' } }); - expect(expiredSchedule).toBeNull(); + await ScheduleService.updateSchedules(1, updateData.updates); - // 留뚮즺�섏� �딆� �ㅼ�以꾩� �⑥븘�덈뒗吏� �뺤씤 - const validSchedule = await Schedule.findOne({ where: { title: 'Valid Flexible Schedule' } }); - expect(validSchedule).toBeDefined(); - expect(validSchedule.title).toBe('Valid Flexible Schedule'); + const schedule = await ScheduleService.getScheduleByTimeIdx(1, 36); - // Jest�� Fake Timers瑜� 蹂듦뎄 - jest.useRealTimers(); + expect(schedule).toBeDefined(); + expect(schedule.title).toBe('Alice Updated Fixed Schedule'); + expect(schedule.time_idx).toBe(36); + }); + + test('should throw error when retrieving a non-existing schedule', async () => { + await expect(ScheduleService.getScheduleByTimeIdx(1, 999)) + .rejects + .toThrow('Schedule not found'); + }); + }); + + describe('cleanExpiredSchedules', () => { + test('should delete all flexible schedules', async () => { + // �щ윭 �좊룞 �ㅼ�以꾩쓣 �앹꽦 + await ScheduleService.createSchedules({ + userId: 1, + title: 'Alice Flexible Schedule 2', + is_fixed: false, + events: [ + { time_idx: 80 }, + { time_idx: 81 }, + ], + }); + + await ScheduleService.createSchedules({ + userId: 2, + title: 'Bob Flexible Schedule 2', + is_fixed: false, + events: [ + { time_idx: 90 }, + { time_idx: 91 }, + ], + }); + + // �좊룞 �ㅼ�以� ��젣 + await ScheduleService.cleanExpiredSchedules(); + + // �곗씠�곕쿋�댁뒪�먯꽌 �좊룞 �ㅼ�以꾩씠 紐⑤몢 ��젣�섏뿀�붿� �뺤씤 + const remainingFlexibleSchedules = await Schedule.findAll({ + where: { is_fixed: false }, + }); + + expect(remainingFlexibleSchedules.length).toBe(0); + }); + + test('should not delete fixed schedules', async () => { + // �щ윭 怨좎젙 �ㅼ�以꾩쓣 �앹꽦 + await ScheduleService.createSchedules({ + userId: 3, + title: 'Charlie Fixed Schedule 2', + is_fixed: true, + events: [ + { time_idx: 120 }, + { time_idx: 121 }, + ], + }); + + // �좊룞 �ㅼ�以� ��젣 + await ScheduleService.cleanExpiredSchedules(); + + // �곗씠�곕쿋�댁뒪�먯꽌 怨좎젙 �ㅼ�以꾩씠 �좎��섏뿀�붿� �뺤씤 + const remainingFixedSchedules = await Schedule.findAll({ + where: { user_id: 3, is_fixed: true }, + }); + + expect(remainingFixedSchedules.length).toBe(3); + }); }); -}); - }); diff --git a/services/scheduleService.js b/services/scheduleService.js index 66d0bbcc3f5d09509632cd564473b2fd14d20c31..f827c219f8ed4bea2447a48ecab7d9ea00233b1d 100644 --- a/services/scheduleService.js +++ b/services/scheduleService.js @@ -1,261 +1,171 @@ // services/scheduleService.js - +const sequelize = require('../config/sequelize'); const { Op } = require('sequelize'); const Schedule = require('../models/Schedule'); const ScheduleResponseDTO = require('../dtos/ScheduleResponseDTO'); -class scheduleService { - /** - * �몃옖��뀡 �섑띁 �⑥닔 - */ - async withTransaction(callback) { - const transaction = await Schedule.sequelize.transaction(); - try { - const result = await callback(transaction); - await transaction.commit(); - return result; - } catch (error) { - await transaction.rollback(); - throw error; - } - } - - /** - * 怨듯넻 where �� �앹꽦 - */ - getScheduleWhereClause(userId, id = null) { - const where = { - user_id: userId, - [Op.or]: [ - { is_fixed: true }, - { - is_fixed: false, - expiry_date: { [Op.gt]: new Date() }, - }, - ], - }; - - if (id) { - where.id = id; +class ScheduleService { + /** + * �ㅼ�以� �앹꽦 (踰뚰겕) + * @param {object} [transaction] - Sequelize �몃옖��뀡 媛앹껜 -> 誘명똿諛⑹뿉�� �곌린�꾪빐 �몃옖��뀡�� �섍꺼諛쏅뒗嫄� 異붽� + */ + async createSchedules({ userId, title, is_fixed, events }, transaction = null) { + const scheduleDTOs = []; + + for (const event of events) { + const { time_idx } = event; + + // 以묐났 �ㅼ�以� 寃��� + const overlap = await this.checkScheduleOverlap(userId, time_idx, transaction); + if (overlap) { + throw new Error(`Schedule overlaps with existing schedule at time_idx ${time_idx}`); + } + + const scheduleData = { + user_id: userId, + title, + time_idx, + is_fixed, + }; + + const schedule = await Schedule.create(scheduleData, { transaction }); + scheduleDTOs.push(new ScheduleResponseDTO(schedule)); + } + + return scheduleDTOs; } - return where; - } - - /** - * �ㅼ�以� �좏슚�� 寃��� - * �대� 而⑦듃濡ㅻ윭�먯꽌 寃�利앺뻽�쇰�濡�, 異붽� 寃�利� �꾩슂 �� �섑뻾 - */ - validateScheduleTime(start_time, end_time) { - if (new Date(start_time) >= new Date(end_time)) { - throw new Error("Start time must be before end time"); - } - } - - /** - * �좊룞 �ㅼ�以� 留뚮즺�� 援ы븯湲� - */ - getNextMonday(startTime) { - const date = new Date(startTime); - const day = date.getUTCDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday - const daysUntilNextMonday = (8 - day) % 7 || 7; // Ensure next Monday - - const nextMonday = new Date( - Date.UTC( - date.getUTCFullYear(), - date.getUTCMonth(), - date.getUTCDate() + daysUntilNextMonday, - 0, - 0, - 0, - 0 // Set to midnight UTC - ) - ); - - return nextMonday; - } - - /** - * �ъ슜�� �ㅼ�以� �앹꽦 - */ - async createSchedule({ userId, title, start_time, end_time, is_fixed }) { - const schedule = await this.withTransaction(async (transaction) => { - this.validateScheduleTime(start_time, end_time); - - const overlap = await this.checkScheduleOverlap( - userId, - start_time, - end_time - ); - if (overlap) { - throw new Error("Schedule overlaps with existing schedule"); - } + /** + * �ㅼ�以� �섏젙 (踰뚰겕) + * @param {Array} updates - �섏젙�� �ㅼ�以� 諛곗뿴 + */ + async updateSchedules(userId, updates, transaction = null) { + const updatedSchedules = []; - const scheduleData = { - user_id: userId, - title, - start_time, - end_time, - is_fixed, - expiry_date: is_fixed ? null : this.getNextMonday(start_time), - }; + for (const update of updates) { + const { time_idx, title, is_fixed } = update; - return Schedule.create(scheduleData, { transaction }); - }); + const schedule = await Schedule.findOne({ + where: { user_id: userId, time_idx }, + transaction, + }); - return new ScheduleResponseDTO(schedule); - } + if (!schedule) { + throw new Error(`Schedule not found at time_idx ${time_idx}`); + } - /** - * �ъ슜�� �ㅼ�以� �섏젙 - */ - async updateSchedule(id, userId, updateData) { - const updatedSchedule = await this.withTransaction(async (transaction) => { - const schedule = await Schedule.findOne({ - where: { id, user_id: userId }, - transaction, - }); + const updatedData = {}; + if (title !== undefined) updatedData.title = title; + if (is_fixed !== undefined) updatedData.is_fixed = is_fixed; - if (!schedule) { - throw new Error("Schedule not found"); - } + const updatedSchedule = await schedule.update(updatedData, { transaction }); + updatedSchedules.push(new ScheduleResponseDTO(updatedSchedule)); + } - // �대� 而⑦듃濡ㅻ윭�먯꽌 寃�利앺뻽�쇰�濡�, 異붽� 寃�利앹씠 �꾩슂�섎떎硫� �섑뻾 - if (updateData.start_time && updateData.end_time) { - this.validateScheduleTime(updateData.start_time, updateData.end_time); - } - - const overlap = await this.checkScheduleOverlap( - userId, - updateData.start_time || schedule.start_time, - updateData.end_time || schedule.end_time, - id - ); - if (overlap) { - throw new Error("Schedule overlaps with existing schedule"); - } - - const is_fixed = schedule.is_fixed; - const updatedDataWithExpiry = { - ...updateData, - expiry_date: is_fixed - ? null - : this.getNextMonday(updateData.start_time || schedule.start_time), - updatedAt: new Date(), - }; - delete updatedDataWithExpiry.is_fixed; - - return schedule.update(updatedDataWithExpiry, { transaction }); - }); - - return new ScheduleResponseDTO(updatedSchedule); - } - - /** - * �ъ슜�� �ㅼ�以� ��젣 - */ - async deleteSchedule(id, userId) { - return this.withTransaction(async (transaction) => { - const result = await Schedule.destroy({ - where: { id, user_id: userId }, - transaction, - }); - - if (!result) { - throw new Error("Schedule not found"); - } - - // ��젣 �깃났 硫붿떆吏� 諛섑솚 - return { message: "Schedule successfully deleted" }; - }); - } + return updatedSchedules; + } - /** - * �대떦 �ъ슜�먯쓽 �ㅼ�以� �뺣낫 議고쉶 - */ - async getAllSchedules(userId) { - try { - const schedules = await Schedule.findAll({ - where: this.getScheduleWhereClause(userId), - order: [["start_time", "ASC"]], - }); - const schedulesDTO = schedules.map( - (schedule) => new ScheduleResponseDTO(schedule) - ); - return schedulesDTO; - } catch (error) { - throw new Error(`Failed to fetch schedules: ${error.message}`); + /** + * �ㅼ�以� ��젣 (踰뚰겕) + * @param {number} userId - �ъ슜�� ID + * @param {Array<number>} time_idxs - ��젣�� �ㅼ�以꾩쓽 time_idx 諛곗뿴 + * @param {object} [transaction] - Sequelize �몃옖��뀡 媛앹껜 + */ + async deleteSchedules(userId, time_idxs, transaction = null) { + const deleted_time_idxs = []; + + for (const time_idx of time_idxs) { + const deletedCount = await Schedule.destroy({ + where: { user_id: userId, time_idx }, + transaction, + }); + + if (deletedCount === 0) { + throw new Error(`Schedule not found at time_idx ${time_idx}`); + } + + deleted_time_idxs.push(time_idx); + } + + return { deleted_time_idxs }; } - } - /** - * �대떦 �ъ슜�먯쓽 �뱀젙 �ㅼ�以� 議고쉶 - */ - async getScheduleById(id, userId) { - try { - const schedule = await Schedule.findOne({ - where: this.getScheduleWhereClause(userId, id), - }); + /** + * �뱀젙 time_idx濡� �ㅼ�以� 議고쉶 + */ + async getScheduleByTimeIdx(userId, time_idx) { + const schedule = await Schedule.findOne({ + where: { user_id: userId, time_idx }, + }); - if (!schedule) { - throw new Error("Schedule not found"); - } + if (!schedule) { + throw new Error('Schedule not found'); + } - return new ScheduleResponseDTO(schedule); - } catch (error) { - throw new Error(`Failed to fetch schedule: ${error.message}`); + return new ScheduleResponseDTO(schedule); } - } - /** - * 留뚮즺�� �좊룞 �ㅼ�以� �뺣━ - */ - async cleanExpiredSchedules() { - try { - await Schedule.destroy({ - where: { - is_fixed: false, - expiry_date: { [Op.lte]: new Date() }, - }, - }); - } catch (error) { - throw new Error(`Failed to clean expired schedules: ${error.message}`); + /** + * 紐⑤뱺 �ㅼ�以� 議고쉶 + */ + async getAllSchedules(userId) { + try { + const schedules = await Schedule.findAll({ + where: { user_id: userId }, + order: [['time_idx', 'ASC']], + }); + return schedules.map((schedule) => new ScheduleResponseDTO(schedule)); + } catch (error) { + throw new Error(`Failed to fetch schedules: ${error.message}`); + } } - } - /** - * �ㅼ�以� 以묐났 寃��� - */ - async checkScheduleOverlap(userId, start_time, end_time, excludeId = null) { - try { - const where = { - user_id: userId, - [Op.or]: [ - { - [Op.and]: [ - { start_time: { [Op.lte]: start_time } }, - { end_time: { [Op.gte]: start_time } }, - ], - }, - { - [Op.and]: [ - { start_time: { [Op.gte]: start_time } }, - { start_time: { [Op.lte]: end_time } }, - ], - }, - ], - }; + /** + * 以묐났 �ㅼ�以� 寃��� + */ + async checkScheduleOverlap(userId, time_idx, transaction = null) { + const overlappingSchedule = await Schedule.findOne({ + where: { user_id: userId, time_idx }, + transaction, + }); - if (excludeId) { - where.id = { [Op.ne]: excludeId }; - } + return !!overlappingSchedule; + } - const overlappingSchedule = await Schedule.findOne({ where }); - return overlappingSchedule; - } catch (error) { - throw new Error(`Failed to check schedule overlap: ${error.message}`); + async checkScheduleOverlapByTime(userId, time_idx_start, time_idx_end, transaction = null) { + console.log( + `checkScheduleOverlapByTime �몄텧: userId=${userId}, time_idx_start=${time_idx_start}, time_idx_end=${time_idx_end}` + ); + const overlappingSchedule = await Schedule.findOne({ + where: { + user_id: userId, + time_idx: { + [Op.between]: [time_idx_start, time_idx_end] + } + }, + transaction, + }); + console.log(`以묐났 �ㅼ�以�: ${JSON.stringify(overlappingSchedule)}`); + const result = !!overlappingSchedule; + console.log(`�ㅼ�以� 異⑸룎 寃곌낵: ${result}`); + return result; + } + + + /** + * 留뚮즺�� �ㅼ�以� ��젣 + */ + async cleanExpiredSchedules() { + try { + const deletedCount = await Schedule.destroy({ + where: { is_fixed: false }, + }); + //console.log(`Deleted ${deletedCount} flexible schedules.`); + } catch (error) { + console.error('Failed to clean expired schedules:', error); + throw error; + } } - } } -module.exports = new scheduleService(); +module.exports = new ScheduleService();