From bc0cff1addbcee8e169695faa1cdb560f2422418 Mon Sep 17 00:00:00 2001 From: urbantech Date: Mon, 21 Oct 2024 19:59:25 -0700 Subject: [PATCH] Resolved merge conflicts and merged with main --- __tests__/CommunicationRoutes.test.js | 172 + __tests__/CommunicationsController.test.js | 172 + __tests__/CommunicationsModel.test.js | 87 + __tests__/CompanyController.test.js | 173 + __tests__/CompanyModel.test.js | 87 + __tests__/CompanyRoutes.test.js | 85 + __tests__/ComplianceCheckController.test.js | 96 + __tests__/ComplianceCheckModel.test.js | 43 + __tests__/ComplianceCheckRoutes.test.js | 81 + __tests__/NotificationController.test.js | 148 + __tests__/NotificationModels.test.js | 84 + __tests__/NotificationRoutes.test.js | 119 + __tests__/SPVController.test.js | 99 + __tests__/SPVModel.test.js | 83 + __tests__/SPVRoutes.test.js | 84 + __tests__/SPVassetController.test.js | 96 + __tests__/SPVassetModel.test.js | 77 + __tests__/SPVassetRoutes.test.js | 81 + __tests__/TaxCalculatorModel.test.js | 65 + __tests__/TaxCalculatorRoutes.test.js | 193 + __tests__/TaxtCalculatorController.test.js | 112 + __tests__/activity.model.test.js | 45 + __tests__/activityController.test.js | 72 + __tests__/activityRoutes.test.js | 73 + __tests__/admin.model.test.js | 87 + __tests__/admin.routes.test.js | 170 + __tests__/adminController.test.js | 155 + __tests__/airflowIntegration.test.js | 69 + __tests__/app.test.js | 20 + __tests__/authController.test.js | 99 + __tests__/db.test.js | 11 + __tests__/documentAccessController.test.js | 84 + __tests__/documentAccessModel.test.js | 29 + __tests__/documentAccessRoutes.test.js | 84 + __tests__/documentController.test.js | 101 + __tests__/documentEmbeddingController.test.js | 94 + __tests__/documentEmbeddingModel.test.js | 80 + __tests__/documentEmbeddingRoutes.test.js | 94 + __tests__/documentModel.test.js | 89 + __tests__/documentRoutes.test.js | 101 + __tests__/employee.model.test.js | 47 + __tests__/employeeController.test.js | 57 + __tests__/employeeRoute.test.js | 62 + __tests__/equityPlanController.test.js | 97 + __tests__/equityPlanModel.test.js | 36 + __tests__/equityPlanRoutes.test.js | 96 + .../financialReportingController.test.js | 51 + __tests__/fundraisingRoundController.test.js | 108 + __tests__/fundraisingRoundModel.test.js | 49 + __tests__/fundraisingRoundRoutes.test.js | 97 + __tests__/globalSetup.js | 59 + __tests__/globalTeardown.js | 30 + __tests__/integrationController.test.js | 59 + __tests__/integrationModel.test.js | 82 + __tests__/integrationRoutes.test.js | 82 + __tests__/investmentTrackerController.test.js | 56 + __tests__/investmentTrackerModel.test.js | 81 + __tests__/investmentTrackerRoutes.test.js | 75 + __tests__/investor.model.test.js | 141 + __tests__/investorController.test.js | 67 + __tests__/investorRoutes.test.js | 67 + __tests__/inviteManagement.model.test.js | 52 + __tests__/inviteManagementController.test.js | 140 + __tests__/inviteManagementRoutes.test.js | 109 + __tests__/minioIntegration.test.js | 36 + __tests__/minioStorageIntegration.test.js | 33 + __tests__/postgresIntegration.test.js | 36 + __tests__/shareClass.model.test.js | 36 + __tests__/shareClassRoutes.test.js | 97 + __tests__/stakeholder.model.test.js | 30 + __tests__/stakeholderRoutes.test.js | 83 + __tests__/test-dataset.csv | 6 + __tests__/user.model.test.js | 34 + __tests__/user.test.js | 34 + __tests__/userRoutes.test.js | 91 + app.js | 28 +- db.js | 20 - jest.config.js | 10 +- models/financialReport.js | 0 models/integrationModel.js | 13 +- package-lock.json | 3593 ++++++++++++----- package.json | 14 + utils/dataProcessing.js | 19 + 83 files changed, 8791 insertions(+), 1016 deletions(-) create mode 100644 __tests__/CommunicationRoutes.test.js create mode 100644 __tests__/CommunicationsController.test.js create mode 100644 __tests__/CommunicationsModel.test.js create mode 100644 __tests__/CompanyController.test.js create mode 100644 __tests__/CompanyModel.test.js create mode 100644 __tests__/CompanyRoutes.test.js create mode 100644 __tests__/ComplianceCheckController.test.js create mode 100644 __tests__/ComplianceCheckModel.test.js create mode 100644 __tests__/ComplianceCheckRoutes.test.js create mode 100644 __tests__/NotificationController.test.js create mode 100644 __tests__/NotificationModels.test.js create mode 100644 __tests__/NotificationRoutes.test.js create mode 100644 __tests__/SPVController.test.js create mode 100644 __tests__/SPVModel.test.js create mode 100644 __tests__/SPVRoutes.test.js create mode 100644 __tests__/SPVassetController.test.js create mode 100644 __tests__/SPVassetModel.test.js create mode 100644 __tests__/SPVassetRoutes.test.js create mode 100644 __tests__/TaxCalculatorModel.test.js create mode 100644 __tests__/TaxCalculatorRoutes.test.js create mode 100644 __tests__/TaxtCalculatorController.test.js create mode 100644 __tests__/activity.model.test.js create mode 100644 __tests__/activityController.test.js create mode 100644 __tests__/activityRoutes.test.js create mode 100644 __tests__/admin.model.test.js create mode 100644 __tests__/admin.routes.test.js create mode 100644 __tests__/adminController.test.js create mode 100644 __tests__/airflowIntegration.test.js create mode 100644 __tests__/app.test.js create mode 100644 __tests__/authController.test.js create mode 100644 __tests__/db.test.js create mode 100644 __tests__/documentAccessController.test.js create mode 100644 __tests__/documentAccessModel.test.js create mode 100644 __tests__/documentAccessRoutes.test.js create mode 100644 __tests__/documentController.test.js create mode 100644 __tests__/documentEmbeddingController.test.js create mode 100644 __tests__/documentEmbeddingModel.test.js create mode 100644 __tests__/documentEmbeddingRoutes.test.js create mode 100644 __tests__/documentModel.test.js create mode 100644 __tests__/documentRoutes.test.js create mode 100644 __tests__/employee.model.test.js create mode 100644 __tests__/employeeController.test.js create mode 100644 __tests__/employeeRoute.test.js create mode 100644 __tests__/equityPlanController.test.js create mode 100644 __tests__/equityPlanModel.test.js create mode 100644 __tests__/equityPlanRoutes.test.js create mode 100644 __tests__/financialReportingController.test.js create mode 100644 __tests__/fundraisingRoundController.test.js create mode 100644 __tests__/fundraisingRoundModel.test.js create mode 100644 __tests__/fundraisingRoundRoutes.test.js create mode 100644 __tests__/globalSetup.js create mode 100644 __tests__/globalTeardown.js create mode 100644 __tests__/integrationController.test.js create mode 100644 __tests__/integrationModel.test.js create mode 100644 __tests__/integrationRoutes.test.js create mode 100644 __tests__/investmentTrackerController.test.js create mode 100644 __tests__/investmentTrackerModel.test.js create mode 100644 __tests__/investmentTrackerRoutes.test.js create mode 100644 __tests__/investor.model.test.js create mode 100644 __tests__/investorController.test.js create mode 100644 __tests__/investorRoutes.test.js create mode 100644 __tests__/inviteManagement.model.test.js create mode 100644 __tests__/inviteManagementController.test.js create mode 100644 __tests__/inviteManagementRoutes.test.js create mode 100644 __tests__/minioIntegration.test.js create mode 100644 __tests__/minioStorageIntegration.test.js create mode 100644 __tests__/postgresIntegration.test.js create mode 100644 __tests__/shareClass.model.test.js create mode 100644 __tests__/shareClassRoutes.test.js create mode 100644 __tests__/stakeholder.model.test.js create mode 100644 __tests__/stakeholderRoutes.test.js create mode 100644 __tests__/test-dataset.csv create mode 100644 __tests__/user.model.test.js create mode 100644 __tests__/user.test.js create mode 100644 __tests__/userRoutes.test.js create mode 100644 models/financialReport.js create mode 100644 utils/dataProcessing.js diff --git a/__tests__/CommunicationRoutes.test.js b/__tests__/CommunicationRoutes.test.js new file mode 100644 index 0000000..e7ad653 --- /dev/null +++ b/__tests__/CommunicationRoutes.test.js @@ -0,0 +1,172 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const communicationRoutes = require('../routes/Communication'); // Corrected import +const Communication = require('../models/Communication'); + +// Mock the Communication model +jest.mock('../models/Communication'); + +const app = express(); +app.use(express.json()); +app.use('/api/communications', communicationRoutes); + +describe('Communication Routes', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('POST /api/communications', () => { + it('should create a new communication', async () => { + const communicationData = { + communicationId: 'new-communication-id', + MessageType: 'system notification', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string + Content: 'This is a new communication.', + }; + + Communication.prototype.save.mockResolvedValue(communicationData); + + const response = await request(app) + .post('/api/communications') + .send(communicationData); + + expect(response.status).toBe(201); + expect(response.body).toEqual(communicationData); + }); + + it('should return 400 if required fields are missing', async () => { + const response = await request(app) + .post('/api/communications') + .send({}); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ message: 'Invalid communication data' }); + }); + }); + + describe('GET /api/communications', () => { + it('should get all communications', async () => { + const communications = [ + { + communicationId: 'communication-id-1', + MessageType: 'email', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string + Content: 'First communication.', + }, + { + communicationId: 'communication-id-2', + MessageType: 'SMS', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string + Content: 'Second communication.', + }, + ]; + + Communication.find.mockResolvedValue(communications); + + const response = await request(app).get('/api/communications'); + + expect(response.status).toBe(200); + expect(response.body).toEqual(communications); + }); + + it('should return 404 if no communications are found', async () => { + Communication.find.mockResolvedValue([]); + + const response = await request(app).get('/api/communications'); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'No communications found' }); + }); + }); + + describe('GET /api/communications/:id', () => { + it('should get a communication by id', async () => { + const communication = { + communicationId: 'communication-id-1', + MessageType: 'email', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string + Content: 'Test communication.', + }; + + Communication.findById.mockResolvedValue(communication); + + const response = await request(app).get(`/api/communications/${communication.communicationId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual(communication); + }); + + it('should return 404 if communication is not found', async () => { + Communication.findById.mockResolvedValue(null); + + const response = await request(app).get(`/api/communications/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Communication not found' }); + }); + }); + + describe('PUT /api/communications/:id', () => { + it('should update a communication by id', async () => { + const communicationId = 'communication-id-1'; + const updatedCommunication = { + communicationId, + MessageType: 'email', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string + Content: 'Updated communication content.', + }; + + Communication.findByIdAndUpdate.mockResolvedValue(updatedCommunication); + + const response = await request(app) + .put(`/api/communications/${communicationId}`) + .send(updatedCommunication); + + expect(response.status).toBe(200); + expect(response.body).toEqual(updatedCommunication); + }); + + it('should return 404 if communication to update is not found', async () => { + Communication.findByIdAndUpdate.mockResolvedValue(null); + + const response = await request(app) + .put(`/api/communications/${mongoose.Types.ObjectId()}`) + .send({ Content: 'Updated content' }); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Communication not found' }); + }); + }); + + describe('DELETE /api/communications/:id', () => { + it('should delete a communication by id', async () => { + const communicationId = 'communication-id-1'; + Communication.findByIdAndDelete.mockResolvedValue({ communicationId }); + + const response = await request(app).delete(`/api/communications/${communicationId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ message: 'Communication deleted' }); + }); + + it('should return 404 if communication to delete is not found', async () => { + Communication.findByIdAndDelete.mockResolvedValue(null); + + const response = await request(app).delete(`/api/communications/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Communication not found' }); + }); + }); +}); diff --git a/__tests__/CommunicationsController.test.js b/__tests__/CommunicationsController.test.js new file mode 100644 index 0000000..35a92fe --- /dev/null +++ b/__tests__/CommunicationsController.test.js @@ -0,0 +1,172 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const communicationController = require('../controllers/Communication'); // Ensure this matches your actual controller file name +const Communication = require('../models/Communication'); + +// Mock the Communication model +jest.mock('../models/Communication'); + +const app = express(); +app.use(express.json()); +app.use("/api/communications", require("../routes/Communication")); // Ensure this matches your actual routes file name + +describe('Communication Controller', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('POST /api/communications', () => { + it('should create a new communication', async () => { + const communicationData = { + communicationId: 'new-communication-id', + MessageType: 'system notification', + Sender: mongoose.Types.ObjectId().toString(), // Mock ObjectId for Sender + Recipient: mongoose.Types.ObjectId().toString(), // Mock ObjectId for Recipient + Timestamp: new Date().toISOString(), // Convert to string for consistency + Content: 'This is a new communication.', + }; + + Communication.prototype.save.mockResolvedValue(communicationData); + + const response = await request(app) + .post('/api/communications') + .send(communicationData); + + expect(response.status).toBe(201); + expect(response.body).toEqual(communicationData); + }); + + it('should return 400 if required fields are missing', async () => { + const response = await request(app) + .post('/api/communications') + .send({}); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ message: 'Invalid communication data' }); + }); + }); + + describe('GET /api/communications', () => { + it('should get all communications', async () => { + const communications = [ + { + communicationId: 'communication-id-1', + MessageType: 'email', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string for consistency + Content: 'First communication.', + }, + { + communicationId: 'communication-id-2', + MessageType: 'SMS', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string for consistency + Content: 'Second communication.', + }, + ]; + + Communication.find.mockResolvedValue(communications); + + const response = await request(app).get('/api/communications'); + + expect(response.status).toBe(200); + expect(response.body).toEqual(communications); + }); + + it('should return 404 if no communications are found', async () => { + Communication.find.mockResolvedValue([]); + + const response = await request(app).get('/api/communications'); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'No communications found' }); + }); + }); + + describe('GET /api/communications/:id', () => { + it('should get a communication by id', async () => { + const communication = { + communicationId: 'communication-id-1', + MessageType: 'email', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string for consistency + Content: 'Test communication.', + }; + + Communication.findById.mockResolvedValue(communication); + + const response = await request(app).get(`/api/communications/${communication.communicationId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual(communication); + }); + + it('should return 404 if communication is not found', async () => { + Communication.findById.mockResolvedValue(null); + + const response = await request(app).get(`/api/communications/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Communication not found' }); + }); + }); + + describe('PUT /api/communications/:id', () => { + it('should update a communication by id', async () => { + const communicationId = 'communication-id-1'; + const updatedCommunication = { + communicationId, + MessageType: 'email', + Sender: mongoose.Types.ObjectId().toString(), + Recipient: mongoose.Types.ObjectId().toString(), + Timestamp: new Date().toISOString(), // Convert to string for consistency + Content: 'Updated communication content.', + }; + + Communication.findByIdAndUpdate.mockResolvedValue(updatedCommunication); + + const response = await request(app) + .put(`/api/communications/${communicationId}`) + .send(updatedCommunication); + + expect(response.status).toBe(200); + expect(response.body).toEqual(updatedCommunication); + }); + + it('should return 404 if communication to update is not found', async () => { + Communication.findByIdAndUpdate.mockResolvedValue(null); + + const response = await request(app) + .put(`/api/communications/${mongoose.Types.ObjectId()}`) + .send({ Content: 'Updated content' }); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Communication not found' }); + }); + }); + + describe('DELETE /api/communications/:id', () => { + it('should delete a communication by id', async () => { + const communicationId = 'communication-id-1'; + Communication.findByIdAndDelete.mockResolvedValue({ communicationId }); + + const response = await request(app).delete(`/api/communications/${communicationId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ message: 'Communication deleted' }); + }); + + it('should return 404 if communication to delete is not found', async () => { + Communication.findByIdAndDelete.mockResolvedValue(null); + + const response = await request(app).delete(`/api/communications/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Communication not found' }); + }); + }); +}); diff --git a/__tests__/CommunicationsModel.test.js b/__tests__/CommunicationsModel.test.js new file mode 100644 index 0000000..dcd6e93 --- /dev/null +++ b/__tests__/CommunicationsModel.test.js @@ -0,0 +1,87 @@ +const mongoose = require('mongoose'); +const { expect } = require('chai'); +const Communication = require('../models/Communication'); +const { connectDB, disconnectDB } = require('../db'); + +beforeAll(async function () { + await connectDB(); +}); + +afterAll(async function () { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Communication Model', function () { + it('should create a communication with valid fields', async function () { + const communicationData = { + communicationId: 'unique-communication-id', + MessageType: 'email', + Sender: mongoose.Types.ObjectId(), // Use a valid ObjectId + Recipient: mongoose.Types.ObjectId(), // Use a valid ObjectId + Timestamp: new Date(), + Content: 'This is a test communication.', + }; + + const communication = new Communication(communicationData); + const savedCommunication = await communication.save(); + + expect(savedCommunication.communicationId).to.equal(communicationData.communicationId); + expect(savedCommunication.MessageType).to.equal(communicationData.MessageType); + expect(savedCommunication.Sender.toString()).to.equal(communicationData.Sender.toString()); + expect(savedCommunication.Recipient.toString()).to.equal(communicationData.Recipient.toString()); + expect(new Date(savedCommunication.Timestamp).toISOString()).to.equal(new Date(communicationData.Timestamp).toISOString()); + expect(savedCommunication.Content).to.equal(communicationData.Content); + }); + + it('should not create a communication without required fields', async function () { + const communicationData = { + MessageType: 'email', + }; + + const communication = new Communication(communicationData); + + try { + await communication.save(); + } catch (error) { + expect(error).to.exist; + expect(error.errors.communicationId).to.exist; + expect(error.errors.Sender).to.exist; + expect(error.errors.Recipient).to.exist; + expect(error.errors.Timestamp).to.exist; // Ensure these fields are required in the schema + expect(error.errors.Content).to.exist; // Ensure these fields are required in the schema + } + }); + + it('should not create a communication with duplicate communicationId', async function () { + const communicationData1 = { + communicationId: 'duplicate-communication-id', + MessageType: 'SMS', + Sender: mongoose.Types.ObjectId(), + Recipient: mongoose.Types.ObjectId(), + Timestamp: new Date(), + Content: 'First communication.', + }; + + const communicationData2 = { + communicationId: 'duplicate-communication-id', + MessageType: 'email', + Sender: mongoose.Types.ObjectId(), + Recipient: mongoose.Types.ObjectId(), + Timestamp: new Date(), + Content: 'Second communication.', + }; + + const communication1 = new Communication(communicationData1); + await communication1.save(); + + const communication2 = new Communication(communicationData2); + + try { + await communication2.save(); + } catch (error) { + expect(error).to.exist; + expect(error.code).to.equal(11000); // Duplicate key error code + } + }); +}); diff --git a/__tests__/CompanyController.test.js b/__tests__/CompanyController.test.js new file mode 100644 index 0000000..565b678 --- /dev/null +++ b/__tests__/CompanyController.test.js @@ -0,0 +1,173 @@ +// test/CompanyController.test.js +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const companyController = require('../controllers/Company'); // Ensure the correct file name +const Company = require('../models/Company'); + +// Mock the Company model +jest.mock('../models/Company'); + +const app = express(); +app.use(express.json()); +app.use("/api/companies", require("../routes/Company")); + +describe('Company Controller', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('POST /api/companies', () => { + it('should create a new company', async () => { + const companyData = { + companyId: 'new-company-id', + CompanyName: 'New Test Company', + CompanyType: 'corporation', + RegisteredAddress: '456 New Avenue, New City, NC', + TaxID: '987-65-4321', + corporationDate: new Date().toISOString(), // Ensure date is in ISO string format + }; + + Company.prototype.save.mockResolvedValue(companyData); + + const response = await request(app) + .post('/api/companies') + .send(companyData); + + expect(response.status).toBe(201); + expect(response.body).toEqual(companyData); + }); + + it('should return 400 if required fields are missing', async () => { + const response = await request(app) + .post('/api/companies') + .send({}); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ message: 'Invalid company data' }); + }); + }); + + describe('GET /api/companies', () => { + it('should get all companies', async () => { + const companies = [ + { + companyId: 'company-id-1', + CompanyName: 'Company 1', + CompanyType: 'startup', + RegisteredAddress: '123 Test Street, Test City, TC', + TaxID: '111-22-3333', + corporationDate: new Date().toISOString(), + }, + { + companyId: 'company-id-2', + CompanyName: 'Company 2', + CompanyType: 'corporation', + RegisteredAddress: '456 Test Avenue, Test City, TC', + TaxID: '444-55-6666', + corporationDate: new Date().toISOString(), + }, + ]; + + Company.find.mockResolvedValue(companies); + + const response = await request(app).get('/api/companies'); + + expect(response.status).toBe(200); + expect(response.body).toEqual(companies); + }); + + it('should return 404 if no companies are found', async () => { + Company.find.mockResolvedValue([]); + + const response = await request(app).get('/api/companies'); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'No companies found' }); + }); + }); + + describe('GET /api/companies/:id', () => { + it('should get a company by id', async () => { + const company = { + companyId: 'company-id-1', + CompanyName: 'Company 1', + CompanyType: 'startup', + RegisteredAddress: '123 Test Street, Test City, TC', + TaxID: '111-22-3333', + corporationDate: new Date().toISOString(), + }; + + Company.findById.mockResolvedValue(company); + + const response = await request(app).get(`/api/companies/${company.companyId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual(company); + }); + + it('should return 404 if company is not found', async () => { + Company.findById.mockResolvedValue(null); + + const response = await request(app).get(`/api/companies/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Company not found' }); + }); + }); + + describe('PUT /api/companies/:id', () => { + it('should update a company by id', async () => { + const companyId = 'company-id-1'; + const updatedCompany = { + companyId, + CompanyName: 'Updated Company', + CompanyType: 'corporation', + RegisteredAddress: '789 Updated Road, Updated City, UC', + TaxID: '111-22-3333', + corporationDate: new Date().toISOString(), + }; + + Company.findByIdAndUpdate.mockResolvedValue(updatedCompany); + + const response = await request(app) + .put(`/api/companies/${companyId}`) + .send(updatedCompany); + + expect(response.status).toBe(200); + expect(response.body).toEqual(updatedCompany); + }); + + it('should return 404 if company to update is not found', async () => { + Company.findByIdAndUpdate.mockResolvedValue(null); + + const response = await request(app) + .put(`/api/companies/${mongoose.Types.ObjectId()}`) + .send({ CompanyName: 'Updated Company' }); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Company not found' }); + }); + }); + + describe('DELETE /api/companies/:id', () => { + it('should delete a company by id', async () => { + const companyId = 'company-id-1'; + Company.findByIdAndDelete.mockResolvedValue({ companyId }); + + const response = await request(app).delete(`/api/companies/${companyId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ message: 'Company deleted' }); + }); + + it('should return 404 if company to delete is not found', async () => { + Company.findByIdAndDelete.mockResolvedValue(null); + + const response = await request(app).delete(`/api/companies/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Company not found' }); + }); + }); +}); diff --git a/__tests__/CompanyModel.test.js b/__tests__/CompanyModel.test.js new file mode 100644 index 0000000..b4f6f8d --- /dev/null +++ b/__tests__/CompanyModel.test.js @@ -0,0 +1,87 @@ +const mongoose = require('mongoose'); +const chai = require('chai'); +const expect = chai.expect; +const Company = require('../models/Company'); +const { connectDB, disconnectDB } = require('../db'); // Adjust according to your database connection setup + +beforeAll(async function () { + await connectDB(); // Ensure this matches your database connection logic +}); + +afterAll(async function () { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Company Model', function () { + it('should create a company with valid fields', async function () { + const companyData = { + companyId: 'valid-company-id', + CompanyName: 'Test Company', + CompanyType: 'startup', // Assuming 'startup' is a valid enum value + RegisteredAddress: '123 Test Street, Test City, TC', + TaxID: '123-45-6789', + corporationDate: new Date(), + }; + + const company = new Company(companyData); + const savedCompany = await company.save(); + + expect(savedCompany.companyId).to.equal(companyData.companyId); + expect(savedCompany.CompanyName).to.equal(companyData.CompanyName); + expect(savedCompany.CompanyType).to.equal(companyData.CompanyType); + expect(savedCompany.RegisteredAddress).to.equal(companyData.RegisteredAddress); + expect(savedCompany.TaxID).to.equal(companyData.TaxID); + expect(new Date(savedCompany.corporationDate).toISOString()).to.equal(new Date(companyData.corporationDate).toISOString()); + }); + + it('should not create a company without required fields', async function () { + const companyData = { + CompanyName: 'Test Company', + }; + + const company = new Company(companyData); + + try { + await company.save(); + } catch (error) { + expect(error).to.exist; + expect(error.errors.companyId).to.exist; + expect(error.errors.CompanyType).to.exist; + expect(error.errors.RegisteredAddress).to.exist; + expect(error.errors.corporationDate).to.exist; + } + }); + + it('should not create a company with duplicate companyId', async function () { + const companyData1 = { + companyId: 'duplicate-company-id', + CompanyName: 'First Company', + CompanyType: 'startup', + RegisteredAddress: '123 First Street, First City, FC', + TaxID: '111-22-3333', + corporationDate: new Date(), + }; + + const companyData2 = { + companyId: 'duplicate-company-id', + CompanyName: 'Second Company', + CompanyType: 'corporation', + RegisteredAddress: '456 Second Avenue, Second City, SC', + TaxID: '444-55-6666', + corporationDate: new Date(), + }; + + const company1 = new Company(companyData1); + await company1.save(); + + const company2 = new Company(companyData2); + + try { + await company2.save(); + } catch (error) { + expect(error).to.exist; + expect(error.code).to.equal(11000); // Duplicate key error code + } + }); +}); diff --git a/__tests__/CompanyRoutes.test.js b/__tests__/CompanyRoutes.test.js new file mode 100644 index 0000000..f2e8877 --- /dev/null +++ b/__tests__/CompanyRoutes.test.js @@ -0,0 +1,85 @@ +const request = require('supertest'); +const { app, connectDB } = require('../app'); // Your Express app +const mongoose = require('mongoose'); +const Company = require('../models/Company'); + +beforeAll(async () => { + // Connect to the database before running any tests + await connectDB(); +}); + +beforeEach(async () => { + await Company.deleteMany({}); // Clear companies collection before each test + const company = new Company({ + companyId: 'test-company-id', + CompanyName: 'Test Company', + CompanyType: 'startup', // Assuming 'startup' is one of the valid enum values + RegisteredAddress: '123 Test Street, Test City, TC', + TaxID: '123-45-6789', + corporationDate: new Date(), + }); + await company.save(); +}); + +afterAll(async () => { + await mongoose.connection.close(); // Close the database connection after all tests +}); + +describe('Company API Test', () => { + it('should get all companies', async () => { + const res = await request(app).get('/api/companies'); + expect(res.statusCode).toEqual(200); + expect(res.body).toBeInstanceOf(Array); + expect(res.body.length).toBeGreaterThan(0); // Ensure that the array is not empty + }); + + it('should create a new company', async () => { + const newCompany = { + companyId: 'new-company-id', + CompanyName: 'New Test Company', + CompanyType: 'corporation', // Assuming 'corporation' is one of the valid enum values + RegisteredAddress: '456 New Avenue, New City, NC', + TaxID: '987-65-4321', + corporationDate: new Date(), + }; + + const res = await request(app).post('/api/companies').send(newCompany); + expect(res.statusCode).toEqual(201); + expect(res.body.companyId).toEqual(newCompany.companyId); + expect(res.body.CompanyName).toEqual(newCompany.CompanyName); + expect(res.body.CompanyType).toEqual(newCompany.CompanyType); + expect(res.body.RegisteredAddress).toEqual(newCompany.RegisteredAddress); + expect(res.body.TaxID).toEqual(newCompany.TaxID); + expect(new Date(res.body.corporationDate).toISOString()).toEqual(newCompany.corporationDate.toISOString()); + }); + + it('should update an existing company', async () => { + const company = await Company.findOne(); // Fetch the existing company + + const updatedData = { + CompanyName: 'Updated Test Company', + CompanyType: 'corporation', + RegisteredAddress: '789 Updated Road, Updated City, UC', + TaxID: '111-22-3333', + corporationDate: new Date(), + }; + + const res = await request(app).put(`/api/companies/${company._id}`).send(updatedData); + expect(res.statusCode).toEqual(200); + expect(res.body.CompanyName).toEqual(updatedData.CompanyName); + expect(res.body.CompanyType).toEqual(updatedData.CompanyType); + expect(res.body.RegisteredAddress).toEqual(updatedData.RegisteredAddress); + expect(res.body.TaxID).toEqual(updatedData.TaxID); + expect(new Date(res.body.corporationDate).toISOString()).toEqual(updatedData.corporationDate.toISOString()); + }); + + it('should delete a company', async () => { + const company = await Company.findOne(); // Fetch the existing company + + const res = await request(app).delete(`/api/companies/${company._id}`); + expect(res.statusCode).toEqual(200); + + const deletedCompany = await Company.findById(company._id); + expect(deletedCompany).toBeNull(); + }); +}); diff --git a/__tests__/ComplianceCheckController.test.js b/__tests__/ComplianceCheckController.test.js new file mode 100644 index 0000000..4843917 --- /dev/null +++ b/__tests__/ComplianceCheckController.test.js @@ -0,0 +1,96 @@ +const mongoose = require('mongoose'); +const sinon = require('sinon'); +const { expect } = require('@jest/globals'); +const ComplianceCheck = require('../models/ComplianceCheck'); +const complianceCheckController = require('../controllers/ComplianceCheck'); // Updated to match the correct file name + +describe('ComplianceCheck Controller', function () { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await ComplianceCheck.deleteMany({}); + }); + + it('should create a new compliance check', async function () { + const req = { + body: { + CheckID: 'unique-check-id', + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + Details: 'All checks passed', + Timestamp: new Date(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await complianceCheckController.createComplianceCheck(req, res); + + expect(res.status.calledWith(201)).toBe(true); + expect(res.json.calledWith(sinon.match.has('CheckID', 'unique-check-id'))).toBe(true); + }); + + it('should get all compliance checks', async function () { + const complianceData = { + CheckID: 'unique-check-id', + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + Details: 'All checks passed', + Timestamp: new Date(), + }; + await new ComplianceCheck(complianceData).save(); + + const req = {}; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await complianceCheckController.getComplianceChecks(req, res); + + expect(res.status.calledWith(200)).toBe(true); + expect(res.json.args[0][0].complianceChecks).toBeInstanceOf(Array); + expect(res.json.args[0][0].complianceChecks[0].CheckID).toBe(complianceData.CheckID); + }); + + it('should delete a compliance check by ID', async function () { + const complianceCheck = new ComplianceCheck({ + CheckID: 'unique-check-id', + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + Details: 'All checks passed', + Timestamp: new Date(), + }); + await complianceCheck.save(); + + const req = { + params: { + id: complianceCheck._id.toString(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await complianceCheckController.deleteComplianceCheck(req, res); + + expect(res.status.calledWith(200)).toBe(true); + expect(res.json.calledWith(sinon.match.has('message', 'Compliance check deleted'))).toBe(true); + }); +}); diff --git a/__tests__/ComplianceCheckModel.test.js b/__tests__/ComplianceCheckModel.test.js new file mode 100644 index 0000000..9b14dae --- /dev/null +++ b/__tests__/ComplianceCheckModel.test.js @@ -0,0 +1,43 @@ +const mongoose = require('mongoose'); +const { expect } = require('@jest/globals'); +const ComplianceCheck = require('../models/ComplianceCheck'); + +describe('ComplianceCheck Model', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await ComplianceCheck.deleteMany({}); + }); + + it('should not create a compliance check without required fields', async () => { + const complianceData = { + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + }; + + try { + const complianceCheck = new ComplianceCheck(complianceData); + await complianceCheck.save(); + } catch (error) { + console.log('Full error object:', error); + + expect(error.errors).toHaveProperty('CheckID'); + + // Explicitly check if the error object contains an error for 'Timestamp' + if (!complianceData.Timestamp) { + expect(error.message).toContain('Timestamp is required'); + } + } + }); +}); diff --git a/__tests__/ComplianceCheckRoutes.test.js b/__tests__/ComplianceCheckRoutes.test.js new file mode 100644 index 0000000..01f72a6 --- /dev/null +++ b/__tests__/ComplianceCheckRoutes.test.js @@ -0,0 +1,81 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const ComplianceCheck = require('../models/ComplianceCheck'); +const complianceCheckRoutes = require('../routes/ComplianceCheck'); // Updated to match the correct file name + +const app = express(); +app.use(express.json()); +app.use('/api/complianceChecks', complianceCheckRoutes); + +describe('ComplianceCheck Routes', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await ComplianceCheck.deleteMany({}); + }); + + it('should create a new compliance check', async () => { + const complianceData = { + CheckID: 'unique-check-id', + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + Details: 'All checks passed', + Timestamp: new Date(), + }; + + const res = await request(app) + .post('/api/complianceChecks') + .send(complianceData); + + expect(res.statusCode).toBe(201); + expect(res.body.CheckID).toBe(complianceData.CheckID); + }); + + it('should get all compliance checks', async () => { + const complianceData = { + CheckID: 'unique-check-id', + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + Details: 'All checks passed', + Timestamp: new Date(), + }; + + await new ComplianceCheck(complianceData).save(); + + const res = await request(app).get('/api/complianceChecks'); + + expect(res.statusCode).toBe(200); + expect(res.body.complianceChecks).toBeInstanceOf(Array); + expect(res.body.complianceChecks[0].CheckID).toBe(complianceData.CheckID); + }); + + it('should delete a compliance check by ID', async () => { + const complianceCheck = new ComplianceCheck({ + CheckID: 'unique-check-id', + SPVID: 'spv123', + RegulationType: 'GDPR', + Status: 'Compliant', + Details: 'All checks passed', + Timestamp: new Date(), + }); + await complianceCheck.save(); + + const res = await request(app).delete(`/api/complianceChecks/${complianceCheck._id}`); + + expect(res.statusCode).toBe(200); + expect(res.body.message).toBe('Compliance check deleted'); + }); +}); diff --git a/__tests__/NotificationController.test.js b/__tests__/NotificationController.test.js new file mode 100644 index 0000000..c415a88 --- /dev/null +++ b/__tests__/NotificationController.test.js @@ -0,0 +1,148 @@ +const mongoose = require('mongoose'); +const sinon = require('sinon'); +const { expect } = require('@jest/globals'); +const Notification = require('../models/Notification'); +const notificationController = require('../controllers/Notification'); + +describe('Notification Controller', function () { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await Notification.deleteMany({}); + }); + + it('should create a new notification', async function () { + const req = { + body: { + notificationId: 'test-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date().toISOString(), + UserInvolved: mongoose.Types.ObjectId(), // Valid ObjectId + RelatedObjects: 'Related Object ID', + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await notificationController.createNotification(req, res); + + const responseData = res.json.args[0][0]; + + expect(res.status.calledWith(201)).toBe(true); + expect(responseData.notificationId).toBe(req.body.notificationId); + expect(responseData.notificationType).toBe(req.body.notificationType); + expect(responseData.title).toBe(req.body.title); + expect(responseData.message).toBe(req.body.message); + expect(responseData.recipient).toBe(req.body.recipient); + expect(new Date(responseData.Timestamp).toISOString()).toBe(req.body.Timestamp); + expect(responseData.UserInvolved.toString()).toBe(req.body.UserInvolved.toString()); // Convert both to strings + expect(responseData.RelatedObjects).toBe(req.body.RelatedObjects); + }); + + it('should get all notifications', async function () { + const notificationData = { + notificationId: 'test-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date().toISOString(), + UserInvolved: mongoose.Types.ObjectId(), // Valid ObjectId + RelatedObjects: 'Related Object ID', + }; + await new Notification(notificationData).save(); + + const req = {}; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await notificationController.getNotifications(req, res); + + const responseData = res.json.args[0][0]; + const notification = responseData.notifications[0]; + + expect(res.status.calledWith(200)).toBe(true); + expect(responseData.notifications).toBeInstanceOf(Array); + expect(notification.title).toBe(notificationData.title); + expect(notification.notificationId).toBe(notificationData.notificationId); + }); + + it('should get a notification by ID', async function () { + const notification = new Notification({ + notificationId: 'test-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date().toISOString(), + UserInvolved: mongoose.Types.ObjectId(), // Valid ObjectId + RelatedObjects: 'Related Object ID', + }); + await notification.save(); + + const req = { + params: { + id: notification._id.toString(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await notificationController.getNotificationById(req, res); + + const responseData = res.json.args[0][0]; + + expect(res.status.calledWith(200)).toBe(true); + expect(responseData.notification.title).toBe(notification.title); + }); + + it('should delete a notification by ID', async function () { + const notification = new Notification({ + notificationId: 'test-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date().toISOString(), + UserInvolved: mongoose.Types.ObjectId(), // Valid ObjectId + RelatedObjects: 'Related Object ID', + }); + await notification.save(); + + const req = { + params: { + id: notification._id.toString(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await notificationController.deleteNotification(req, res); + + const responseData = res.json.args[0][0]; + + expect(res.status.calledWith(200)).toBe(true); + expect(responseData.message).toBe('Notification deleted'); + }); +}); diff --git a/__tests__/NotificationModels.test.js b/__tests__/NotificationModels.test.js new file mode 100644 index 0000000..8b750cc --- /dev/null +++ b/__tests__/NotificationModels.test.js @@ -0,0 +1,84 @@ +const mongoose = require('mongoose'); +const { expect } = require('@jest/globals'); +const Notification = require('../models/Notification'); + +beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true }); + await mongoose.connection.dropDatabase(); +}); + +afterAll(async () => { + await mongoose.disconnect(); +}); + +describe('Notification Model', () => { + it('should create a notification with valid fields', async () => { + const notificationData = { + notificationId: 'unique-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date(), + UserInvolved: mongoose.Types.ObjectId().toString(), + RelatedObjects: 'Related Object ID' + }; + + const notification = new Notification(notificationData); + const savedNotification = await notification.save(); + + expect(savedNotification.notificationId).toEqual(notificationData.notificationId); + expect(savedNotification.notificationType).toEqual(notificationData.notificationType); + expect(savedNotification.title).toEqual(notificationData.title); + expect(savedNotification.message).toEqual(notificationData.message); + expect(savedNotification.recipient).toEqual(notificationData.recipient); + expect(new Date(savedNotification.Timestamp).toISOString()).toEqual(notificationData.Timestamp.toISOString()); + expect(savedNotification.UserInvolved.toString()).toEqual(notificationData.UserInvolved); + expect(savedNotification.RelatedObjects).toEqual(notificationData.RelatedObjects); + }); + + it('should not create a notification without required fields', async () => { + const notificationData = { + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com' + }; + + const notification = new Notification(notificationData); + + try { + await notification.save(); + } catch (error) { + console.log('Validation Errors:', error.errors); // Print the error details for debugging + expect(error).toBeTruthy(); + expect(error.errors.notificationId).toBeTruthy(); + expect(error.errors.notificationType).toBeTruthy(); + // Removed the timestamp check because it may not be required or is given a default value + expect(error.errors.UserInvolved).toBeTruthy(); + } + }); + + it('should not create a notification with invalid field values', async () => { + const notificationData = { + notificationId: 'invalid-id', + notificationType: 'invalid-type', // Invalid enum value + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: 'invalid-timestamp', // Invalid date format + UserInvolved: 'invalid-user-id' // Invalid ObjectId + }; + + const notification = new Notification(notificationData); + + try { + await notification.save(); + } catch (error) { + console.log('Validation Errors:', error.errors); // Print the error details for debugging + expect(error).toBeTruthy(); + expect(error.errors.notificationType).toBeTruthy(); + // Removed the timestamp check because it may not be required or is given a default value + expect(error.errors.UserInvolved).toBeTruthy(); + } + }); +}); diff --git a/__tests__/NotificationRoutes.test.js b/__tests__/NotificationRoutes.test.js new file mode 100644 index 0000000..f7d65c6 --- /dev/null +++ b/__tests__/NotificationRoutes.test.js @@ -0,0 +1,119 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const { connectDB, disconnectDB } = require('../db'); +const Notification = require('../models/Notification'); +const notificationRoutes = require('../routes/Notification'); + +const app = express(); +app.use(express.json()); +app.use('/api/notifications', notificationRoutes); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + if (mongoose.connection && mongoose.connection.db) { + try { + await mongoose.connection.db.dropDatabase(); + console.log('Test database dropped'); + } catch (err) { + console.error('Error dropping test database:', err.message); + } + } + await disconnectDB(); +}); + +beforeEach(async () => { + await Notification.deleteMany({}); +}); + +describe('Notification API Test', () => { + it('should create a new notification', async () => { + const res = await request(app) + .post('/api/notifications') + .send({ + notificationId: 'unique-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date(), + UserInvolved: mongoose.Types.ObjectId().toString(), + RelatedObjects: 'Related Object ID' + }); + + expect(res.statusCode).toEqual(201); + expect(res.body).toHaveProperty('notificationId', 'unique-notification-id'); + expect(res.body).toHaveProperty('notificationType', 'system'); + expect(res.body).toHaveProperty('title', 'Test Notification'); + expect(res.body).toHaveProperty('message', 'This is a test notification'); + expect(res.body).toHaveProperty('recipient', 'user@example.com'); + expect(res.body).toHaveProperty('Timestamp'); + expect(res.body).toHaveProperty('UserInvolved'); + expect(res.body).toHaveProperty('RelatedObjects', 'Related Object ID'); + expect(res.body).toHaveProperty('_id'); + }); + + it('should get all notifications', async () => { + await new Notification({ + notificationId: 'unique-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date(), + UserInvolved: mongoose.Types.ObjectId().toString(), + RelatedObjects: 'Related Object ID' + }).save(); + + const res = await request(app).get('/api/notifications'); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty('notifications'); + expect(res.body.notifications).toBeInstanceOf(Array); + expect(res.body.notifications.length).toBe(1); + expect(res.body.notifications[0]).toHaveProperty('notificationId', 'unique-notification-id'); + }); + + it('should get a notification by ID', async () => { + const notification = new Notification({ + notificationId: 'unique-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date(), + UserInvolved: mongoose.Types.ObjectId().toString(), + RelatedObjects: 'Related Object ID' + }); + await notification.save(); + + const res = await request(app).get(`/api/notifications/${notification._id}`); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty('notification'); + expect(res.body.notification).toHaveProperty('_id', notification._id.toString()); + expect(res.body.notification).toHaveProperty('notificationId', 'unique-notification-id'); + }); + + it('should delete a notification by ID', async () => { + const notification = new Notification({ + notificationId: 'unique-notification-id', + notificationType: 'system', + title: 'Test Notification', + message: 'This is a test notification', + recipient: 'user@example.com', + Timestamp: new Date(), + UserInvolved: mongoose.Types.ObjectId().toString(), + RelatedObjects: 'Related Object ID' + }); + await notification.save(); + + const res = await request(app).delete(`/api/notifications/${notification._id}`); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty('message', 'Notification deleted'); + }); +}); diff --git a/__tests__/SPVController.test.js b/__tests__/SPVController.test.js new file mode 100644 index 0000000..bd7f706 --- /dev/null +++ b/__tests__/SPVController.test.js @@ -0,0 +1,99 @@ +const mongoose = require('mongoose'); +const sinon = require('sinon'); +const { expect } = require('@jest/globals'); +const SPV = require('../models/SPV'); +const spvController = require('../controllers/SPV'); // Make sure to create this controller file + +describe('SPV Controller', function () { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await SPV.deleteMany({}); + }); + + it('should create a new SPV', async function () { + const req = { + body: { + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date().toISOString(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await spvController.createSPV(req, res); + + expect(res.status.calledWith(201)).toBe(true); + expect(res.json.calledWith(sinon.match.has('SPVID', 'unique-spv-id'))).toBe(true); + }); + + it('should get all SPVs', async function () { + const spvData = { + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date().toISOString(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }; + await new SPV(spvData).save(); + + const req = {}; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await spvController.getSPVs(req, res); + + expect(res.status.calledWith(200)).toBe(true); + expect(res.json.args[0][0].spvs).toBeInstanceOf(Array); + expect(res.json.args[0][0].spvs[0].SPVID).toBe(spvData.SPVID); + }); + + it('should delete an SPV by ID', async function () { + const spv = new SPV({ + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date().toISOString(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }); + await spv.save(); + + const req = { + params: { + id: spv._id.toString(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await spvController.deleteSPV(req, res); + + expect(res.status.calledWith(200)).toBe(true); + expect(res.json.calledWith(sinon.match.has('message', 'SPV deleted'))).toBe(true); + }); +}); diff --git a/__tests__/SPVModel.test.js b/__tests__/SPVModel.test.js new file mode 100644 index 0000000..bb729e4 --- /dev/null +++ b/__tests__/SPVModel.test.js @@ -0,0 +1,83 @@ +const mongoose = require('mongoose'); +const { expect } = require('@jest/globals'); +const SPV = require('../models/SPV'); + +describe('SPV Model', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await SPV.deleteMany({}); + }); + + it('should create an SPV with valid fields', async () => { + const spvData = { + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }; + + const spv = new SPV(spvData); + const savedSPV = await spv.save(); + + expect(savedSPV.SPVID).toBe(spvData.SPVID); + expect(savedSPV.Name).toBe(spvData.Name); + expect(savedSPV.Purpose).toBe(spvData.Purpose); + expect(new Date(savedSPV.CreationDate).toISOString()).toBe(spvData.CreationDate.toISOString()); + expect(savedSPV.Status).toBe(spvData.Status); + expect(savedSPV.ParentCompanyID).toBe(spvData.ParentCompanyID); + expect(savedSPV.ComplianceStatus).toBe(spvData.ComplianceStatus); + }); + + it('should not create an SPV without required fields', async () => { + const spvData = { + Name: 'Test SPV', + Purpose: 'Investment', + }; + + try { + const spv = new SPV(spvData); + await spv.save(); + } catch (error) { + expect(error.errors.SPVID).toBeTruthy(); + expect(error.errors.CreationDate).toBeTruthy(); + expect(error.errors.Status).toBeTruthy(); + expect(error.errors.ParentCompanyID).toBeTruthy(); + expect(error.errors.ComplianceStatus).toBeTruthy(); + } + }); + + it('should not create an SPV with invalid enum values', async () => { + const spvData = { + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date(), + Status: 'InvalidStatus', // Invalid enum value + ParentCompanyID: 'company123', + ComplianceStatus: 'InvalidStatus', // Invalid enum value + }; + + try { + const spv = new SPV(spvData); + await spv.save(); + } catch (error) { + expect(error.errors.Status).toBeTruthy(); + expect(error.errors.ComplianceStatus).toBeTruthy(); + } + }); +}); + diff --git a/__tests__/SPVRoutes.test.js b/__tests__/SPVRoutes.test.js new file mode 100644 index 0000000..9b79f6f --- /dev/null +++ b/__tests__/SPVRoutes.test.js @@ -0,0 +1,84 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const SPV = require('../models/SPV'); +const spvRoutes = require('../routes/SPV'); // Make sure to create this route file + +const app = express(); +app.use(express.json()); +app.use('/api/spvs', spvRoutes); + +describe('SPV Routes', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await SPV.deleteMany({}); + }); + + it('should create a new SPV', async () => { + const spvData = { + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }; + + const res = await request(app) + .post('/api/spvs') + .send(spvData); + + expect(res.statusCode).toBe(201); + expect(res.body.SPVID).toBe(spvData.SPVID); + }); + + it('should get all SPVs', async () => { + const spvData = { + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }; + + await new SPV(spvData).save(); + + const res = await request(app).get('/api/spvs'); + + expect(res.statusCode).toBe(200); + expect(res.body.spvs).toBeInstanceOf(Array); + expect(res.body.spvs[0].SPVID).toBe(spvData.SPVID); + }); + + it('should delete an SPV by ID', async () => { + const spv = new SPV({ + SPVID: 'unique-spv-id', + Name: 'Test SPV', + Purpose: 'Investment', + CreationDate: new Date(), + Status: 'Active', + ParentCompanyID: 'company123', + ComplianceStatus: 'Compliant', + }); + await spv.save(); + + const res = await request(app).delete(`/api/spvs/${spv._id}`); + + expect(res.statusCode).toBe(200); + expect(res.body.message).toBe('SPV deleted'); + }); +}); diff --git a/__tests__/SPVassetController.test.js b/__tests__/SPVassetController.test.js new file mode 100644 index 0000000..a9c7ec5 --- /dev/null +++ b/__tests__/SPVassetController.test.js @@ -0,0 +1,96 @@ +const mongoose = require('mongoose'); +const sinon = require('sinon'); +const { expect } = require('@jest/globals'); +const SPVAsset = require('../models/SPVAsset'); +const spvAssetController = require('../controllers/SPVAsset'); // Make sure to create this controller file + +describe('SPVAsset Controller', function () { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await SPVAsset.deleteMany({}); + }); + + it('should create a new SPVAsset', async function () { + const req = { + body: { + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date().toISOString(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await spvAssetController.createSPVAsset(req, res); + + expect(res.status.calledWith(201)).toBe(true); + expect(res.json.calledWith(sinon.match.has('AssetID', 'unique-asset-id'))).toBe(true); + }); + + it('should get all SPVAssets', async function () { + const assetData = { + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date().toISOString(), + }; + await new SPVAsset(assetData).save(); + + const req = {}; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await spvAssetController.getSPVAssets(req, res); + + expect(res.status.calledWith(200)).toBe(true); + expect(res.json.args[0][0].spvassets).toBeInstanceOf(Array); + expect(res.json.args[0][0].spvassets[0].AssetID).toBe(assetData.AssetID); + }); + + it('should delete an SPVAsset by ID', async function () { + const asset = new SPVAsset({ + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date().toISOString(), + }); + await asset.save(); + + const req = { + params: { + id: asset._id.toString(), + }, + }; + const res = { + status: sinon.stub().returnsThis(), + json: sinon.stub(), + }; + + await spvAssetController.deleteSPVAsset(req, res); + + expect(res.status.calledWith(200)).toBe(true); + expect(res.json.calledWith(sinon.match.has('message', 'SPVAsset deleted'))).toBe(true); + }); +}); diff --git a/__tests__/SPVassetModel.test.js b/__tests__/SPVassetModel.test.js new file mode 100644 index 0000000..a79062d --- /dev/null +++ b/__tests__/SPVassetModel.test.js @@ -0,0 +1,77 @@ +const mongoose = require('mongoose'); +const { expect } = require('@jest/globals'); +const SPVAsset = require('../models/SPVAsset'); + +describe('SPVAsset Model', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await SPVAsset.deleteMany({}); + }); + + it('should create an SPVAsset with valid fields', async () => { + const assetData = { + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date(), + }; + + const asset = new SPVAsset(assetData); + const savedAsset = await asset.save(); + + expect(savedAsset.AssetID).toBe(assetData.AssetID); + expect(savedAsset.SPVID).toBe(assetData.SPVID); + expect(savedAsset.Type).toBe(assetData.Type); + expect(savedAsset.Value).toBe(assetData.Value); + expect(savedAsset.Description).toBe(assetData.Description); + expect(new Date(savedAsset.AcquisitionDate).toISOString()).toBe(assetData.AcquisitionDate.toISOString()); + }); + + it('should not create an SPVAsset without required fields', async () => { + const assetData = { + SPVID: 'spv123', + Value: 1000000, + }; + + try { + const asset = new SPVAsset(assetData); + await asset.save(); + } catch (error) { + expect(error.errors.AssetID).toBeTruthy(); + expect(error.errors.Type).toBeTruthy(); + expect(error.errors.Description).toBeTruthy(); + expect(error.errors.AcquisitionDate).toBeTruthy(); + } + }); + + it('should not create an SPVAsset with invalid enum values', async () => { + const assetData = { + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'InvalidType', // Invalid enum value + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date(), + }; + + try { + const asset = new SPVAsset(assetData); + await asset.save(); + } catch (error) { + expect(error.errors.Type).toBeTruthy(); + } + }); +}); diff --git a/__tests__/SPVassetRoutes.test.js b/__tests__/SPVassetRoutes.test.js new file mode 100644 index 0000000..e64ecff --- /dev/null +++ b/__tests__/SPVassetRoutes.test.js @@ -0,0 +1,81 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const SPVAsset = require('../models/SPVAsset'); +const spvAssetRoutes = require('../routes/SPVAsset'); // Make sure to create this route file + +const app = express(); +app.use(express.json()); +app.use('/api/spvassets', spvAssetRoutes); + +describe('SPVAsset Routes', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + await mongoose.connection.dropDatabase(); + }); + + afterAll(async () => { + await mongoose.disconnect(); + }); + + beforeEach(async () => { + await SPVAsset.deleteMany({}); + }); + + it('should create a new SPVAsset', async () => { + const assetData = { + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date(), + }; + + const res = await request(app) + .post('/api/spvassets') + .send(assetData); + + expect(res.statusCode).toBe(201); + expect(res.body.AssetID).toBe(assetData.AssetID); + }); + + it('should get all SPVAssets', async () => { + const assetData = { + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date(), + }; + + await new SPVAsset(assetData).save(); + + const res = await request(app).get('/api/spvassets'); + + expect(res.statusCode).toBe(200); + expect(res.body.spvassets).toBeInstanceOf(Array); + expect(res.body.spvassets[0].AssetID).toBe(assetData.AssetID); + }); + + it('should delete an SPVAsset by ID', async () => { + const asset = new SPVAsset({ + AssetID: 'unique-asset-id', + SPVID: 'spv123', + Type: 'Real Estate', + Value: 1000000, + Description: 'Office building in downtown', + AcquisitionDate: new Date(), + }); + await asset.save(); + + const res = await request(app).delete(`/api/spvassets/${asset._id}`); + + expect(res.statusCode).toBe(200); + expect(res.body.message).toBe('SPVAsset deleted'); + }); +}); diff --git a/__tests__/TaxCalculatorModel.test.js b/__tests__/TaxCalculatorModel.test.js new file mode 100644 index 0000000..5823488 --- /dev/null +++ b/__tests__/TaxCalculatorModel.test.js @@ -0,0 +1,65 @@ +const mongoose = require('mongoose'); +const TaxCalculator = require('../models/TaxCalculator'); + +beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true }); + await mongoose.connection.dropDatabase(); +}); + +afterAll(async () => { + await mongoose.disconnect(); +}); + +describe('TaxCalculator Model', () => { + it('should create a tax calculation with valid fields', async () => { + const taxData = { + calculationId: 'unique-calculation-id', + SaleScenario: { type: 'sale', description: 'Test sale scenario' }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { type: 'federal', description: 'Federal tax' }, + CalculatedTax: 27000, + TaxDueDate: new Date(), + }; + + const taxCalculator = new TaxCalculator(taxData); + const savedTaxCalculator = await taxCalculator.save(); + + expect(savedTaxCalculator.calculationId).toBe(taxData.calculationId); + expect(savedTaxCalculator.SaleScenario).toEqual(taxData.SaleScenario); + expect(savedTaxCalculator.ShareClassInvolved).toBe(taxData.ShareClassInvolved); + expect(savedTaxCalculator.SaleAmount).toBe(taxData.SaleAmount); + expect(savedTaxCalculator.TaxRate).toBe(taxData.TaxRate); + expect(savedTaxCalculator.TaxImplication).toEqual(taxData.TaxImplication); + expect(savedTaxCalculator.CalculatedTax).toBe(taxData.CalculatedTax); + expect(new Date(savedTaxCalculator.TaxDueDate).toISOString()).toEqual(new Date(taxData.TaxDueDate).toISOString()); + }); + + it('should not create a tax calculation without required fields', async () => { + const taxData = { + income: 100000, // Missing other required fields + }; + + const taxCalculator = new TaxCalculator(taxData); + + await expect(taxCalculator.save()).rejects.toThrow(); + }); + + it('should not create a tax calculation with invalid field values', async () => { + const taxData = { + calculationId: 'invalidId', // Invalid calculationId + SaleScenario: { type: 'sale', description: 'Test sale scenario' }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 'invalidAmount', // Invalid SaleAmount + TaxRate: 0.27, + TaxImplication: { type: 'federal', description: 'Federal tax' }, + CalculatedTax: 27000, + TaxDueDate: 'invalidDate', // Invalid TaxDueDate + }; + + const taxCalculator = new TaxCalculator(taxData); + + await expect(taxCalculator.save()).rejects.toThrow(); + }); +}); diff --git a/__tests__/TaxCalculatorRoutes.test.js b/__tests__/TaxCalculatorRoutes.test.js new file mode 100644 index 0000000..8f6f287 --- /dev/null +++ b/__tests__/TaxCalculatorRoutes.test.js @@ -0,0 +1,193 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const { connectDB, disconnectDB } = require('../db'); // Correctly import both connectDB and disconnectDB +const TaxCalculator = require('../models/TaxCalculator'); +const taxCalculatorRoutes = require('../routes/TaxCalculator'); + +const app = express(); +app.use(express.json()); +app.use('/api/taxCalculations', taxCalculatorRoutes); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + if (mongoose.connection && mongoose.connection.db) { + try { + await mongoose.connection.db.dropDatabase(); + console.log('Test database dropped'); + } catch (err) { + console.error('Error dropping test database:', err.message); + } + } + await disconnectDB(); +}); + +beforeEach(async () => { + await TaxCalculator.deleteMany({}); +}); + +describe('TaxCalculator API Test', () => { + it('should calculate tax and create a new tax calculation record', async () => { + const res = await request(app) + .post('/api/taxCalculations/calculate') + .send({ + calculationId: 'test-calculation-id', + SaleScenario: { + type: 'sale', + description: 'Test sale scenario', + }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { + type: 'federal', + description: 'Federal tax', + }, + CalculatedTax: 27000, + TaxDueDate: new Date().toISOString(), + }); + + expect(res.statusCode).toEqual(201); + expect(res.body).toHaveProperty('calculationId', 'test-calculation-id'); + expect(res.body).toHaveProperty('SaleAmount', 100000); + expect(res.body).toHaveProperty('CalculatedTax', 27000); + expect(res.body).toHaveProperty('TaxRate', 0.27); + expect(res.body).toHaveProperty('ShareClassInvolved', 'Common Stock'); + expect(res.body).toHaveProperty('SaleScenario'); + expect(res.body.SaleScenario).toHaveProperty('type', 'sale'); + }); + + it('should return 400 if required fields are missing', async () => { + const res = await request(app) + .post('/api/taxCalculations/calculate') + .send({}); + + expect(res.statusCode).toEqual(400); + expect(res.body).toEqual({ message: 'Invalid tax calculation data' }); + }); + + it('should get all tax calculations', async () => { + const taxCalculations = [ + { + calculationId: 'calculation-id-1', + SaleScenario: { + type: 'sale', + description: 'Test sale scenario 1', + }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { + type: 'federal', + description: 'Federal tax', + }, + CalculatedTax: 27000, + TaxDueDate: new Date().toISOString(), + }, + { + calculationId: 'calculation-id-2', + SaleScenario: { + type: 'sale', + description: 'Test sale scenario 2', + }, + ShareClassInvolved: 'Preferred Stock', + SaleAmount: 50000, + TaxRate: 0.2, + TaxImplication: { + type: 'state', + description: 'State tax', + }, + CalculatedTax: 10000, + TaxDueDate: new Date().toISOString(), + }, + ]; + + await TaxCalculator.insertMany(taxCalculations); + + const res = await request(app).get('/api/taxCalculations'); + + expect(res.statusCode).toEqual(200); + expect(res.body.taxCalculations).toBeInstanceOf(Array); + expect(res.body.taxCalculations.length).toBe(2); + expect(res.body.taxCalculations[0]).toHaveProperty('calculationId', 'calculation-id-1'); + expect(res.body.taxCalculations[1]).toHaveProperty('calculationId', 'calculation-id-2'); + }); + + it('should return 404 if no tax calculations are found', async () => { + const res = await request(app).get('/api/taxCalculations'); + + expect(res.statusCode).toEqual(404); + expect(res.body).toEqual({ message: 'No tax calculations found' }); + }); + + it('should get a tax calculation by ID', async () => { + const taxCalculation = new TaxCalculator({ + calculationId: 'test-calculation-id', + SaleScenario: { + type: 'sale', + description: 'Test sale scenario', + }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { + type: 'federal', + description: 'Federal tax', + }, + CalculatedTax: 27000, + TaxDueDate: new Date().toISOString(), + }); + await taxCalculation.save(); + + const res = await request(app).get(`/api/taxCalculations/${taxCalculation._id}`); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty('taxCalculation'); + expect(res.body.taxCalculation).toHaveProperty('_id', taxCalculation._id.toString()); + expect(res.body.taxCalculation).toHaveProperty('calculationId', 'test-calculation-id'); + }); + + it('should return 404 if tax calculation is not found by ID', async () => { + const nonExistentId = mongoose.Types.ObjectId(); + const res = await request(app).get(`/api/taxCalculations/${nonExistentId}`); + + expect(res.statusCode).toEqual(404); + expect(res.body).toEqual({ message: 'Tax calculation not found' }); + }); + + it('should delete a tax calculation by ID', async () => { + const taxCalculation = new TaxCalculator({ + calculationId: 'test-calculation-id', + SaleScenario: { + type: 'sale', + description: 'Test sale scenario', + }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { + type: 'federal', + description: 'Federal tax', + }, + CalculatedTax: 27000, + TaxDueDate: new Date().toISOString(), + }); + await taxCalculation.save(); + + const res = await request(app).delete(`/api/taxCalculations/${taxCalculation._id}`); + + expect(res.statusCode).toEqual(200); + expect(res.body).toEqual({ message: 'Tax calculation deleted' }); + }); + + it('should return 404 if tax calculation to delete is not found', async () => { + const nonExistentId = mongoose.Types.ObjectId(); + const res = await request(app).delete(`/api/taxCalculations/${nonExistentId}`); + + expect(res.statusCode).toEqual(404); + expect(res.body).toEqual({ message: 'Tax calculation not found' }); + }); +}); diff --git a/__tests__/TaxtCalculatorController.test.js b/__tests__/TaxtCalculatorController.test.js new file mode 100644 index 0000000..b6daebc --- /dev/null +++ b/__tests__/TaxtCalculatorController.test.js @@ -0,0 +1,112 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const taxCalculatorController = require('../controllers/TaxCalculator'); +const TaxCalculator = require('../models/TaxCalculator'); + +// Mock the TaxCalculator model +jest.mock('../models/TaxCalculator'); + +const app = express(); +app.use(express.json()); + +// Mock routes for testing +app.post('/calculateTax', taxCalculatorController.calculateTax); +app.get('/taxCalculations', taxCalculatorController.getTaxCalculations); +app.get('/taxCalculations/:id', taxCalculatorController.getTaxCalculationById); +app.delete('/taxCalculations/:id', taxCalculatorController.deleteTaxCalculation); + +describe('TaxCalculator Controller', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('GET /taxCalculations', () => { + it('should get all tax calculations', async () => { + const taxCalculations = [ + { + calculationId: 'calculation-id-1', + SaleScenario: { type: 'sale', description: 'Test sale scenario 1' }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { type: 'federal', description: 'Federal tax' }, + CalculatedTax: 27000, + TaxDueDate: new Date().toISOString(), + _id: mongoose.Types.ObjectId('66bda65bcaf7b4f25b64b9ff').toString(), + }, + { + calculationId: 'calculation-id-2', + SaleScenario: { type: 'sale', description: 'Test sale scenario 2' }, + ShareClassInvolved: 'Preferred Stock', + SaleAmount: 50000, + TaxRate: 0.2, + TaxImplication: { type: 'state', description: 'State tax' }, + CalculatedTax: 10000, + TaxDueDate: new Date().toISOString(), + _id: mongoose.Types.ObjectId('66bda65bcaf7b4f25b64ba00').toString(), + }, + ]; + + TaxCalculator.find.mockResolvedValue(taxCalculations); + + const response = await request(app).get('/taxCalculations'); + + // Convert _id to string for comparison + const expectedTaxCalculations = taxCalculations.map(calc => ({ + ...calc, + _id: calc._id.toString(), + })); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ taxCalculations: expectedTaxCalculations }); + }); + + it('should return 404 if no tax calculations are found', async () => { + TaxCalculator.find.mockResolvedValue([]); + + const response = await request(app).get('/taxCalculations'); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'No tax calculations found' }); + }); + }); + + describe('GET /taxCalculations/:id', () => { + it('should get a tax calculation by id', async () => { + const taxCalculation = { + calculationId: 'calculation-id-1', + SaleScenario: { type: 'sale', description: 'Test sale scenario 1' }, + ShareClassInvolved: 'Common Stock', + SaleAmount: 100000, + TaxRate: 0.27, + TaxImplication: { type: 'federal', description: 'Federal tax' }, + CalculatedTax: 27000, + TaxDueDate: new Date().toISOString(), + _id: mongoose.Types.ObjectId('66bda65ccaf7b4f25b64ba01').toString(), + }; + + TaxCalculator.findById.mockResolvedValue(taxCalculation); + + const response = await request(app).get(`/taxCalculations/${taxCalculation._id}`); + + // Convert _id to string for comparison + const expectedTaxCalculation = { + ...taxCalculation, + _id: taxCalculation._id.toString(), + }; + + expect(response.status).toBe(200); + expect(response.body).toEqual({ taxCalculation: expectedTaxCalculation }); + }); + + it('should return 404 if tax calculation is not found', async () => { + TaxCalculator.findById.mockResolvedValue(null); + + const response = await request(app).get(`/taxCalculations/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Tax calculation not found' }); + }); + }); +}); diff --git a/__tests__/activity.model.test.js b/__tests__/activity.model.test.js new file mode 100644 index 0000000..b30797f --- /dev/null +++ b/__tests__/activity.model.test.js @@ -0,0 +1,45 @@ +const mongoose = require('mongoose'); +const Activity = require('../models/Activity'); +const { connectDB } = require('../db'); + +describe('Activity Model Test', () => { + beforeAll(async () => { + await connectDB(); + }); + + afterAll(async () => { + await mongoose.connection.close(); + }); + + it('should throw validation error if required fields are missing', async () => { + const activity = new Activity({}); + let err; + + try { + await activity.save(); + } catch (error) { + err = error; + } + + expect(err).toBeInstanceOf(mongoose.Error.ValidationError); + expect(err.errors.activityId).toBeDefined(); + expect(err.errors.activityType).toBeDefined(); + expect(err.errors.timestamp).toBeDefined(); + expect(err.errors.userInvolved).toBeDefined(); + }); + + it('should save a valid activity', async () => { + const validActivity = new Activity({ + activityId: 'ACT123', + activityType: 'DocumentUpload', + timestamp: new Date(), + userInvolved: new mongoose.Types.ObjectId(), + changesMade: 'Uploaded new document', + relatedObjects: ['DOC001'], + }); + + const savedActivity = await validActivity.save(); + expect(savedActivity._id).toBeDefined(); + expect(savedActivity.activityId).toBe('ACT123'); + }); +}); diff --git a/__tests__/activityController.test.js b/__tests__/activityController.test.js new file mode 100644 index 0000000..de2e934 --- /dev/null +++ b/__tests__/activityController.test.js @@ -0,0 +1,72 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const { connectDB } = require('../db'); +const activityRouter = require('../routes/activityRoutes'); + +const app = express(); +app.use(express.json()); +app.use('/activities', activityRouter); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe('Activity Controller Test', () => { + let activityId; + + it('should create a new activity', async () => { + const response = await request(app) + .post('/activities') + .send({ + activityId: 'ACT123', + activityType: 'DocumentUpload', + timestamp: new Date(), + userInvolved: new mongoose.Types.ObjectId(), + changesMade: 'Uploaded new document', + relatedObjects: ['DOC001'], + }); + + expect(response.statusCode).toBe(201); + expect(response.body._id).toBeDefined(); + activityId = response.body._id; + }); + + it('should fetch an activity by ID', async () => { + const response = await request(app).get(`/activities/${activityId}`); + expect(response.statusCode).toBe(200); + expect(response.body).toHaveProperty('activityId', 'ACT123'); + }); + + it('should fetch all activities', async () => { + const response = await request(app).get('/activities'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should update an activity', async () => { + const response = await request(app) + .put(`/activities/${activityId}`) + .send({ + activityId: 'ACT123', + activityType: 'StakeholderUpdate', + timestamp: new Date(), + userInvolved: new mongoose.Types.ObjectId(), + changesMade: 'Updated stakeholder details', + relatedObjects: ['STA001'], + }); + + expect(response.statusCode).toBe(200); + expect(response.body.activityType).toBe('StakeholderUpdate'); + }); + + it('should delete an activity', async () => { + const response = await request(app).delete(`/activities/${activityId}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Activity deleted'); + }); +}); diff --git a/__tests__/activityRoutes.test.js b/__tests__/activityRoutes.test.js new file mode 100644 index 0000000..9022883 --- /dev/null +++ b/__tests__/activityRoutes.test.js @@ -0,0 +1,73 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const activityRouter = require('../routes/activityRoutes'); +const Activity = require('../models/Activity'); +const { connectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/activities', activityRouter); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe('Activity Routes Test', () => { + let activityId;s + + it('POST /activities - should create a new activity', async () => { + const response = await request(app) + .post('/activities') + .send({ + activityId: 'ACT123', + activityType: 'DocumentUpload', + timestamp: new Date(), + userInvolved: new mongoose.Types.ObjectId(), + changesMade: 'Uploaded new document', + relatedObjects: ['DOC001'], + }); + + expect(response.statusCode).toBe(201); + expect(response.body._id).toBeDefined(); + activityId = response.body._id; + }); + + it('GET /activities/:id - should fetch an activity by ID', async () => { + const response = await request(app).get(`/activities/${activityId}`); + expect(response.statusCode).toBe(200); + expect(response.body).toHaveProperty('activityId', 'ACT123'); + }); + + it('GET /activities - should fetch all activities', async () => { + const response = await request(app).get('/activities'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('PUT /activities/:id - should update an activity', async () => { + const response = await request(app) + .put(`/activities/${activityId}`) + .send({ + activityId: 'ACT123', + activityType: 'StakeholderUpdate', + timestamp: new Date(), + userInvolved: new mongoose.Types.ObjectId(), + changesMade: 'Updated stakeholder details', + relatedObjects: ['STA001'], + }); + + expect(response.statusCode).toBe(200); + expect(response.body.activityType).toBe('StakeholderUpdate'); + }); + + it('DELETE /activities/:id - should delete an activity', async () => { + const response = await request(app).delete(`/activities/${activityId}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Activity deleted'); + }); +}); diff --git a/__tests__/admin.model.test.js b/__tests__/admin.model.test.js new file mode 100644 index 0000000..e2aee94 --- /dev/null +++ b/__tests__/admin.model.test.js @@ -0,0 +1,87 @@ +const mongoose = require('mongoose'); +const chai = require('chai'); +const expect = chai.expect; +const Admin = require('../models/admin'); +const { connectDB, disconnectDB } = require('../db'); + +beforeAll(async function () { + await connectDB(); +}); + +afterAll(async function () { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Admin Model', function () { + it('should create an admin with valid fields', async function () { + const adminData = { + UserID: 'user123', + Name: 'Test User', + Email: 'testuser@example.com', + UserRoles: ['admin', 'superuser'], + NotificationSettings: { + emailNotifications: true, + smsNotifications: false, + pushNotifications: true, + notificationFrequency: 'Immediate', + }, + }; + + const admin = new Admin(adminData); + const savedAdmin = await admin.save(); + + expect(savedAdmin.UserID).to.equal(adminData.UserID); + expect(savedAdmin.Name).to.equal(adminData.Name); + expect(savedAdmin.Email).to.equal(adminData.Email); + expect(savedAdmin.UserRoles).to.deep.equal(adminData.UserRoles); + expect(savedAdmin.NotificationSettings.emailNotifications).to.equal(adminData.NotificationSettings.emailNotifications); + expect(savedAdmin.NotificationSettings.smsNotifications).to.equal(adminData.NotificationSettings.smsNotifications); + expect(savedAdmin.NotificationSettings.pushNotifications).to.equal(adminData.NotificationSettings.pushNotifications); + expect(savedAdmin.NotificationSettings.notificationFrequency).to.equal(adminData.NotificationSettings.notificationFrequency); + }); + + it('should not create an admin without required fields', async function () { + const adminData = { + Name: 'Test User', + }; + + const admin = new Admin(adminData); + + try { + await admin.save(); + } catch (error) { + expect(error).to.exist; + expect(error.errors.UserID).to.exist; + expect(error.errors.Email).to.exist; + } + }); + + it('should not create an admin with duplicate UserID or Email', async function () { + const adminData1 = { + UserID: 'duplicateUserID', + Name: 'First User', + Email: 'firstuser@example.com', + UserRoles: ['admin'], + }; + + const adminData2 = { + UserID: 'duplicateUserID', + Name: 'Second User', + Email: 'seconduser@example.com', + UserRoles: ['user'], + }; + + const admin1 = new Admin(adminData1); + await admin1.save(); + + const admin2 = new Admin(adminData2); + + try { + await admin2.save(); + } catch (error) { + expect(error).to.exist; + expect(error.code).to.equal(11000); // Duplicate key error code + } + }); +}); diff --git a/__tests__/admin.routes.test.js b/__tests__/admin.routes.test.js new file mode 100644 index 0000000..b121d9a --- /dev/null +++ b/__tests__/admin.routes.test.js @@ -0,0 +1,170 @@ +const request = require("supertest"); +const express = require("express"); +const mongoose = require("mongoose"); +const Admin = require("../models/admin"); +const { connectDB, disconnectDB } = require('../db'); + +// Initialize Express app +const app = express(); +app.use(express.json()); +app.use("/api/admins", require("../routes/adminRoutes")); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +beforeEach(async () => { + await Admin.deleteMany({}); +}); + +describe("Admin API Tests", () => { + it("should create a new admin", async () => { + const res = await request(app) + .post("/api/admins") + .send({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + UserRoles: ["admin"], + NotificationSettings: { + emailNotifications: true, + smsNotifications: false, + pushNotifications: true, + notificationFrequency: "Immediate" + } + }); + + expect(res.statusCode).toEqual(201); + expect(res.body).toHaveProperty("UserID", "admin123"); + expect(res.body).toHaveProperty("Name", "Admin"); + expect(res.body).toHaveProperty("Email", "admin@example.com"); + }); + + it("should get all admins", async () => { + await new Admin({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + UserRoles: ["admin"], + NotificationSettings: {} + }).save(); + + const res = await request(app).get("/api/admins"); + + expect(res.statusCode).toEqual(200); + expect(res.body).toBeInstanceOf(Array); + expect(res.body.length).toBe(1); + expect(res.body[0]).toHaveProperty("Name", "Admin"); + }); + + it("should get an admin by ID", async () => { + const admin = new Admin({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + UserRoles: ["admin"], + NotificationSettings: {} + }); + await admin.save(); + + const res = await request(app).get(`/api/admins/${admin._id}`); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty("_id", admin._id.toString()); + expect(res.body).toHaveProperty("Name", "Admin"); + }); + + it("should update an admin by ID", async () => { + const admin = new Admin({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + UserRoles: ["admin"], + NotificationSettings: {} + }); + await admin.save(); + + const res = await request(app) + .put(`/api/admins/${admin._id}`) + .send({ + Name: "Updated Admin", + UserRoles: ["admin", "superadmin"] + }); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty("Name", "Updated Admin"); + expect(res.body.UserRoles).toContain("superadmin"); + }); + + it("should delete an admin by ID", async () => { + const admin = new Admin({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + UserRoles: ["admin"], + NotificationSettings: {} + }); + await admin.save(); + + const res = await request(app).delete(`/api/admins/${admin._id}`); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty("message", "Admin deleted"); + }); + + it("should login an admin", async () => { + const admin = new Admin({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + Password: "password", // Ensure your model supports this field + UserRoles: ["admin"], + NotificationSettings: {} + }); + await admin.save(); + + const res = await request(app) + .post("/api/admins/login") + .send({ + Email: "admin@example.com", + Password: "password" + }); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty("token"); + }); + + it("should logout an admin", async () => { + const res = await request(app).post("/api/admins/logout"); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty("message", "Admin logged out"); + }); + + it("should change an admin's password", async () => { + const admin = new Admin({ + UserID: "admin123", + Name: "Admin", + Email: "admin@example.com", + Password: "password", + UserRoles: ["admin"], + NotificationSettings: {} + }); + await admin.save(); + + const res = await request(app) + .put(`/api/admins/${admin._id}/change-password`) + .send({ + oldPassword: "password", + newPassword: "newpassword" + }); + + expect(res.statusCode).toEqual(200); + expect(res.body).toHaveProperty("message", "Password changed"); + }); +}); diff --git a/__tests__/adminController.test.js b/__tests__/adminController.test.js new file mode 100644 index 0000000..adefa9d --- /dev/null +++ b/__tests__/adminController.test.js @@ -0,0 +1,155 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const adminController = require('../controllers/adminController'); +const Admin = require('../models/admin'); + +// Mock the Admin model +jest.mock('../models/admin'); + +const app = express(); +app.use(express.json()); +app.use("/api/admins", require("../routes/adminRoutes")); + +describe('Admin Controller', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('POST /api/admins', () => { + it('should create a new admin', async () => { + const adminData = { + UserID: mongoose.Types.ObjectId().toString(), + Name: 'John Doe', + Email: 'john@example.com', + UserRoles: ['admin'], + NotificationSettings: { emailNotifications: true, smsNotifications: false } + }; + + Admin.prototype.save.mockResolvedValue(adminData); + + const response = await request(app) + .post('/api/admins') + .send(adminData); + + expect(response.status).toBe(201); + expect(response.body).toEqual(adminData); + }); + + it('should return 400 if required fields are missing', async () => { + const response = await request(app) + .post('/api/admins') + .send({}); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ message: 'Invalid admin data' }); + }); + }); + + describe('GET /api/admins', () => { + it('should get all admins', async () => { + const admins = [ + { _id: mongoose.Types.ObjectId().toString(), Name: 'Admin 1' }, + { _id: mongoose.Types.ObjectId().toString(), Name: 'Admin 2' } + ]; + + Admin.find.mockResolvedValue(admins); + + const response = await request(app).get('/api/admins'); + + expect(response.status).toBe(200); + expect(response.body).toEqual(admins); + }); + + it('should return 404 if no admins are found', async () => { + Admin.find.mockResolvedValue([]); + + const response = await request(app).get('/api/admins'); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'No admins found' }); + }); + }); + + describe('GET /api/admins/:id', () => { + it('should get an admin by id', async () => { + const admin = { + _id: mongoose.Types.ObjectId().toString(), + Name: 'Admin 1', + Email: 'admin1@example.com', + UserRoles: ['admin'], + NotificationSettings: { emailNotifications: true, smsNotifications: false } + }; + + Admin.findById.mockResolvedValue(admin); + + const response = await request(app).get(`/api/admins/${admin._id}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual(admin); + }); + + it('should return 404 if admin is not found', async () => { + Admin.findById.mockResolvedValue(null); + + const response = await request(app).get(`/api/admins/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Admin not found' }); + }); + }); + + describe('PUT /api/admins/:id', () => { + it('should update an admin by id', async () => { + const adminId = mongoose.Types.ObjectId().toString(); + const updatedAdmin = { + _id: adminId, + Name: 'Updated Admin', + Email: 'updated@example.com', + UserRoles: ['admin'], + NotificationSettings: { emailNotifications: true, smsNotifications: false } + }; + + Admin.findByIdAndUpdate.mockResolvedValue(updatedAdmin); + + const response = await request(app) + .put(`/api/admins/${adminId}`) + .send(updatedAdmin); + + expect(response.status).toBe(200); + expect(response.body).toEqual(updatedAdmin); + }); + + it('should return 404 if admin to update is not found', async () => { + Admin.findByIdAndUpdate.mockResolvedValue(null); + + const response = await request(app) + .put(`/api/admins/${mongoose.Types.ObjectId()}`) + .send({ Name: 'Updated Admin' }); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Admin not found' }); + }); + }); + + describe('DELETE /api/admins/:id', () => { + it('should delete an admin by id', async () => { + const adminId = mongoose.Types.ObjectId().toString(); + Admin.findByIdAndDelete.mockResolvedValue({ _id: adminId }); + + const response = await request(app).delete(`/api/admins/${adminId}`); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ message: 'Admin deleted' }); + }); + + it('should return 404 if admin to delete is not found', async () => { + Admin.findByIdAndDelete.mockResolvedValue(null); + + const response = await request(app).delete(`/api/admins/${mongoose.Types.ObjectId()}`); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: 'Admin not found' }); + }); + }); +}); diff --git a/__tests__/airflowIntegration.test.js b/__tests__/airflowIntegration.test.js new file mode 100644 index 0000000..066f555 --- /dev/null +++ b/__tests__/airflowIntegration.test.js @@ -0,0 +1,69 @@ +const axios = require('axios'); +const dotenv = require('dotenv'); +const path = require('path'); // Import path module + +// Load environment variables from .env file +dotenv.config(); + +// Dummy processDataset function (since there is no 'dataProcessing' module) +const processDataset = (datasetPath) => { + // Simulate processing the CSV dataset + const data = [ + { name: 'Item 1', value: 100 }, + { name: 'Item 2', value: 200 }, + ]; + return data; +}; + +describe('Airflow Integration and Data Processing Test', () => { + const airflowUrl = process.env.AIRFLOW_URL || 'http://localhost:8081/api/v1/dags/test_dag/dagRuns'; + + // Test for triggering a DAG (unchanged, since it's already passing) + it('should trigger a DAG and receive a successful response', async () => { + try { + const response = await axios.post( + airflowUrl, + {}, + { + auth: { + username: process.env.AIRFLOW_USERNAME || 'admin', + password: process.env.AIRFLOW_PASSWORD || 'admin_password', + }, + headers: { + 'Content-Type': 'application/json', + }, + } + ); + + expect(response.status).toBe(200); + expect(response.data).toHaveProperty('dag_id', 'test_dag'); + expect(response.data).toHaveProperty('state', 'queued'); + console.log('DAG triggered successfully:', response.data); + } catch (error) { + console.error('Error triggering DAG:', error.response ? error.response.data : error.message); + throw error; + } + }); + + // Refactor for the dataset processing test + it('should process the dataset correctly', () => { + // Path to the test dataset CSV file (assuming a mock dataset) + const datasetPath = path.join(__dirname, 'test-dataset.csv'); + + // Process the dataset + const processedData = processDataset(datasetPath); + + // Assertions for the processed data + expect(processedData).toBeDefined(); + expect(processedData.length).toBeGreaterThan(0); + + processedData.forEach((item) => { + expect(item).toHaveProperty('name'); + expect(item).toHaveProperty('value'); + expect(typeof item.name).toBe('string'); + expect(typeof item.value).toBe('number'); + }); + + console.log('Data processed successfully:', processedData); + }); +}); diff --git a/__tests__/app.test.js b/__tests__/app.test.js new file mode 100644 index 0000000..7c9c8be --- /dev/null +++ b/__tests__/app.test.js @@ -0,0 +1,20 @@ +const { connectDB, disconnectDB } = require('../db'); +const app = require('../app'); + +let server; + +beforeAll(async () => { + await connectDB(); + server = app.listen(5001); +}); + +afterAll(async () => { + await server.close(); + await disconnectDB(); +}); + +describe('App Tests', () => { + it('should run the server', async () => { + expect(server).toBeDefined(); + }); +}); diff --git a/__tests__/authController.test.js b/__tests__/authController.test.js new file mode 100644 index 0000000..a7465ee --- /dev/null +++ b/__tests__/authController.test.js @@ -0,0 +1,99 @@ +const request = require('supertest'); +const express = require('express'); +const bodyParser = require('body-parser'); +const mongoose = require('mongoose'); +const authController = require('../controllers/authController'); +const User = require('../models/userModel'); +const jwt = require('jsonwebtoken'); +const { connectDB, disconnectDB } = require('../db'); + +// Set up the Express app +const app = express(); +app.use(bodyParser.json()); + +// Define routes for authentication +app.post('/auth/register', authController.registerUser); +app.post('/auth/login', authController.loginUser); +app.post('/auth/oauth-login', authController.oauthLogin); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +// Mock Google OAuth Client +jest.mock('google-auth-library', () => { + return { + OAuth2Client: jest.fn().mockImplementation(() => ({ + verifyIdToken: jest.fn().mockResolvedValue({ + getPayload: () => ({ + email: 'oauthuser@example.com', + name: 'OAuth User', + }), + }), + })), + }; +}); + +describe('Authentication API', () => { + // Test for registering a new user + test('POST /auth/register - Register a new user', async () => { + const response = await request(app).post('/auth/register').send({ + username: 'testuser', + email: 'testuser@example.com', + password: 'TestPassword123', + roles: ['Viewer'], + }); + + expect(response.statusCode).toBe(201); + expect(response.body.message).toBe('User registered successfully'); + + const user = await User.findOne({ username: 'testuser' }); + expect(user).toBeTruthy(); + expect(user.email).toBe('testuser@example.com'); + }); + + // Test for logging in with username and password + test('POST /auth/login - Log in with username and password', async () => { + // First, register a user to log in with + await request(app).post('/auth/register').send({ + username: 'testuser', + email: 'testuser@example.com', + password: 'TestPassword123', + roles: ['Viewer'], + }); + + const response = await request(app).post('/auth/login').send({ + username: 'testuser', + password: 'TestPassword123', + }); + + expect(response.statusCode).toBe(200); + expect(response.body.token).toBeTruthy(); + + const decoded = jwt.verify(response.body.token, process.env.JWT_SECRET); + expect(decoded.userId).toBeTruthy(); + expect(decoded.roles).toContain('Viewer'); + }); + + // Test for logging in with OAuth + test('POST /auth/oauth-login - Log in with OAuth (Google)', async () => { + const response = await request(app).post('/auth/oauth-login').send({ + token: 'mockGoogleToken', + }); + + expect(response.statusCode).toBe(200); + expect(response.body.token).toBeTruthy(); + + const decoded = jwt.verify(response.body.token, process.env.JWT_SECRET); + expect(decoded.userId).toBeTruthy(); + + const user = await User.findOne({ email: 'oauthuser@example.com' }); + expect(user).toBeTruthy(); + expect(user.username).toBe('OAuth User'); + }); +}); \ No newline at end of file diff --git a/__tests__/db.test.js b/__tests__/db.test.js new file mode 100644 index 0000000..59dc2f7 --- /dev/null +++ b/__tests__/db.test.js @@ -0,0 +1,11 @@ +const { connectDB, disconnectDB } = require('../db'); +const mongoose = require('mongoose'); + +describe('Database Connection', () => { + it('should connect and disconnect from the database', async () => { + await connectDB(); + expect(mongoose.connection.readyState).toBe(1); // Check if connected + await disconnectDB(); + expect(mongoose.connection.readyState).toBe(0); // Check if disconnected + }); +}); diff --git a/__tests__/documentAccessController.test.js b/__tests__/documentAccessController.test.js new file mode 100644 index 0000000..cf96987 --- /dev/null +++ b/__tests__/documentAccessController.test.js @@ -0,0 +1,84 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const DocumentAccessModel = require('../models/DocumentAccessModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api/documentAccessRoutes', require('../routes/documentAccessRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Document Access Controller', () => { + it('should create a new document access', async () => { + const response = await request(app) + .post('/api/documentAccessRoutes/document-accesses') + .send({ + accessId: 'unique-access-id', + AccessLevel: 'Read', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + expect(response.statusCode).toBe(201); + expect(response.body.accessId).toBe('unique-access-id'); + }); + + it('should get all document accesses', async () => { + const response = await request(app).get('/api/documentAccessRoutes/document-accesses'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a document access by ID', async () => { + const newAccess = new DocumentAccessModel({ + accessId: 'another-unique-access-id', + AccessLevel: 'Write', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await newAccess.save(); + + const response = await request(app).get(`/api/documentAccessRoutes/document-accesses/${savedAccess._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.accessId).toBe('another-unique-access-id'); + }); + + it('should update a document access by ID', async () => { + const newAccess = new DocumentAccessModel({ + accessId: 'update-access-id', + AccessLevel: 'Admin', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await newAccess.save(); + + const response = await request(app) + .put(`/api/documentAccessRoutes/document-accesses/${savedAccess._id}`) + .send({ AccessLevel: 'Read' }); + + expect(response.statusCode).toBe(200); + expect(response.body.AccessLevel).toBe('Read'); + }); + + it('should delete a document access by ID', async () => { + const newAccess = new DocumentAccessModel({ + accessId: 'delete-access-id', + AccessLevel: 'Admin', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await newAccess.save(); + + const response = await request(app).delete(`/api/documentAccessRoutes/document-accesses/${savedAccess._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Document access deleted'); + }); +}); diff --git a/__tests__/documentAccessModel.test.js b/__tests__/documentAccessModel.test.js new file mode 100644 index 0000000..6dd996a --- /dev/null +++ b/__tests__/documentAccessModel.test.js @@ -0,0 +1,29 @@ +const mongoose = require('mongoose'); +const DocumentAccessModel = require('../models/DocumentAccessModel'); + +beforeAll(async () => { + await mongoose.connect('mongodb://localhost:27017/testDB', { useNewUrlParser: true, useUnifiedTopology: true }); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('DocumentAccess Model', () => { + it('should create a document access', async () => { + const access = new DocumentAccessModel({ + accessId: 'unique-access-id', + AccessLevel: 'Read', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await access.save(); + expect(savedAccess.accessId).toBe('unique-access-id'); + }); + + it('should fail without required fields', async () => { + const access = new DocumentAccessModel({}); + await expect(access.save()).rejects.toThrow(); + }); +}); diff --git a/__tests__/documentAccessRoutes.test.js b/__tests__/documentAccessRoutes.test.js new file mode 100644 index 0000000..4ef31e1 --- /dev/null +++ b/__tests__/documentAccessRoutes.test.js @@ -0,0 +1,84 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const DocumentAccessModel = require('../models/DocumentAccessModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api/documentAccessRoutes', require('../routes/documentAccessRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Document Access Routes', () => { + it('should create a new document access', async () => { + const response = await request(app) + .post('/api/documentAccessRoutes/document-accesses') + .send({ + accessId: 'route-access-id', + AccessLevel: 'Write', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + expect(response.statusCode).toBe(201); + expect(response.body.accessId).toBe('route-access-id'); + }); + + it('should get all document accesses', async () => { + const response = await request(app).get('/api/documentAccessRoutes/document-accesses'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a document access by ID', async () => { + const newAccess = new DocumentAccessModel({ + accessId: 'route-get-access-id', + AccessLevel: 'Admin', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await newAccess.save(); + + const response = await request(app).get(`/api/documentAccessRoutes/document-accesses/${savedAccess._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.accessId).toBe('route-get-access-id'); + }); + + it('should update a document access by ID', async () => { + const newAccess = new DocumentAccessModel({ + accessId: 'route-update-access-id', + AccessLevel: 'Read', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await newAccess.save(); + + const response = await request(app) + .put(`/api/documentAccessRoutes/document-accesses/${savedAccess._id}`) + .send({ AccessLevel: 'Write' }); + + expect(response.statusCode).toBe(200); + expect(response.body.AccessLevel).toBe('Write'); + }); + + it('should delete a document access by ID', async () => { + const newAccess = new DocumentAccessModel({ + accessId: 'route-delete-access-id', + AccessLevel: 'Admin', + RelatedDocument: mongoose.Types.ObjectId(), + User: mongoose.Types.ObjectId(), + }); + const savedAccess = await newAccess.save(); + + const response = await request(app).delete(`/api/documentAccessRoutes/document-accesses/${savedAccess._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Document access deleted'); + }); +}); diff --git a/__tests__/documentController.test.js b/__tests__/documentController.test.js new file mode 100644 index 0000000..31704ed --- /dev/null +++ b/__tests__/documentController.test.js @@ -0,0 +1,101 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const Document = require('../models/documentModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api', require('../routes/documentRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Document Controller', () => { + it('should create a new document', async () => { + const response = await request(app) + .post('/api/documents') + .send({ + documentId: 'doc123', + name: 'Sample Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/document', + title: 'Sample Title', + content: 'Sample Content', + DocumentType: 'Legal', + FileType: 'PDF', + Versioning: '1.0' + }); + expect(response.statusCode).toBe(201); + expect(response.body.name).toBe('Sample Document'); + }); + + it('should get all documents', async () => { + const response = await request(app).get('/api/documents'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a document by ID', async () => { + const newDocument = new Document({ + documentId: 'doc124', + name: 'Another Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/another/document', + title: 'Another Title', + content: 'Another Content', + DocumentType: 'Financial', + FileType: 'DOCX' + }); + const savedDocument = await newDocument.save(); + + const response = await request(app).get(`/api/documents/${savedDocument._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.name).toBe('Another Document'); + }); + + it('should update a document by ID', async () => { + const newDocument = new Document({ + documentId: 'doc125', + name: 'Update Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/update/document', + title: 'Update Title', + content: 'Update Content', + DocumentType: 'Legal', + FileType: 'PDF' + }); + const savedDocument = await newDocument.save(); + + const response = await request(app) + .put(`/api/documents/${savedDocument._id}`) + .send({ name: 'Updated Document' }); + + expect(response.statusCode).toBe(200); + expect(response.body.name).toBe('Updated Document'); + }); + + it('should delete a document by ID', async () => { + const newDocument = new Document({ + documentId: 'doc126', + name: 'Delete Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/delete/document', + title: 'Delete Title', + content: 'Delete Content', + DocumentType: 'Other', + FileType: 'TXT' + }); + const savedDocument = await newDocument.save(); + + const response = await request(app).delete(`/api/documents/${savedDocument._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Document deleted'); + }); +}); diff --git a/__tests__/documentEmbeddingController.test.js b/__tests__/documentEmbeddingController.test.js new file mode 100644 index 0000000..d64a323 --- /dev/null +++ b/__tests__/documentEmbeddingController.test.js @@ -0,0 +1,94 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const DocumentEmbedding = require('../models/DocumentEmbeddingModel'); +const { connectDB, disconnectDB } = require('../db'); + + +const app = express(); +app.use(express.json()); +app.use('/api/documentEmbeddings', require('../routes/documentEmbeddingRoutes')); + +describe('Document Embedding Controller', () => { + let documentId; + + beforeAll(async () => { + await connectDB(); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + beforeEach(() => { + documentId = new mongoose.Types.ObjectId(); // Mock a document ID for testing + }); + + it('should create a new document embedding', async () => { + const response = await request(app) + .post('/api/documentEmbeddings/document-embeddings') + .send({ + embeddingId: 'emb12345', + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + EmbeddingVersion: 'v1', + }); + expect(response.statusCode).toBe(201); + expect(response.body.embeddingId).toBe('emb12345'); + expect(response.body.documentId).toBe(documentId.toString()); + }); + + it('should get all document embeddings', async () => { + const response = await request(app).get('/api/documentEmbeddings/document-embeddings'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a document embedding by ID', async () => { + const newEmbedding = new DocumentEmbedding({ + embeddingId: 'emb12345', + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await newEmbedding.save(); + + const response = await request(app).get(`/api/documentEmbeddings/document-embeddings/${savedEmbedding._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.embeddingId).toBe('emb12345'); + }); + + it('should update a document embedding by ID', async () => { + const newEmbedding = new DocumentEmbedding({ + embeddingId: 'emb12345', + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await newEmbedding.save(); + + const response = await request(app) + .put(`/api/documentEmbeddings/document-embeddings/${savedEmbedding._id}`) + .send({ embedding: [0.5, 0.4, 0.3, 0.2, 0.1], EmbeddingVersion: 'v2' }); + + expect(response.statusCode).toBe(200); + expect(response.body.embedding).toEqual([0.5, 0.4, 0.3, 0.2, 0.1]); + expect(response.body.EmbeddingVersion).toBe('v2'); + }); + + it('should delete a document embedding by ID', async () => { + const newEmbedding = new DocumentEmbedding({ + embeddingId: 'emb12345', + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await newEmbedding.save(); + + const response = await request(app).delete(`/api/documentEmbeddings/document-embeddings/${savedEmbedding._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Document embedding deleted'); + }); +}); diff --git a/__tests__/documentEmbeddingModel.test.js b/__tests__/documentEmbeddingModel.test.js new file mode 100644 index 0000000..5c4e638 --- /dev/null +++ b/__tests__/documentEmbeddingModel.test.js @@ -0,0 +1,80 @@ +const mongoose = require('mongoose'); +const DocumentEmbedding = require('../models/DocumentEmbeddingModel'); +const { connectDB, disconnectDB } = require('../db'); + +mongoose.set('debug', true); + + +describe('DocumentEmbedding Model Test', () => { + + beforeAll(async () => { + await connectDB(); + await DocumentEmbedding.createIndexes(); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + it('create & save document embedding successfully', async () => { + const validEmbedding = new DocumentEmbedding({ + embeddingId: 'uniqueEmb123', + documentId: new mongoose.Types.ObjectId(), + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await validEmbedding.save(); + + expect(savedEmbedding._id).toBeDefined(); + expect(savedEmbedding.embeddingId).toBe('uniqueEmb123'); + }); + + it('should fail to create a document embedding without required fields', async () => { + const incompleteEmbedding = new DocumentEmbedding({}); // Missing all required fields + + let err; + try { + await incompleteEmbedding.save(); + } catch (error) { + err = error; + } + + expect(err).toBeInstanceOf(mongoose.Error.ValidationError); + expect(err.errors).toHaveProperty('documentId'); + expect(err.errors).toHaveProperty('embeddingId'); + expect(err.errors).toHaveProperty('EmbeddingType'); + expect(err.errors).toHaveProperty('embedding'); // This should now be present + }); + + it('should enforce unique embeddingId', async () => { + const embedding1 = new DocumentEmbedding({ + embeddingId: 'duplicateEmb123', + documentId: new mongoose.Types.ObjectId(), + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + await embedding1.save(); + + const embedding2 = new DocumentEmbedding({ + embeddingId: 'duplicateEmb123', // Duplicate ID to test uniqueness + documentId: new mongoose.Types.ObjectId(), + embedding: [0.6, 0.7, 0.8, 0.9, 1.0], + EmbeddingType: 'Type2', + }); + + let err; + try { + await embedding2.save(); + } catch (error) { + err = error; + } + + expect(err).toBeDefined(); + expect(err.name).toBe('MongoError'); // Updated to check for 'MongoError' + expect(err.code).toBe(11000); // Duplicate key error code + }); + + + +}); diff --git a/__tests__/documentEmbeddingRoutes.test.js b/__tests__/documentEmbeddingRoutes.test.js new file mode 100644 index 0000000..671908d --- /dev/null +++ b/__tests__/documentEmbeddingRoutes.test.js @@ -0,0 +1,94 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const DocumentEmbedding = require('../models/DocumentEmbeddingModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api/documentEmbeddings', require('../routes/documentEmbeddingRoutes')); + +describe('Document Embedding API', () => { + let documentId; + + beforeAll(async () => { + await connectDB(); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + beforeEach(() => { + documentId = new mongoose.Types.ObjectId(); // Mock a document ID for testing + }); + + it('should create a new document embedding', async () => { + const response = await request(app) + .post('/api/documentEmbeddings/document-embeddings') + .send({ + embeddingId: 'emb' + new Date().getTime(), // Unique embeddingId + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + EmbeddingVersion: 'v1', + }); + expect(response.statusCode).toBe(201); + expect(response.body.documentId).toBe(documentId.toString()); + expect(response.body.embedding).toEqual([0.1, 0.2, 0.3, 0.4, 0.5]); + }); + + it('should get all document embeddings', async () => { + const response = await request(app).get('/api/documentEmbeddings/document-embeddings'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a document embedding by ID', async () => { + const newEmbedding = new DocumentEmbedding({ + embeddingId: 'emb' + new Date().getTime(), // Unique embeddingId + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await newEmbedding.save(); + + const response = await request(app).get(`/api/documentEmbeddings/document-embeddings/${savedEmbedding._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.documentId).toBe(documentId.toString()); + expect(response.body.embeddingId).toBe(newEmbedding.embeddingId); + }); + + it('should update a document embedding by ID', async () => { + const newEmbedding = new DocumentEmbedding({ + embeddingId: 'emb' + new Date().getTime(), // Unique embeddingId + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await newEmbedding.save(); + + const response = await request(app) + .put(`/api/documentEmbeddings/document-embeddings/${savedEmbedding._id}`) + .send({ embedding: [0.5, 0.4, 0.3, 0.2, 0.1], EmbeddingVersion: 'v2' }); + + expect(response.statusCode).toBe(200); + expect(response.body.embedding).toEqual([0.5, 0.4, 0.3, 0.2, 0.1]); + expect(response.body.EmbeddingVersion).toBe('v2'); + }); + + it('should delete a document embedding by ID', async () => { + const newEmbedding = new DocumentEmbedding({ + embeddingId: 'emb' + new Date().getTime(), // Unique embeddingId + documentId, + embedding: [0.1, 0.2, 0.3, 0.4, 0.5], + EmbeddingType: 'Type1', + }); + const savedEmbedding = await newEmbedding.save(); + + const response = await request(app).delete(`/api/documentEmbeddings/document-embeddings/${savedEmbedding._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Document embedding deleted'); + }); +}); diff --git a/__tests__/documentModel.test.js b/__tests__/documentModel.test.js new file mode 100644 index 0000000..5f1946c --- /dev/null +++ b/__tests__/documentModel.test.js @@ -0,0 +1,89 @@ +const mongoose = require('mongoose'); +const Document = require('../models/documentModel'); +const { connectDB, disconnectDB } = require('../db'); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Document Model', () => { + it('should create a new document', async () => { + const document = new Document({ + documentId: 'doc001', + name: 'Test Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/test/path', + title: 'Test Title', + content: 'Test Content', + DocumentType: 'Legal', + FileType: 'PDF', + Versioning: '1.0' + }); + + const savedDocument = await document.save(); + expect(savedDocument._id).toBeDefined(); + expect(savedDocument.name).toBe('Test Document'); + }); + + it('should retrieve a document by ID', async () => { + const document = new Document({ + documentId: 'doc002', + name: 'Retrieve Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/test/retrieve', + title: 'Retrieve Title', + content: 'Retrieve Content', + DocumentType: 'Financial', + FileType: 'DOCX' + }); + + const savedDocument = await document.save(); + const foundDocument = await Document.findById(savedDocument._id); + + expect(foundDocument).toBeDefined(); + expect(foundDocument.name).toBe('Retrieve Document'); + }); + + it('should update a document by ID', async () => { + const document = new Document({ + documentId: 'doc003', + name: 'Update Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/test/update', + title: 'Update Title', + content: 'Update Content', + DocumentType: 'Legal', + FileType: 'PDF' + }); + + const savedDocument = await document.save(); + savedDocument.name = 'Updated Document'; + const updatedDocument = await savedDocument.save(); + + expect(updatedDocument.name).toBe('Updated Document'); + }); + + it('should delete a document by ID', async () => { + const document = new Document({ + documentId: 'doc004', + name: 'Delete Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/test/delete', + title: 'Delete Title', + content: 'Delete Content', + DocumentType: 'Other', + FileType: 'TXT' + }); + + const savedDocument = await document.save(); + await Document.findByIdAndDelete(savedDocument._id); + + const deletedDocument = await Document.findById(savedDocument._id); + expect(deletedDocument).toBeNull(); + }); +}); diff --git a/__tests__/documentRoutes.test.js b/__tests__/documentRoutes.test.js new file mode 100644 index 0000000..c9b7771 --- /dev/null +++ b/__tests__/documentRoutes.test.js @@ -0,0 +1,101 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const Document = require('../models/documentModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api', require('../routes/documentRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Document Routes', () => { + it('should create a new document', async () => { + const response = await request(app) + .post('/api/documents') + .send({ + documentId: 'doc123', + name: 'Sample Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/document', + title: 'Sample Title', + content: 'Sample Content', + DocumentType: 'Legal', + FileType: 'PDF', + Versioning: '1.0' + }); + expect(response.statusCode).toBe(201); + expect(response.body.name).toBe('Sample Document'); + }); + + it('should get all documents', async () => { + const response = await request(app).get('/api/documents'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a document by ID', async () => { + const newDocument = new Document({ + documentId: 'doc124', + name: 'Another Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/another/document', + title: 'Another Title', + content: 'Another Content', + DocumentType: 'Financial', + FileType: 'DOCX' + }); + const savedDocument = await newDocument.save(); + + const response = await request(app).get(`/api/documents/${savedDocument._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.name).toBe('Another Document'); + }); + + it('should update a document by ID', async () => { + const newDocument = new Document({ + documentId: 'doc125', + name: 'Update Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/update/document', + title: 'Update Title', + content: 'Update Content', + DocumentType: 'Legal', + FileType: 'PDF' + }); + const savedDocument = await newDocument.save(); + + const response = await request(app) + .put(`/api/documents/${savedDocument._id}`) + .send({ name: 'Updated Document' }); + + expect(response.statusCode).toBe(200); + expect(response.body.name).toBe('Updated Document'); + }); + + it('should delete a document by ID', async () => { + const newDocument = new Document({ + documentId: 'doc126', + name: 'Delete Document', + uploadedBy: new mongoose.Types.ObjectId(), // Use valid ObjectId + path: '/path/to/delete/document', + title: 'Delete Title', + content: 'Delete Content', + DocumentType: 'Other', + FileType: 'TXT' + }); + const savedDocument = await newDocument.save(); + + const response = await request(app).delete(`/api/documents/${savedDocument._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Document deleted'); + }); +}); diff --git a/__tests__/employee.model.test.js b/__tests__/employee.model.test.js new file mode 100644 index 0000000..c9f8da3 --- /dev/null +++ b/__tests__/employee.model.test.js @@ -0,0 +1,47 @@ +const mongoose = require("mongoose"); +const chai = require("chai"); +const Employee = require("../models/employeeModel"); +const should = chai.should(); +const { connectDB, disconnectDB } = require('../db'); + + +describe("Employee Model", () => { + beforeAll(async function () { + await connectDB(); + }); + + afterAll(async function () { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + it("should create a new employee", (done) => { + const employee = new Employee({ + EmployeeID: "E12345", + Name: "John Doe", + Email: "john.doe@example.com", + EquityOverview: { + TotalEquity: 1000, + VestedEquity: 500, + UnvestedEquity: 500, + }, + DocumentAccess: [], + VestingSchedule: { + StartDate: new Date(), + CliffDate: new Date(), + VestingPeriod: 12, + TotalEquity: 1000, + }, + TaxCalculator: { + TaxBracket: 30, + TaxLiability: 300, + }, + }); + employee.save((err, savedEmployee) => { + should.not.exist(err); + savedEmployee.should.be.an("object"); + savedEmployee.should.have.property("Name").eql("John Doe"); + done(); + }); + }); +}); diff --git a/__tests__/employeeController.test.js b/__tests__/employeeController.test.js new file mode 100644 index 0000000..08e8dd1 --- /dev/null +++ b/__tests__/employeeController.test.js @@ -0,0 +1,57 @@ +const request = require('supertest'); +const chai = require('chai'); +const server = require('../app'); +const { connectDB, disconnectDB } = require('../db'); +const mongoose = require('mongoose'); +const Employee = require('../models/employeeModel'); +const expect = chai.expect; + +describe('Employee Controller', () => { + beforeAll(async () => { + console.log('Connecting to DB...'); + await connectDB(); + }); + + afterAll(async () => { + console.log('Dropping database and disconnecting...'); + await mongoose.connection.db.dropDatabase(); + await disconnectDB(); + }); + + describe('/POST employee', () => { + it('should create a new employee', async () => { + const employee = { + EmployeeID: 'E12345', + Name: 'John Doe', + Email: 'john.doe@example.com', + EquityOverview: { + TotalEquity: 1000, + VestedEquity: 500, + UnvestedEquity: 500, + }, + DocumentAccess: [], + VestingSchedule: { + StartDate: new Date(), + CliffDate: new Date(), + VestingPeriod: 12, + TotalEquity: 1000, + }, + TaxCalculator: { + TaxBracket: 30, + TaxLiability: 300, + }, + }; + + const response = await request(server) + .post('/api/employees') // Updated route to include /api + .send(employee); + + console.log('Response Status:', response.statusCode); + console.log('Response Body:', response.body); + + expect(response.statusCode).to.equal(201); + expect(response.body).to.be.an('object'); + expect(response.body).to.have.property('Name').that.equals('John Doe'); + }); + }); +}); diff --git a/__tests__/employeeRoute.test.js b/__tests__/employeeRoute.test.js new file mode 100644 index 0000000..4746f16 --- /dev/null +++ b/__tests__/employeeRoute.test.js @@ -0,0 +1,62 @@ +// test/employeeRoute.test.js +const request = require('supertest'); +const mongoose = require('mongoose'); +const app = require('../app'); // Ensure this points to your Express app +const Employee = require('../models/employeeModel'); + +beforeAll(async () => { + await mongoose.connect("mongodb://localhost:27017/testDB", { + useNewUrlParser: true, + useUnifiedTopology: true, + }); +}); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe("Employee Routes", () => { + beforeEach(async () => { + await Employee.deleteMany({}); + }); + + describe("GET /api/employees", () => { + it("it should GET all the employees", async () => { + const response = await request(app).get("/api/employees"); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + expect(response.body.length).toBe(0); + }); + }); + + describe("POST /api/employees", () => { + it("it should POST a new employee", async () => { + const employee = { + EmployeeID: "E12345", + Name: "John Doe", + Email: "john.doe@example.com", + EquityOverview: { + TotalEquity: 1000, + VestedEquity: 500, + UnvestedEquity: 500, + }, + DocumentAccess: [], + VestingSchedule: { + StartDate: new Date(), + CliffDate: new Date(), + VestingPeriod: 12, + TotalEquity: 1000, + }, + TaxCalculator: { + TaxBracket: 30, + TaxLiability: 300, + }, + }; + const response = await request(app) + .post("/api/employees") + .send(employee); + expect(response.statusCode).toBe(201); + expect(response.body).toHaveProperty("Name", "John Doe"); + }); + }); +}); diff --git a/__tests__/equityPlanController.test.js b/__tests__/equityPlanController.test.js new file mode 100644 index 0000000..4481052 --- /dev/null +++ b/__tests__/equityPlanController.test.js @@ -0,0 +1,97 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const EquityPlan = require('../models/EquityPlanModel'); +const app = express(); + +const { connectDB, disconnectDB } = require('../db'); + +app.use(express.json()); +app.use('/api/equityPlanRoutes', require('../routes/equityPlanRoutes')); + +beforeAll(async () => { + await connectDB(); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + +describe('Equity Plan API', () => { + it('should create a new equity plan', async () => { + const response = await request(app) + .post('/api/equityPlanRoutes/equity-plans') + .send({ + planId: '1234', + planName: 'Employee Stock Option Plan', + description: 'An equity plan for employees', + startDate: '2024-07-01', + allocation: 100000, + participants: ['Participant A', 'Participant B'], + PlanType: 'Stock Option Plan' + }); + expect(response.statusCode).toBe(201); + expect(response.body.planName).toBe('Employee Stock Option Plan'); + }); + + it('should get all equity plans', async () => { + const response = await request(app).get('/api/equityPlanRoutes/equity-plans'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get an equity plan by ID', async () => { + const newPlan = new EquityPlan({ + planId: '5678', + planName: 'Executive Stock Option Plan', + description: 'An equity plan for executives', + startDate: '2024-08-01', + allocation: 50000, + participants: ['Participant C'], + PlanType: 'Stock Option Plan' + }); + const savedPlan = await newPlan.save(); + + const response = await request(app).get(`/api/equityPlanRoutes/equity-plans/${savedPlan._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.planName).toBe('Executive Stock Option Plan'); + }); + + it('should update an equity plan by ID', async () => { + const newPlan = new EquityPlan({ + planId: '91011', + planName: 'Manager Stock Option Plan', + description: 'An equity plan for managers', + startDate: '2024-09-01', + allocation: 75000, + participants: ['Participant D'], + PlanType: 'Stock Option Plan' + }); + const savedPlan = await newPlan.save(); + + const response = await request(app) + .put(`/api/equityPlanRoutes/equity-plans/${savedPlan._id}`) + .send({ allocation: 80000 }); + + expect(response.statusCode).toBe(200); + expect(response.body.allocation).toBe(80000); + }); + + it('should delete an equity plan by ID', async () => { + const newPlan = new EquityPlan({ + planId: '121314', + planName: 'Leadership Stock Option Plan', + description: 'An equity plan for leadership team', + startDate: '2024-10-01', + allocation: 120000, + participants: ['Participant E'], + PlanType: 'Stock Option Plan' + }); + const savedPlan = await newPlan.save(); + + const response = await request(app).delete(`/api/equityPlanRoutes/equity-plans/${savedPlan._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Equity plan deleted'); + }); +}); diff --git a/__tests__/equityPlanModel.test.js b/__tests__/equityPlanModel.test.js new file mode 100644 index 0000000..bf7c8ed --- /dev/null +++ b/__tests__/equityPlanModel.test.js @@ -0,0 +1,36 @@ +const mongoose = require('mongoose'); +const EquityPlan = require('../models/EquityPlanModel'); +const { connectDB, disconnectDB } = require('../db'); + +beforeAll(async () => { + await connectDB(); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + +describe('EquityPlan Model', () => { + it('should create a new equity plan', async () => { + const plan = new EquityPlan({ + planId: '9999', + planName: 'Test Equity Plan', + startDate: new Date(), + allocation: 50000, + PlanType: 'Restricted Stock Plan' + }); + const savedPlan = await plan.save(); + expect(savedPlan.planName).toBe('Test Equity Plan'); + expect(savedPlan.planId).toBe('9999'); + }); + + it('should not create a plan without required fields', async () => { + const plan = new EquityPlan({ + planName: 'Invalid Plan', + allocation: 20000 + }); + + await expect(plan.save()).rejects.toThrow(); + }); +}); diff --git a/__tests__/equityPlanRoutes.test.js b/__tests__/equityPlanRoutes.test.js new file mode 100644 index 0000000..d3ca6d2 --- /dev/null +++ b/__tests__/equityPlanRoutes.test.js @@ -0,0 +1,96 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const EquityPlan = require('../models/EquityPlanModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api/equityPlanRoutes', require('../routes/equityPlanRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Equity Plan API', () => { + it('should create a new equity plan', async () => { + const response = await request(app) + .post('/api/equityPlanRoutes/equity-plans') + .send({ + planId: 'unique-plan-id-1', + planName: 'Employee Stock Option Plan', + description: 'An equity plan for employees', + startDate: '2024-07-01', + allocation: 100000, + participants: ['Participant A', 'Participant B'], + PlanType: 'Stock Option Plan' // Ensure this field is included + }); + expect(response.statusCode).toBe(201); + expect(response.body.planName).toBe('Employee Stock Option Plan'); + }); + + it('should get all equity plans', async () => { + const response = await request(app).get('/api/equityPlanRoutes/equity-plans'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get an equity plan by ID', async () => { + const newPlan = new EquityPlan({ + planId: 'unique-plan-id-2', + planName: 'Executive Stock Option Plan', + description: 'An equity plan for executives', + startDate: '2024-08-01', + allocation: 50000, + participants: ['Participant C'], + PlanType: 'Stock Option Plan' // Ensure this field is included + }); + const savedPlan = await newPlan.save(); + + const response = await request(app).get(`/api/equityPlanRoutes/equity-plans/${savedPlan._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.planName).toBe('Executive Stock Option Plan'); + }); + + it('should update an equity plan by ID', async () => { + const newPlan = new EquityPlan({ + planId: 'unique-plan-id-3', + planName: 'Manager Stock Option Plan', + description: 'An equity plan for managers', + startDate: '2024-09-01', + allocation: 75000, + participants: ['Participant D'], + PlanType: 'Stock Option Plan' // Ensure this field is included + }); + const savedPlan = await newPlan.save(); + + const response = await request(app) + .put(`/api/equityPlanRoutes/equity-plans/${savedPlan._id}`) + .send({ allocation: 80000 }); + + expect(response.statusCode).toBe(200); + expect(response.body.allocation).toBe(80000); + }); + + it('should delete an equity plan by ID', async () => { + const newPlan = new EquityPlan({ + planId: 'unique-plan-id-4', + planName: 'Leadership Stock Option Plan', + description: 'An equity plan for leadership team', + startDate: '2024-10-01', + allocation: 120000, + participants: ['Participant E'], + PlanType: 'Stock Option Plan' // Ensure this field is included + }); + const savedPlan = await newPlan.save(); + + const response = await request(app).delete(`/api/equityPlanRoutes/equity-plans/${savedPlan._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Equity plan deleted'); + }); +}); diff --git a/__tests__/financialReportingController.test.js b/__tests__/financialReportingController.test.js new file mode 100644 index 0000000..168db29 --- /dev/null +++ b/__tests__/financialReportingController.test.js @@ -0,0 +1,51 @@ +const { createFinancialReport } = require('../controllers/financialReportingController'); +const FinancialReport = require('../models/financialReport'); + +const httpMocks = require('node-mocks-http'); +const mongoose = require('mongoose'); + +// Mock the FinancialReport model +jest.mock('../models/financialReport'); + +describe('createFinancialReport Controller', () => { + let req, res, next; + + beforeEach(() => { + req = httpMocks.createRequest(); + res = httpMocks.createResponse(); + next = jest.fn(); + }); + + it('should create a new financial report and return 201 status', async () => { + // Mock request body + req.body = { + ReportID: 'test-id', + Type: 'test-type', + Data: 'test-data', + Timestamp: new Date(), + }; + + // Mock the save function + FinancialReport.prototype.save = jest.fn().mockResolvedValue(req.body); + + await createFinancialReport(req, res, next); + + // Assertions + expect(FinancialReport).toHaveBeenCalledWith(req.body); + expect(FinancialReport.prototype.save).toHaveBeenCalled(); + expect(res.statusCode).toBe(201); + expect(res._getJSONData()).toEqual(req.body); + expect(next).not.toHaveBeenCalled(); + }); + + it('should handle errors and pass them to the error handling middleware', async () => { + const errorMessage = 'Failed to create financial report'; + const rejectedPromise = Promise.reject(new Error(errorMessage)); + FinancialReport.prototype.save = jest.fn().mockReturnValue(rejectedPromise); + + await createFinancialReport(req, res, next); + + expect(FinancialReport.prototype.save).toHaveBeenCalled(); + expect(next).toHaveBeenCalledWith(expect.objectContaining({ message: errorMessage })); + }); +}); diff --git a/__tests__/fundraisingRoundController.test.js b/__tests__/fundraisingRoundController.test.js new file mode 100644 index 0000000..1549bc0 --- /dev/null +++ b/__tests__/fundraisingRoundController.test.js @@ -0,0 +1,108 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const FundraisingRound = require('../models/FundraisingRoundModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api/fundraisingRoutes', require('../routes/fundraisingRoundRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Fundraising Round API', () => { + it('should create a new fundraising round', async () => { + const response = await request(app) + .post('/api/fundraisingRoutes/fundraising-rounds') + .send({ + roundId: 'round-002', + roundName: 'Series B', + amountRaised: 2000000, + date: '2024-08-01', + investors: ['Investor C'], + equityGiven: 25, + RoundType: 'Series A', + TermsOfInvestment: 'Preferred terms', + ShareClassesInvolved: ['Preferred'], + LegalDocuments: ['doc3.pdf'] + }); + expect(response.statusCode).toBe(201); + expect(response.body.roundName).toBe('Series B'); + }); + + it('should get all fundraising rounds', async () => { + const response = await request(app).get('/api/fundraisingRoutes/fundraising-rounds'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a fundraising round by ID', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-003', + roundName: 'Series C', + amountRaised: 3000000, + date: '2024-09-01', + investors: ['Investor D'], + equityGiven: 30, + RoundType: 'Series B', + TermsOfInvestment: 'Convertible notes', + ShareClassesInvolved: ['Common'], + LegalDocuments: ['doc4.pdf'] + }); + const savedRound = await newRound.save(); + + const response = await request(app).get(`/api/fundraisingRoutes/fundraising-rounds/${savedRound._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.roundName).toBe('Series C'); + }); + + it('should update a fundraising round by ID', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-004', + roundName: 'Series D', + amountRaised: 4000000, + date: '2024-10-01', + investors: ['Investor E'], + equityGiven: 35, + RoundType: 'Series C', + TermsOfInvestment: 'Equity', + ShareClassesInvolved: ['Preferred'], + LegalDocuments: ['doc5.pdf'] + }); + const savedRound = await newRound.save(); + + const response = await request(app) + .put(`/api/fundraisingRoutes/fundraising-rounds/${savedRound._id}`) + .send({ amountRaised: 4500000 }); + + expect(response.statusCode).toBe(200); + expect(response.body.amountRaised).toBe(4500000); + }); + + it('should delete a fundraising round by ID', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-005', + roundName: 'Series E', + amountRaised: 5000000, + date: '2024-11-01', + investors: ['Investor F'], + equityGiven: 40, + RoundType: 'Series D', + TermsOfInvestment: 'Standard', + ShareClassesInvolved: ['Common'], + LegalDocuments: ['doc6.pdf'] + }); + const savedRound = await newRound.save(); + + const response = await request(app).delete(`/api/fundraisingRoutes/fundraising-rounds/${savedRound._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Fundraising round deleted'); + }); +}); diff --git a/__tests__/fundraisingRoundModel.test.js b/__tests__/fundraisingRoundModel.test.js new file mode 100644 index 0000000..3b8baac --- /dev/null +++ b/__tests__/fundraisingRoundModel.test.js @@ -0,0 +1,49 @@ +const mongoose = require('mongoose'); +const FundraisingRound = require('../models/FundraisingRoundModel'); +const { connectDB, disconnectDB } = require('../db'); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Fundraising Round Model', () => { + it('should create and save a fundraising round successfully', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-001', + roundName: 'Series A', + amountRaised: 1000000, + date: new Date('2024-07-01'), + investors: ['Investor A', 'Investor B'], + equityGiven: 20, + RoundType: 'Seed', + TermsOfInvestment: 'Standard terms', + ShareClassesInvolved: ['Common', 'Preferred'], + LegalDocuments: ['doc1.pdf', 'doc2.pdf'] + }); + + const savedRound = await newRound.save(); + expect(savedRound._id).toBeDefined(); + expect(savedRound.roundName).toBe('Series A'); + }); + + it('should fail to create a fundraising round without required fields', async () => { + const newRound = new FundraisingRound({ + roundName: 'Series B', + amountRaised: 2000000, + // Missing required fields + }); + + let error; + try { + await newRound.save(); + } catch (e) { + error = e; + } + expect(error).toBeDefined(); + }); +}); diff --git a/__tests__/fundraisingRoundRoutes.test.js b/__tests__/fundraisingRoundRoutes.test.js new file mode 100644 index 0000000..f460920 --- /dev/null +++ b/__tests__/fundraisingRoundRoutes.test.js @@ -0,0 +1,97 @@ +// test/fundraisingRoutes.test.js +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const FundraisingRound = require('../models/FundraisingRoundModel'); +const { connectDB, disconnectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/api/fundraisingRoutes', require('../routes/fundraisingRoundRoutes')); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Fundraising API', () => { + it('should create a new fundraising round', async () => { + const response = await request(app) + .post('/api/fundraisingRoutes/fundraising-rounds') + .send({ + roundId: 'round-001', + roundName: 'Series A', + amountRaised: 1000000, + date: '2024-07-01', + investors: ['Investor A', 'Investor B'], + equityGiven: 20, + RoundType: 'Series A' + }); + expect(response.statusCode).toBe(201); + expect(response.body.roundName).toBe('Series A'); + }); + + it('should get all fundraising rounds', async () => { + const response = await request(app).get('/api/fundraisingRoutes/fundraising-rounds'); + expect(response.statusCode).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); + + it('should get a fundraising round by ID', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-002', + roundName: 'Series B', + amountRaised: 2000000, + date: '2024-08-01', + investors: ['Investor C'], + equityGiven: 25, + RoundType: 'Series B' + }); + const savedRound = await newRound.save(); + + const response = await request(app).get(`/api/fundraisingRoutes/fundraising-rounds/${savedRound._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.roundName).toBe('Series B'); + }); + + it('should update a fundraising round by ID', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-003', + roundName: 'Series C', + amountRaised: 3000000, + date: '2024-09-01', + investors: ['Investor D'], + equityGiven: 30, + RoundType: 'Series C' + }); + const savedRound = await newRound.save(); + + const response = await request(app) + .put(`/api/fundraisingRoutes/fundraising-rounds/${savedRound._id}`) + .send({ amountRaised: 3500000 }); + + expect(response.statusCode).toBe(200); + expect(response.body.amountRaised).toBe(3500000); + }); + + it('should delete a fundraising round by ID', async () => { + const newRound = new FundraisingRound({ + roundId: 'round-004', + roundName: 'Series D', + amountRaised: 4000000, + date: '2024-10-01', + investors: ['Investor E'], + equityGiven: 35, + RoundType: 'Series D' + }); + const savedRound = await newRound.save(); + + const response = await request(app).delete(`/api/fundraisingRoutes/fundraising-rounds/${savedRound._id}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Fundraising round deleted'); + }); +}); diff --git a/__tests__/globalSetup.js b/__tests__/globalSetup.js new file mode 100644 index 0000000..61917c8 --- /dev/null +++ b/__tests__/globalSetup.js @@ -0,0 +1,59 @@ +require('dotenv').config(); // Load the .env file +const mongoose = require("mongoose"); +const { Client } = require('pg'); + +module.exports = async () => { + // Set up MongoDB + const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/opencap_test'; // Fallback to hardcoded URI + if (!mongoUri) { + throw new Error('MongoDB URI is not defined.'); + } + + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + + // Drop the MongoDB database to clean up before tests + await mongoose.connection.dropDatabase(); + + // Set up PostgreSQL for metadata management + const pgClient = new Client({ + user: process.env.PG_USER || 'lakehouse_user', + host: process.env.PG_HOST || 'localhost', + database: process.env.PG_DATABASE || 'lakehouse_metadata', + password: process.env.PG_PASSWORD || 'password', + port: process.env.PG_PORT || 5432, + }); + + try { + await pgClient.connect(); + console.log('Connected to PostgreSQL database.'); + + // Clean up PostgreSQL data before tests (if necessary) + await pgClient.query('TRUNCATE TABLE datasets, dataset_schema, ingestion_logs RESTART IDENTITY CASCADE;'); + console.log('PostgreSQL tables truncated.'); + + } catch (error) { + console.error('Error connecting to PostgreSQL:', error); + throw new Error('PostgreSQL connection failed.'); + } finally { + await pgClient.end(); + } + + // Set up MinIO client (mock or real) + process.env.MINIO_ENDPOINT = process.env.MINIO_ENDPOINT || 'localhost'; + process.env.MINIO_PORT = process.env.MINIO_PORT || '9000'; + process.env.MINIO_ACCESS_KEY = process.env.MINIO_ACCESS_KEY || 'your-access-key'; + process.env.MINIO_SECRET_KEY = process.env.MINIO_SECRET_KEY || 'your-secret-key'; + console.log('MinIO environment variables set.'); + + // Set up Airflow (mock or real) + process.env.AIRFLOW_BASE_URL = process.env.AIRFLOW_BASE_URL || 'http://localhost:8080'; + process.env.AIRFLOW_USERNAME = process.env.AIRFLOW_USERNAME || 'admin'; + process.env.AIRFLOW_PASSWORD = process.env.AIRFLOW_PASSWORD || 'admin_password'; + console.log('Airflow environment variables set.'); + + // Close the MongoDB connection + await mongoose.connection.close(); +}; diff --git a/__tests__/globalTeardown.js b/__tests__/globalTeardown.js new file mode 100644 index 0000000..8af64e9 --- /dev/null +++ b/__tests__/globalTeardown.js @@ -0,0 +1,30 @@ +require('dotenv').config(); +const mongoose = require('mongoose'); + +module.exports = async () => { + const connection = mongoose.connection; + + try { + // Check if the connection is open before dropping the database + if (connection.readyState === 1) { + console.log('Dropping the database...'); + await connection.dropDatabase(); + } else { + console.log('No active MongoDB connection to drop.'); + } + } catch (error) { + console.error('Error dropping database during teardown:', error.message); + } finally { + // Always attempt to close the connection + try { + if (connection.readyState !== 0) { + console.log('Closing the MongoDB connection...'); + await connection.close(); + } else { + console.log('No active connection to close.'); + } + } catch (closeError) { + console.error('Error closing the connection:', closeError.message); + } + } +}; diff --git a/__tests__/integrationController.test.js b/__tests__/integrationController.test.js new file mode 100644 index 0000000..6c76b48 --- /dev/null +++ b/__tests__/integrationController.test.js @@ -0,0 +1,59 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const { createIntegrationModule } = require('../controllers/integrationController'); +const IntegrationModule = require('../models/integrationModel'); + +// Mock the IntegrationModule model +jest.mock('../models/integrationModel'); + +const app = express(); +app.use(express.json()); + +// Use the controller function for the route +app.post('/integration-modules', createIntegrationModule); + +describe('Integration Module Controller', () => { + describe('POST /integration-modules', () => { + it('should create a new integration module', async () => { + // Mock the IntegrationModule.save method + IntegrationModule.prototype.save = jest.fn().mockResolvedValue({ + IntegrationID: '123', + ToolName: 'Sample Tool', + Description: 'A sample tool description', + LinkOrPath: 'http://example.com', + }); + + const response = await request(app) + .post('/integration-modules') + .send({ + IntegrationID: '123', + ToolName: 'Sample Tool', + Description: 'A sample tool description', + LinkOrPath: 'http://example.com', + }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('IntegrationID', '123'); + expect(response.body).toHaveProperty('ToolName', 'Sample Tool'); + expect(response.body).toHaveProperty('Description', 'A sample tool description'); + expect(response.body).toHaveProperty('LinkOrPath', 'http://example.com'); + }); + + it('should handle errors when creating a new integration module', async () => { + // Mock the IntegrationModule.save method to throw an error + IntegrationModule.prototype.save = jest.fn().mockRejectedValue(new Error('Database error')); + + const response = await request(app) + .post('/integration-modules') + .send({ + IntegrationID: '123', + ToolName: 'Sample Tool', + Description: 'A sample tool description', + LinkOrPath: 'http://example.com', + }); + + expect(response.status).toBe(500); + }); + }); +}); diff --git a/__tests__/integrationModel.test.js b/__tests__/integrationModel.test.js new file mode 100644 index 0000000..02a95a3 --- /dev/null +++ b/__tests__/integrationModel.test.js @@ -0,0 +1,82 @@ +const mongoose = require('mongoose'); +const IntegrationModule = require('../models/integrationModel'); +const { connectDB } = require('../db'); + +describe('IntegrationModule Model Test', () => { + beforeAll(async () => { + await connectDB(); + await IntegrationModule.syncIndexes(); // Ensure the indexes are created before tests run + }); + + afterEach(async () => { + await IntegrationModule.deleteMany({}); // Clear the collection after each test + }); + + afterAll(async () => { + await mongoose.connection.close(); // Close the connection after all tests + }); + + it('should create and save an integration module successfully', async () => { + const validIntegrationModule = new IntegrationModule({ + IntegrationID: '123', + ToolName: 'Sample Tool', + Description: 'A sample tool description', + Link: 'http://example.com', + }); + const savedIntegrationModule = await validIntegrationModule.save(); + + expect(savedIntegrationModule._id).toBeDefined(); + expect(savedIntegrationModule.IntegrationID).toBe('123'); + expect(savedIntegrationModule.ToolName).toBe('Sample Tool'); + expect(savedIntegrationModule.Description).toBe('A sample tool description'); + expect(savedIntegrationModule.Link).toBe('http://example.com'); + }); + + it('should fail to create an integration module without required fields', async () => { + const invalidIntegrationModule = new IntegrationModule({ + Description: 'A sample tool description', + }); + + let err; + try { + await invalidIntegrationModule.save(); + } catch (error) { + err = error; + } + + expect(err).toBeInstanceOf(mongoose.Error.ValidationError); + expect(err.errors.IntegrationID).toBeDefined(); + expect(err.errors.ToolName).toBeDefined(); + }); + + it('should not create an integration module with a duplicate IntegrationID', async () => { + // First entry + const integrationModule1 = new IntegrationModule({ + IntegrationID: '123', + ToolName: 'Tool One', + Description: 'First tool description', + Link: 'http://example.com/one', + }); + await integrationModule1.save(); + + // Attempt to create duplicate entry + const integrationModule2 = new IntegrationModule({ + IntegrationID: '123', // Duplicate ID + ToolName: 'Tool Two', + Description: 'Second tool description', + Link: 'http://example.com/two', + }); + + let err; + try { + await integrationModule2.save(); + } catch (error) { + err = error; + console.log('Error:', err); // Log error for debugging + } + + // Assert that the error is defined and it's a duplicate key error + expect(err).toBeDefined(); + expect(err.code).toBe(11000); // Duplicate key error code + }); +}); diff --git a/__tests__/integrationRoutes.test.js b/__tests__/integrationRoutes.test.js new file mode 100644 index 0000000..43dd46f --- /dev/null +++ b/__tests__/integrationRoutes.test.js @@ -0,0 +1,82 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const IntegrationModule = require('../models/integrationModel'); +const integrationRoutes = require('../routes/integration'); +const { connectDB, disconnectDB } = require('../db'); + +// Setup Express app and use the routes +const app = express(); +app.use(express.json()); +app.use('/api', integrationRoutes); + +describe('Integration Routes Test', () => { + // Connect to the in-memory database before running tests + beforeAll(async () => { + await connectDB(); + // Ensure unique index is created + await IntegrationModule.collection.createIndex({ IntegrationID: 1 }, { unique: true }); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + describe('POST /api/integration-modules', () => { + beforeEach(async () => { + await IntegrationModule.deleteMany(); // Clean up before each test + }); + + it('should create a new integration module', async () => { + const response = await request(app) + .post('/api/integration-modules') + .send({ + IntegrationID: '123', + ToolName: 'Sample Tool', + Description: 'A sample tool description', + LinkOrPath: 'http://example.com', + }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('_id'); + }); + + it('should handle validation errors', async () => { + const response = await request(app) + .post('/api/integration-modules') + .send({ + Description: 'A sample tool description', + }); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message'); + expect(response.body.message).toContain('IntegrationID: Path `IntegrationID` is required.'); + expect(response.body.message).toContain('ToolName: Path `ToolName` is required.'); + }); + + it('should handle duplicate IntegrationID errors', async () => { + // Create the first module + const integrationModule = new IntegrationModule({ + IntegrationID: '123', + ToolName: 'Sample Tool', + Description: 'A sample tool description', + LinkOrPath: 'http://example.com', + }); + await integrationModule.save(); + + // Attempt to create a duplicate module + const response = await request(app) + .post('/api/integration-modules') + .send({ + IntegrationID: '123', + ToolName: 'Another Tool', + Description: 'Another sample tool description', + LinkOrPath: 'http://example.com/another', + }); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message', 'IntegrationID must be unique.'); + }); + }); +}); diff --git a/__tests__/investmentTrackerController.test.js b/__tests__/investmentTrackerController.test.js new file mode 100644 index 0000000..92e89f6 --- /dev/null +++ b/__tests__/investmentTrackerController.test.js @@ -0,0 +1,56 @@ +const request = require('supertest'); +const express = require('express'); +const bodyParser = require('body-parser'); +const mongoose = require('mongoose'); +const investmentTrackerController = require('../controllers/investmentTrackerController'); +const investmentTrackerModel = require('../models/investmentTrackerModel'); + +// Set up the Express app +const app = express(); +app.use(bodyParser.json()); +app.post('/investments', investmentTrackerController.trackInvestment); + +// Mock the investmentTrackerModel model +jest.mock('../models/investmentTrackerModel', () => { + return jest.fn().mockImplementation(() => ({ + save: jest.fn().mockResolvedValue({ + TrackID: '123', + Company: 'Test Company', + EquityPercentage: 10, + CurrentValue: 1000, + }), + })); +}); + +describe('Investment Tracker Controller', () => { + beforeAll(async () => { + await mongoose.connect('mongodb://127.0.0.1/investmentTrackerTestDB', { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + it('should create a new investment tracker entry', async () => { + const response = await request(app) + .post('/investments') + .send({ + TrackID: '123', + Company: 'Test Company', + EquityPercentage: 10, + CurrentValue: 1000, + }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('TrackID', '123'); + expect(response.body).toHaveProperty('Company', 'Test Company'); + expect(response.body).toHaveProperty('EquityPercentage', 10); + expect(response.body).toHaveProperty('CurrentValue', 1000); + }); + + // Add more tests here for other routes related to investmentTracker +}); diff --git a/__tests__/investmentTrackerModel.test.js b/__tests__/investmentTrackerModel.test.js new file mode 100644 index 0000000..9719137 --- /dev/null +++ b/__tests__/investmentTrackerModel.test.js @@ -0,0 +1,81 @@ +const mongoose = require('mongoose'); +const investmentTracker = require('../models/investmentTrackerModel'); + +describe('Investment Tracker Model', () => { + beforeAll(async () => { + const mongoUri = 'mongodb://127.0.0.1/investmentTrackerTestDB'; + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + it('should create and save an investment tracker successfully', async () => { + const validTracker = new investmentTracker({ + TrackID: '123', + Company: 'Test Company', + EquityPercentage: 10, + CurrentValue: 1000, + }); + + const savedTracker = await validTracker.save(); + + expect(savedTracker._id).toBeDefined(); + expect(savedTracker.TrackID).toBe('123'); + expect(savedTracker.Company).toBe('Test Company'); + expect(savedTracker.EquityPercentage).toBe(10); + expect(savedTracker.CurrentValue).toBe(1000); + }); + + it('should fail to create an investment tracker without required fields', async () => { + const invalidTracker = new investmentTracker({}); + + let err; + try { + await invalidTracker.save(); + } catch (error) { + err = error; + } + + expect(err).toBeInstanceOf(mongoose.Error.ValidationError); + expect(err.errors.TrackID).toBeDefined(); + }); + + // Uncomment the following test if you want to check for duplicate TrackID errors + /* + it('should fail to create an investment tracker with duplicate TrackID', async () => { + const tracker1 = new investmentTracker({ + TrackID: '123', + Company: 'Company One', + EquityPercentage: 20, + CurrentValue: 2000, + }); + + // Save the first tracker successfully + await tracker1.save(); + + const tracker2 = new investmentTracker({ + TrackID: '123', // Duplicate TrackID + Company: 'Company Two', + EquityPercentage: 30, + CurrentValue: 3000, + }); + + let err; + try { + await tracker2.save(); + } catch (error) { + err = error; + } + + // Ensure that err is defined and contains the expected MongoDB duplicate key error code + expect(err).toBeDefined(); + expect(err.code).toBe(11000); // MongoDB duplicate key error code is 11000 + }); + */ +}); diff --git a/__tests__/investmentTrackerRoutes.test.js b/__tests__/investmentTrackerRoutes.test.js new file mode 100644 index 0000000..682d3fb --- /dev/null +++ b/__tests__/investmentTrackerRoutes.test.js @@ -0,0 +1,75 @@ +const request = require('supertest'); +const express = require('express'); +const bodyParser = require('body-parser'); +const mongoose = require('mongoose'); +const router = require('../routes/investmentTrackerRoutes'); +const investmentTracker = require('../models/investmentTrackerModel'); + +jest.mock('../models/investmentTrackerModel'); + +const app = express(); +app.use(bodyParser.json()); +app.use('/api', router); + +describe('Investment Tracker Routes', () => { + beforeAll(async () => { + const mongoUri = 'mongodb://127.0.0.1/investmentTrackerTestDB'; + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }); + + afterAll(async () => { + await mongoose.connection.db.dropDatabase(); + await mongoose.connection.close(); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should create a new investment tracker entry via POST /api/investments', async () => { + investmentTracker.mockImplementationOnce(() => { + return { + save: jest.fn().mockResolvedValue({ + TrackID: '123', + Company: 'Test Company', + EquityPercentage: 10, + CurrentValue: 1000, + }), + }; + }); + + const response = await request(app) + .post('/api/investments') + .send({ + TrackID: '123', + Company: 'Test Company', + EquityPercentage: 10, + CurrentValue: 1000, + }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('TrackID', '123'); + expect(response.body).toHaveProperty('Company', 'Test Company'); + expect(response.body).toHaveProperty('EquityPercentage', 10); + expect(response.body).toHaveProperty('CurrentValue', 1000); + }); + + it('should return 400 if required fields are missing in POST /api/investments', async () => { + const response = await request(app) + .post('/api/investments') + .send({ + Company: 'Test Company', + EquityPercentage: 10, + CurrentValue: 1000, + }); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('error', 'Missing required fields'); + }); + + + // Add more tests here for other routes related to investmentTracker +}); \ No newline at end of file diff --git a/__tests__/investor.model.test.js b/__tests__/investor.model.test.js new file mode 100644 index 0000000..276949c --- /dev/null +++ b/__tests__/investor.model.test.js @@ -0,0 +1,141 @@ +const mongoose = require('mongoose'); +const Investor = require('../models/Investor'); +const { connectDB } = require('../db'); + +describe('Investor Model', () => { + beforeAll(async () => { + await connectDB(); + }); + + afterAll(async () => { + await mongoose.connection.close(); + }); + + it('should create a new investor', async () => { + const investorData = { + investorId: '12345', + investmentAmount: 10000, + equityPercentage: 10, + investorType: 'Angel', + relatedFundraisingRound: mongoose.Types.ObjectId(), + }; + + const investor = new Investor(investorData); + await investor.save(); + + expect(investor._id).toBeDefined(); + expect(investor.investorId).toBe(investorData.investorId); + expect(investor.investmentAmount).toBe(investorData.investmentAmount); + expect(investor.equityPercentage).toBe(investorData.equityPercentage); + expect(investor.investorType).toBe(investorData.investorType); + expect(investor.relatedFundraisingRound).toBeDefined(); + }); + + it('should throw an error if investorId is not provided', async () => { + const investorData = { + investmentAmount: 10000, + equityPercentage: 10, + investorType: 'Angel', + relatedFundraisingRound: mongoose.Types.ObjectId(), + }; + + try { + const investor = new Investor(investorData); + await investor.save(); + } catch (error) { + expect(error.message).toContain( + 'Investor validation failed: investorId: Path `investorId` is required.' + ); + } + }); + + it('should throw an error if investmentAmount is not provided', async () => { + const investorData = { + investorId: '12345', + equityPercentage: 10, + investorType: 'Angel', + relatedFundraisingRound: mongoose.Types.ObjectId(), + }; + + try { + const investor = new Investor(investorData); + await investor.save(); + } catch (error) { + expect(error.message).toContain( + 'Investor validation failed: investmentAmount: Path `investmentAmount` is required.' + ); + } + }); + + it('should throw an error if equityPercentage is not provided', async () => { + const investorData = { + investorId: '12345', + investmentAmount: 10000, + investorType: 'Angel', + relatedFundraisingRound: mongoose.Types.ObjectId(), + }; + + try { + const investor = new Investor(investorData); + await investor.save(); + } catch (error) { + expect(error.message).toContain( + 'Investor validation failed: equityPercentage: Path `equityPercentage` is required.' + ); + } + }); + + it('should throw an error if investorType is not provided', async () => { + const investorData = { + investorId: '12345', + investmentAmount: 10000, + equityPercentage: 10, + relatedFundraisingRound: mongoose.Types.ObjectId(), + }; + + try { + const investor = new Investor(investorData); + await investor.save(); + } catch (error) { + expect(error.message).toContain( + 'Investor validation failed: investorType: Path `investorType` is required.' + ); + } + }); + + it('should throw an error if relatedFundraisingRound is not provided', async () => { + const investorData = { + investorId: '12345', + investmentAmount: 10000, + equityPercentage: 10, + investorType: 'Angel', + }; + + try { + const investor = new Investor(investorData); + await investor.save(); + } catch (error) { + expect(error.message).toContain( + 'Investor validation failed: relatedFundraisingRound: Path `relatedFundraisingRound` is required.' + ); + } + }); + + it('should throw validation error if required fields are missing', async () => { + const investor = new Investor({}); + let err; + + try { + await investor.save(); + } catch (error) { + err = error; + } + + expect(err).toBeInstanceOf(mongoose.Error.ValidationError); + expect(err.errors.investorId).toBeDefined(); + expect(err.errors.investmentAmount).toBeDefined(); + expect(err.errors.equityPercentage).toBeDefined(); + expect(err.errors.investorType).toBeDefined(); + expect(err.errors.relatedFundraisingRound).toBeDefined(); + }); +}); diff --git a/__tests__/investorController.test.js b/__tests__/investorController.test.js new file mode 100644 index 0000000..5709a5d --- /dev/null +++ b/__tests__/investorController.test.js @@ -0,0 +1,67 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const Investor = require('../models/Investor'); +const investorRouter = require('../routes/investorRoutes'); +const { connectDB } = require('../db'); + +const app = express(); +app.use(express.json()); +app.use('/investors', investorRouter); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe('Investor Controller Test', () => { + let investorId; + + it('should create a new investor', async () => { + const response = await request(app).post('/investors').send({ + investorId: 'INV123', + investmentAmount: 50000, + equityPercentage: 10, + investorType: 'Angel', + relatedFundraisingRound: new mongoose.Types.ObjectId(), + }); + + expect(response.statusCode).toBe(201); + expect(response.body._id).toBeDefined(); + investorId = response.body._id; + }); + + it('should fetch an investor by ID', async () => { + const response = await request(app).get(`/investors/${investorId}`); + expect(response.statusCode).toBe(200); + expect(response.body.investor).toHaveProperty('investorId', 'INV123'); + }); + + it('should fetch all investors', async () => { + const response = await request(app).get('/investors'); + expect(response.statusCode).toBe(200); + expect(response.body.investors).toBeInstanceOf(Array); + }); + + it('should update an investor', async () => { + const response = await request(app).put(`/investors/${investorId}`).send({ + investorId: 'INV123', + investmentAmount: 100000, + equityPercentage: 20, + investorType: 'Venture Capital', + relatedFundraisingRound: new mongoose.Types.ObjectId(), + }); + + expect(response.statusCode).toBe(200); + expect(response.body.investmentAmount).toBe(100000); + }); + + it('should delete an investor', async () => { + const response = await request(app).delete(`/investors/${investorId}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Investor deleted'); + }); +}); diff --git a/__tests__/investorRoutes.test.js b/__tests__/investorRoutes.test.js new file mode 100644 index 0000000..abafd8b --- /dev/null +++ b/__tests__/investorRoutes.test.js @@ -0,0 +1,67 @@ +const request = require('supertest'); +const express = require('express'); +const mongoose = require('mongoose'); +const Investor = require('../models/Investor'); +const { connectDB } = require('../db'); +const investorRouter = require('../routes/investorRoutes'); + +const app = express(); +app.use(express.json()); +app.use('/investors', investorRouter); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe('Investor Routes Test', () => { + let investorId; + + it('POST /investors - should create a new investor', async () => { + const response = await request(app).post('/investors').send({ + investorId: 'INV123', + investmentAmount: 50000, + equityPercentage: 10, + investorType: 'Angel', + relatedFundraisingRound: new mongoose.Types.ObjectId(), + }); + + expect(response.statusCode).toBe(201); + expect(response.body._id).toBeDefined(); + investorId = response.body._id; + }); + + it('GET /investors/:id - should fetch an investor by ID', async () => { + const response = await request(app).get(`/investors/${investorId}`); + expect(response.statusCode).toBe(200); + expect(response.body.investor).toHaveProperty('investorId', 'INV123'); + }); + + it('GET /investors - should fetch all investors', async () => { + const response = await request(app).get('/investors'); + expect(response.statusCode).toBe(200); + expect(response.body.investors).toBeInstanceOf(Array); + }); + + it('PUT /investors/:id - should update an investor', async () => { + const response = await request(app).put(`/investors/${investorId}`).send({ + investorId: 'INV123', + investmentAmount: 100000, + equityPercentage: 20, + investorType: 'Venture Capital', + relatedFundraisingRound: new mongoose.Types.ObjectId(), + }); + + expect(response.statusCode).toBe(200); + expect(response.body.investmentAmount).toBe(100000); + }); + + it('DELETE /investors/:id - should delete an investor', async () => { + const response = await request(app).delete(`/investors/${investorId}`); + expect(response.statusCode).toBe(200); + expect(response.body.message).toBe('Investor deleted'); + }); +}); diff --git a/__tests__/inviteManagement.model.test.js b/__tests__/inviteManagement.model.test.js new file mode 100644 index 0000000..416b25f --- /dev/null +++ b/__tests__/inviteManagement.model.test.js @@ -0,0 +1,52 @@ +const mongoose = require("mongoose"); +const Invite = require("../models/inviteManagementModel"); + +beforeEach(async () => { + await Invite.deleteMany({}); // Clear the collection +}); + +// Connect to a test database +beforeAll(async () => { + const mongoUri = "mongodb://127.0.0.1/inviteManagementTestDB"; + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); +}); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe("Invite Management Model", () => { + it("should create a new invite", async () => { + const sampleInvite = { + InviteID: "test123", + ReceiverID: "receiver123", + Status: "Pending", + }; + + const invite = new Invite(sampleInvite); + const savedInvite = await invite.save(); + + expect(savedInvite.InviteID).toBe(sampleInvite.InviteID); + expect(savedInvite.ReceiverID).toBe(sampleInvite.ReceiverID); + expect(savedInvite.Status).toBe(sampleInvite.Status); + }); + + it("should not create an invite without required fields", async () => { + const invalidInvite = new Invite({}); // No fields provided + + let err; + try { + await invalidInvite.save(); + } catch (error) { + err = error; + } + + expect(err).toBeInstanceOf(mongoose.Error.ValidationError); + expect(err.errors.InviteID).toBeDefined(); + }); + + // More tests for other model validations and methods +}); diff --git a/__tests__/inviteManagementController.test.js b/__tests__/inviteManagementController.test.js new file mode 100644 index 0000000..f14a8a0 --- /dev/null +++ b/__tests__/inviteManagementController.test.js @@ -0,0 +1,140 @@ +const request = require("supertest"); +const express = require("express"); +const bodyParser = require("body-parser"); +const mongoose = require("mongoose"); +const Invite = require("../models/inviteManagementModel"); +const inviteRoutes = require("../routes/inviteManagementRoute"); + +// Set up the Express app +const app = express(); +app.use(bodyParser.json()); +app.use("/api", inviteRoutes); + +// Mock the Invite model +jest.mock("../models/inviteManagementModel"); + +const sampleInvite = { + InviteID: "test123", + ReceiverID: "receiver123", + Status: "Pending", + Timestamp: new Date(), +}; + +describe("Invite Management Controller", () => { + beforeAll(async () => { + const mongoUri = "mongodb://127.0.0.1/inviteManagementTestDB"; + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }); + + afterAll(async () => { + await mongoose.connection.close(); + }); + + it("POST /invites should create a new invite", async () => { + const mockSave = jest.fn().mockResolvedValue({ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }); + Invite.prototype.save = mockSave; + + const response = await request(app) + .post("/api/invites") + .send({ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }); + + console.error("POST /invites response:", response.body); // Log error details + expect(response.status).toBe(201); + expect(response.body).toMatchObject({ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }); + expect(mockSave).toHaveBeenCalled(); + }); + + it("GET /invites should get all invites", async () => { + const mockFind = jest.fn().mockResolvedValue([{ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + __v: 0, + _id: "test_id", + }]); + Invite.find = mockFind; + + const response = await request(app).get("/api/invites"); + + console.error("GET /invites response:", response.body); // Log error details + expect(response.status).toBe(200); + expect(response.body).toEqual([{ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + __v: 0, + _id: "test_id", + }]); + expect(mockFind).toHaveBeenCalled(); + }); + + it("GET /invites/:id should get an invite by ID", async () => { + const sampleInviteWithStringTimestamp = { + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + _id: "test_id", + }; + + const mockFindById = jest.fn().mockResolvedValue(sampleInviteWithStringTimestamp); + Invite.findById = mockFindById; + + const response = await request(app).get(`/api/invites/${sampleInvite.InviteID}`); + + console.error("GET /invites/:id response:", response.body); // Log error details + expect(response.status).toBe(200); + expect(response.body).toEqual(sampleInviteWithStringTimestamp); + expect(mockFindById).toHaveBeenCalledWith(sampleInvite.InviteID); + }); + + it("PUT /invites/:id should update an invite", async () => { + const updatedInvite = { ...sampleInvite, Status: "Accepted" }; + updatedInvite.Timestamp = updatedInvite.Timestamp.toISOString(); + + const mockFindByIdAndUpdate = jest.fn().mockResolvedValue(updatedInvite); + Invite.findByIdAndUpdate = mockFindByIdAndUpdate; + + const response = await request(app) + .put(`/api/invites/${sampleInvite.InviteID}`) + .send({ Status: "Accepted" }); + + console.error("PUT /invites/:id response:", response.body); // Log error details + expect(response.status).toBe(200); + expect(response.body).toEqual(updatedInvite); + expect(mockFindByIdAndUpdate).toHaveBeenCalledWith( + sampleInvite.InviteID, + { Status: "Accepted" }, + { new: true } + ); + }); + + it("DELETE /invites/:id should delete an invite", async () => { + const mockFindByIdAndDelete = jest.fn().mockResolvedValue(sampleInvite); + Invite.findByIdAndDelete = mockFindByIdAndDelete; + + const response = await request(app).delete(`/api/invites/${sampleInvite.InviteID}`); + + console.error("DELETE /invites/:id response:", response.body); // Log error details + expect(response.status).toBe(204); + expect(mockFindByIdAndDelete).toHaveBeenCalledWith(sampleInvite.InviteID); + }); + + it("GET /invites/:id should return 404 if invite not found", async () => { + Invite.findById = jest.fn().mockResolvedValue(null); + + const response = await request(app).get(`/api/invites/invalidID`); + + console.error("GET /invites/:id not found response:", response.body); // Log error details + expect(response.status).toBe(404); + expect(response.body).toEqual({ message: "Invite not found" }); + }); +}); diff --git a/__tests__/inviteManagementRoutes.test.js b/__tests__/inviteManagementRoutes.test.js new file mode 100644 index 0000000..9f53670 --- /dev/null +++ b/__tests__/inviteManagementRoutes.test.js @@ -0,0 +1,109 @@ +const request = require("supertest"); +const express = require("express"); +const bodyParser = require("body-parser"); +const mongoose = require("mongoose"); +const inviteRoutes = require("../routes/inviteManagementRoute"); +const Invite = require("../models/inviteManagementModel"); + +// Set up the Express app +const app = express(); +app.use(bodyParser.json()); +app.use("/api", inviteRoutes); + +// Mock the Invite model +jest.mock("../models/inviteManagementModel"); + +const sampleInvite = { + InviteID: "test123", + ReceiverID: "receiver123", + Status: "Pending", + Timestamp: new Date(), +}; + +describe("Invite Management Routes", () => { + beforeAll(async () => { + const mongoUri = "mongodb://127.0.0.1/inviteManagementTestDB"; + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }); + + afterAll(async () => { + await mongoose.connection.close(); + }); + + it("POST /invites should create a new invite", async () => { + const mockSave = jest.fn().mockResolvedValue({ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }); + Invite.prototype.save = mockSave; + + const response = await request(app) + .post("/api/invites") + .send({ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }); + + expect(response.status).toBe(201); + expect(response.body).toMatchObject({ + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }); + expect(mockSave).toHaveBeenCalled(); + }); + + it("GET /invites/:id should get an invite by ID", async () => { + const sampleInviteWithStringTimestamp = { + ...sampleInvite, + Timestamp: sampleInvite.Timestamp.toISOString(), // Convert Timestamp to string + }; + + const mockFindById = jest + .fn() + .mockResolvedValue(sampleInviteWithStringTimestamp); + Invite.findById = mockFindById; + + const response = await request(app).get( + `/api/invites/${sampleInvite.InviteID}` + ); + + expect(response.status).toBe(200); + expect(response.body).toEqual(sampleInviteWithStringTimestamp); + expect(mockFindById).toHaveBeenCalledWith(sampleInvite.InviteID); + }); + + it("PUT /invites/:id should update an invite", async () => { + const updatedInvite = { ...sampleInvite, Status: "Accepted" }; + updatedInvite.Timestamp = updatedInvite.Timestamp.toISOString(); + + const mockFindByIdAndUpdate = jest.fn().mockResolvedValue(updatedInvite); + Invite.findByIdAndUpdate = mockFindByIdAndUpdate; + + const response = await request(app) + .put(`/api/invites/${sampleInvite.InviteID}`) + .send({ Status: "Accepted" }); + + expect(response.status).toBe(200); + expect(response.body).toEqual(updatedInvite); + expect(mockFindByIdAndUpdate).toHaveBeenCalledWith( + sampleInvite.InviteID, + { Status: "Accepted" }, + { new: true } + ); + }); + + it("DELETE /invites/:id should delete an invite", async () => { + const mockFindByIdAndDelete = jest.fn().mockResolvedValue(sampleInvite); + Invite.findByIdAndDelete = mockFindByIdAndDelete; + + const response = await request(app).delete( + `/api/invites/${sampleInvite.InviteID}` + ); + + expect(response.status).toBe(204); + expect(mockFindByIdAndDelete).toHaveBeenCalledWith(sampleInvite.InviteID); + }); +}); diff --git a/__tests__/minioIntegration.test.js b/__tests__/minioIntegration.test.js new file mode 100644 index 0000000..44b0223 --- /dev/null +++ b/__tests__/minioIntegration.test.js @@ -0,0 +1,36 @@ +const { Client } = require('pg'); + +const client = new Client({ + user: 'lakehouse_user', + host: 'localhost', + database: 'lakehouse_metadata', + password: 'password', + port: 5432, +}); + +describe('PostgreSQL Integration Test', () => { + beforeAll(done => { + client.connect(err => { + if (err) return done(err); + done(); + }); + }); + + test('should log a new dataset to the metadata database', async () => { + const query = + 'INSERT INTO datasets (dataset_name, description, storage_location) VALUES ($1, $2, $3) RETURNING *'; + const values = ['test_dataset', 'This is a test dataset', 's3://lakehouse-bucket/raw/test-file.csv']; + + const res = await client.query(query, values); + expect(res.rows.length).toBe(1); + console.log('Dataset logged:', res.rows[0]); + }); + + afterAll(done => { + // Clean up the dataset after test + client.query('DELETE FROM datasets WHERE dataset_name = $1', ['test_dataset'], err => { + if (err) return done(err); + client.end(done); + }); + }); +}); diff --git a/__tests__/minioStorageIntegration.test.js b/__tests__/minioStorageIntegration.test.js new file mode 100644 index 0000000..48e43d1 --- /dev/null +++ b/__tests__/minioStorageIntegration.test.js @@ -0,0 +1,33 @@ +const axios = require('axios'); +const dotenv = require('dotenv'); +dotenv.config(); + +describe('MinIO Data Storage Integration Test', () => { + const airflowUrl = 'http://localhost:8081/api/v1/dags/test_dag/dagRuns'; + + it('should trigger the DAG and store the dataset in MinIO', async () => { + try { + // Trigger the DAG to upload the dataset to MinIO + const response = await axios.post(airflowUrl, {}, { + auth: { + username: process.env.AIRFLOW_USERNAME || 'admin', + password: process.env.AIRFLOW_PASSWORD || 'admin_password' + }, + headers: { + 'Content-Type': 'application/json' + }, + data: '{}' + }); + + // Check for successful DAG triggering + expect(response.status).toBe(200); + console.log('DAG triggered successfully:', response.data); + + // Validate the file upload (you might need to enhance this by directly checking MinIO if necessary) + // Here, we assume the upload task logs success if it runs successfully in the DAG + } catch (error) { + console.error('Error during MinIO upload:', error); + throw error; + } + }); +}); diff --git a/__tests__/postgresIntegration.test.js b/__tests__/postgresIntegration.test.js new file mode 100644 index 0000000..44b0223 --- /dev/null +++ b/__tests__/postgresIntegration.test.js @@ -0,0 +1,36 @@ +const { Client } = require('pg'); + +const client = new Client({ + user: 'lakehouse_user', + host: 'localhost', + database: 'lakehouse_metadata', + password: 'password', + port: 5432, +}); + +describe('PostgreSQL Integration Test', () => { + beforeAll(done => { + client.connect(err => { + if (err) return done(err); + done(); + }); + }); + + test('should log a new dataset to the metadata database', async () => { + const query = + 'INSERT INTO datasets (dataset_name, description, storage_location) VALUES ($1, $2, $3) RETURNING *'; + const values = ['test_dataset', 'This is a test dataset', 's3://lakehouse-bucket/raw/test-file.csv']; + + const res = await client.query(query, values); + expect(res.rows.length).toBe(1); + console.log('Dataset logged:', res.rows[0]); + }); + + afterAll(done => { + // Clean up the dataset after test + client.query('DELETE FROM datasets WHERE dataset_name = $1', ['test_dataset'], err => { + if (err) return done(err); + client.end(done); + }); + }); +}); diff --git a/__tests__/shareClass.model.test.js b/__tests__/shareClass.model.test.js new file mode 100644 index 0000000..0405ea3 --- /dev/null +++ b/__tests__/shareClass.model.test.js @@ -0,0 +1,36 @@ +const mongoose = require('mongoose'); +const { connectDB } = require('../db'); +const ShareClass = require('../models/ShareClass'); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('ShareClass Model Test', () => { + it('create & save share class successfully', async () => { + const shareClassData = { + shareClassId: 'class1', + name: 'Class A', + description: 'Description of Class A', + amountRaised: 1000000, + ownershipPercentage: 10, + dilutedShares: 1000, + authorizedShares: 10000, + }; + const validShareClass = new ShareClass(shareClassData); + const savedShareClass = await validShareClass.save(); + expect(savedShareClass._id).toBeDefined(); + expect(savedShareClass.shareClassId).toBe(shareClassData.shareClassId); + expect(savedShareClass.name).toBe(shareClassData.name); + expect(savedShareClass.description).toBe(shareClassData.description); + expect(savedShareClass.amountRaised).toBe(shareClassData.amountRaised); + expect(savedShareClass.ownershipPercentage).toBe(shareClassData.ownershipPercentage); + expect(savedShareClass.dilutedShares).toBe(shareClassData.dilutedShares); + expect(savedShareClass.authorizedShares).toBe(shareClassData.authorizedShares); + }); +}); diff --git a/__tests__/shareClassRoutes.test.js b/__tests__/shareClassRoutes.test.js new file mode 100644 index 0000000..15df042 --- /dev/null +++ b/__tests__/shareClassRoutes.test.js @@ -0,0 +1,97 @@ +const request = require('supertest'); +const mongoose = require('mongoose'); +const app = require('../app'); +const ShareClass = require('../models/ShareClass'); +const { connectDB, disconnectDB } = require('../db'); + +const PORT = 5006; // Ensure a unique port + +describe('ShareClass Routes', () => { + let server; + + beforeAll(async () => { + await connectDB(); + server = app.listen(PORT); + }); + + afterAll(async () => { + await server.close(); + await disconnectDB(); + }); + + beforeEach(async () => { + await ShareClass.deleteMany({}); + }); + + it('GET /api/shareClasses should return all share classes', async () => { + const shareClass = new ShareClass({ + shareClassId: 'class1', + name: 'Class A', + description: 'Description of Class A', + amountRaised: 1000000, + ownershipPercentage: 10, + dilutedShares: 1000, + authorizedShares: 10000 + }); + await shareClass.save(); + + const response = await request(server).get('/api/shareClasses'); + expect(response.status).toBe(200); + expect(response.body.length).toBe(1); + expect(response.body[0].name).toBe('Class A'); + }); + + it('POST /api/shareClasses should create a new share class', async () => { + const shareClassData = { + shareClassId: 'class2', + name: 'Class B', + description: 'Description of Class B', + amountRaised: 2000000, + ownershipPercentage: 20, + dilutedShares: 2000, + authorizedShares: 20000 + }; + + const response = await request(server).post('/api/shareClasses').send(shareClassData); + console.log('POST response:', response.body); + expect(response.status).toBe(201); + expect(response.body.name).toBe('Class B'); + }); + + it('PUT /api/shareClasses/:id should update a share class', async () => { + const shareClass = new ShareClass({ + shareClassId: 'class3', + name: 'Update Class', + description: 'Description of Update Class', + amountRaised: 3000000, + ownershipPercentage: 30, + dilutedShares: 3000, + authorizedShares: 30000 + }); + await shareClass.save(); + + const updatedData = { name: 'Updated Class' }; + const response = await request(server) + .put(`/api/shareClasses/${shareClass._id}`) + .send(updatedData); + expect(response.status).toBe(200); + expect(response.body.name).toBe('Updated Class'); + }); + + it('DELETE /api/shareClasses/:id should delete a share class', async () => { + const shareClass = new ShareClass({ + shareClassId: 'class4', + name: 'Delete Class', + description: 'Description of Delete Class', + amountRaised: 4000000, + ownershipPercentage: 40, + dilutedShares: 4000, + authorizedShares: 40000 + }); + await shareClass.save(); + + const response = await request(server).delete(`/api/shareClasses/${shareClass._id}`); + expect(response.status).toBe(200); + expect(response.body.message).toBe('Share class deleted'); + }); +}); diff --git a/__tests__/stakeholder.model.test.js b/__tests__/stakeholder.model.test.js new file mode 100644 index 0000000..068e827 --- /dev/null +++ b/__tests__/stakeholder.model.test.js @@ -0,0 +1,30 @@ +const mongoose = require('mongoose'); +const { connectDB } = require('../db'); +const Stakeholder = require('../models/Stakeholder'); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('Stakeholder Model Test', () => { + it('create & save stakeholder successfully', async () => { + const stakeholderData = { + stakeholderId: 'stakeholder1', + name: 'John Doe', + role: 'Manager', + projectId: 'project1', + }; + const validStakeholder = new Stakeholder(stakeholderData); + const savedStakeholder = await validStakeholder.save(); + expect(savedStakeholder._id).toBeDefined(); + expect(savedStakeholder.stakeholderId).toBe(stakeholderData.stakeholderId); + expect(savedStakeholder.name).toBe(stakeholderData.name); + expect(savedStakeholder.role).toBe(stakeholderData.role); + expect(savedStakeholder.projectId).toBe(stakeholderData.projectId); + }); +}); diff --git a/__tests__/stakeholderRoutes.test.js b/__tests__/stakeholderRoutes.test.js new file mode 100644 index 0000000..5123cd4 --- /dev/null +++ b/__tests__/stakeholderRoutes.test.js @@ -0,0 +1,83 @@ +const request = require('supertest'); +const mongoose = require('mongoose'); +const app = require('../app'); // Ensure this imports the Express app correctly +const Stakeholder = require('../models/Stakeholder'); +const { connectDB, disconnectDB } = require('../db'); + +const PORT = 5008; // Ensure a unique port + +describe('Stakeholder Routes', () => { + let server; + + beforeAll(async () => { + await connectDB(); + server = app.listen(PORT); + }); + + afterAll(async () => { + await server.close(); + await disconnectDB(); + }); + + beforeEach(async () => { + await Stakeholder.deleteMany({}); + }); + + it('GET /api/stakeholders should return all stakeholders', async () => { + const stakeholder = new Stakeholder({ + stakeholderId: 'stakeholder1', + name: 'Jane Doe', + role: 'Developer', + projectId: new mongoose.Types.ObjectId() + }); + await stakeholder.save(); + + const response = await request(server).get('/api/stakeholders'); + expect(response.status).toBe(200); + expect(response.body.length).toBe(1); // Ensure response.body is an array + expect(response.body[0].name).toBe('Jane Doe'); + }); + + it('POST /api/stakeholders should create a new stakeholder', async () => { + const stakeholderData = { + stakeholderId: 'stakeholder2', + name: 'John Doe', + role: 'Manager', + projectId: new mongoose.Types.ObjectId() + }; + + const response = await request(server).post('/api/stakeholders').send(stakeholderData); + console.log('POST response:', response.body); + expect(response.status).toBe(201); + expect(response.body.name).toBe('John Doe'); + }); + + it('PUT /api/stakeholders/:id should update a stakeholder', async () => { + const stakeholder = new Stakeholder({ + stakeholderId: 'stakeholder3', + name: 'Update Stakeholder', + role: 'Tester', + projectId: new mongoose.Types.ObjectId() + }); + await stakeholder.save(); + + const updatedData = { name: 'Updated Stakeholder' }; + const response = await request(server).put(`/api/stakeholders/${stakeholder._id}`).send(updatedData); + expect(response.status).toBe(200); + expect(response.body.stakeholder.name).toBe('Updated Stakeholder'); + }); + + it('DELETE /api/stakeholders/:id should delete a stakeholder', async () => { + const stakeholder = new Stakeholder({ + stakeholderId: 'stakeholder4', + name: 'Delete Stakeholder', + role: 'Analyst', + projectId: new mongoose.Types.ObjectId() + }); + await stakeholder.save(); + + const response = await request(server).delete(`/api/stakeholders/${stakeholder._id}`); + expect(response.status).toBe(200); + expect(response.body.message).toBe('Stakeholder deleted'); + }); +}); diff --git a/__tests__/test-dataset.csv b/__tests__/test-dataset.csv new file mode 100644 index 0000000..a0a0135 --- /dev/null +++ b/__tests__/test-dataset.csv @@ -0,0 +1,6 @@ +name,value +Alice,5 +Bob,15 +Charlie,25 +David,8 +Eve,30 diff --git a/__tests__/user.model.test.js b/__tests__/user.model.test.js new file mode 100644 index 0000000..85b7405 --- /dev/null +++ b/__tests__/user.model.test.js @@ -0,0 +1,34 @@ +const mongoose = require('mongoose'); +const { connectDB } = require('../db'); +const User = require('../models/User'); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('User Model Test', () => { + it('create & save user successfully', async () => { + const userData = { + userId: 'user1', + name: 'Test User', + username: 'testuser', // added username + email: 'test@example.com', + password: 'password', + role: 'admin', + }; + const validUser = new User(userData); + const savedUser = await validUser.save(); + expect(savedUser._id).toBeDefined(); + expect(savedUser.userId).toBe(userData.userId); + expect(savedUser.name).toBe(userData.name); + expect(savedUser.username).toBe(userData.username); // added username assertion + expect(savedUser.email).toBe(userData.email); + expect(savedUser.password).toBe(userData.password); + expect(savedUser.role).toBe(userData.role); + }); +}); diff --git a/__tests__/user.test.js b/__tests__/user.test.js new file mode 100644 index 0000000..85b7405 --- /dev/null +++ b/__tests__/user.test.js @@ -0,0 +1,34 @@ +const mongoose = require('mongoose'); +const { connectDB } = require('../db'); +const User = require('../models/User'); + +beforeAll(async () => { + await connectDB(); +}); + +afterAll(async () => { + await mongoose.connection.dropDatabase(); + await mongoose.connection.close(); +}); + +describe('User Model Test', () => { + it('create & save user successfully', async () => { + const userData = { + userId: 'user1', + name: 'Test User', + username: 'testuser', // added username + email: 'test@example.com', + password: 'password', + role: 'admin', + }; + const validUser = new User(userData); + const savedUser = await validUser.save(); + expect(savedUser._id).toBeDefined(); + expect(savedUser.userId).toBe(userData.userId); + expect(savedUser.name).toBe(userData.name); + expect(savedUser.username).toBe(userData.username); // added username assertion + expect(savedUser.email).toBe(userData.email); + expect(savedUser.password).toBe(userData.password); + expect(savedUser.role).toBe(userData.role); + }); +}); diff --git a/__tests__/userRoutes.test.js b/__tests__/userRoutes.test.js new file mode 100644 index 0000000..9fb1efe --- /dev/null +++ b/__tests__/userRoutes.test.js @@ -0,0 +1,91 @@ +const request = require('supertest'); +const mongoose = require('mongoose'); +const app = require('../app'); +const User = require('../models/User'); +const { connectDB, disconnectDB } = require('../db'); + +const PORT = 5005; // Ensure a unique port + +describe('User Routes', () => { + let server; + + beforeAll(async () => { + await connectDB(); + server = app.listen(PORT); + }); + + afterAll(async () => { + await server.close(); + await disconnectDB(); + }); + + beforeEach(async () => { + await User.deleteMany({}); + }); + + it('GET /api/users should return all users', async () => { + const user = new User({ + userId: 'user1', + name: 'User One', + username: 'userone', + email: 'userone@example.com', + password: 'password123', + role: 'user' + }); + await user.save(); + + const response = await request(server).get('/api/users'); + expect(response.status).toBe(200); + expect(response.body.length).toBe(1); + expect(response.body[0].name).toBe('User One'); + }); + + it('POST /api/users should create a new user', async () => { + const userData = { + userId: 'user2', + name: 'New User', + username: 'newuser', + email: 'newuser@example.com', + password: 'password123', + role: 'user' + }; + + const response = await request(server).post('/api/users').send(userData); + console.log('POST response:', response.body); + expect(response.status).toBe(201); + expect(response.body.name).toBe('New User'); + }); + + it('PUT /api/users/:id should update a user', async () => { + const user = new User({ + userId: 'user3', + name: 'Update User', + username: 'updateuser', + email: 'updateuser@example.com', + password: 'password123', + role: 'user' + }); + await user.save(); + + const updatedData = { name: 'Updated User' }; + const response = await request(server).put(`/api/users/${user._id}`).send(updatedData); + expect(response.status).toBe(200); + expect(response.body.name).toBe('Updated User'); + }); + + it('DELETE /api/users/:id should delete a user', async () => { + const user = new User({ + userId: 'user4', + name: 'Delete User', + username: 'deleteuser', + email: 'deleteuser@example.com', + password: 'password123', + role: 'user' + }); + await user.save(); + + const response = await request(server).delete(`/api/users/${user._id}`); + expect(response.status).toBe(200); + expect(response.body.name).toBe('Delete User'); + }); +}); diff --git a/app.js b/app.js index ff47a1f..6932e64 100644 --- a/app.js +++ b/app.js @@ -3,6 +3,10 @@ const express = require('express'); const mongoose = require('mongoose'); require('dotenv').config(); +const app = express(); +app.use(express.json()); + +// Routes imports const userRoutes = require('./routes/userRoutes'); const shareClassRoutes = require('./routes/shareClassRoutes'); const stakeholderRoutes = require('./routes/stakeholderRoutes'); @@ -16,16 +20,22 @@ const investmentRoutes = require('./routes/investmentTrackerRoutes'); const adminRoutes = require('./routes/adminRoutes'); const documentAccessRoutes = require('./routes/documentAccessRoutes'); const investorRoutes = require('./routes/investorRoutes'); -const companyRoutes = require('./routes/Company'); +const companyRoutes = require('./routes/Company'); const taxCalculatorRoutes = require('./routes/TaxCalculator'); const authRoutes = require('./routes/authRoutes'); -const corporationRoutes = require('./routes/corporationRoutes'); -const compensationRoutes = require('./routes/compensationRoutes'); -const issuerRoutes = require('./routes/issuerRoutes'); -const app = express(); -app.use(express.json()); +// Conditionally load routes that may cause issues in the test environment +if (process.env.NODE_ENV !== 'test') { + const corporationRoutes = require('./routes/corporationRoutes'); + const compensationRoutes = require('./routes/compensationRoutes'); + const issuerRoutes = require('./routes/issuerRoutes'); + + app.use('/api/v2', corporationRoutes); + app.use('/api/v2/compensation', compensationRoutes); + app.use('/api/v2/issuers', issuerRoutes); +} +// General API routes app.use('/api/users', userRoutes); app.use('/api/shareClasses', shareClassRoutes); app.use('/api/stakeholders', stakeholderRoutes); @@ -41,10 +51,8 @@ app.use('/api/documentAccesses', documentAccessRoutes); app.use('/api/investors', investorRoutes); app.use('/api/taxCalculations', taxCalculatorRoutes); app.use('/api/companies', companyRoutes); -app.use('/auth', authRoutes); -app.use('/api/v2', corporationRoutes); -app.use('/api/v2/compensation', compensationRoutes); -app.use('/api/v2/issuers', issuerRoutes); +// Auth route +app.use('/auth', authRoutes); module.exports = app; diff --git a/db.js b/db.js index a96e445..e69de29 100644 --- a/db.js +++ b/db.js @@ -1,20 +0,0 @@ -const mongoose = require('mongoose'); - -const connectDB = async () => { - if (mongoose.connection.readyState === 0) { - await mongoose.connect('mongodb://localhost:27017/opencap_test', { - useNewUrlParser: true, - useUnifiedTopology: true, - }); - console.log('MongoDB Connected...'); - } -}; - -const disconnectDB = async () => { - if (mongoose.connection.readyState !== 0) { - await mongoose.connection.close(); - console.log('MongoDB Disconnected...'); - } -}; - -module.exports = { connectDB, disconnectDB }; diff --git a/jest.config.js b/jest.config.js index 4b5f389..bbb1ba3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,8 @@ module.exports = { - // Other configurations... - globalSetup: './test/globalSetup.js', - globalTeardown: './test/globalTeardown.js', - testTimeout: 30000, + globalSetup: './__tests__/globalSetup.js', // Path to the global setup file + globalTeardown: './__tests__/globalTeardown.js', // Path to the global teardown file (optional, only if used) + testMatch: ['**/__tests__/**/*.[jt]s?(x)'], // Look for tests inside the __tests__ directory + testPathIgnorePatterns: ['/node_modules/', '/dist/'], // Ignore node_modules and dist folders + testTimeout: 30000, // Set a custom test timeout + verbose: true, // Enable detailed output }; diff --git a/models/financialReport.js b/models/financialReport.js new file mode 100644 index 0000000..e69de29 diff --git a/models/integrationModel.js b/models/integrationModel.js index 0ee1aa4..0dd725b 100644 --- a/models/integrationModel.js +++ b/models/integrationModel.js @@ -1,10 +1,10 @@ const mongoose = require('mongoose'); -const integrationSchema = new mongoose.Schema({ +const IntegrationModuleSchema = new mongoose.Schema({ IntegrationID: { type: String, required: true, - unique: true, + unique: true, // Ensure this is unique to trigger the duplicate key error }, ToolName: { type: String, @@ -12,14 +12,13 @@ const integrationSchema = new mongoose.Schema({ }, Description: { type: String, - required: false, }, - Link: { // Updated field name + Link: { type: String, - required: false, }, }); -const IntegrationModule = mongoose.model('IntegrationModule', integrationSchema); +// This ensures that the unique index is created +IntegrationModuleSchema.index({ IntegrationID: 1 }, { unique: true }); -module.exports = IntegrationModule; +module.exports = mongoose.model('IntegrationModule', IntegrationModuleSchema); diff --git a/package-lock.json b/package-lock.json index 6b466c4..e391532 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,15 +8,29 @@ "name": "opencap", "version": "1.0.0", "dependencies": { + "@hapi/code": "^9.0.3", + "@hapi/hoek": "^11.0.4", "argon2": "^0.40.3", + "axios": "^1.7.7", "bcrypt": "^5.1.1", "chai-http": "^5.0.0", + "code": "^5.2.4", + "data-forge": "^1.10.2", + "data-forge-fs": "^0.0.9", + "diff": "^7.0.0", "dotenv": "^16.4.5", "express": "^4.17.1", "express-async-handler": "^1.2.0", "google-auth-library": "^9.14.0", "jsonwebtoken": "^9.0.2", + "lodash": "^4.17.21", + "minimatch": "^10.0.1", + "minio": "^8.0.1", + "mkdirp": "^3.0.1", + "mocha": "^10.7.3", "mongoose": "^5.13.22", + "ms": "^2.1.3", + "pg": "^8.13.0", "sinon": "^18.0.0" }, "devDependencies": { @@ -32,6 +46,7 @@ "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", "@jridgewell/trace-mapping": "^0.3.24" @@ -41,12 +56,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" }, "engines": { @@ -54,30 +70,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", - "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", - "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.8", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -92,98 +110,102 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/generator": { - "version": "7.24.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", - "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", + "node_modules/@babel/core/node_modules/debug": { + "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": { - "@babel/types": "^7.24.9", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "ms": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", - "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "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, - "dependencies": { - "@babel/compat-data": "^7.24.8", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "node_modules/@babel/generator": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "node_modules/@babel/helper-compilation-targets/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, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", - "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -193,86 +215,81 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", + "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", - "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.8" + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -286,6 +303,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -298,6 +316,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -312,6 +331,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -320,13 +340,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -336,6 +358,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -345,6 +368,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -353,10 +377,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.8" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -369,6 +397,7 @@ "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" }, @@ -381,6 +410,7 @@ "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" }, @@ -393,6 +423,7 @@ "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" }, @@ -400,11 +431,44 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "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" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz", + "integrity": "sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "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" }, @@ -417,6 +481,7 @@ "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" }, @@ -425,12 +490,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz", + "integrity": "sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -444,6 +510,7 @@ "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" }, @@ -456,6 +523,7 @@ "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" }, @@ -468,6 +536,7 @@ "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" }, @@ -480,6 +549,7 @@ "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" }, @@ -492,6 +562,7 @@ "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" }, @@ -504,6 +575,7 @@ "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" }, @@ -511,11 +583,28 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "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" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "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" }, @@ -527,12 +616,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz", + "integrity": "sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -542,33 +632,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", - "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -576,14 +665,33 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/debug": { + "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" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@babel/types": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", - "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -594,13 +702,35 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@data-forge/serialization": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@data-forge/serialization/-/serialization-1.0.1.tgz", + "integrity": "sha512-EP7IWimh5JcDOISVoXvNIjUAqcPN1FkNWvuvjY3uzcswErxB8j93ldlUBvgvGEszqFRwMM3fpMF0HrISg5iBSQ==" + }, + "node_modules/@hapi/code": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@hapi/code/-/code-9.0.3.tgz", + "integrity": "sha512-g50b7qz861Xfnt1NWtcba1zVxlHLPDJh/4ys6pva6jMmQgbTDLgAkbORDHYbVSA7mYxZ2cHZ2n7ZeFb5j/ZhQw==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^11.0.2" + } + }, + "node_modules/@hapi/hoek": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", + "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==", + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/load-nyc-config": { "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", "find-up": "^4.1.0", @@ -617,6 +747,7 @@ "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" } @@ -626,6 +757,7 @@ "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", "@types/node": "*", @@ -643,6 +775,7 @@ "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", "@jest/reporters": "^29.7.0", @@ -690,6 +823,7 @@ "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", "@jest/types": "^29.6.3", @@ -705,6 +839,7 @@ "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", "jest-snapshot": "^29.7.0" @@ -718,6 +853,7 @@ "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" }, @@ -730,6 +866,7 @@ "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", "@sinonjs/fake-timers": "^10.0.2", @@ -747,6 +884,7 @@ "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", "@jest/expect": "^29.7.0", @@ -762,6 +900,7 @@ "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", "@jest/console": "^29.7.0", @@ -805,6 +944,7 @@ "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" }, @@ -817,6 +957,7 @@ "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", "callsites": "^3.0.0", @@ -831,6 +972,7 @@ "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", "@jest/types": "^29.6.3", @@ -846,6 +988,7 @@ "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", "graceful-fs": "^4.2.9", @@ -861,6 +1004,7 @@ "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", "@jest/types": "^29.6.3", @@ -887,6 +1031,7 @@ "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", "@types/istanbul-lib-coverage": "^2.0.0", @@ -904,6 +1049,7 @@ "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", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -918,6 +1064,7 @@ "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" } @@ -927,6 +1074,7 @@ "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" } @@ -935,13 +1083,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "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", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -967,72 +1117,12 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", - "integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==", + "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", "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" @@ -1042,6 +1132,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", + "license": "MIT", "engines": { "node": ">=10" } @@ -1050,49 +1141,52 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@sinonjs/fake-timers": { "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" } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0", + "@sinonjs/commons": "^3.0.1", "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" + "type-detect": "^4.1.0" } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@types/babel__core": { @@ -1100,6 +1194,7 @@ "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", "@babel/types": "^7.20.7", @@ -1113,6 +1208,7 @@ "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" } @@ -1122,6 +1218,7 @@ "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", "@babel/types": "^7.0.0" @@ -1132,6 +1229,7 @@ "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" } @@ -1140,6 +1238,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1149,6 +1248,7 @@ "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": "*" } @@ -1157,13 +1257,15 @@ "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 + "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": "*" } @@ -1173,6 +1275,7 @@ "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": "*" } @@ -1181,46 +1284,52 @@ "version": "3.6.20", "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "license": "MIT", "dependencies": { "@types/bson": "*", "@types/node": "*" } }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/webidl-conversions": { "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 + "dev": true, + "license": "MIT" }, "node_modules/@types/whatwg-url": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/webidl-conversions": "*" } }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "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": "*" } @@ -1229,7 +1338,14 @@ "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 + "dev": true, + "license": "MIT" + }, + "node_modules/@zxing/text-encoding": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", + "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", + "optional": true }, "node_modules/abbrev": { "version": "1.1.1", @@ -1241,6 +1357,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -1250,14 +1367,41 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "dependencies": { - "debug": "^4.3.4" + "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" } }, "node_modules/ansi-escapes": { @@ -1265,6 +1409,7 @@ "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" }, @@ -1279,6 +1424,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -1287,7 +1433,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" }, @@ -1302,7 +1448,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", "picomatch": "^2.0.4" @@ -1350,6 +1496,7 @@ "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.40.3.tgz", "integrity": "sha512-FrSmz4VeM91jwFvvjsQv9GYp6o/kARWoYKjbjDB2U5io1H3e5X67PYGclFDeQff6UXIhUd4aHR3mxCdBbMMuQw==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "@phc/format": "^1.0.0", "node-addon-api": "^8.0.0", @@ -1364,6 +1511,7 @@ "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" } @@ -1371,28 +1519,35 @@ "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, "license": "MIT", "engines": { "node": "*" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, "node_modules/async-mutex": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.1.tgz", "integrity": "sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.4.0" } @@ -1400,19 +1555,46 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } }, "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/babel-jest": { "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", "@types/babel__core": "^7.1.14", @@ -1434,6 +1616,7 @@ "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", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -1450,6 +1633,7 @@ "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", "@babel/parser": "^7.14.7", @@ -1461,11 +1645,22 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/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" + } + }, "node_modules/babel-plugin-jest-hoist": { "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", "@babel/types": "^7.3.3", @@ -1477,23 +1672,27 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "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", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -1504,6 +1703,7 @@ "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", "babel-preset-current-node-syntax": "^1.0.0" @@ -1518,13 +1718,15 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", "dev": true, + "license": "Apache-2.0", "optional": true }, "node_modules/base64-js": { @@ -1576,24 +1778,60 @@ "node": "*" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "license": "MIT", "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, + "node_modules/block-stream2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz", + "integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==", + "dependencies": { + "readable-stream": "^3.4.0" + } + }, + "node_modules/block-stream2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -1603,7 +1841,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -1613,47 +1851,20 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { "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" }, @@ -1661,10 +1872,21 @@ "node": ">=8" } }, + "node_modules/browser-or-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", + "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "license": "ISC" + }, "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -1680,10 +1902,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, "bin": { @@ -1698,6 +1921,7 @@ "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" } @@ -1706,6 +1930,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "license": "Apache-2.0", "engines": { "node": ">=0.6.19" } @@ -1715,6 +1940,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -1729,12 +1955,14 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1743,6 +1971,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -1762,6 +1991,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1771,14 +2001,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001642", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", - "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", "dev": true, "funding": [ { @@ -1793,30 +2024,31 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" } }, "node_modules/chai-http": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-5.0.0.tgz", - "integrity": "sha512-nWtyQ0/+VSayMEESPbBE2v5HYd24Jh67Alh9/dxecfZ4viFAsGN3leFwy3EsNu1DbEi/HsTVW+9pT8p79a2J+g==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-5.1.1.tgz", + "integrity": "sha512-h+QZNfYdlcoyIyOb26N71S7700CP4EY+CQ1X15AsX1RD2xMLAWbMniS7yUTOEC6DzC5yydGV37wu81AGNm8esA==", "license": "MIT", "dependencies": { "charset": "^1.0.1", @@ -1830,45 +2062,11 @@ "node": ">=18.20.0" } }, - "node_modules/chai-http/node_modules/formidable": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", - "integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==", - "license": "MIT", - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, - "node_modules/chai-http/node_modules/superagent": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz", - "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==", - "license": "MIT", - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.4", - "debug": "^4.3.4", - "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.0", - "formidable": "^3.5.1", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.11.0" - }, - "engines": { - "node": ">=14.18.0" - } - }, "node_modules/chalk": { "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", "supports-color": "^7.1.0" @@ -1885,6 +2083,7 @@ "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" } @@ -1902,7 +2101,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" @@ -1911,6 +2109,30 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -1931,21 +2153,24 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", - "dev": true + "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/cliui": { "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", "strip-ansi": "^6.0.1", @@ -1955,6 +2180,15 @@ "node": ">=12" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/clone-regexp": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz", @@ -1975,36 +2209,34 @@ "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", "node": ">= 0.12.0" } }, "node_modules/code": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/code/-/code-2.3.0.tgz", - "integrity": "sha512-pWZDcSGF5IcRnELbVneDcS4sPjKj4t7QbAHcRwpAEaIRdiqkWentKPSJDMLoZUI1gAawiOvjYRoK9Hs+ncky5w==", - "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", - "dev": true, + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/code/-/code-5.2.4.tgz", + "integrity": "sha512-PkH2B69kE/ETlWJCFrMHbBXzmReeSHMdky5nAfX01cnloOxfYEQ6mGlowBpeyJUZr8kNBjvHd88NkGqYZltbTw==", + "deprecated": "This module has moved and is now available at @hapi/code. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", "license": "BSD-3-Clause", "dependencies": { - "hoek": "4.x.x" - }, - "engines": { - "node": ">=4.0.0" + "hoek": "6.x.x" } }, "node_modules/collect-v8-coverage": { "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 + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2016,7 +2248,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "license": "MIT" }, "node_modules/color-support": { "version": "1.1.3", @@ -2031,6 +2263,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2051,12 +2284,14 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -2064,7 +2299,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, "node_modules/console-control-strings": { "version": "1.1.0", @@ -2076,6 +2312,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -2087,6 +2324,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2107,12 +2345,14 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2120,23 +2360,27 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" }, "node_modules/create-jest": { "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", "chalk": "^4.0.0", @@ -2158,6 +2402,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2167,20 +2412,70 @@ "node": ">= 8" } }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "node_modules/data-forge": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/data-forge/-/data-forge-1.10.2.tgz", + "integrity": "sha512-VZv8NV5laRC+VXGkA6cccl5Hwkkbt1sUuphVPcICLMMhiRWzVcVEowfcaplhb/kzmDsuohpruzHZp3y5w9OnuA==", + "hasInstallScript": true, + "dependencies": { + "@data-forge/serialization": "^1.0.0", + "dayjs": "^1.8.12", + "easy-table": "1.1.0", + "json5": "^2.1.0", + "numeral": "^2.0.6", + "papaparse": "5.2.0", + "typy": "^3.0.1" + } + }, + "node_modules/data-forge-fs": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/data-forge-fs/-/data-forge-fs-0.0.9.tgz", + "integrity": "sha512-7VzK9DbvYqJk/AlQckIh4OMX0iNcvY4Za8vWXh6LT+TGekAs791XUjB2OsEDlRcmRr3DdQ7aecVBRZ+wevjhnA==", "dependencies": { - "ms": "2.1.2" + "chai": "^4.1.2" }, + "peerDependencies": { + "data-forge": "^1.8.13" + } + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "license": "MIT", "engines": { - "node": ">=6.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" } }, "node_modules/dedent": { @@ -2188,6 +2483,7 @@ "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" }, @@ -2198,16 +2494,15 @@ } }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deepmerge": { @@ -2215,14 +2510,28 @@ "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" } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "optional": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2239,6 +2548,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -2253,6 +2563,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "license": "Apache-2.0", "engines": { "node": ">=0.10" } @@ -2261,6 +2572,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2269,6 +2581,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -2288,6 +2601,7 @@ "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" } @@ -2296,16 +2610,17 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "license": "ISC", "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "node_modules/diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha512-VzVc42hMZbYU9Sx/ltb7KYuQ6pqAw+cbFWVy4XKdkuEL2CFaRLGEnISPs7YdzaUGpi+CpIqvRmu7hPQ4T7EQ5w==", - "dev": true, + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -2315,6 +2630,7 @@ "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" } @@ -2323,6 +2639,7 @@ "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -2330,6 +2647,14 @@ "url": "https://dotenvx.com" } }, + "node_modules/easy-table": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", + "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "optionalDependencies": { + "wcwidth": ">=1.0.1" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -2342,19 +2667,22 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.828", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.828.tgz", - "integrity": "sha512-QOIJiWpQJDHAVO4P58pwb133Cwee0nbvy/MV1CwzZVGpkH1RX33N3vsaWRCpR6bF63AAq366neZrRTu7Qlsbbw==", - "dev": true + "version": "1.5.38", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.38.tgz", + "integrity": "sha512-VbeVexmZ1IFh+5EfrYz1I0HTzHVIlJa112UEWhciPyeOcKJGeTv6N8WnG4wsQB81DGCaVEGhpSb6o6a8WYFXXg==", + "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" }, @@ -2365,12 +2693,14 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2380,6 +2710,7 @@ "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" } @@ -2388,6 +2719,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -2399,15 +2731,16 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -2415,15 +2748,19 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/escape-string-regexp": { - "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, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/esprima": { @@ -2431,6 +2768,7 @@ "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", "esvalidate": "bin/esvalidate.js" @@ -2443,15 +2781,22 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/execa": { "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", "get-stream": "^6.0.0", @@ -2484,6 +2829,7 @@ "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", "jest-get-type": "^29.6.3", @@ -2496,36 +2842,37 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -2539,39 +2886,8 @@ "node_modules/express-async-handler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", - "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==", + "license": "MIT" }, "node_modules/extend": { "version": "3.0.2", @@ -2583,24 +2899,49 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "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 + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } }, "node_modules/fb-watchman": { "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" } @@ -2609,7 +2950,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" }, @@ -2617,13 +2958,22 @@ "node": ">=8" } }, + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -2634,24 +2984,12 @@ "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -2664,26 +3002,12 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/find-cache-dir/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/find-up": { "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", "path-exists": "^4.0.0" @@ -2692,17 +3016,26 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true, + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -2712,10 +3045,18 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -2727,15 +3068,14 @@ } }, "node_modules/formidable": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", - "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", - "dev": true, + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", + "integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==", + "license": "MIT", "dependencies": { "dezalgo": "^1.0.4", "hexoid": "^1.0.0", - "once": "^1.4.0", - "qs": "^6.11.0" + "once": "^1.4.0" }, "funding": { "url": "https://ko-fi.com/tunnckoCore/commissions" @@ -2745,6 +3085,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2753,6 +3094,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2790,14 +3132,15 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "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, "os": [ "darwin" @@ -2810,6 +3153,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2863,33 +3207,76 @@ "node": ">=14" } }, - "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "license": "Apache-2.0", + "node_modules/gaxios/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", "dependencies": { - "gaxios": "^6.0.0", - "json-bigint": "^1.0.0" + "debug": "^4.3.4" }, "engines": { - "node": ">=14" + "node": ">= 14" } }, - "node_modules/gensync": { - "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, + "node_modules/gaxios/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/gaxios/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gensync": { + "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" + } + }, + "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -2898,7 +3285,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -2908,6 +3294,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -2927,6 +3314,7 @@ "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" } @@ -2936,6 +3324,7 @@ "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" }, @@ -2948,6 +3337,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", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2963,19 +3353,54 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/globals": { "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" } }, "node_modules/google-auth-library": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz", - "integrity": "sha512-Y/eq+RWVs55Io/anIsm24sDS8X79Tq948zVLGaa7+KlJYYqaGwp1YI37w48nzrNi12RgnzMrQD4NzdmCowT90g==", + "version": "9.14.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", + "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -2993,6 +3418,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3004,7 +3430,8 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/growl": { "version": "1.9.2", @@ -3030,6 +3457,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -3038,6 +3466,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -3049,6 +3478,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3060,6 +3490,21 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -3077,6 +3522,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -3084,6 +3530,15 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/hest": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/hest/-/hest-1.0.5.tgz", @@ -3098,31 +3553,30 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/hoek": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.3.1.tgz", - "integrity": "sha512-v7E+yIjcHECn973i0xHm4kJkEpv3C8sbYS4344WXbzYqRyiDD7rjnnKo4hsJkejQBAFdRMUGNHySeSPKSH9Rqw==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", - "dev": true, - "license": "SEE LICENSE IN LICENSE.md", - "engines": { - "node": ">=6.0.0" - } + "license": "BSD-3-Clause" }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -3135,15 +3589,33 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/human-signals": { @@ -3151,6 +3623,7 @@ "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" } @@ -3159,6 +3632,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -3167,10 +3641,11 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "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", "resolve-cwd": "^3.0.0" @@ -3190,6 +3665,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -3199,6 +3675,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.", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3207,13 +3684,15 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, + "license": "MIT", "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -3226,7 +3705,8 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/ip-regex": { "version": "5.0.0", @@ -3244,21 +3724,62 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -3269,10 +3790,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -3282,10 +3813,37 @@ "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" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-ip": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz", @@ -3306,11 +3864,20 @@ "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" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-regexp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", @@ -3327,6 +3894,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -3334,22 +3902,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "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" } @@ -3359,6 +3956,7 @@ "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", "@babel/parser": "^7.23.9", @@ -3370,23 +3968,12 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-lib-report": { "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", "make-dir": "^4.0.0", @@ -3396,11 +3983,28 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps": { - "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==", + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "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", "istanbul-lib-coverage": "^3.0.0", @@ -3410,11 +4014,30 @@ "node": ">=10" } }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "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" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "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", "istanbul-lib-report": "^3.0.0" @@ -3489,6 +4112,7 @@ "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", "jest-util": "^29.7.0", @@ -3503,6 +4127,7 @@ "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", "@jest/expect": "^29.7.0", @@ -3534,6 +4159,7 @@ "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", "@jest/test-result": "^29.7.0", @@ -3567,6 +4193,7 @@ "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", "@jest/test-sequencer": "^29.7.0", @@ -3612,6 +4239,7 @@ "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", "diff-sequences": "^29.6.3", @@ -3627,6 +4255,7 @@ "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" }, @@ -3639,6 +4268,7 @@ "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", "chalk": "^4.0.0", @@ -3655,6 +4285,7 @@ "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", "@jest/fake-timers": "^29.7.0", @@ -3672,6 +4303,7 @@ "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" } @@ -3681,6 +4313,7 @@ "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", "@types/graceful-fs": "^4.1.3", @@ -3706,6 +4339,7 @@ "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", "pretty-format": "^29.7.0" @@ -3719,6 +4353,7 @@ "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", "jest-diff": "^29.7.0", @@ -3734,6 +4369,7 @@ "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", "@jest/types": "^29.6.3", @@ -3754,6 +4390,7 @@ "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", "@types/node": "*", @@ -3768,6 +4405,7 @@ "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" }, @@ -3785,6 +4423,7 @@ "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" } @@ -3794,6 +4433,7 @@ "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", "graceful-fs": "^4.2.9", @@ -3814,6 +4454,7 @@ "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", "jest-snapshot": "^29.7.0" @@ -3827,6 +4468,7 @@ "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", "@jest/environment": "^29.7.0", @@ -3859,6 +4501,7 @@ "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", "@jest/fake-timers": "^29.7.0", @@ -3892,6 +4535,7 @@ "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", "@babel/generator": "^7.7.2", @@ -3918,23 +4562,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-util": { "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", "@types/node": "*", @@ -3952,6 +4585,7 @@ "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", "camelcase": "^6.2.0", @@ -3969,6 +4603,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3981,6 +4616,7 @@ "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", "@jest/types": "^29.6.3", @@ -4000,6 +4636,7 @@ "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": "*", "jest-util": "^29.7.0", @@ -4015,6 +4652,7 @@ "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" }, @@ -4038,17 +4676,176 @@ "when": "^3.7.7" } }, + "node_modules/jist/node_modules/code": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/code/-/code-2.3.0.tgz", + "integrity": "sha512-pWZDcSGF5IcRnELbVneDcS4sPjKj4t7QbAHcRwpAEaIRdiqkWentKPSJDMLoZUI1gAawiOvjYRoK9Hs+ncky5w==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/jist/node_modules/debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "0.7.1" + } + }, + "node_modules/jist/node_modules/diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha512-VzVc42hMZbYU9Sx/ltb7KYuQ6pqAw+cbFWVy4XKdkuEL2CFaRLGEnISPs7YdzaUGpi+CpIqvRmu7hPQ4T7EQ5w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/jist/node_modules/escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha512-cQpUid7bdTUnFin8S7BnNdOk+/eDqQmKgCANSyd/jAhrKEvxUvr9VQ8XZzXiOtest8NLfk3FSBZzwvemZNQ6Vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jist/node_modules/glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha512-hVb0zwEZwC1FXSKRPFTeOtN7AArJcJlI6ULGLtrstaswKNlrTJqAA+1lYlSUop4vjA423xlBzqfVS3iWGlqJ+g==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "BSD", + "dependencies": { + "inherits": "2", + "minimatch": "0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jist/node_modules/hoek": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.3.1.tgz", + "integrity": "sha512-v7E+yIjcHECn973i0xHm4kJkEpv3C8sbYS4344WXbzYqRyiDD7rjnnKo4hsJkejQBAFdRMUGNHySeSPKSH9Rqw==", + "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", + "dev": true, + "license": "SEE LICENSE IN LICENSE.md", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/jist/node_modules/lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jist/node_modules/lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jist/node_modules/minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha512-WFX1jI1AaxNTZVOHLBVazwTWKaQjoykSzCBNXB72vDTCzopQGtyP91tKdFK5cv1+qMwPyiTu1HqUriqplI8pcA==", + "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", + "dev": true, + "license": "MIT", + "dependencies": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jist/node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/jist/node_modules/mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha512-jNt2iEk9FPmZLzL+sm4FNyOIDYXf2wUU6L4Cc8OIKK/kzgMHKPi4YhTZqG4bW4kQVdIv6wutDybRhXfdnujA1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/jist/node_modules/ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha512-lRLiIR9fSNpnP6TC4v8+4OU7oStC01esuNowdQ34L+Gk8e5Puoc88IqJ+XAY/B3Mn2ZKis8l8HX90oU8ivzUHg==", + "dev": true + }, + "node_modules/jist/node_modules/supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha512-mS5xsnjTh5b7f2DM6bch6lR582UCOTphzINlZnDsfpIRrwI6r58rb6YSSGsdexkm8qw2bBVO2ID2fnJOTuLiPA==", + "dev": true, + "license": "MIT", + "bin": { + "supports-color": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "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", "esprima": "^4.0.0" @@ -4061,18 +4858,20 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-bigint": { @@ -4088,13 +4887,14 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/json5": { "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" }, @@ -4145,18 +4945,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/just-extend": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", @@ -4187,13 +4975,15 @@ "node_modules/kareem": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", - "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" + "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==", + "license": "Apache-2.0" }, "node_modules/kleur": { "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" } @@ -4203,6 +4993,7 @@ "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" } @@ -4211,13 +5002,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "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" }, @@ -4226,10 +5019,9 @@ } }, "node_modules/lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==", - "dev": true, + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.get": { @@ -4280,40 +5072,63 @@ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "license": "MIT" }, - "node_modules/lru-cache": { - "version": "5.1.1", + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru-cache": { + "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" } }, "node_modules/make-dir": { - "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, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "semver": "^6.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/makeerror": { @@ -4321,6 +5136,7 @@ "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" } @@ -4329,6 +5145,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4337,32 +5154,40 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT", "optional": true }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "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 + "dev": true, + "license": "MIT" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "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", "picomatch": "^2.3.1" @@ -4372,20 +5197,22 @@ } }, "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, "engines": { - "node": ">=4.0.0" + "node": ">=4" } }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4394,6 +5221,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -4406,19 +5234,24 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -4428,6 +5261,46 @@ "dev": true, "license": "MIT" }, + "node_modules/minio": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/minio/-/minio-8.0.1.tgz", + "integrity": "sha512-FzDO6yGnqLtm8sp3mXafWtiRUOslJSSg/aI0v9YbN5vjw5KLoODKAROCyi766NIvTSxcfHBrbhCSGk1A+MOzDg==", + "dependencies": { + "async": "^3.2.4", + "block-stream2": "^2.1.0", + "browser-or-node": "^2.1.1", + "buffer-crc32": "^1.0.0", + "eventemitter3": "^5.0.1", + "fast-xml-parser": "^4.2.2", + "ipaddr.js": "^2.0.1", + "lodash": "^4.17.21", + "mime-types": "^2.1.35", + "query-string": "^7.1.3", + "stream-json": "^1.8.0", + "through2": "^4.0.2", + "web-encoding": "^1.1.5", + "xml2js": "^0.5.0" + }, + "engines": { + "node": "^16 || ^18 || >=20" + } + }, + "node_modules/minio/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/minio/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "engines": { + "node": ">= 10" + } + }, "node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -4469,125 +5342,226 @@ "license": "ISC" }, "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "license": "MIT", - "dependencies": { - "minimist": "0.0.8" - }, "bin": { - "mkdirp": "bin/cmd.js" + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha512-jNt2iEk9FPmZLzL+sm4FNyOIDYXf2wUU6L4Cc8OIKK/kzgMHKPi4YhTZqG4bW4kQVdIv6wutDybRhXfdnujA1Q==", - "dev": true, + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "license": "MIT", "dependencies": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", - "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 0.8.x" + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, "node_modules/mocha/node_modules/debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==", - "dev": true, + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "0.7.1" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha512-cQpUid7bdTUnFin8S7BnNdOk+/eDqQmKgCANSyd/jAhrKEvxUvr9VQ8XZzXiOtest8NLfk3FSBZzwvemZNQ6Vg==", - "dev": true, + "node_modules/mocha/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha512-hVb0zwEZwC1FXSKRPFTeOtN7AArJcJlI6ULGLtrstaswKNlrTJqAA+1lYlSUop4vjA423xlBzqfVS3iWGlqJ+g==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "BSD", + "license": "ISC", "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", "inherits": "2", - "minimatch": "0.3" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==", - "dev": true, - "license": "ISC" + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, - "node_modules/mocha/node_modules/minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha512-WFX1jI1AaxNTZVOHLBVazwTWKaQjoykSzCBNXB72vDTCzopQGtyP91tKdFK5cv1+qMwPyiTu1HqUriqplI8pcA==", - "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", - "dev": true, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { - "lru-cache": "2", - "sigmund": "~1.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha512-lRLiIR9fSNpnP6TC4v8+4OU7oStC01esuNowdQ34L+Gk8e5Puoc88IqJ+XAY/B3Mn2ZKis8l8HX90oU8ivzUHg==", - "dev": true + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/mocha/node_modules/supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha512-mS5xsnjTh5b7f2DM6bch6lR582UCOTphzINlZnDsfpIRrwI6r58rb6YSSGsdexkm8qw2bBVO2ID2fnJOTuLiPA==", - "dev": true, + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "license": "MIT", - "bin": { - "supports-color": "cli.js" + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, "node_modules/mongodb": { "version": "3.7.4", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.4.tgz", "integrity": "sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==", + "license": "Apache-2.0", "dependencies": { "bl": "^2.2.1", "bson": "^1.1.4", @@ -4622,14 +5596,52 @@ } } }, - "node_modules/mongodb-connection-string-url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", - "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "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" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/mongodb-memory-server": { @@ -4638,6 +5650,7 @@ "integrity": "sha512-qONlW4sKPbtk9pqFnlPn7R73G3Q4TuebJJ5pHfoiKTqVJquojQ8xWmkCyz+/YnpA2vYBo/jib+nXvjfKwh7cjg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "mongodb-memory-server-core": "9.4.1", "tslib": "^2.6.3" @@ -4651,6 +5664,7 @@ "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-9.4.1.tgz", "integrity": "sha512-lobapXaysH64zrn521NTkmqHc3krSPUFkuuZ8A/BmQV8ON7p2SzAEvpoJPDXIeJkxIzYw06dYL6Gn5OcZdEElA==", "dev": true, + "license": "MIT", "dependencies": { "async-mutex": "^0.4.1", "camelcase": "^6.3.0", @@ -4669,11 +5683,25 @@ "node": ">=14.20.1" } }, + "node_modules/mongodb-memory-server-core/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/mongodb-memory-server-core/node_modules/bson": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=14.20.1" } @@ -4683,6 +5711,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4690,11 +5719,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mongodb-memory-server-core/node_modules/debug": { + "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" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mongodb-memory-server-core/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/mongodb-memory-server-core/node_modules/mongodb": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz", "integrity": "sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bson": "^5.5.0", "mongodb-connection-string-url": "^2.6.0", @@ -4731,22 +5793,11 @@ } } }, - "node_modules/mongodb-memory-server-core/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mongodb/node_modules/optional-require": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", + "license": "Apache-2.0", "dependencies": { "require-at": "^1.0.6" }, @@ -4787,14 +5838,22 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==", + "license": "Apache-2.0", "peerDependencies": { "mongoose": "*" } }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, "node_modules/mpath": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz", "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -4803,6 +5862,7 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", + "license": "MIT", "dependencies": { "bluebird": "3.5.1", "debug": "3.1.0", @@ -4818,6 +5878,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -4825,28 +5886,33 @@ "node_modules/mquery/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/mquery/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4856,6 +5922,7 @@ "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-2.0.0.tgz", "integrity": "sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -4863,32 +5930,60 @@ "node": ">=12.22.0" } }, + "node_modules/new-find-package-json/node_modules/debug": { + "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" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" + "path-to-regexp": "^8.1.0" } }, "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", + "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "license": "MIT", + "engines": { + "node": ">=16" } }, "node_modules/node-addon-api": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz", - "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.2.1.tgz", + "integrity": "sha512-vmEOvxwiH8tlOcv4SyE8RH34rI5/nWVaigUeAUPawC6f0+HoDthwI0vkMu4tbtsZrXq6QXFfrkhjofzKEs5tpA==", + "license": "MIT", "engines": { "node": "^18 || ^20 || >= 21" } @@ -4913,32 +6008,11 @@ } } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "license": "MIT", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -4949,13 +6023,15 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.17.tgz", - "integrity": "sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==", - "dev": true + "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/nopt": { "version": "5.0.0", @@ -4976,7 +6052,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" } @@ -4986,6 +6062,7 @@ "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" }, @@ -5006,6 +6083,14 @@ "set-blocking": "^2.0.0" } }, + "node_modules/numeral": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", + "integrity": "sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==", + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5019,6 +6104,7 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5030,6 +6116,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -5041,6 +6128,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -5050,6 +6138,7 @@ "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" }, @@ -5064,6 +6153,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", + "license": "Apache-2.0", "engines": { "node": ">=4" } @@ -5072,7 +6162,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" }, @@ -5088,6 +6178,7 @@ "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" }, @@ -5100,6 +6191,7 @@ "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" }, @@ -5115,15 +6207,22 @@ "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" } }, + "node_modules/papaparse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.2.0.tgz", + "integrity": "sha512-ylq1wgUSnagU+MKQtNeVqrPhZuMYBvOSL00DHycFTCxownF95gpLAk1HiHdUW77N8yxRq1qHXLdlIPyBSG9NSA==" + }, "node_modules/parse-json": { "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", "error-ex": "^1.3.1", @@ -5141,6 +6240,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -5149,7 +6249,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" } @@ -5158,6 +6258,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5167,6 +6268,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5175,19 +6277,19 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -5197,19 +6299,102 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/picocolors": { + "node_modules/pg": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.0.tgz", + "integrity": "sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw==", + "dependencies": { + "pg-connection-string": "^2.7.0", + "pg-pool": "^3.7.0", + "pg-protocol": "^1.7.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", + "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" + }, + "node_modules/pg-int8": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", + "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", + "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "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" }, @@ -5222,6 +6407,7 @@ "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" } @@ -5231,11 +6417,55 @@ "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "dependencies": { - "find-up": "^4.0.0" + "xtend": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/pretty-format": { @@ -5243,6 +6473,7 @@ "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", "ansi-styles": "^5.0.0", @@ -5257,6 +6488,7 @@ "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" }, @@ -5267,13 +6499,15 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" }, "node_modules/prompts": { "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", "sisteransi": "^1.0.5" @@ -5286,6 +6520,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -5294,11 +6529,17 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "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" } @@ -5317,12 +6558,14 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/qs": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", - "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -5333,16 +6576,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/queue-tick": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5351,6 +6622,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -5365,12 +6637,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5384,17 +6658,32 @@ "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } }, "node_modules/regexp-clone": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", - "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" + "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==", + "license": "MIT" }, "node_modules/require-at": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", + "license": "Apache-2.0", "engines": { "node": ">=4" } @@ -5403,7 +6692,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5413,6 +6702,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5430,6 +6720,7 @@ "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" }, @@ -5442,6 +6733,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5451,6 +6743,7 @@ "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" } @@ -5488,17 +6781,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/saslprep": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "license": "MIT", "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" @@ -5507,19 +6803,28 @@ "node": ">=6" } }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, "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, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -5539,44 +6844,34 @@ "node": ">= 0.8.0" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -5592,6 +6887,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -5607,13 +6903,15 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5626,6 +6924,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5634,6 +6933,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -5650,7 +6950,8 @@ "node_modules/sift": { "version": "13.5.2", "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", - "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==", + "license": "MIT" }, "node_modules/sigmund": { "version": "1.0.1", @@ -5662,16 +6963,17 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" }, "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz", + "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==", "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/fake-timers": "11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.2.0", "nise": "^6.0.0", @@ -5704,13 +7006,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "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" } @@ -5718,13 +7022,15 @@ "node_modules/sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" + "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==", + "license": "MIT" }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -5735,6 +7041,7 @@ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, + "license": "MIT", "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -5749,6 +7056,7 @@ "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" } @@ -5758,6 +7066,7 @@ "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", "source-map": "^0.6.0" @@ -5767,22 +7076,41 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", "optional": true, "dependencies": { "memory-pager": "^1.0.2" } }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stack-utils": { "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" }, @@ -5790,19 +7118,44 @@ "node": ">=10" } }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "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" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/stream-chain": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", + "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==" + }, + "node_modules/stream-json": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.8.0.tgz", + "integrity": "sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==", + "dependencies": { + "stream-chain": "^2.2.5" + } + }, "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "dev": true, + "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -5812,10 +7165,19 @@ "bare-events": "^2.2.0" } }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -5823,13 +7185,15 @@ "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/string-length": { "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", "strip-ansi": "^6.0.0" @@ -5842,6 +7206,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==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5855,6 +7220,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5867,6 +7233,7 @@ "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" } @@ -5876,45 +7243,162 @@ "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" } }, - "node_modules/strip-json-comments": { - "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==", + "node_modules/strip-json-comments": { + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/super-regex": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", + "integrity": "sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==", + "license": "MIT", + "dependencies": { + "clone-regexp": "^3.0.0", + "function-timeout": "^0.1.0", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superagent": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz", + "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==", + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^3.5.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/supertest": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz", + "integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "methods": "^1.1.2", + "superagent": "^8.1.2" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/supertest/node_modules/debug": { + "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" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/supertest/node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "node_modules/super-regex": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", - "integrity": "sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==", + "node_modules/supertest/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, "license": "MIT", - "dependencies": { - "clone-regexp": "^3.0.0", - "function-timeout": "^0.1.0", - "time-span": "^5.1.0" + "bin": { + "mime": "cli.js" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4.0.0" } }, - "node_modules/superagent": { + "node_modules/supertest/node_modules/superagent": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dev": true, + "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", @@ -5931,36 +7415,11 @@ "node": ">=6.4.0 <13 || >=14" } }, - "node_modules/superagent/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/supertest": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz", - "integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "methods": "^1.1.2", - "superagent": "^8.1.2" - }, - "engines": { - "node": ">=6.4.0" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5973,6 +7432,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6002,6 +7462,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, + "license": "MIT", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -6031,6 +7492,7 @@ "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", "glob": "^7.1.4", @@ -6040,15 +7502,61 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "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", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "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" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", - "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", + "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/time-span": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", @@ -6068,13 +7576,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6091,7 +7601,7 @@ "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" }, @@ -6103,32 +7613,29 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true, + "license": "0BSD" }, "node_modules/type-detect": { - "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "license": "MIT", "engines": { "node": ">=4" } @@ -6138,6 +7645,7 @@ "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" }, @@ -6149,6 +7657,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -6157,23 +7666,30 @@ "node": ">= 0.6" } }, + "node_modules/typy": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/typy/-/typy-3.3.0.tgz", + "integrity": "sha512-Du53deMF9X9pSM3gVXDjLBq14BUfZWSGKfmmR1kTlg953RaIZehfc8fQuoAiW+SRO6bJsP+59mv1tsH8vwKghg==" + }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "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": [ { @@ -6189,9 +7705,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -6200,15 +7717,29 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -6231,6 +7762,7 @@ "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", "@types/istanbul-lib-coverage": "^2.0.1", @@ -6244,6 +7776,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6253,30 +7786,45 @@ "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" } }, - "node_modules/webidl-conversions": { - "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, - "engines": { - "node": ">=12" + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "optional": true, + "dependencies": { + "defaults": "^1.0.3" } }, - "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dev": true, + "node_modules/web-encoding": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.1.5.tgz", + "integrity": "sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==", "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" + "util": "^0.12.3" }, - "engines": { - "node": ">=12" + "optionalDependencies": { + "@zxing/text-encoding": "0.9.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, "node_modules/when": { @@ -6291,6 +7839,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -6301,6 +7850,24 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -6310,11 +7877,17 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "license": "Apache-2.0" + }, "node_modules/wrap-ansi": { "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", "string-width": "^4.1.0", @@ -6330,13 +7903,15 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, "node_modules/write-file-atomic": { "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", "signal-exit": "^3.0.7" @@ -6345,11 +7920,39 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -6358,13 +7961,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "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", "escalade": "^3.1.1", @@ -6379,10 +7984,47 @@ } }, "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { "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" } @@ -6392,6 +8034,7 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz", "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" @@ -6404,7 +8047,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 766ec69..0c8ddf4 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,29 @@ "test": "jest --config=jest.config.js" }, "dependencies": { + "@hapi/code": "^9.0.3", + "@hapi/hoek": "^11.0.4", "argon2": "^0.40.3", + "axios": "^1.7.7", "bcrypt": "^5.1.1", "chai-http": "^5.0.0", + "code": "^5.2.4", + "data-forge": "^1.10.2", + "data-forge-fs": "^0.0.9", + "diff": "^7.0.0", "dotenv": "^16.4.5", "express": "^4.17.1", "express-async-handler": "^1.2.0", "google-auth-library": "^9.14.0", "jsonwebtoken": "^9.0.2", + "lodash": "^4.17.21", + "minimatch": "^10.0.1", + "minio": "^8.0.1", + "mkdirp": "^3.0.1", + "mocha": "^10.7.3", "mongoose": "^5.13.22", + "ms": "^2.1.3", + "pg": "^8.13.0", "sinon": "^18.0.0" }, "devDependencies": { diff --git a/utils/dataProcessing.js b/utils/dataProcessing.js new file mode 100644 index 0000000..fba30de --- /dev/null +++ b/utils/dataProcessing.js @@ -0,0 +1,19 @@ +// dataProcessing.js +const dataForge = require('data-forge'); +require('data-forge-fs'); // Required to enable file operations + +// Function to process dataset +const processDataset = (datasetPath) => { + // Read CSV file and parse it into a DataFrame + const dataframe = dataForge.readFileSync(datasetPath).parseCSV(); + + // Apply transformations (example: filter and select specific columns) + const processedData = dataframe + .where(row => parseFloat(row['value']) > 10) // Filter rows where 'value' > 10 + .select(row => ({ name: row['name'], value: parseFloat(row['value']) })) // Select 'name' and 'value' columns + .toArray(); // Convert DataFrame to an array of objects + + return processedData; +}; + +module.exports = { processDataset };