diff --git a/package-lock.json b/package-lock.json
index 04571c006..d5a2e7fdf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -95,7 +95,6 @@
"@types/node": "^8.10.61",
"@types/supertest": "^6.0.2",
"babel-jest": "^29.7.0",
- "baseline-browser-mapping": "^2.10.29",
"eslint": "^8.47.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-base": "^15.0.0",
@@ -3085,9 +3084,9 @@
"license": "MIT"
},
"node_modules/@emnapi/runtime": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
- "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"license": "MIT",
"optional": true,
"dependencies": {
@@ -6522,15 +6521,10 @@
}
},
"node_modules/baseline-browser-mapping": {
- "version": "2.10.29",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz",
- "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==",
+ "version": "2.8.25",
"license": "Apache-2.0",
"bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
- },
- "engines": {
- "node": ">=6.0.0"
+ "baseline-browser-mapping": "dist/cli.js"
}
},
"node_modules/basic-ftp": {
diff --git a/package.json b/package.json
index 34751423a..c7c84088b 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,6 @@
"@types/node": "^8.10.61",
"@types/supertest": "^6.0.2",
"babel-jest": "^29.7.0",
- "baseline-browser-mapping": "^2.10.29",
"eslint": "^8.47.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-base": "^15.0.0",
diff --git a/src/constants/toolUtilization.js b/src/constants/toolUtilization.js
new file mode 100644
index 000000000..f56298be2
--- /dev/null
+++ b/src/constants/toolUtilization.js
@@ -0,0 +1,88 @@
+const UTILIZATION_THRESHOLDS = {
+ UNDER_UTILIZED_MAX: 55,
+ NORMAL_MAX: 85,
+};
+
+const UTILIZATION_LABELS = {
+ UNDER: 'Under-utilized',
+ NORMAL: 'Normal',
+ OVER: 'Over-utilized',
+};
+
+const TRAFFIC_LIGHT = {
+ GREEN: 'green',
+ YELLOW: 'yellow',
+ RED: 'red',
+};
+
+const FORECAST_MODES = {
+ HISTORICAL: 'historical',
+ FORECAST_30: 'forecast30',
+ FORECAST_FULL: 'forecastFull',
+};
+
+const VALID_FORECAST_MODES = Object.values(FORECAST_MODES);
+
+const REPORT_FORMATS = ['pdf', 'csv'];
+
+const MAINTENANCE_TRIGGER_THRESHOLD = 85;
+
+const MINIMUM_WEEKS_FOR_REGRESSION = 3;
+
+const FORECAST_DEFAULT_DAYS = 30;
+
+const HOURS_PER_DAY = 24;
+const DAYS_PER_WEEK = 7;
+const MS_PER_HOUR = 3600000;
+
+const DEGRADED_CONDITIONS = ['Worn', 'Needs Repair', 'Needs Replacing'];
+const NON_OPERATIONAL_STATUSES = ['Under Maintenance', 'Out of Service'];
+
+const CONFIDENCE_THRESHOLDS = {
+ HIGH: 0.7,
+ MEDIUM: 0.4,
+};
+
+const ENSEMBLE_WEIGHTS = {
+ HIGH_R2: { regression: 0.6, ema: 0.4 },
+ MEDIUM_R2: { regression: 0.4, ema: 0.6 },
+ LOW_R2: { regression: 0.2, ema: 0.8 },
+};
+
+const EMA_SMOOTHING_BASE = 2;
+
+const ROUNDING_PRECISION = 10;
+const PDF_MOVE_DOWN_HALF = 0.5;
+
+const PDF_STYLES = {
+ FONT_SIZE_TITLE: 24,
+ FONT_SIZE_METADATA: 10,
+ FONT_SIZE_SECTION_HEADER: 16,
+ FONT_SIZE_BODY: 11,
+ FONT_SIZE_DETAIL: 10,
+ PAGE_BREAK_THRESHOLD: 700,
+ PAGE_MARGIN: 50,
+};
+
+module.exports = {
+ UTILIZATION_THRESHOLDS,
+ UTILIZATION_LABELS,
+ TRAFFIC_LIGHT,
+ FORECAST_MODES,
+ VALID_FORECAST_MODES,
+ REPORT_FORMATS,
+ MAINTENANCE_TRIGGER_THRESHOLD,
+ MINIMUM_WEEKS_FOR_REGRESSION,
+ FORECAST_DEFAULT_DAYS,
+ HOURS_PER_DAY,
+ DAYS_PER_WEEK,
+ MS_PER_HOUR,
+ DEGRADED_CONDITIONS,
+ NON_OPERATIONAL_STATUSES,
+ CONFIDENCE_THRESHOLDS,
+ ENSEMBLE_WEIGHTS,
+ EMA_SMOOTHING_BASE,
+ ROUNDING_PRECISION,
+ PDF_MOVE_DOWN_HALF,
+ PDF_STYLES,
+};
diff --git a/src/controllers/bmdashboard/__tests__/bmNewLessonController.test.js b/src/controllers/bmdashboard/__tests__/bmNewLessonController.test.js
index 0ce794a59..617ca927d 100644
--- a/src/controllers/bmdashboard/__tests__/bmNewLessonController.test.js
+++ b/src/controllers/bmdashboard/__tests__/bmNewLessonController.test.js
@@ -1,5 +1,4 @@
const bmNewLessonController = require('../bmNewLessonController');
-const logger = require('../../../startup/logger');
// Mock dependencies
const mockBuildingNewLesson = {
@@ -12,7 +11,6 @@ const mockBuildingNewLesson = {
updateMany: jest.fn(),
deleteMany: jest.fn(),
getAllTags: jest.fn(),
- aggregate: jest.fn(),
};
const mockBuildingProject = {
@@ -49,7 +47,6 @@ describe('bmNewLessonController', () => {
mockReq = {
body: {},
params: {},
- query: {},
};
mockRes = {
@@ -401,296 +398,6 @@ describe('bmNewLessonController', () => {
});
});
- describe('getLessonsLearnt', () => {
- const VALID_PROJECT_ID = '507f1f77bcf86cd799439011';
- const mockProjectObjId = { toString: () => VALID_PROJECT_ID };
-
- const defaultLessonsInRange = [
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 5 },
- ];
- const defaultThisMonth = [{ _id: mockProjectObjId, thisMonthCount: 3 }];
- const defaultLastMonth = [{ _id: mockProjectObjId, lastMonthCount: 2 }];
-
- beforeEach(() => {
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce(defaultLessonsInRange)
- .mockResolvedValueOnce(defaultThisMonth)
- .mockResolvedValueOnce(defaultLastMonth);
- });
-
- // --- Validation: Issue 1 (invalid projectId) ---
- it('should return 400 for an invalid projectId', async () => {
- mockReq.query = { projectId: 'not-a-valid-objectid' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(400);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Invalid projectId' });
- expect(mockBuildingNewLesson.aggregate).not.toHaveBeenCalled();
- });
-
- it('should not reject projectId=ALL and proceed normally', async () => {
- mockReq.query = { projectId: 'ALL' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(200);
- expect(mockBuildingNewLesson.aggregate).toHaveBeenCalledTimes(3);
- });
-
- it('should not apply a relatedProject filter when projectId=ALL', async () => {
- mockReq.query = { projectId: 'ALL' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- const firstMatchStage = mockBuildingNewLesson.aggregate.mock.calls[0][0][0].$match;
- expect(firstMatchStage.relatedProject).toBeUndefined();
- });
-
- // --- Validation: Issue 3 (invalid dates) ---
- it('should return 400 for an invalid startDate', async () => {
- mockReq.query = { startDate: 'not-a-date' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(400);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Invalid startDate' });
- expect(mockBuildingNewLesson.aggregate).not.toHaveBeenCalled();
- });
-
- it('should return 400 for an invalid endDate', async () => {
- mockReq.query = { endDate: 'not-a-date' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(400);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Invalid endDate' });
- expect(mockBuildingNewLesson.aggregate).not.toHaveBeenCalled();
- });
-
- // --- Happy path: no params ---
- it('should return 200 with lessons grouped by project when no params given', async () => {
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockBuildingNewLesson.aggregate).toHaveBeenCalledTimes(3);
- expect(mockRes.status).toHaveBeenCalledWith(200);
- expect(mockRes.json).toHaveBeenCalledWith({
- data: [
- {
- project: 'Project A',
- projectId: mockProjectObjId,
- lessonsCount: 5,
- changePercentage: '+50.0%',
- },
- ],
- });
- });
-
- it('should return empty data array when no lessons exist', async () => {
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([])
- .mockResolvedValueOnce([])
- .mockResolvedValueOnce([]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(200);
- expect(mockRes.json).toHaveBeenCalledWith({ data: [] });
- });
-
- // --- Filter construction: valid projectId ---
- it('should apply relatedProject filter when a valid projectId is given', async () => {
- mockReq.query = { projectId: VALID_PROJECT_ID };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(200);
- const firstMatchStage = mockBuildingNewLesson.aggregate.mock.calls[0][0][0].$match;
- expect(firstMatchStage.relatedProject).toBeDefined();
- });
-
- // --- Filter construction: date range ---
- it('should apply $gte and $lte date filters when startDate and endDate are given', async () => {
- mockReq.query = { startDate: '2024-01-01', endDate: '2024-12-31' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- const firstMatchStage = mockBuildingNewLesson.aggregate.mock.calls[0][0][0].$match;
- expect(firstMatchStage.date.$gte).toEqual(new Date('2024-01-01'));
- expect(firstMatchStage.date.$lte).toEqual(new Date('2024-12-31'));
- });
-
- it('should apply only $gte when only startDate is given', async () => {
- mockReq.query = { startDate: '2024-01-01' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- const firstMatchStage = mockBuildingNewLesson.aggregate.mock.calls[0][0][0].$match;
- expect(firstMatchStage.date.$gte).toEqual(new Date('2024-01-01'));
- expect(firstMatchStage.date.$lte).toBeUndefined();
- });
-
- it('should apply only $lte when only endDate is given', async () => {
- mockReq.query = { endDate: '2024-12-31' };
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- const firstMatchStage = mockBuildingNewLesson.aggregate.mock.calls[0][0][0].$match;
- expect(firstMatchStage.date.$lte).toEqual(new Date('2024-12-31'));
- expect(firstMatchStage.date.$gte).toBeUndefined();
- });
-
- it('should not apply a date filter when neither startDate nor endDate is given', async () => {
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- const firstMatchStage = mockBuildingNewLesson.aggregate.mock.calls[0][0][0].$match;
- expect(firstMatchStage.date).toBeUndefined();
- });
-
- // --- changePercentage calculation ---
- it('should return +100% when lastMonth is 0 and thisMonth is positive', async () => {
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 3 },
- ])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, thisMonthCount: 3 }])
- .mockResolvedValueOnce([]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalledWith({
- data: [expect.objectContaining({ changePercentage: '+100%' })],
- });
- });
-
- it('should return 0% when both lastMonth and thisMonth are 0', async () => {
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 5 },
- ])
- .mockResolvedValueOnce([])
- .mockResolvedValueOnce([]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalledWith({
- data: [expect.objectContaining({ changePercentage: '0%' })],
- });
- });
-
- it('should return a positive percentage when thisMonth exceeds lastMonth', async () => {
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 6 },
- ])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, thisMonthCount: 6 }])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, lastMonthCount: 4 }]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalledWith({
- data: [expect.objectContaining({ changePercentage: '+50.0%' })],
- });
- });
-
- it('should return a negative percentage when thisMonth is less than lastMonth', async () => {
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 2 },
- ])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, thisMonthCount: 2 }])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, lastMonthCount: 4 }]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalledWith({
- data: [expect.objectContaining({ changePercentage: '-50.0%' })],
- });
- });
-
- it('should return +0.0% when thisMonth equals lastMonth (no change)', async () => {
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 4 },
- ])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, thisMonthCount: 4 }])
- .mockResolvedValueOnce([{ _id: mockProjectObjId, lastMonthCount: 4 }]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalledWith({
- data: [expect.objectContaining({ changePercentage: '+0.0%' })],
- });
- });
-
- it('should correctly compute changePercentage independently for multiple projects', async () => {
- const projectObjId2 = { toString: () => '507f1f77bcf86cd799439012' };
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate
- .mockResolvedValueOnce([
- { project: 'Project A', projectId: mockProjectObjId, lessonsCount: 6 },
- { project: 'Project B', projectId: projectObjId2, lessonsCount: 2 },
- ])
- .mockResolvedValueOnce([
- { _id: mockProjectObjId, thisMonthCount: 6 },
- { _id: projectObjId2, thisMonthCount: 1 },
- ])
- .mockResolvedValueOnce([
- { _id: mockProjectObjId, lastMonthCount: 4 },
- { _id: projectObjId2, lastMonthCount: 2 },
- ]);
- mockReq.query = {};
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- const responseData = mockRes.json.mock.calls[0][0].data;
- expect(responseData).toHaveLength(2);
- expect(responseData[0]).toMatchObject({ project: 'Project A', changePercentage: '+50.0%' });
- expect(responseData[1]).toMatchObject({ project: 'Project B', changePercentage: '-50.0%' });
- });
-
- // --- Error path: Issue 4 (logger) ---
- it('should return 500 and call logger.logException when aggregate throws', async () => {
- const dbError = new Error('Database error');
- mockBuildingNewLesson.aggregate.mockReset();
- mockBuildingNewLesson.aggregate.mockRejectedValue(dbError);
- mockReq.query = { projectId: VALID_PROJECT_ID };
-
- // The controller captures `logger` at module-load time (top-level require), so
- // jest.mock factory cannot intercept it. jest.spyOn mutates the shared cached
- // module object that the controller already holds a reference to.
- const logExceptionSpy = jest
- .spyOn(logger, 'logException')
- .mockReturnValue('mock-tracking-id');
-
- await controller.getLessonsLearnt(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(500);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Internal Server Error' });
- expect(logExceptionSpy).toHaveBeenCalledWith(dbError, 'getLessonsLearnt', {
- query: { projectId: VALID_PROJECT_ID },
- });
-
- logExceptionSpy.mockRestore();
- });
- });
-
describe('getLessonTags', () => {
it('should return unique sorted tags', async () => {
const mockLessons = [
diff --git a/src/controllers/bmdashboard/__tests__/toolUtilizationController.test.js b/src/controllers/bmdashboard/__tests__/toolUtilizationController.test.js
new file mode 100644
index 000000000..a7cd2a44f
--- /dev/null
+++ b/src/controllers/bmdashboard/__tests__/toolUtilizationController.test.js
@@ -0,0 +1,307 @@
+jest.mock('../../../helpers/toolUtilizationHelpers');
+jest.mock('../../../helpers/toolUtilizationReportHelpers');
+jest.mock('../../../startup/logger', () => ({ logException: jest.fn() }));
+
+const {
+ computeUtilizationData,
+ buildUtilizationResponse,
+ generateRecommendations,
+ generateMaintenanceAlerts,
+ generateResourceBalancingSuggestions,
+ buildInsightsSummary,
+ buildReportPayload,
+} = require('../../../helpers/toolUtilizationHelpers');
+const {
+ generatePDFReport,
+ generateCSVReport,
+} = require('../../../helpers/toolUtilizationReportHelpers');
+const toolUtilizationController = require('../toolUtilizationController');
+
+// ─── Shared setup ───
+const mockBuildingTool = {};
+const controller = toolUtilizationController(mockBuildingTool);
+
+const makeReq = (query = {}) => ({ query });
+const makeRes = () => ({
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn(),
+ setHeader: jest.fn(),
+ send: jest.fn(),
+ headersSent: false,
+});
+
+const mockRangeStart = new Date('2026-01-01');
+const mockRangeEnd = new Date('2026-01-31');
+const mockUtilizationData = [
+ {
+ name: 'Drill',
+ utilizationRate: 75,
+ downtime: 180,
+ classification: { label: 'Normal', trafficLight: 'green' },
+ toolCount: 1,
+ toolGroupDetails: { tools: [], purchaseStatuses: [], conditions: [], currentUsages: [] },
+ },
+];
+const mockReportPayload = {
+ utilizationData: mockUtilizationData,
+ alerts: [],
+ balancing: [],
+ recommendations: [],
+ summary: {},
+ metadata: {},
+};
+
+beforeEach(() => {
+ jest.clearAllMocks();
+ computeUtilizationData.mockResolvedValue({
+ utilizationData: mockUtilizationData,
+ rangeStart: mockRangeStart,
+ rangeEnd: mockRangeEnd,
+ });
+ buildUtilizationResponse.mockResolvedValue(mockUtilizationData);
+ generateRecommendations.mockReturnValue([]);
+ generateMaintenanceAlerts.mockReturnValue([]);
+ generateResourceBalancingSuggestions.mockReturnValue([]);
+ buildInsightsSummary.mockReturnValue({
+ totalToolTypes: 1,
+ underUtilized: 0,
+ normal: 1,
+ overUtilized: 0,
+ averageUtilization: 75,
+ });
+ buildReportPayload.mockReturnValue(mockReportPayload);
+});
+
+// ─── getUtilization ───
+describe('getUtilization', () => {
+ it('returns 200 with utilization data when no mode is specified', async () => {
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.getUtilization(req, res);
+
+ expect(computeUtilizationData).toHaveBeenCalledWith(mockBuildingTool, {
+ tool: undefined,
+ project: undefined,
+ startDate: undefined,
+ endDate: undefined,
+ });
+ expect(buildUtilizationResponse).toHaveBeenCalledWith(
+ expect.objectContaining({ selectedMode: 'historical' }),
+ );
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith(mockUtilizationData);
+ });
+
+ it('passes forecast30 mode to buildUtilizationResponse', async () => {
+ const req = makeReq({ mode: 'forecast30' });
+ const res = makeRes();
+
+ await controller.getUtilization(req, res);
+
+ expect(buildUtilizationResponse).toHaveBeenCalledWith(
+ expect.objectContaining({ selectedMode: 'forecast30' }),
+ );
+ expect(res.status).toHaveBeenCalledWith(200);
+ });
+
+ it('returns 400 when mode is invalid', async () => {
+ const req = makeReq({ mode: 'badMode' });
+ const res = makeRes();
+
+ await controller.getUtilization(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('Invalid mode') }),
+ );
+ });
+
+ it('returns 400 when startDate is after endDate', async () => {
+ const req = makeReq({ startDate: '2026-01-31', endDate: '2026-01-01' });
+ const res = makeRes();
+
+ await controller.getUtilization(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('startDate') }),
+ );
+ expect(computeUtilizationData).not.toHaveBeenCalled();
+ });
+
+ it('returns 500 when computeUtilizationData throws', async () => {
+ computeUtilizationData.mockRejectedValue(new Error('DB failure'));
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.getUtilization(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(500);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('DB failure') }),
+ );
+ });
+
+ it('returns 500 when buildUtilizationResponse throws', async () => {
+ buildUtilizationResponse.mockRejectedValue(new Error('Response build failed'));
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.getUtilization(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(500);
+ });
+});
+
+// ─── getInsights ───
+describe('getInsights', () => {
+ it('returns 200 with all insight sections', async () => {
+ const recommendations = [{ toolName: 'Drill', action: 'Plan maintenance.' }];
+ const alerts = [{ toolName: 'Drill', alertType: 'overuse', message: 'High.', urgency: 'high' }];
+ const balancing = [{ suggestion: 'Redistribute.', fromTool: 'Drill', toTool: 'Shovel' }];
+ const summary = {
+ totalToolTypes: 1,
+ underUtilized: 0,
+ normal: 0,
+ overUtilized: 1,
+ averageUtilization: 90,
+ };
+
+ generateRecommendations.mockReturnValue(recommendations);
+ generateMaintenanceAlerts.mockReturnValue(alerts);
+ generateResourceBalancingSuggestions.mockReturnValue(balancing);
+ buildInsightsSummary.mockReturnValue(summary);
+
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.getInsights(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith({
+ recommendations,
+ maintenanceAlerts: alerts,
+ resourceBalancing: balancing,
+ summary,
+ });
+ });
+
+ it('calls all insight helpers with utilizationData from computeUtilizationData', async () => {
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.getInsights(req, res);
+
+ expect(generateRecommendations).toHaveBeenCalledWith(mockUtilizationData);
+ expect(generateMaintenanceAlerts).toHaveBeenCalledWith(mockUtilizationData);
+ expect(generateResourceBalancingSuggestions).toHaveBeenCalledWith(mockUtilizationData);
+ expect(buildInsightsSummary).toHaveBeenCalledWith(mockUtilizationData);
+ });
+
+ it('returns 400 when startDate is after endDate', async () => {
+ const req = makeReq({ startDate: '2026-01-31', endDate: '2026-01-01' });
+ const res = makeRes();
+
+ await controller.getInsights(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('startDate') }),
+ );
+ expect(computeUtilizationData).not.toHaveBeenCalled();
+ });
+
+ it('returns 500 when computeUtilizationData throws', async () => {
+ computeUtilizationData.mockRejectedValue(new Error('DB error'));
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.getInsights(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(500);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('DB error') }),
+ );
+ });
+});
+
+// ─── exportReport ───
+describe('exportReport', () => {
+ it('returns 400 when format param is missing', async () => {
+ const req = makeReq({});
+ const res = makeRes();
+
+ await controller.exportReport(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('Invalid format') }),
+ );
+ });
+
+ it('returns 400 when format is not pdf or csv', async () => {
+ const req = makeReq({ format: 'xlsx' });
+ const res = makeRes();
+
+ await controller.exportReport(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ });
+
+ it('returns 400 when startDate is after endDate', async () => {
+ const req = makeReq({ format: 'csv', startDate: '2026-01-31', endDate: '2026-01-01' });
+ const res = makeRes();
+
+ await controller.exportReport(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('startDate') }),
+ );
+ expect(computeUtilizationData).not.toHaveBeenCalled();
+ });
+
+ it('calls generateCSVReport for csv format', async () => {
+ const req = makeReq({ format: 'csv' });
+ const res = makeRes();
+
+ await controller.exportReport(req, res);
+
+ expect(generateCSVReport).toHaveBeenCalledWith(res, mockReportPayload);
+ expect(generatePDFReport).not.toHaveBeenCalled();
+ });
+
+ it('calls generatePDFReport for pdf format', async () => {
+ const req = makeReq({ format: 'pdf' });
+ const res = makeRes();
+
+ await controller.exportReport(req, res);
+
+ expect(generatePDFReport).toHaveBeenCalledWith(res, mockReportPayload);
+ expect(generateCSVReport).not.toHaveBeenCalled();
+ });
+
+ it('returns 500 when error occurs and headers are not yet sent', async () => {
+ computeUtilizationData.mockRejectedValue(new Error('Export failed'));
+ const req = makeReq({ format: 'csv' });
+ const res = { ...makeRes(), headersSent: false };
+
+ await controller.exportReport(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(500);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ error: expect.stringContaining('Export failed') }),
+ );
+ });
+
+ it('does not send error response when headers are already sent', async () => {
+ computeUtilizationData.mockRejectedValue(new Error('Stream error'));
+ const req = makeReq({ format: 'csv' });
+ const res = { ...makeRes(), headersSent: true };
+
+ await controller.exportReport(req, res);
+
+ expect(res.status).not.toHaveBeenCalled();
+ });
+});
diff --git a/src/controllers/bmdashboard/bmNewLessonController.js b/src/controllers/bmdashboard/bmNewLessonController.js
index bb304481a..6704805f1 100644
--- a/src/controllers/bmdashboard/bmNewLessonController.js
+++ b/src/controllers/bmdashboard/bmNewLessonController.js
@@ -1,29 +1,6 @@
/* eslint-disable no-unused-vars */
const mongoose = require('mongoose');
-const logger = require('../../startup/logger');
-/** Builds a MongoDB filter fragment for projectId. Returns {} for 'ALL' or absent value. */
-const buildProjectIdFilter = (projectId) => {
- if (!projectId || projectId === 'ALL') return {};
- return { relatedProject: new mongoose.Types.ObjectId(projectId) };
-};
-
-/** Returns month-over-month change as a signed percentage string (e.g. '+50.0%', '-25.0%'). */
-const calculateChangePercentage = (thisMonth, lastMonth) => {
- if (lastMonth === 0 && thisMonth > 0) return '+100%';
- if (lastMonth > 0) {
- const change = ((thisMonth - lastMonth) / lastMonth) * 100;
- return `${change >= 0 ? '+' : ''}${change.toFixed(1)}%`;
- }
- return '0%';
-};
-
-// Named constants for end-of-day time components used in month boundary Date construction
-const END_HOUR = 23;
-const END_MINUTE = 59;
-const END_SECOND = 59;
-
-// eslint-disable-next-line max-lines-per-function
const bmNewLessonController = function (BuildingNewLesson) {
const buildingProject = require('../../models/bmdashboard/buildingProject');
const Like = require('../../models/bmdashboard/buldingLessonLike');
@@ -58,7 +35,7 @@ const bmNewLessonController = function (BuildingNewLesson) {
res.json(lesson);
} catch (error) {
- logger.logException(error, 'bmGetSingleLesson', { lessonId });
+ console.error(`Error fetching lesson with ID ${lessonId}:`, error);
res.status(500).json({ error: 'Internal Server Error' });
}
};
@@ -98,7 +75,7 @@ const bmNewLessonController = function (BuildingNewLesson) {
res.json(updatedLesson);
} catch (error) {
- logger.logException(error, 'bmEditSingleLesson', { lessonId });
+ console.error(`Error updating lesson with ID ${req.params.lessonId}:`, error);
res.status(500).json({ error: 'Internal Server Error' });
}
};
@@ -130,7 +107,7 @@ const bmNewLessonController = function (BuildingNewLesson) {
res.json({ message: 'Lesson deleted successfully', deletedLesson });
} catch (error) {
- logger.logException(error, 'bmDeleteSingleLesson', { lessonId });
+ console.error(`Error removing lesson with ID ${lessonId}:`, error);
res.status(500).json({ error: 'Internal Server Error' });
}
};
@@ -159,7 +136,7 @@ const bmNewLessonController = function (BuildingNewLesson) {
const tags = await BuildingNewLesson.getAllTags();
return res.status(201).json(tags);
} catch (error) {
- logger.logException(error, 'addNewTag', { tag: req.body.tag });
+ console.error('Tag creation error:', error);
return res.status(500).json({
error: 'Error adding new tag',
details: error.message,
@@ -187,7 +164,7 @@ const bmNewLessonController = function (BuildingNewLesson) {
const remainingTags = await BuildingNewLesson.getAllTags();
return res.status(200).json(remainingTags);
} catch (error) {
- logger.logException(error, 'deleteTag', { tag: req.params.tag });
+ console.error('Delete tag error:', error);
return res.status(500).json({
error: 'Error deleting tag',
details: error.message,
@@ -224,7 +201,7 @@ const bmNewLessonController = function (BuildingNewLesson) {
return res.status(200).json({ status: 'success', message: 'Lesson liked successfully' });
} catch (error) {
- logger.logException(error, 'likeLesson', { lessonId, userId });
+ console.error('Error liking/unliking lesson:', error);
return res.status(500).json({ status: 'error', message: 'Error liking/unliking lesson' });
}
};
@@ -242,26 +219,25 @@ const bmNewLessonController = function (BuildingNewLesson) {
try {
const { projectId, startDate, endDate } = req.query;
- if (projectId && projectId !== 'ALL' && !mongoose.Types.ObjectId.isValid(projectId)) {
- return res.status(400).json({ error: 'Invalid projectId' });
+ const filter = {};
+ if (projectId && projectId !== 'ALL') {
+ filter.relatedProject = new mongoose.Types.ObjectId(projectId);
}
- if (startDate && Number.isNaN(Date.parse(startDate))) {
- return res.status(400).json({ error: 'Invalid startDate' });
- }
- if (endDate && Number.isNaN(Date.parse(endDate))) {
- return res.status(400).json({ error: 'Invalid endDate' });
- }
-
- const filter = { ...buildProjectIdFilter(projectId) };
if (startDate || endDate) {
filter.date = {};
if (startDate) filter.date.$gte = new Date(startDate);
if (endDate) filter.date.$lte = new Date(endDate);
}
+ // Current Period
const lessonsInRange = await BuildingNewLesson.aggregate([
{ $match: filter },
- { $group: { _id: '$relatedProject', lessonsCount: { $sum: 1 } } },
+ {
+ $group: {
+ _id: '$relatedProject',
+ lessonsCount: { $sum: 1 },
+ },
+ },
{
$lookup: {
from: 'buildingProjects',
@@ -280,57 +256,92 @@ const bmNewLessonController = function (BuildingNewLesson) {
},
]);
- const now = endDate ? new Date(endDate) : new Date();
- const year = now.getFullYear();
- const month = now.getMonth();
- const projectFilter = buildProjectIdFilter(projectId);
+ // This Month
+ let now = new Date();
+ if (endDate) {
+ now = new Date(endDate);
+ }
+ const thisMonthStart = new Date(now.getFullYear(), now.getMonth(), 1);
+ const thisMonthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59);
+
+ const thisMonthFilter = {
+ ...(projectId &&
+ projectId !== 'ALL' &&
+ mongoose.Types.ObjectId.isValid(projectId) && {
+ relatedProject: new mongoose.Types.ObjectId(String(projectId)),
+ }),
+ date: { $gte: thisMonthStart, $lte: thisMonthEnd },
+ };
const thisMonthLessons = await BuildingNewLesson.aggregate([
+ { $match: thisMonthFilter },
{
- $match: {
- ...projectFilter,
- date: {
- $gte: new Date(year, month, 1),
- $lte: new Date(year, month + 1, 0, END_HOUR, END_MINUTE, END_SECOND),
- },
+ $group: {
+ _id: '$relatedProject',
+ thisMonthCount: { $sum: 1 },
},
},
- { $group: { _id: '$relatedProject', thisMonthCount: { $sum: 1 } } },
]);
+ // Last Month
+ const lastMonthStart = new Date(now.getFullYear(), now.getMonth() - 1, 1);
+ const lastMonthEnd = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59);
+
+ const lastMonthFilter = {
+ ...(projectId &&
+ projectId !== 'ALL' &&
+ mongoose.Types.ObjectId.isValid(projectId) && {
+ relatedProject: new mongoose.Types.ObjectId(String(projectId)),
+ }),
+ date: { $gte: lastMonthStart, $lte: lastMonthEnd },
+ };
+
const lastMonthLessons = await BuildingNewLesson.aggregate([
+ { $match: lastMonthFilter },
{
- $match: {
- ...projectFilter,
- date: {
- $gte: new Date(year, month - 1, 1),
- $lte: new Date(year, month, 0, END_HOUR, END_MINUTE, END_SECOND),
- },
+ $group: {
+ _id: '$relatedProject',
+ lastMonthCount: { $sum: 1 },
},
},
- { $group: { _id: '$relatedProject', lastMonthCount: { $sum: 1 } } },
]);
- const thisMonthMap = Object.fromEntries(
- thisMonthLessons.map((e) => [e._id.toString(), e.thisMonthCount]),
- );
- const lastMonthMap = Object.fromEntries(
- lastMonthLessons.map((e) => [e._id.toString(), e.lastMonthCount]),
- );
+ // Mapping this month and last month counts
+ const thisMonthMap = {};
+ thisMonthLessons.forEach((entry) => {
+ thisMonthMap[entry._id.toString()] = entry.thisMonthCount;
+ });
+ const lastMonthMap = {};
+ lastMonthLessons.forEach((entry) => {
+ lastMonthMap[entry._id.toString()] = entry.lastMonthCount;
+ });
+ // console.log(lastMonthMap, thisMonthMap)
+
+ // Build final result
const result = lessonsInRange.map((entry) => {
- const id = entry.projectId.toString();
+ const projectIdStr = entry.projectId.toString();
+ const thisMonth = thisMonthMap[projectIdStr] || 0;
+ const lastMonth = lastMonthMap[projectIdStr] || 0;
+ let changePercentage = '0%';
+ if (lastMonth === 0 && thisMonth > 0) {
+ changePercentage = '+100%';
+ } else if (lastMonth > 0) {
+ const change = ((thisMonth - lastMonth) / lastMonth) * 100;
+ changePercentage = `${change >= 0 ? '+' : ''}${change.toFixed(1)}%`;
+ }
+
return {
project: entry.project,
projectId: entry.projectId,
lessonsCount: entry.lessonsCount,
- changePercentage: calculateChangePercentage(thisMonthMap[id] || 0, lastMonthMap[id] || 0),
+ changePercentage,
};
});
res.status(200).json({ data: result });
} catch (err) {
- logger.logException(err, 'getLessonsLearnt', { query: req.query });
+ console.error('Error fetching lessons learnt:', err);
res.status(500).json({ error: 'Internal Server Error' });
}
};
diff --git a/src/controllers/bmdashboard/toolUtilizationController.js b/src/controllers/bmdashboard/toolUtilizationController.js
index 93dea939e..6378632d5 100644
--- a/src/controllers/bmdashboard/toolUtilizationController.js
+++ b/src/controllers/bmdashboard/toolUtilizationController.js
@@ -1,174 +1,126 @@
-const mongoose = require('mongoose');
-
-const toolUtilizationController = (BuildingTool) => {
- // Shared helper: compute utilization data for a given set of tools and date range
- const computeUtilizationForRange = (tools, rangeStart, rangeEnd) => {
- const totalHours = (rangeEnd - rangeStart) / (1000 * 60 * 60);
-
- // Group tools by itemType
- const toolGroups = {};
- tools.forEach((toolItem) => {
- if (!toolItem.itemType) return;
- const toolName = toolItem.itemType.name || 'Unknown Tool';
- const toolTypeId = toolItem.itemType._id.toString();
- if (!toolGroups[toolTypeId]) {
- toolGroups[toolTypeId] = { name: toolName, tools: [] };
- }
- toolGroups[toolTypeId].tools.push(toolItem);
- });
-
- // Calculate utilization per tool group
- const utilizationData = Object.values(toolGroups).map((group) => {
- let totalCheckedOutHours = 0;
- let totalDowntimeHours = 0;
- let toolCount = 0;
-
- group.tools.forEach((toolItem) => {
- toolCount += 1;
+const logger = require('../../startup/logger');
+const {
+ FORECAST_MODES,
+ VALID_FORECAST_MODES,
+ REPORT_FORMATS,
+} = require('../../constants/toolUtilization');
+const {
+ computeUtilizationData,
+ buildUtilizationResponse,
+ generateRecommendations,
+ generateMaintenanceAlerts,
+ generateResourceBalancingSuggestions,
+ buildInsightsSummary,
+ buildReportPayload,
+} = require('../../helpers/toolUtilizationHelpers');
+const {
+ generatePDFReport,
+ generateCSVReport,
+} = require('../../helpers/toolUtilizationReportHelpers');
+
+const toolUtilizationController = function (BuildingTool) {
+ const getUtilization = async (req, res) => {
+ try {
+ const { tool, project, startDate, endDate, mode } = req.query;
+ const selectedMode = mode || FORECAST_MODES.HISTORICAL;
- const relevantLogs = (toolItem.logRecord || []).filter((log) => {
- const logDate = new Date(log.date);
- return logDate >= rangeStart && logDate <= rangeEnd;
+ if (mode && !VALID_FORECAST_MODES.includes(selectedMode)) {
+ return res.status(400).json({
+ error: `Invalid mode. Must be one of: ${VALID_FORECAST_MODES.join(', ')}`,
});
+ }
- relevantLogs.sort((a, b) => new Date(a.date) - new Date(b.date));
-
- let checkedOutTime = 0;
- let lastCheckOut = null;
-
- relevantLogs.forEach((log) => {
- if (log.type === 'Check Out') {
- lastCheckOut = new Date(log.date);
- } else if (log.type === 'Check In' && lastCheckOut) {
- const checkInTime = new Date(log.date);
- const hoursCheckedOut = (checkInTime - lastCheckOut) / (1000 * 60 * 60);
- checkedOutTime += Math.max(0, hoursCheckedOut);
- lastCheckOut = null;
- }
- });
+ if (startDate && endDate && new Date(startDate) > new Date(endDate)) {
+ return res.status(400).json({ error: 'startDate cannot be after endDate.' });
+ }
- if (lastCheckOut) {
- const hoursCheckedOut = (rangeEnd - lastCheckOut) / (1000 * 60 * 60);
- checkedOutTime += Math.max(0, hoursCheckedOut);
- }
-
- if (relevantLogs.length === 0 && toolItem.logRecord && toolItem.logRecord.length > 0) {
- const sortedAllLogs = [...toolItem.logRecord].sort(
- (a, b) => new Date(b.date) - new Date(a.date),
- );
- const lastLog = sortedAllLogs[0];
- if (lastLog && lastLog.type === 'Check Out') {
- const lastCheckOutDate = new Date(lastLog.date);
- if (lastCheckOutDate < rangeStart) {
- checkedOutTime = totalHours;
- }
- }
- }
-
- totalCheckedOutHours += checkedOutTime;
+ const { utilizationData, rangeStart, rangeEnd } = await computeUtilizationData(BuildingTool, {
+ tool,
+ project,
+ startDate,
+ endDate,
});
- totalDowntimeHours = totalHours * toolCount - totalCheckedOutHours;
+ const responseData = await buildUtilizationResponse({
+ utilizationData,
+ rangeStart,
+ rangeEnd,
+ selectedMode,
+ project,
+ });
- const totalPossibleHours = totalHours * toolCount;
- const utilizationRate =
- totalPossibleHours > 0 ? Math.round((totalCheckedOutHours / totalPossibleHours) * 100) : 0;
+ return res.status(200).json(responseData);
+ } catch (err) {
+ logger.logException(err, 'toolUtilizationController.getUtilization');
+ return res.status(500).json({ error: `Server error: ${err.message}` });
+ }
+ };
- return {
- name: group.name,
- utilizationRate,
- downtime: Math.round(totalDowntimeHours * 10) / 10,
- count: toolCount,
- };
- });
+ const getInsights = async (req, res) => {
+ try {
+ const { startDate, endDate } = req.query;
+ if (startDate && endDate && new Date(startDate) > new Date(endDate)) {
+ return res.status(400).json({ error: 'startDate cannot be after endDate.' });
+ }
- utilizationData.sort((a, b) => b.utilizationRate - a.utilizationRate);
- return utilizationData;
- };
+ const { utilizationData } = await computeUtilizationData(BuildingTool, req.query);
- // Split a date range into N weekly buckets
- const buildWeeklyBuckets = (rangeStart, rangeEnd, numWeeks = 4) => {
- const buckets = [];
- for (let i = 0; i < numWeeks; i += 1) {
- const bucketStart = new Date(rangeEnd);
- bucketStart.setDate(rangeEnd.getDate() - (numWeeks - i) * 7);
- const bucketEnd = new Date(rangeEnd);
- bucketEnd.setDate(rangeEnd.getDate() - (numWeeks - i - 1) * 7);
- const label = `Week of ${bucketStart.toLocaleDateString('en-US', {
- month: 'short',
- day: 'numeric',
- })}`;
- buckets.push({ label, start: bucketStart, end: bucketEnd });
+ return res.status(200).json({
+ recommendations: generateRecommendations(utilizationData),
+ maintenanceAlerts: generateMaintenanceAlerts(utilizationData),
+ resourceBalancing: generateResourceBalancingSuggestions(utilizationData),
+ summary: buildInsightsSummary(utilizationData),
+ });
+ } catch (err) {
+ logger.logException(err, 'toolUtilizationController.getInsights');
+ return res.status(500).json({ error: `Server error: ${err.message}` });
}
- return buckets;
};
- const getUtilization = async (req, res) => {
+ const exportReport = async (req, res) => {
try {
- const { tool, project, startDate, endDate, groupBy } = req.query;
-
- // Build filter for tools
- const toolFilter = {};
+ const { format, startDate, endDate } = req.query;
- if (tool && tool !== 'ALL') {
- if (mongoose.Types.ObjectId.isValid(tool)) {
- toolFilter.itemType = mongoose.Types.ObjectId(tool);
- }
+ if (startDate && endDate && new Date(startDate) > new Date(endDate)) {
+ return res.status(400).json({ error: 'startDate cannot be after endDate.' });
}
- if (project && project !== 'ALL') {
- if (mongoose.Types.ObjectId.isValid(project)) {
- toolFilter.project = mongoose.Types.ObjectId(project);
- }
- }
-
- // Fetch all matching tools once
- const tools = await BuildingTool.find({
- ...toolFilter,
- __t: 'tool_item',
- })
- .populate('itemType', 'name')
- .populate('project', 'name')
- .lean();
-
- // Resolve date range
- const defaultEnd = new Date();
- const defaultStart = new Date();
- defaultStart.setDate(defaultStart.getDate() - 30);
-
- const rangeStart = startDate ? new Date(startDate) : defaultStart;
- const rangeEnd = endDate ? new Date(endDate) : defaultEnd;
-
- // --- groupBy=week: return weekly bucketed avg utilization ---
- if (groupBy === 'week') {
- const buckets = buildWeeklyBuckets(rangeStart, rangeEnd, 4);
-
- const weeklyData = buckets.map(({ label, start, end }) => {
- const utilizationData = computeUtilizationForRange(tools, start, end);
- const avgUtilization =
- utilizationData.length > 0
- ? Math.round(
- (utilizationData.reduce((sum, t) => sum + t.utilizationRate, 0) /
- utilizationData.length) *
- 10,
- ) / 10
- : 0;
- return { week: label, avgUtilization };
+ if (!format || !REPORT_FORMATS.includes(format)) {
+ return res.status(400).json({
+ error: `Invalid format. Must be one of: ${REPORT_FORMATS.join(', ')}`,
});
-
- return res.status(200).json(weeklyData);
}
- // --- Default: return per-tool utilization ---
- const utilizationData = computeUtilizationForRange(tools, rangeStart, rangeEnd);
- return res.status(200).json(utilizationData);
+ const { utilizationData, rangeStart, rangeEnd } = await computeUtilizationData(
+ BuildingTool,
+ req.query,
+ );
+ const reportPayload = buildReportPayload(
+ utilizationData,
+ rangeStart,
+ rangeEnd,
+ req.query.project,
+ );
+
+ if (format === 'pdf') {
+ generatePDFReport(res, reportPayload);
+ } else {
+ generateCSVReport(res, reportPayload);
+ }
} catch (err) {
- console.error('Error calculating tool utilization:', err);
- res.status(500).json({ error: `Server error: ${err.message}` });
+ logger.logException(err, 'toolUtilizationController.exportReport');
+ if (!res.headersSent) {
+ return res.status(500).json({ error: `Server error: ${err.message}` });
+ }
}
+ return undefined;
};
- return { getUtilization };
+ return {
+ getUtilization,
+ getInsights,
+ exportReport,
+ };
};
module.exports = toolUtilizationController;
diff --git a/src/controllers/studentTaskController.js b/src/controllers/studentTaskController.js
index f4e3803ac..d23ecc3d7 100644
--- a/src/controllers/studentTaskController.js
+++ b/src/controllers/studentTaskController.js
@@ -366,78 +366,10 @@ const studentTaskController = function () {
}
};
- /**
- * POST /student/tasks/:taskId/log-hours
- * Increments loggedHours for a task, capped at suggestedTotalHours.
- * Returns updated loggedHours and a canMarkDone eligibility flag.
- */
- const logHours = async (req, res) => {
- try {
- const { taskId } = req.params;
- const studentId = req.body.requestor?.requestorId;
-
- if (!taskId || !mongoose.Types.ObjectId.isValid(taskId)) {
- return res.status(400).json({ error: 'Invalid Task ID' });
- }
- if (!studentId || !mongoose.Types.ObjectId.isValid(studentId)) {
- return res.status(400).json({ error: 'Invalid Student ID' });
- }
-
- const hours = Number(req.body.hours);
- if (!Number.isFinite(hours) || hours <= 0) {
- return res.status(400).json({ error: 'hours must be a positive number' });
- }
-
- const task = await EducationTask.findOne({
- _id: mongoose.Types.ObjectId(taskId),
- studentId: mongoose.Types.ObjectId(studentId),
- });
-
- if (!task) {
- return res.status(404).json({ error: 'Task not found or does not belong to you' });
- }
-
- if (task.status === 'completed' || task.status === 'graded') {
- return res.status(400).json({ error: 'Cannot log hours for a completed task' });
- }
-
- const cap = task.suggestedTotalHours > 0 ? task.suggestedTotalHours : Infinity;
- const newLoggedHours = Math.min(task.loggedHours + hours, cap);
-
- const newStatus =
- task.status === 'assigned' && newLoggedHours > 0 ? 'in_progress' : task.status;
-
- const updated = await EducationTask.findOneAndUpdate(
- { _id: mongoose.Types.ObjectId(taskId) },
- { $set: { loggedHours: newLoggedHours, status: newStatus } },
- { new: true, runValidators: false },
- );
-
- if (!updated) {
- return res.status(404).json({ error: 'Task not found during update' });
- }
-
- const canMarkDone =
- updated.suggestedTotalHours > 0 && updated.loggedHours >= updated.suggestedTotalHours;
-
- return res.status(200).json({
- message: 'Hours logged successfully',
- loggedHours: updated.loggedHours,
- suggestedTotalHours: updated.suggestedTotalHours,
- status: updated.status,
- canMarkDone,
- });
- } catch (error) {
- console.error('Error logging hours:', error);
- return res.status(500).json({ error: 'Internal server error' });
- }
- };
-
return {
getStudentTasks,
updateTaskProgress,
uploadFile,
- logHours,
};
};
diff --git a/src/controllers/studentTaskController.spec.js b/src/controllers/studentTaskController.spec.js
deleted file mode 100644
index d6ca7408b..000000000
--- a/src/controllers/studentTaskController.spec.js
+++ /dev/null
@@ -1,166 +0,0 @@
-const EducationTask = require('../models/educationTask');
-const { mockReq, mockRes } = require('../test');
-const studentTaskController = require('./studentTaskController');
-
-const VALID_TASK_ID = '507f1f77bcf86cd799439011';
-const VALID_STUDENT_ID = '65cf6c3706d8ac105827bb2e';
-
-// Shared helpers to reduce repetition
-const makeTask = (overrides = {}) => ({
- status: 'assigned',
- loggedHours: 0,
- suggestedTotalHours: 5,
- ...overrides,
-});
-
-const makeUpdated = (overrides = {}) => ({
- loggedHours: 1,
- suggestedTotalHours: 5,
- status: 'in_progress',
- ...overrides,
-});
-
-const spyFindOne = (result) => jest.spyOn(EducationTask, 'findOne').mockResolvedValueOnce(result);
-const spyFindOneAndUpdate = (result) =>
- jest.spyOn(EducationTask, 'findOneAndUpdate').mockResolvedValueOnce(result);
-
-describe('studentTaskController - logHours', () => {
- let logHours;
-
- beforeEach(() => {
- logHours = studentTaskController().logHours;
- mockReq.params.taskId = VALID_TASK_ID;
- mockReq.body.requestor = { requestorId: VALID_STUDENT_ID };
- mockReq.body.hours = 1;
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
- describe('Input validation', () => {
- test.each([
- ['taskId is missing', { params: { taskId: '' } }, 400, { error: 'Invalid Task ID' }],
- [
- 'taskId is not a valid ObjectId',
- { params: { taskId: 'bad-id' } },
- 400,
- { error: 'Invalid Task ID' },
- ],
- [
- 'studentId is missing',
- { body: { requestor: {}, hours: 1 } },
- 400,
- { error: 'Invalid Student ID' },
- ],
- [
- 'studentId is not a valid ObjectId',
- { body: { requestor: { requestorId: 'bad' }, hours: 1 } },
- 400,
- { error: 'Invalid Student ID' },
- ],
- [
- 'hours is zero',
- { body: { requestor: { requestorId: VALID_STUDENT_ID }, hours: 0 } },
- 400,
- { error: 'hours must be a positive number' },
- ],
- [
- 'hours is negative',
- { body: { requestor: { requestorId: VALID_STUDENT_ID }, hours: -1 } },
- 400,
- { error: 'hours must be a positive number' },
- ],
- [
- 'hours is not a number',
- { body: { requestor: { requestorId: VALID_STUDENT_ID }, hours: 'abc' } },
- 400,
- { error: 'hours must be a positive number' },
- ],
- ])('Returns %i when %s', async (_, reqOverrides, expectedStatus, expectedBody) => {
- Object.assign(mockReq, reqOverrides);
- if (reqOverrides.params) Object.assign(mockReq.params, reqOverrides.params);
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(expectedStatus);
- expect(mockRes.json).toHaveBeenCalledWith(expectedBody);
- });
- });
-
- describe('Database interactions', () => {
- test('Returns 404 if task is not found', async () => {
- spyFindOne(null);
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(404);
- expect(mockRes.json).toHaveBeenCalledWith({
- error: 'Task not found or does not belong to you',
- });
- });
-
- test.each([
- ['completed', makeTask({ status: 'completed', loggedHours: 3 })],
- ['graded', makeTask({ status: 'graded', loggedHours: 5 })],
- ])('Returns 400 if task status is %s', async (_, task) => {
- spyFindOne(task);
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(400);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Cannot log hours for a completed task' });
- });
-
- test('Returns 200 and transitions assigned -> in_progress on first log', async () => {
- spyFindOne(makeTask());
- spyFindOneAndUpdate(makeUpdated());
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(200);
- expect(mockRes.json).toHaveBeenCalledWith({
- message: 'Hours logged successfully',
- loggedHours: 1,
- suggestedTotalHours: 5,
- status: 'in_progress',
- canMarkDone: false,
- });
- });
-
- test('Returns 200 and caps loggedHours at suggestedTotalHours', async () => {
- mockReq.body.hours = 3;
- spyFindOne(makeTask({ status: 'in_progress', loggedHours: 4 }));
- spyFindOneAndUpdate(makeUpdated({ loggedHours: 5 }));
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(200);
- expect(mockRes.json).toHaveBeenCalledWith({
- message: 'Hours logged successfully',
- loggedHours: 5,
- suggestedTotalHours: 5,
- status: 'in_progress',
- canMarkDone: true,
- });
- expect(EducationTask.findOneAndUpdate).toHaveBeenCalledWith(
- expect.any(Object),
- { $set: { loggedHours: 5, status: 'in_progress' } },
- { new: true, runValidators: false },
- );
- });
-
- test('Returns 404 if findOneAndUpdate returns null', async () => {
- spyFindOne(makeTask());
- spyFindOneAndUpdate(null);
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(404);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Task not found during update' });
- });
-
- test('Returns 200 with canMarkDone false when suggestedTotalHours is 0', async () => {
- spyFindOne(makeTask({ suggestedTotalHours: 0 }));
- spyFindOneAndUpdate(makeUpdated({ suggestedTotalHours: 0 }));
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(200);
- expect(mockRes.json).toHaveBeenCalledWith(expect.objectContaining({ canMarkDone: false }));
- });
-
- test('Returns 500 if findOne throws an error', async () => {
- spyFindOne(Promise.reject(new Error('DB error')));
- await logHours(mockReq, mockRes);
- expect(mockRes.status).toHaveBeenCalledWith(500);
- expect(mockRes.json).toHaveBeenCalledWith({ error: 'Internal server error' });
- });
- });
-});
diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js
index 6db0d6f36..16b1ba46f 100644
--- a/src/controllers/userProfileController.js
+++ b/src/controllers/userProfileController.js
@@ -2089,8 +2089,6 @@ const createControllerMethods = function (UserProfile, Project, cache) {
if (userIdx !== -1) {
const userData = allUserData[userIdx];
userData.isActive = user.isActive;
- userData.reactivationDate = null;
- userData.endDate = null;
allUserData.splice(userIdx, 1, userData);
cache.setCache('allusers', JSON.stringify(allUserData));
}
diff --git a/src/helpers/__tests__/toolUtilizationHelpers.test.js b/src/helpers/__tests__/toolUtilizationHelpers.test.js
new file mode 100644
index 000000000..dc7baa86d
--- /dev/null
+++ b/src/helpers/__tests__/toolUtilizationHelpers.test.js
@@ -0,0 +1,872 @@
+jest.mock('mongoose', () => ({
+ Types: {
+ ObjectId: Object.assign(
+ jest.fn((id) => id),
+ {
+ isValid: jest.fn(),
+ },
+ ),
+ },
+}));
+
+jest.mock('regression', () => ({ linear: jest.fn() }));
+
+jest.mock('../../models/bmdashboard/projectRiskProfile', () => ({ findOne: jest.fn() }));
+
+const mockCache = { hasCache: jest.fn(), getCache: jest.fn(), setCache: jest.fn() };
+jest.mock('../../utilities/nodeCache', () => jest.fn(() => mockCache));
+
+const mongoose = require('mongoose');
+const regression = require('regression');
+const ProjectRiskProfile = require('../../models/bmdashboard/projectRiskProfile');
+const cache = require('../../utilities/nodeCache')();
+const {
+ classifyUtilization,
+ calculateCheckedOutHours,
+ buildToolFilter,
+ parseDateRange,
+ groupToolsByType,
+ calculateGroupUtilization,
+ buildCacheKey,
+ computeUtilizationData,
+ bucketUtilizationByWeek,
+ forecastUtilization,
+ generateMaintenanceAlerts,
+ generateResourceBalancingSuggestions,
+ generateRecommendations,
+ stripInternalDetails,
+ buildInsightsSummary,
+ determineForecastDays,
+ buildUtilizationResponse,
+ buildReportPayload,
+} = require('../toolUtilizationHelpers');
+
+// ─── Shared fixtures ───
+const makeLog = (type, dateStr) => ({ type, date: new Date(dateStr) });
+
+const JAN1 = new Date('2026-01-01T00:00:00Z');
+const JAN31 = new Date('2026-01-31T23:59:59Z');
+const JAN_HOURS = (JAN31 - JAN1) / 3600000;
+
+const makeToolItem = (logRecord = [], extra = {}) => ({
+ logRecord,
+ itemType: { _id: { toString: () => 'type1' }, name: 'Power Drill' },
+ purchaseStatus: 'Purchased',
+ condition: 'Good',
+ currentUsage: 'Available',
+ ...extra,
+});
+
+const makeUtilizationItem = (
+ name,
+ rate,
+ purchaseStatuses = [],
+ conditions = [],
+ currentUsages = [],
+) => ({
+ name,
+ utilizationRate: rate,
+ downtime: 100,
+ classification: classifyUtilization(rate),
+ toolCount: purchaseStatuses.length || 2,
+ totalCheckedOutHours: rate * 0.72,
+ totalPossibleHours: 720,
+ toolGroupDetails: {
+ tools: purchaseStatuses.map(() => ({})),
+ purchaseStatuses,
+ conditions,
+ currentUsages,
+ },
+});
+
+const makeMockBuildingTool = (tools = []) => {
+ const lean = jest.fn().mockResolvedValue(tools);
+ const chain = { populate: jest.fn(), lean };
+ chain.populate.mockReturnValue(chain);
+ return { BuildingTool: { find: jest.fn().mockReturnValue(chain) }, lean };
+};
+
+beforeEach(() => {
+ jest.clearAllMocks();
+ mongoose.Types.ObjectId.isValid.mockReturnValue(true);
+ cache.hasCache.mockReturnValue(false);
+ regression.linear.mockReturnValue({
+ r2: 0.8,
+ predict: jest.fn().mockImplementation((i) => [i, 60]),
+ });
+});
+
+// ─── classifyUtilization ───
+describe('classifyUtilization', () => {
+ it('returns Under-utilized and yellow for rate 0', () => {
+ expect(classifyUtilization(0)).toEqual({ label: 'Under-utilized', trafficLight: 'yellow' });
+ });
+
+ it('returns Under-utilized and yellow for rate 54', () => {
+ expect(classifyUtilization(54)).toEqual({ label: 'Under-utilized', trafficLight: 'yellow' });
+ });
+
+ it('returns Normal and green for rate 55', () => {
+ expect(classifyUtilization(55)).toEqual({ label: 'Normal', trafficLight: 'green' });
+ });
+
+ it('returns Normal and green for rate 85', () => {
+ expect(classifyUtilization(85)).toEqual({ label: 'Normal', trafficLight: 'green' });
+ });
+
+ it('returns Over-utilized and red for rate 86', () => {
+ expect(classifyUtilization(86)).toEqual({ label: 'Over-utilized', trafficLight: 'red' });
+ });
+
+ it('returns Over-utilized and red for rate 100', () => {
+ expect(classifyUtilization(100)).toEqual({ label: 'Over-utilized', trafficLight: 'red' });
+ });
+});
+
+// ─── calculateCheckedOutHours ───
+describe('calculateCheckedOutHours', () => {
+ it('returns 0 when logRecord is undefined', () => {
+ expect(calculateCheckedOutHours({ logRecord: undefined }, JAN1, JAN31)).toBe(0);
+ });
+
+ it('returns 0 when no logs fall within period and only a prior checkin exists', () => {
+ const toolWithCheckin = makeToolItem([makeLog('Check In', '2025-12-15T00:00:00Z')]);
+ expect(calculateCheckedOutHours(toolWithCheckin, JAN1, JAN31)).toBe(0);
+ });
+
+ it('returns full period hours when no logs in period and last prior log is Check Out', () => {
+ const tool = makeToolItem([makeLog('Check Out', '2025-12-15T00:00:00Z')]);
+ const result = calculateCheckedOutHours(tool, JAN1, JAN31);
+ expect(result).toBeCloseTo(JAN_HOURS, 0);
+ });
+
+ it('returns 0 when no logs in period and last prior log is Check In', () => {
+ const tool = makeToolItem([
+ makeLog('Check Out', '2025-12-01T00:00:00Z'),
+ makeLog('Check In', '2025-12-15T00:00:00Z'),
+ ]);
+ expect(calculateCheckedOutHours(tool, JAN1, JAN31)).toBe(0);
+ });
+
+ it('returns hours between Check Out and Check In within period', () => {
+ const checkOut = new Date('2026-01-05T08:00:00Z');
+ const checkIn = new Date('2026-01-05T12:00:00Z');
+ const tool = makeToolItem([makeLog('Check Out', checkOut), makeLog('Check In', checkIn)]);
+ expect(calculateCheckedOutHours(tool, JAN1, JAN31)).toBeCloseTo(4, 5);
+ });
+
+ it('counts time to period end when Check Out has no matching Check In', () => {
+ const checkOut = new Date('2026-01-31T20:00:00Z');
+ const tool = makeToolItem([makeLog('Check Out', checkOut)]);
+ const expected = (JAN31 - checkOut) / 3600000;
+ expect(calculateCheckedOutHours(tool, JAN1, JAN31)).toBeCloseTo(expected, 5);
+ });
+
+ it('ignores orphan Check In with no preceding Check Out', () => {
+ const tool = makeToolItem([makeLog('Check In', '2026-01-10T10:00:00Z')]);
+ expect(calculateCheckedOutHours(tool, JAN1, JAN31)).toBe(0);
+ });
+
+ it('accumulates multiple checkout/checkin pairs', () => {
+ const logs = [
+ makeLog('Check Out', '2026-01-05T08:00:00Z'),
+ makeLog('Check In', '2026-01-05T10:00:00Z'), // 2 hours
+ makeLog('Check Out', '2026-01-10T06:00:00Z'),
+ makeLog('Check In', '2026-01-10T10:00:00Z'), // 4 hours
+ ];
+ const tool = makeToolItem(logs);
+ expect(calculateCheckedOutHours(tool, JAN1, JAN31)).toBeCloseTo(6, 5);
+ });
+});
+
+// ─── buildToolFilter ───
+describe('buildToolFilter', () => {
+ it('returns only __t filter when no params', () => {
+ expect(buildToolFilter({})).toEqual({ __t: 'tool_item' });
+ });
+
+ it('ignores tool when tool is ALL', () => {
+ expect(buildToolFilter({ tool: 'ALL' })).toEqual({ __t: 'tool_item' });
+ });
+
+ it('ignores tool when ObjectId is invalid', () => {
+ mongoose.Types.ObjectId.isValid.mockReturnValue(false);
+ expect(buildToolFilter({ tool: 'invalid-id' })).toEqual({ __t: 'tool_item' });
+ });
+
+ it('adds itemType when tool is a valid ObjectId', () => {
+ const result = buildToolFilter({ tool: 'abc123' });
+ expect(result.__t).toBe('tool_item');
+ expect(result.itemType).toBeDefined();
+ });
+
+ it('ignores project when project is ALL', () => {
+ expect(buildToolFilter({ project: 'ALL' })).toEqual({ __t: 'tool_item' });
+ });
+
+ it('adds both itemType and project when both are valid ObjectIds', () => {
+ const result = buildToolFilter({ tool: 'tool1', project: 'proj1' });
+ expect(result.itemType).toBeDefined();
+ expect(result.project).toBeDefined();
+ });
+});
+
+// ─── parseDateRange ───
+describe('parseDateRange', () => {
+ it('defaults to last 30 days when no dates provided', () => {
+ const before = Date.now();
+ const { rangeEnd, totalHours } = parseDateRange(undefined, undefined);
+ const after = Date.now();
+ expect(rangeEnd.getTime()).toBeGreaterThanOrEqual(before);
+ expect(rangeEnd.getTime()).toBeLessThanOrEqual(after);
+ // 30 calendar days ≈ 719–721 hours depending on DST transitions
+ expect(totalHours).toBeGreaterThanOrEqual(29 * 24);
+ expect(totalHours).toBeLessThanOrEqual(31 * 24);
+ });
+
+ it('uses provided startDate', () => {
+ const { rangeStart } = parseDateRange('2026-01-01', undefined);
+ expect(rangeStart.toISOString().startsWith('2026-01-01')).toBe(true);
+ });
+
+ it('uses provided endDate', () => {
+ const { rangeEnd } = parseDateRange(undefined, '2026-02-01');
+ expect(rangeEnd.toISOString().startsWith('2026-02-01')).toBe(true);
+ });
+
+ it('computes totalHours correctly when both dates provided', () => {
+ const { totalHours } = parseDateRange('2026-01-01T00:00:00Z', '2026-01-02T00:00:00Z');
+ expect(totalHours).toBeCloseTo(24, 5);
+ });
+});
+
+// ─── groupToolsByType ───
+describe('groupToolsByType', () => {
+ it('returns empty object for empty tools array', () => {
+ expect(groupToolsByType([])).toEqual({});
+ });
+
+ it('skips tools without itemType', () => {
+ const tool = { logRecord: [] }; // no itemType
+ expect(groupToolsByType([tool])).toEqual({});
+ });
+
+ it('groups multiple tools of the same type under one key', () => {
+ const tool1 = makeToolItem();
+ const tool2 = makeToolItem();
+ const groups = groupToolsByType([tool1, tool2]);
+ expect(Object.keys(groups)).toHaveLength(1);
+ expect(groups.type1.tools).toHaveLength(2);
+ });
+
+ it('creates separate groups for different types', () => {
+ const tool1 = makeToolItem([], {
+ itemType: { _id: { toString: () => 'typeA' }, name: 'Drill' },
+ });
+ const tool2 = makeToolItem([], {
+ itemType: { _id: { toString: () => 'typeB' }, name: 'Hammer' },
+ });
+ const groups = groupToolsByType([tool1, tool2]);
+ expect(Object.keys(groups)).toHaveLength(2);
+ });
+});
+
+// ─── calculateGroupUtilization ───
+describe('calculateGroupUtilization', () => {
+ it('returns utilizationRate of 0 when totalHours is 0', () => {
+ const group = { name: 'Drill', tools: [makeToolItem()] };
+ const result = calculateGroupUtilization(group, JAN1, JAN1, 0);
+ expect(result.utilizationRate).toBe(0);
+ });
+
+ it('computes correct utilization rate and downtime for normal case', () => {
+ const checkOut = new Date('2026-01-15T00:00:00Z');
+ const checkIn = new Date('2026-01-16T00:00:00Z'); // 24 hours checked out
+ const tool = makeToolItem([makeLog('Check Out', checkOut), makeLog('Check In', checkIn)]);
+ const result = calculateGroupUtilization(
+ { name: 'Drill', tools: [tool] },
+ JAN1,
+ JAN31,
+ JAN_HOURS,
+ );
+ expect(result.utilizationRate).toBeGreaterThan(0);
+ expect(result.downtime).toBeGreaterThanOrEqual(0);
+ expect(result.classification).toBeDefined();
+ });
+
+ it('collects purchaseStatuses, conditions, and currentUsages from tools', () => {
+ const tool1 = makeToolItem([], {
+ purchaseStatus: 'Purchased',
+ condition: 'Worn',
+ currentUsage: 'Under Maintenance',
+ });
+ const tool2 = makeToolItem([], {
+ purchaseStatus: 'Rental',
+ condition: 'Good',
+ currentUsage: 'Available',
+ });
+ const result = calculateGroupUtilization(
+ { name: 'Drill', tools: [tool1, tool2] },
+ JAN1,
+ JAN31,
+ JAN_HOURS,
+ );
+ expect(result.toolGroupDetails.purchaseStatuses).toEqual(['Purchased', 'Rental']);
+ expect(result.toolGroupDetails.conditions).toEqual(['Worn', 'Good']);
+ expect(result.toolGroupDetails.currentUsages).toEqual(['Under Maintenance', 'Available']);
+ });
+
+ it('includes toolCount and totalCheckedOutHours in result', () => {
+ const group = { name: 'Drill', tools: [makeToolItem(), makeToolItem()] };
+ const result = calculateGroupUtilization(group, JAN1, JAN31, JAN_HOURS);
+ expect(result.toolCount).toBe(2);
+ expect(result.totalCheckedOutHours).toBeGreaterThanOrEqual(0);
+ expect(result.totalPossibleHours).toBeCloseTo(JAN_HOURS * 2, 0);
+ });
+});
+
+// ─── buildCacheKey ───
+describe('buildCacheKey', () => {
+ it('builds full key from all params', () => {
+ expect(
+ buildCacheKey({ tool: 't1', project: 'p1', startDate: '2026-01-01', endDate: '2026-01-31' }),
+ ).toBe('toolUtil:t1:p1:2026-01-01:2026-01-31');
+ });
+
+ it('uses ALL and default when params are absent', () => {
+ expect(buildCacheKey({})).toBe('toolUtil:ALL:ALL:default:default');
+ });
+
+ it('fills in defaults for missing params only', () => {
+ expect(buildCacheKey({ tool: 'myTool' })).toBe('toolUtil:myTool:ALL:default:default');
+ });
+});
+
+// ─── computeUtilizationData ───
+describe('computeUtilizationData', () => {
+ it('returns cached result without querying DB when cache hits', async () => {
+ const cached = {
+ utilizationData: [],
+ rangeStart: JAN1,
+ rangeEnd: JAN31,
+ totalHours: JAN_HOURS,
+ };
+ cache.hasCache.mockReturnValue(true);
+ cache.getCache.mockReturnValue(cached);
+
+ const { BuildingTool } = makeMockBuildingTool([]);
+ const result = await computeUtilizationData(BuildingTool, {});
+
+ expect(result).toBe(cached);
+ expect(BuildingTool.find).not.toHaveBeenCalled();
+ });
+
+ it('queries DB and caches result on cache miss', async () => {
+ const tool = makeToolItem([], { itemType: { _id: { toString: () => 'id1' }, name: 'Drill' } });
+ const { BuildingTool } = makeMockBuildingTool([tool]);
+
+ const result = await computeUtilizationData(BuildingTool, {});
+
+ expect(BuildingTool.find).toHaveBeenCalled();
+ expect(cache.setCache).toHaveBeenCalled();
+ expect(result.utilizationData).toHaveLength(1);
+ });
+
+ it('returns empty utilizationData when no tools found', async () => {
+ const { BuildingTool } = makeMockBuildingTool([]);
+ const result = await computeUtilizationData(BuildingTool, {});
+ expect(result.utilizationData).toHaveLength(0);
+ });
+
+ it('sorts utilizationData by utilizationRate descending', async () => {
+ const now = new Date();
+ const thirtyDaysAgo = new Date(now.getTime() - 29 * 24 * 3600000);
+ const highUseTool = makeToolItem(
+ [makeLog('Check Out', thirtyDaysAgo), makeLog('Check In', now)],
+ { itemType: { _id: { toString: () => 'highId' }, name: 'Hammer' } },
+ );
+ const lowUseTool = makeToolItem([], {
+ itemType: { _id: { toString: () => 'lowId' }, name: 'Shovel' },
+ });
+ const { BuildingTool } = makeMockBuildingTool([lowUseTool, highUseTool]);
+
+ const result = await computeUtilizationData(BuildingTool, {});
+
+ expect(result.utilizationData[0].utilizationRate).toBeGreaterThanOrEqual(
+ result.utilizationData[1].utilizationRate,
+ );
+ });
+});
+
+// ─── bucketUtilizationByWeek ───
+describe('bucketUtilizationByWeek', () => {
+ const toolGroup = { tools: [makeToolItem()] };
+
+ it('returns 1 bucket when range is less than one week', () => {
+ const start = new Date('2026-01-01T00:00:00Z');
+ const end = new Date('2026-01-03T00:00:00Z'); // 2 days
+ const buckets = bucketUtilizationByWeek(toolGroup, start, end);
+ expect(buckets).toHaveLength(1);
+ });
+
+ it('returns 2 buckets for a 14-day range', () => {
+ const start = new Date('2026-01-01T00:00:00Z');
+ const end = new Date('2026-01-15T00:00:00Z');
+ const buckets = bucketUtilizationByWeek(toolGroup, start, end);
+ expect(buckets).toHaveLength(2);
+ });
+
+ it('returns 5 buckets for a 30-day range', () => {
+ const start = new Date('2026-01-01T00:00:00Z');
+ const end = new Date('2026-01-31T00:00:00Z');
+ const buckets = bucketUtilizationByWeek(toolGroup, start, end);
+ expect(buckets).toHaveLength(5);
+ });
+
+ it('each bucket has weekIndex, weekStart, weekEnd, and utilizationRate', () => {
+ const start = new Date('2026-01-01T00:00:00Z');
+ const end = new Date('2026-01-15T00:00:00Z');
+ const buckets = bucketUtilizationByWeek(toolGroup, start, end);
+ buckets.forEach((bucket, i) => {
+ expect(bucket.weekIndex).toBe(i);
+ expect(bucket.weekStart).toBeInstanceOf(Date);
+ expect(bucket.weekEnd).toBeInstanceOf(Date);
+ expect(typeof bucket.utilizationRate).toBe('number');
+ });
+ });
+});
+
+// ─── forecastUtilization ───
+describe('forecastUtilization', () => {
+ const makeWeeklyBuckets = (count, rate = 50) =>
+ Array.from({ length: count }, (_, i) => ({
+ weekIndex: i,
+ weekStart: new Date(Date.now() - (count - i) * 7 * 24 * 3600000),
+ weekEnd: new Date(Date.now() - (count - i - 1) * 7 * 24 * 3600000),
+ utilizationRate: rate,
+ }));
+
+ it('returns predictedRate 0 and method average for empty buckets', () => {
+ const result = forecastUtilization([], 30);
+ expect(result.predictedRate).toBe(0);
+ expect(result.method).toBe('average');
+ expect(result.confidence).toBe('low');
+ });
+
+ it('uses average method when fewer than 3 buckets', () => {
+ const result = forecastUtilization(makeWeeklyBuckets(2, 60), 30);
+ expect(result.method).toBe('average');
+ expect(result.predictedRate).toBe(60);
+ expect(result.confidence).toBe('low');
+ });
+
+ it('uses average when exactly 1 bucket', () => {
+ const result = forecastUtilization(makeWeeklyBuckets(1, 40), 30);
+ expect(result.method).toBe('average');
+ expect(result.predictedRate).toBe(40);
+ });
+
+ it('uses ensemble method with high confidence for r2 >= 0.7', () => {
+ regression.linear.mockReturnValue({ r2: 0.8, predict: jest.fn().mockReturnValue([0, 65]) });
+ const result = forecastUtilization(makeWeeklyBuckets(4, 60), 30);
+ expect(result.method).toBe('ensemble');
+ expect(result.confidence).toBe('high');
+ });
+
+ it('uses ensemble with medium confidence for r2 between 0.4 and 0.7', () => {
+ regression.linear.mockReturnValue({ r2: 0.5, predict: jest.fn().mockReturnValue([0, 55]) });
+ const result = forecastUtilization(makeWeeklyBuckets(4, 50), 30);
+ expect(result.method).toBe('ensemble');
+ expect(result.confidence).toBe('medium');
+ });
+
+ it('uses ensemble with low confidence for r2 below 0.4', () => {
+ regression.linear.mockReturnValue({ r2: 0.2, predict: jest.fn().mockReturnValue([0, 50]) });
+ const result = forecastUtilization(makeWeeklyBuckets(4, 50), 30);
+ expect(result.confidence).toBe('low');
+ });
+
+ it('clamps blended prediction to 0 when regression predicts very low', () => {
+ regression.linear.mockReturnValue({ r2: 0.9, predict: jest.fn().mockReturnValue([0, -100]) });
+ const result = forecastUtilization(makeWeeklyBuckets(4, 0), 30);
+ result.weeklyPredictions.forEach((w) => {
+ expect(w.predictedRate).toBeGreaterThanOrEqual(0);
+ });
+ });
+
+ it('clamps blended prediction to 100 when regression predicts very high', () => {
+ regression.linear.mockReturnValue({ r2: 0.9, predict: jest.fn().mockReturnValue([0, 200]) });
+ const result = forecastUtilization(makeWeeklyBuckets(4, 100), 30);
+ result.weeklyPredictions.forEach((w) => {
+ expect(w.predictedRate).toBeLessThanOrEqual(100);
+ });
+ });
+
+ it('returns ISO forecastEndDate and predictedClassification', () => {
+ const result = forecastUtilization(makeWeeklyBuckets(2, 50), 30);
+ expect(() => new Date(result.forecastEndDate)).not.toThrow();
+ expect(result.predictedClassification).toHaveProperty('label');
+ expect(result.predictedClassification).toHaveProperty('trafficLight');
+ });
+});
+
+// ─── generateMaintenanceAlerts ───
+describe('generateMaintenanceAlerts', () => {
+ it('returns no alerts for a normal tool', () => {
+ const data = [makeUtilizationItem('Drill', 70, ['Purchased'], ['Good'], ['Available'])];
+ expect(generateMaintenanceAlerts(data)).toHaveLength(0);
+ });
+
+ it('generates overuse alert when rate exceeds 85', () => {
+ const data = [makeUtilizationItem('Drill', 90, ['Purchased'], ['Good'], ['Available'])];
+ const alerts = generateMaintenanceAlerts(data);
+ const overuseAlert = alerts.find((a) => a.alertType === 'overuse');
+ expect(overuseAlert).toBeDefined();
+ expect(overuseAlert.urgency).toBe('high');
+ expect(overuseAlert.message).toContain('90%');
+ });
+
+ it('generates condition alert for degraded tool condition', () => {
+ const data = [makeUtilizationItem('Drill', 70, [], ['Worn'], [])];
+ const alerts = generateMaintenanceAlerts(data);
+ expect(alerts.find((a) => a.alertType === 'condition')).toBeDefined();
+ });
+
+ it('deduplicates condition alerts for same condition appearing twice', () => {
+ const data = [makeUtilizationItem('Drill', 70, [], ['Worn', 'Worn'], [])];
+ const conditionAlerts = generateMaintenanceAlerts(data).filter(
+ (a) => a.alertType === 'condition',
+ );
+ expect(conditionAlerts).toHaveLength(1);
+ });
+
+ it('does not generate condition alert for Good condition', () => {
+ const data = [makeUtilizationItem('Drill', 70, [], ['Good'], [])];
+ expect(generateMaintenanceAlerts(data).filter((a) => a.alertType === 'condition')).toHaveLength(
+ 0,
+ );
+ });
+
+ it('generates non_operational alert when tool is Under Maintenance', () => {
+ const data = [makeUtilizationItem('Drill', 70, [], [], ['Under Maintenance'])];
+ const alerts = generateMaintenanceAlerts(data);
+ const nonOpAlert = alerts.find((a) => a.alertType === 'non_operational');
+ expect(nonOpAlert).toBeDefined();
+ expect(nonOpAlert.urgency).toBe('medium');
+ expect(nonOpAlert.message).toContain('1 unit(s)');
+ });
+
+ it('counts multiple non-operational units in single alert per status', () => {
+ const data = [
+ makeUtilizationItem('Drill', 70, [], [], ['Under Maintenance', 'Under Maintenance']),
+ ];
+ const nonOpAlerts = generateMaintenanceAlerts(data).filter(
+ (a) => a.alertType === 'non_operational',
+ );
+ expect(nonOpAlerts).toHaveLength(1);
+ expect(nonOpAlerts[0].message).toContain('2 unit(s)');
+ });
+});
+
+// ─── generateResourceBalancingSuggestions ───
+describe('generateResourceBalancingSuggestions', () => {
+ it('returns no suggestions for all-normal tools', () => {
+ const data = [makeUtilizationItem('Drill', 70), makeUtilizationItem('Hammer', 65)];
+ expect(generateResourceBalancingSuggestions(data)).toHaveLength(0);
+ });
+
+ it('suggests redistribution when over and under-utilized tools coexist', () => {
+ const data = [makeUtilizationItem('Drill', 90), makeUtilizationItem('Wheelbarrow', 30)];
+ const suggestions = generateResourceBalancingSuggestions(data);
+ expect(suggestions.find((s) => s.suggestion.includes('redistributing'))).toBeDefined();
+ });
+
+ it('pairs over-utilized with the least-used under-utilized tool', () => {
+ const data = [
+ makeUtilizationItem('Drill', 90),
+ makeUtilizationItem('Shovel', 40),
+ makeUtilizationItem('Wheelbarrow', 20),
+ ];
+ const suggestions = generateResourceBalancingSuggestions(data);
+ const redist = suggestions.find((s) => s.suggestion.includes('redistributing'));
+ expect(redist.toTool).toBe('Wheelbarrow');
+ });
+
+ it('suggests purchasing when over-utilized tool is mostly rented', () => {
+ const data = [makeUtilizationItem('Drill', 90, ['Rental', 'Rental', 'Purchased'])];
+ const suggestions = generateResourceBalancingSuggestions(data);
+ expect(suggestions.find((s) => s.suggestion.includes('purchasing additional'))).toBeDefined();
+ });
+
+ it('suggests renting when under-utilized tool is mostly owned', () => {
+ const data = [makeUtilizationItem('Shovel', 30, ['Purchased', 'Purchased', 'Rental'])];
+ const suggestions = generateResourceBalancingSuggestions(data);
+ expect(suggestions.find((s) => s.suggestion.includes('renting instead'))).toBeDefined();
+ });
+
+ it('no redistribution suggestion when over-utilized has no under-utilized counterpart', () => {
+ const data = [makeUtilizationItem('Drill', 90, ['Purchased', 'Purchased'])];
+ const suggestions = generateResourceBalancingSuggestions(data);
+ expect(suggestions.find((s) => s.suggestion.includes('redistributing'))).toBeUndefined();
+ });
+});
+
+// ─── generateRecommendations ───
+describe('generateRecommendations', () => {
+ it('recommends review for under-utilized tool', () => {
+ const result = generateRecommendations([makeUtilizationItem('Shovel', 30)]);
+ expect(result[0].action).toContain('Potentially removable');
+ expect(result[0].toolName).toBe('Shovel');
+ expect(result[0].trafficLight).toBe('yellow');
+ });
+
+ it('recommends no action for normal tool', () => {
+ const result = generateRecommendations([makeUtilizationItem('Drill', 70)]);
+ expect(result[0].action).toContain('Normal operation');
+ expect(result[0].trafficLight).toBe('green');
+ });
+
+ it('recommends maintenance planning for over-utilized tool', () => {
+ const result = generateRecommendations([makeUtilizationItem('Crane', 90)]);
+ expect(result[0].action).toContain('Requires maintenance scheduling');
+ expect(result[0].trafficLight).toBe('red');
+ });
+});
+
+// ─── stripInternalDetails ───
+describe('stripInternalDetails', () => {
+ it('removes toolGroupDetails from item', () => {
+ const item = { name: 'Drill', utilizationRate: 75, toolGroupDetails: { tools: [] } };
+ const result = stripInternalDetails(item);
+ expect(result.toolGroupDetails).toBeUndefined();
+ });
+
+ it('preserves all other public fields', () => {
+ const item = {
+ name: 'Drill',
+ utilizationRate: 75,
+ downtime: 100,
+ classification: { label: 'Normal', trafficLight: 'green' },
+ toolCount: 2,
+ toolGroupDetails: { tools: [] },
+ };
+ const result = stripInternalDetails(item);
+ expect(result.name).toBe('Drill');
+ expect(result.utilizationRate).toBe(75);
+ expect(result.downtime).toBe(100);
+ expect(result.classification).toBeDefined();
+ expect(result.toolCount).toBe(2);
+ });
+});
+
+// ─── buildInsightsSummary ───
+describe('buildInsightsSummary', () => {
+ it('returns all zeros for empty array', () => {
+ const result = buildInsightsSummary([]);
+ expect(result).toEqual({
+ totalToolTypes: 0,
+ underUtilized: 0,
+ normal: 0,
+ overUtilized: 0,
+ averageUtilization: 0,
+ });
+ });
+
+ it('counts all as normal when all tools are normal', () => {
+ const data = [makeUtilizationItem('A', 60), makeUtilizationItem('B', 75)];
+ const result = buildInsightsSummary(data);
+ expect(result.normal).toBe(2);
+ expect(result.underUtilized).toBe(0);
+ expect(result.overUtilized).toBe(0);
+ });
+
+ it('correctly counts mixed utilization categories', () => {
+ const data = [
+ makeUtilizationItem('A', 30), // under
+ makeUtilizationItem('B', 70), // normal
+ makeUtilizationItem('C', 90), // over
+ ];
+ const result = buildInsightsSummary(data);
+ expect(result.underUtilized).toBe(1);
+ expect(result.normal).toBe(1);
+ expect(result.overUtilized).toBe(1);
+ expect(result.totalToolTypes).toBe(3);
+ });
+
+ it('computes averageUtilization as rounded mean', () => {
+ const data = [makeUtilizationItem('A', 60), makeUtilizationItem('B', 80)];
+ const result = buildInsightsSummary(data);
+ expect(result.averageUtilization).toBe(70);
+ });
+});
+
+// ─── determineForecastDays ───
+describe('determineForecastDays', () => {
+ it('returns 30 days with no warning for forecast30 mode', async () => {
+ const result = await determineForecastDays('forecast30', 'anyId');
+ expect(result.forecastDays).toBe(30);
+ expect(result.warning).toBeNull();
+ });
+
+ it('returns 30 days with warning when no projectId for forecastFull', async () => {
+ const result = await determineForecastDays('forecastFull', undefined);
+ expect(result.forecastDays).toBe(30);
+ expect(result.warning).toContain('No specific project');
+ });
+
+ it('returns 30 days with warning when projectId is ALL', async () => {
+ const result = await determineForecastDays('forecastFull', 'ALL');
+ expect(result.forecastDays).toBe(30);
+ expect(result.warning).toBeTruthy();
+ });
+
+ it('returns 30 days with warning when no risk profile found', async () => {
+ ProjectRiskProfile.findOne.mockReturnValue({ lean: jest.fn().mockResolvedValue(null) });
+ const result = await determineForecastDays('forecastFull', 'validProjectId');
+ expect(result.forecastDays).toBe(30);
+ expect(result.warning).toContain('No project schedule');
+ });
+
+ it('returns 30 days with warning when risk profile has no endDate', async () => {
+ ProjectRiskProfile.findOne.mockReturnValue({
+ lean: jest.fn().mockResolvedValue({ projectId: 'p1' }),
+ });
+ const result = await determineForecastDays('forecastFull', 'validProjectId');
+ expect(result.forecastDays).toBe(30);
+ expect(result.warning).toBeTruthy();
+ });
+
+ it('returns calculated days when risk profile has a future endDate', async () => {
+ const futureDate = new Date(Date.now() + 60 * 24 * 3600000);
+ ProjectRiskProfile.findOne.mockReturnValue({
+ lean: jest.fn().mockResolvedValue({ endDate: futureDate }),
+ });
+ const result = await determineForecastDays('forecastFull', 'validProjectId');
+ expect(result.forecastDays).toBeGreaterThan(50);
+ expect(result.warning).toBeNull();
+ });
+
+ it('enforces minimum of 7 days when endDate is very soon', async () => {
+ const nearDate = new Date(Date.now() + 2 * 24 * 3600000);
+ ProjectRiskProfile.findOne.mockReturnValue({
+ lean: jest.fn().mockResolvedValue({ endDate: nearDate }),
+ });
+ const result = await determineForecastDays('forecastFull', 'validProjectId');
+ expect(result.forecastDays).toBe(7);
+ });
+});
+
+// ─── buildUtilizationResponse ───
+describe('buildUtilizationResponse', () => {
+ const rangeStart = new Date('2026-01-01T00:00:00Z');
+ const rangeEnd = new Date('2026-01-22T00:00:00Z'); // 21 days → 3 weekly buckets
+
+ const makeItem = (name, rate) => ({
+ ...makeUtilizationItem(name, rate),
+ toolGroupDetails: {
+ tools: [makeToolItem()],
+ purchaseStatuses: [],
+ conditions: [],
+ currentUsages: [],
+ },
+ });
+
+ it('sets forecast to null in historical mode', async () => {
+ const data = [makeItem('Drill', 70)];
+ const result = await buildUtilizationResponse({
+ utilizationData: data,
+ rangeStart,
+ rangeEnd,
+ selectedMode: 'historical',
+ project: null,
+ });
+ expect(result[0].forecast).toBeNull();
+ expect(result[0].toolGroupDetails).toBeUndefined();
+ });
+
+ it('attaches forecast object in forecast30 mode', async () => {
+ const data = [makeItem('Drill', 70)];
+ const result = await buildUtilizationResponse({
+ utilizationData: data,
+ rangeStart,
+ rangeEnd,
+ selectedMode: 'forecast30',
+ project: null,
+ });
+ expect(result[0].forecast).not.toBeNull();
+ expect(result[0].forecast).toHaveProperty('predictedRate');
+ expect(result[0].forecast).toHaveProperty('weeklyPredictions');
+ });
+
+ it('adds warning to all items when no project selected in forecastFull', async () => {
+ const data = [makeItem('Drill', 70), makeItem('Hammer', 50)];
+ const result = await buildUtilizationResponse({
+ utilizationData: data,
+ rangeStart,
+ rangeEnd,
+ selectedMode: 'forecastFull',
+ project: null,
+ });
+ expect(result[0].warning).toBeTruthy();
+ expect(result[1].warning).toBeTruthy();
+ });
+
+ it('does not add warning when valid project has a risk profile', async () => {
+ const futureDate = new Date(Date.now() + 60 * 24 * 3600000);
+ ProjectRiskProfile.findOne.mockReturnValue({
+ lean: jest.fn().mockResolvedValue({ endDate: futureDate }),
+ });
+ const data = [makeItem('Drill', 70)];
+ const result = await buildUtilizationResponse({
+ utilizationData: data,
+ rangeStart,
+ rangeEnd,
+ selectedMode: 'forecastFull',
+ project: 'validProjectId',
+ });
+ expect(result[0].warning).toBeUndefined();
+ });
+
+ it('strips toolGroupDetails from all response items', async () => {
+ const data = [makeItem('Drill', 70)];
+ const result = await buildUtilizationResponse({
+ utilizationData: data,
+ rangeStart,
+ rangeEnd,
+ selectedMode: 'historical',
+ project: null,
+ });
+ expect(result[0].toolGroupDetails).toBeUndefined();
+ });
+});
+
+// ─── buildReportPayload ───
+describe('buildReportPayload', () => {
+ const rangeStart = new Date('2026-01-01T00:00:00Z');
+ const rangeEnd = new Date('2026-01-31T00:00:00Z');
+
+ it('returns object with all required keys', () => {
+ const data = [makeUtilizationItem('Drill', 70)];
+ const result = buildReportPayload(data, rangeStart, rangeEnd, 'proj1');
+ expect(result).toHaveProperty('utilizationData');
+ expect(result).toHaveProperty('alerts');
+ expect(result).toHaveProperty('balancing');
+ expect(result).toHaveProperty('recommendations');
+ expect(result).toHaveProperty('summary');
+ expect(result).toHaveProperty('metadata');
+ });
+
+ it('builds metadata with correct dateRange and projectFilter', () => {
+ const data = [makeUtilizationItem('Drill', 70)];
+ const result = buildReportPayload(data, rangeStart, rangeEnd, 'myProject');
+ expect(result.metadata.dateRange).toContain(rangeStart.toISOString());
+ expect(result.metadata.dateRange).toContain(rangeEnd.toISOString());
+ expect(result.metadata.projectFilter).toBe('myProject');
+ });
+
+ it('defaults projectFilter to ALL when project is not provided', () => {
+ const data = [];
+ const result = buildReportPayload(data, rangeStart, rangeEnd, undefined);
+ expect(result.metadata.projectFilter).toBe('ALL');
+ });
+});
diff --git a/src/helpers/__tests__/toolUtilizationReportHelpers.test.js b/src/helpers/__tests__/toolUtilizationReportHelpers.test.js
new file mode 100644
index 000000000..644473d2c
--- /dev/null
+++ b/src/helpers/__tests__/toolUtilizationReportHelpers.test.js
@@ -0,0 +1,181 @@
+jest.mock('pdfkit', () => jest.fn());
+jest.mock('json2csv', () => ({ Parser: jest.fn() }));
+
+const PDFDocument = require('pdfkit');
+const { Parser } = require('json2csv');
+const { generatePDFReport, generateCSVReport } = require('../toolUtilizationReportHelpers');
+
+// ─── Shared fixtures ───
+const makeReportData = (overrides = {}) => ({
+ utilizationData: [
+ {
+ name: 'Drill',
+ utilizationRate: 90,
+ downtime: 72,
+ classification: { label: 'Over-utilized', trafficLight: 'red' },
+ toolCount: 2,
+ },
+ {
+ name: 'Wheelbarrow',
+ utilizationRate: 30,
+ downtime: 504,
+ classification: { label: 'Under-utilized', trafficLight: 'yellow' },
+ toolCount: 1,
+ },
+ ],
+ alerts: [{ toolName: 'Drill', urgency: 'high', message: 'High utilization at 90%.' }],
+ balancing: [
+ {
+ suggestion: 'Redistribute.',
+ rationale: 'Drill at 90%.',
+ fromTool: 'Drill',
+ toTool: 'Wheelbarrow',
+ },
+ ],
+ recommendations: [
+ { toolName: 'Drill', action: 'Schedule maintenance.' },
+ { toolName: 'Wheelbarrow', action: 'Review necessity.' },
+ ],
+ summary: {
+ totalToolTypes: 2,
+ underUtilized: 1,
+ normal: 0,
+ overUtilized: 1,
+ averageUtilization: 60,
+ },
+ metadata: {
+ generatedDate: '3/20/2026',
+ dateRange: '2026-01-01 to 2026-01-31',
+ projectFilter: 'ALL',
+ },
+ ...overrides,
+});
+
+// ─── generatePDFReport ───
+describe('generatePDFReport', () => {
+ let mockDoc;
+ let mockRes;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockDoc = {
+ fontSize: jest.fn().mockReturnThis(),
+ font: jest.fn().mockReturnThis(),
+ text: jest.fn().mockReturnThis(),
+ moveDown: jest.fn().mockReturnThis(),
+ addPage: jest.fn().mockReturnThis(),
+ fillColor: jest.fn().mockReturnThis(),
+ pipe: jest.fn(),
+ end: jest.fn(),
+ y: 100,
+ };
+ PDFDocument.mockImplementation(() => mockDoc);
+
+ mockRes = {
+ setHeader: jest.fn(),
+ pipe: jest.fn(),
+ };
+ });
+
+ it('sets Content-Type header to application/pdf', () => {
+ generatePDFReport(mockRes, makeReportData());
+ expect(mockRes.setHeader).toHaveBeenCalledWith('Content-Type', 'application/pdf');
+ });
+
+ it('sets Content-Disposition header with pdf filename', () => {
+ generatePDFReport(mockRes, makeReportData());
+ const [, disposition] = mockRes.setHeader.mock.calls.find(([h]) => h === 'Content-Disposition');
+ expect(disposition).toMatch(/attachment; filename="tool-utilization-report-\d+\.pdf"/);
+ });
+
+ it('pipes document to response', () => {
+ generatePDFReport(mockRes, makeReportData());
+ expect(mockDoc.pipe).toHaveBeenCalledWith(mockRes);
+ });
+
+ it('calls doc.end() to finalize PDF', () => {
+ generatePDFReport(mockRes, makeReportData());
+ expect(mockDoc.end).toHaveBeenCalled();
+ });
+
+ it('skips empty sections when alerts, balancing, and recommendations are empty', () => {
+ const emptyData = makeReportData({ alerts: [], balancing: [], recommendations: [] });
+ const moveDownCallsBefore = mockDoc.moveDown.mock.calls.length;
+ generatePDFReport(mockRes, emptyData);
+ // writePDFSection returns early for empty arrays, so fewer moveDown calls
+ // At minimum doc.end() is called meaning the function completed
+ expect(mockDoc.end).toHaveBeenCalled();
+ expect(mockDoc.moveDown.mock.calls.length).toBeLessThanOrEqual(moveDownCallsBefore + 10);
+ });
+
+ it('calls addPage when doc.y exceeds page break threshold', () => {
+ mockDoc.y = 750; // above PAGE_BREAK_THRESHOLD (700)
+ generatePDFReport(mockRes, makeReportData());
+ expect(mockDoc.addPage).toHaveBeenCalled();
+ });
+});
+
+// ─── generateCSVReport ───
+describe('generateCSVReport', () => {
+ let mockRes;
+ let mockParseInstance;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockParseInstance = { parse: jest.fn().mockReturnValue('Tool Name,Rate\nDrill,90') };
+ Parser.mockImplementation(() => mockParseInstance);
+
+ mockRes = {
+ setHeader: jest.fn(),
+ send: jest.fn(),
+ };
+ });
+
+ it('sets Content-Type header to text/csv', () => {
+ generateCSVReport(mockRes, makeReportData());
+ expect(mockRes.setHeader).toHaveBeenCalledWith('Content-Type', 'text/csv; charset=utf-8');
+ });
+
+ it('sets Content-Disposition header with csv filename', () => {
+ generateCSVReport(mockRes, makeReportData());
+ const [, disposition] = mockRes.setHeader.mock.calls.find(([h]) => h === 'Content-Disposition');
+ expect(disposition).toMatch(/attachment; filename="tool-utilization-report-\d+\.csv"/);
+ });
+
+ it('sends response with UTF-8 BOM prefix', () => {
+ generateCSVReport(mockRes, makeReportData());
+ const sent = mockRes.send.mock.calls[0][0];
+ expect(sent.startsWith('\ufeff')).toBe(true);
+ });
+
+ it('sets maintenanceAlert to None when no alerts for a tool', () => {
+ const data = makeReportData({ alerts: [] });
+ generateCSVReport(mockRes, data);
+ const rowsPassed = mockParseInstance.parse.mock.calls[0][0];
+ rowsPassed.forEach((row) => {
+ expect(row.maintenanceAlert).toBe('None');
+ });
+ });
+
+ it('concatenates multiple alerts for the same tool with semicolons', () => {
+ const data = makeReportData({
+ alerts: [
+ { toolName: 'Drill', message: 'High usage.' },
+ { toolName: 'Drill', message: 'Condition worn.' },
+ ],
+ });
+ generateCSVReport(mockRes, data);
+ const rowsPassed = mockParseInstance.parse.mock.calls[0][0];
+ const drillRow = rowsPassed.find((r) => r.name === 'Drill');
+ expect(drillRow.maintenanceAlert).toBe('High usage.; Condition worn.');
+ });
+
+ it('sets recommendation to None when no recommendation exists for a tool', () => {
+ const data = makeReportData({ recommendations: [] });
+ generateCSVReport(mockRes, data);
+ const rowsPassed = mockParseInstance.parse.mock.calls[0][0];
+ rowsPassed.forEach((row) => {
+ expect(row.recommendation).toBe('None');
+ });
+ });
+});
diff --git a/src/helpers/toolUtilizationHelpers.js b/src/helpers/toolUtilizationHelpers.js
new file mode 100644
index 000000000..bac7f9f09
--- /dev/null
+++ b/src/helpers/toolUtilizationHelpers.js
@@ -0,0 +1,564 @@
+const mongoose = require('mongoose');
+const regression = require('regression');
+const ProjectRiskProfile = require('../models/bmdashboard/projectRiskProfile');
+const cache = require('../utilities/nodeCache')();
+const {
+ UTILIZATION_THRESHOLDS,
+ UTILIZATION_LABELS,
+ TRAFFIC_LIGHT,
+ FORECAST_MODES,
+ MAINTENANCE_TRIGGER_THRESHOLD,
+ MINIMUM_WEEKS_FOR_REGRESSION,
+ FORECAST_DEFAULT_DAYS,
+ HOURS_PER_DAY,
+ DAYS_PER_WEEK,
+ MS_PER_HOUR,
+ DEGRADED_CONDITIONS,
+ NON_OPERATIONAL_STATUSES,
+ CONFIDENCE_THRESHOLDS,
+ ENSEMBLE_WEIGHTS,
+ EMA_SMOOTHING_BASE,
+ ROUNDING_PRECISION,
+} = require('../constants/toolUtilization');
+
+// ─── classifyUtilization ───
+const classifyUtilization = (rate) => {
+ if (rate < UTILIZATION_THRESHOLDS.UNDER_UTILIZED_MAX) {
+ return { label: UTILIZATION_LABELS.UNDER, trafficLight: TRAFFIC_LIGHT.YELLOW };
+ }
+ if (rate <= UTILIZATION_THRESHOLDS.NORMAL_MAX) {
+ return { label: UTILIZATION_LABELS.NORMAL, trafficLight: TRAFFIC_LIGHT.GREEN };
+ }
+ return { label: UTILIZATION_LABELS.OVER, trafficLight: TRAFFIC_LIGHT.RED };
+};
+
+// ─── calculateCheckedOutHours ───
+const calculateCheckedOutHours = (toolItem, periodStart, periodEnd) => {
+ const periodHours = (periodEnd - periodStart) / MS_PER_HOUR;
+ const relevantLogs = (toolItem.logRecord || []).filter((log) => {
+ const logDate = new Date(log.date);
+ return logDate >= periodStart && logDate <= periodEnd;
+ });
+
+ relevantLogs.sort((a, b) => new Date(a.date) - new Date(b.date));
+
+ let checkedOutTime = 0;
+ let lastCheckOut = null;
+
+ relevantLogs.forEach((log) => {
+ if (log.type === 'Check Out') {
+ lastCheckOut = new Date(log.date);
+ } else if (log.type === 'Check In' && lastCheckOut) {
+ const hoursOut = (new Date(log.date) - lastCheckOut) / MS_PER_HOUR;
+ checkedOutTime += Math.max(0, hoursOut);
+ lastCheckOut = null;
+ }
+ });
+
+ if (lastCheckOut) {
+ checkedOutTime += Math.max(0, (periodEnd - lastCheckOut) / MS_PER_HOUR);
+ }
+
+ if (relevantLogs.length === 0 && toolItem.logRecord && toolItem.logRecord.length > 0) {
+ const sortedAllLogs = [...toolItem.logRecord].sort(
+ (a, b) => new Date(b.date) - new Date(a.date),
+ );
+ const lastLog = sortedAllLogs[0];
+ if (lastLog?.type === 'Check Out' && new Date(lastLog.date) < periodStart) {
+ checkedOutTime = periodHours;
+ }
+ }
+
+ return checkedOutTime;
+};
+
+// ─── buildToolFilter ───
+const buildToolFilter = (query) => {
+ const filter = { __t: 'tool_item' };
+ if (query.tool && query.tool !== 'ALL' && mongoose.Types.ObjectId.isValid(query.tool)) {
+ filter.itemType = mongoose.Types.ObjectId(query.tool);
+ }
+ if (query.project && query.project !== 'ALL' && mongoose.Types.ObjectId.isValid(query.project)) {
+ filter.project = mongoose.Types.ObjectId(query.project);
+ }
+ return filter;
+};
+
+// ─── parseDateRange ───
+const parseDateRange = (startDate, endDate) => {
+ const rangeEnd = endDate ? new Date(endDate) : new Date();
+ const defaultStart = new Date();
+ defaultStart.setDate(defaultStart.getDate() - FORECAST_DEFAULT_DAYS);
+ const rangeStart = startDate ? new Date(startDate) : defaultStart;
+ const totalHours = (rangeEnd - rangeStart) / MS_PER_HOUR;
+ return { rangeStart, rangeEnd, totalHours };
+};
+
+// ─── groupToolsByType ───
+const groupToolsByType = (tools) => {
+ const toolGroups = {};
+ tools.forEach((toolItem) => {
+ if (!toolItem.itemType) return;
+ const toolTypeId = toolItem.itemType._id.toString();
+ if (!toolGroups[toolTypeId]) {
+ toolGroups[toolTypeId] = {
+ name: toolItem.itemType.name || 'Unknown Tool',
+ tools: [],
+ };
+ }
+ toolGroups[toolTypeId].tools.push(toolItem);
+ });
+ return toolGroups;
+};
+
+// ─── calculateGroupUtilization ───
+const calculateGroupUtilization = (group, rangeStart, rangeEnd, totalHours) => {
+ let totalCheckedOut = 0;
+ const purchaseStatuses = [];
+ const conditions = [];
+ const currentUsages = [];
+
+ group.tools.forEach((toolItem) => {
+ totalCheckedOut += calculateCheckedOutHours(toolItem, rangeStart, rangeEnd);
+ if (toolItem.purchaseStatus) purchaseStatuses.push(toolItem.purchaseStatus);
+ if (toolItem.condition) conditions.push(toolItem.condition);
+ if (toolItem.currentUsage) currentUsages.push(toolItem.currentUsage);
+ });
+
+ const toolCount = group.tools.length;
+ const totalPossibleHours = totalHours * toolCount;
+ const utilizationRate =
+ totalPossibleHours > 0 ? Math.round((totalCheckedOut / totalPossibleHours) * 100) : 0;
+ const downtime =
+ Math.round((totalPossibleHours - totalCheckedOut) * ROUNDING_PRECISION) / ROUNDING_PRECISION;
+
+ return {
+ name: group.name,
+ utilizationRate,
+ downtime,
+ classification: classifyUtilization(utilizationRate),
+ toolCount,
+ totalCheckedOutHours: Math.round(totalCheckedOut * ROUNDING_PRECISION) / ROUNDING_PRECISION,
+ totalPossibleHours: Math.round(totalPossibleHours * ROUNDING_PRECISION) / ROUNDING_PRECISION,
+ toolGroupDetails: {
+ tools: group.tools,
+ purchaseStatuses,
+ conditions,
+ currentUsages,
+ },
+ };
+};
+
+// ─── buildCacheKey ───
+const buildCacheKey = (query) =>
+ `toolUtil:${query.tool || 'ALL'}:${query.project || 'ALL'}:${query.startDate || 'default'}:${query.endDate || 'default'}`;
+
+// ─── computeUtilizationData ───
+const computeUtilizationData = async (BuildingTool, query) => {
+ const cacheKey = buildCacheKey(query);
+ if (cache.hasCache(cacheKey)) {
+ return cache.getCache(cacheKey);
+ }
+
+ const filter = buildToolFilter(query);
+ const tools = await BuildingTool.find(filter)
+ .populate('itemType', 'name')
+ .populate('project', 'name')
+ .lean();
+
+ const { rangeStart, rangeEnd, totalHours } = parseDateRange(query.startDate, query.endDate);
+ const toolGroups = groupToolsByType(tools);
+ const utilizationData = Object.values(toolGroups)
+ .map((group) => calculateGroupUtilization(group, rangeStart, rangeEnd, totalHours))
+ .sort((a, b) => b.utilizationRate - a.utilizationRate);
+
+ const result = { toolGroups, utilizationData, rangeStart, rangeEnd, totalHours };
+ cache.setCache(cacheKey, result);
+ return result;
+};
+
+// ─── bucketUtilizationByWeek ───
+const bucketUtilizationByWeek = (toolGroup, rangeStart, rangeEnd) => {
+ const rangeDuration = rangeEnd.getTime() - rangeStart.getTime();
+ const weekMs = DAYS_PER_WEEK * HOURS_PER_DAY * MS_PER_HOUR;
+ const numWeeks = Math.max(1, Math.ceil(rangeDuration / weekMs));
+ const buckets = [];
+
+ for (let i = 0; i < numWeeks; i += 1) {
+ const weekStart = new Date(rangeStart.getTime() + i * weekMs);
+ const weekEnd = new Date(Math.min(weekStart.getTime() + weekMs, rangeEnd.getTime()));
+ const weekHours = (weekEnd - weekStart) / MS_PER_HOUR;
+
+ let weekCheckedOut = 0;
+ toolGroup.tools.forEach((toolItem) => {
+ weekCheckedOut += calculateCheckedOutHours(toolItem, weekStart, weekEnd);
+ });
+
+ const weekTotalPossible = weekHours * toolGroup.tools.length;
+ const weekRate =
+ weekTotalPossible > 0 ? Math.round((weekCheckedOut / weekTotalPossible) * 100) : 0;
+
+ buckets.push({ weekIndex: i, weekStart, weekEnd, utilizationRate: weekRate });
+ }
+
+ return buckets;
+};
+
+// ─── computeEnsemblePredictions (internal helper for forecastUtilization) ───
+const computeEnsemblePredictions = (weeklyBuckets, forecastWeeks, weekMs, existingWeeks) => {
+ const data = weeklyBuckets.map((b, i) => [i, b.utilizationRate]);
+ const result = regression.linear(data);
+ const r2 = result.r2 || 0;
+
+ let emaValue = weeklyBuckets[0].utilizationRate;
+ const alpha = EMA_SMOOTHING_BASE / (existingWeeks + 1);
+ for (let i = 1; i < existingWeeks; i += 1) {
+ emaValue = alpha * weeklyBuckets[i].utilizationRate + (1 - alpha) * emaValue;
+ }
+
+ let weights;
+ let confidence = 'low';
+ if (r2 >= CONFIDENCE_THRESHOLDS.HIGH) {
+ weights = ENSEMBLE_WEIGHTS.HIGH_R2;
+ confidence = 'high';
+ } else if (r2 >= CONFIDENCE_THRESHOLDS.MEDIUM) {
+ weights = ENSEMBLE_WEIGHTS.MEDIUM_R2;
+ confidence = 'medium';
+ } else {
+ weights = ENSEMBLE_WEIGHTS.LOW_R2;
+ }
+
+ const weeklyPredictions = [];
+ for (let j = 0; j < forecastWeeks; j += 1) {
+ const futureIndex = existingWeeks + j;
+ const regressionPred = result.predict(futureIndex)[1];
+ const blended = weights.regression * regressionPred + weights.ema * emaValue;
+ const clamped = Math.min(100, Math.max(0, Math.round(blended)));
+
+ const weekStart = new Date(Date.now() + j * weekMs);
+ const weekEnd = new Date(weekStart.getTime() + weekMs);
+ weeklyPredictions.push({
+ weekStart: weekStart.toISOString(),
+ weekEnd: weekEnd.toISOString(),
+ predictedRate: clamped,
+ });
+ }
+
+ return { weeklyPredictions, confidence };
+};
+
+// ─── forecastUtilization (ensemble: regression + EMA) ───
+const forecastUtilization = (weeklyBuckets, forecastDays) => {
+ const weekMs = DAYS_PER_WEEK * HOURS_PER_DAY * MS_PER_HOUR;
+ const forecastWeeks = Math.max(1, Math.ceil(forecastDays / DAYS_PER_WEEK));
+ const existingWeeks = weeklyBuckets.length;
+ let weeklyPredictions;
+ let confidence = 'low';
+ let method = 'average';
+
+ if (existingWeeks < MINIMUM_WEEKS_FOR_REGRESSION) {
+ const avgRate =
+ existingWeeks > 0
+ ? Math.round(weeklyBuckets.reduce((sum, b) => sum + b.utilizationRate, 0) / existingWeeks)
+ : 0;
+
+ weeklyPredictions = [];
+ for (let j = 0; j < forecastWeeks; j += 1) {
+ const weekStart = new Date(Date.now() + j * weekMs);
+ const weekEnd = new Date(weekStart.getTime() + weekMs);
+ weeklyPredictions.push({
+ weekStart: weekStart.toISOString(),
+ weekEnd: weekEnd.toISOString(),
+ predictedRate: avgRate,
+ });
+ }
+ } else {
+ const ensemble = computeEnsemblePredictions(
+ weeklyBuckets,
+ forecastWeeks,
+ weekMs,
+ existingWeeks,
+ );
+ weeklyPredictions = ensemble.weeklyPredictions;
+ confidence = ensemble.confidence;
+ method = 'ensemble';
+ }
+
+ const predictedRate =
+ weeklyPredictions.length > 0
+ ? Math.round(
+ weeklyPredictions.reduce((sum, w) => sum + w.predictedRate, 0) / weeklyPredictions.length,
+ )
+ : 0;
+
+ const forecastEndDate = new Date(
+ Date.now() + forecastDays * HOURS_PER_DAY * MS_PER_HOUR,
+ ).toISOString();
+
+ return {
+ predictedRate,
+ confidence,
+ forecastEndDate,
+ weeklyPredictions,
+ predictedClassification: classifyUtilization(predictedRate),
+ method,
+ };
+};
+
+// ─── generateMaintenanceAlerts ───
+const generateMaintenanceAlerts = (utilizationData) => {
+ const alerts = [];
+
+ utilizationData.forEach((item) => {
+ const { toolGroupDetails } = item;
+
+ if (item.utilizationRate > MAINTENANCE_TRIGGER_THRESHOLD) {
+ alerts.push({
+ toolName: item.name,
+ alertType: 'overuse',
+ message: `High utilization at ${item.utilizationRate}%. Schedule preventive maintenance.`,
+ urgency: 'high',
+ });
+ }
+
+ const degradedSet = new Set();
+ toolGroupDetails.conditions.forEach((condition) => {
+ if (DEGRADED_CONDITIONS.includes(condition) && !degradedSet.has(condition)) {
+ degradedSet.add(condition);
+ alerts.push({
+ toolName: item.name,
+ alertType: 'condition',
+ message: `Tool condition is ${condition}. Immediate maintenance recommended.`,
+ urgency: 'high',
+ });
+ }
+ });
+
+ const nonOpCounts = {};
+ toolGroupDetails.currentUsages.forEach((usage) => {
+ if (NON_OPERATIONAL_STATUSES.includes(usage)) {
+ nonOpCounts[usage] = (nonOpCounts[usage] || 0) + 1;
+ }
+ });
+ Object.entries(nonOpCounts).forEach(([status, count]) => {
+ alerts.push({
+ toolName: item.name,
+ alertType: 'non_operational',
+ message: `${count} unit(s) currently ${status}. Effective fleet capacity reduced.`,
+ urgency: 'medium',
+ });
+ });
+ });
+
+ return alerts;
+};
+
+// ─── generateResourceBalancingSuggestions ───
+const generateResourceBalancingSuggestions = (utilizationData) => {
+ const suggestions = [];
+ const overUtilized = utilizationData.filter(
+ (d) => d.utilizationRate > UTILIZATION_THRESHOLDS.NORMAL_MAX,
+ );
+ const underUtilized = utilizationData.filter(
+ (d) => d.utilizationRate < UTILIZATION_THRESHOLDS.UNDER_UTILIZED_MAX,
+ );
+
+ const sortedUnder = [...underUtilized].sort((a, b) => a.utilizationRate - b.utilizationRate);
+
+ overUtilized.forEach((overTool) => {
+ if (sortedUnder.length > 0) {
+ const leastUsed = sortedUnder[0];
+ suggestions.push({
+ suggestion: 'Consider redistributing workload.',
+ fromTool: overTool.name,
+ toTool: leastUsed.name,
+ rationale: `${overTool.name} is at ${overTool.utilizationRate}% while ${leastUsed.name} is at ${leastUsed.utilizationRate}%.`,
+ });
+ }
+
+ const rentalCount = overTool.toolGroupDetails.purchaseStatuses.filter(
+ (s) => s === 'Rental',
+ ).length;
+ if (rentalCount > overTool.toolCount / 2) {
+ suggestions.push({
+ suggestion: 'Consider purchasing additional units to reduce rental dependency.',
+ fromTool: overTool.name,
+ toTool: null,
+ rationale: `${overTool.name} is over-utilized at ${overTool.utilizationRate}% and predominantly rented.`,
+ });
+ }
+ });
+
+ underUtilized.forEach((underTool) => {
+ const purchasedCount = underTool.toolGroupDetails.purchaseStatuses.filter(
+ (s) => s === 'Purchased',
+ ).length;
+ if (purchasedCount > underTool.toolCount / 2) {
+ suggestions.push({
+ suggestion: 'Consider renting instead of owning, or reassign to other projects.',
+ fromTool: underTool.name,
+ toTool: null,
+ rationale: `${underTool.name} is under-utilized at ${underTool.utilizationRate}% and predominantly owned.`,
+ });
+ }
+ });
+
+ return suggestions;
+};
+
+// ─── generateRecommendations ───
+const generateRecommendations = (utilizationData) =>
+ utilizationData.map((item) => {
+ let action;
+ if (item.classification.label === UTILIZATION_LABELS.UNDER) {
+ action = 'Potentially removable or rentable instead of owned. Review necessity.';
+ } else if (item.classification.label === UTILIZATION_LABELS.OVER) {
+ action = 'Requires maintenance scheduling, backup inventory, or purchase planning.';
+ } else {
+ action = 'Normal operation. No action required.';
+ }
+
+ return {
+ toolName: item.name,
+ utilizationRate: item.utilizationRate,
+ label: item.classification.label,
+ trafficLight: item.classification.trafficLight,
+ action,
+ };
+ });
+
+// ─── stripInternalDetails ───
+const stripInternalDetails = (item) => {
+ const publicFields = Object.fromEntries(
+ Object.entries(item).filter(([key]) => key !== 'toolGroupDetails')
+ );
+ return publicFields;
+};
+
+// ─── buildInsightsSummary ───
+const buildInsightsSummary = (utilizationData) => {
+ const totalToolTypes = utilizationData.length;
+ const underCount = utilizationData.filter(
+ (d) => d.classification.label === UTILIZATION_LABELS.UNDER,
+ ).length;
+ const overCount = utilizationData.filter(
+ (d) => d.classification.label === UTILIZATION_LABELS.OVER,
+ ).length;
+ const normalCount = totalToolTypes - underCount - overCount;
+ const averageUtilization =
+ totalToolTypes > 0
+ ? Math.round(utilizationData.reduce((s, d) => s + d.utilizationRate, 0) / totalToolTypes)
+ : 0;
+
+ return {
+ totalToolTypes,
+ underUtilized: underCount,
+ normal: normalCount,
+ overUtilized: overCount,
+ averageUtilization,
+ };
+};
+
+// ─── determineForecastDays ───
+const determineForecastDays = async (mode, projectId) => {
+ if (mode === FORECAST_MODES.FORECAST_30) {
+ return { forecastDays: FORECAST_DEFAULT_DAYS, warning: null };
+ }
+
+ if (!projectId || projectId === 'ALL') {
+ return {
+ forecastDays: FORECAST_DEFAULT_DAYS,
+ warning: 'No specific project selected. Defaulting to 30-day forecast.',
+ };
+ }
+
+ const riskProfile = await ProjectRiskProfile.findOne({
+ projectId: mongoose.Types.ObjectId(projectId),
+ }).lean();
+
+ if (!riskProfile?.endDate) {
+ return {
+ forecastDays: FORECAST_DEFAULT_DAYS,
+ warning: 'No project schedule found. Defaulting to 30-day forecast.',
+ };
+ }
+
+ const daysToEnd = Math.ceil(
+ (new Date(riskProfile.endDate) - Date.now()) / (HOURS_PER_DAY * MS_PER_HOUR),
+ );
+ return {
+ forecastDays: Math.max(DAYS_PER_WEEK, daysToEnd),
+ warning: null,
+ };
+};
+
+// ─── buildUtilizationResponse ───
+const buildUtilizationResponse = async ({
+ utilizationData,
+ rangeStart,
+ rangeEnd,
+ selectedMode,
+ project,
+}) => {
+ let warning = null;
+
+ const responseData = await Promise.all(
+ utilizationData.map(async (item) => {
+ const publicItem = stripInternalDetails(item);
+ publicItem.forecast = null;
+
+ if (selectedMode !== FORECAST_MODES.HISTORICAL) {
+ const { forecastDays, warning: fw } = await determineForecastDays(selectedMode, project);
+ if (fw) warning = fw;
+
+ const weeklyBuckets = bucketUtilizationByWeek(item.toolGroupDetails, rangeStart, rangeEnd);
+ publicItem.forecast = forecastUtilization(weeklyBuckets, forecastDays);
+ }
+
+ return publicItem;
+ }),
+ );
+
+ if (warning) {
+ responseData.forEach((item) => {
+ item.warning = warning;
+ });
+ }
+
+ return responseData;
+};
+
+// ─── buildReportPayload ───
+const buildReportPayload = (utilizationData, rangeStart, rangeEnd, project) => ({
+ utilizationData,
+ alerts: generateMaintenanceAlerts(utilizationData),
+ balancing: generateResourceBalancingSuggestions(utilizationData),
+ recommendations: generateRecommendations(utilizationData),
+ summary: buildInsightsSummary(utilizationData),
+ metadata: {
+ generatedDate: new Date().toLocaleString(),
+ dateRange: `${rangeStart.toISOString()} to ${rangeEnd.toISOString()}`,
+ projectFilter: project || 'ALL',
+ },
+});
+
+module.exports = {
+ classifyUtilization,
+ calculateCheckedOutHours,
+ buildToolFilter,
+ parseDateRange,
+ groupToolsByType,
+ calculateGroupUtilization,
+ buildCacheKey,
+ computeUtilizationData,
+ bucketUtilizationByWeek,
+ forecastUtilization,
+ generateMaintenanceAlerts,
+ generateResourceBalancingSuggestions,
+ generateRecommendations,
+ stripInternalDetails,
+ buildInsightsSummary,
+ determineForecastDays,
+ buildUtilizationResponse,
+ buildReportPayload,
+};
diff --git a/src/helpers/toolUtilizationReportHelpers.js b/src/helpers/toolUtilizationReportHelpers.js
new file mode 100644
index 000000000..d4c85a0f0
--- /dev/null
+++ b/src/helpers/toolUtilizationReportHelpers.js
@@ -0,0 +1,143 @@
+const PDFDocument = require('pdfkit');
+const { Parser } = require('json2csv');
+const { PDF_STYLES, PDF_MOVE_DOWN_HALF } = require('../constants/toolUtilization');
+
+// ─── writePDFSection (internal helper) ───
+const writePDFSection = (doc, title, items, formatLine) => {
+ if (items.length === 0) return;
+ doc.moveDown();
+ doc.fontSize(PDF_STYLES.FONT_SIZE_SECTION_HEADER).font('Helvetica-Bold').text(title);
+ doc.moveDown(PDF_MOVE_DOWN_HALF);
+ items.forEach((item, idx) => {
+ if (doc.y > PDF_STYLES.PAGE_BREAK_THRESHOLD) doc.addPage();
+ doc.fontSize(PDF_STYLES.FONT_SIZE_DETAIL).font('Helvetica');
+ doc.text(formatLine(item, idx));
+ });
+};
+
+// ─── generatePDFReport ───
+const generatePDFReport = (res, reportData) => {
+ const { utilizationData, alerts, balancing, recommendations, summary, metadata } = reportData;
+ const doc = new PDFDocument({
+ margin: PDF_STYLES.PAGE_MARGIN,
+ bufferPages: true,
+ compress: true,
+ });
+ const filename = `tool-utilization-report-${Date.now()}.pdf`;
+
+ res.setHeader('Content-Type', 'application/pdf');
+ res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
+ doc.pipe(res);
+
+ doc
+ .fontSize(PDF_STYLES.FONT_SIZE_TITLE)
+ .font('Helvetica-Bold')
+ .text('Tool Utilization & Procurement/Operations Report', { align: 'center' });
+ doc.moveDown();
+
+ doc.fontSize(PDF_STYLES.FONT_SIZE_METADATA).font('Helvetica').fillColor('#666666');
+ doc.text(`Generated: ${metadata.generatedDate}`);
+ doc.text(`Date Range: ${metadata.dateRange}`);
+ doc.text(`Project Filter: ${metadata.projectFilter}`);
+ doc.moveDown();
+ doc.fillColor('#000000');
+
+ doc.fontSize(PDF_STYLES.FONT_SIZE_SECTION_HEADER).font('Helvetica-Bold').text('Summary');
+ doc.fontSize(PDF_STYLES.FONT_SIZE_BODY).font('Helvetica');
+ doc.text(`Total Tool Types: ${summary.totalToolTypes}`);
+ doc.text(`Average Utilization: ${summary.averageUtilization}%`);
+ doc.text(
+ `Under-utilized: ${summary.underUtilized} | Normal: ${summary.normal} | Over-utilized: ${summary.overUtilized}`,
+ );
+ doc.moveDown();
+
+ doc
+ .fontSize(PDF_STYLES.FONT_SIZE_SECTION_HEADER)
+ .font('Helvetica-Bold')
+ .text('Utilization Details');
+ doc.moveDown(PDF_MOVE_DOWN_HALF);
+ utilizationData.forEach((item) => {
+ if (doc.y > PDF_STYLES.PAGE_BREAK_THRESHOLD) doc.addPage();
+ doc.fontSize(PDF_STYLES.FONT_SIZE_BODY).font('Helvetica-Bold');
+ doc.text(`${item.name} — ${item.utilizationRate}% (${item.classification.label})`);
+ doc.fontSize(PDF_STYLES.FONT_SIZE_DETAIL).font('Helvetica');
+ doc.text(` Downtime: ${item.downtime} hrs | Tool Count: ${item.toolCount}`);
+ doc.moveDown(PDF_MOVE_DOWN_HALF);
+ });
+
+ writePDFSection(
+ doc,
+ 'Maintenance Alerts',
+ alerts,
+ (alert) => `\u2022 [${alert.urgency.toUpperCase()}] ${alert.toolName}: ${alert.message}`,
+ );
+
+ writePDFSection(
+ doc,
+ 'Resource Balancing Suggestions',
+ balancing,
+ (item, idx) => `${idx + 1}. ${item.suggestion} ${item.rationale}`,
+ );
+
+ writePDFSection(
+ doc,
+ 'Recommendations',
+ recommendations,
+ (rec) => `\u2022 ${rec.toolName}: ${rec.action}`,
+ );
+
+ doc.end();
+};
+
+// ─── generateCSVReport ───
+const generateCSVReport = (res, reportData) => {
+ const { utilizationData, alerts, recommendations } = reportData;
+ const filename = `tool-utilization-report-${Date.now()}.csv`;
+
+ res.setHeader('Content-Type', 'text/csv; charset=utf-8');
+ res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
+
+ const alertsByTool = {};
+ alerts.forEach((alert) => {
+ if (!alertsByTool[alert.toolName]) alertsByTool[alert.toolName] = [];
+ alertsByTool[alert.toolName].push(alert.message);
+ });
+
+ const recByTool = {};
+ recommendations.forEach((rec) => {
+ recByTool[rec.toolName] = rec.action;
+ });
+
+ const rows = utilizationData.map((item) => ({
+ name: item.name,
+ utilizationRate: item.utilizationRate,
+ downtime: item.downtime,
+ classificationLabel: item.classification.label,
+ trafficLight: item.classification.trafficLight,
+ toolCount: item.toolCount,
+ maintenanceAlert: (alertsByTool[item.name] || []).join('; ') || 'None',
+ recommendation: recByTool[item.name] || 'None',
+ }));
+
+ const fields = [
+ { label: 'Tool Name', value: 'name' },
+ { label: 'Utilization Rate (%)', value: 'utilizationRate' },
+ { label: 'Downtime (hours)', value: 'downtime' },
+ { label: 'Classification', value: 'classificationLabel' },
+ { label: 'Traffic Light', value: 'trafficLight' },
+ { label: 'Tool Count', value: 'toolCount' },
+ { label: 'Maintenance Alert', value: 'maintenanceAlert' },
+ { label: 'Recommendation', value: 'recommendation' },
+ ];
+
+ const parser = new Parser({ fields });
+ const csv = parser.parse(rows);
+ res.send(`\ufeff${csv}`);
+};
+
+module.exports = {
+ generatePDFReport,
+ generateCSVReport,
+};
diff --git a/src/helpers/userHelper.js b/src/helpers/userHelper.js
index e2ab0df4b..4fa26c802 100644
--- a/src/helpers/userHelper.js
+++ b/src/helpers/userHelper.js
@@ -39,7 +39,6 @@ const Timer = require('../models/timer');
const DEFAULT_CC_EMAILS = ['onecommunityglobal@gmail.com', 'jae@onecommunityglobal.org'];
const DEFAULT_BCC_EMAILS = ['onecommunityhospitality@gmail.com'];
const DEFAULT_REPLY_TO = ['jae@onecommunityglobal.org'];
-const { COMPANY_TZ } = require('../constants/company');
const delay = (ms) =>
new Promise((resolve) => {
@@ -2260,7 +2259,7 @@ const userHelper = function () {
const lastDay = moment(person.endDate).format('YYYY-MM-DD');
logger.logInfo(`User with id: ${user._id}'s final Day is set at ${moment().format()}.`);
person.teams.map(async (teamId) => {
- const managementEmails = await getTeamManagementEmail(teamId);
+ const managementEmails = await userHelper.getTeamManagementEmail(teamId);
if (Array.isArray(managementEmails) && managementEmails.length > 0) {
managementEmails.forEach((management) => {
recipients.push(management.email);
@@ -2297,7 +2296,7 @@ const userHelper = function () {
const lastDay = moment(person.endDate).format('YYYY-MM-DD');
logger.logInfo(`User with id: ${user._id} was de-activated at ${moment().format()}.`);
person.teams.map(async (teamId) => {
- const managementEmails = await getTeamManagementEmail(teamId);
+ const managementEmails = await userHelper.getTeamManagementEmail(teamId);
if (Array.isArray(managementEmails) && managementEmails.length > 0) {
managementEmails.forEach((management) => {
recipients.push(management.email);
@@ -2628,316 +2627,12 @@ const userHelper = function () {
}
};
- const sendUserPausedEmail = ({ firstName, lastName, email, reactivationDate, recipients }) => {
- const returnDate = moment(reactivationDate)
- .tz(COMPANY_TZ)
- .add(1, 'day') // adding a day to make it clear they return on the day of reactivation
- .format('M-D-YYYY');
- const subject = `IMPORTANT: ${firstName} ${lastName} has been PAUSED in the Highest Good Network`;
-
- const emailBody = `
-
Management,
-
- Please note that ${firstName} ${lastName} has been PAUSED in the Highest Good Network.
-
-
- Please confirm all work has been wrapped up until they return on
- ${returnDate}.
-
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- const sendUserSeparatedEmail = ({ firstName, lastName, email, recipients, endDate }) => {
- const formattedFinalDay = moment(endDate).tz(COMPANY_TZ).format('M-D-YYYY');
- const subject = `IMPORTANT: ${firstName} ${lastName} has been deactivated in the Highest Good Network`;
-
- const emailBody = `
- Management,
-
- Please note that ${firstName} ${lastName} has been DEACTIVATED and made inactive in the Highest Good Network from ${formattedFinalDay} onwards.
-
-
- Please confirm all work has been wrapped up and nothing further is required.
-
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- const sendUserActivatedEmail = ({ firstName, lastName, email, recipients }) => {
- const subject = `IMPORTANT: ${firstName} ${lastName} has been activated in the Highest Good Network`;
-
- const emailBody = `
- Management,
-
- ${firstName} ${lastName} has been activated in the Highest Good Network.
-
- Email: ${email}
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- const sendUserScheduledSeparationEmail = ({
- firstName,
- lastName,
- email,
- endDate,
- recipients,
- }) => {
- const formattedFinalDay = endDate ? moment(endDate).tz(COMPANY_TZ).format('M-D-YYYY') : 'N/A';
- const subject = `IMPORTANT: ${firstName} ${lastName} has a FINAL DAY scheduled in the Highest Good Network`;
-
- const emailBody = `
- Management,
-
- Please note that ${firstName} ${lastName} has a FINAL DAY scheduled in the Highest Good Network.
-
-
- The final day is set for ${formattedFinalDay}, and they have until the end of this day to continue logging hours.
-
-
- Please begin wrapping up any remaining work as they will be deactivated the following day.
-
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- const sendUserResumedEmail = ({ firstName, lastName, email, recipients, pausedOn }) => {
- const formattedPausedOn = pausedOn
- ? moment(pausedOn).tz(COMPANY_TZ).format('M-D-YYYY')
- : 'an earlier date';
- const subject = `IMPORTANT: ${firstName} ${lastName} has been RESUMED in the Highest Good Network`;
-
- const emailBody = `
- Management,
-
- Please note that ${firstName} ${lastName}, who was previously PAUSED in the Highest Good Network on
- ${formattedPausedOn}, has now been RESUMED and is active again.
-
-
- ${firstName} ${lastName} will remain active until they are deactivated, paused again,
- or a final day is scheduled.
-
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- const sendUserReactivatedAfterSeparation = ({
- firstName,
- lastName,
- email,
- recipients,
- previousEndDate,
- }) => {
- const formattedPreviousEndDate = moment(previousEndDate).tz(COMPANY_TZ).format('M-D-YYYY');
- const subject = `IMPORTANT: ${firstName} ${lastName} has been REACTIVATED in the Highest Good Network`;
-
- const emailBody = `
- Management,
-
- Please note that ${firstName} ${lastName}, who was previously DEACTIVATED from the Highest Good Network on
- ${formattedPreviousEndDate}, has now been REACTIVATED.
-
-
- ${firstName} ${lastName} is currently active and will remain so until they are deactivated,
- paused, or a final day is scheduled.
-
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- const sendUserCancelledSeparationEmail = ({
- firstName,
- lastName,
- email,
- recipients,
- previousEndDate,
- }) => {
- const formattedPreviousEndDate = moment(previousEndDate).tz(COMPANY_TZ).format('M-D-YYYY');
- const subject = `IMPORTANT: Final Day has been CANCELLED for ${firstName} ${lastName}`;
-
- const emailBody = `
- Management,
-
- Please note that the previously scheduled FINAL DAY for ${firstName} ${lastName}
- in the Highest Good Network as ${formattedPreviousEndDate} has now been REMOVED.
-
-
- ${firstName} ${lastName} is currently active and will remain so until they are
- deactivated, paused, or a new final day is scheduled.
-
- With Gratitude,
One Community
- `;
-
- emailSender(recipients, subject, emailBody, null, email);
- };
-
- async function finalizeUserEndDates() {
- const now = moment.tz(COMPANY_TZ);
-
- // 1) Only users who are scheduled for separation (still active)
- const users = await userProfile.find({
- isActive: true,
- endDate: { $ne: null },
- inactiveReason: InactiveReason.SCHEDULED_SEPARATION,
- // Safety: should not be a paused user
- reactivationDate: { $in: [null, undefined] },
- });
-
- console.log('Found', users.length, 'scheduled-separation users to process.');
-
- for (const user of users) {
- const scheduledEndMoment = moment(user.endDate).tz(COMPANY_TZ).endOf('day');
- const recipients = await getEmailRecipientsForStatusChange(user._id);
-
- // 2) 3-week email logic (trigger window starts at start of day, 3 weeks before endDate)
- if (
- !user.finalEmailThreeWeeksSent &&
- now.isSameOrAfter(
- moment(scheduledEndMoment)
- .subtract(WEEKS_BEFORE_END_DATE_FOR_EMAIL, 'weeks')
- .startOf('day'),
- ) &&
- now.isBefore(scheduledEndMoment) // only while still pending
- ) {
- await sendThreeWeekFinalDayEmail({
- email: user.email,
- firstName: user.firstName,
- lastName: user.lastName,
- endDate: user.endDate, // IMPORTANT: email references scheduled endDate
- recipients,
- });
-
- user.finalEmailThreeWeeksSent = true;
- await user.save();
- }
-
- // 3) If endDate hasn't passed yet, skip finalization
- if (now.isBefore(scheduledEndMoment)) continue;
-
- // 4) Finalize separation
- if (user.deactivatedAt) continue; // safety check
-
- user.deactivatedAt = now.toDate();
- user.isActive = false;
- user.inactiveReason = InactiveReason.SEPARATED;
- user.endDate = resolveEffectiveEndDate(user).toDate();
- sendUserSeparatedEmail({
- firstName: user.firstName,
- lastName: user.lastName,
- email: user.email,
- recipients,
- endDate: user.endDate,
- });
- await user.save();
- }
- }
-
- function resolveEffectiveEndDate(user) {
- // 1) endDate + lastActivityAt → earlier of the two
- if (user?.endDate && user?.lastActivityAt) {
- return moment.min(
- moment(user.endDate).tz(COMPANY_TZ),
- moment(user.lastActivityAt).tz(COMPANY_TZ),
- );
- }
-
- // 2) no lastActivityAt → use createdDate (normalized to COMPANY_TZ)
- if (!user?.lastActivityAt && user?.createdDate) {
- return moment.tz(user.createdDate, 'YYYY-MM-DD', COMPANY_TZ).startOf('day');
- }
-
- // 3) only endDate present
- if (user?.endDate) {
- return moment(user.endDate).tz(COMPANY_TZ);
- }
-
- // 4) only lastActivityAt present
- if (user?.lastActivityAt) {
- return moment(user.lastActivityAt).tz(COMPANY_TZ);
- }
-
- // 5) fallback → now
- return moment().tz(COMPANY_TZ);
- }
-
- const sendThreeWeekFinalDayEmail = async ({
- email,
- firstName,
- lastName,
- endDate,
- recipients,
- }) => {
- const subject = `IMPORTANT: Upcoming final day for ${firstName} ${lastName} in the Highest Good Network`;
-
- const formattedEndDate = moment(endDate).tz(COMPANY_TZ).format('M-D-YYYY');
-
- const emailBody = `
- Management,
-
-
- Please note that the final day for ${firstName} ${lastName}
- in the Highest Good Network is set for ${formattedEndDate}.
-
-
-
- This is a reminder sent approximately three weeks in advance.
- Please begin wrapping up any remaining work and transitions with this individual.
-
-
-
- Please note that they will be actively able to log hours until the end of their final day.
-
-
- With gratitude,
One Community
- `;
- try {
- await emailSender(recipients, subject, emailBody, null, email, email);
- } catch (err) {
- logger.logException(err, 'Failed to send 3-week final day email');
- }
- };
-
- const getEmailRecipientsForStatusChange = async (userId) => {
- const emailReceivers = await userProfile.find(
- { isActive: true, role: { $in: ['Owner'] } },
- '_id isActive role email',
- );
- const recipients = emailReceivers.map((receiver) => receiver.email);
-
- try {
- const findUser = await userProfile.findById(userId, 'teams');
- findUser.teams.map(async (teamId) => {
- const managementEmails = await getTeamManagementEmail(teamId);
- if (Array.isArray(managementEmails) && managementEmails.length > 0) {
- managementEmails.forEach((management) => {
- recipients.push(management.email);
- });
- }
- });
- } catch (err) {
- logger.logException(err, 'Unexpected error in finding menagement team');
- }
- return recipients;
- };
-
return {
changeBadgeCount,
getUserName,
getTeamMembers,
checkTeamCodeMismatch,
+ getTeamManagementEmail,
validateProfilePic,
assignBlueSquareForTimeNotMet,
applyMissedHourForCoreTeam,
@@ -2954,16 +2649,6 @@ const userHelper = function () {
deleteExpiredTokens,
deleteOldTimeOffRequests,
getProfileImagesFromWebsite,
- sendUserPausedEmail,
- sendUserSeparatedEmail,
- sendUserActivatedEmail,
- sendUserScheduledSeparationEmail,
- sendUserResumedEmail,
- sendUserReactivatedAfterSeparation,
- sendUserCancelledSeparationEmail,
- finalizeUserEndDates,
- getEmailRecipientsForStatusChange,
- getTeamManagementEmail,
};
};
diff --git a/src/routes/bmdashboard/toolUtilizationRouter.js b/src/routes/bmdashboard/toolUtilizationRouter.js
index b981c3e57..9a4026c82 100644
--- a/src/routes/bmdashboard/toolUtilizationRouter.js
+++ b/src/routes/bmdashboard/toolUtilizationRouter.js
@@ -7,6 +7,8 @@ const routes = function (BuildingTool) {
);
toolUtilizationRouter.route('/tools/utilization').get(controller.getUtilization);
+ toolUtilizationRouter.route('/tools/utilization/insights').get(controller.getInsights);
+ toolUtilizationRouter.route('/tools/utilization/export').get(controller.exportReport);
return toolUtilizationRouter;
};
diff --git a/src/routes/studentTaskRouter.js b/src/routes/studentTaskRouter.js
index 26bcfc144..0a2290e5a 100644
--- a/src/routes/studentTaskRouter.js
+++ b/src/routes/studentTaskRouter.js
@@ -7,8 +7,6 @@ const routes = function () {
studentTaskRouter.route('/student/tasks').get(controller.getStudentTasks);
- studentTaskRouter.route('/student/tasks/:taskId/log-hours').post(controller.logHours);
-
studentTaskRouter.route('/student/tasks/:taskId/progress').put(controller.updateTaskProgress);
studentTaskRouter
diff --git a/src/startup/cors.js b/src/startup/cors.js
index 61ac21c23..16199d719 100644
--- a/src/startup/cors.js
+++ b/src/startup/cors.js
@@ -25,7 +25,7 @@ module.exports = function (app) {
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
- allowedHeaders: ['Content-Type', 'Authorization', 'Cache-Control', 'Pragma'],
+ allowedHeaders: ['Content-Type', 'Authorization'],
}),
);
};
diff --git a/src/startup/middleware.js b/src/startup/middleware.js
index d6f14cee4..c9c1b29a4 100644
--- a/src/startup/middleware.js
+++ b/src/startup/middleware.js
@@ -133,15 +133,15 @@ module.exports = function (app) {
try {
payload = jwt.verify(authToken, config.JWT_SECRET);
- } catch (error) {
+ } catch {
res.status(401).send('Invalid token');
return;
}
if (
!payload ||
- !payload.expiryTimestamp ||
- !payload.userid ||
- !payload.role ||
+ !payload?.expiryTimestamp ||
+ !payload?.userid ||
+ !payload?.role ||
moment().isAfter(payload.expiryTimestamp)
) {
res.status(401).send('Unauthorized request');
diff --git a/yarn.lock b/yarn.lock
index deb3f7562..e809952ad 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -13,17 +13,15 @@
tslib "^2.8.1"
"@apimatic/axios-client-adapter@^0.3.4":
- version "0.3.21"
- resolved "https://registry.yarnpkg.com/@apimatic/axios-client-adapter/-/axios-client-adapter-0.3.21.tgz#94fa288fffefc6cade844216f6a701def1f74a63"
- integrity sha512-pr/XvAvH9FjbpwM+B7vHQxM7alocOX1kLNtSpXKW3yxTYxksF3ydnUuQ85rRbCoNpyfMOIjnRBCNUBzX5p2Hnw==
+ version "0.3.20"
dependencies:
- "@apimatic/convert-to-stream" "^0.1.9"
+ "@apimatic/convert-to-stream" "^0.1.8"
"@apimatic/core-interfaces" "^0.2.14"
"@apimatic/file-wrapper" "^0.3.9"
"@apimatic/http-headers" "^0.3.8"
"@apimatic/http-query" "^0.3.9"
"@apimatic/json-bigint" "^1.2.0"
- "@apimatic/proxy" "^0.1.4"
+ "@apimatic/proxy" "^0.1.3"
axios "^1.8.4"
detect-browser "^5.3.0"
detect-node "^2.1.0"
@@ -32,10 +30,8 @@
tiny-warning "^1.0.3"
tslib "^2.8.1"
-"@apimatic/convert-to-stream@^0.1.9":
- version "0.1.9"
- resolved "https://registry.yarnpkg.com/@apimatic/convert-to-stream/-/convert-to-stream-0.1.9.tgz#4a46a66330d69e8ea5c3bff99739063bcdad90b8"
- integrity sha512-C9NEKnDZoTRBRVeUGXVyAEmy6P5o+8oLwEckTKj0iBlExJLEXNt14nf4wxfzRO1KR8j5Bw8S6yStKCrQzcVERA==
+"@apimatic/convert-to-stream@^0.1.8":
+ version "0.1.8"
dependencies:
tslib "2.8.1"
@@ -49,11 +45,9 @@
tslib "^2.8.1"
"@apimatic/core@^0.10.14":
- version "0.10.29"
- resolved "https://registry.yarnpkg.com/@apimatic/core/-/core-0.10.29.tgz#df4399643be47f38a3c8f81fe4bc2f99ac56ed0e"
- integrity sha512-QhORiq0QbjlDMrw8ZZsAeG2DzE6QgGz5ukD5w2MOWE/3iIWnUDEROjmc2SfhyiGsE3GoEJ8cyhMMdjlOioP6ww==
+ version "0.10.28"
dependencies:
- "@apimatic/convert-to-stream" "^0.1.9"
+ "@apimatic/convert-to-stream" "^0.1.8"
"@apimatic/core-interfaces" "^0.2.14"
"@apimatic/file-wrapper" "^0.3.9"
"@apimatic/http-headers" "^0.3.8"
@@ -106,10 +100,8 @@
"@apimatic/http-headers" "^0.3.8"
tslib "^2.8.1"
-"@apimatic/proxy@^0.1.4":
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/@apimatic/proxy/-/proxy-0.1.4.tgz#9a5b729ac3da8edc01ca5846f14e7f29b744f8d0"
- integrity sha512-Vzgfu7wcA5aEJyj2SjQ00Tb06fhBof8gDo1kSsF6sZBm4QjdFywN5AMbQwhfFOKjHqcsNmJspdeqcdymUQ77jA==
+"@apimatic/proxy@^0.1.3":
+ version "0.1.3"
dependencies:
http-proxy-agent "^7.0.2"
https-proxy-agent "^7.0.6"
@@ -192,7 +184,14 @@
dependencies:
tslib "^2.8.1"
-"@atproto/syntax@^0.5.0", "@atproto/syntax@^0.5.4":
+"@atproto/syntax@^0.5.0":
+ version "0.5.4"
+ resolved "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.5.4.tgz"
+ integrity sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw==
+ dependencies:
+ tslib "^2.8.1"
+
+"@atproto/syntax@^0.5.4":
version "0.5.4"
resolved "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.5.4.tgz"
integrity sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw==
@@ -250,7 +249,7 @@
"@smithy/util-utf8" "^2.0.0"
tslib "^2.6.2"
-"@aws-crypto/sha256-js@5.2.0", "@aws-crypto/sha256-js@^5.2.0":
+"@aws-crypto/sha256-js@^5.2.0", "@aws-crypto/sha256-js@5.2.0":
version "5.2.0"
resolved "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz"
integrity sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==
@@ -266,7 +265,7 @@
dependencies:
tslib "^2.6.2"
-"@aws-crypto/util@5.2.0", "@aws-crypto/util@^5.2.0":
+"@aws-crypto/util@^5.2.0", "@aws-crypto/util@5.2.0":
version "5.2.0"
resolved "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz"
integrity sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==
@@ -720,7 +719,7 @@
"@smithy/types" "^4.11.0"
tslib "^2.6.2"
-"@aws-sdk/types@3.956.0", "@aws-sdk/types@^3.222.0":
+"@aws-sdk/types@^3.222.0", "@aws-sdk/types@3.956.0":
version "3.956.0"
resolved "https://registry.npmjs.org/@aws-sdk/types/-/types-3.956.0.tgz"
integrity sha512-DMRU/p9wAlAJxEjegnLwduCA8YP2pcT/sIJ+17KSF38c5cC6CbBhykwbZLECTo+zYzoFrOqeLbqE6paH8Gx3ug==
@@ -804,7 +803,7 @@
"@azure/core-util" "^1.13.0"
tslib "^2.6.2"
-"@azure/core-client@^1.9.3":
+"@azure/core-client@^1.10.0", "@azure/core-client@^1.9.3":
version "1.10.1"
resolved "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz"
integrity sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==
@@ -818,11 +817,11 @@
tslib "^2.6.2"
"@azure/core-http-compat@^2.2.0":
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/@azure/core-http-compat/-/core-http-compat-2.4.0.tgz#28322f317eb46d625d7d18bb0eb02c2654f5de1b"
- integrity sha512-f1P96IB399YiN2ARYHP7EpZi3Bf3wH4SN2lGzrw7JVwm7bbsVYtf2iKSBwTywD2P62NOPZGHFSZi+6jjb75JuA==
+ version "2.3.1"
dependencies:
"@azure/abort-controller" "^2.1.2"
+ "@azure/core-client" "^1.10.0"
+ "@azure/core-rest-pipeline" "^1.22.0"
"@azure/core-lro@^2.2.0":
version "2.7.2"
@@ -842,16 +841,14 @@
tslib "^2.6.2"
"@azure/core-rest-pipeline@^1.19.1", "@azure/core-rest-pipeline@^1.22.0":
- version "1.23.0"
- resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.23.0.tgz#35f16e1c180ca9545c260ac124b751be1da9c08c"
- integrity sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ==
+ version "1.22.2"
dependencies:
"@azure/abort-controller" "^2.1.2"
"@azure/core-auth" "^1.10.0"
"@azure/core-tracing" "^1.3.0"
"@azure/core-util" "^1.13.0"
"@azure/logger" "^1.3.0"
- "@typespec/ts-http-runtime" "^0.3.4"
+ "@typespec/ts-http-runtime" "^0.3.0"
tslib "^2.6.2"
"@azure/core-tracing@^1.2.0", "@azure/core-tracing@^1.3.0":
@@ -871,11 +868,9 @@
tslib "^2.6.2"
"@azure/core-xml@^1.4.5":
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/@azure/core-xml/-/core-xml-1.5.1.tgz#5528aef8e561ee97c605d0080b8803a21d2be783"
- integrity sha512-xcNRHqCoSp4AunOALEae6A8f3qATb83gSrm31Iqb01OzblvC3/W/bfXozcq78EzIdzZzuH1bZ2NvRR0TdX709w==
+ version "1.5.0"
dependencies:
- fast-xml-parser "^5.5.9"
+ fast-xml-parser "^5.0.7"
tslib "^2.8.1"
"@azure/logger@^1.0.0", "@azure/logger@^1.1.4", "@azure/logger@^1.3.0":
@@ -887,9 +882,7 @@
tslib "^2.6.2"
"@azure/storage-blob@^12.26.0":
- version "12.31.0"
- resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.31.0.tgz#97b09be2bf6ab59739b862edd8124798362ce720"
- integrity sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg==
+ version "12.29.1"
dependencies:
"@azure/abort-controller" "^2.1.2"
"@azure/core-auth" "^1.9.0"
@@ -902,14 +895,12 @@
"@azure/core-util" "^1.11.0"
"@azure/core-xml" "^1.4.5"
"@azure/logger" "^1.1.4"
- "@azure/storage-common" "^12.3.0"
+ "@azure/storage-common" "^12.1.1"
events "^3.0.0"
tslib "^2.8.1"
-"@azure/storage-common@^12.3.0":
- version "12.3.0"
- resolved "https://registry.yarnpkg.com/@azure/storage-common/-/storage-common-12.3.0.tgz#5bf257383836e67a426c91d7e9678479afe802a9"
- integrity sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ==
+"@azure/storage-common@^12.1.1":
+ version "12.1.1"
dependencies:
"@azure/abort-controller" "^2.1.2"
"@azure/core-auth" "^1.9.0"
@@ -922,9 +913,7 @@
tslib "^2.8.1"
"@babel/cli@^7.15.4":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.28.6.tgz#1da8eb79f92cbe75542b853b3b1db683c5ea406a"
- integrity sha512-6EUNcuBbNkj08Oj4gAZ+BUU8yLCgKzgVX4gaTh09Ya2C8ICM4P+G30g4m3akRxSYAp3A/gnWchrNst7px4/nUQ==
+ version "7.28.3"
dependencies:
"@jridgewell/trace-mapping" "^0.3.28"
commander "^6.2.0"
@@ -937,34 +926,28 @@
"@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.3"
chokidar "^3.6.0"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c"
- integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-validator-identifier" "^7.28.5"
+ "@babel/helper-validator-identifier" "^7.27.1"
js-tokens "^4.0.0"
picocolors "^1.1.1"
-"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.3":
- version "7.29.3"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.3.tgz#e3f5347f0589596c91d227ccb6a541d37fb1307b"
- integrity sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==
-
-"@babel/core@^7.10.2", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322"
- integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==
- dependencies:
- "@babel/code-frame" "^7.29.0"
- "@babel/generator" "^7.29.0"
- "@babel/helper-compilation-targets" "^7.28.6"
- "@babel/helper-module-transforms" "^7.28.6"
- "@babel/helpers" "^7.28.6"
- "@babel/parser" "^7.29.0"
- "@babel/template" "^7.28.6"
- "@babel/traverse" "^7.29.0"
- "@babel/types" "^7.29.0"
+"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5":
+ version "7.28.5"
+
+"@babel/core@^7.0.0", "@babel/core@^7.0.0 || ^8.0.0-0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.10.2", "@babel/core@^7.11.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.23.9", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.8.0":
+ version "7.28.5"
+ dependencies:
+ "@babel/code-frame" "^7.27.1"
+ "@babel/generator" "^7.28.5"
+ "@babel/helper-compilation-targets" "^7.27.2"
+ "@babel/helper-module-transforms" "^7.28.3"
+ "@babel/helpers" "^7.28.4"
+ "@babel/parser" "^7.28.5"
+ "@babel/template" "^7.27.2"
+ "@babel/traverse" "^7.28.5"
+ "@babel/types" "^7.28.5"
"@jridgewell/remapping" "^2.3.5"
convert-source-map "^2.0.0"
debug "^4.1.0"
@@ -973,21 +956,17 @@
semver "^6.3.1"
"@babel/eslint-parser@^7.15.0":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.28.6.tgz#6a294a4add732ebe7ded8a8d2792dd03dd81dc3f"
- integrity sha512-QGmsKi2PBO/MHSQk+AAgA9R6OHQr+VqnniFE0eMWZcVcfBZoA2dKn2hUsl3Csg/Plt9opRUWdY7//VXsrIlEiA==
+ version "7.28.5"
dependencies:
"@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1"
eslint-visitor-keys "^2.1.0"
semver "^6.3.1"
-"@babel/generator@^7.29.0", "@babel/generator@^7.7.2":
- version "7.29.1"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50"
- integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==
+"@babel/generator@^7.28.5", "@babel/generator@^7.7.2":
+ version "7.28.5"
dependencies:
- "@babel/parser" "^7.29.0"
- "@babel/types" "^7.29.0"
+ "@babel/parser" "^7.28.5"
+ "@babel/types" "^7.28.5"
"@jridgewell/gen-mapping" "^0.3.12"
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
@@ -999,31 +978,27 @@
dependencies:
"@babel/types" "^7.27.3"
-"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25"
- integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==
+"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2":
+ version "7.27.2"
dependencies:
- "@babel/compat-data" "^7.28.6"
+ "@babel/compat-data" "^7.27.2"
"@babel/helper-validator-option" "^7.27.1"
browserslist "^4.24.0"
lru-cache "^5.1.1"
semver "^6.3.1"
-"@babel/helper-create-class-features-plugin@^7.28.6":
- version "7.29.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz#67328947d956f06fc7b48def269bf0489155fd42"
- integrity sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==
+"@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3":
+ version "7.28.5"
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.3"
"@babel/helper-member-expression-to-functions" "^7.28.5"
"@babel/helper-optimise-call-expression" "^7.27.1"
- "@babel/helper-replace-supers" "^7.28.6"
+ "@babel/helper-replace-supers" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
- "@babel/traverse" "^7.29.0"
+ "@babel/traverse" "^7.28.5"
semver "^6.3.1"
-"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1", "@babel/helper-create-regexp-features-plugin@^7.28.5":
+"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz"
integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==
@@ -1032,23 +1007,21 @@
regexpu-core "^6.3.1"
semver "^6.3.1"
-"@babel/helper-define-polyfill-provider@^0.6.5", "@babel/helper-define-polyfill-provider@^0.6.8":
- version "0.6.8"
- resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz#cf1e4462b613f2b54c41e6ff758d5dfcaa2c85d1"
- integrity sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==
+"@babel/helper-define-polyfill-provider@^0.6.5":
+ version "0.6.5"
dependencies:
- "@babel/helper-compilation-targets" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
- debug "^4.4.3"
+ "@babel/helper-compilation-targets" "^7.27.2"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ debug "^4.4.1"
lodash.debounce "^4.0.8"
- resolve "^1.22.11"
+ resolve "^1.22.10"
"@babel/helper-globals@^7.28.0":
version "7.28.0"
resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz"
integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==
-"@babel/helper-member-expression-to-functions@^7.28.5":
+"@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz"
integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==
@@ -1056,22 +1029,18 @@
"@babel/traverse" "^7.28.5"
"@babel/types" "^7.28.5"
-"@babel/helper-module-imports@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c"
- integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==
+"@babel/helper-module-imports@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/traverse" "^7.28.6"
- "@babel/types" "^7.28.6"
+ "@babel/traverse" "^7.27.1"
+ "@babel/types" "^7.27.1"
-"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e"
- integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
+"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3":
+ version "7.28.3"
dependencies:
- "@babel/helper-module-imports" "^7.28.6"
- "@babel/helper-validator-identifier" "^7.28.5"
- "@babel/traverse" "^7.28.6"
+ "@babel/helper-module-imports" "^7.27.1"
+ "@babel/helper-validator-identifier" "^7.27.1"
+ "@babel/traverse" "^7.28.3"
"@babel/helper-optimise-call-expression@^7.27.1":
version "7.27.1"
@@ -1080,10 +1049,8 @@
dependencies:
"@babel/types" "^7.27.1"
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.28.6", "@babel/helper-plugin-utils@^7.8.0":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8"
- integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0":
+ version "7.27.1"
"@babel/helper-remap-async-to-generator@^7.27.1":
version "7.27.1"
@@ -1094,14 +1061,12 @@
"@babel/helper-wrap-function" "^7.27.1"
"@babel/traverse" "^7.27.1"
-"@babel/helper-replace-supers@^7.27.1", "@babel/helper-replace-supers@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz#94aa9a1d7423a00aead3f204f78834ce7d53fe44"
- integrity sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==
+"@babel/helper-replace-supers@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-member-expression-to-functions" "^7.28.5"
+ "@babel/helper-member-expression-to-functions" "^7.27.1"
"@babel/helper-optimise-call-expression" "^7.27.1"
- "@babel/traverse" "^7.28.6"
+ "@babel/traverse" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers@^7.27.1":
version "7.27.1"
@@ -1116,7 +1081,7 @@
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz"
integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
-"@babel/helper-validator-identifier@^7.28.5":
+"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz"
integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
@@ -1127,40 +1092,32 @@
integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==
"@babel/helper-wrap-function@^7.27.1":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz#4e349ff9222dab69a93a019cc296cdd8442e279a"
- integrity sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==
+ version "7.28.3"
dependencies:
- "@babel/template" "^7.28.6"
- "@babel/traverse" "^7.28.6"
- "@babel/types" "^7.28.6"
+ "@babel/template" "^7.27.2"
+ "@babel/traverse" "^7.28.3"
+ "@babel/types" "^7.28.2"
-"@babel/helpers@^7.28.6":
- version "7.29.2"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.2.tgz#9cfbccb02b8e229892c0b07038052cc1a8709c49"
- integrity sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==
+"@babel/helpers@^7.28.4":
+ version "7.28.4"
dependencies:
- "@babel/template" "^7.28.6"
- "@babel/types" "^7.29.0"
+ "@babel/template" "^7.27.2"
+ "@babel/types" "^7.28.4"
"@babel/node@^7.14.9":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.29.0.tgz#278d903d17bf80d361ed6ac9552125eebd5eab5f"
- integrity sha512-9UeU8F3rx2lOZXneEW2HTnTYdA8+fXP0kr54tk7d0fPomWNlZ6WJ2H9lunr5dSvr8FNY0CDnop3Km6jZ5NAUsQ==
+ version "7.28.0"
dependencies:
- "@babel/register" "^7.28.6"
+ "@babel/register" "^7.27.1"
commander "^6.2.0"
- core-js "^3.48.0"
+ core-js "^3.30.2"
node-environment-flags "^1.0.5"
regenerator-runtime "^0.14.0"
v8flags "^3.1.1"
-"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
- version "7.29.3"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e"
- integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==
+"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5":
+ version "7.28.5"
dependencies:
- "@babel/types" "^7.29.0"
+ "@babel/types" "^7.28.5"
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5":
version "7.28.5"
@@ -1184,14 +1141,6 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@^7.29.3":
- version "7.29.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz#2e14f9335803d892ccb67ef487e23cf9726156fe"
- integrity sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
-
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1":
version "7.27.1"
resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz"
@@ -1201,13 +1150,11 @@
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-optional-chaining" "^7.27.1"
-"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz#0e8289cec28baaf05d54fd08d81ae3676065f69f"
- integrity sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==
+"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.3":
+ version "7.28.3"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
- "@babel/traverse" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/traverse" "^7.28.3"
"@babel/plugin-proposal-logical-assignment-operators@^7.20.7":
version "7.20.7"
@@ -1250,19 +1197,15 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-import-assertions@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz#ae9bc1923a6ba527b70104dd2191b0cd872c8507"
- integrity sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==
+"@babel/plugin-syntax-import-assertions@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-syntax-import-attributes@^7.24.7", "@babel/plugin-syntax-import-attributes@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz#b71d5914665f60124e133696f17cd7669062c503"
- integrity sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==
+"@babel/plugin-syntax-import-attributes@^7.24.7", "@babel/plugin-syntax-import-attributes@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-syntax-import-meta@^7.10.4":
version "7.10.4"
@@ -1279,11 +1222,9 @@
"@babel/helper-plugin-utils" "^7.8.0"
"@babel/plugin-syntax-jsx@^7.7.2":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz#f8ca28bbd84883b5fea0e447c635b81ba73997ee"
- integrity sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
version "7.10.4"
@@ -1342,11 +1283,9 @@
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-syntax-typescript@^7.7.2":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz#c7b2ddf1d0a811145b1de800d1abd146af92e3a2"
- integrity sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-syntax-unicode-sets-regex@^7.18.6":
version "7.18.6"
@@ -1363,22 +1302,18 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-async-generator-functions@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz#63ed829820298f0bf143d5a4a68fb8c06ffd742f"
- integrity sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==
+"@babel/plugin-transform-async-generator-functions@^7.28.0":
+ version "7.28.0"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-remap-async-to-generator" "^7.27.1"
- "@babel/traverse" "^7.29.0"
+ "@babel/traverse" "^7.28.0"
-"@babel/plugin-transform-async-to-generator@^7.10.1", "@babel/plugin-transform-async-to-generator@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz#bd97b42237b2d1bc90d74bcb486c39be5b4d7e77"
- integrity sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==
+"@babel/plugin-transform-async-to-generator@^7.10.1", "@babel/plugin-transform-async-to-generator@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-module-imports" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-module-imports" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-remap-async-to-generator" "^7.27.1"
"@babel/plugin-transform-block-scoped-functions@^7.27.1":
@@ -1388,50 +1323,40 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-block-scoping@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz#e1ef5633448c24e76346125c2534eeb359699a99"
- integrity sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==
+"@babel/plugin-transform-block-scoping@^7.28.5":
+ version "7.28.5"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-class-properties@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz#d274a4478b6e782d9ea987fda09bdb6d28d66b72"
- integrity sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==
+"@babel/plugin-transform-class-properties@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-class-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-class-static-block@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz#1257491e8259c6d125ac4d9a6f39f9d2bf3dba70"
- integrity sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==
+"@babel/plugin-transform-class-static-block@^7.28.3":
+ version "7.28.3"
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-class-features-plugin" "^7.28.3"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-classes@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz#8f6fb79ba3703978e701ce2a97e373aae7dda4b7"
- integrity sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==
+"@babel/plugin-transform-classes@^7.28.4":
+ version "7.28.4"
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.3"
- "@babel/helper-compilation-targets" "^7.28.6"
+ "@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-globals" "^7.28.0"
- "@babel/helper-plugin-utils" "^7.28.6"
- "@babel/helper-replace-supers" "^7.28.6"
- "@babel/traverse" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/helper-replace-supers" "^7.27.1"
+ "@babel/traverse" "^7.28.4"
-"@babel/plugin-transform-computed-properties@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz#936824fc71c26cb5c433485776d79c8e7b0202d2"
- integrity sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==
+"@babel/plugin-transform-computed-properties@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
- "@babel/template" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/template" "^7.27.1"
-"@babel/plugin-transform-destructuring@^7.28.5":
+"@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz"
integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==
@@ -1439,13 +1364,11 @@
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.28.5"
-"@babel/plugin-transform-dotall-regex@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz#def31ed84e0fb6e25c71e53c124e7b76a4ab8e61"
- integrity sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==
+"@babel/plugin-transform-dotall-regex@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.28.5"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-duplicate-keys@^7.27.1":
version "7.27.1"
@@ -1454,13 +1377,11 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz#8014b8a6cfd0e7b92762724443bf0d2400f26df1"
- integrity sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==
+"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.28.5"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-dynamic-import@^7.27.1":
version "7.27.1"
@@ -1469,20 +1390,16 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-explicit-resource-management@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz#dd6788f982c8b77e86779d1d029591e39d9d8be7"
- integrity sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==
+"@babel/plugin-transform-explicit-resource-management@^7.28.0":
+ version "7.28.0"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
- "@babel/plugin-transform-destructuring" "^7.28.5"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/plugin-transform-destructuring" "^7.28.0"
-"@babel/plugin-transform-exponentiation-operator@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz#5e477eb7eafaf2ab5537a04aaafcf37e2d7f1091"
- integrity sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==
+"@babel/plugin-transform-exponentiation-operator@^7.28.5":
+ version "7.28.5"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-export-namespace-from@^7.27.1":
version "7.27.1"
@@ -1508,12 +1425,10 @@
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.27.1"
-"@babel/plugin-transform-json-strings@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz#4c8c15b2dc49e285d110a4cf3dac52fd2dfc3038"
- integrity sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==
+"@babel/plugin-transform-json-strings@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-literals@^7.27.1":
version "7.27.1"
@@ -1522,12 +1437,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-logical-assignment-operators@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz#53028a3d77e33c50ef30a8fce5ca17065936e605"
- integrity sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==
+"@babel/plugin-transform-logical-assignment-operators@^7.28.5":
+ version "7.28.5"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-member-expression-literals@^7.27.1":
version "7.27.1"
@@ -1544,23 +1457,19 @@
"@babel/helper-module-transforms" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-modules-commonjs@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz#c0232e0dfe66a734cc4ad0d5e75fc3321b6fdef1"
- integrity sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==
+"@babel/plugin-transform-modules-commonjs@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-module-transforms" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-module-transforms" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-modules-systemjs@^7.29.4":
- version "7.29.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz#f621105da99919c15cf4bde6fcc7346ef95e7b20"
- integrity sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==
+"@babel/plugin-transform-modules-systemjs@^7.28.5":
+ version "7.28.5"
dependencies:
- "@babel/helper-module-transforms" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-module-transforms" "^7.28.3"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-validator-identifier" "^7.28.5"
- "@babel/traverse" "^7.29.0"
+ "@babel/traverse" "^7.28.5"
"@babel/plugin-transform-modules-umd@^7.27.1":
version "7.27.1"
@@ -1570,13 +1479,11 @@
"@babel/helper-module-transforms" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-named-capturing-groups-regex@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz#a26cd51e09c4718588fc4cce1c5d1c0152102d6a"
- integrity sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.28.5"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-new-target@^7.27.1":
version "7.27.1"
@@ -1585,30 +1492,24 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-nullish-coalescing-operator@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz#9bc62096e90ab7a887f3ca9c469f6adec5679757"
- integrity sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==
+"@babel/plugin-transform-nullish-coalescing-operator@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-numeric-separator@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz#1310b0292762e7a4a335df5f580c3320ee7d9e9f"
- integrity sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==
+"@babel/plugin-transform-numeric-separator@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-object-rest-spread@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz#fdd4bc2d72480db6ca42aed5c051f148d7b067f7"
- integrity sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==
+"@babel/plugin-transform-object-rest-spread@^7.28.4":
+ version "7.28.4"
dependencies:
- "@babel/helper-compilation-targets" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
- "@babel/plugin-transform-destructuring" "^7.28.5"
+ "@babel/helper-compilation-targets" "^7.27.2"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/plugin-transform-destructuring" "^7.28.0"
"@babel/plugin-transform-parameters" "^7.27.7"
- "@babel/traverse" "^7.28.6"
+ "@babel/traverse" "^7.28.4"
"@babel/plugin-transform-object-super@^7.27.1":
version "7.27.1"
@@ -1618,19 +1519,15 @@
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-replace-supers" "^7.27.1"
-"@babel/plugin-transform-optional-catch-binding@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz#75107be14c78385978201a49c86414a150a20b4c"
- integrity sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==
+"@babel/plugin-transform-optional-catch-binding@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz#926cf150bd421fc8362753e911b4a1b1ce4356cd"
- integrity sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==
+"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5":
+ version "7.28.5"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-parameters@^7.27.7":
@@ -1640,22 +1537,18 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-private-methods@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz#c76fbfef3b86c775db7f7c106fff544610bdb411"
- integrity sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==
+"@babel/plugin-transform-private-methods@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-class-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-private-property-in-object@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz#4fafef1e13129d79f1d75ac180c52aafefdb2811"
- integrity sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==
+"@babel/plugin-transform-private-property-in-object@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-annotate-as-pure" "^7.27.3"
- "@babel/helper-create-class-features-plugin" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-annotate-as-pure" "^7.27.1"
+ "@babel/helper-create-class-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-property-literals@^7.27.1":
version "7.27.1"
@@ -1664,20 +1557,16 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-regenerator@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz#dec237cec1b93330876d6da9992c4abd42c9d18b"
- integrity sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==
+"@babel/plugin-transform-regenerator@^7.28.4":
+ version "7.28.4"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-regexp-modifiers@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz#7ef0163bd8b4a610481b2509c58cf217f065290b"
- integrity sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==
+"@babel/plugin-transform-regexp-modifiers@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.28.5"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-reserved-words@^7.27.1":
version "7.27.1"
@@ -1687,12 +1576,10 @@
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-runtime@^7.10.1":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz#a5fded13cc656700804bfd6e5ebd7fffd5266803"
- integrity sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==
+ version "7.28.5"
dependencies:
- "@babel/helper-module-imports" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-module-imports" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
babel-plugin-polyfill-corejs2 "^0.4.14"
babel-plugin-polyfill-corejs3 "^0.13.0"
babel-plugin-polyfill-regenerator "^0.6.5"
@@ -1705,12 +1592,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-spread@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz#40a2b423f6db7b70f043ad027a58bcb44a9757b6"
- integrity sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==
+"@babel/plugin-transform-spread@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-sticky-regex@^7.27.1":
@@ -1741,13 +1626,11 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-unicode-property-regex@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz#63a7a6c21a0e75dae9b1861454111ea5caa22821"
- integrity sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==
+"@babel/plugin-transform-unicode-property-regex@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.28.5"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-unicode-regex@^7.27.1":
version "7.27.1"
@@ -1757,89 +1640,84 @@
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-unicode-sets-regex@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz#924912914e5df9fe615ec472f88ff4788ce04d4e"
- integrity sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==
+"@babel/plugin-transform-unicode-sets-regex@^7.27.1":
+ version "7.27.1"
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.28.5"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/preset-env@^7.10.2":
- version "7.29.5"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.5.tgz#c48b7ed94582c8b685e21b8b42de8633ec289268"
- integrity sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==
+ version "7.28.5"
dependencies:
- "@babel/compat-data" "^7.29.3"
- "@babel/helper-compilation-targets" "^7.28.6"
- "@babel/helper-plugin-utils" "^7.28.6"
+ "@babel/compat-data" "^7.28.5"
+ "@babel/helper-compilation-targets" "^7.27.2"
+ "@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-validator-option" "^7.27.1"
"@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5"
"@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1"
- "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array" "^7.29.3"
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1"
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.28.6"
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.28.3"
"@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2"
- "@babel/plugin-syntax-import-assertions" "^7.28.6"
- "@babel/plugin-syntax-import-attributes" "^7.28.6"
+ "@babel/plugin-syntax-import-assertions" "^7.27.1"
+ "@babel/plugin-syntax-import-attributes" "^7.27.1"
"@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
"@babel/plugin-transform-arrow-functions" "^7.27.1"
- "@babel/plugin-transform-async-generator-functions" "^7.29.0"
- "@babel/plugin-transform-async-to-generator" "^7.28.6"
+ "@babel/plugin-transform-async-generator-functions" "^7.28.0"
+ "@babel/plugin-transform-async-to-generator" "^7.27.1"
"@babel/plugin-transform-block-scoped-functions" "^7.27.1"
- "@babel/plugin-transform-block-scoping" "^7.28.6"
- "@babel/plugin-transform-class-properties" "^7.28.6"
- "@babel/plugin-transform-class-static-block" "^7.28.6"
- "@babel/plugin-transform-classes" "^7.28.6"
- "@babel/plugin-transform-computed-properties" "^7.28.6"
+ "@babel/plugin-transform-block-scoping" "^7.28.5"
+ "@babel/plugin-transform-class-properties" "^7.27.1"
+ "@babel/plugin-transform-class-static-block" "^7.28.3"
+ "@babel/plugin-transform-classes" "^7.28.4"
+ "@babel/plugin-transform-computed-properties" "^7.27.1"
"@babel/plugin-transform-destructuring" "^7.28.5"
- "@babel/plugin-transform-dotall-regex" "^7.28.6"
+ "@babel/plugin-transform-dotall-regex" "^7.27.1"
"@babel/plugin-transform-duplicate-keys" "^7.27.1"
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.29.0"
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1"
"@babel/plugin-transform-dynamic-import" "^7.27.1"
- "@babel/plugin-transform-explicit-resource-management" "^7.28.6"
- "@babel/plugin-transform-exponentiation-operator" "^7.28.6"
+ "@babel/plugin-transform-explicit-resource-management" "^7.28.0"
+ "@babel/plugin-transform-exponentiation-operator" "^7.28.5"
"@babel/plugin-transform-export-namespace-from" "^7.27.1"
"@babel/plugin-transform-for-of" "^7.27.1"
"@babel/plugin-transform-function-name" "^7.27.1"
- "@babel/plugin-transform-json-strings" "^7.28.6"
+ "@babel/plugin-transform-json-strings" "^7.27.1"
"@babel/plugin-transform-literals" "^7.27.1"
- "@babel/plugin-transform-logical-assignment-operators" "^7.28.6"
+ "@babel/plugin-transform-logical-assignment-operators" "^7.28.5"
"@babel/plugin-transform-member-expression-literals" "^7.27.1"
"@babel/plugin-transform-modules-amd" "^7.27.1"
- "@babel/plugin-transform-modules-commonjs" "^7.28.6"
- "@babel/plugin-transform-modules-systemjs" "^7.29.4"
+ "@babel/plugin-transform-modules-commonjs" "^7.27.1"
+ "@babel/plugin-transform-modules-systemjs" "^7.28.5"
"@babel/plugin-transform-modules-umd" "^7.27.1"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.29.0"
+ "@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1"
"@babel/plugin-transform-new-target" "^7.27.1"
- "@babel/plugin-transform-nullish-coalescing-operator" "^7.28.6"
- "@babel/plugin-transform-numeric-separator" "^7.28.6"
- "@babel/plugin-transform-object-rest-spread" "^7.28.6"
+ "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1"
+ "@babel/plugin-transform-numeric-separator" "^7.27.1"
+ "@babel/plugin-transform-object-rest-spread" "^7.28.4"
"@babel/plugin-transform-object-super" "^7.27.1"
- "@babel/plugin-transform-optional-catch-binding" "^7.28.6"
- "@babel/plugin-transform-optional-chaining" "^7.28.6"
+ "@babel/plugin-transform-optional-catch-binding" "^7.27.1"
+ "@babel/plugin-transform-optional-chaining" "^7.28.5"
"@babel/plugin-transform-parameters" "^7.27.7"
- "@babel/plugin-transform-private-methods" "^7.28.6"
- "@babel/plugin-transform-private-property-in-object" "^7.28.6"
+ "@babel/plugin-transform-private-methods" "^7.27.1"
+ "@babel/plugin-transform-private-property-in-object" "^7.27.1"
"@babel/plugin-transform-property-literals" "^7.27.1"
- "@babel/plugin-transform-regenerator" "^7.29.0"
- "@babel/plugin-transform-regexp-modifiers" "^7.28.6"
+ "@babel/plugin-transform-regenerator" "^7.28.4"
+ "@babel/plugin-transform-regexp-modifiers" "^7.27.1"
"@babel/plugin-transform-reserved-words" "^7.27.1"
"@babel/plugin-transform-shorthand-properties" "^7.27.1"
- "@babel/plugin-transform-spread" "^7.28.6"
+ "@babel/plugin-transform-spread" "^7.27.1"
"@babel/plugin-transform-sticky-regex" "^7.27.1"
"@babel/plugin-transform-template-literals" "^7.27.1"
"@babel/plugin-transform-typeof-symbol" "^7.27.1"
"@babel/plugin-transform-unicode-escapes" "^7.27.1"
- "@babel/plugin-transform-unicode-property-regex" "^7.28.6"
+ "@babel/plugin-transform-unicode-property-regex" "^7.27.1"
"@babel/plugin-transform-unicode-regex" "^7.27.1"
- "@babel/plugin-transform-unicode-sets-regex" "^7.28.6"
+ "@babel/plugin-transform-unicode-sets-regex" "^7.27.1"
"@babel/preset-modules" "0.1.6-no-external-plugins"
- babel-plugin-polyfill-corejs2 "^0.4.15"
- babel-plugin-polyfill-corejs3 "^0.14.0"
- babel-plugin-polyfill-regenerator "^0.6.6"
- core-js-compat "^3.48.0"
+ babel-plugin-polyfill-corejs2 "^0.4.14"
+ babel-plugin-polyfill-corejs3 "^0.13.0"
+ babel-plugin-polyfill-regenerator "^0.6.5"
+ core-js-compat "^3.43.0"
semver "^6.3.1"
"@babel/preset-modules@0.1.6-no-external-plugins":
@@ -1851,10 +1729,8 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
-"@babel/register@^7.28.6":
- version "7.29.3"
- resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.29.3.tgz#726233ed488d52bb67aa8fd0dc5cdf19d10a2584"
- integrity sha512-F6C1KpIdoImKQfsD6HSxZ+mS4YY/2Q+JsqrmTC5ApVkTR2rG+nnbpjhWwzA5bDNu8mJjB3AryqDaWFLd4gCbJQ==
+"@babel/register@^7.27.1":
+ version "7.28.3"
dependencies:
clone-deep "^4.0.1"
find-cache-dir "^2.0.0"
@@ -1863,36 +1739,28 @@
source-map-support "^0.5.16"
"@babel/runtime@^7.10.2", "@babel/runtime@^7.21.0":
- version "7.29.2"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.29.2.tgz#9a6e2d05f4b6692e1801cd4fb176ad823930ed5e"
- integrity sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==
-
-"@babel/template@^7.28.6", "@babel/template@^7.3.3":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57"
- integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==
- dependencies:
- "@babel/code-frame" "^7.28.6"
- "@babel/parser" "^7.28.6"
- "@babel/types" "^7.28.6"
-
-"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
- integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
- dependencies:
- "@babel/code-frame" "^7.29.0"
- "@babel/generator" "^7.29.0"
+ version "7.28.4"
+
+"@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3":
+ version "7.27.2"
+ dependencies:
+ "@babel/code-frame" "^7.27.1"
+ "@babel/parser" "^7.27.2"
+ "@babel/types" "^7.27.1"
+
+"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5":
+ version "7.28.5"
+ dependencies:
+ "@babel/code-frame" "^7.27.1"
+ "@babel/generator" "^7.28.5"
"@babel/helper-globals" "^7.28.0"
- "@babel/parser" "^7.29.0"
- "@babel/template" "^7.28.6"
- "@babel/types" "^7.29.0"
+ "@babel/parser" "^7.28.5"
+ "@babel/template" "^7.27.2"
+ "@babel/types" "^7.28.5"
debug "^4.3.1"
-"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
- integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
+"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
+ version "7.28.5"
dependencies:
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.28.5"
@@ -1910,9 +1778,7 @@
tslib "^2.4.0"
"@eslint-community/eslint-utils@^4.2.0":
- version "4.9.1"
- resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595"
- integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==
+ version "4.9.0"
dependencies:
eslint-visitor-keys "^3.4.3"
@@ -1995,9 +1861,7 @@
integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
"@img/colour@^1.0.0":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@img/colour/-/colour-1.1.0.tgz#b0c2c2fa661adf75effd6b4964497cd80010bb9d"
- integrity sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==
+ version "1.0.0"
"@img/sharp-darwin-arm64@0.34.5":
version "0.34.5"
@@ -2023,16 +1887,16 @@
resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz"
integrity sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==
-"@img/sharp-libvips-linux-arm64@1.2.4":
- version "1.2.4"
- resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz"
- integrity sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==
-
"@img/sharp-libvips-linux-arm@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz"
integrity sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==
+"@img/sharp-libvips-linux-arm64@1.2.4":
+ version "1.2.4"
+ resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz"
+ integrity sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==
+
"@img/sharp-libvips-linux-ppc64@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz"
@@ -2063,13 +1927,6 @@
resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz"
integrity sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==
-"@img/sharp-linux-arm64@0.34.5":
- version "0.34.5"
- resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz"
- integrity sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==
- optionalDependencies:
- "@img/sharp-libvips-linux-arm64" "1.2.4"
-
"@img/sharp-linux-arm@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz"
@@ -2077,6 +1934,13 @@
optionalDependencies:
"@img/sharp-libvips-linux-arm" "1.2.4"
+"@img/sharp-linux-arm64@0.34.5":
+ version "0.34.5"
+ resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz"
+ integrity sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==
+ optionalDependencies:
+ "@img/sharp-libvips-linux-arm64" "1.2.4"
+
"@img/sharp-linux-ppc64@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz"
@@ -2153,9 +2017,7 @@
resolve-from "^5.0.0"
"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3":
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.6.tgz#8dc9afa2ac1506cb1a58f89940f1c124446c8df3"
- integrity sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==
+ version "0.1.3"
"@jest/console@^29.7.0":
version "29.7.0"
@@ -2423,11 +2285,6 @@
resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz"
integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==
-"@nodable/entities@^2.1.0":
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/@nodable/entities/-/entities-2.1.0.tgz#f543e5c6446720d4cf9e498a83019dd159973bc2"
- integrity sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==
-
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
@@ -2497,10 +2354,10 @@
resolved "https://registry.npmjs.org/@paypal/paypalhttp/-/paypalhttp-1.0.1.tgz"
integrity sha512-DC7AHxTT7drF6dUi3YaFdPVuT15sIkpD5H2eHmdtFgxM4UanS1o1ZDfMhR9mpxd8o+X6pz2r+EZVRRq+n1cssQ==
-"@puppeteer/browsers@2.13.2":
- version "2.13.2"
- resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.13.2.tgz#dcc8e7a4545d9680a8a72c53f132e80afc582284"
- integrity sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==
+"@puppeteer/browsers@2.13.0":
+ version "2.13.0"
+ resolved "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz"
+ integrity sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==
dependencies:
debug "^4.4.3"
extract-zip "^2.0.1"
@@ -2515,7 +2372,7 @@
resolved "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz"
integrity sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==
-"@redis/client@1.6.1":
+"@redis/client@^1.0.0", "@redis/client@1.6.1":
version "1.6.1"
resolved "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz"
integrity sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==
@@ -2566,7 +2423,7 @@
"@sentry/types" "7.120.4"
"@sentry/utils" "7.120.4"
-"@sentry/integrations@7.120.4", "@sentry/integrations@^7.110.0":
+"@sentry/integrations@^7.110.0", "@sentry/integrations@7.120.4":
version "7.120.4"
resolved "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.120.4.tgz"
integrity sha512-kkBTLk053XlhDCg7OkBQTIMF4puqFibeRO3E3YiVc4PGLnocXMaVpOSCkMqAc1k1kZ09UgGi8DxfQhnFEjUkpA==
@@ -2600,9 +2457,7 @@
"@sentry/types" "7.120.4"
"@sinclair/typebox@^0.27.8":
- version "0.27.10"
- resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.10.tgz#beefe675f1853f73676aecc915b2bd2ac98c4fc6"
- integrity sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==
+ version "0.27.8"
"@sinonjs/commons@^3.0.0":
version "3.0.1"
@@ -3228,9 +3083,7 @@
"@types/node" "*"
"@types/express-serve-static-core@^4.17.33":
- version "4.19.8"
- resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz#99b960322a4d576b239a640ab52ef191989b036f"
- integrity sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==
+ version "4.19.7"
dependencies:
"@types/node" "*"
"@types/qs" "*"
@@ -3309,7 +3162,7 @@
"@types/bson" "*"
"@types/node" "*"
-"@types/node-fetch@^2.6.12":
+"@types/node-fetch@^2.5.7", "@types/node-fetch@^2.6.12":
version "2.6.13"
resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz"
integrity sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==
@@ -3323,16 +3176,12 @@
integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==
"@types/node@>=10.0.0":
- version "25.7.0"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-25.7.0.tgz#7498f82e90dbdce7c34b75aaaa256c498a0ebe6c"
- integrity sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==
+ version "24.10.0"
dependencies:
- undici-types "~7.21.0"
+ undici-types "~7.16.0"
"@types/qs@*":
- version "6.15.1"
- resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.15.1.tgz#8606884272c63f0db96986bd3548650d8a9388bf"
- integrity sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==
+ version "6.14.0"
"@types/range-parser@*":
version "1.2.7"
@@ -3391,29 +3240,18 @@
resolved "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz"
integrity sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==
-"@types/ws@^8.5.12":
- version "8.18.1"
- resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9"
- integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==
- dependencies:
- "@types/node" "*"
-
"@types/yargs-parser@*":
version "21.0.3"
resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz"
integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==
"@types/yargs@^15.0.0":
- version "15.0.20"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.20.tgz#6d00a124c9f757427d4ca3cbc87daea778053c68"
- integrity sha512-KIkX+/GgfFitlASYCGoSF+T4XRXhOubJLhkLVtSfsRTe9jWMmuM2g28zQ41BtPTG7TRBb2xHW+LCNVE9QR/vsg==
+ version "15.0.19"
dependencies:
"@types/yargs-parser" "*"
"@types/yargs@^17.0.8":
- version "17.0.35"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24"
- integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==
+ version "17.0.34"
dependencies:
"@types/yargs-parser" "*"
@@ -3424,10 +3262,8 @@
dependencies:
"@types/node" "*"
-"@typespec/ts-http-runtime@^0.3.0", "@typespec/ts-http-runtime@^0.3.4":
- version "0.3.5"
- resolved "https://registry.yarnpkg.com/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.5.tgz#ccc9b35464aa8da90982d00553d49a5c591d95f3"
- integrity sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw==
+"@typespec/ts-http-runtime@^0.3.0":
+ version "0.3.2"
dependencies:
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.0"
@@ -3475,10 +3311,13 @@ acorn@^5.5.0:
resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz"
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
-acorn@^8.9.0:
- version "8.16.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a"
- integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
+"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0:
+ version "8.15.0"
+
+agent-base@^7.1.0, agent-base@^7.1.2:
+ version "7.1.4"
+ resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz"
+ integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==
agent-base@6:
version "6.0.2"
@@ -3487,11 +3326,6 @@ agent-base@6:
dependencies:
debug "4"
-agent-base@^7.1.0, agent-base@^7.1.2:
- version "7.1.4"
- resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz"
- integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==
-
ajv-keywords@^1.0.0:
version "1.5.1"
resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz"
@@ -3505,10 +3339,8 @@ ajv@^4.7.0:
co "^4.6.0"
json-stable-stringify "^1.0.1"
-ajv@^6.12.3, ajv@^6.12.4:
- version "6.15.0"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.15.0.tgz#07e982c74626167aa7a2495c53817892d7139492"
- integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==
+ajv@^6.12.3, ajv@^6.12.4, ajv@>=4.10.0:
+ version "6.12.6"
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
@@ -3528,9 +3360,7 @@ ansi-escapes@^4.2.1:
type-fest "^0.21.3"
ansi-escapes@^7.0.0:
- version "7.3.0"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-7.3.0.tgz#5395bb74b2150a4a1d6e3c2565f4aeca78d28627"
- integrity sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==
+ version "7.2.0"
dependencies:
environment "^1.0.0"
@@ -3556,10 +3386,8 @@ ansi-regex@^5.0.0, ansi-regex@^5.0.1:
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
-ansi-regex@^6.2.2:
+ansi-regex@^6.0.1:
version "6.2.2"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1"
- integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
ansi-styles@^2.2.1:
version "2.2.1"
@@ -3578,7 +3406,7 @@ ansi-styles@^5.0.0:
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
-ansi-styles@^6.2.1, ansi-styles@^6.2.3:
+ansi-styles@^6.2.1:
version "6.2.3"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz"
integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
@@ -3700,10 +3528,8 @@ array.prototype.flatmap@^1.3.2, array.prototype.flatmap@^1.3.3:
es-abstract "^1.23.5"
es-shim-unscopables "^1.0.2"
-array.prototype.reduce@^1.0.8:
+array.prototype.reduce@^1.0.6:
version "1.0.8"
- resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.8.tgz#42f97f5078daedca687d4463fd3c05cbfd83da57"
- integrity sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.4"
@@ -3755,7 +3581,7 @@ asn1@~0.2.3:
dependencies:
safer-buffer "~2.1.0"
-assert-plus@1.0.0, assert-plus@^1.0.0:
+assert-plus@^1.0.0, assert-plus@1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
@@ -3840,19 +3666,14 @@ aws4@^1.8.0:
integrity sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==
axe-core@^4.10.0:
- version "4.11.4"
- resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.4.tgz#5b535e381ff1e61ffdd615e5483d16186d3b46a5"
- integrity sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==
+ version "4.11.0"
-axios@^1.13.5, axios@^1.16.1, axios@^1.8.4:
- version "1.16.1"
- resolved "https://registry.yarnpkg.com/axios/-/axios-1.16.1.tgz#517e29291d19d6e8cf919ff264f4fe157261ba12"
- integrity sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==
+axios@^1.12.0, axios@^1.7.7, axios@^1.8.4:
+ version "1.13.2"
dependencies:
- follow-redirects "^1.16.0"
- form-data "^4.0.5"
- https-proxy-agent "^5.0.1"
- proxy-from-env "^2.1.0"
+ follow-redirects "^1.15.6"
+ form-data "^4.0.4"
+ proxy-from-env "^1.1.0"
axobject-query@^4.1.0:
version "4.1.0"
@@ -3907,10 +3728,8 @@ babel-plugin-jest-hoist@^29.6.3:
"@types/babel__core" "^7.1.14"
"@types/babel__traverse" "^7.0.6"
-babel-plugin-module-resolver@^5.0.0:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.3.tgz#13f03cf29048ad7e0239e6a1c4dcc669d199f394"
- integrity sha512-h8h6H71ZvdLJZxZrYkaeR30BojTaV7O9GfqacY14SNj5CNB8ocL9tydNzTC0JrnNN7vY3eJhwCmkDj7tuEUaqQ==
+"babel-plugin-module-resolver@^3.0.0 || ^4.0.0 || ^5.0.0", babel-plugin-module-resolver@^5.0.0:
+ version "5.0.2"
dependencies:
find-babel-config "^2.1.1"
glob "^9.3.3"
@@ -3918,13 +3737,11 @@ babel-plugin-module-resolver@^5.0.0:
reselect "^4.1.7"
resolve "^1.22.8"
-babel-plugin-polyfill-corejs2@^0.4.14, babel-plugin-polyfill-corejs2@^0.4.15:
- version "0.4.17"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz#198f970f1c99a856b466d1187e88ce30bd199d91"
- integrity sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==
+babel-plugin-polyfill-corejs2@^0.4.14:
+ version "0.4.14"
dependencies:
- "@babel/compat-data" "^7.28.6"
- "@babel/helper-define-polyfill-provider" "^0.6.8"
+ "@babel/compat-data" "^7.27.7"
+ "@babel/helper-define-polyfill-provider" "^0.6.5"
semver "^6.3.1"
babel-plugin-polyfill-corejs3@^0.13.0:
@@ -3935,20 +3752,10 @@ babel-plugin-polyfill-corejs3@^0.13.0:
"@babel/helper-define-polyfill-provider" "^0.6.5"
core-js-compat "^3.43.0"
-babel-plugin-polyfill-corejs3@^0.14.0:
- version "0.14.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz#6ac08d2f312affb70c4c69c0fbba4cb417ee5587"
- integrity sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==
- dependencies:
- "@babel/helper-define-polyfill-provider" "^0.6.8"
- core-js-compat "^3.48.0"
-
-babel-plugin-polyfill-regenerator@^0.6.5, babel-plugin-polyfill-regenerator@^0.6.6:
- version "0.6.8"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz#8a6bfd5dd54239362b3d06ce47ac52b2d95d7721"
- integrity sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==
+babel-plugin-polyfill-regenerator@^0.6.5:
+ version "0.6.5"
dependencies:
- "@babel/helper-define-polyfill-provider" "^0.6.8"
+ "@babel/helper-define-polyfill-provider" "^0.6.5"
babel-preset-current-node-syntax@^1.0.0:
version "1.2.0"
@@ -3984,12 +3791,7 @@ balanced-match@^1.0.0:
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
-balanced-match@^4.0.2:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a"
- integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==
-
-bare-events@^2.5.4, bare-events@^2.7.0:
+bare-events@*, bare-events@^2.5.4, bare-events@^2.7.0:
version "2.8.2"
resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz"
integrity sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==
@@ -4032,24 +3834,24 @@ bare-url@^2.2.2:
dependencies:
bare-path "^3.0.0"
-base64-js@0.0.8:
- version "0.0.8"
- resolved "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz"
- integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==
-
base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-base64id@2.0.0, base64id@~2.0.0:
+base64-js@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz"
+ integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==
+
+base64id@~2.0.0, base64id@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
-baseline-browser-mapping@^2.10.12, baseline-browser-mapping@^2.10.29:
+baseline-browser-mapping@^2.10.29, baseline-browser-mapping@^2.8.19:
version "2.10.29"
- resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz#47bdc13027af28d341f367a4f35a07ce872e27b4"
+ resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz"
integrity sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==
basic-ftp@^5.0.2:
@@ -4135,27 +3937,16 @@ bowser@^2.11.0:
integrity sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==
brace-expansion@^1.1.7:
- version "1.1.14"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.14.tgz#d9de602370d91347cd9ddad1224d4fd701eb348b"
- integrity sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==
+ version "1.1.12"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.0.tgz#4f41a41190216ee36067ec381526fe9539c4f0ae"
- integrity sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==
+ version "2.0.2"
dependencies:
balanced-match "^1.0.0"
-brace-expansion@^5.0.5:
- version "5.0.6"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.6.tgz#ec68fe0a641a29d8711579caf641d05bae1f2285"
- integrity sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==
- dependencies:
- balanced-match "^4.0.2"
-
braces@^3.0.3, braces@~3.0.2:
version "3.0.3"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"
@@ -4170,16 +3961,14 @@ brotli@^1.3.2:
dependencies:
base64-js "^1.1.2"
-browserslist@^4.24.0, browserslist@^4.28.1:
- version "4.28.2"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.2.tgz#f50b65362ef48974ca9f50b3680566d786b811d2"
- integrity sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==
+browserslist@^4.24.0, browserslist@^4.26.3, "browserslist@>= 4.21.0":
+ version "4.27.0"
dependencies:
- baseline-browser-mapping "^2.10.12"
- caniuse-lite "^1.0.30001782"
- electron-to-chromium "^1.5.328"
- node-releases "^2.0.36"
- update-browserslist-db "^1.2.3"
+ baseline-browser-mapping "^2.8.19"
+ caniuse-lite "^1.0.30001751"
+ electron-to-chromium "^1.5.238"
+ node-releases "^2.0.26"
+ update-browserslist-db "^1.1.4"
bser@2.1.1:
version "2.1.1"
@@ -4189,9 +3978,7 @@ bser@2.1.1:
node-int64 "^0.4.0"
bson@*:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/bson/-/bson-7.2.0.tgz#1a496a42d9ff130b9f3ab8efd465459c758c747f"
- integrity sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==
+ version "7.0.0"
bson@^1.1.4:
version "1.1.6"
@@ -4213,6 +4000,14 @@ buffer-from@^1.0.0:
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+buffer@^5.5.0:
+ version "5.7.1"
+ resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
+ integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+ dependencies:
+ base64-js "^1.3.1"
+ ieee754 "^1.1.13"
+
buffer@4.9.2:
version "4.9.2"
resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz"
@@ -4222,14 +4017,6 @@ buffer@4.9.2:
ieee754 "^1.1.4"
isarray "^1.0.0"
-buffer@^5.5.0:
- version "5.7.1"
- resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
- integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
- dependencies:
- base64-js "^1.3.1"
- ieee754 "^1.1.13"
-
bufferstreams@^1.1.1:
version "1.1.3"
resolved "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.1.3.tgz"
@@ -4244,12 +4031,12 @@ busboy@^1.6.0:
dependencies:
streamsearch "^1.1.0"
-bytes@3.1.2, bytes@~3.1.2:
+bytes@~3.1.2, bytes@3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
-call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
+call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
@@ -4257,14 +4044,12 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
es-errors "^1.3.0"
function-bind "^1.1.2"
-call-bind@^1.0.7, call-bind@^1.0.8, call-bind@^1.0.9:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.9.tgz#39a644700c80bc7d0ca9102fc6d1d43b2fd7eee7"
- integrity sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==
+call-bind@^1.0.7, call-bind@^1.0.8:
+ version "1.0.8"
dependencies:
- call-bind-apply-helpers "^1.0.2"
- es-define-property "^1.0.1"
- get-intrinsic "^1.3.0"
+ call-bind-apply-helpers "^1.0.0"
+ es-define-property "^1.0.0"
+ get-intrinsic "^1.2.4"
set-function-length "^1.2.2"
call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4:
@@ -4297,37 +4082,41 @@ camelcase@^5.3.1:
resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-camelcase@^6.1.0, camelcase@^6.2.0:
+camelcase@^6.1.0:
+ version "6.3.0"
+ resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
+ integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
+
+camelcase@^6.2.0:
version "6.3.0"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-caniuse-lite@^1.0.30001782:
- version "1.0.30001792"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz#ca8bb9be244835a335e2018272ce7223691873c5"
- integrity sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==
+caniuse-lite@^1.0.30001751:
+ version "1.0.30001754"
card-validator@^10.0.2:
- version "10.0.4"
- resolved "https://registry.yarnpkg.com/card-validator/-/card-validator-10.0.4.tgz#7396c5df930fb0e0287a18190eaf24a65419e18a"
- integrity sha512-1Q/tDCSvM5iL3psPo6j8KF/VoI63WA7Y4Zthy1E7l/H4Iul2e2X+1S0vp33n3OMRjLgGU2+gLaK2NsGtwArJkQ==
+ version "10.0.3"
dependencies:
- credit-card-type "^10.1.0"
+ credit-card-type "^10.0.2"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
-"chalk@4.1 - 4.1.2", chalk@^4.0.0:
- version "4.1.2"
- resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
- integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+chalk@^1.0.0:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
+ integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==
dependencies:
- ansi-styles "^4.1.0"
- supports-color "^7.1.0"
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
-chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
+chalk@^1.1.1:
version "1.1.3"
resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==
@@ -4338,11 +4127,30 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-change-case@^5.4.4:
- version "5.4.4"
- resolved "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz"
- integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==
-
+chalk@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
+ integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+chalk@^4.0.0, "chalk@4.1 - 4.1.2":
+ version "4.1.2"
+ resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+change-case@^5.4.4:
+ version "5.4.4"
+ resolved "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz"
+ integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==
+
char-regex@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz"
@@ -4423,12 +4231,10 @@ cli-cursor@^5.0.0:
restore-cursor "^5.0.0"
cli-truncate@^5.0.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-5.2.0.tgz#c8e72aaca8339c773d128c36e0a17c6315b694eb"
- integrity sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==
+ version "5.1.1"
dependencies:
- slice-ansi "^8.0.0"
- string-width "^8.2.0"
+ slice-ansi "^7.1.0"
+ string-width "^8.0.0"
cli-width@^2.0.0:
version "2.2.1"
@@ -4458,11 +4264,6 @@ clone-stats@^0.0.1:
resolved "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz"
integrity sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==
-clone@2.x, clone@^2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
- integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
-
clone@^1.0.0:
version "1.0.4"
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
@@ -4524,10 +4325,8 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@^14.0.3:
- version "14.0.3"
- resolved "https://registry.yarnpkg.com/commander/-/commander-14.0.3.tgz#425d79b48f9af82fcd9e4fc1ea8af6c5ec07bbc2"
- integrity sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==
+commander@^14.0.1:
+ version "14.0.2"
commander@^6.2.0:
version "6.2.1"
@@ -4626,32 +4425,26 @@ cookiejar@^2.1.4:
resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz"
integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==
-core-js-compat@^3.43.0, core-js-compat@^3.48.0:
- version "3.49.0"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.49.0.tgz#06145447d92f4aaf258a0c44f24b47afaeaffef6"
- integrity sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==
+core-js-compat@^3.43.0:
+ version "3.46.0"
dependencies:
- browserslist "^4.28.1"
-
-core-js@^3.48.0:
- version "3.49.0"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.49.0.tgz#8b4d520ac034311fa21aa616f017ada0e0dbbddd"
- integrity sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==
+ browserslist "^4.26.3"
-core-util-is@1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
- integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
+core-js@^3.30.2:
+ version "3.46.0"
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+core-util-is@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
+
cors@^2.8.4, cors@~2.8.5:
- version "2.8.6"
- resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.6.tgz#ff5dd69bd95e547503820d29aba4f8faf8dfec96"
- integrity sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==
+ version "2.8.5"
dependencies:
object-assign "^4"
vary "^1"
@@ -4679,10 +4472,8 @@ create-jest@^29.7.0:
jest-util "^29.7.0"
prompts "^2.0.1"
-credit-card-type@^10.1.0:
- version "10.1.2"
- resolved "https://registry.yarnpkg.com/credit-card-type/-/credit-card-type-10.1.2.tgz#7cac67d259a1260ecb242b213dc7cfb277538513"
- integrity sha512-fP9vlyeYSHfKbIdE6IOR63YivTXMy0ZqyEkBhHxuAbvpltepe+zJmQ34A2Va7zJ8J7ZaB5IMAdD+1YJOmsajJA==
+credit-card-type@^10.0.2:
+ version "10.1.0"
cron-parser@^4.2.0:
version "4.9.0"
@@ -4692,11 +4483,9 @@ cron-parser@^4.2.0:
luxon "^3.2.1"
cron@^1.8.2:
- version "1.8.3"
- resolved "https://registry.yarnpkg.com/cron/-/cron-1.8.3.tgz#2a61d7b15848716885834ec56ac072f4b9744ebd"
- integrity sha512-JYR/QZFklJCIPndBLfd/2nU1nSlCMrUdtQ2mGLXSVM/qqqEK7DOrFR0gsEiyeqs0PdWrs0ve1ggH4V7XksDwXg==
+ version "1.8.2"
dependencies:
- luxon "^1.23.x"
+ moment-timezone "^0.5.x"
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.6"
@@ -4727,7 +4516,7 @@ css-what@2.1:
resolved "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz"
integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
-d@1, d@^1.0.1, d@^1.0.2:
+d@^1.0.1, d@^1.0.2, d@1:
version "1.0.2"
resolved "https://registry.npmjs.org/d/-/d-1.0.2.tgz"
integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==
@@ -4784,7 +4573,7 @@ date-fns-tz@^2.0.1:
resolved "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.1.tgz"
integrity sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==
-date-fns@^2.30.0:
+date-fns@^2.30.0, date-fns@2.x:
version "2.30.0"
resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz"
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
@@ -4796,43 +4585,68 @@ dateformat@^2.0.0:
resolved "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz"
integrity sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==
-dayjs@^1.11.7, dayjs@^1.11.9:
- version "1.11.20"
- resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.20.tgz#88d919fd639dc991415da5f4cb6f1b6650811938"
- integrity sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==
+dayjs@^1.11.9:
+ version "1.11.19"
-debug@2.6.9, debug@^2.1.1, debug@~2.6.9:
+debug@^2.1.1:
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"
-debug@3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz"
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
+debug@^3.2.7:
+ version "3.2.7"
+ resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
+ integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
- ms "2.0.0"
+ ms "^2.1.1"
-debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.3, debug@~4.4.1:
+debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.1, debug@^4.4.3, debug@4:
version "4.4.3"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
dependencies:
ms "^2.1.3"
-debug@^3.2.7:
- version "3.2.7"
- resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
- integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
+debug@~2.6.9:
+ version "2.6.9"
+ resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
+ integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
- ms "^2.1.1"
+ ms "2.0.0"
+
+debug@~4.3.1:
+ version "4.3.7"
+ dependencies:
+ ms "^2.1.3"
+
+debug@~4.3.2:
+ version "4.3.7"
+ dependencies:
+ ms "^2.1.3"
+
+debug@~4.3.4:
+ version "4.3.7"
+ dependencies:
+ ms "^2.1.3"
+
+debug@2.6.9:
+ 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"
+
+debug@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz"
+ integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
+ dependencies:
+ ms "2.0.0"
dedent@^1.0.0:
- version "1.7.2"
- resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.2.tgz#34e2264ab538301e27cf7b07bf2369c19baa8dd9"
- integrity sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==
+ version "1.7.0"
deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.4"
@@ -4881,12 +4695,12 @@ denque@^1.4.1:
resolved "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz"
integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
-depd@2.0.0, depd@~2.0.0:
+depd@~2.0.0, depd@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
-destroy@1.2.0, destroy@~1.2.0:
+destroy@~1.2.0, destroy@1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
@@ -4911,10 +4725,10 @@ detect-node@^2.1.0:
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
-devtools-protocol@0.0.1608973:
- version "0.0.1608973"
- resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1608973.tgz#56e0a2a999b06d416ee928ca06aeba95a5880515"
- integrity sha512-Tpm17fxYzt+J7VrGdc1k8YdRqS3YV7se/M6KeemEqvUbq/n7At1rWVuXMxQgpWkdwSdIEKYbU//Bve+Shm4YNQ==
+devtools-protocol@*, devtools-protocol@0.0.1581282:
+ version "0.0.1581282"
+ resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz"
+ integrity sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==
dezalgo@^1.0.4:
version "1.0.4"
@@ -4939,7 +4753,14 @@ diff-sequences@^29.6.3:
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz"
integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
-doctrine@^2.0.0, doctrine@^2.1.0:
+doctrine@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
+ integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
+ dependencies:
+ esutils "^2.0.2"
+
+doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
@@ -4953,14 +4774,6 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
-dom-serializer@0, dom-serializer@~0.1.0:
- version "0.1.1"
- resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz"
- integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
- dependencies:
- domelementtype "^1.3.0"
- entities "^1.1.1"
-
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz"
@@ -4970,7 +4783,15 @@ dom-serializer@^2.0.0:
domhandler "^5.0.2"
entities "^4.2.0"
-domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
+dom-serializer@~0.1.0, dom-serializer@0:
+ version "0.1.1"
+ resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz"
+ integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
+ dependencies:
+ domelementtype "^1.3.0"
+ entities "^1.1.1"
+
+domelementtype@^1.3.0, domelementtype@^1.3.1, domelementtype@1:
version "1.3.1"
resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz"
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
@@ -4994,7 +4815,7 @@ domhandler@^5.0.2, domhandler@^5.0.3:
dependencies:
domelementtype "^2.3.0"
-domutils@1.5.1, domutils@^1.5.1:
+domutils@^1.5.1, domutils@1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz"
integrity sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==
@@ -5002,10 +4823,8 @@ domutils@1.5.1, domutils@^1.5.1:
dom-serializer "0"
domelementtype "1"
-domutils@^3.2.2:
+domutils@^3.0.1:
version "3.2.2"
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78"
- integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
@@ -5047,7 +4866,7 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
-ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11:
+ecdsa-sig-formatter@^1.0.11, ecdsa-sig-formatter@1.0.11:
version "1.0.11"
resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
@@ -5059,10 +4878,8 @@ ee-first@1.1.1:
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
-electron-to-chromium@^1.5.328:
- version "1.5.354"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.354.tgz#a155a4ff0009ff225d46ea2ef7037ba48e6601fb"
- integrity sha512-JaBHwWcfIdmSAfWM5l3uwjGd431j8YEMikZ+K/2nXVuBqJKyZ0f+2h4n4JY5AyNiZmnY9qQr2RU3v9DxDmHMNg==
+electron-to-chromium@^1.5.238:
+ version "1.5.249"
emittery@^0.13.1:
version "0.13.1"
@@ -5084,6 +4901,9 @@ emoji-regex@^9.2.2:
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+encodeurl@~1.0.2:
+ version "1.0.2"
+
encodeurl@~2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz"
@@ -5102,36 +4922,28 @@ engine.io-parser@~5.2.1:
integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==
engine.io@~6.6.0:
- version "6.6.7"
- resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.6.7.tgz#60efa5b5b67167cdf93d64430c40a68bae9e4f21"
- integrity sha512-DgOngfDKM2EviOH3Mr9m7ks1q8roetLy/IMmYthAYzbpInMbYc/GS+fWFA3rl1gvwKVsQrVV61fo5emD1y3OJQ==
+ version "6.6.4"
dependencies:
"@types/cors" "^2.8.12"
"@types/node" ">=10.0.0"
- "@types/ws" "^8.5.12"
accepts "~1.3.4"
base64id "2.0.0"
cookie "~0.7.2"
cors "~2.8.5"
- debug "~4.4.1"
+ debug "~4.3.1"
engine.io-parser "~5.2.1"
- ws "~8.18.3"
+ ws "~8.17.1"
entities@^1.1.1, entities@~1.1.1:
version "1.1.2"
resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
-entities@^4.2.0:
+entities@^4.2.0, entities@^4.4.0:
version "4.5.0"
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
-entities@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/entities/-/entities-7.0.1.tgz#26e8a88889db63417dcb9a1e79a3f1bc92b5976b"
- integrity sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==
-
env-paths@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz"
@@ -5149,10 +4961,8 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0, es-abstract@^1.24.2:
- version "1.24.2"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.2.tgz#2dbd38c180735ee983f77585140a2706a963ed9a"
- integrity sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==
+es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0:
+ version "1.24.0"
dependencies:
array-buffer-byte-length "^1.0.2"
arraybuffer.prototype.slice "^1.0.4"
@@ -5225,26 +5035,24 @@ es-errors@^1.3.0:
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-iterator-helpers@^1.2.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz#8f4ff1f3603cbd09fbdb72c747a679779a65cc7f"
- integrity sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==
+ version "1.2.1"
dependencies:
- call-bind "^1.0.9"
- call-bound "^1.0.4"
+ call-bind "^1.0.8"
+ call-bound "^1.0.3"
define-properties "^1.2.1"
- es-abstract "^1.24.2"
+ es-abstract "^1.23.6"
es-errors "^1.3.0"
- es-set-tostringtag "^2.1.0"
+ es-set-tostringtag "^2.0.3"
function-bind "^1.1.2"
- get-intrinsic "^1.3.0"
+ get-intrinsic "^1.2.6"
globalthis "^1.0.4"
gopd "^1.2.0"
has-property-descriptors "^1.0.2"
has-proto "^1.2.0"
has-symbols "^1.1.0"
internal-slot "^1.1.0"
- iterator.prototype "^1.1.5"
- math-intrinsics "^1.1.0"
+ iterator.prototype "^1.1.4"
+ safe-array-concat "^1.1.3"
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
version "1.1.1"
@@ -5253,7 +5061,7 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
dependencies:
es-errors "^1.3.0"
-es-set-tostringtag@^2.1.0:
+es-set-tostringtag@^2.0.3, es-set-tostringtag@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
@@ -5350,7 +5158,12 @@ escape-html@~1.0.3:
resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
-escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+escape-string-regexp@^1.0.2:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
+
+escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
@@ -5419,13 +5232,11 @@ eslint-import-resolver-babel-module@^5.3.2:
resolve "^1.20.0"
eslint-import-resolver-node@^0.3.9:
- version "0.3.10"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz#84ce3005abfc300588cf23bbac1aabec1fc6e8c1"
- integrity sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==
+ version "0.3.9"
dependencies:
debug "^3.2.7"
- is-core-module "^2.16.1"
- resolve "^2.0.0-next.6"
+ is-core-module "^2.13.0"
+ resolve "^1.22.4"
eslint-module-utils@^2.12.1:
version "2.12.1"
@@ -5434,7 +5245,7 @@ eslint-module-utils@^2.12.1:
dependencies:
debug "^3.2.7"
-eslint-plugin-import@^2.28.0:
+eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3, eslint-plugin-import@^2.28.0:
version "2.32.0"
resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz"
integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==
@@ -5459,7 +5270,7 @@ eslint-plugin-import@^2.28.0:
string.prototype.trimend "^1.0.9"
tsconfig-paths "^3.15.0"
-eslint-plugin-jsx-a11y@^6.7.1:
+eslint-plugin-jsx-a11y@^6.5.1, eslint-plugin-jsx-a11y@^6.7.1:
version "6.10.2"
resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz"
integrity sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==
@@ -5480,12 +5291,12 @@ eslint-plugin-jsx-a11y@^6.7.1:
safe-regex-test "^1.0.3"
string.prototype.includes "^2.0.1"
-eslint-plugin-react-hooks@^4.6.0:
+eslint-plugin-react-hooks@^4.3.0, eslint-plugin-react-hooks@^4.6.0:
version "4.6.2"
resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz"
integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==
-eslint-plugin-react@^7.33.1:
+eslint-plugin-react@^7.28.0, eslint-plugin-react@^7.33.1:
version "7.37.5"
resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz"
integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==
@@ -5509,14 +5320,6 @@ eslint-plugin-react@^7.33.1:
string.prototype.matchall "^4.0.12"
string.prototype.repeat "^1.0.0"
-eslint-scope@5.1.1:
- version "5.1.1"
- resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
- integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
- dependencies:
- esrecurse "^4.3.0"
- estraverse "^4.1.1"
-
eslint-scope@^7.2.2:
version "7.2.2"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz"
@@ -5525,58 +5328,30 @@ eslint-scope@^7.2.2:
esrecurse "^4.3.0"
estraverse "^5.2.0"
+eslint-scope@5.1.1:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
+ integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^4.1.1"
+
eslint-visitor-keys@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
-eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
+eslint-visitor-keys@^3.4.1:
version "3.4.3"
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
-eslint@^3.0.0:
- version "3.19.0"
- resolved "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz"
- integrity sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==
- dependencies:
- babel-code-frame "^6.16.0"
- chalk "^1.1.3"
- concat-stream "^1.5.2"
- debug "^2.1.1"
- doctrine "^2.0.0"
- escope "^3.6.0"
- espree "^3.4.0"
- esquery "^1.0.0"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- file-entry-cache "^2.0.0"
- glob "^7.0.3"
- globals "^9.14.0"
- ignore "^3.2.0"
- imurmurhash "^0.1.4"
- inquirer "^0.12.0"
- is-my-json-valid "^2.10.0"
- is-resolvable "^1.0.0"
- js-yaml "^3.5.1"
- json-stable-stringify "^1.0.0"
- levn "^0.3.0"
- lodash "^4.0.0"
- mkdirp "^0.5.0"
- natural-compare "^1.4.0"
- optionator "^0.8.2"
- path-is-inside "^1.0.1"
- pluralize "^1.2.1"
- progress "^1.1.8"
- require-uncached "^1.0.2"
- shelljs "^0.7.5"
- strip-bom "^3.0.0"
- strip-json-comments "~2.0.1"
- table "^3.7.8"
- text-table "~0.2.0"
- user-home "^2.0.0"
+eslint-visitor-keys@^3.4.3:
+ version "3.4.3"
+ resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
+ integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
-eslint@^8.47.0:
+"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.32.0 || ^8.2.0", "eslint@^7.5.0 || ^8.0.0 || ^9.0.0", eslint@^8.47.0, eslint@>=7.0.0:
version "8.57.1"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz"
integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==
@@ -5620,6 +5395,47 @@ eslint@^8.47.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
+eslint@^3.0.0:
+ version "3.19.0"
+ resolved "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz"
+ integrity sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==
+ dependencies:
+ babel-code-frame "^6.16.0"
+ chalk "^1.1.3"
+ concat-stream "^1.5.2"
+ debug "^2.1.1"
+ doctrine "^2.0.0"
+ escope "^3.6.0"
+ espree "^3.4.0"
+ esquery "^1.0.0"
+ estraverse "^4.2.0"
+ esutils "^2.0.2"
+ file-entry-cache "^2.0.0"
+ glob "^7.0.3"
+ globals "^9.14.0"
+ ignore "^3.2.0"
+ imurmurhash "^0.1.4"
+ inquirer "^0.12.0"
+ is-my-json-valid "^2.10.0"
+ is-resolvable "^1.0.0"
+ js-yaml "^3.5.1"
+ json-stable-stringify "^1.0.0"
+ levn "^0.3.0"
+ lodash "^4.0.0"
+ mkdirp "^0.5.0"
+ natural-compare "^1.4.0"
+ optionator "^0.8.2"
+ path-is-inside "^1.0.1"
+ pluralize "^1.2.1"
+ progress "^1.1.8"
+ require-uncached "^1.0.2"
+ shelljs "^0.7.5"
+ strip-bom "^3.0.0"
+ strip-json-comments "~2.0.1"
+ table "^3.7.8"
+ text-table "~0.2.0"
+ user-home "^2.0.0"
+
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz"
@@ -5653,9 +5469,7 @@ esprima@^4.0.0, esprima@^4.0.1:
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
esquery@^1.0.0, esquery@^1.4.2:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d"
- integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==
+ version "1.6.0"
dependencies:
estraverse "^5.1.0"
@@ -5666,7 +5480,12 @@ esrecurse@^4.1.0, esrecurse@^4.3.0:
dependencies:
estraverse "^5.2.0"
-estraverse@^4.1.1, estraverse@^4.2.0:
+estraverse@^4.1.1:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
+ integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+
+estraverse@^4.2.0:
version "4.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
@@ -5700,9 +5519,7 @@ event-target-shim@^5.0.0:
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
eventemitter3@^5.0.1:
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.4.tgz#a86d66170433712dde814707ac52b5271ceb1feb"
- integrity sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==
+ version "5.0.1"
events-to-async@^2.0.2:
version "2.0.2"
@@ -5716,11 +5533,6 @@ events-universal@^1.0.0:
dependencies:
bare-events "^2.7.0"
-events@1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/events/-/events-1.1.1.tgz"
- integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==
-
events@^3.0.0, events@^3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
@@ -5777,12 +5589,10 @@ express-session@^1.19.0:
uid-safe "~2.1.5"
express-validator@^7.0.1:
- version "7.3.2"
- resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-7.3.2.tgz#7b322847efc81f9cf76f9a42c10de29b80536e9b"
- integrity sha512-ctLw1Vl6dXVH62dIQMDdTAQkrh480mkFuG6/SGXOaVlwPNukhRAe7EgJIMJ2TSAni8iwHBRp530zAZE5ZPF2IA==
+ version "7.3.0"
dependencies:
- lodash "^4.18.1"
- validator "~13.15.23"
+ lodash "^4.17.21"
+ validator "~13.15.15"
express-ws@^5.0.2:
version "5.0.2"
@@ -5791,7 +5601,7 @@ express-ws@^5.0.2:
dependencies:
ws "^7.4.6"
-express@^4.22.1:
+"express@^4.0.0 || ^5.0.0-alpha.1", express@^4.22.1:
version "4.22.1"
resolved "https://registry.npmjs.org/express/-/express-4.22.1.tgz"
integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==
@@ -5851,7 +5661,7 @@ extract-zip@^2.0.1:
optionalDependencies:
"@types/yauzl" "^2.9.1"
-extsprintf@1.3.0, extsprintf@^1.2.0:
+extsprintf@^1.2.0, extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz"
integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
@@ -5896,13 +5706,10 @@ fast-text-encoding@^1.0.0:
resolved "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz"
integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==
-fast-xml-builder@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz#abd2363145a7625d9789ad96da375fabe3cff28c"
- integrity sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==
+fast-xml-parser@^5.0.7:
+ version "5.3.1"
dependencies:
- path-expression-matcher "^1.5.0"
- xml-naming "^0.1.0"
+ strnum "^2.1.0"
fast-xml-parser@5.2.5:
version "5.2.5"
@@ -5911,21 +5718,8 @@ fast-xml-parser@5.2.5:
dependencies:
strnum "^2.1.0"
-fast-xml-parser@^5.5.9:
- version "5.8.0"
- resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz#64d71f0f8d4bf23621dffd762aef7e98c1884fc1"
- integrity sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==
- dependencies:
- "@nodable/entities" "^2.1.0"
- fast-xml-builder "^1.2.0"
- path-expression-matcher "^1.5.0"
- strnum "^2.3.0"
- xml-naming "^0.1.0"
-
fastq@^1.6.0:
- version "1.20.1"
- resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675"
- integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==
+ version "1.19.1"
dependencies:
reusify "^1.0.4"
@@ -5974,16 +5768,14 @@ fill-range@^7.1.1:
to-regex-range "^5.0.1"
finalhandler@~1.3.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88"
- integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==
+ version "1.3.1"
dependencies:
debug "2.6.9"
encodeurl "~2.0.0"
escape-html "~1.0.3"
- on-finished "~2.4.1"
+ on-finished "2.4.1"
parseurl "~1.3.3"
- statuses "~2.0.2"
+ statuses "2.0.1"
unpipe "~1.0.0"
find-babel-config@^2.1.1:
@@ -6054,14 +5846,10 @@ flat-cache@^3.0.4:
rimraf "^3.0.2"
flatted@^3.2.9:
- version "3.4.2"
- resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726"
- integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==
+ version "3.3.3"
-follow-redirects@^1.16.0:
- version "1.16.0"
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc"
- integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==
+follow-redirects@^1.15.6:
+ version "1.15.11"
fontkit@^2.0.4:
version "2.0.4"
@@ -6125,7 +5913,7 @@ forwarded@0.2.0:
resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
-fresh@~0.5.2:
+fresh@~0.5.2, fresh@0.5.2:
version "0.5.2"
resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
@@ -6145,16 +5933,16 @@ fs.realpath@^1.0.0:
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-fsevents@2.3.2:
- version "2.3.2"
- resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
- integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
-
fsevents@^2.3.2, fsevents@~2.3.2:
version "2.3.3"
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+fsevents@2.3.2:
+ version "2.3.2"
+ resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
@@ -6243,10 +6031,8 @@ get-caller-file@^2.0.5:
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
-get-east-asian-width@^1.0.0, get-east-asian-width@^1.3.1, get-east-asian-width@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz#216900f91df11a8b2c198c3e1d93d6c035a776b9"
- integrity sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==
+get-east-asian-width@^1.0.0, get-east-asian-width@^1.3.0, get-east-asian-width@^1.3.1:
+ version "1.4.0"
get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0:
version "1.3.0"
@@ -6575,16 +6361,6 @@ html-escaper@^2.0.0:
resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
-htmlparser2@^10.1.0:
- version "10.1.0"
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-10.1.0.tgz#fe3f2e12c73b6e462d4e10395db9c1119e4d6ae4"
- integrity sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==
- dependencies:
- domelementtype "^2.3.0"
- domhandler "^5.0.3"
- domutils "^3.2.2"
- entities "^7.0.1"
-
htmlparser2@^3.9.1:
version "3.10.1"
resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz"
@@ -6597,7 +6373,24 @@ htmlparser2@^3.9.1:
inherits "^2.0.1"
readable-stream "^3.1.1"
-http-errors@~2.0.0, http-errors@~2.0.1:
+htmlparser2@^8.0.0:
+ version "8.0.2"
+ dependencies:
+ domelementtype "^2.3.0"
+ domhandler "^5.0.3"
+ domutils "^3.0.1"
+ entities "^4.4.0"
+
+http-errors@~2.0.0, http-errors@2.0.0:
+ version "2.0.0"
+ dependencies:
+ depd "2.0.0"
+ inherits "2.0.4"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ toidentifier "1.0.1"
+
+http-errors@~2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz"
integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==
@@ -6625,9 +6418,9 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
-https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
+https-proxy-agent@^5.0.0:
version "5.0.1"
- resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
+ resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz"
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
dependencies:
agent-base "6"
@@ -6651,23 +6444,21 @@ husky@^9.1.7:
resolved "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz"
integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==
-"iconv-lite@0.4.13 - 0.6.3", iconv-lite@~0.4.24:
+iconv-lite@~0.4.24, "iconv-lite@0.4.13 - 0.6.3":
version "0.4.24"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
dependencies:
safer-buffer ">= 2.1.2 < 3"
-ieee754@1.1.13, ieee754@^1.1.4:
+ieee754@^1.1.13:
+ version "1.2.1"
+
+ieee754@^1.1.4, ieee754@1.1.13:
version "1.1.13"
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz"
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
-ieee754@^1.1.13:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
- integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
-
ignore-by-default@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz"
@@ -6717,7 +6508,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
+inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4, inherits@2, inherits@2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -6755,6 +6546,11 @@ interpret@^1.0.0:
resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
+ip-address@^10.0.1:
+ version "10.1.0"
+ resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz"
+ integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==
+
"ip-address@5.8.9 - 5.9.4":
version "5.9.4"
resolved "https://registry.npmjs.org/ip-address/-/ip-address-5.9.4.tgz"
@@ -6764,11 +6560,6 @@ interpret@^1.0.0:
lodash "^4.17.15"
sprintf-js "1.1.2"
-ip-address@^10.0.1:
- version "10.1.0"
- resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz"
- integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==
-
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz"
@@ -6834,7 +6625,7 @@ is-callable@^1.2.7:
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
-is-core-module@^2.16.1:
+is-core-module@^2.13.0, is-core-module@^2.16.1:
version "2.16.1"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz"
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
@@ -6887,7 +6678,7 @@ is-fullwidth-code-point@^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==
-is-fullwidth-code-point@^5.0.0, is-fullwidth-code-point@^5.1.0:
+is-fullwidth-code-point@^5.0.0:
version "5.1.0"
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz"
integrity sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==
@@ -7069,12 +6860,7 @@ is@^3.2.1:
resolved "https://registry.npmjs.org/is/-/is-3.3.2.tgz"
integrity sha512-a2xr4E3s1PjDS8ORcGgXpWx6V+liNs+O3JRD2mb9aeugD7rtkkZ0zgLdYgw0tWsKhsdiezGYptSiMlVazCBTuQ==
-isarray@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
-
-isarray@^1.0.0, isarray@~1.0.0:
+isarray@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
@@ -7084,6 +6870,16 @@ isarray@^2.0.5:
resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
+isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
+
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
+
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
@@ -7170,10 +6966,8 @@ istanbul-reports@^3.1.3:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
-iterator.prototype@^1.1.5:
+iterator.prototype@^1.1.4:
version "1.1.5"
- resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz#12c959a29de32de0aa3bbbb801f4d777066dae39"
- integrity sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==
dependencies:
define-data-property "^1.1.4"
es-object-atoms "^1.0.0"
@@ -7401,7 +7195,7 @@ jest-resolve-dependencies@^29.7.0:
jest-regex-util "^29.6.3"
jest-snapshot "^29.7.0"
-jest-resolve@^29.7.0:
+jest-resolve@*, jest-resolve@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz"
integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==
@@ -7589,30 +7383,26 @@ js-tokens@^3.0.2:
integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==
js-yaml@^3.13.1, js-yaml@^3.5.1:
- version "3.14.2"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0"
- integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==
+ version "3.14.1"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.1.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b"
- integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==
+ version "4.1.0"
dependencies:
argparse "^2.0.1"
-jsbn@1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz"
- integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==
-
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz"
integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
+jsbn@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz"
+ integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==
+
jsesc@^3.0.2, jsesc@~3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz"
@@ -7697,12 +7487,10 @@ jsonpointer@^5.0.0:
resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz"
integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==
-jsonwebtoken@^9.0.0, jsonwebtoken@^9.0.3:
- version "9.0.3"
- resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz#6cd57ab01e9b0ac07cb847d53d3c9b6ee31f7ae2"
- integrity sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==
+jsonwebtoken@^9.0.0, jsonwebtoken@^9.0.2:
+ version "9.0.2"
dependencies:
- jws "^4.0.1"
+ jws "^3.2.2"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
@@ -7733,21 +7521,30 @@ jsprim@^1.2.2:
object.assign "^4.1.4"
object.values "^1.1.6"
-jwa@^2.0.1:
+jwa@^1.4.1:
+ version "1.4.2"
+ dependencies:
+ buffer-equal-constant-time "^1.0.1"
+ ecdsa-sig-formatter "1.0.11"
+ safe-buffer "^5.0.1"
+
+jwa@^2.0.0:
version "2.0.1"
- resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.1.tgz#bf8176d1ad0cd72e0f3f58338595a13e110bc804"
- integrity sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==
dependencies:
buffer-equal-constant-time "^1.0.1"
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
-jws@^4.0.0, jws@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.1.tgz#07edc1be8fac20e677b283ece261498bd38f0690"
- integrity sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==
+jws@^3.2.2:
+ version "3.2.2"
+ dependencies:
+ jwa "^1.4.1"
+ safe-buffer "^5.0.1"
+
+jws@^4.0.0:
+ version "4.0.0"
dependencies:
- jwa "^2.0.1"
+ jwa "^2.0.0"
safe-buffer "^5.0.1"
kareem@2.3.2:
@@ -7784,13 +7581,6 @@ language-tags@^1.0.9:
dependencies:
language-subtag-registry "^0.3.20"
-launder@^1.7.1:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/launder/-/launder-1.7.1.tgz#ef7155ab0c3ddec2323089c961d2e9a249aa5b0d"
- integrity sha512-mU6WRz5EusL9ZZuiZ5SO4Y6C0P9PAUR9iwdb6bzj4KDihm28DiHFw+/yk9DBH4f+Pv1wuzQ4e2jV3oQ7mkIqvw==
- dependencies:
- dayjs "^1.11.7"
-
lazy@1.0.11:
version "1.0.11"
resolved "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz"
@@ -7838,16 +7628,15 @@ lines-and-columns@^1.1.6:
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lint-staged@^16.2.6:
- version "16.4.0"
- resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-16.4.0.tgz#a00b0e3abff59239cef6d7d9341e8f8473308e23"
- integrity sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==
+ version "16.2.6"
dependencies:
- commander "^14.0.3"
+ commander "^14.0.1"
listr2 "^9.0.5"
- picomatch "^4.0.3"
+ micromatch "^4.0.8"
+ nano-spawn "^2.0.0"
+ pidtree "^0.6.0"
string-argv "^0.3.2"
- tinyexec "^1.0.4"
- yaml "^2.8.2"
+ yaml "^2.8.1"
listr2@^9.0.5:
version "9.0.5"
@@ -8156,11 +7945,6 @@ lru-cache@^7.14.1:
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
-luxon@^1.23.x:
- version "1.28.1"
- resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.1.tgz#528cdf3624a54506d710290a2341aa8e6e6c61b0"
- integrity sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==
-
luxon@^3.2.1:
version "3.7.2"
resolved "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz"
@@ -8260,16 +8044,16 @@ micromatch@^4.0.4:
braces "^3.0.3"
picomatch "^2.3.1"
-mime-db@1.52.0:
- version "1.52.0"
- resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
- integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
-
"mime-db@>= 1.43.0 < 2":
version "1.54.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz"
integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==
+mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
@@ -8277,7 +8061,7 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
dependencies:
mime-db "1.52.0"
-mime@1.6.0, mime@^1.3.4:
+mime@^1.3.4, mime@1.6.0:
version "1.6.0"
resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
@@ -8297,24 +8081,13 @@ mimic-function@^5.0.0:
resolved "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz"
integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==
-minimatch@^10.2.1:
- version "10.2.5"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.5.tgz#bd48687a0be38ed2961399105600f832095861d1"
- integrity sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==
- dependencies:
- brace-expansion "^5.0.5"
-
minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e"
- integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==
+ version "3.1.2"
dependencies:
brace-expansion "^1.1.7"
minimatch@^8.0.2:
- version "8.0.7"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.7.tgz#954766e22da88a3e0a17ad93b58c15c9d8a579de"
- integrity sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==
+ version "8.0.4"
dependencies:
brace-expansion "^2.0.1"
@@ -8329,28 +8102,38 @@ minipass@^4.2.4:
integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.3.tgz#79389b4eb1bb2d003a9bba87d492f2bd37bdc65b"
- integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==
+ version "7.1.2"
mitt@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz"
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
-mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.6:
+mkdirp@^0.5.0:
+ version "0.5.6"
+ resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz"
+ integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
+ dependencies:
+ minimist "^1.2.6"
+
+mkdirp@^0.5.1:
version "0.5.6"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz"
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
dependencies:
minimist "^1.2.6"
+mkdirp@^0.5.6:
+ version "0.5.6"
+ dependencies:
+ minimist "^1.2.6"
+
mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
-moment-timezone@^0.5.35:
+moment-timezone@^0.5.35, moment-timezone@^0.5.x:
version "0.5.48"
resolved "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz"
integrity sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==
@@ -8394,7 +8177,7 @@ mongodb-memory-server@^7.6.3:
mongodb-memory-server-core "7.6.3"
tslib "^2.3.0"
-mongodb@3.7.4, mongodb@^3.7.3:
+mongodb@^3.7.3, mongodb@3.7.4:
version "3.7.4"
resolved "https://registry.npmjs.org/mongodb/-/mongodb-3.7.4.tgz"
integrity sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==
@@ -8420,7 +8203,7 @@ mongoose-validator@^2.1.0:
is "^3.2.1"
validator "^10.4.0"
-mongoose@^5.13.23:
+mongoose@*, mongoose@^5.13.23:
version "5.13.23"
resolved "https://registry.npmjs.org/mongoose/-/mongoose-5.13.23.tgz"
integrity sha512-Q5bo1yYOcH2wbBPP4tGmcY5VKsFkQcjUDh66YjrbneAFB3vNKQwLvteRFLuLiU17rA5SDl3UMcMJLD9VS8ng2Q==
@@ -8456,6 +8239,11 @@ mquery@3.2.5:
safe-buffer "5.1.2"
sliced "1.0.1"
+ms@^2.1.1, ms@^2.1.3, ms@2.1.3:
+ version "2.1.3"
+ resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
@@ -8466,11 +8254,6 @@ ms@2.1.2:
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-ms@2.1.3, ms@^2.1.1, ms@^2.1.3:
- version "2.1.3"
- resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
- integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-
multer@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz"
@@ -8501,6 +8284,9 @@ mute-stream@0.0.5:
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz"
integrity sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==
+nano-spawn@^2.0.0:
+ version "2.0.0"
+
nanoid@^3.3.11:
version "3.3.11"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz"
@@ -8511,16 +8297,16 @@ natural-compare@^1.4.0:
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
-negotiator@0.6.3:
- version "0.6.3"
- resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
- integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-
negotiator@~0.6.4:
version "0.6.4"
resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz"
integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==
+negotiator@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
+ integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
+
netmask@^2.0.2:
version "2.1.1"
resolved "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz"
@@ -8575,16 +8361,6 @@ node-environment-flags@^1.0.5:
object.getownpropertydescriptors "^2.0.3"
semver "^5.7.0"
-node-exports-info@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/node-exports-info/-/node-exports-info-1.6.0.tgz#1aedafb01a966059c9a5e791a94a94d93f5c2a13"
- integrity sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==
- dependencies:
- array.prototype.flatmap "^1.3.3"
- es-errors "^1.3.0"
- object.entries "^1.1.9"
- semver "^6.3.1"
-
node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.7.0:
version "2.7.0"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz"
@@ -8593,19 +8369,15 @@ node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.7.0:
whatwg-url "^5.0.0"
node-forge@^1.3.1:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.4.0.tgz#1c7b7d8bdc2d078739f58287d589d903a11b2fc2"
- integrity sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==
+ version "1.3.1"
node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz"
integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==
-node-releases@^2.0.36:
- version "2.0.44"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.44.tgz#212c9b983f5bb70d311dd68c27d55dd0e65d1ca7"
- integrity sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==
+node-releases@^2.0.26:
+ version "2.0.27"
node-schedule@^2.1.1:
version "2.1.1"
@@ -8622,14 +8394,12 @@ nodemailer@^7.0.11:
integrity sha512-gnXhNRE0FNhD7wPSCGhdNh46Hs6nm+uTyg+Kq0cZukNQiYdnCsoQjodNP9BQVG9XrcK/v6/MgpAPBUFyzh9pvw==
nodemon@^3.0.1:
- version "3.1.14"
- resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.14.tgz#8487ca379c515301d221ec007f27f24ecafa2b51"
- integrity sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==
+ version "3.1.10"
dependencies:
chokidar "^3.5.2"
debug "^4"
ignore-by-default "^1.0.1"
- minimatch "^10.2.1"
+ minimatch "^3.1.2"
pstree.remy "^1.1.8"
semver "^7.5.3"
simple-update-notifier "^2.0.0"
@@ -8724,17 +8494,15 @@ object.fromentries@^2.0.8:
es-object-atoms "^1.0.0"
object.getownpropertydescriptors@^2.0.3:
- version "2.1.9"
- resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.9.tgz#bf9e7520f14d50de88dee2b9c9eca841166322dc"
- integrity sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==
+ version "2.1.8"
dependencies:
- array.prototype.reduce "^1.0.8"
- call-bind "^1.0.8"
+ array.prototype.reduce "^1.0.6"
+ call-bind "^1.0.7"
define-properties "^1.2.1"
- es-abstract "^1.24.0"
- es-object-atoms "^1.1.1"
- gopd "^1.2.0"
- safe-array-concat "^1.1.3"
+ es-abstract "^1.23.2"
+ es-object-atoms "^1.0.0"
+ gopd "^1.0.1"
+ safe-array-concat "^1.1.2"
object.groupby@^1.0.3:
version "1.0.3"
@@ -8755,7 +8523,7 @@ object.values@^1.1.6, object.values@^1.2.1:
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
-on-finished@~2.4.1:
+on-finished@~2.4.1, on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
@@ -8793,11 +8561,6 @@ onetime@^7.0.0:
dependencies:
mimic-function "^5.0.0"
-optional-require@1.0.x:
- version "1.0.3"
- resolved "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz"
- integrity sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==
-
optional-require@^1.1.8:
version "1.1.10"
resolved "https://registry.npmjs.org/optional-require/-/optional-require-1.1.10.tgz"
@@ -8805,6 +8568,11 @@ optional-require@^1.1.8:
dependencies:
require-at "^1.0.6"
+optional-require@1.0.x:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz"
+ integrity sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==
+
optionator@^0.8.2:
version "0.8.3"
resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz"
@@ -8969,11 +8737,6 @@ path-exists@^4.0.0:
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
-path-expression-matcher@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz#3b98545dc88ffebb593e2d8458d0929da9275f4a"
- integrity sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==
-
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
@@ -9003,9 +8766,7 @@ path-scurry@^1.6.1:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-to-regexp@~0.1.12:
- version "0.1.13"
- resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.13.tgz#9b22ec16bc3ab88d05a0c7e369869421401ab17d"
- integrity sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==
+ version "0.1.12"
pdfkit@^0.17.2:
version "0.17.2"
@@ -9034,14 +8795,7 @@ picocolors@^1.1.1:
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601"
- integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==
-
-picomatch@^4.0.3:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589"
- integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==
+ version "2.3.1"
pidtree@^0.6.0:
version "0.6.0"
@@ -9065,7 +8819,14 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
-pkg-dir@^4.1.0, pkg-dir@^4.2.0:
+pkg-dir@^4.1.0:
+ version "4.2.0"
+ resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz"
+ integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
+ dependencies:
+ find-up "^4.0.0"
+
+pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
@@ -9109,9 +8870,7 @@ possible-typed-array-names@^1.0.0:
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
postcss@^8.3.11:
- version "8.5.14"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.14.tgz#a66c2d7808fadf69ebb5b84a03f8bafd76c4919c"
- integrity sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==
+ version "8.5.6"
dependencies:
nanoid "^3.3.11"
picocolors "^1.1.1"
@@ -9215,11 +8974,6 @@ proxy-from-env@^1.1.0:
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
-proxy-from-env@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz#a7487568adad577cfaaa7e88c49cab3ab3081aba"
- integrity sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==
-
psl@^1.1.28:
version "1.15.0"
resolved "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz"
@@ -9240,60 +8994,53 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
-punycode@1.3.2:
- version "1.3.2"
- resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz"
- integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==
-
punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
-puppeteer-core@24.43.1:
- version "24.43.1"
- resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.43.1.tgz#c10a5d398b69911c324e04c85ee2b236b9ec940e"
- integrity sha512-T5ScUMAsmhdNbgDR41AGESYeS6V9MSgetkSnVhhW+gXvzC42VesKCn5ld87gAZDJ6vLHL9GkRvY9WtQWSnwFbw==
+punycode@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz"
+ integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==
+
+puppeteer-core@24.40.0:
+ version "24.40.0"
+ resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.40.0.tgz"
+ integrity sha512-MWL3XbUCfVgGR0gRsidzT6oKJT2QydPLhMITU6HoVWiiv4gkb6gJi3pcdAa8q4HwjBTbqISOWVP4aJiiyUJvag==
dependencies:
- "@puppeteer/browsers" "2.13.2"
+ "@puppeteer/browsers" "2.13.0"
chromium-bidi "14.0.0"
debug "^4.4.3"
- devtools-protocol "0.0.1608973"
- typed-query-selector "^2.12.2"
+ devtools-protocol "0.0.1581282"
+ typed-query-selector "^2.12.1"
webdriver-bidi-protocol "0.4.1"
- ws "^8.20.0"
+ ws "^8.19.0"
-puppeteer@^24.41.0:
- version "24.43.1"
- resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.43.1.tgz#86cad9170ce2dec2db3b8d1d34c0c91424bbe3e3"
- integrity sha512-/FSOViCrqRdb1HDocpsM9Z1giA71gTQPUt3SpHGVRALKAy/rJr1fLFYZW9F23qPxqVxTHQnbh/5B5opJST3kAw==
+puppeteer@^24.40.0:
+ version "24.40.0"
+ resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-24.40.0.tgz"
+ integrity sha512-IxQbDq93XHVVLWHrAkFP7F7iHvb9o0mgfsSIMlhHb+JM+JjM1V4v4MNSQfcRWJopx9dsNOr9adYv0U5fm9BJBQ==
dependencies:
- "@puppeteer/browsers" "2.13.2"
+ "@puppeteer/browsers" "2.13.0"
chromium-bidi "14.0.0"
cosmiconfig "^9.0.0"
- devtools-protocol "0.0.1608973"
- puppeteer-core "24.43.1"
- typed-query-selector "^2.12.2"
+ devtools-protocol "0.0.1581282"
+ puppeteer-core "24.40.0"
+ typed-query-selector "^2.12.1"
pure-rand@^6.0.0:
version "6.1.0"
resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz"
integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==
-qs@^6.11.0, qs@^6.7.0, qs@~6.14.0:
+qs@^6.11.0, qs@^6.7.0, qs@^6.9.4, qs@~6.14.0:
version "6.14.2"
resolved "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz"
integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==
dependencies:
side-channel "^1.1.0"
-qs@^6.14.1:
- version "6.15.1"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.1.tgz#bdb55aed06bfac257a90c44a446a73fba5575c8f"
- integrity sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==
- dependencies:
- side-channel "^1.1.0"
-
qs@~6.5.2:
version "6.5.5"
resolved "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz"
@@ -9344,7 +9091,33 @@ react-is@^18.0.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
-readable-stream@^2.0.2, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@~2.3.6:
+readable-stream@^2.0.2:
+ version "2.3.8"
+ resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
+readable-stream@^2.2.2:
+ version "2.3.8"
+ resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
+readable-stream@^2.3.5:
version "2.3.8"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
@@ -9376,6 +9149,19 @@ readable-stream@~1.1.9:
isarray "0.0.1"
string_decoder "~0.10.x"
+readable-stream@~2.3.6:
+ version "2.3.8"
+ resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
@@ -9383,6 +9169,11 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
+readline@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz"
+ integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==
+
readline2@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz"
@@ -9392,11 +9183,6 @@ readline2@^1.0.1:
is-fullwidth-code-point "^1.0.0"
mute-stream "0.0.5"
-readline@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz"
- integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==
-
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz"
@@ -9447,7 +9233,7 @@ regenerator-runtime@^0.14.0:
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz"
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
-regexp-clone@1.0.0, regexp-clone@^1.0.0:
+regexp-clone@^1.0.0, regexp-clone@1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz"
integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==
@@ -9482,9 +9268,7 @@ regjsgen@^0.8.0:
integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==
regjsparser@^0.13.0:
- version "0.13.1"
- resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.1.tgz#0593cbacb27527927692030928ae4d3b878d6f8d"
- integrity sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==
+ version "0.13.0"
dependencies:
jsesc "~3.1.0"
@@ -9574,25 +9358,17 @@ resolve.exports@^2.0.0:
resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz"
integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==
-resolve@^1.1.6, resolve@^1.20.0, resolve@^1.22.11, resolve@^1.22.8:
- version "1.22.12"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f"
- integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==
+resolve@^1.1.6, resolve@^1.20.0, resolve@^1.22.10, resolve@^1.22.4, resolve@^1.22.8:
+ version "1.22.11"
dependencies:
- es-errors "^1.3.0"
is-core-module "^2.16.1"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-resolve@^2.0.0-next.5, resolve@^2.0.0-next.6:
- version "2.0.0-next.6"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.6.tgz#b3961812be69ace7b3bc35d5bf259434681294af"
- integrity sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==
+resolve@^2.0.0-next.5:
+ version "2.0.0-next.5"
dependencies:
- es-errors "^1.3.0"
- is-core-module "^2.16.1"
- node-exports-info "^1.6.0"
- object-keys "^1.1.1"
+ is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
@@ -9627,13 +9403,6 @@ rfdc@^1.4.1:
resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz"
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
-"rimraf@2.5.2 - 2.7.1":
- version "2.7.1"
- resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
- integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
- dependencies:
- glob "^7.1.3"
-
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
@@ -9648,6 +9417,13 @@ rimraf@~2.6.2:
dependencies:
glob "^7.1.3"
+"rimraf@2.5.2 - 2.7.1":
+ version "2.7.1"
+ resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
+ integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
+ dependencies:
+ glob "^7.1.3"
+
run-async@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz"
@@ -9667,7 +9443,7 @@ rx-lite@^3.1.2:
resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz"
integrity sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==
-safe-array-concat@^1.1.3:
+safe-array-concat@^1.1.2, safe-array-concat@^1.1.3:
version "1.1.3"
resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz"
integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==
@@ -9678,15 +9454,20 @@ safe-array-concat@^1.1.3:
has-symbols "^1.1.0"
isarray "^2.0.5"
-safe-buffer@5.1.2, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0, safe-buffer@~5.2.1, safe-buffer@5.2.1:
+ version "5.2.1"
+ resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0, safe-buffer@~5.2.1:
- version "5.2.1"
- resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
- integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+safe-buffer@5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
+ integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-push-apply@^1.0.0:
version "1.0.0"
@@ -9705,21 +9486,18 @@ safe-regex-test@^1.0.3, safe-regex-test@^1.1.0:
es-errors "^1.3.0"
is-regex "^1.2.1"
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+safer-buffer@^2.0.2, safer-buffer@^2.1.0, "safer-buffer@>= 2.1.2 < 3", safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sanitize-html@^2.16.0:
- version "2.17.4"
- resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.17.4.tgz#7db8b73b0024ccf543978c2a44da8223c4740cb1"
- integrity sha512-2HW7v2ol/uAM7sX4hbD8Z59OGWmAPrvjL8E71UWlBcj6m+kcF6ilQBLny+cIgY214QJeJT5tQuxKKqX0SQqjGQ==
+ version "2.17.0"
dependencies:
deepmerge "^4.2.2"
escape-string-regexp "^4.0.0"
- htmlparser2 "^10.1.0"
+ htmlparser2 "^8.0.0"
is-plain-object "^5.0.0"
- launder "^1.7.1"
parse-srcset "^1.0.2"
postcss "^8.3.11"
@@ -9730,7 +9508,7 @@ saslprep@^1.0.0:
dependencies:
sparse-bitfield "^3.0.3"
-sax@1.2.1, sax@1.2.x, sax@>=0.6.0:
+sax@>=0.6.0, sax@1.2.1, sax@1.2.x:
version "1.2.1"
resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz"
integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==
@@ -9745,49 +9523,65 @@ semver@^5.6.0, semver@^5.7.0:
resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
-semver@^6.0.0, semver@^6.3.0, semver@^6.3.1:
+semver@^5.7.0:
+ version "5.7.2"
+ resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz"
+ integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
+
+semver@^6.0.0:
version "6.3.1"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.7.3:
- version "7.8.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.0.tgz#ed0661039fcbcda2ce71f01fa6adbefaa77040df"
- integrity sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==
+semver@^6.3.0, semver@^6.3.1:
+ version "6.3.1"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+
+semver@^7.3.5:
+ version "7.7.3"
+
+semver@^7.3.8:
+ version "7.7.3"
+
+semver@^7.5.3:
+ version "7.7.3"
+
+semver@^7.5.4:
+ version "7.7.3"
+
+semver@^7.7.3:
+ version "7.7.3"
semver@^7.7.4:
version "7.7.4"
resolved "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz"
integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==
-send@~0.19.0, send@~0.19.1:
- version "0.19.2"
- resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29"
- integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==
+send@~0.19.0, send@0.19.0:
+ version "0.19.0"
dependencies:
debug "2.6.9"
depd "2.0.0"
destroy "1.2.0"
- encodeurl "~2.0.0"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
- fresh "~0.5.2"
- http-errors "~2.0.1"
+ fresh "0.5.2"
+ http-errors "2.0.0"
mime "1.6.0"
ms "2.1.3"
- on-finished "~2.4.1"
+ on-finished "2.4.1"
range-parser "~1.2.1"
- statuses "~2.0.2"
+ statuses "2.0.1"
serve-static@~1.16.2:
- version "1.16.3"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9"
- integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==
+ version "1.16.2"
dependencies:
encodeurl "~2.0.0"
escape-html "~1.0.3"
parseurl "~1.3.3"
- send "~0.19.1"
+ send "0.19.0"
set-function-length@^1.2.2:
version "1.2.2"
@@ -9820,7 +9614,7 @@ set-proto@^1.0.0:
es-errors "^1.3.0"
es-object-atoms "^1.0.0"
-setprototypeof@1.2.0, setprototypeof@~1.2.0:
+setprototypeof@~1.2.0, setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
@@ -9888,12 +9682,10 @@ shelljs@^0.7.5:
rechoir "^0.6.2"
side-channel-list@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127"
- integrity sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==
+ version "1.0.0"
dependencies:
es-errors "^1.3.0"
- object-inspect "^1.13.4"
+ object-inspect "^1.13.3"
side-channel-map@^1.0.1:
version "1.0.1"
@@ -9964,11 +9756,6 @@ slash@^3.0.0:
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-slice-ansi@0.0.4:
- version "0.0.4"
- resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz"
- integrity sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==
-
slice-ansi@^7.1.0:
version "7.1.2"
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz"
@@ -9977,13 +9764,10 @@ slice-ansi@^7.1.0:
ansi-styles "^6.2.1"
is-fullwidth-code-point "^5.0.0"
-slice-ansi@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-8.0.0.tgz#22d0b66d18bc5c57f488bfcf36cbde3bef731537"
- integrity sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==
- dependencies:
- ansi-styles "^6.2.3"
- is-fullwidth-code-point "^5.1.0"
+slice-ansi@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz"
+ integrity sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==
sliced@1.0.1:
version "1.0.1"
@@ -9996,30 +9780,24 @@ smart-buffer@^4.2.0:
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
socket.io-adapter@~2.5.2:
- version "2.5.6"
- resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz#c697f609d36a676a46749782274607d8df52c1d8"
- integrity sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==
+ version "2.5.5"
dependencies:
- debug "~4.4.1"
- ws "~8.18.3"
+ debug "~4.3.4"
+ ws "~8.17.1"
socket.io-parser@~4.2.4:
- version "4.2.6"
- resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.6.tgz#19156bf179af3931abd05260cfb1491822578a6f"
- integrity sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==
+ version "4.2.4"
dependencies:
"@socket.io/component-emitter" "~3.1.0"
- debug "~4.4.1"
+ debug "~4.3.1"
socket.io@^4.8.1:
- version "4.8.3"
- resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.8.3.tgz#ca6ba1431c69532e1e0a6f496deebeb601dbc4df"
- integrity sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==
+ version "4.8.1"
dependencies:
accepts "~1.3.4"
base64id "~2.0.0"
cors "~2.8.5"
- debug "~4.4.1"
+ debug "~4.3.2"
engine.io "~6.6.0"
socket.io-adapter "~2.5.2"
socket.io-parser "~4.2.4"
@@ -10051,14 +9829,6 @@ source-map-js@^1.2.1:
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
-source-map-support@0.5.13:
- version "0.5.13"
- resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz"
- integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
source-map-support@^0.5.16:
version "0.5.21"
resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz"
@@ -10067,6 +9837,14 @@ source-map-support@^0.5.16:
buffer-from "^1.0.0"
source-map "^0.6.0"
+source-map-support@0.5.13:
+ version "0.5.13"
+ resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz"
+ integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
@@ -10084,16 +9862,16 @@ sparse-bitfield@^3.0.3:
dependencies:
memory-pager "^1.0.2"
-sprintf-js@1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
- integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
+sprintf-js@1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
+ integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
+
sshpk@^1.7.0:
version "1.18.0"
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz"
@@ -10116,7 +9894,10 @@ stack-utils@^2.0.3:
dependencies:
escape-string-regexp "^2.0.0"
-statuses@~2.0.1, statuses@~2.0.2:
+statuses@~2.0.1, statuses@2.0.1:
+ version "2.0.1"
+
+statuses@~2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz"
integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==
@@ -10153,6 +9934,25 @@ strict-event-emitter@^0.5.1:
resolved "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz"
integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
+
+string_decoder@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
+ integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+ dependencies:
+ safe-buffer "~5.1.0"
+
string-argv@^0.3.2:
version "0.3.2"
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz"
@@ -10183,7 +9983,16 @@ string-width@^2.0.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+string-width@^4.1.0, string-width@^4.2.0:
+ version "4.2.3"
+ resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -10201,13 +10010,11 @@ string-width@^7.0.0:
get-east-asian-width "^1.0.0"
strip-ansi "^7.1.0"
-string-width@^8.2.0:
- version "8.2.1"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-8.2.1.tgz#165089cfa527cc88fbc23dd73313f5e334af1ea1"
- integrity sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==
+string-width@^8.0.0:
+ version "8.1.0"
dependencies:
- get-east-asian-width "^1.5.0"
- strip-ansi "^7.1.2"
+ get-east-asian-width "^1.3.0"
+ strip-ansi "^7.1.0"
string.prototype.includes@^2.0.1:
version "2.0.1"
@@ -10277,25 +10084,6 @@ string.prototype.trimstart@^1.0.8:
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
-string_decoder@^1.1.1:
- version "1.3.0"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
- integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
- dependencies:
- safe-buffer "~5.2.0"
-
-string_decoder@~0.10.x:
- version "0.10.31"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
- integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
@@ -10317,12 +10105,10 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
dependencies:
ansi-regex "^5.0.1"
-strip-ansi@^7.1.0, strip-ansi@^7.1.2:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.2.0.tgz#d22a269522836a627af8d04b5c3fd2c7fa3e32e3"
- integrity sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==
+strip-ansi@^7.1.0:
+ version "7.1.2"
dependencies:
- ansi-regex "^6.2.2"
+ ansi-regex "^6.0.1"
strip-bom@^3.0.0:
version "3.0.0"
@@ -10349,10 +10135,8 @@ strip-json-comments@~2.0.1:
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz"
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
-strnum@^2.1.0, strnum@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.3.0.tgz#81bfbfef53db8c3217ea62a98c026886ec4a2761"
- integrity sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==
+strnum@^2.1.0:
+ version "2.1.1"
superagent@^8.1.2:
version "8.1.2"
@@ -10488,6 +10272,11 @@ text-table@^0.2.0, text-table@~0.2.0:
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
+through@^2.3.6:
+ version "2.3.8"
+ resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
+ integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+
through2@^2.0.0:
version "2.0.5"
resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
@@ -10496,11 +10285,6 @@ through2@^2.0.0:
readable-stream "~2.3.6"
xtend "~4.0.1"
-through@^2.3.6:
- version "2.3.8"
- resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
- integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
-
time-stamp@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz"
@@ -10516,11 +10300,6 @@ tiny-warning@^1.0.3:
resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
-tinyexec@^1.0.4:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.1.2.tgz#11feef204b706d4668ca4013db29f3bd64f5c4dc"
- integrity sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==
-
tlds@^1.234.0:
version "1.261.0"
resolved "https://registry.npmjs.org/tlds/-/tlds-1.261.0.tgz"
@@ -10543,7 +10322,7 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
-toidentifier@~1.0.1:
+toidentifier@~1.0.1, toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
@@ -10581,7 +10360,7 @@ tsconfig-paths@^3.15.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
-tslib@2.8.1, tslib@^2.0.1, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.8.0, tslib@^2.8.1:
+tslib@^2.0.1, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.8.0, tslib@^2.8.1, tslib@2.8.1:
version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
@@ -10599,15 +10378,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
twilio@^5.10.2:
- version "5.13.1"
- resolved "https://registry.yarnpkg.com/twilio/-/twilio-5.13.1.tgz#ecfdad46644b58045b6d47cf973bd0124c632c4f"
- integrity sha512-sT+PkhptF4Mf7t8eXFFvPQx4w5VHnBIPXbltGPMFRe+R2GxfRdMuFbuNA/cEm0aQR6LFQOn33+fhClg+TjRVqQ==
+ version "5.10.4"
dependencies:
- axios "^1.13.5"
+ axios "^1.12.0"
dayjs "^1.11.9"
https-proxy-agent "^5.0.0"
- jsonwebtoken "^9.0.3"
- qs "^6.14.1"
+ jsonwebtoken "^9.0.2"
+ qs "^6.9.4"
scmp "^2.1.0"
xmlbuilder "^13.0.2"
@@ -10698,10 +10475,10 @@ typed-array-length@^1.0.7:
possible-typed-array-names "^1.0.0"
reflect.getprototypeof "^1.0.6"
-typed-query-selector@^2.12.2:
- version "2.12.2"
- resolved "https://registry.yarnpkg.com/typed-query-selector/-/typed-query-selector-2.12.2.tgz#65e2462ac6b0aecfae1bfac1a4f3027070dbabaa"
- integrity sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==
+typed-query-selector@^2.12.1:
+ version "2.12.1"
+ resolved "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz"
+ integrity sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==
typedarray@^0.0.6:
version "0.0.6"
@@ -10737,10 +10514,8 @@ undefsafe@^2.0.5:
resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz"
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
-undici-types@~7.21.0:
- version "7.21.0"
- resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.21.0.tgz#433f7dd1b5daa9ab4dacb721a5e11a8de51eadda"
- integrity sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==
+undici-types@~7.16.0:
+ version "7.16.0"
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.1"
@@ -10791,10 +10566,8 @@ unpipe@~1.0.0:
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
-update-browserslist-db@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d"
- integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==
+update-browserslist-db@^1.1.4:
+ version "1.1.4"
dependencies:
escalade "^3.2.0"
picocolors "^1.1.1"
@@ -10847,21 +10620,31 @@ utils-merge@1.0.1:
resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
+uuid@^3.3.2, uuid@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz"
+ integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
+
+uuid@^8.0.0:
+ version "8.3.2"
+ resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
+uuid@^8.3.1:
+ version "8.3.2"
+ resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
uuid@8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz"
integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==
-uuid@8.3.2, uuid@^8.0.0, uuid@^8.3.1:
+uuid@8.3.2:
version "8.3.2"
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
-uuid@^3.3.2, uuid@^3.4.0:
- version "3.4.0"
- resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz"
- integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-
v8-to-istanbul@^9.0.1:
version "9.3.0"
resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz"
@@ -10883,10 +10666,8 @@ validator@^10.4.0:
resolved "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz"
integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==
-validator@~13.15.23:
- version "13.15.35"
- resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.35.tgz#81cf455c51f15b69d8d340be5914f3fab00dbf7f"
- integrity sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==
+validator@~13.15.15:
+ version "13.15.20"
vary@^1, vary@~1.1.2:
version "1.1.2"
@@ -10982,9 +10763,7 @@ which-collection@^1.0.2:
is-weakset "^2.0.3"
which-typed-array@^1.1.16, which-typed-array@^1.1.19, which-typed-array@^1.1.2:
- version "1.1.20"
- resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.20.tgz#3fdb7adfafe0ea69157b1509f3a1cd892bd1d122"
- integrity sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==
+ version "1.1.19"
dependencies:
available-typed-arrays "^1.0.7"
call-bind "^1.0.8"
@@ -11044,30 +10823,18 @@ write@^0.2.1:
dependencies:
mkdirp "^0.5.1"
-ws@^7.4.6:
- version "7.5.10"
- resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz"
- integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==
-
-ws@^8.17.1, ws@^8.18.3:
+ws@*, ws@^8.17.1, ws@^8.18.3, ws@^8.19.0:
version "8.19.0"
resolved "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz"
integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==
-ws@^8.20.0:
- version "8.20.1"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.1.tgz#91a9ae2b312ccf98e0a85ec499b48cef45ab0ddb"
- integrity sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==
-
-ws@~8.18.3:
- version "8.18.3"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472"
- integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==
+ws@^7.4.6:
+ version "7.5.10"
+ resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz"
+ integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==
-xml-naming@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/xml-naming/-/xml-naming-0.1.0.tgz#8ab7106c5b8d23caa2fabac1cadf17136379fbd8"
- integrity sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==
+ws@~8.17.1:
+ version "8.17.1"
xml2js@0.6.2:
version "0.6.2"
@@ -11077,11 +10844,6 @@ xml2js@0.6.2:
sax ">=0.6.0"
xmlbuilder "~11.0.0"
-xmlbuilder@8.2.x:
- version "8.2.2"
- resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz"
- integrity sha512-eKRAFz04jghooy8muekqzo8uCSVNeyRedbuJrp0fovbLIi7wlsYtdUn3vBAAPq2Y3/0xMz2WMEUQ8yhVVO9Stw==
-
xmlbuilder@^13.0.2:
version "13.0.2"
resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz"
@@ -11092,6 +10854,11 @@ xmlbuilder@~11.0.0:
resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+xmlbuilder@8.2.x:
+ version "8.2.2"
+ resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz"
+ integrity sha512-eKRAFz04jghooy8muekqzo8uCSVNeyRedbuJrp0fovbLIi7wlsYtdUn3vBAAPq2Y3/0xMz2WMEUQ8yhVVO9Stw==
+
xmlrpc@^1.3.2:
version "1.3.2"
resolved "https://registry.npmjs.org/xmlrpc/-/xmlrpc-1.3.2.tgz"
@@ -11110,20 +10877,23 @@ y18n@^5.0.5:
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
-yallist@4.0.0, yallist@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
- integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-yaml@^2.8.2:
- version "2.9.0"
- resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.9.0.tgz#78274afd93598a1dfdd6130df6a566defcbf9aa4"
- integrity sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==
+yallist@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
+ integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yallist@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
+ integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yaml@^2.8.1:
+ version "2.8.1"
yargs-parser@^21.1.1:
version "21.1.1"
@@ -11143,7 +10913,7 @@ yargs@^17.3.1, yargs@^17.7.2:
y18n "^5.0.5"
yargs-parser "^21.1.1"
-"yauzl@2.9.2 - 2.10.0", yauzl@^2.10.0:
+yauzl@^2.10.0, "yauzl@2.9.2 - 2.10.0":
version "2.10.0"
resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
@@ -11156,7 +10926,12 @@ yocto-queue@^0.1.0:
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
-zod@^3.23.8, zod@^3.24.1:
+zod@^3.23.8:
+ version "3.25.76"
+ resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz"
+ integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==
+
+zod@^3.24.1:
version "3.25.76"
resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz"
integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==