From c0d878f03dee32cea009f117a83ac3f534f75983 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 02:37:08 +0000 Subject: [PATCH 01/30] build(deps-dev): bump eslint-plugin-jest from 29.15.1 to 29.15.2 Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 29.15.1 to 29.15.2. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v29.15.1...v29.15.2) --- updated-dependencies: - dependency-name: eslint-plugin-jest dependency-version: 29.15.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 89cedd61..a79bf2b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "^29.15.1", + "eslint-plugin-jest": "^29.15.2", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", @@ -4539,9 +4539,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.15.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.1.tgz", - "integrity": "sha512-6BjyErCQauz3zfJvzLw/kAez2lf4LEpbHLvWBfEcG4EI0ZiRSwjoH2uZulMouU8kRkBH+S0rhqn11IhTvxKgKw==", + "version": "29.15.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", + "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13765,9 +13765,9 @@ } }, "eslint-plugin-jest": { - "version": "29.15.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.1.tgz", - "integrity": "sha512-6BjyErCQauz3zfJvzLw/kAez2lf4LEpbHLvWBfEcG4EI0ZiRSwjoH2uZulMouU8kRkBH+S0rhqn11IhTvxKgKw==", + "version": "29.15.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", + "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", "dev": true, "requires": { "@typescript-eslint/utils": "^8.0.0" diff --git a/package.json b/package.json index 22a9dc53..208827b2 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "^29.15.1", + "eslint-plugin-jest": "^29.15.2", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", From c972a78ee2c99da137ec7ad96f43dd32ace0fc75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 02:43:25 +0000 Subject: [PATCH 02/30] build(deps): bump axios from 1.15.0 to 1.15.2 Bumps [axios](https://github.com/axios/axios) from 1.15.0 to 1.15.2. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.15.0...v1.15.2) --- updated-dependencies: - dependency-name: axios dependency-version: 1.15.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index a79bf2b2..59c10473 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", - "axios": "^1.15.0", + "axios": "^1.15.2", "dotenv": "^17.3.1", "envalid": "^8.1.1", "express": "^5.2.1", @@ -3104,9 +3104,9 @@ } }, "node_modules/axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", @@ -12776,9 +12776,9 @@ } }, "axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "requires": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", diff --git a/package.json b/package.json index 208827b2..3b185083 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", - "axios": "^1.15.0", + "axios": "^1.15.2", "dotenv": "^17.3.1", "envalid": "^8.1.1", "express": "^5.2.1", From 5daf495232706922720e5b55a790099dbc54ad95 Mon Sep 17 00:00:00 2001 From: Jay Date: Fri, 22 May 2026 13:27:09 +0200 Subject: [PATCH 03/30] feat: sync proposals, experiments and samples to SciCat from UOS feat: sync proposals, experiments and samples to SciCat from UOS --- .env.tests | 8 +- src/index.spec.ts | 5 + src/index.ts | 5 + src/models/Event.ts | 2 + src/models/ProposalMessage.ts | 34 +- .../upsertProposalInScicat.ts | 270 ++--------- .../consumerCallbacks/upsertSampleInScicat.ts | 37 ++ .../ChatroomCreationQueueConsumer.ts | 4 +- .../ExperimentCreationQueueConsumer.ts | 47 ++ .../FolderCreationQueueConsumer.spec.ts | 10 +- .../consumers/FolderCreationQueueConsumer.ts | 4 +- .../ProposalCreationQueueConsumer.ts | 18 +- .../consumers/scicat/scicatProposal/dto.ts | 37 -- .../uoToScicatExperiment.mapper.spec.ts.snap | 151 +++++++ .../uoToScicatProposal.mapper.spec.ts.snap | 287 ++++++++++++ .../uoToScicatExperiment.mapper.spec.ts | 112 +++++ .../mappers/uoToScicatExperiment.mapper.ts | 216 +++++++++ .../mappers/uoToScicatProposal.mapper.spec.ts | 110 +++++ .../mappers/uoToScicatProposal.mapper.ts | 160 +++++++ .../type/scicatProposal.type.ts | 68 +++ .../scicat/scicatProposal/utils/common.ts | 10 + .../scicatProposal/utils/scicatApi.spec.ts | 25 ++ .../scicat/scicatProposal/utils/scicatApi.ts | 351 +++++++++++++++ .../collectUsersFromProposalMessage.spec.ts | 2 + .../consumers/utils/hasTriggeringStatus.ts | 17 +- .../utils/validateExperimentMessage.spec.ts | 41 ++ .../utils/validateExperimentMessage.ts | 29 ++ .../consumers/syncProposalQueueConsumer.ts | 4 +- src/queue/queueHandling.ts | 6 +- .../queries/getExperiment.query.ts | 422 ++++++++++++++++++ .../queries/getProposal.query.ts | 398 +++++++++++++++++ .../userOfficeApi/type/uoExperiment.type.ts | 44 ++ .../userOfficeApi/type/uoProposal.type.ts | 54 +++ src/services/userOfficeApi/uoApi.spec.ts | 78 ++++ src/services/userOfficeApi/uoApi.ts | 59 +++ 35 files changed, 2817 insertions(+), 308 deletions(-) create mode 100644 src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertSampleInScicat.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap create mode 100644 src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatProposal.mapper.spec.ts.snap create mode 100644 src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/type/scicatProposal.type.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/utils/common.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts create mode 100644 src/queue/consumers/utils/validateExperimentMessage.spec.ts create mode 100644 src/queue/consumers/utils/validateExperimentMessage.ts create mode 100644 src/services/userOfficeApi/queries/getExperiment.query.ts create mode 100644 src/services/userOfficeApi/queries/getProposal.query.ts create mode 100644 src/services/userOfficeApi/type/uoExperiment.type.ts create mode 100644 src/services/userOfficeApi/type/uoProposal.type.ts create mode 100644 src/services/userOfficeApi/uoApi.spec.ts create mode 100644 src/services/userOfficeApi/uoApi.ts diff --git a/.env.tests b/.env.tests index 0fe7df5c..b335d6f4 100644 --- a/.env.tests +++ b/.env.tests @@ -10,11 +10,12 @@ KAFKA_PASSWORD=test KAFKA_TOPIC=TestTopic SCICAT_BASE_URL=http://localhost/some/api -SCICAT_LOGIN_ENDPOINT=/login -SCICAT_USERNAME=user -SCICAT_PASSWORD=pass +SCICAT_JWT=eyJhbGciOiJIUzI1NiIsInR5 SCICAT_PROPOSAL_TRIGGERING_STATUSES="SCHEDULING, ALLOCATED" +USER_OFFICE_GRAPHQL_URL=http://localhost:8080 +USER_OFFICE_JWT=some-token + SYNAPSE_SERVER_URL=https://server-scichat SYNAPSE_SERVER_NAME=serverName SYNAPSE_SERVICE_USER=user @@ -23,6 +24,7 @@ SYNAPSE_OAUTH_ISSUER=SAMPLE_ISSUER USER_OFFICE_CORE_EXCHANGE_NAME=user_office_backend.fanout PROPOSAL_CREATION_QUEUE_NAME=connector.proposal_creation.queue +EXPERIMENT_CREATION_QUEUE_NAME=connector.experiment_creation.queue CHATROOM_CREATION_QUEUE_NAME=consumer.chatroom_creation.queue FOLDER_CREATION_QUEUE_NAME=connector.proposals_folders_creation.queue VISA_QUEUE_NAME=dummy diff --git a/src/index.spec.ts b/src/index.spec.ts index 99a55385..44d2016d 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -6,6 +6,11 @@ jest.mock('express', () => { return jest.fn(() => express); }); +jest.mock('./queue/consumers/scicat/scicatProposal/utils/scicatApi', () => ({ + scicatApi: { + serviceUsername: 'testuser', + }, +})); jest.mock('@user-office-software/duo-logger'); jest.mock('./middlewares/metrics/metrics', () => jest.fn()); diff --git a/src/index.ts b/src/index.ts index 23409f92..86a62ee4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,6 +34,9 @@ async function bootstrap() { const enableScicatProposalUpsert = str2Bool( process.env.ENABLE_SCICAT_PROPOSAL_UPSERT as string ); + const enableScicatExperimentUpsert = str2Bool( + process.env.ENABLE_SCICAT_EXPERIMENT_UPSERT as string + ); const enableScichatRoomCreation = str2Bool( process.env.ENABLE_SCICHAT_ROOM_CREATION as string ); @@ -55,6 +58,7 @@ async function bootstrap() { logger.logInfo('Services configuration', { SciCat_Proposal_Upsert: enableScicatProposalUpsert, + SciCat_Experiment_Upsert: enableScicatExperimentUpsert, Scichat_Room_Creation: enableScichatRoomCreation, Proposal_Folders_Creation: enableProposalFoldersCreation, Nicos_to_Scichat_Messages: enableNicosToScichatMessages, @@ -75,6 +79,7 @@ async function bootstrap() { if ( enableScicatProposalUpsert || + enableScicatExperimentUpsert || enableScichatRoomCreation || enableProposalFoldersCreation || enableMoodleFoldersCreation || diff --git a/src/models/Event.ts b/src/models/Event.ts index 2ed1cff6..158124a4 100644 --- a/src/models/Event.ts +++ b/src/models/Event.ts @@ -4,4 +4,6 @@ export enum Event { PROPOSAL_UPDATED = 'PROPOSAL_UPDATED', VISIT_CREATED = 'VISIT_CREATED', VISIT_DELETED = 'VISIT_DELETED', + EXPERIMENT_CREATED = 'EXPERIMENT_CREATED', + EXPERIMENT_UPDATED = 'EXPERIMENT_UPDATED', } diff --git a/src/models/ProposalMessage.ts b/src/models/ProposalMessage.ts index b2955ae5..e4e7e68b 100644 --- a/src/models/ProposalMessage.ts +++ b/src/models/ProposalMessage.ts @@ -1,4 +1,4 @@ -import { ProposalUser } from './../queue/consumers/scicat/scicatProposal/dto'; +import { ProposalUser } from '../queue/consumers/scicat/scicatProposal/dto'; export type Instrument = { id: number; @@ -6,6 +6,11 @@ export type Instrument = { allocatedTime: number; }; +export type Sample = { + id: number; + title: string; +}; + export interface InstrumentDto { _id: string; id: string; @@ -34,16 +39,27 @@ export enum ProposalStatusDefaultShortCodes { } export type ProposalMessageData = { - proposalPk: number; - shortCode: string; - title: string; abstract: string; callId: number; - newStatus?: ProposalStatusDefaultShortCodes; - submitted: boolean; + instruments?: Instrument[]; members: ProposalUser[]; - dataAccessUsers?: ProposalUser[]; - visitors?: ProposalUser[]; + dataAccessUsers: ProposalUser[]; + visitors: ProposalUser[]; + newStatus?: string; + proposalPk: number; proposer?: ProposalUser; - instruments?: Instrument[]; + shortCode: string; + title: string; + submitted: boolean; + samples?: Sample[]; +}; + +export type ExperimentMessageData = { + experimentId: string; + experimentPk: number; + startsAt: Date; + endsAt: Date; + status: string; + proposal?: ProposalMessageData; + samples?: Sample[]; }; diff --git a/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertProposalInScicat.ts b/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertProposalInScicat.ts index 0e1d5ade..a88186b0 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertProposalInScicat.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertProposalInScicat.ts @@ -1,256 +1,52 @@ import { logger } from '@user-office-software/duo-logger'; +import { upsertSamplesInScicat } from './upsertSampleInScicat'; import { - Instrument, - InstrumentDto, + ExperimentMessageData, + ProposalMessageData, } from '../../../../../models/ProposalMessage'; -import { ValidProposalMessageData } from '../../../utils/validateProposalMessage'; -import { CreateProposalDto, UpdateProposalDto } from '../dto'; - -const sciCatBaseUrl = process.env.SCICAT_BASE_URL; -const sciCatLoginEndpoint = process.env.SCICAT_LOGIN_ENDPOINT || '/Users/login'; -const sciCatUsername = process.env.SCICAT_USERNAME; -const sciCatPassword = process.env.SCICAT_PASSWORD; - -async function request( - url: string, - config: RequestInit -): Promise { - // NOTE: Node v18 comes with fetch API by default - const response = await fetch(url, config); - - if (!response.ok) { - return response.text().then((errorDetail) => { - throw new Error(errorDetail); - }); - } - - return (await response.json()) as TResponse; -} - -const getSciCatAccessToken = async () => { - const loginCredentials = { - username: sciCatUsername, - password: sciCatPassword, - }; - - // NOTE: We login every time when there is new message to get the access_token - const { access_token: sciCatAccessToken } = await request<{ - access_token: string; - }>(`${sciCatBaseUrl}${sciCatLoginEndpoint}`, { - method: 'POST', - body: JSON.stringify(loginCredentials), - headers: { - 'Content-Type': 'application/json', - }, - }); - - if (!sciCatAccessToken) { - throw new Error('No access token found'); - } - - return sciCatAccessToken; -}; - -const getCreateProposalDto = (proposalMessage: ValidProposalMessageData) => { - const createProposalDto: CreateProposalDto = { - proposalId: proposalMessage.shortCode, - title: proposalMessage.title, - pi_email: proposalMessage.proposer.email, - pi_firstname: proposalMessage.proposer.firstName, - pi_lastname: proposalMessage.proposer.lastName, - email: proposalMessage.proposer.email, - firstname: proposalMessage.proposer.firstName, - lastname: proposalMessage.proposer.lastName, - abstract: proposalMessage.abstract, - ownerGroup: proposalMessage.shortCode, - instrumentIds: [], - accessGroups: [], - startTime: new Date(), - endTime: new Date(), - MeasurementPeriodList: [], - metadata: {}, - }; - - return createProposalDto; -}; - -const getUpdateProposalDto = (proposalMessage: ValidProposalMessageData) => { - const updateProposalDto: UpdateProposalDto = { - title: proposalMessage.title, - pi_email: proposalMessage.proposer.email, - pi_firstname: proposalMessage.proposer.firstName, - pi_lastname: proposalMessage.proposer.lastName, - email: proposalMessage.proposer.email, - firstname: proposalMessage.proposer.firstName, - lastname: proposalMessage.proposer.lastName, - abstract: proposalMessage.abstract, - ownerGroup: proposalMessage.shortCode, - instrumentIds: [], - accessGroups: [], - startTime: new Date(), - endTime: new Date(), - MeasurementPeriodList: [], - metadata: {}, - }; - - return updateProposalDto; -}; - -const createProposal = async ( - proposalMessage: ValidProposalMessageData, - sciCatAccessToken: string -) => { - const url = `${sciCatBaseUrl}/Proposals`; - const createProposalDto = getCreateProposalDto(proposalMessage); - - logger.logInfo('POST', { url }); - logger.logInfo('Proposal data', { proposalData: createProposalDto }); - - // RabbitMQ message only provides shortCodes (instrument names). - // To persist proposals with proper references, we resolve those shortCodes to - // actual Instrument IDs from SciCat and store the instrumentIds in the record. - createProposalDto.instrumentIds = await getInstrumentIds( - proposalMessage.instruments - ); - - const createProposalResponse = await request(url, { - method: 'POST', - body: JSON.stringify(createProposalDto), - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${sciCatAccessToken}`, - }, - }); - - logger.logInfo('createProposalResponse', { createProposalResponse }); - - logger.logInfo('Proposal was created in scicat', { - proposalId: createProposalDto.proposalId, - }); -}; - -const updateProposal = async ( - proposalMessage: ValidProposalMessageData, - sciCatAccessToken: string -) => { - const url = `${sciCatBaseUrl}/Proposals/${proposalMessage.shortCode}`; - const updateProposalDto = getUpdateProposalDto(proposalMessage); - - // RabbitMQ message only provides shortCodes (instrument names). - // To persist proposals with proper references, we resolve those shortCodes to - // actual Instrument IDs from SciCat and store the instrumentIds in the record. - updateProposalDto.instrumentIds = await getInstrumentIds( - proposalMessage.instruments - ); - const updateProposalResponse = await request(url, { - method: 'PATCH', - body: JSON.stringify(updateProposalDto), - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${sciCatAccessToken}`, - }, - }); - - logger.logInfo('Patch', { url }); - logger.logInfo('Proposal data', { proposalData: updateProposalDto }); - logger.logInfo('updateProposalResponse', { updateProposalResponse }); - - logger.logInfo('Proposal was updated in scicat', { - proposalId: proposalMessage.shortCode, - }); -}; +import { + fetchUoExperiment, + fetchUoProposal, +} from '../../../../../services/userOfficeApi/uoApi'; +import { scicatApi } from '../utils/scicatApi'; -const checkProposalExists = async ( - proposalId: string, - sciCatAccessToken: string +export const upsertProposalInScicat = async ( + proposalMessage: ProposalMessageData ) => { - const url = `${sciCatBaseUrl}/Proposals/${proposalId}`; - const response = await request(url, { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${sciCatAccessToken}`, - }, - }).catch((error) => { - try { - const parsedError = JSON.parse(error.message); - if (parsedError.statusCode === 404) { - return false; - } - } catch (reason) { - logger.logError('Error parsing error message', { - error, - reason, - }); - } - throw error; - }); + const proposal = await fetchUoProposal(proposalMessage.proposalPk); + const exists = await scicatApi.checkProposalExists(proposal.proposalId); - if (response) { - return true; + if (exists) { + logger.logInfo('Proposal already exists, updating...', { + proposalId: proposal.proposalId, + }); + await scicatApi.updateProposal(proposal); } else { - return false; - } -}; - -const getInstrumentIds = async (instruments: Instrument[]) => { - const sciCatAccessToken = await getSciCatAccessToken(); - const instrumentNames = instruments.map((inst) => inst.shortCode); - - const instrumentIds = []; - - for (const name of instrumentNames) { - const instrumentNameLowerCase = name.toLowerCase(); - - const filterString = JSON.stringify({ - where: { name: { ilike: instrumentNameLowerCase } }, + logger.logInfo('Proposal does not exist yet, creating...', { + proposalId: proposal.proposalId, }); - - const url = `${sciCatBaseUrl}/Instruments?filter=${encodeURIComponent(filterString)}`; - - try { - const res = await request(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${sciCatAccessToken}`, - }, - }); - - instrumentIds.push(res[0].pid); - } catch (error) { - logger.logError(`Error fetching instrument ID from scicat for ${name}`, { - error, - }); - } + await scicatApi.createProposal(proposal); } - - return instrumentIds; }; -const upsertProposalInScicat = async ( - proposalMessage: ValidProposalMessageData +export const upsertExperimentInScicat = async ( + experimentMessage: ExperimentMessageData ) => { - const sciCatAccessToken = await getSciCatAccessToken(); - - const proposalExists = await checkProposalExists( - proposalMessage.shortCode, - sciCatAccessToken - ); + const experiment = await fetchUoExperiment(experimentMessage.experimentPk); + const exists = await scicatApi.checkProposalExists(experiment.experimentId); - if (proposalExists) { - logger.logInfo('Proposal already exists, updating...', { - proposalId: proposalMessage.shortCode, + if (exists) { + logger.logInfo('Experiment already exists, updating...', { + proposalId: experiment.experimentId, }); - - updateProposal(proposalMessage, sciCatAccessToken); + await scicatApi.updateExperiment(experiment); } else { - logger.logInfo('Proposal does not exist yet, creating...', { - proposalId: proposalMessage.shortCode, + logger.logInfo('Experiment does not exist yet, creating...', { + proposalId: experiment.experimentId, }); - - createProposal(proposalMessage, sciCatAccessToken); + await scicatApi.createExperiment(experiment); } -}; -export { upsertProposalInScicat }; + await upsertSamplesInScicat(experiment); +}; diff --git a/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertSampleInScicat.ts b/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertSampleInScicat.ts new file mode 100644 index 00000000..fbb2642b --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/consumerCallbacks/upsertSampleInScicat.ts @@ -0,0 +1,37 @@ +import { logger } from '@user-office-software/duo-logger'; + +import { UOExperimentDto } from '../../../../../services/userOfficeApi/type/uoExperiment.type'; +import { + getCreateScicatSampleDto, + getUpdateScicatSampleDto, +} from '../mappers/uoToScicatExperiment.mapper'; +import { scicatApi } from '../utils/scicatApi'; + +export const upsertSamplesInScicat = async (experiment: UOExperimentDto) => { + const samples = experiment.experimentSafety?.samples ?? []; + + for (const sample of samples) { + const sampleLookup = `${experiment.experimentId}-${sample.sampleId}`; + const existingSample = await scicatApi.findSampleByLookup(sampleLookup); + + if (existingSample) { + const existingHash = + existingSample.sampleCharacteristics?.['sample_hash']?.value; + const dto = getUpdateScicatSampleDto(sample, experiment); + const newHash = dto.sampleCharacteristics?.['sample_hash']?.value; + + if (existingHash === newHash) { + continue; + } + + logger.logInfo('Sample changed, updating...', { + sampleId: existingSample.sampleId, + }); + await scicatApi.updateSample(existingSample.sampleId!, dto); + } else { + logger.logInfo('Sample does not exist yet, creating...', {}); + const dto = getCreateScicatSampleDto(sample, experiment); + await scicatApi.createSample(dto); + } + } +}; diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ChatroomCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ChatroomCreationQueueConsumer.ts index cc431a52..efde0b0b 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ChatroomCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ChatroomCreationQueueConsumer.ts @@ -2,7 +2,7 @@ import { ConsumerCallback } from '@user-office-software/duo-message-broker'; import { Event } from '../../../../../models/Event'; import { QueueConsumer } from '../../../QueueConsumer'; -import { hasTriggeringStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringProposalStatus } from '../../../utils/hasTriggeringStatus'; import { hasTriggeringType } from '../../../utils/hasTriggeringType'; import { validateProposalMessage } from '../../../utils/validateProposalMessage'; import { createChatroom } from '../consumerCallbacks/createChatroom'; @@ -30,7 +30,7 @@ export class ChatroomCreationQueueConsumer extends QueueConsumer { return; } - const hasStatus = hasTriggeringStatus(message, triggeringStatuses); + const hasStatus = hasTriggeringProposalStatus(message, triggeringStatuses); if (!hasStatus) { return; diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts new file mode 100644 index 00000000..ecda5324 --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts @@ -0,0 +1,47 @@ +import { ConsumerCallback } from '@user-office-software/duo-message-broker'; + +import { Event } from '../../../../../models/Event'; +import { QueueConsumer } from '../../../QueueConsumer'; +import { hasTriggringExperimentStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringType } from '../../../utils/hasTriggeringType'; +import { validateExperimentMessage } from '../../../utils/validateExperimentMessage'; +import { upsertExperimentInScicat } from '../consumerCallbacks/upsertProposalInScicat'; + +const EXPERIMENT_EVENT_TYPES = [ + Event.EXPERIMENT_CREATED, + Event.EXPERIMENT_UPDATED, +]; + +const experimentTriggeringStatuses = + process.env.SCICAT_EXPERIMENT_TRIGGERING_STATUSES?.split(', '); + +export class ExperimentCreationQueueConsumer extends QueueConsumer { + getQueueName(): string { + return process.env.EXPERIMENT_CREATION_QUEUE_NAME as string; + } + + getExchangeName(): string { + return process.env.USER_OFFICE_CORE_EXCHANGE_NAME as string; + } + + onMessage: ConsumerCallback = async (type, message) => { + const hasExperimentType = hasTriggeringType(type, EXPERIMENT_EVENT_TYPES); + + if (!hasExperimentType) { + return; + } + + const hasExperimentStatus = hasTriggringExperimentStatus( + message, + experimentTriggeringStatuses + ); + + if (!hasExperimentStatus) { + return; + } + + const experimentMessage = validateExperimentMessage(message); + + upsertExperimentInScicat(experimentMessage); + }; +} diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.spec.ts b/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.spec.ts index 059016a4..d339ca9f 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.spec.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.spec.ts @@ -9,13 +9,13 @@ jest.mock('../../../QueueConsumer', () => ({ import { MessageBroker } from '@user-office-software/duo-message-broker'; import { FolderCreationQueueConsumer } from './FolderCreationQueueConsumer'; -import { hasTriggeringStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringProposalStatus } from '../../../utils/hasTriggeringStatus'; import { hasTriggeringType } from '../../../utils/hasTriggeringType'; describe('FolderCreationQueueConsumer', () => { it('should not throw an error when message does not have the correct type and status', async () => { (hasTriggeringType as jest.Mock).mockReturnValueOnce(false); - (hasTriggeringStatus as jest.Mock).mockReturnValueOnce(false); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(false); const consumer = new FolderCreationQueueConsumer({} as MessageBroker); @@ -28,7 +28,7 @@ describe('FolderCreationQueueConsumer', () => { it('should not throw an error when message does have the incorrect type and correct status', async () => { (hasTriggeringType as jest.Mock).mockReturnValueOnce(false); - (hasTriggeringStatus as jest.Mock).mockReturnValueOnce(true); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(true); const consumer = new FolderCreationQueueConsumer({} as MessageBroker); @@ -41,7 +41,7 @@ describe('FolderCreationQueueConsumer', () => { it('should not throw an error when message does have the correct type and incorrect status', async () => { (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); - (hasTriggeringStatus as jest.Mock).mockReturnValueOnce(false); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(false); const consumer = new FolderCreationQueueConsumer({} as MessageBroker); @@ -53,7 +53,7 @@ describe('FolderCreationQueueConsumer', () => { }); it('should throw error when invalid message does have the correct type or status', async () => { - (hasTriggeringStatus as jest.Mock).mockReturnValueOnce(true); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(true); (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); const consumer = new FolderCreationQueueConsumer({} as MessageBroker); diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.ts index fad6dc2e..ce2fca8d 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer.ts @@ -2,7 +2,7 @@ import { ConsumerCallback } from '@user-office-software/duo-message-broker'; import { Event } from '../../../../../models/Event'; import { QueueConsumer } from '../../../QueueConsumer'; -import { hasTriggeringStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringProposalStatus } from '../../../utils/hasTriggeringStatus'; import { hasTriggeringType } from '../../../utils/hasTriggeringType'; import { validateProposalMessage } from '../../../utils/validateProposalMessage'; import { proposalFoldersCreation } from '../consumerCallbacks/proposalFoldersCreation'; @@ -28,7 +28,7 @@ export class FolderCreationQueueConsumer extends QueueConsumer { return; } - const hasStatus = hasTriggeringStatus(message, triggeringStatuses); + const hasStatus = hasTriggeringProposalStatus(message, triggeringStatuses); if (!hasStatus) { return; diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts index e6f790c2..0a700cb9 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts @@ -2,17 +2,17 @@ import { ConsumerCallback } from '@user-office-software/duo-message-broker'; import { Event } from '../../../../../models/Event'; import { QueueConsumer } from '../../../QueueConsumer'; -import { hasTriggeringStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringProposalStatus } from '../../../utils/hasTriggeringStatus'; import { hasTriggeringType } from '../../../utils/hasTriggeringType'; import { validateProposalMessage } from '../../../utils/validateProposalMessage'; import { upsertProposalInScicat } from '../consumerCallbacks/upsertProposalInScicat'; -const EVENT_TYPES = [ +const PROPOSAL_EVENT_TYPES = [ Event.PROPOSAL_STATUS_ACTION_EXECUTED, Event.PROPOSAL_UPDATED, ]; -const triggeringStatuses = +const proposalTriggeringStatuses = process.env.SCICAT_PROPOSAL_TRIGGERING_STATUSES?.split(', '); export class ProposalCreationQueueConsumer extends QueueConsumer { @@ -25,20 +25,22 @@ export class ProposalCreationQueueConsumer extends QueueConsumer { } onMessage: ConsumerCallback = async (type, message) => { - const hasType = hasTriggeringType(type, EVENT_TYPES); + const hasProposalType = hasTriggeringType(type, PROPOSAL_EVENT_TYPES); - if (!hasType) { + if (!hasProposalType) { return; } - const hasStatus = hasTriggeringStatus(message, triggeringStatuses); + const hasProposalStatus = hasTriggeringProposalStatus( + message, + proposalTriggeringStatuses + ); - if (!hasStatus) { + if (!hasProposalStatus) { return; } const proposalMessage = validateProposalMessage(message); - upsertProposalInScicat(proposalMessage); }; } diff --git a/src/queue/consumers/scicat/scicatProposal/dto.ts b/src/queue/consumers/scicat/scicatProposal/dto.ts index 8aa79b07..c882d922 100644 --- a/src/queue/consumers/scicat/scicatProposal/dto.ts +++ b/src/queue/consumers/scicat/scicatProposal/dto.ts @@ -1,40 +1,3 @@ -export type CreateProposalDto = { - ownerGroup: string; - accessGroups: string[]; - proposalId: string; - pi_email: string; - pi_firstname: string; - pi_lastname: string; - email: string; - firstname: string; - lastname: string; - title: string; - abstract: string; - startTime?: Date; - endTime?: Date; - instrumentIds: string[]; - MeasurementPeriodList: any[]; - metadata?: Record; -}; - -export type UpdateProposalDto = { - ownerGroup?: string; - accessGroups?: string[]; - pi_email?: string; - pi_firstname?: string; - pi_lastname?: string; - email: string; - firstname?: string; - lastname?: string; - title: string; - abstract?: string; - startTime?: Date; - endTime?: Date; - instrumentIds: string[]; - MeasurementPeriodList?: any[]; - metadata?: Record; -}; - export interface Institution { id: number; name: string; diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap b/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap new file mode 100644 index 00000000..cbe13f31 --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap @@ -0,0 +1,151 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`getCreateScicatExperimentDto includes visitor entries when registrations are present 1`] = ` +{ + "MeasurementPeriodList": [], + "abstract": "Experiment 158548-3 +Test Abstract", + "accessGroups": [ + "158548-3", + ], + "email": "john.doe@example.com", + "endTime": 2026-10-03T07:00:00.000Z, + "firstname": "John", + "instrumentIds": [ + "scicat-inst-1", + ], + "lastname": "Doe", + "metadata": { + "instrument_name": { + "human_name": "Instrument Name", + "value": "YMIR", + }, + "number_of_visitors": { + "human_name": "Number of Visitors", + "value": 1, + }, + "status_experiment": { + "human_name": "UOS Experiment Status", + "value": "ACTIVE", + }, + "status_proposal": { + "human_name": "UOS Proposal Status", + "value": "ALLOCATED", + }, + "visitor_1_email": { + "human_name": "Visitor 1 Email", + "value": "test@example.com", + }, + "visitor_1_firstname": { + "human_name": "Visitor 1 First Name", + "value": "testFirst", + }, + "visitor_1_lastname": { + "human_name": "Visitor 1 Last Name", + "value": "testLast", + }, + "visitor_1_orcid": { + "human_name": "Visitor 1 ORCID", + "value": "testOidcSub", + }, + }, + "ownerGroup": "testuser", + "parentProposalId": "158548", + "pi_email": "john.doe@example.com", + "pi_firstname": "John", + "pi_lastname": "Doe", + "proposalId": "158548-3", + "startTime": 2026-10-02T07:00:00.000Z, + "title": "Test Proposal - 158548-3", + "type": "Experiment", +} +`; + +exports[`getCreateScicatExperimentDto maps experiment to create DTO correctly 1`] = ` +{ + "MeasurementPeriodList": [], + "abstract": "Experiment 158548-3 +Test Abstract", + "accessGroups": [ + "158548-3", + ], + "email": "john.doe@example.com", + "endTime": 2026-10-03T07:00:00.000Z, + "firstname": "John", + "instrumentIds": [ + "scicat-inst-1", + ], + "lastname": "Doe", + "metadata": { + "instrument_name": { + "human_name": "Instrument Name", + "value": "YMIR", + }, + "number_of_visitors": { + "human_name": "Number of Visitors", + "value": 0, + }, + "status_experiment": { + "human_name": "UOS Experiment Status", + "value": "ACTIVE", + }, + "status_proposal": { + "human_name": "UOS Proposal Status", + "value": "ALLOCATED", + }, + }, + "ownerGroup": "testuser", + "parentProposalId": "158548", + "pi_email": "john.doe@example.com", + "pi_firstname": "John", + "pi_lastname": "Doe", + "proposalId": "158548-3", + "startTime": 2026-10-02T07:00:00.000Z, + "title": "Test Proposal - 158548-3", + "type": "Experiment", +} +`; + +exports[`getUpdateScicatExperimentDto maps experiment to update DTO correctly 1`] = ` +{ + "MeasurementPeriodList": [], + "abstract": "Experiment 158548-3 +Test Abstract", + "accessGroups": [ + "158548-3", + ], + "email": "john.doe@example.com", + "endTime": 2026-10-03T07:00:00.000Z, + "firstname": "John", + "instrumentIds": [ + "scicat-inst-1", + ], + "lastname": "Doe", + "metadata": { + "instrument_name": { + "human_name": "Instrument Name", + "value": "YMIR", + }, + "number_of_visitors": { + "human_name": "Number of Visitors", + "value": 0, + }, + "status_experiment": { + "human_name": "UOS Experiment Status", + "value": "ACTIVE", + }, + "status_proposal": { + "human_name": "UOS Proposal Status", + "value": "ALLOCATED", + }, + }, + "ownerGroup": "testuser", + "parentProposalId": "158548", + "pi_email": "john.doe@example.com", + "pi_firstname": "John", + "pi_lastname": "Doe", + "startTime": 2026-10-02T07:00:00.000Z, + "title": "Test Proposal - 158548-3", + "type": "Experiment", +} +`; diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatProposal.mapper.spec.ts.snap b/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatProposal.mapper.spec.ts.snap new file mode 100644 index 00000000..dce6907e --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatProposal.mapper.spec.ts.snap @@ -0,0 +1,287 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`getCreateScicatProposalDto includes co-PI, DAU and instrument metadata when present 1`] = ` +{ + "MeasurementPeriodList": [], + "abstract": "Test Abstract", + "accessGroups": [], + "email": "john.doe@example.com", + "endTime": 2025-12-31T00:00:00.000Z, + "firstname": "John", + "instrumentIds": [ + "scicat-inst-1", + ], + "lastname": "Doe", + "metadata": { + "call_id": { + "human_name": "Call Id", + "value": 1, + }, + "call_name": { + "human_name": "Call", + "value": "CALL-2025", + }, + "co_i_1_affiliation": { + "human_name": "CoI 1 Affiliation", + "value": "ESS", + }, + "co_i_1_email": { + "human_name": "CoI 1 Email", + "value": "jane@example.com", + }, + "co_i_1_firstname": { + "human_name": "CoI 1 First Name", + "value": "Jane", + }, + "co_i_1_lastname": { + "human_name": "CoI 1 Last Name", + "value": "Smith", + }, + "co_i_1_orcid": { + "human_name": "CoI 1 ORCID", + "value": "0000-0002-3456-7890", + }, + "dau_1_email": { + "human_name": "Data Access User 1 Email", + "value": "bob@example.com", + }, + "dau_1_firstname": { + "human_name": "Data Access User 1 First Name", + "value": "Bob", + }, + "dau_1_lastname": { + "human_name": "Data Access User 1 Last Name", + "value": "Jones", + }, + "dau_1_orcid": { + "human_name": "Data Access User 1 ORCID", + "value": "0000-0003-4567-8901", + }, + "dau_2_email": { + "human_name": "Data Access User 2 Email", + "value": "alice@example.com", + }, + "dau_2_firstname": { + "human_name": "Data Access User 2 First Name", + "value": "Alice", + }, + "dau_2_lastname": { + "human_name": "Data Access User 2 Last Name", + "value": "Johnson", + }, + "dau_2_orcid": { + "human_name": "Data Access User 2 ORCID", + "value": "0000-0004-5678-9012", + }, + "end_call": { + "human_name": "Call End Date", + "value": "2025-12-31T00:00:00.000Z", + }, + "instrument_1_contact_firstname": { + "human_name": "Instrument 1 Contact First Name", + "value": "Fredrik", + }, + "instrument_1_contact_lastname": { + "human_name": "Instrument 1 Contact Last Name", + "value": "Bolmsten", + }, + "instrument_1_id": { + "human_name": "Instrument 1 Id", + "value": 1, + }, + "instrument_1_name": { + "human_name": "Instrument 1 Name", + "value": "YMIR", + }, + "number_of_co_is": { + "human_name": "Number of CoIs", + "value": 1, + }, + "number_of_dau": { + "human_name": "Number of Data Access Users", + "value": 2, + }, + "number_of_instruments": { + "human_name": "Number of Instruments", + "value": 1, + }, + "pi_email": { + "human_name": "PI Email", + "value": "john.doe@example.com", + }, + "pi_firstname": { + "human_name": "PI First Name", + "value": "John", + }, + "pi_lastname": { + "human_name": "PI Last Name", + "value": "Doe", + }, + "pi_orcid": { + "human_name": "PI ORCID", + "value": "0000-0001-2345-6789", + }, + "start_call": { + "human_name": "Call Start Date", + "value": "2025-01-01T00:00:00.000Z", + }, + "status": { + "human_name": "UOS Proposal Status", + "value": "ALLOCATED", + }, + }, + "ownerGroup": "158548", + "pi_email": "john.doe@example.com", + "pi_firstname": "John", + "pi_lastname": "Doe", + "proposalId": "158548", + "startTime": 2025-01-01T00:00:00.000Z, + "title": "Test Proposal", + "type": "Proposal", +} +`; + +exports[`getCreateScicatProposalDto maps proposal to create DTO correctly 1`] = ` +{ + "MeasurementPeriodList": [], + "abstract": "Test Abstract", + "accessGroups": [], + "email": "john.doe@example.com", + "endTime": 2025-12-31T00:00:00.000Z, + "firstname": "John", + "instrumentIds": [ + "scicat-inst-1", + ], + "lastname": "Doe", + "metadata": { + "call_id": { + "human_name": "Call Id", + "value": 1, + }, + "call_name": { + "human_name": "Call", + "value": "CALL-2025", + }, + "end_call": { + "human_name": "Call End Date", + "value": "2025-12-31T00:00:00.000Z", + }, + "number_of_co_is": { + "human_name": "Number of CoIs", + "value": 0, + }, + "number_of_dau": { + "human_name": "Number of Data Access Users", + "value": 0, + }, + "number_of_instruments": { + "human_name": "Number of Instruments", + "value": 0, + }, + "pi_email": { + "human_name": "PI Email", + "value": "john.doe@example.com", + }, + "pi_firstname": { + "human_name": "PI First Name", + "value": "John", + }, + "pi_lastname": { + "human_name": "PI Last Name", + "value": "Doe", + }, + "pi_orcid": { + "human_name": "PI ORCID", + "value": "0000-0001-2345-6789", + }, + "start_call": { + "human_name": "Call Start Date", + "value": "2025-01-01T00:00:00.000Z", + }, + "status": { + "human_name": "UOS Proposal Status", + "value": "ALLOCATED", + }, + }, + "ownerGroup": "158548", + "pi_email": "john.doe@example.com", + "pi_firstname": "John", + "pi_lastname": "Doe", + "proposalId": "158548", + "startTime": 2025-01-01T00:00:00.000Z, + "title": "Test Proposal", + "type": "Proposal", +} +`; + +exports[`getUpdateScicatProposalDto maps proposal to update DTO correctly 1`] = ` +{ + "MeasurementPeriodList": [], + "abstract": "Test Abstract", + "accessGroups": [], + "email": "john.doe@example.com", + "endTime": 2025-12-31T00:00:00.000Z, + "firstname": "John", + "instrumentIds": [ + "scicat-inst-1", + ], + "lastname": "Doe", + "metadata": { + "call_id": { + "human_name": "Call Id", + "value": 1, + }, + "call_name": { + "human_name": "Call", + "value": "CALL-2025", + }, + "end_call": { + "human_name": "Call End Date", + "value": "2025-12-31T00:00:00.000Z", + }, + "number_of_co_is": { + "human_name": "Number of CoIs", + "value": 0, + }, + "number_of_dau": { + "human_name": "Number of Data Access Users", + "value": 0, + }, + "number_of_instruments": { + "human_name": "Number of Instruments", + "value": 0, + }, + "pi_email": { + "human_name": "PI Email", + "value": "john.doe@example.com", + }, + "pi_firstname": { + "human_name": "PI First Name", + "value": "John", + }, + "pi_lastname": { + "human_name": "PI Last Name", + "value": "Doe", + }, + "pi_orcid": { + "human_name": "PI ORCID", + "value": "0000-0001-2345-6789", + }, + "start_call": { + "human_name": "Call Start Date", + "value": "2025-01-01T00:00:00.000Z", + }, + "status": { + "human_name": "UOS Proposal Status", + "value": "ALLOCATED", + }, + }, + "ownerGroup": "158548", + "pi_email": "john.doe@example.com", + "pi_firstname": "John", + "pi_lastname": "Doe", + "startTime": 2025-01-01T00:00:00.000Z, + "title": "Test Proposal", + "type": "Proposal", +} +`; diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts new file mode 100644 index 00000000..f50ed7fe --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts @@ -0,0 +1,112 @@ +jest.mock('../utils/scicatApi', () => ({ + scicatApi: { + serviceUsername: 'testuser', + }, +})); + +import { + getCreateScicatExperimentDto, + getUpdateScicatExperimentDto, +} from './uoToScicatExperiment.mapper'; +import { UOExperimentDto } from '../../../../../services/userOfficeApi/type/uoExperiment.type'; + +const createBaseUoExperiment = ( + overrides: Partial = {} +): UOExperimentDto => ({ + experimentId: '158548-3', + startsAt: '2026-10-02T07:00:00.000Z', + endsAt: '2026-10-03T07:00:00.000Z', + status: 'ACTIVE', + instrument: { + id: 1, + name: 'YMIR', + shortCode: 'ymir', + }, + proposal: { + proposalId: '158548', + title: 'Test Proposal', + abstract: 'Test Abstract', + status: { id: 1, shortCode: 'ALLOCATED', name: 'ALLOCATED' }, + proposer: { + id: 1, + firstname: 'John', + lastname: 'Doe', + email: 'john.doe@example.com', + oidcSub: '0000-0001-2345-6789', + institution: 'ESS', + }, + }, + visit: null, + ...overrides, +}); + +const instrumentIds = ['scicat-inst-1']; + +describe('getCreateScicatExperimentDto', () => { + it('maps experiment to create DTO correctly', () => { + const dto = getCreateScicatExperimentDto( + createBaseUoExperiment(), + instrumentIds + ); + + expect(dto).toMatchSnapshot(); + }); + + it('includes visitor entries when registrations are present', () => { + const dto = getCreateScicatExperimentDto( + createBaseUoExperiment({ + visit: { + registrations: [ + { + status: 'DRAFTED', + user: { + id: 7, + firstname: 'testFirst', + lastname: 'testLast', + email: 'test@example.com', + oidcSub: 'testOidcSub', + institution: 'ESS', + }, + }, + ], + }, + }), + instrumentIds + ); + + expect(dto).toMatchSnapshot(); + }); + + it('skips visitor entries when user is null', () => { + const dto = getCreateScicatExperimentDto( + createBaseUoExperiment({ + visit: { + registrations: [{ status: 'DRAFTED', user: null }], + }, + }), + instrumentIds + ); + + expect(dto.metadata?.['visitor_1_firstname']).toBeUndefined(); + }); +}); + +describe('getUpdateScicatExperimentDto', () => { + it('maps experiment to update DTO correctly', () => { + const dto = getUpdateScicatExperimentDto( + createBaseUoExperiment(), + instrumentIds + ); + + expect(dto).toMatchSnapshot(); + }); + + it('should not include proposalId', () => { + const dto = getUpdateScicatExperimentDto( + createBaseUoExperiment(), + instrumentIds + ); + + expect((dto as any).proposalId).toBeUndefined(); + }); +}); diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts new file mode 100644 index 00000000..6eb955db --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts @@ -0,0 +1,216 @@ +import { createHash } from 'crypto'; + +import { + UOExperimentDto, + UOExperimentSafetySample, +} from '../../../../../services/userOfficeApi/type/uoExperiment.type'; +import { + CreateScicatProposalDto, + CreateScicatSampleDto, + MdEntry, + MdEntryValue, + UpdateScicatProposalDto, + UpdateScicatSampleDto, +} from '../type/scicatProposal.type'; +import { metadataEntry } from '../utils/common'; +import { scicatApi } from '../utils/scicatApi'; + +// ────────────────────────────────────────────────────────────────────────────── +// ── Experiment ──────────────────────────────────────────────────────────────── +// ────────────────────────────────────────────────────────────────────────────── +const buildMetadata = (experiment: UOExperimentDto): MdEntry => { + const { proposal, instrument, visit } = experiment; + const registrations = visit?.registrations ?? []; + + const rows: [string, MdEntryValue][] = [ + metadataEntry( + 'status_proposal', + 'UOS Proposal Status', + proposal.status.name + ), + metadataEntry( + 'status_experiment', + 'UOS Experiment Status', + experiment.status + ), + metadataEntry('instrument_name', 'Instrument Name', instrument.name), + metadataEntry( + 'number_of_visitors', + 'Number of Visitors', + registrations.length + ), + ]; + + registrations.forEach((registration, index) => { + if (!registration.user) return; + const i = index + 1; + rows.push( + metadataEntry( + `visitor_${i}_firstname`, + `Visitor ${i} First Name`, + registration.user.firstname + ), + metadataEntry( + `visitor_${i}_lastname`, + `Visitor ${i} Last Name`, + registration.user.lastname + ), + metadataEntry( + `visitor_${i}_email`, + `Visitor ${i} Email`, + registration.user.email + ), + metadataEntry( + `visitor_${i}_orcid`, + `Visitor ${i} ORCID`, + registration.user.oidcSub + ) + ); + }); + + return Object.fromEntries(rows); +}; + +export const getCreateScicatExperimentDto = ( + experiment: UOExperimentDto, + instrumentIds: string[] +): CreateScicatProposalDto => { + const { proposal, experimentId } = experiment; + const { proposer } = proposal; + + return { + type: 'Experiment', + proposalId: experimentId, + parentProposalId: proposal.proposalId, + title: `${proposal.title} - ${experimentId}`, + abstract: `Experiment ${experimentId}\n${proposal.abstract}`, + firstname: proposer.firstname, + lastname: proposer.lastname, + email: proposer.email, + pi_firstname: proposer.firstname, + pi_lastname: proposer.lastname, + pi_email: proposer.email, + instrumentIds, + ownerGroup: scicatApi.serviceUsername || '', + accessGroups: [experimentId], + startTime: new Date(experiment.startsAt), + endTime: new Date(experiment.endsAt), + MeasurementPeriodList: [], + metadata: buildMetadata(experiment), + }; +}; + +export const getUpdateScicatExperimentDto = ( + experiment: UOExperimentDto, + instrumentIds: string[] +): UpdateScicatProposalDto => { + const { proposal, experimentId } = experiment; + const { proposer } = proposal; + + return { + type: 'Experiment', + parentProposalId: proposal.proposalId, + title: `${proposal.title} - ${experimentId}`, + abstract: `Experiment ${experimentId}\n${proposal.abstract}`, + firstname: proposer.firstname, + lastname: proposer.lastname, + email: proposer.email, + pi_firstname: proposer.firstname, + pi_lastname: proposer.lastname, + pi_email: proposer.email, + instrumentIds, + ownerGroup: scicatApi.serviceUsername, + accessGroups: [experimentId], + startTime: new Date(experiment.startsAt), + endTime: new Date(experiment.endsAt), + MeasurementPeriodList: [], + metadata: buildMetadata(experiment), + }; +}; + +// ────────────────────────────────────────────────────────────────────────────── +// ── Sample ──────────────────────────────────────────────────────────────────── +// ────────────────────────────────────────────────────────────────────────────── + +const buildSampleHash = (dto: CreateScicatSampleDto): string => { + const hashableData = { + accessGroups: dto.accessGroups, + sampleName: dto.sampleName, + isPublished: dto.isPublished, + ownerGroup: dto.ownerGroup, + proposalId: dto.proposalId, + sampleCharacteristics: dto.sampleCharacteristics, + }; + + return createHash('md5').update(JSON.stringify(hashableData)).digest('hex'); +}; + +const buildSampleCharacteristics = ( + sample: UOExperimentSafetySample, + experiment: UOExperimentDto +): Record => { + const fields = sample.questionary.steps.flatMap((step) => step.fields); + const sampleLookup = `${experiment.experimentId}-${sample.sampleId}`; + + const rows: [string, MdEntryValue][] = [ + metadataEntry('uos_sample_id', 'UOS Sample ID', sample.sampleId), + metadataEntry('uos_sample_lookup', 'UOS Sample Lookup', sampleLookup), + metadataEntry( + 'questionary_length', + 'Number of questions in Questionary', + fields.length + ), + ...fields.map((field) => + metadataEntry( + field.question.id, + field.question.question, + JSON.stringify(field.value) + ) + ), + ]; + + return Object.fromEntries(rows); +}; + +export const getCreateScicatSampleDto = ( + sample: UOExperimentSafetySample, + experiment: UOExperimentDto +): CreateScicatSampleDto => { + const sampleCharacteristics = buildSampleCharacteristics(sample, experiment); + const dto = { + ownerGroup: scicatApi.serviceUsername || '', + type: 'Sample Information', + accessGroups: [experiment.experimentId], + proposalId: experiment.experimentId, + sampleName: sample.sample.title, + isPublished: false, + sampleCharacteristics, + }; + dto.sampleCharacteristics['sample_hash'] = { + human_name: 'Sample Hash', + value: buildSampleHash(dto), + }; + + return dto; +}; + +export const getUpdateScicatSampleDto = ( + sample: UOExperimentSafetySample, + experiment: UOExperimentDto +): UpdateScicatSampleDto => { + const sampleCharacteristics = buildSampleCharacteristics(sample, experiment); + const dto = { + ownerGroup: scicatApi.serviceUsername || '', + accessGroups: [experiment.experimentId], + proposalId: experiment.experimentId, + sampleName: sample.sample.title, + isPublished: false, + sampleCharacteristics, + }; + dto.sampleCharacteristics['sample_hash'] = { + human_name: 'Sample Hash', + value: buildSampleHash(dto), + }; + + return dto; +}; diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts new file mode 100644 index 00000000..9800bba8 --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts @@ -0,0 +1,110 @@ +import { + getCreateScicatProposalDto, + getUpdateScicatProposalDto, +} from './uoToScicatProposal.mapper'; +import { UOProposalDto } from '../../../../../services/userOfficeApi/type/uoProposal.type'; + +const createBaseUoProposal = ( + overrides: Partial = {} +): UOProposalDto => ({ + proposalId: '158548', + title: 'Test Proposal', + abstract: 'Test Abstract', + status: { id: 1, shortCode: 'ALLOCATED', name: 'ALLOCATED' }, + proposer: { + id: 1, + firstname: 'John', + lastname: 'Doe', + email: 'john.doe@example.com', + oidcSub: '0000-0001-2345-6789', + institution: 'ESS', + }, + users: [], + dataAccessUsers: [], + instruments: [], + call: { + id: 1, + shortCode: 'CALL-2025', + isActive: true, + startCall: '2025-01-01T00:00:00.000Z', + endCall: '2025-12-31T00:00:00.000Z', + }, + ...overrides, +}); + +const instrumentIds = ['scicat-inst-1']; + +describe('getCreateScicatProposalDto', () => { + it('maps proposal to create DTO correctly', () => { + expect( + getCreateScicatProposalDto(createBaseUoProposal(), instrumentIds) + ).toMatchSnapshot(); + }); + + it('includes co-PI, DAU and instrument metadata when present', () => { + expect( + getCreateScicatProposalDto( + createBaseUoProposal({ + users: [ + { + id: 2, + firstname: 'Jane', + lastname: 'Smith', + email: 'jane@example.com', + oidcSub: '0000-0002-3456-7890', + institution: 'ESS', + }, + ], + dataAccessUsers: [ + { + id: 3, + firstname: 'Bob', + lastname: 'Jones', + email: 'bob@example.com', + oidcSub: '0000-0003-4567-8901', + institution: 'ESS', + }, + { + id: 4, + firstname: 'Alice', + lastname: 'Johnson', + email: 'alice@example.com', + oidcSub: '0000-0004-5678-9012', + institution: 'ESS', + }, + ], + instruments: [ + { + id: 1, + name: 'YMIR', + shortCode: 'ymir', + instrumentContact: { + id: 7, + firstname: 'Fredrik', + lastname: 'Bolmsten', + }, + }, + ], + }), + instrumentIds + ) + ).toMatchSnapshot(); + }); +}); + +describe('getUpdateScicatProposalDto', () => { + it('maps proposal to update DTO correctly', () => { + expect( + getUpdateScicatProposalDto(createBaseUoProposal(), instrumentIds) + ).toMatchSnapshot(); + }); + + it('should not include proposalId', () => { + const dto = getUpdateScicatProposalDto( + createBaseUoProposal(), + instrumentIds + ); + + expect((dto as any).proposalId).toBeUndefined(); + }); +}); diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts new file mode 100644 index 00000000..186d818f --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts @@ -0,0 +1,160 @@ +import { UOProposalDto } from '../../../../../services/userOfficeApi/type/uoProposal.type'; +import { + CreateScicatProposalDto, + MdEntry, + MdEntryValue, + UpdateScicatProposalDto, +} from '../type/scicatProposal.type'; +import { metadataEntry } from '../utils/common'; + +const buildMetadata = (proposal: UOProposalDto): MdEntry => { + const { + proposer, + users = [], + dataAccessUsers = [], + instruments = [], + call, + status, + } = proposal; + + const rows: [string, MdEntryValue][] = [ + metadataEntry('status', 'UOS Proposal Status', status.name), + metadataEntry('pi_firstname', 'PI First Name', proposer.firstname), + metadataEntry('pi_lastname', 'PI Last Name', proposer.lastname), + metadataEntry('pi_email', 'PI Email', proposer.email), + metadataEntry('pi_orcid', 'PI ORCID', proposer.oidcSub), + metadataEntry('number_of_co_is', 'Number of CoIs', users.length), + metadataEntry( + 'number_of_dau', + 'Number of Data Access Users', + dataAccessUsers.length + ), + metadataEntry('call_name', 'Call', call.shortCode), + metadataEntry('call_id', 'Call Id', call.id), + metadataEntry('start_call', 'Call Start Date', call.startCall), + metadataEntry('end_call', 'Call End Date', call.endCall), + metadataEntry( + 'number_of_instruments', + 'Number of Instruments', + instruments.length + ), + ]; + + // Co-PIs + users.forEach((user, index) => { + const i = index + 1; + rows.push( + metadataEntry( + `co_i_${i}_firstname`, + `CoI ${i} First Name`, + user.firstname + ), + metadataEntry(`co_i_${i}_lastname`, `CoI ${i} Last Name`, user.lastname), + metadataEntry(`co_i_${i}_email`, `CoI ${i} Email`, user.email), + metadataEntry(`co_i_${i}_orcid`, `CoI ${i} ORCID`, user.oidcSub), + metadataEntry( + `co_i_${i}_affiliation`, + `CoI ${i} Affiliation`, + user.institution + ) + ); + }); + + // Data Access Users + dataAccessUsers.forEach((dau, index) => { + const i = index + 1; + rows.push( + metadataEntry( + `dau_${i}_firstname`, + `Data Access User ${i} First Name`, + dau.firstname + ), + metadataEntry( + `dau_${i}_lastname`, + `Data Access User ${i} Last Name`, + dau.lastname + ), + metadataEntry(`dau_${i}_email`, `Data Access User ${i} Email`, dau.email), + metadataEntry( + `dau_${i}_orcid`, + `Data Access User ${i} ORCID`, + dau.oidcSub + ) + ); + }); + + // Instruments + instruments.forEach((inst, index) => { + const i = index + 1; + const ic = inst.instrumentContact; + rows.push( + metadataEntry(`instrument_${i}_name`, `Instrument ${i} Name`, inst.name), + metadataEntry(`instrument_${i}_id`, `Instrument ${i} Id`, inst.id), + metadataEntry( + `instrument_${i}_contact_firstname`, + `Instrument ${i} Contact First Name`, + ic?.firstname || null + ), + metadataEntry( + `instrument_${i}_contact_lastname`, + `Instrument ${i} Contact Last Name`, + ic?.lastname || null + ) + ); + }); + + return Object.fromEntries(rows); +}; + +export const getCreateScicatProposalDto = ( + proposal: UOProposalDto, + instrumentIds: string[] +): CreateScicatProposalDto => { + const { proposer } = proposal; + + return { + type: 'Proposal', + proposalId: proposal.proposalId, + title: proposal.title, + abstract: proposal.abstract, + firstname: proposer.firstname, + lastname: proposer.lastname, + email: proposer.email, + pi_firstname: proposer.firstname, + pi_lastname: proposer.lastname, + pi_email: proposer.email, + instrumentIds, + ownerGroup: proposal.proposalId, + accessGroups: [], + startTime: new Date(proposal.call.startCall), + endTime: new Date(proposal.call.endCall), + MeasurementPeriodList: [], + metadata: buildMetadata(proposal), + }; +}; + +export const getUpdateScicatProposalDto = ( + proposal: UOProposalDto, + instrumentIds: string[] +): UpdateScicatProposalDto => { + const { proposer } = proposal; + + return { + type: 'Proposal', + title: proposal.title, + abstract: proposal.abstract, + firstname: proposer.firstname, + lastname: proposer.lastname, + email: proposer.email, + pi_firstname: proposer.firstname, + pi_lastname: proposer.lastname, + pi_email: proposer.email, + instrumentIds, + ownerGroup: proposal.proposalId, + accessGroups: [], + startTime: new Date(proposal.call.startCall), + endTime: new Date(proposal.call.endCall), + MeasurementPeriodList: [], + metadata: buildMetadata(proposal), + }; +}; diff --git a/src/queue/consumers/scicat/scicatProposal/type/scicatProposal.type.ts b/src/queue/consumers/scicat/scicatProposal/type/scicatProposal.type.ts new file mode 100644 index 00000000..612e58ec --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/type/scicatProposal.type.ts @@ -0,0 +1,68 @@ +export interface MdEntryValue { + human_name?: string; + value: string | number | boolean | null | undefined; +} + +export interface MdEntry { + [key: string]: MdEntryValue; +} + +export type CreateScicatProposalDto = { + ownerGroup: string; + accessGroups: string[]; + proposalId: string; + parentProposalId?: string; + pi_email: string; + pi_firstname: string; + pi_lastname: string; + email: string; + type: 'Proposal' | 'Experiment'; + firstname: string; + lastname: string; + title: string; + abstract: string; + startTime?: Date; + endTime?: Date; + instrumentIds: string[]; + MeasurementPeriodList: any[]; + metadata?: Record; +}; + +export type UpdateScicatProposalDto = { + ownerGroup?: string; + accessGroups?: string[]; + parentProposalId?: string; + pi_email?: string; + pi_firstname?: string; + pi_lastname?: string; + email: string; + firstname?: string; + lastname?: string; + type: 'Proposal' | 'Experiment'; + title: string; + abstract?: string; + startTime?: Date; + endTime?: Date; + instrumentIds: string[]; + MeasurementPeriodList?: any[]; + metadata?: Record; +}; + +export type CreateScicatSampleDto = { + proposalId: string; + sampleName: string; + ownerGroup: string; + accessGroups?: string[]; + isPublished?: boolean; + sampleCharacteristics?: Record; +}; + +export type UpdateScicatSampleDto = { + sampleId?: string; + sampleName?: string; + proposalId?: string; + ownerGroup?: string; + accessGroups?: string[]; + isPublished?: boolean; + sampleCharacteristics?: Record; +}; diff --git a/src/queue/consumers/scicat/scicatProposal/utils/common.ts b/src/queue/consumers/scicat/scicatProposal/utils/common.ts new file mode 100644 index 00000000..89b755e6 --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/utils/common.ts @@ -0,0 +1,10 @@ +import { MdEntryValue } from '../type/scicatProposal.type'; + +export const metadataEntry = ( + key: string, + human_name: string, + value: string | number | boolean | null | undefined +): [string, MdEntryValue] => [ + key, + human_name ? { human_name, value } : { value }, +]; diff --git a/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts new file mode 100644 index 00000000..4f7edade --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts @@ -0,0 +1,25 @@ +describe('ScicatApi', () => { + it('should initialize with correct serviceUsername', () => { + process.env.SCICAT_BASE_URL = 'http://localhost:3000'; + process.env.SCICAT_JWT = + 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3R1c2VyIn0.signature'; + + jest.isolateModules(() => { + const { scicatApi } = require('./scicatApi'); + expect(scicatApi.serviceUsername).toBe('testuser'); + }); + + delete process.env.SCICAT_BASE_URL; + delete process.env.SCICAT_JWT; + }); + + it('should throw if SCICAT_JWT is not defined', () => { + process.env.SCICAT_BASE_URL = 'http://localhost:3000'; + + jest.isolateModules(() => { + expect(() => require('./scicatApi')).toThrow('SCICAT_JWT is not defined'); + }); + + delete process.env.SCICAT_BASE_URL; + }); +}); diff --git a/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts new file mode 100644 index 00000000..ec4e6a01 --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts @@ -0,0 +1,351 @@ +import { logger } from '@user-office-software/duo-logger'; + +import { InstrumentDto } from '../../../../../models/ProposalMessage'; +import { UOExperimentDto } from '../../../../../services/userOfficeApi/type/uoExperiment.type'; +import { + UOInstrument, + UOProposalDto, +} from '../../../../../services/userOfficeApi/type/uoProposal.type'; +import { + getCreateScicatExperimentDto, + getUpdateScicatExperimentDto, +} from '../mappers/uoToScicatExperiment.mapper'; +import { + getCreateScicatProposalDto, + getUpdateScicatProposalDto, +} from '../mappers/uoToScicatProposal.mapper'; +import { + CreateScicatProposalDto, + CreateScicatSampleDto, + UpdateScicatProposalDto, + UpdateScicatSampleDto, +} from '../type/scicatProposal.type'; + +class ScicatApi { + readonly baseUrl = process.env.SCICAT_BASE_URL; + readonly scicatToken = process.env.SCICAT_JWT; + readonly serviceUsername: string; + + constructor() { + if (!this.baseUrl) { + throw new Error('SCICAT_BASE_URL is not defined'); + } + + if (!this.scicatToken) { + throw new Error('SCICAT_JWT is not defined'); + } + + this.serviceUsername = this.getServiceUsername(this.scicatToken); + + logger.logInfo('ScicatApi initialized', { + baseUrl: this.baseUrl, + serviceUsername: this.serviceUsername, + }); + } + + private getServiceUsername(token: string): string { + try { + const payload = JSON.parse( + Buffer.from(token.split('.')[1], 'base64url').toString() + ); + if (!payload.username) { + throw new Error('Username not found in token payload'); + } + + return payload.username; + } catch { + throw new Error('Failed to decode JWT token'); + } + } + + async request( + url: string, + config: RequestInit + ): Promise { + const response = await fetch(url, config); + + const text = await response.text(); + + if (!response.ok) { + throw new Error(text || `HTTP error: ${response.status}`); + } + + if (!text) return undefined as TResponse; + + return JSON.parse(text) as TResponse; + } + + async getInstrumentIds( + instruments: UOInstrument | UOInstrument[] + ): Promise { + const sciCatAccessToken = this.scicatToken; + const instrumentArray = Array.isArray(instruments) + ? instruments + : [instruments]; + const instrumentNames = instrumentArray.map((inst) => inst.shortCode); + + const instrumentIds = []; + + for (const name of instrumentNames) { + const instrumentNameLowerCase = name.toLowerCase(); + + const filterString = JSON.stringify({ + where: { name: { ilike: instrumentNameLowerCase } }, + }); + + const url = `${this.baseUrl}/Instruments?filter=${encodeURIComponent(filterString)}`; + + try { + const res = await this.request(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + }); + if (res[0].pid) { + instrumentIds.push(res[0].pid); + } + } catch (error) { + logger.logError( + `Error fetching instrument ID from scicat for ${name}`, + { + error, + } + ); + } + } + + return instrumentIds; + } + + async checkProposalExists(proposalId: string): Promise { + const url = `${this.baseUrl}/Proposals/${proposalId}`; + const sciCatAccessToken = this.scicatToken; + const response = await this.request(url, { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + }).catch((error) => { + try { + const parsedError = JSON.parse(error.message); + if (parsedError.statusCode === 404) { + return false; + } + } catch (reason) { + logger.logError('Error parsing error message', { + error, + reason, + }); + } + throw error; + }); + + return Boolean(response); + } + + async findSampleByLookup( + sampleLookup: string + ): Promise { + const sciCatAccessToken = this.scicatToken; + const filter = JSON.stringify({ + where: { + 'sampleCharacteristics.uos_sample_lookup.value': sampleLookup, + }, + }); + + const url = `${this.baseUrl}/Samples/findOne?filter=${encodeURIComponent(filter)}`; + + const response = await this.request(url, { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + }).catch((error) => { + try { + const parsedError = JSON.parse(error.message); + if (parsedError.statusCode === 404) return null; + } catch (reason) { + logger.logError('Error parsing error message', { error, reason }); + } + throw error; + }); + + return response ?? null; + } + + async createProposal(UOProposal: UOProposalDto) { + const url = `${this.baseUrl}/Proposals`; + const sciCatAccessToken = this.scicatToken; + // RabbitMQ message only provides shortCodes (instrument names). + // To persist proposals with proper references, we resolve those shortCodes to + // actual Instrument IDs from SciCat and store the instrumentIds in the record. + const scicatInstrumentIds = await this.getInstrumentIds( + UOProposal.instruments + ); + const createProposalDto = getCreateScicatProposalDto( + UOProposal, + scicatInstrumentIds + ); + + const createProposalResponse = await this.request( + url, + { + method: 'POST', + body: JSON.stringify(createProposalDto), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + } + ); + + logger.logInfo('Proposal created in SciCat', { + url, + proposalId: createProposalDto.proposalId, + response: createProposalResponse, + }); + } + + async updateProposal(UOProposal: UOProposalDto) { + const url = `${this.baseUrl}/Proposals/${UOProposal.proposalId}`; + const sciCatAccessToken = this.scicatToken; + // RabbitMQ message only provides shortCodes (instrument names). + // To persist proposals with proper references, we resolve those shortCodes to + // actual Instrument IDs from SciCat and store the instrumentIds in the record. + const scicatInstrumentIds = await this.getInstrumentIds( + UOProposal.instruments + ); + const updateProposalDto = getUpdateScicatProposalDto( + UOProposal, + scicatInstrumentIds + ); + + const updateProposalResponse = await this.request( + url, + { + method: 'PATCH', + body: JSON.stringify(updateProposalDto), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + } + ); + + logger.logInfo('Proposal updated in SciCat', { + url, + proposalId: UOProposal.proposalId, + response: updateProposalResponse, + }); + } + + async createExperiment(UOExperiment: UOExperimentDto) { + const url = `${this.baseUrl}/Proposals`; + const sciCatAccessToken = this.scicatToken; + // RabbitMQ message only provides shortCodes (instrument names). + // To persist proposals with proper references, we resolve those shortCodes to + // actual Instrument IDs from SciCat and store the instrumentIds in the record. + const scicatInstrumentIds = await this.getInstrumentIds( + UOExperiment.instrument + ); + const createExperimentDto = getCreateScicatExperimentDto( + UOExperiment, + scicatInstrumentIds + ); + + const createExperimentResponse = + await this.request(url, { + method: 'POST', + body: JSON.stringify(createExperimentDto), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + }); + + // NOTE: UOExperiment.experimentId = proposalId in SciCat for experiments + logger.logInfo('Experiment created in SciCat', { + url, + proposalId: UOExperiment.experimentId, + response: createExperimentResponse, + }); + } + + async updateExperiment(UOExperiment: UOExperimentDto) { + const url = `${this.baseUrl}/Proposals/${UOExperiment.experimentId}`; + const sciCatAccessToken = this.scicatToken; + // RabbitMQ message only provides shortCodes (instrument names). + // To persist proposals with proper references, we resolve those shortCodes to + // actual Instrument IDs from SciCat and store the instrumentIds in the record. + const scicatInstrumentIds = await this.getInstrumentIds( + UOExperiment.instrument + ); + const updateExperimentDto = getUpdateScicatExperimentDto( + UOExperiment, + scicatInstrumentIds + ); + + const updateExperimentResponse = + await this.request(url, { + method: 'PATCH', + body: JSON.stringify(updateExperimentDto), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + }); + + // NOTE: UOExperiment.experimentId = proposalId in SciCat for experiments + logger.logInfo('Experiment updated in SciCat', { + url, + proposalId: UOExperiment.experimentId, + response: updateExperimentResponse, + }); + } + + async createSample(dto: CreateScicatSampleDto): Promise { + const sciCatAccessToken = this.scicatToken; + const url = `${this.baseUrl}/Samples`; + + const createSampleResponse = await this.request( + url, + { + method: 'POST', + body: JSON.stringify(dto), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + } + ); + + logger.logInfo('Sample created in SciCat', { + url, + response: createSampleResponse, + }); + } + + async updateSample( + sampleId: string, + dto: UpdateScicatSampleDto + ): Promise { + const sciCatAccessToken = this.scicatToken; + + const url = `${this.baseUrl}/Samples/${sampleId}`; + + await this.request(url, { + method: 'PATCH', + body: JSON.stringify(dto), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${sciCatAccessToken}`, + }, + }); + + logger.logInfo('Sample updated in SciCat', { sampleId }); + } +} + +export const scicatApi = new ScicatApi(); diff --git a/src/queue/consumers/utils/collectUsersFromProposalMessage.spec.ts b/src/queue/consumers/utils/collectUsersFromProposalMessage.spec.ts index 0de84c4d..0617eef4 100644 --- a/src/queue/consumers/utils/collectUsersFromProposalMessage.spec.ts +++ b/src/queue/consumers/utils/collectUsersFromProposalMessage.spec.ts @@ -21,6 +21,8 @@ describe('collectUsersFromProposalMessage', () => { callId: 2, submitted: true, members: [], + dataAccessUsers: [], + visitors: [], ...overrides, }); diff --git a/src/queue/consumers/utils/hasTriggeringStatus.ts b/src/queue/consumers/utils/hasTriggeringStatus.ts index 49c31de3..729c3147 100644 --- a/src/queue/consumers/utils/hasTriggeringStatus.ts +++ b/src/queue/consumers/utils/hasTriggeringStatus.ts @@ -1,4 +1,4 @@ -export const hasTriggeringStatus = ( +export const hasTriggeringProposalStatus = ( message: any, statuses: string[] | undefined ) => { @@ -13,3 +13,18 @@ export const hasTriggeringStatus = ( return true; }; + +export const hasTriggringExperimentStatus = ( + message: any, + statuses: string[] | undefined +) => { + if (!message.status || !statuses) { + return false; + } + + if (statuses.indexOf(message.status) === -1) { + return false; + } + + return true; +}; diff --git a/src/queue/consumers/utils/validateExperimentMessage.spec.ts b/src/queue/consumers/utils/validateExperimentMessage.spec.ts new file mode 100644 index 00000000..58918fa4 --- /dev/null +++ b/src/queue/consumers/utils/validateExperimentMessage.spec.ts @@ -0,0 +1,41 @@ +import { validateExperimentMessage } from './validateExperimentMessage'; + +describe('validateExperimentMessage', () => { + it('should throw error when message is not valid', () => { + expect(() => validateExperimentMessage({ message: 'message' })).toThrow(); + }); + + it('should throw when experimentId is missing', () => { + expect(() => + validateExperimentMessage({ + experimentPk: 1, + startsAt: new Date(), + endsAt: new Date(), + status: 'ALLOCATED', + }) + ).toThrow('Experiment ID is missing'); + }); + + it('should throw when experimentPk is missing', () => { + expect(() => + validateExperimentMessage({ + experimentId: 'exp-123', + startsAt: new Date(), + endsAt: new Date(), + status: 'ALLOCATED', + }) + ).toThrow('Experiment primary key is missing'); + }); + + it('should not throw when message is valid', () => { + expect(() => + validateExperimentMessage({ + experimentId: 'exp-123', + experimentPk: 1, + startsAt: new Date(), + endsAt: new Date(), + status: 'ALLOCATED', + }) + ).not.toThrow(); + }); +}); diff --git a/src/queue/consumers/utils/validateExperimentMessage.ts b/src/queue/consumers/utils/validateExperimentMessage.ts new file mode 100644 index 00000000..57caa005 --- /dev/null +++ b/src/queue/consumers/utils/validateExperimentMessage.ts @@ -0,0 +1,29 @@ +import { ExperimentMessageData } from '../../../models/ProposalMessage'; + +export type ValidExperimentMessageData = Required; + +export function validateExperimentMessage( + message: Record +): ValidExperimentMessageData { + if (!message.experimentId) { + throw new Error('Experiment ID is missing'); + } + + if (!message.experimentPk) { + throw new Error('Experiment primary key is missing'); + } + + if (!message.startsAt) { + throw new Error('Experiment start date is missing'); + } + + if (!message.endsAt) { + throw new Error('Experiment end date is missing'); + } + + if (!message.status) { + throw new Error('Experiment status is missing'); + } + + return message as unknown as ValidExperimentMessageData; +} diff --git a/src/queue/consumers/visa/consumers/syncProposalQueueConsumer.ts b/src/queue/consumers/visa/consumers/syncProposalQueueConsumer.ts index 1347bb4f..19f27087 100644 --- a/src/queue/consumers/visa/consumers/syncProposalQueueConsumer.ts +++ b/src/queue/consumers/visa/consumers/syncProposalQueueConsumer.ts @@ -4,7 +4,7 @@ import { ConsumerCallback } from '@user-office-software/duo-message-broker'; import { Event } from '../../../../models/Event'; import { ProposalMessageData } from '../../../../models/ProposalMessage'; import { QueueConsumer } from '../../QueueConsumer'; -import { hasTriggeringStatus } from '../../utils/hasTriggeringStatus'; +import { hasTriggeringProposalStatus } from '../../utils/hasTriggeringStatus'; import { hasTriggeringType } from '../../utils/hasTriggeringType'; import { validateProposalMessage } from '../../utils/validateProposalMessage'; import { syncVisaProposal } from '../consumerCallbacks/syncVisaProposal'; @@ -35,7 +35,7 @@ export class SyncProposalQueueConsumer extends QueueConsumer { message, }); - const hasStatus = hasTriggeringStatus(message, triggeringStatuses); + const hasStatus = hasTriggeringProposalStatus(message, triggeringStatuses); if (!hasStatus) { return; diff --git a/src/queue/queueHandling.ts b/src/queue/queueHandling.ts index e221b72e..c9251f11 100644 --- a/src/queue/queueHandling.ts +++ b/src/queue/queueHandling.ts @@ -1,14 +1,15 @@ import { container } from 'tsyringe'; +import { Tokens } from '../config/Tokens'; +import { str2Bool } from '../config/utils'; import { MoodleFolderCreationQueueConsumer } from './consumers/moodle/MoodleFolderCreationQueueConsumer'; import { OneIdentityIntegrationQueueConsumer } from './consumers/oneidentity/OneIdentityIntegrationQueueConsumer'; import { ChatroomCreationQueueConsumer } from './consumers/scicat/scicatProposal/consumers/ChatroomCreationQueueConsumer'; +import { ExperimentCreationQueueConsumer } from './consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer'; import { FolderCreationQueueConsumer } from './consumers/scicat/scicatProposal/consumers/FolderCreationQueueConsumer'; import { ProposalCreationQueueConsumer } from './consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer'; import { SyncProposalQueueConsumer } from './consumers/visa/consumers/syncProposalQueueConsumer'; import { GetMessageBroker } from './messageBroker/getMessageBroker'; -import { Tokens } from '../config/Tokens'; -import { str2Bool } from '../config/utils'; const getMessageBroker: GetMessageBroker = container.resolve( Tokens.ProvideMessageBroker @@ -16,6 +17,7 @@ const getMessageBroker: GetMessageBroker = container.resolve( const queueConsumers = { ENABLE_SCICAT_PROPOSAL_UPSERT: ProposalCreationQueueConsumer, + ENABLE_SCICAT_EXPERIMENT_UPSERT: ExperimentCreationQueueConsumer, ENABLE_SCICHAT_ROOM_CREATION: ChatroomCreationQueueConsumer, ENABLE_PROPOSAL_FOLDERS_CREATION: FolderCreationQueueConsumer, ENABLE_MOODLE_FOLDERS_CREATION: MoodleFolderCreationQueueConsumer, diff --git a/src/services/userOfficeApi/queries/getExperiment.query.ts b/src/services/userOfficeApi/queries/getExperiment.query.ts new file mode 100644 index 00000000..68ba5612 --- /dev/null +++ b/src/services/userOfficeApi/queries/getExperiment.query.ts @@ -0,0 +1,422 @@ +export const GET_EXPERIMENT_QUERY = `query getExperiment($experimentPk: Int!) { + experiment(experimentPk: $experimentPk) { + ...experiment + proposal { + ...proposal + proposer { + ...basicUserDetails + } + } + visit { + registrations { + status + user { + ...basicUserDetails + } + } + } + experimentSafety { + ...experimentSafety + } + } +} + +fragment experiment on Experiment { + experimentPk + experimentId + startsAt + endsAt + scheduledEventId + proposalPk + status + localContactId + instrumentId + createdAt + updatedAt + instrument { + id + name + shortCode + description + managerUserId + scientists { + ...basicUserDetails + } + } +} + +fragment basicUserDetails on BasicUserDetails { + id + firstname + lastname + preferredname + institution + institutionId + created + email + country + oidcSub +} + +fragment proposal on Proposal { + primaryKey + title + abstract + statusId + status { + ...status + } + publicStatus + proposalId + finalStatus + commentForUser + commentForManagement + created + updated + callId + questionaryId + notified + submitted + managementDecisionSubmitted + fileId +} + +fragment status on Status { + id + shortCode + name + description + isDefault + entityType +} + +fragment experimentSafety on ExperimentSafety { + experimentSafetyPk + experimentPk + esiQuestionaryId + esiQuestionarySubmittedAt + createdBy + statusId + safetyReviewQuestionaryId + reviewedBy + createdAt + updatedAt + instrumentScientistDecision + instrumentScientistComment + experimentSafetyReviewerDecision + experimentSafetyReviewerComment + status { + ...status + } + samples { + experimentPk + sampleId + isEsiSubmitted + sampleEsiQuestionaryId + createdAt + updatedAt + questionary { + ...questionary + } + sample { + ...sample + } + } +} + +fragment questionary on Questionary { + questionaryId + templateId + created + steps { + ...questionaryStep + } +} + +fragment questionaryStep on QuestionaryStep { + topic { + ...topic + } + isCompleted + fields { + ...answer + } +} + +fragment topic on Topic { + title + id + templateId + sortOrder + isEnabled +} + +fragment answer on Answer { + answerId + question { + ...question + } + sortOrder + topicId + config { + ...fieldConfig + } + dependencies { + questionId + dependencyId + dependencyNaturalKey + condition { + ...fieldCondition + } + } + dependenciesOperator + value +} + +fragment question on Question { + id + question + naturalKey + dataType + categoryId + config { + ...fieldConfig + } +} + +fragment fieldConfig on FieldConfig { + ... on BooleanConfig { + small_label + required + tooltip + readPermissions + } + ... on DateConfig { + small_label + required + tooltip + readPermissions + minDate + maxDate + defaultDate + includeTime + } + ... on EmbellishmentConfig { + html + plain + omitFromPdf + readPermissions + } + ... on FileUploadConfig { + file_type + max_files + pdf_page_limit + omitFromPdf + small_label + required + tooltip + readPermissions + } + ... on IntervalConfig { + units { + ...unit + } + numberValueConstraint + small_label + required + tooltip + readPermissions + } + ... on NumberInputConfig { + units { + ...unit + } + numberValueConstraint + small_label + required + tooltip + readPermissions + } + ... on ProposalBasisConfig { + tooltip + readPermissions + } + ... on ProposalEsiBasisConfig { + tooltip + readPermissions + } + ... on SampleEsiBasisConfig { + tooltip + readPermissions + } + ... on SampleBasisConfig { + titlePlaceholder + readPermissions + } + ... on SampleDeclarationConfig { + addEntryButtonLabel + minEntries + maxEntries + templateId + esiTemplateId + templateCategory + required + small_label + readPermissions + } + ... on SubTemplateConfig { + addEntryButtonLabel + copyButtonLabel + canCopy + isMultipleCopySelect + isCompleteOnCopy + minEntries + maxEntries + templateId + templateCategory + required + small_label + readPermissions + } + ... on SelectionFromOptionsConfig { + variant + options + isMultipleSelect + small_label + required + tooltip + readPermissions + } + ... on TextInputConfig { + min + max + multiline + placeholder + small_label + required + tooltip + readPermissions + htmlQuestion + isHtmlQuestion + isCounterHidden + } + ... on ShipmentBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on RichTextInputConfig { + small_label + required + tooltip + readPermissions + max + allowImages + } + ... on DynamicMultipleChoiceConfig { + small_label + required + tooltip + readPermissions + url + jsonPath + apiCallRequestHeaders { + name + value + } + isMultipleSelect + variant + } + ... on VisitBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on FapReviewBasisConfig { + small_label + required + tooltip + readPermissions + minGrade + maxGrade + decimalPoints + nonNumericOptions + } + ... on TechnicalReviewBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on GenericTemplateBasisConfig { + titlePlaceholder + questionLabel + readPermissions + } + ... on FeedbackBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on ExperimentSafetyReviewBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on InstrumentPickerConfig { + variant + small_label + required + tooltip + readPermissions + isMultipleSelect + requestTime + instruments { + id + name + } + } + ... on TechniquePickerConfig { + variant + small_label + required + tooltip + readPermissions + isMultipleSelect + techniques { + id + name + } + } +} + +fragment unit on Unit { + id + unit + quantity + symbol + siConversionFormula +} + +fragment fieldCondition on FieldCondition { + condition + params +} + +fragment sample on Sample { + id + title + creatorId + questionaryId + safetyStatus + safetyComment + isPostProposalSubmission + created + proposalPk + questionId +} +`; diff --git a/src/services/userOfficeApi/queries/getProposal.query.ts b/src/services/userOfficeApi/queries/getProposal.query.ts new file mode 100644 index 00000000..4eba4090 --- /dev/null +++ b/src/services/userOfficeApi/queries/getProposal.query.ts @@ -0,0 +1,398 @@ +export const GET_PROPOSAL_QUERY = `query getProposal($primaryKey: Int!) { + proposal(primaryKey: $primaryKey) { + ...proposal + proposer { + ...basicUserDetails + } + users { + ...basicUserDetails + } + dataAccessUsers { + ...basicUserDetails + } + experiments { + experimentPk + } + instruments { + id + name + shortCode + instrumentContact { + id + firstname + lastname + preferredname + } + scientists { + id + firstname + lastname + preferredname + } + managementTimeAllocation + multipleTechReviewsEnabled + } + call { + id + shortCode + isActive + isActiveInternal + allocationTimeUnit + referenceNumberFormat + startCall + endCall + endCallInternal + proposalWorkflowId + } + samples { + ...sample + questionary { + ...questionary + } + } + } +} + +fragment proposal on Proposal { + primaryKey + title + abstract + statusId + status { + ...status + } + publicStatus + proposalId + finalStatus + commentForUser + commentForManagement + created + updated + callId + questionaryId + notified + submitted + managementDecisionSubmitted + fileId +} + +fragment status on Status { + id + shortCode + name + description + isDefault + entityType +} + +fragment basicUserDetails on BasicUserDetails { + id + firstname + lastname + preferredname + institution + institutionId + created + email + country + oidcSub +} + +fragment questionary on Questionary { + questionaryId + templateId + created + steps { + ...questionaryStep + } +} + +fragment questionaryStep on QuestionaryStep { + topic { + ...topic + } + isCompleted + fields { + ...answer + } +} + +fragment topic on Topic { + title + id + templateId + sortOrder + isEnabled +} + +fragment answer on Answer { + answerId + question { + ...question + } + sortOrder + topicId + config { + ...fieldConfig + } + dependencies { + questionId + dependencyId + dependencyNaturalKey + condition { + ...fieldCondition + } + } + dependenciesOperator + value +} + +fragment question on Question { + id + question + naturalKey + dataType + categoryId + config { + ...fieldConfig + } +} + +fragment fieldConfig on FieldConfig { + ... on BooleanConfig { + small_label + required + tooltip + readPermissions + } + ... on DateConfig { + small_label + required + tooltip + readPermissions + minDate + maxDate + defaultDate + includeTime + } + ... on EmbellishmentConfig { + html + plain + omitFromPdf + readPermissions + } + ... on FileUploadConfig { + file_type + max_files + pdf_page_limit + omitFromPdf + small_label + required + tooltip + readPermissions + } + ... on IntervalConfig { + units { + ...unit + } + numberValueConstraint + small_label + required + tooltip + readPermissions + } + ... on NumberInputConfig { + units { + ...unit + } + numberValueConstraint + small_label + required + tooltip + readPermissions + } + ... on ProposalBasisConfig { + tooltip + readPermissions + } + ... on ProposalEsiBasisConfig { + tooltip + readPermissions + } + ... on SampleEsiBasisConfig { + tooltip + readPermissions + } + ... on SampleBasisConfig { + titlePlaceholder + readPermissions + } + ... on SampleDeclarationConfig { + addEntryButtonLabel + minEntries + maxEntries + templateId + esiTemplateId + templateCategory + required + small_label + readPermissions + } + ... on SubTemplateConfig { + addEntryButtonLabel + copyButtonLabel + canCopy + isMultipleCopySelect + isCompleteOnCopy + minEntries + maxEntries + templateId + templateCategory + required + small_label + readPermissions + } + ... on SelectionFromOptionsConfig { + variant + options + isMultipleSelect + small_label + required + tooltip + readPermissions + } + ... on TextInputConfig { + min + max + multiline + placeholder + small_label + required + tooltip + readPermissions + htmlQuestion + isHtmlQuestion + isCounterHidden + } + ... on ShipmentBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on RichTextInputConfig { + small_label + required + tooltip + readPermissions + max + allowImages + } + ... on DynamicMultipleChoiceConfig { + small_label + required + tooltip + readPermissions + url + jsonPath + apiCallRequestHeaders { + name + value + } + isMultipleSelect + variant + } + ... on VisitBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on FapReviewBasisConfig { + small_label + required + tooltip + readPermissions + minGrade + maxGrade + decimalPoints + nonNumericOptions + } + ... on TechnicalReviewBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on GenericTemplateBasisConfig { + titlePlaceholder + questionLabel + readPermissions + } + ... on FeedbackBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on ExperimentSafetyReviewBasisConfig { + small_label + required + tooltip + readPermissions + } + ... on InstrumentPickerConfig { + variant + small_label + required + tooltip + readPermissions + isMultipleSelect + requestTime + instruments { + id + name + } + } + ... on TechniquePickerConfig { + variant + small_label + required + tooltip + readPermissions + isMultipleSelect + techniques { + id + name + } + } +} + +fragment unit on Unit { + id + unit + quantity + symbol + siConversionFormula +} + +fragment fieldCondition on FieldCondition { + condition + params +} + +fragment sample on Sample { + id + title + creatorId + questionaryId + safetyStatus + safetyComment + isPostProposalSubmission + created + proposalPk + questionId + questionary { + ...questionary + } +}`; diff --git a/src/services/userOfficeApi/type/uoExperiment.type.ts b/src/services/userOfficeApi/type/uoExperiment.type.ts new file mode 100644 index 00000000..9c4e3a12 --- /dev/null +++ b/src/services/userOfficeApi/type/uoExperiment.type.ts @@ -0,0 +1,44 @@ +import { UOProposalDto, UOUser } from './uoProposal.type'; + +export interface UOExperimentSafetySample { + sampleId: number; + questionary: { + steps: { + fields: { + question: { + id: string; + question: string; + }; + value: string | number | boolean | null; + }[]; + }[]; + }; + sample: { + id: number; + title: string; + }; +} +export interface UOExperimentDto { + experimentId: string; + startsAt: string; + status: string; + endsAt: string; + instrument: { + id: number; + name: string; + shortCode: string; + }; + proposal: Pick< + UOProposalDto, + 'proposalId' | 'title' | 'abstract' | 'status' | 'proposer' + >; + visit?: { + registrations: { + status: string; + user: UOUser | null; + }[]; + } | null; + experimentSafety?: { + samples: UOExperimentSafetySample[]; + } | null; +} diff --git a/src/services/userOfficeApi/type/uoProposal.type.ts b/src/services/userOfficeApi/type/uoProposal.type.ts new file mode 100644 index 00000000..dc701d9c --- /dev/null +++ b/src/services/userOfficeApi/type/uoProposal.type.ts @@ -0,0 +1,54 @@ +export interface UOUser { + id: number; + firstname: string; + lastname: string; + preferredname?: string | null; + institution?: string; + email: string; + oidcSub?: string | null; + country?: string | null; +} + +export interface UOInstrumentContact { + id: number; + firstname: string; + lastname: string; + preferredname?: string | null; +} + +export interface UOInstrument { + id: number; + name: string; + shortCode: string; + instrumentContact?: UOInstrumentContact; + managementTimeAllocation?: number; +} + +export interface UOCall { + id: number; + shortCode: string; + isActive: boolean; + startCall: string; + endCall: string; + allocationTimeUnit?: string; + proposalWorkflowId?: number; +} + +export interface UOStatus { + id: number; + shortCode: string; + name: string; + description?: string; +} + +export interface UOProposalDto { + proposalId: string; + title: string; + abstract: string; + status: UOStatus; + proposer: UOUser; + users: UOUser[]; + dataAccessUsers: UOUser[]; + instruments: UOInstrument[]; + call: UOCall; +} diff --git a/src/services/userOfficeApi/uoApi.spec.ts b/src/services/userOfficeApi/uoApi.spec.ts new file mode 100644 index 00000000..5dc5bd94 --- /dev/null +++ b/src/services/userOfficeApi/uoApi.spec.ts @@ -0,0 +1,78 @@ +import { fetchUoProposal, fetchUoExperiment } from './uoApi'; + +const mockFetch = jest.fn(); +global.fetch = mockFetch; + +const mockProposal = { + proposalId: '158548', + title: 'Test Proposal', +}; + +const mockExperiment = { + experimentId: '158548-3', +}; + +beforeEach(() => { + jest.clearAllMocks(); + process.env.USER_OFFICE_GRAPHQL_URL = 'http://localhost:8080/graphql'; + process.env.USER_OFFICE_JWT = 'test-token'; +}); + +describe('fetchUoProposal', () => { + it('returns proposal data on success', async () => { + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: { proposal: mockProposal } }), + }); + + const result = await fetchUoProposal(1); + + expect(result).toEqual(mockProposal); + }); + + it('throws when response is not ok', async () => { + mockFetch.mockResolvedValueOnce({ + ok: false, + text: async () => 'Internal Server Error', + }); + + await expect(fetchUoProposal(1)).rejects.toThrow( + 'UOS GraphQL request failed: Internal Server Error' + ); + }); + + it('throws when response contains GraphQL errors', async () => { + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + errors: [{ message: 'Not found' }], + }), + }); + + await expect(fetchUoProposal(1)).rejects.toThrow('UOS GraphQL errors'); + }); +}); + +describe('fetchUoExperiment', () => { + it('returns experiment data on success', async () => { + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: { experiment: mockExperiment } }), + }); + + const result = await fetchUoExperiment(311); + + expect(result).toEqual(mockExperiment); + }); + + it('throws when response is not ok', async () => { + mockFetch.mockResolvedValueOnce({ + ok: false, + text: async () => 'Internal Server Error', + }); + + await expect(fetchUoExperiment(311)).rejects.toThrow( + 'UOS GraphQL request failed: Internal Server Error' + ); + }); +}); diff --git a/src/services/userOfficeApi/uoApi.ts b/src/services/userOfficeApi/uoApi.ts new file mode 100644 index 00000000..5df1b554 --- /dev/null +++ b/src/services/userOfficeApi/uoApi.ts @@ -0,0 +1,59 @@ +import { GET_EXPERIMENT_QUERY } from './queries/getExperiment.query'; +import { GET_PROPOSAL_QUERY } from './queries/getProposal.query'; +import { UOExperimentDto } from './type/uoExperiment.type'; +import { UOProposalDto } from './type/uoProposal.type'; + +const uosGraphqlUrl = process.env.USER_OFFICE_GRAPHQL_URL; +const uosToken = process.env.USER_OFFICE_JWT; + +const graphqlRequest = async ( + query: string, + variables: Record +): Promise => { + if (!uosGraphqlUrl) { + throw new Error('USER_OFFICE_GRAPHQL_URL is not defined'); + } + + if (!uosToken) { + throw new Error('USER_OFFICE_JWT is not defined'); + } + + const response = await fetch(uosGraphqlUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${uosToken}`, + }, + body: JSON.stringify({ query, variables }), + }); + + if (!response.ok) { + const detail = await response.text(); + throw new Error(`UOS GraphQL request failed: ${detail}`); + } + + const json = await response.json(); + + if (json.errors?.length) { + throw new Error(`UOS GraphQL errors: ${JSON.stringify(json.errors)}`); + } + + return json as TResponse; +}; + +export const fetchUoProposal = async (primaryKey: number) => { + const { data } = await graphqlRequest<{ data: { proposal: UOProposalDto } }>( + GET_PROPOSAL_QUERY, + { primaryKey } + ); + + return data.proposal; +}; + +export const fetchUoExperiment = async (experimentPk: number) => { + const { data } = await graphqlRequest<{ + data: { experiment: UOExperimentDto }; + }>(GET_EXPERIMENT_QUERY, { experimentPk }); + + return data.experiment; +}; From 81944f2bb86056c7a455db64078084a385371c48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 May 2026 13:37:32 +0000 Subject: [PATCH 04/30] build(deps): bump qs from 6.15.0 to 6.15.2 Bumps [qs](https://github.com/ljharb/qs) from 6.15.0 to 6.15.2. - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.15.0...v6.15.2) --- updated-dependencies: - dependency-name: qs dependency-version: 6.15.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59c10473..2a89665b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8347,9 +8347,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -16245,9 +16245,9 @@ "dev": true }, "qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", "requires": { "side-channel": "^1.1.0" } From 6bd928548338fea3c77cc68b2067cd2ac1babd57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 May 2026 13:44:19 +0000 Subject: [PATCH 05/30] build(deps-dev): bump lint-staged from 16.4.0 to 17.0.5 Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 16.4.0 to 17.0.5. - [Release notes](https://github.com/lint-staged/lint-staged/releases) - [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md) - [Commits](https://github.com/lint-staged/lint-staged/compare/v16.4.0...v17.0.5) --- updated-dependencies: - dependency-name: lint-staged dependency-version: 17.0.4 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 284 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 143 insertions(+), 143 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a89665b..95a6229f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", "jest": "^30.3.0", - "lint-staged": "^16.4.0", + "lint-staged": "^17.0.5", "prettier": "3.8.1", "ts-jest": "^29.4.6", "typescript": "^5.9.3" @@ -3780,13 +3780,6 @@ "node": ">=12.20" } }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3799,16 +3792,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5273,9 +5256,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "dev": true, "license": "MIT", "engines": { @@ -7185,27 +7168,28 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", - "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.5.tgz", + "integrity": "sha512-d12yC+/e8RhBjZtaxZn71FyrgU/P5e+uAPifhCLwdosQZP/zamSdKRWDC30ocVIbzDKiFG1McHc/LUgB92GIPw==", "dev": true, "license": "MIT", "dependencies": { - "commander": "^14.0.3", - "listr2": "^9.0.5", - "picomatch": "^4.0.3", + "listr2": "^10.2.1", + "picomatch": "^4.0.4", "string-argv": "^0.3.2", - "tinyexec": "^1.0.4", - "yaml": "^2.8.2" + "tinyexec": "^1.1.2" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=20.17" + "node": ">=22.22.1" }, "funding": { "url": "https://opencollective.com/lint-staged" + }, + "optionalDependencies": { + "yaml": "^2.8.4" } }, "node_modules/lint-staged/node_modules/picomatch": { @@ -7222,21 +7206,20 @@ } }, "node_modules/listr2": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", - "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", + "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", "dev": true, "license": "MIT", "dependencies": { - "cli-truncate": "^5.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", "log-update": "^6.1.0", "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" + "wrap-ansi": "^10.0.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.13.0" } }, "node_modules/locate-path": { @@ -7321,6 +7304,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, "node_modules/log-update/node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", @@ -7338,6 +7328,42 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/logform": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", @@ -9185,9 +9211,9 @@ } }, "node_modules/string-width": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", "dev": true, "license": "MIT", "dependencies": { @@ -9465,9 +9491,9 @@ } }, "node_modules/tinyexec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", - "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", "dev": true, "license": "MIT", "engines": { @@ -10413,18 +10439,18 @@ "license": "MIT" }, "node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -10510,31 +10536,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -10593,11 +10594,12 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, "license": "ISC", + "optional": true, "bin": { "yaml": "bin.mjs" }, @@ -13225,12 +13227,6 @@ } } }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -13239,12 +13235,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -14218,9 +14208,9 @@ "dev": true }, "get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "dev": true }, "get-intrinsic": { @@ -15472,17 +15462,16 @@ "dev": true }, "lint-staged": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", - "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.5.tgz", + "integrity": "sha512-d12yC+/e8RhBjZtaxZn71FyrgU/P5e+uAPifhCLwdosQZP/zamSdKRWDC30ocVIbzDKiFG1McHc/LUgB92GIPw==", "dev": true, "requires": { - "commander": "^14.0.3", - "listr2": "^9.0.5", - "picomatch": "^4.0.3", + "listr2": "^10.2.1", + "picomatch": "^4.0.4", "string-argv": "^0.3.2", - "tinyexec": "^1.0.4", - "yaml": "^2.8.2" + "tinyexec": "^1.1.2", + "yaml": "^2.8.4" }, "dependencies": { "picomatch": { @@ -15494,17 +15483,16 @@ } }, "listr2": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", - "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", + "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", "dev": true, "requires": { - "cli-truncate": "^5.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", "log-update": "^6.1.0", "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" + "wrap-ansi": "^10.0.0" } }, "locate-path": { @@ -15561,6 +15549,12 @@ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true }, + "emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true + }, "slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", @@ -15570,6 +15564,28 @@ "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } + }, + "string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + } + }, + "wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "requires": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + } } } }, @@ -16820,9 +16836,9 @@ } }, "string-width": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", "dev": true, "requires": { "get-east-asian-width": "^1.5.0", @@ -17003,9 +17019,9 @@ "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==" }, "tinyexec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", - "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", "dev": true }, "tinyglobby": { @@ -17610,14 +17626,14 @@ "dev": true }, "wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", "dev": true, "requires": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" }, "dependencies": { "ansi-styles": { @@ -17625,23 +17641,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true - }, - "emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true - }, - "string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "requires": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - } } } }, @@ -17731,10 +17730,11 @@ "dev": true }, "yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "dev": true + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "optional": true }, "yargs": { "version": "17.7.2", diff --git a/package.json b/package.json index 3b185083..91b98028 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", "jest": "^30.3.0", - "lint-staged": "^16.4.0", + "lint-staged": "^17.0.5", "prettier": "3.8.1", "ts-jest": "^29.4.6", "typescript": "^5.9.3" From 000d5347de402bb1b2bfd27039d710c155daf5e5 Mon Sep 17 00:00:00 2001 From: Yoganandan Pandiyan Date: Fri, 22 May 2026 09:27:27 +0200 Subject: [PATCH 06/30] feat(oneidentity): add VISIT_UPDATED flow for access sync --- src/index.ts | 2 +- src/models/Event.ts | 1 + .../OneIdentityIntegrationQueueConsumer.ts | 1 + ...osalAndMembersToOneIdentityHandler.spec.ts | 1 + .../syncVisitToOneIdentityHandler.spec.ts | 329 +++++++++++++++++- .../syncVisitToOneIdentityHandler.ts | 138 +++++++- .../oneidentity/utils/ESSOneIdentity.ts | 15 + .../oneidentity/utils/OneIdentityApi.ts | 12 + .../utils/interfaces/VisitMessage.ts | 1 + 9 files changed, 477 insertions(+), 23 deletions(-) diff --git a/src/index.ts b/src/index.ts index 23409f92..17c2fb64 100644 --- a/src/index.ts +++ b/src/index.ts @@ -71,7 +71,7 @@ async function bootstrap() { logger.logException('Unhandled NODE exception', error); }); - logger.logInfo(`Running connector service at localhost:${PORT}`, {}); + logger.logInfo(`Running connector services at localhost:${PORT}`, {}); if ( enableScicatProposalUpsert || diff --git a/src/models/Event.ts b/src/models/Event.ts index 2ed1cff6..add33a9b 100644 --- a/src/models/Event.ts +++ b/src/models/Event.ts @@ -4,4 +4,5 @@ export enum Event { PROPOSAL_UPDATED = 'PROPOSAL_UPDATED', VISIT_CREATED = 'VISIT_CREATED', VISIT_DELETED = 'VISIT_DELETED', + VISIT_UPDATED = 'VISIT_UPDATED', } diff --git a/src/queue/consumers/oneidentity/OneIdentityIntegrationQueueConsumer.ts b/src/queue/consumers/oneidentity/OneIdentityIntegrationQueueConsumer.ts index 0dfaacbb..65d3d618 100644 --- a/src/queue/consumers/oneidentity/OneIdentityIntegrationQueueConsumer.ts +++ b/src/queue/consumers/oneidentity/OneIdentityIntegrationQueueConsumer.ts @@ -25,6 +25,7 @@ const SYNC_PROPOSAL_AND_MEMBERS_EVENTS_FOR_HANDLING = [ const SYNC_VISIT_EVENTS_FOR_HANDLING = [ Event.VISIT_CREATED, Event.VISIT_DELETED, + Event.VISIT_UPDATED, ]; // Class for consuming messages from the ESS One Identity Integration Queue diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts index cb8cf144..c0a08c6c 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts @@ -25,6 +25,7 @@ const mockOneIdentity: jest.Mocked> = { removeConnectionBetweenPersonAndProposal: jest.fn(), getPersonWantsOrg: jest.fn(), createPersonWantsOrg: jest.fn(), + updatePersonWantsOrg: jest.fn(), cancelPersonWantsOrg: jest.fn(), hasPersonSiteAccessToProposal: jest.fn(), }; diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts index ce60cc3c..6e5e5c33 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts @@ -38,6 +38,7 @@ const mockOneIdentity: jest.Mocked> = { getProposalPersonConnections: jest.fn(), removeConnectionBetweenPersonAndProposal: jest.fn(), createPersonWantsOrg: jest.fn(), + updatePersonWantsOrg: jest.fn(), cancelPersonWantsOrg: jest.fn(), hasPersonSiteAccessToProposal: jest.fn(), }; @@ -45,6 +46,7 @@ const mockOneIdentity: jest.Mocked> = { const mockUidESet: UID_ESet = 'eset-uid-123'; const visitMessage: VisitMessage = { + id: '1', visitorId: 'visitor-oidc-sub', startAt: '2023-01-01T00:00:00.000Z', endAt: '2023-01-10T00:00:00.000Z', @@ -144,7 +146,7 @@ describe('syncVisitToOneIdentityHandler', () => { visitMessage.visitorId, visitMessage.startAt, visitMessage.endAt, - visitMessage.proposal.shortCode + visitMessage.id ); // Calculate expected system access dates @@ -163,7 +165,7 @@ describe('syncVisitToOneIdentityHandler', () => { visitMessage.visitorId, expectedValidFrom, expectedEndDate.toISOString(), - 'site-access-uid' + visitMessage.id ); expect(logger.logInfo).toHaveBeenCalledWith( @@ -325,7 +327,7 @@ describe('syncVisitToOneIdentityHandler', () => { DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, ValidFrom: '2023-01-01T00:00:00.000Z', ValidUntil: '2023-01-10T00:00:00.000Z', - CustomProperty04: 'proposal-short-code', + CustomProperty04: visitMessageVisitorNotMember.id, OrderState: OrderState.GRANTED, } as PersonWantsOrg, { @@ -334,7 +336,7 @@ describe('syncVisitToOneIdentityHandler', () => { DisplayOrg: PersonWantsOrgRole.SYSTEM_ACCESS, ValidFrom: '2023-01-01T00:00:00.000Z', ValidUntil: '2023-01-10T00:00:00.000Z', - CustomProperty04: 'site-access-uid', + CustomProperty04: visitMessageVisitorNotMember.id, OrderState: OrderState.GRANTED, } as PersonWantsOrg, ]; @@ -423,7 +425,7 @@ describe('syncVisitToOneIdentityHandler', () => { DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, ValidFrom: '2023-01-01T00:00:00.000Z', ValidUntil: '2023-01-10T00:00:00.000Z', - CustomProperty04: 'proposal-short-code', + CustomProperty04: visitMessage.id, OrderState: OrderState.GRANTED, } as PersonWantsOrg, { @@ -432,7 +434,7 @@ describe('syncVisitToOneIdentityHandler', () => { DisplayOrg: PersonWantsOrgRole.SYSTEM_ACCESS, ValidFrom: '2023-01-01T00:00:00.000Z', ValidUntil: '2023-01-10T00:00:00.000Z', - CustomProperty04: 'site-access-uid', + CustomProperty04: visitMessage.id, OrderState: OrderState.GRANTED, } as PersonWantsOrg, ]; @@ -574,17 +576,17 @@ describe('syncVisitToOneIdentityHandler', () => { DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, ValidFrom: visitMessage.startAt, ValidUntil: visitMessage.endAt, - CustomProperty04: 'proposal-short-code', + CustomProperty04: visitMessage.id, OrderState: OrderState.GRANTED, } as PersonWantsOrg, - // No system access with CustomProperty04 matching site-access-uid + // No system access with CustomProperty04 matching visitMessage.id { UID_PersonWantsOrg: 'system-access-uid', UID_PersonOrdered: 'visitor-uid', DisplayOrg: PersonWantsOrgRole.SYSTEM_ACCESS, ValidFrom: '2023-01-01T00:00:00.000Z', ValidUntil: '2023-01-10T00:00:00.000Z', - CustomProperty04: 'different-site-access-uid', + CustomProperty04: 'different-visit-id', OrderState: OrderState.GRANTED, } as PersonWantsOrg, ]; @@ -617,4 +619,313 @@ describe('syncVisitToOneIdentityHandler', () => { expect(mockOneIdentity.logout).toHaveBeenCalled(); }); }); + + describe('VISIT_UPDATED', () => { + it('should update site access and system access dates when visit dates have changed', async () => { + const mockPerson = { + UID_Person: 'visitor-uid', + CCC_EmployeeSubType: IdentityType.ESSSCIENCEUSER, + } as Person; + + const oldSiteAccess = { + UID_PersonWantsOrg: 'site-access-uid', + UID_PersonOrdered: 'visitor-uid', + DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, + ValidFrom: '2023-01-01T00:00:00.000Z', + ValidUntil: '2023-01-10T00:00:00.000Z', + CustomProperty04: '1', + OrderState: OrderState.GRANTED, + } as PersonWantsOrg; + + const oldSystemAccess = { + UID_PersonWantsOrg: 'system-access-uid', + UID_PersonOrdered: 'visitor-uid', + DisplayOrg: PersonWantsOrgRole.SYSTEM_ACCESS, + ValidFrom: '2023-01-01T00:00:00.000Z', + ValidUntil: '2023-01-25T00:00:00.000Z', + CustomProperty04: '1', + OrderState: OrderState.GRANTED, + } as PersonWantsOrg; + + const mockPersonWantsOrgs = [oldSiteAccess, oldSystemAccess]; + + mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); + mockOneIdentity.getProposal.mockResolvedValueOnce(mockUidESet); + mockOneIdentity.getPersonWantsOrg.mockResolvedValueOnce( + mockPersonWantsOrgs + ); + mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([]); // No existing connection + + // Updated visit message with new dates + const updatedVisitMessage: VisitMessage = { + ...visitMessage, + startAt: '2023-02-01T00:00:00.000Z', + endAt: '2023-02-15T00:00:00.000Z', + }; + + await syncVisitToOneIdentityHandler( + updatedVisitMessage, + Event.VISIT_UPDATED + ); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + expect(mockOneIdentity.getPersonWantsOrg).toHaveBeenCalledWith( + 'visitor-uid' + ); + + // Verify site access update + expect(mockOneIdentity.updatePersonWantsOrg).toHaveBeenNthCalledWith( + 1, + 'site-access-uid', + '2023-02-01T00:00:00.000Z', + '2023-02-15T00:00:00.000Z' + ); + expect(logger.logInfo).toHaveBeenCalledWith( + 'Site access updated in One Identity', + { + UID_PersonWantsOrg: 'site-access-uid', + } + ); + + // Verify system access update + expect(mockOneIdentity.updatePersonWantsOrg).toHaveBeenNthCalledWith( + 2, + 'system-access-uid', + '2023-02-01T00:00:00.000Z', + '2023-02-15T00:00:00.000Z' + ); + expect(logger.logInfo).toHaveBeenCalledWith( + 'System access updated in One Identity', + { + UID_PersonWantsOrg: 'system-access-uid', + } + ); + + expect(mockOneIdentity.connectPersonToProposal).toHaveBeenCalledWith( + mockUidESet, + 'visitor-uid' + ); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + + it('should skip update when visit dates have not changed', async () => { + const mockPerson = { + UID_Person: 'visitor-uid', + CCC_EmployeeSubType: IdentityType.ESSSCIENCEUSER, + } as Person; + + const mockSiteAccess = { + UID_PersonWantsOrg: 'site-access-uid', + UID_PersonOrdered: 'visitor-uid', + DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, + ValidFrom: visitMessage.startAt, + ValidUntil: visitMessage.endAt, + CustomProperty04: '1', + OrderState: OrderState.GRANTED, + } as PersonWantsOrg; + + const mockSystemAccess = { + UID_PersonWantsOrg: 'system-access-uid', + UID_PersonOrdered: 'visitor-uid', + DisplayOrg: PersonWantsOrgRole.SYSTEM_ACCESS, + ValidFrom: visitMessage.startAt, + ValidUntil: visitMessage.endAt, + CustomProperty04: '1', + OrderState: OrderState.GRANTED, + } as PersonWantsOrg; + + const mockPersonWantsOrgs = [mockSiteAccess, mockSystemAccess]; + + mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); + mockOneIdentity.getProposal.mockResolvedValueOnce(mockUidESet); + mockOneIdentity.getPersonWantsOrg.mockResolvedValueOnce( + mockPersonWantsOrgs + ); + mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([]); // No existing connection + + await syncVisitToOneIdentityHandler(visitMessage, Event.VISIT_UPDATED); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + + // Verify no update occurred + expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); + expect(logger.logInfo).toHaveBeenCalledWith( + 'Visit dates unchanged, skipping access update in One Identity', + { + UID_PersonWantsOrg: 'site-access-uid', + visitId: visitMessage.id, + } + ); + + // But proposal connection should still be created as backup + expect(mockOneIdentity.connectPersonToProposal).toHaveBeenCalledWith( + mockUidESet, + 'visitor-uid' + ); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + + it('should create new access if site access not found', async () => { + const mockPerson = { + UID_Person: 'visitor-uid', + CCC_EmployeeSubType: IdentityType.ESSSCIENCEUSER, + } as Person; + + const mockSiteAccess = { + UID_PersonWantsOrg: 'site-access-uid', + } as PersonWantsOrg; + const mockSystemAccess = { + UID_PersonWantsOrg: 'system-access-uid', + } as PersonWantsOrg; + + mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); + mockOneIdentity.getProposal.mockResolvedValueOnce(mockUidESet); + mockOneIdentity.getPersonWantsOrg.mockResolvedValueOnce([]); // No existing access + mockOneIdentity.createPersonWantsOrg + .mockResolvedValueOnce([mockSiteAccess]) + .mockResolvedValueOnce([mockSystemAccess]); + mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([]); // No existing connection + + await syncVisitToOneIdentityHandler(visitMessage, Event.VISIT_UPDATED); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + expect(mockOneIdentity.getPersonWantsOrg).toHaveBeenCalledWith( + 'visitor-uid' + ); + + expect(logger.logInfo).toHaveBeenCalledWith( + 'Site access not found in One Identity, creating access', + { + visitId: visitMessage.id, + uidPerson: 'visitor-uid', + } + ); + + // Verify creation occurred instead of update + expect(mockOneIdentity.createPersonWantsOrg).toHaveBeenCalledTimes(2); + expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); + + expect(mockOneIdentity.connectPersonToProposal).toHaveBeenCalledWith( + mockUidESet, + 'visitor-uid' + ); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + + it('should throw error if system access not found during update', async () => { + const mockPerson = { + UID_Person: 'visitor-uid', + CCC_EmployeeSubType: IdentityType.ESSSCIENCEUSER, + } as Person; + + const mockSiteAccess = { + UID_PersonWantsOrg: 'site-access-uid', + UID_PersonOrdered: 'visitor-uid', + DisplayOrg: PersonWantsOrgRole.SITE_ACCESS, + ValidFrom: '2023-01-01T00:00:00.000Z', + ValidUntil: '2023-01-10T00:00:00.000Z', + CustomProperty04: '1', + OrderState: OrderState.GRANTED, + } as PersonWantsOrg; + + const mockPersonWantsOrgs = [mockSiteAccess]; // Only site access, no system access + + mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); + mockOneIdentity.getProposal.mockResolvedValueOnce(mockUidESet); + mockOneIdentity.getPersonWantsOrg.mockResolvedValueOnce( + mockPersonWantsOrgs + ); + + const updatedVisitMessage: VisitMessage = { + ...visitMessage, + startAt: '2023-02-01T00:00:00.000Z', + endAt: '2023-02-15T00:00:00.000Z', + }; + + await expect( + syncVisitToOneIdentityHandler(updatedVisitMessage, Event.VISIT_UPDATED) + ).rejects.toThrow( + 'System access not found in One Identity, cannot update access' + ); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + + it('should skip processing if visitor is not a science user', async () => { + const mockPerson = { + UID_Person: 'visitor-uid', + CCC_EmployeeSubType: 'EMPLOYEEDK', + } as Person; + + mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); + + await syncVisitToOneIdentityHandler(visitMessage, Event.VISIT_UPDATED); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + expect(logger.logInfo).toHaveBeenCalledWith( + 'Visitor is not a Science User, skipping', + {} + ); + expect(mockOneIdentity.getPersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + + it('should throw error if proposal is not found in One Identity', async () => { + const mockPerson = { + UID_Person: 'visitor-uid', + CCC_EmployeeSubType: IdentityType.ESSSCIENCEUSER, + } as Person; + + mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); + mockOneIdentity.getProposal.mockResolvedValueOnce(undefined); // Proposal not found + + await expect( + syncVisitToOneIdentityHandler(visitMessage, Event.VISIT_UPDATED) + ).rejects.toThrow( + 'Proposal not found in One Identity, cannot sync visit' + ); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + expect(mockOneIdentity.getProposal).toHaveBeenCalledWith( + visitMessage.proposal + ); + expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + + it('should throw error if person not found', async () => { + mockOneIdentity.getPerson.mockResolvedValueOnce(undefined); + + await expect( + syncVisitToOneIdentityHandler(visitMessage, Event.VISIT_UPDATED) + ).rejects.toThrow('Person not found in One Identity'); + + expect(mockOneIdentity.login).toHaveBeenCalled(); + expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( + 'visitor-oidc-sub' + ); + expect(mockOneIdentity.getPersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.logout).toHaveBeenCalled(); + }); + }); }); diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index 781f1d7b..699a4c9d 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -18,7 +18,7 @@ const ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS = parseInt( ); export async function syncVisitToOneIdentityHandler( - { startAt, endAt, visitorId: oidcSub, proposal }: VisitMessage, + { id: visitId, startAt, endAt, visitorId: oidcSub, proposal }: VisitMessage, type: Event ): Promise { const oneIdentity = new ESSOneIdentity(); @@ -44,16 +44,29 @@ export async function syncVisitToOneIdentityHandler( if (type === Event.VISIT_CREATED) { await createAccessInOneIdentity( oneIdentity, + visitId, startAt, endAt, - oidcSub, - proposal + oidcSub ); // Every visitor should have access to the proposal folders await createProposalConnection(oneIdentity, uidESet, uidPerson); + } else if (type === Event.VISIT_UPDATED) { + // For simplicity, we will just update the access with the new dates. The update takes place only if the dates are changed. + await updateAccessInOneIdentity( + oneIdentity, + visitId, + startAt, + endAt, + uidPerson, + oidcSub + ); + + // If the Proposal connection has not been established during Visit Creation, this will be a backup + await createProposalConnection(oneIdentity, uidESet, uidPerson); } else if (type === Event.VISIT_DELETED) { - await removeAccessFromOneIdentity(oneIdentity, startAt, endAt, uidPerson); + await removeAccessFromOneIdentity(oneIdentity, visitId, uidPerson); // Remove the connection between the proposal and the visitor await removeProposalConnection( @@ -90,10 +103,10 @@ async function getScienceUser( async function createAccessInOneIdentity( oneIdentity: ESSOneIdentity, + visitId: string, startAt: string, endAt: string, - centralAccount: string, - proposal: ProposalMessageData + centralAccount: string ) { // Create site access const [pwoSite] = await oneIdentity.createPersonWantsOrg( @@ -101,7 +114,7 @@ async function createAccessInOneIdentity( centralAccount, toIsoString(startAt), toIsoString(endAt), - proposal.shortCode // CustomProperty04 - We store the proposal short code for the site access to be able to find it later + visitId.toString() // CustomProperty04 - We store the visit ID for the site access to be able to find it later ); logger.logInfo('Site access created in One Identity', { @@ -120,7 +133,7 @@ async function createAccessInOneIdentity( centralAccount, toIsoString(validFrom), toIsoString(validUntil), - pwoSite.UID_PersonWantsOrg // CustomProperty04 - We store the site access UID for the system access to be able to find it later + visitId.toString() // CustomProperty04 - We store the visit ID for the system access to be able to find it later ); logger.logInfo('System access created in One Identity', { @@ -128,10 +141,99 @@ async function createAccessInOneIdentity( }); } -async function removeAccessFromOneIdentity( +async function updateAccessInOneIdentity( oneIdentity: ESSOneIdentity, + visitId: string, startAt: string, endAt: string, + uidPerson: UID_Person, + centralAccount: string +) { + // Find person wants orgs for the visitor + const personWantsOrgs = await oneIdentity.getPersonWantsOrg(uidPerson); + + // Find site access for the visitor + const siteAccess = personWantsOrgs.find( + (pwo) => + pwo.DisplayOrg === PersonWantsOrgRole.SITE_ACCESS && + pwo.CustomProperty04 === visitId.toString() && // CustomProperty04 is the visit ID for the site access + pwo.OrderState !== OrderState.ABORTED + ); + + // If there is no existing siteAccess record, new one will be created for both siteAccess and systemAccess. + if (!siteAccess) { + logger.logInfo('Site access not found in One Identity, creating access', { + visitId, + uidPerson, + }); + + await createAccessInOneIdentity( + oneIdentity, + visitId, + startAt, + endAt, + centralAccount + ); + + return; + } + + const validFrom = toIsoString(startAt); + const validUntil = toIsoString(endAt); + + if ( + isSameDateTime(siteAccess.ValidFrom, validFrom) && + isSameDateTime(siteAccess.ValidUntil, validUntil) + ) { + logger.logInfo( + 'Visit dates unchanged, skipping access update in One Identity', + { + UID_PersonWantsOrg: siteAccess.UID_PersonWantsOrg, + visitId, + } + ); + + return; + } + + await oneIdentity.updatePersonWantsOrg( + siteAccess.UID_PersonWantsOrg, + validFrom, + validUntil + ); + + logger.logInfo('Site access updated in One Identity', { + UID_PersonWantsOrg: siteAccess.UID_PersonWantsOrg, + }); + + // Find system access for the site access (CustomProperty04 is the visit ID) + const systemAccess = personWantsOrgs.find( + (pwo) => + pwo.CustomProperty04 === visitId.toString() && + pwo.DisplayOrg === PersonWantsOrgRole.SYSTEM_ACCESS && + pwo.OrderState !== OrderState.UNSUBSCRIBED + ); + + if (!systemAccess) { + throw new Error( + 'System access not found in One Identity, cannot update access' + ); + } + + await oneIdentity.updatePersonWantsOrg( + systemAccess.UID_PersonWantsOrg, + validFrom, + validUntil + ); + + logger.logInfo('System access updated in One Identity', { + UID_PersonWantsOrg: systemAccess.UID_PersonWantsOrg, + }); +} + +async function removeAccessFromOneIdentity( + oneIdentity: ESSOneIdentity, + visitId: string, uidPerson: UID_Person ) { // Find person wants orgs for the visitor @@ -141,8 +243,7 @@ async function removeAccessFromOneIdentity( const siteAccess = personWantsOrgs.find( (pwo) => pwo.DisplayOrg === PersonWantsOrgRole.SITE_ACCESS && - toIsoString(pwo.ValidFrom) === toIsoString(startAt) && - toIsoString(pwo.ValidUntil) === toIsoString(endAt) && + pwo.CustomProperty04 === visitId.toString() && // CustomProperty04 is the visit ID for the site access pwo.OrderState !== OrderState.ABORTED ); @@ -158,10 +259,10 @@ async function removeAccessFromOneIdentity( UID_PersonWantsOrg: siteAccess.UID_PersonWantsOrg, }); - // Find system access for the site access (CustomProperty04 is the site access UID) + // Find system access for the site access (CustomProperty04 is the visit ID) const systemAccess = personWantsOrgs.find( (pwo) => - pwo.CustomProperty04 === siteAccess.UID_PersonWantsOrg && + pwo.CustomProperty04 === visitId.toString() && pwo.DisplayOrg === PersonWantsOrgRole.SYSTEM_ACCESS && pwo.OrderState !== OrderState.UNSUBSCRIBED ); @@ -244,3 +345,14 @@ function toIsoString(date: string | number) { return parsedDate.toISOString(); } + +function isSameDateTime(left: string, right: string) { + const leftTime = new Date(left).getTime(); + const rightTime = new Date(right).getTime(); + + if (isNaN(leftTime) || isNaN(rightTime)) { + return left === right; + } + + return leftTime === rightTime; +} diff --git a/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts b/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts index ad79a121..17ab4cc5 100644 --- a/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts +++ b/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts @@ -166,6 +166,21 @@ export class ESSOneIdentity { return res.Data; } + public async updatePersonWantsOrg( + uidPersonWantsOrg: string, + startDate: string, + endDate: string + ): Promise { + await this.oneIdentityApi.updateEntity( + 'PersonWantsOrg', + uidPersonWantsOrg, + { + ValidFrom: startDate, + ValidUntil: endDate, + } + ); + } + public async cancelPersonWantsOrg(uidPersonWantsOrg: string): Promise { const res = await this.oneIdentityApi.callScript( diff --git a/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts b/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts index 20c2045b..90e63fb1 100644 --- a/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts +++ b/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts @@ -87,6 +87,18 @@ export class OneIdentityApi { return data; } + public async updateEntity( + table: string, + uid: string, + values: Partial + ): Promise { + const { data } = await this.axiosInstance.put(`/entity/${table}/${uid}`, { + values, + }); + + return data; + } + public async getEntities( table: string, where: string, diff --git a/src/queue/consumers/oneidentity/utils/interfaces/VisitMessage.ts b/src/queue/consumers/oneidentity/utils/interfaces/VisitMessage.ts index ce180475..d273cfad 100644 --- a/src/queue/consumers/oneidentity/utils/interfaces/VisitMessage.ts +++ b/src/queue/consumers/oneidentity/utils/interfaces/VisitMessage.ts @@ -1,6 +1,7 @@ import { ProposalMessageData } from '../../../../../models/ProposalMessage'; export interface VisitMessage { + id: string; startAt: string; endAt: string; visitorId: string; From 3a0fd9cc825c2c399087bbbc4b12ef152dc60b4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 07:49:29 +0000 Subject: [PATCH 07/30] fix: apply buffer days to system access ValidUntil on update (same as creation) Agent-Logs-Url: https://github.com/UserOfficeProject/connector/sessions/18fd40a2-d897-4c0f-a140-94c2adc14acd --- package-lock.json | 20 ++----------------- .../syncVisitToOneIdentityHandler.spec.ts | 11 ++++++++-- .../syncVisitToOneIdentityHandler.ts | 8 +++++++- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index f39edfdc..4365c8d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -183,7 +183,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", "dev": true, - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", @@ -1674,7 +1673,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.16.1", @@ -2029,7 +2027,6 @@ "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2520,7 +2517,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001503", "electron-to-chromium": "^1.4.431", @@ -3487,7 +3483,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -3543,7 +3538,6 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -5171,7 +5165,6 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -7277,7 +7270,6 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -9077,7 +9069,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", "dev": true, - "peer": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", @@ -10275,7 +10266,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, - "peer": true, "requires": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.16.1", @@ -10486,8 +10476,7 @@ "acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "peer": true + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" }, "acorn-jsx": { "version": "5.3.2", @@ -10846,7 +10835,6 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, - "peer": true, "requires": { "caniuse-lite": "^1.0.30001503", "electron-to-chromium": "^1.4.431", @@ -11513,7 +11501,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, - "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -11572,7 +11559,6 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "peer": true, "requires": {} }, "eslint-import-resolver-node": { @@ -12690,7 +12676,6 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "peer": true, "requires": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -14162,8 +14147,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "peer": true + "dev": true }, "prettier-linter-helpers": { "version": "1.0.0", diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts index 6e5e5c33..38a0c8fc 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts @@ -690,12 +690,19 @@ describe('syncVisitToOneIdentityHandler', () => { } ); - // Verify system access update + // Verify system access update (ValidUntil extended by ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) + const expectedSystemAccessValidUntil = new Date( + '2023-02-15T00:00:00.000Z' + ); + expectedSystemAccessValidUntil.setDate( + expectedSystemAccessValidUntil.getDate() + + parseInt(ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) + ); expect(mockOneIdentity.updatePersonWantsOrg).toHaveBeenNthCalledWith( 2, 'system-access-uid', '2023-02-01T00:00:00.000Z', - '2023-02-15T00:00:00.000Z' + expectedSystemAccessValidUntil.toISOString() ); expect(logger.logInfo).toHaveBeenCalledWith( 'System access updated in One Identity', diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index 699a4c9d..ebdbae4e 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -220,10 +220,16 @@ async function updateAccessInOneIdentity( ); } + const systemAccessValidUntil = toIsoString( + new Date(endAt).setDate( + new Date(endAt).getDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS + ) + ); + await oneIdentity.updatePersonWantsOrg( systemAccess.UID_PersonWantsOrg, validFrom, - validUntil + systemAccessValidUntil ); logger.logInfo('System access updated in One Identity', { From e71e4300f5c10cc1717607110e310a3fd1eea26c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 07:51:56 +0000 Subject: [PATCH 08/30] fix: update axios to 1.15.2 to address security vulnerabilities Agent-Logs-Url: https://github.com/UserOfficeProject/connector/sessions/18fd40a2-d897-4c0f-a140-94c2adc14acd --- package-lock.json | 67 +++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4365c8d8..0a1d6966 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.2.1", "@user-office-software/duo-message-broker": "^1.7.0", - "axios": "^1.12.0", + "axios": "^1.15.2", "dotenv": "^16.4.5", "envalid": "^8.0.0", "express": "^4.21.2", @@ -2316,14 +2316,14 @@ } }, "node_modules/axios": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz", - "integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" } }, "node_modules/babel-jest": { @@ -4192,15 +4192,16 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -4220,9 +4221,9 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -7356,9 +7357,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/punycode": { "version": "2.3.1", @@ -10680,13 +10685,13 @@ } }, "axios": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz", - "integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" } }, "babel-jest": { @@ -12031,9 +12036,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==" }, "for-each": { "version": "0.3.3", @@ -12045,9 +12050,9 @@ } }, "form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -14206,9 +14211,9 @@ } }, "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==" }, "punycode": { "version": "2.3.1", diff --git a/package.json b/package.json index f1291f4b..451a14e9 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.2.1", "@user-office-software/duo-message-broker": "^1.7.0", - "axios": "^1.12.0", + "axios": "^1.15.2", "dotenv": "^16.4.5", "envalid": "^8.0.0", "express": "^4.21.2", From c5285798531542288bf24eca066e4b6a3513cc94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 07:57:21 +0000 Subject: [PATCH 09/30] fix: address review comments - fix updateEntity return type and revert log message Agent-Logs-Url: https://github.com/UserOfficeProject/connector/sessions/f8cb93b2-b131-43ba-990b-ee3d9d8f436a --- src/index.ts | 2 +- src/queue/consumers/oneidentity/utils/OneIdentityApi.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 17c2fb64..23409f92 100644 --- a/src/index.ts +++ b/src/index.ts @@ -71,7 +71,7 @@ async function bootstrap() { logger.logException('Unhandled NODE exception', error); }); - logger.logInfo(`Running connector services at localhost:${PORT}`, {}); + logger.logInfo(`Running connector service at localhost:${PORT}`, {}); if ( enableScicatProposalUpsert || diff --git a/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts b/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts index 90e63fb1..3f50561f 100644 --- a/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts +++ b/src/queue/consumers/oneidentity/utils/OneIdentityApi.ts @@ -92,11 +92,9 @@ export class OneIdentityApi { uid: string, values: Partial ): Promise { - const { data } = await this.axiosInstance.put(`/entity/${table}/${uid}`, { + await this.axiosInstance.put(`/entity/${table}/${uid}`, { values, }); - - return data; } public async getEntities( From 9a80d149c71f63fbda5c6568afc7f886e641cfb2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 09:08:47 +0000 Subject: [PATCH 10/30] Validate system access exists before updating site access in One Identity Agent-Logs-Url: https://github.com/UserOfficeProject/connector/sessions/52158ce8-921e-46bd-a6bd-f72851eba47b --- .../syncVisitToOneIdentityHandler.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index ce5ba86d..e2c862b0 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -181,6 +181,20 @@ async function updateAccessInOneIdentity( const validFrom = toIsoString(startAt); const validUntil = toIsoString(endAt); + // Find system access for the site access (CustomProperty04 is the visit ID) + const systemAccess = personWantsOrgs.find( + (pwo) => + pwo.CustomProperty04 === visitId.toString() && + pwo.DisplayOrg === PersonWantsOrgRole.SYSTEM_ACCESS && + pwo.OrderState !== OrderState.UNSUBSCRIBED + ); + + if (!systemAccess) { + throw new Error( + 'System access not found in One Identity, cannot update access' + ); + } + if ( isSameDateTime(siteAccess.ValidFrom, validFrom) && isSameDateTime(siteAccess.ValidUntil, validUntil) @@ -206,20 +220,6 @@ async function updateAccessInOneIdentity( UID_PersonWantsOrg: siteAccess.UID_PersonWantsOrg, }); - // Find system access for the site access (CustomProperty04 is the visit ID) - const systemAccess = personWantsOrgs.find( - (pwo) => - pwo.CustomProperty04 === visitId.toString() && - pwo.DisplayOrg === PersonWantsOrgRole.SYSTEM_ACCESS && - pwo.OrderState !== OrderState.UNSUBSCRIBED - ); - - if (!systemAccess) { - throw new Error( - 'System access not found in One Identity, cannot update access' - ); - } - const systemAccessValidUntil = toIsoString( new Date(endAt).setDate( new Date(endAt).getDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS From fa174e7779afd285590410942c43cf40f86f1640 Mon Sep 17 00:00:00 2001 From: Yoganandan Pandiyan Date: Tue, 26 May 2026 11:43:33 +0200 Subject: [PATCH 11/30] fix: remove unnecessary toString conversion for visitId in access handling functions --- .../syncVisitToOneIdentityHandler.ts | 12 ++++++------ .../oneidentity/utils/isVisitMessage.spec.ts | 13 +++++++++++++ .../consumers/oneidentity/utils/isVisitMessage.ts | 1 + 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index e2c862b0..cc363d54 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -114,7 +114,7 @@ async function createAccessInOneIdentity( centralAccount, toIsoString(startAt), toIsoString(endAt), - visitId.toString() // CustomProperty04 - We store the visit ID for the site access to be able to find it later + visitId // CustomProperty04 - We store the visit ID for the site access to be able to find it later ); logger.logInfo('Site access created in One Identity', { @@ -133,7 +133,7 @@ async function createAccessInOneIdentity( centralAccount, toIsoString(validFrom), toIsoString(validUntil), - visitId.toString() // CustomProperty04 - We store the visit ID for the system access to be able to find it later + visitId // CustomProperty04 - We store the visit ID for the system access to be able to find it later ); logger.logInfo('System access created in One Identity', { @@ -156,7 +156,7 @@ async function updateAccessInOneIdentity( const siteAccess = personWantsOrgs.find( (pwo) => pwo.DisplayOrg === PersonWantsOrgRole.SITE_ACCESS && - pwo.CustomProperty04 === visitId.toString() && // CustomProperty04 is the visit ID for the site access + pwo.CustomProperty04 === visitId && // CustomProperty04 is the visit ID for the site access pwo.OrderState !== OrderState.ABORTED ); @@ -184,7 +184,7 @@ async function updateAccessInOneIdentity( // Find system access for the site access (CustomProperty04 is the visit ID) const systemAccess = personWantsOrgs.find( (pwo) => - pwo.CustomProperty04 === visitId.toString() && + pwo.CustomProperty04 === visitId && pwo.DisplayOrg === PersonWantsOrgRole.SYSTEM_ACCESS && pwo.OrderState !== OrderState.UNSUBSCRIBED ); @@ -249,7 +249,7 @@ async function removeAccessFromOneIdentity( const siteAccess = personWantsOrgs.find( (pwo) => pwo.DisplayOrg === PersonWantsOrgRole.SITE_ACCESS && - pwo.CustomProperty04 === visitId.toString() && // CustomProperty04 is the visit ID for the site access + pwo.CustomProperty04 === visitId && // CustomProperty04 is the visit ID for the site access pwo.OrderState !== OrderState.ABORTED ); @@ -268,7 +268,7 @@ async function removeAccessFromOneIdentity( // Find system access for the site access (CustomProperty04 is the visit ID) const systemAccess = personWantsOrgs.find( (pwo) => - pwo.CustomProperty04 === visitId.toString() && + pwo.CustomProperty04 === visitId && pwo.DisplayOrg === PersonWantsOrgRole.SYSTEM_ACCESS && pwo.OrderState !== OrderState.UNSUBSCRIBED ); diff --git a/src/queue/consumers/oneidentity/utils/isVisitMessage.spec.ts b/src/queue/consumers/oneidentity/utils/isVisitMessage.spec.ts index 5f7c0d78..9c593de2 100644 --- a/src/queue/consumers/oneidentity/utils/isVisitMessage.spec.ts +++ b/src/queue/consumers/oneidentity/utils/isVisitMessage.spec.ts @@ -44,8 +44,21 @@ describe('isVisitMessage', () => { expect(isVisitMessage(message)).toBe(false); }); + it('should return false if id is undefined', () => { + const message = { + visitorId: 'visitor123', + startAt: '2023-01-01T00:00:00Z', + endAt: '2023-01-02T00:00:00Z', + proposal: { + shortCode: 'proposal-short-code', + }, + }; + expect(isVisitMessage(message)).toBe(false); + }); + it('should return true if the message is valid', () => { const message = { + id: 'visit123', visitorId: 'visitor123', startAt: '2023-01-01T00:00:00Z', endAt: '2023-01-02T00:00:00Z', diff --git a/src/queue/consumers/oneidentity/utils/isVisitMessage.ts b/src/queue/consumers/oneidentity/utils/isVisitMessage.ts index ed7cb282..167dcc1a 100644 --- a/src/queue/consumers/oneidentity/utils/isVisitMessage.ts +++ b/src/queue/consumers/oneidentity/utils/isVisitMessage.ts @@ -4,6 +4,7 @@ export function isVisitMessage(message: any): message is VisitMessage { return ( message != null && typeof message === 'object' && + 'id' in message && 'visitorId' in message && 'startAt' in message && 'endAt' in message && From e2b37581bcd27e8c302049932879cd990e64dc47 Mon Sep 17 00:00:00 2001 From: Yoganandan Pandiyan Date: Tue, 26 May 2026 14:23:40 +0200 Subject: [PATCH 12/30] refactor: replace createPersonWantsOrg and updatePersonWantsOrg with upsertPersonWantsOrg in One Identity handlers --- ...osalAndMembersToOneIdentityHandler.spec.ts | 3 +- .../syncVisitToOneIdentityHandler.spec.ts | 48 ++++++++++--------- .../syncVisitToOneIdentityHandler.ts | 22 +++++---- .../oneidentity/utils/ESSOneIdentity.spec.ts | 6 +-- .../oneidentity/utils/ESSOneIdentity.ts | 22 ++------- 5 files changed, 47 insertions(+), 54 deletions(-) diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts index f23a67af..60d14aa8 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncProposalAndMembersToOneIdentityHandler.spec.ts @@ -25,8 +25,7 @@ const mockOneIdentity: jest.Mocked> = { getProposalPersonConnections: jest.fn(), removeConnectionBetweenPersonAndProposal: jest.fn(), getPersonWantsOrg: jest.fn(), - createPersonWantsOrg: jest.fn(), - updatePersonWantsOrg: jest.fn(), + upsertPersonWantsOrg: jest.fn(), cancelPersonWantsOrg: jest.fn(), hasPersonSiteAccessToProposal: jest.fn(), }; diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts index 7a1a41c5..15b3d0b1 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts @@ -37,8 +37,7 @@ const mockOneIdentity: jest.Mocked> = { connectPersonToProposal: jest.fn(), getProposalPersonConnections: jest.fn(), removeConnectionBetweenPersonAndProposal: jest.fn(), - createPersonWantsOrg: jest.fn(), - updatePersonWantsOrg: jest.fn(), + upsertPersonWantsOrg: jest.fn(), cancelPersonWantsOrg: jest.fn(), hasPersonSiteAccessToProposal: jest.fn(), }; @@ -107,7 +106,7 @@ describe('syncVisitToOneIdentityHandler', () => { 'Visitor is not a Science User, skipping', {} ); - expect(mockOneIdentity.createPersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.upsertPersonWantsOrg).not.toHaveBeenCalled(); expect(mockOneIdentity.logout).toHaveBeenCalled(); }); }); @@ -138,7 +137,7 @@ describe('syncVisitToOneIdentityHandler', () => { mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([]); // No existing connection // Mock sequential calls to createPersonWantsOrg with different responses - mockOneIdentity.createPersonWantsOrg + mockOneIdentity.upsertPersonWantsOrg .mockResolvedValueOnce([mockSiteAccess]) .mockResolvedValueOnce([mockSystemAccess]); @@ -156,8 +155,8 @@ describe('syncVisitToOneIdentityHandler', () => { ); // Verify site access creation - expect(mockOneIdentity.createPersonWantsOrg).toHaveBeenCalledTimes(2); - expect(mockOneIdentity.createPersonWantsOrg).toHaveBeenNthCalledWith( + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenCalledTimes(2); + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 1, PersonWantsOrgRole.SITE_ACCESS, visitMessage.visitorId, @@ -176,7 +175,7 @@ describe('syncVisitToOneIdentityHandler', () => { ); // Verify system access creation - expect(mockOneIdentity.createPersonWantsOrg).toHaveBeenNthCalledWith( + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 2, PersonWantsOrgRole.SYSTEM_ACCESS, visitMessage.visitorId, @@ -233,7 +232,7 @@ describe('syncVisitToOneIdentityHandler', () => { mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([ { UID_Person: mockPerson.UID_Person, UID_ESet: mockUidESet }, ]); // Connection exists - mockOneIdentity.createPersonWantsOrg + mockOneIdentity.upsertPersonWantsOrg .mockResolvedValueOnce([mockSiteAccess]) .mockResolvedValueOnce([mockSystemAccess]); @@ -272,7 +271,7 @@ describe('syncVisitToOneIdentityHandler', () => { expect(mockOneIdentity.getProposal).toHaveBeenCalledWith( visitMessage.proposal ); - expect(mockOneIdentity.createPersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.upsertPersonWantsOrg).not.toHaveBeenCalled(); expect(mockOneIdentity.logout).toHaveBeenCalled(); }); @@ -285,7 +284,7 @@ describe('syncVisitToOneIdentityHandler', () => { mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); mockOneIdentity.getProposal.mockResolvedValueOnce(mockUidESet); - mockOneIdentity.createPersonWantsOrg.mockRejectedValueOnce( + mockOneIdentity.upsertPersonWantsOrg.mockRejectedValueOnce( new Error('Failed to create site access') ); @@ -324,7 +323,7 @@ describe('syncVisitToOneIdentityHandler', () => { expect(mockOneIdentity.getPerson).toHaveBeenCalledWith( 'visitor-oidc-sub' ); - expect(mockOneIdentity.createPersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.upsertPersonWantsOrg).not.toHaveBeenCalled(); expect(mockOneIdentity.logout).toHaveBeenCalled(); }); }); @@ -744,11 +743,14 @@ describe('syncVisitToOneIdentityHandler', () => { ); // Verify site access update - expect(mockOneIdentity.updatePersonWantsOrg).toHaveBeenNthCalledWith( + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 1, - 'site-access-uid', + PersonWantsOrgRole.SITE_ACCESS, + 'visitor-oidc-sub', '2023-02-01T00:00:00.000Z', - '2023-02-15T00:00:00.000Z' + '2023-02-15T00:00:00.000Z', + '1', + 'site-access-uid' ); expect(logger.logInfo).toHaveBeenCalledWith( 'Site access updated in One Identity', @@ -765,11 +767,14 @@ describe('syncVisitToOneIdentityHandler', () => { expectedSystemAccessValidUntil.getDate() + parseInt(ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS) ); - expect(mockOneIdentity.updatePersonWantsOrg).toHaveBeenNthCalledWith( + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenNthCalledWith( 2, - 'system-access-uid', + PersonWantsOrgRole.SYSTEM_ACCESS, + 'visitor-oidc-sub', '2023-02-01T00:00:00.000Z', - expectedSystemAccessValidUntil.toISOString() + expectedSystemAccessValidUntil.toISOString(), + '1', + 'system-access-uid' ); expect(logger.logInfo).toHaveBeenCalledWith( 'System access updated in One Identity', @@ -828,7 +833,7 @@ describe('syncVisitToOneIdentityHandler', () => { ); // Verify no update occurred - expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenCalledTimes(0); expect(logger.logInfo).toHaveBeenCalledWith( 'Visit dates unchanged, skipping access update in One Identity', { @@ -861,7 +866,7 @@ describe('syncVisitToOneIdentityHandler', () => { mockOneIdentity.getPerson.mockResolvedValueOnce(mockPerson); mockOneIdentity.getProposal.mockResolvedValueOnce(mockUidESet); mockOneIdentity.getPersonWantsOrg.mockResolvedValueOnce([]); // No existing access - mockOneIdentity.createPersonWantsOrg + mockOneIdentity.upsertPersonWantsOrg .mockResolvedValueOnce([mockSiteAccess]) .mockResolvedValueOnce([mockSystemAccess]); mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([]); // No existing connection @@ -885,8 +890,7 @@ describe('syncVisitToOneIdentityHandler', () => { ); // Verify creation occurred instead of update - expect(mockOneIdentity.createPersonWantsOrg).toHaveBeenCalledTimes(2); - expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); + expect(mockOneIdentity.upsertPersonWantsOrg).toHaveBeenCalledTimes(2); expect(mockOneIdentity.connectPersonToProposal).toHaveBeenCalledWith( mockUidESet, @@ -957,7 +961,6 @@ describe('syncVisitToOneIdentityHandler', () => { {} ); expect(mockOneIdentity.getPersonWantsOrg).not.toHaveBeenCalled(); - expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); expect(mockOneIdentity.logout).toHaveBeenCalled(); }); @@ -983,7 +986,6 @@ describe('syncVisitToOneIdentityHandler', () => { expect(mockOneIdentity.getProposal).toHaveBeenCalledWith( visitMessage.proposal ); - expect(mockOneIdentity.updatePersonWantsOrg).not.toHaveBeenCalled(); expect(mockOneIdentity.logout).toHaveBeenCalled(); }); diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index cc363d54..d0a2d382 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -109,7 +109,7 @@ async function createAccessInOneIdentity( centralAccount: string ) { // Create site access - const [pwoSite] = await oneIdentity.createPersonWantsOrg( + const [pwoSite] = await oneIdentity.upsertPersonWantsOrg( PersonWantsOrgRole.SITE_ACCESS, centralAccount, toIsoString(startAt), @@ -128,7 +128,7 @@ async function createAccessInOneIdentity( ); // Create system access - const [pwoSystem] = await oneIdentity.createPersonWantsOrg( + const [pwoSystem] = await oneIdentity.upsertPersonWantsOrg( PersonWantsOrgRole.SYSTEM_ACCESS, centralAccount, toIsoString(validFrom), @@ -210,10 +210,13 @@ async function updateAccessInOneIdentity( return; } - await oneIdentity.updatePersonWantsOrg( - siteAccess.UID_PersonWantsOrg, + await oneIdentity.upsertPersonWantsOrg( + PersonWantsOrgRole.SITE_ACCESS, + centralAccount, validFrom, - validUntil + validUntil, + visitId, + siteAccess.UID_PersonWantsOrg ); logger.logInfo('Site access updated in One Identity', { @@ -226,10 +229,13 @@ async function updateAccessInOneIdentity( ) ); - await oneIdentity.updatePersonWantsOrg( - systemAccess.UID_PersonWantsOrg, + await oneIdentity.upsertPersonWantsOrg( + PersonWantsOrgRole.SYSTEM_ACCESS, + centralAccount, validFrom, - systemAccessValidUntil + systemAccessValidUntil, + visitId, + systemAccess.UID_PersonWantsOrg ); logger.logInfo('System access updated in One Identity', { diff --git a/src/queue/consumers/oneidentity/utils/ESSOneIdentity.spec.ts b/src/queue/consumers/oneidentity/utils/ESSOneIdentity.spec.ts index 918e09f2..05fa8b71 100644 --- a/src/queue/consumers/oneidentity/utils/ESSOneIdentity.spec.ts +++ b/src/queue/consumers/oneidentity/utils/ESSOneIdentity.spec.ts @@ -310,7 +310,7 @@ describe('ESSOneIdentity', () => { Message: 'Success', }); - const result = await essOneIdentity.createPersonWantsOrg( + const result = await essOneIdentity.upsertPersonWantsOrg( role, centralAccount, startDate, @@ -332,7 +332,7 @@ describe('ESSOneIdentity', () => { Message: 'Success', }); - const result = await essOneIdentity.createPersonWantsOrg( + const result = await essOneIdentity.upsertPersonWantsOrg( role, centralAccount, startDate, @@ -364,7 +364,7 @@ describe('ESSOneIdentity', () => { }); await expect( - essOneIdentity.createPersonWantsOrg( + essOneIdentity.upsertPersonWantsOrg( role, centralAccount, startDate, diff --git a/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts b/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts index 85ab0f5d..8b993f65 100644 --- a/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts +++ b/src/queue/consumers/oneidentity/utils/ESSOneIdentity.ts @@ -139,12 +139,13 @@ export class ESSOneIdentity { return entities.map(({ values }) => values); } - public async createPersonWantsOrg( + public async upsertPersonWantsOrg( role: PersonWantsOrgRole, centralAccount: string, startDate: string, endDate: string, - customData: string = '' + customData: string = '', + uidPersonWantsOrg: string = '' ): Promise { const res = await this.oneIdentityApi.callScript( @@ -156,7 +157,7 @@ export class ESSOneIdentity { startDate, endDate, customData, // PersonWantsOrg.CustomProperty04 - '', // UID_PersonWantsOrg (empty for new) + uidPersonWantsOrg, // UID_PersonWantsOrg (empty for new, provided for update) ] ); @@ -166,21 +167,6 @@ export class ESSOneIdentity { return res.Data; } - public async updatePersonWantsOrg( - uidPersonWantsOrg: string, - startDate: string, - endDate: string - ): Promise { - await this.oneIdentityApi.updateEntity( - 'PersonWantsOrg', - uidPersonWantsOrg, - { - ValidFrom: startDate, - ValidUntil: endDate, - } - ); - } - public async cancelPersonWantsOrg(uidPersonWantsOrg: string): Promise { const res = await this.oneIdentityApi.callScript( From 4263c658da5b506f9e8a45c9e57c9079a178e32f Mon Sep 17 00:00:00 2001 From: Yoganandan Pandiyan Date: Tue, 26 May 2026 14:33:04 +0200 Subject: [PATCH 13/30] fix: mock Date.now for system access update and use it in upsertPersonWantsOrg --- .../consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts | 6 +++++- .../consumerCallbacks/syncVisitToOneIdentityHandler.ts | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts index 15b3d0b1..34219cd3 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.spec.ts @@ -722,6 +722,10 @@ describe('syncVisitToOneIdentityHandler', () => { ); mockOneIdentity.getProposalPersonConnections.mockResolvedValueOnce([]); // No existing connection + // Mock Date.now for system access update (same as creation logic) + const mockNowDate = new Date(); + Date.now = jest.fn(() => mockNowDate.getTime()); + // Updated visit message with new dates const updatedVisitMessage: VisitMessage = { ...visitMessage, @@ -771,7 +775,7 @@ describe('syncVisitToOneIdentityHandler', () => { 2, PersonWantsOrgRole.SYSTEM_ACCESS, 'visitor-oidc-sub', - '2023-02-01T00:00:00.000Z', + mockNowDate.toISOString(), expectedSystemAccessValidUntil.toISOString(), '1', 'system-access-uid' diff --git a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts index d0a2d382..8fb9599a 100644 --- a/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts +++ b/src/queue/consumers/oneidentity/consumerCallbacks/syncVisitToOneIdentityHandler.ts @@ -223,6 +223,7 @@ async function updateAccessInOneIdentity( UID_PersonWantsOrg: siteAccess.UID_PersonWantsOrg, }); + const systemAccessValidFrom = toIsoString(Date.now()); const systemAccessValidUntil = toIsoString( new Date(endAt).setDate( new Date(endAt).getDate() + ONE_IDENTITY_SYSTEM_ACCESS_LASTS_FOR_DAYS @@ -232,7 +233,7 @@ async function updateAccessInOneIdentity( await oneIdentity.upsertPersonWantsOrg( PersonWantsOrgRole.SYSTEM_ACCESS, centralAccount, - validFrom, + systemAccessValidFrom, systemAccessValidUntil, visitId, systemAccess.UID_PersonWantsOrg From a324becbdceb352fe861004389d25c2492072830 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 26 May 2026 15:53:31 +0200 Subject: [PATCH 14/30] fix: use proposalId for permission check (#684) --- .env.tests | 1 + README.md | 2 +- .../uoToScicatExperiment.mapper.spec.ts.snap | 6 +++--- .../scicatProposal/mappers/uoToScicatExperiment.mapper.ts | 8 ++++---- .../scicat/scicatProposal/utils/scicatApi.spec.ts | 2 ++ .../consumers/scicat/scicatProposal/utils/scicatApi.ts | 7 +++++++ 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.env.tests b/.env.tests index b335d6f4..57c87a1d 100644 --- a/.env.tests +++ b/.env.tests @@ -12,6 +12,7 @@ KAFKA_TOPIC=TestTopic SCICAT_BASE_URL=http://localhost/some/api SCICAT_JWT=eyJhbGciOiJIUzI1NiIsInR5 SCICAT_PROPOSAL_TRIGGERING_STATUSES="SCHEDULING, ALLOCATED" +SCICAT_EXPERIMENT_TRIGGERING_STATUSES="ACTIVE" USER_OFFICE_GRAPHQL_URL=http://localhost:8080 USER_OFFICE_JWT=some-token diff --git a/README.md b/README.md index 3c673db8..f3585d1f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Connector -The connector connects other services through the message queue. +The connector connects other services through the message queue # Requirements This service requires node >=22.0.0 diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap b/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap index cbe13f31..da2fb085 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap +++ b/src/queue/consumers/scicat/scicatProposal/mappers/__snapshots__/uoToScicatExperiment.mapper.spec.ts.snap @@ -6,7 +6,7 @@ exports[`getCreateScicatExperimentDto includes visitor entries when registration "abstract": "Experiment 158548-3 Test Abstract", "accessGroups": [ - "158548-3", + "158548", ], "email": "john.doe@example.com", "endTime": 2026-10-03T07:00:00.000Z, @@ -67,7 +67,7 @@ exports[`getCreateScicatExperimentDto maps experiment to create DTO correctly 1` "abstract": "Experiment 158548-3 Test Abstract", "accessGroups": [ - "158548-3", + "158548", ], "email": "john.doe@example.com", "endTime": 2026-10-03T07:00:00.000Z, @@ -112,7 +112,7 @@ exports[`getUpdateScicatExperimentDto maps experiment to update DTO correctly 1` "abstract": "Experiment 158548-3 Test Abstract", "accessGroups": [ - "158548-3", + "158548", ], "email": "john.doe@example.com", "endTime": 2026-10-03T07:00:00.000Z, diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts index 6eb955db..673ed3cd 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts @@ -92,7 +92,7 @@ export const getCreateScicatExperimentDto = ( pi_email: proposer.email, instrumentIds, ownerGroup: scicatApi.serviceUsername || '', - accessGroups: [experimentId], + accessGroups: [proposal.proposalId], startTime: new Date(experiment.startsAt), endTime: new Date(experiment.endsAt), MeasurementPeriodList: [], @@ -120,7 +120,7 @@ export const getUpdateScicatExperimentDto = ( pi_email: proposer.email, instrumentIds, ownerGroup: scicatApi.serviceUsername, - accessGroups: [experimentId], + accessGroups: [proposal.proposalId], startTime: new Date(experiment.startsAt), endTime: new Date(experiment.endsAt), MeasurementPeriodList: [], @@ -180,7 +180,7 @@ export const getCreateScicatSampleDto = ( const dto = { ownerGroup: scicatApi.serviceUsername || '', type: 'Sample Information', - accessGroups: [experiment.experimentId], + accessGroups: [experiment.proposal.proposalId], proposalId: experiment.experimentId, sampleName: sample.sample.title, isPublished: false, @@ -201,7 +201,7 @@ export const getUpdateScicatSampleDto = ( const sampleCharacteristics = buildSampleCharacteristics(sample, experiment); const dto = { ownerGroup: scicatApi.serviceUsername || '', - accessGroups: [experiment.experimentId], + accessGroups: [experiment.proposal.proposalId], proposalId: experiment.experimentId, sampleName: sample.sample.title, isPublished: false, diff --git a/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts index 4f7edade..352f756f 100644 --- a/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts +++ b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.spec.ts @@ -1,5 +1,7 @@ describe('ScicatApi', () => { it('should initialize with correct serviceUsername', () => { + process.env.ENABLE_SCICAT_PROPOSAL_UPSERT = 'true'; + process.env.ENABLE_SCICAT_EXPERIMENT_UPSERT = 'true'; process.env.SCICAT_BASE_URL = 'http://localhost:3000'; process.env.SCICAT_JWT = 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3R1c2VyIn0.signature'; diff --git a/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts index ec4e6a01..dcc7a631 100644 --- a/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts +++ b/src/queue/consumers/scicat/scicatProposal/utils/scicatApi.ts @@ -27,6 +27,13 @@ class ScicatApi { readonly serviceUsername: string; constructor() { + if ( + !process.env.ENABLE_SCICAT_PROPOSAL_UPSERT && + !process.env.ENABLE_SCICAT_EXPERIMENT_UPSERT + ) { + return; + } + if (!this.baseUrl) { throw new Error('SCICAT_BASE_URL is not defined'); } From fe851de757aa85cf49c87954b7397c50a7e32945 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 27 May 2026 16:11:34 +0200 Subject: [PATCH 15/30] fix: update getProposal graphQl query (#685) --- src/services/userOfficeApi/queries/getProposal.query.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/userOfficeApi/queries/getProposal.query.ts b/src/services/userOfficeApi/queries/getProposal.query.ts index 4eba4090..dd8b7c5d 100644 --- a/src/services/userOfficeApi/queries/getProposal.query.ts +++ b/src/services/userOfficeApi/queries/getProposal.query.ts @@ -78,7 +78,6 @@ fragment proposal on Proposal { fragment status on Status { id - shortCode name description isDefault From 7dd9e1c4163ee70c3056670b9fccb023c0100531 Mon Sep 17 00:00:00 2001 From: Jay Date: Fri, 29 May 2026 12:30:07 +0200 Subject: [PATCH 16/30] fix: remove shortCode from UOStatus type (#686) --- .../scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts | 2 +- .../scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts | 2 +- src/services/userOfficeApi/queries/getExperiment.query.ts | 1 - src/services/userOfficeApi/type/uoProposal.type.ts | 3 +-- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts index f50ed7fe..118e7f36 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts @@ -26,7 +26,7 @@ const createBaseUoExperiment = ( proposalId: '158548', title: 'Test Proposal', abstract: 'Test Abstract', - status: { id: 1, shortCode: 'ALLOCATED', name: 'ALLOCATED' }, + status: { id: 'ALLOCATED', name: 'ALLOCATED' }, proposer: { id: 1, firstname: 'John', diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts index 9800bba8..cf5d2067 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.spec.ts @@ -10,7 +10,7 @@ const createBaseUoProposal = ( proposalId: '158548', title: 'Test Proposal', abstract: 'Test Abstract', - status: { id: 1, shortCode: 'ALLOCATED', name: 'ALLOCATED' }, + status: { id: 'ALLOCATED', name: 'ALLOCATED' }, proposer: { id: 1, firstname: 'John', diff --git a/src/services/userOfficeApi/queries/getExperiment.query.ts b/src/services/userOfficeApi/queries/getExperiment.query.ts index 68ba5612..3a3a62fa 100644 --- a/src/services/userOfficeApi/queries/getExperiment.query.ts +++ b/src/services/userOfficeApi/queries/getExperiment.query.ts @@ -83,7 +83,6 @@ fragment proposal on Proposal { fragment status on Status { id - shortCode name description isDefault diff --git a/src/services/userOfficeApi/type/uoProposal.type.ts b/src/services/userOfficeApi/type/uoProposal.type.ts index dc701d9c..9bea6a02 100644 --- a/src/services/userOfficeApi/type/uoProposal.type.ts +++ b/src/services/userOfficeApi/type/uoProposal.type.ts @@ -35,8 +35,7 @@ export interface UOCall { } export interface UOStatus { - id: number; - shortCode: string; + id: string; name: string; description?: string; } From db29bf5df968bf218cbcff8bb12e8500d546de80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 15:59:22 +0000 Subject: [PATCH 17/30] build(deps): bump axios from 1.15.2 to 1.16.0 Bumps [axios](https://github.com/axios/axios) from 1.15.2 to 1.16.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.15.2...v1.16.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.16.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95a6229f..1c1a8f53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", - "axios": "^1.15.2", + "axios": "^1.16.0", "dotenv": "^17.3.1", "envalid": "^8.1.1", "express": "^5.2.1", @@ -3104,12 +3104,12 @@ } }, "node_modules/axios": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", - "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } @@ -12778,11 +12778,11 @@ } }, "axios": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", - "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "requires": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } diff --git a/package.json b/package.json index 91b98028..f2a29308 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", - "axios": "^1.15.2", + "axios": "^1.16.0", "dotenv": "^17.3.1", "envalid": "^8.1.1", "express": "^5.2.1", From 75cde66bf8be671cbc61904b158a2e95dea8a9f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 16:34:33 +0000 Subject: [PATCH 18/30] build(deps-dev): bump ts-jest from 29.4.6 to 29.4.11 Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.4.6 to 29.4.11. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.4.6...v29.4.11) --- updated-dependencies: - dependency-name: ts-jest dependency-version: 29.4.11 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 36 ++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c1a8f53..3c231740 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "jest": "^30.3.0", "lint-staged": "^17.0.5", "prettier": "3.8.1", - "ts-jest": "^29.4.6", + "ts-jest": "^29.4.11", "typescript": "^5.9.3" }, "engines": { @@ -8775,9 +8775,9 @@ } }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "dev": true, "license": "ISC", "bin": { @@ -9605,19 +9605,19 @@ } }, "node_modules/ts-jest": { - "version": "29.4.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", - "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "version": "29.4.11", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", + "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", "dev": true, "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", - "handlebars": "^4.7.8", + "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.3", + "semver": "^7.8.0", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -9634,7 +9634,7 @@ "babel-jest": "^29.0.0 || ^30.0.0", "jest": "^29.0.0 || ^30.0.0", "jest-util": "^29.0.0 || ^30.0.0", - "typescript": ">=4.3 <6" + "typescript": ">=4.3 <7" }, "peerDependenciesMeta": { "@babel/core": { @@ -16542,9 +16542,9 @@ "integrity": "sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw==" }, "semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "dev": true }, "send": { @@ -17086,18 +17086,18 @@ "requires": {} }, "ts-jest": { - "version": "29.4.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", - "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "version": "29.4.11", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", + "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", "dev": true, "requires": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", - "handlebars": "^4.7.8", + "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.3", + "semver": "^7.8.0", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, diff --git a/package.json b/package.json index f2a29308..0595a0e6 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "jest": "^30.3.0", "lint-staged": "^17.0.5", "prettier": "3.8.1", - "ts-jest": "^29.4.6", + "ts-jest": "^29.4.11", "typescript": "^5.9.3" }, "dependencies": { From dc11b002b19dab6f797d2d5c950083629cb5f9a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 16:40:42 +0000 Subject: [PATCH 19/30] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.57.1 to 8.60.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.60.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 544 ++++++++++++---------------------------------- package.json | 2 +- 2 files changed, 143 insertions(+), 403 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3c231740..03d360f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@types/jest": "^30.0.0", "@types/node": "^25.5.0", "@types/pg": "^8.20.0", - "@typescript-eslint/eslint-plugin": "^8.57.1", + "@typescript-eslint/eslint-plugin": "^8.60.1", "@typescript-eslint/parser": "^8.59.1", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", @@ -1915,20 +1915,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", + "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/type-utils": "8.60.1", + "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1938,9 +1938,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.1", + "@typescript-eslint/parser": "^8.60.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -1954,16 +1954,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz", - "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", + "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", "debug": "^4.4.3" }, "engines": { @@ -1978,146 +1978,6 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", - "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.1", - "@typescript-eslint/types": "^8.59.1", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", - "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", - "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", - "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", - "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.59.1", - "@typescript-eslint/tsconfig-utils": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", - "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.59.1", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/@typescript-eslint/parser/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2136,35 +1996,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/parser/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2173,14 +2004,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", + "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", + "@typescript-eslint/tsconfig-utils": "^8.60.1", + "@typescript-eslint/types": "^8.60.1", "debug": "^4.4.3" }, "engines": { @@ -2191,7 +2022,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service/node_modules/debug": { @@ -2220,14 +2051,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", + "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2238,9 +2069,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", + "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", "dev": true, "license": "MIT", "engines": { @@ -2251,21 +2082,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", + "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/utils": "8.60.1", "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2276,7 +2107,7 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils/node_modules/debug": { @@ -2305,9 +2136,9 @@ "license": "MIT" }, "node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", + "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", "dev": true, "license": "MIT", "engines": { @@ -2319,21 +2150,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", + "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/project-service": "8.60.1", + "@typescript-eslint/tsconfig-utils": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2343,7 +2174,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { @@ -2357,9 +2188,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -2388,13 +2219,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -2411,16 +2242,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", + "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2431,17 +2262,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", + "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/types": "8.60.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -9501,14 +9332,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -12084,19 +11915,19 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", + "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/type-utils": "8.60.1", + "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "dependencies": { "ignore": { @@ -12108,94 +11939,18 @@ } }, "@typescript-eslint/parser": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz", - "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", + "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", "debug": "^4.4.3" }, "dependencies": { - "@typescript-eslint/project-service": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", - "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", - "dev": true, - "requires": { - "@typescript-eslint/tsconfig-utils": "^8.59.1", - "@typescript-eslint/types": "^8.59.1", - "debug": "^4.4.3" - } - }, - "@typescript-eslint/scope-manager": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", - "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1" - } - }, - "@typescript-eslint/tsconfig-utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", - "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", - "dev": true, - "requires": {} - }, - "@typescript-eslint/types": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", - "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", - "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", - "dev": true, - "requires": { - "@typescript-eslint/project-service": "8.59.1", - "@typescript-eslint/tsconfig-utils": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", - "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.59.1", - "eslint-visitor-keys": "^5.0.0" - } - }, - "balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true - }, - "brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "dev": true, - "requires": { - "balanced-match": "^4.0.2" - } - }, "debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -12205,21 +11960,6 @@ "ms": "^2.1.3" } }, - "eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true - }, - "minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "requires": { - "brace-expansion": "^5.0.5" - } - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -12229,13 +11969,13 @@ } }, "@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", + "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", "dev": true, "requires": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", + "@typescript-eslint/tsconfig-utils": "^8.60.1", + "@typescript-eslint/types": "^8.60.1", "debug": "^4.4.3" }, "dependencies": { @@ -12257,33 +11997,33 @@ } }, "@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", + "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", "dev": true, "requires": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1" } }, "@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", + "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", "dev": true, "requires": {} }, "@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", + "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", "dev": true, "requires": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/utils": "8.60.1", "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "dependencies": { "debug": { @@ -12304,26 +12044,26 @@ } }, "@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", + "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", + "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", "dev": true, "requires": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/project-service": "8.60.1", + "@typescript-eslint/tsconfig-utils": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "dependencies": { "balanced-match": { @@ -12333,9 +12073,9 @@ "dev": true }, "brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "requires": { "balanced-match": "^4.0.2" @@ -12351,12 +12091,12 @@ } }, "minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "requires": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" } }, "ms": { @@ -12368,24 +12108,24 @@ } }, "@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", + "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1" } }, "@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", + "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", "dev": true, "requires": { - "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/types": "8.60.1", "eslint-visitor-keys": "^5.0.0" }, "dependencies": { @@ -17025,13 +16765,13 @@ "dev": true }, "tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "requires": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "dependencies": { "fdir": { diff --git a/package.json b/package.json index 0595a0e6..f4686742 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@types/jest": "^30.0.0", "@types/node": "^25.5.0", "@types/pg": "^8.20.0", - "@typescript-eslint/eslint-plugin": "^8.57.1", + "@typescript-eslint/eslint-plugin": "^8.60.1", "@typescript-eslint/parser": "^8.59.1", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", From 4b70a36d0fa4fd13cd568706905eb83169ae5966 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 23:33:17 +0000 Subject: [PATCH 20/30] build(deps-dev): bump jest from 30.3.0 to 30.4.2 Bumps [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) from 30.3.0 to 30.4.2. - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v30.4.2/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-version: 30.4.2 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 1845 ++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 973 insertions(+), 874 deletions(-) diff --git a/package-lock.json b/package-lock.json index 03d360f1..a405e7e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", - "jest": "^30.3.0", + "jest": "^30.4.2", "lint-staged": "^17.0.5", "prettier": "3.8.1", "ts-jest": "^29.4.11", @@ -226,9 +226,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "dev": true, "license": "MIT", "engines": { @@ -393,13 +393,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -519,13 +519,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -642,21 +642,21 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", - "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.0", + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", - "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", "optional": true, @@ -665,9 +665,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, @@ -1082,17 +1082,17 @@ } }, "node_modules/@jest/console": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", - "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", + "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0" }, "engines": { @@ -1100,38 +1100,39 @@ } }, "node_modules/@jest/core": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", - "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", + "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/pattern": "30.4.0", + "@jest/reporters": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", + "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.3.0", - "jest-config": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-resolve-dependencies": "30.3.0", - "jest-runner": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "jest-watcher": "30.3.0", - "pretty-format": "30.3.0", + "jest-changed-files": "30.4.1", + "jest-config": "30.4.2", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-resolve-dependencies": "30.4.2", + "jest-runner": "30.4.2", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "jest-watcher": "30.4.1", + "pretty-format": "30.4.1", "slash": "^3.0.0" }, "engines": { @@ -1147,9 +1148,9 @@ } }, "node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", "dev": true, "license": "MIT", "engines": { @@ -1157,39 +1158,39 @@ } }, "node_modules/@jest/environment": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", - "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", + "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "30.3.0" + "jest-mock": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", "dev": true, "license": "MIT", "dependencies": { - "expect": "30.3.0", - "jest-snapshot": "30.3.0" + "expect": "30.4.1", + "jest-snapshot": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", - "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1200,18 +1201,18 @@ } }, "node_modules/@jest/fake-timers": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", - "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", + "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", - "@sinonjs/fake-timers": "^15.0.0", + "@jest/types": "30.4.1", + "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -1228,47 +1229,47 @@ } }, "node_modules/@jest/globals": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", - "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", + "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/types": "30.3.0", - "jest-mock": "30.3.0" + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/types": "30.4.1", + "jest-mock": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", - "jest-regex-util": "30.0.1" + "jest-regex-util": "30.4.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/reporters": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", - "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", + "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", @@ -1281,9 +1282,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -1301,9 +1302,9 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -1349,9 +1350,9 @@ } }, "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1362,13 +1363,13 @@ } }, "node_modules/@jest/snapshot-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", - "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", + "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -1393,14 +1394,14 @@ } }, "node_modules/@jest/test-result": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", - "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", + "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/types": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" }, @@ -1409,15 +1410,15 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", - "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", + "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.3.0", + "@jest/test-result": "30.4.1", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", + "jest-haste-map": "30.4.1", "slash": "^3.0.0" }, "engines": { @@ -1425,23 +1426,23 @@ } }, "node_modules/@jest/transform": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", - "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", + "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@jridgewell/trace-mapping": "^0.3.25", "babel-plugin-istanbul": "^7.0.1", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", + "jest-haste-map": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -1451,14 +1452,14 @@ } }, "node_modules/@jest/types": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", - "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -1526,16 +1527,22 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, "node_modules/@opentelemetry/api": { @@ -1577,9 +1584,9 @@ "dev": true }, "node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -1594,9 +1601,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1634,9 +1641,9 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" }, "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "dev": true, "license": "MIT", "optional": true, @@ -2304,9 +2311,9 @@ "license": "ISC" }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", "cpu": [ "arm" ], @@ -2318,9 +2325,9 @@ ] }, "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", "cpu": [ "arm64" ], @@ -2332,9 +2339,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", "cpu": [ "arm64" ], @@ -2346,9 +2353,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", "cpu": [ "x64" ], @@ -2360,9 +2367,9 @@ ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", "cpu": [ "x64" ], @@ -2374,9 +2381,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", "cpu": [ "arm" ], @@ -2388,9 +2395,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", "cpu": [ "arm" ], @@ -2402,9 +2409,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", "cpu": [ "arm64" ], @@ -2416,9 +2423,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", "cpu": [ "arm64" ], @@ -2429,10 +2436,38 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", "cpu": [ "ppc64" ], @@ -2444,9 +2479,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", "cpu": [ "riscv64" ], @@ -2458,9 +2493,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", "cpu": [ "riscv64" ], @@ -2472,9 +2507,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", "cpu": [ "s390x" ], @@ -2486,9 +2521,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", "cpu": [ "x64" ], @@ -2500,9 +2535,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", "cpu": [ "x64" ], @@ -2513,10 +2548,24 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", "cpu": [ "wasm32" ], @@ -2524,16 +2573,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", "cpu": [ "arm64" ], @@ -2545,9 +2596,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", "cpu": [ "ia32" ], @@ -2559,9 +2610,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", "cpu": [ "x64" ], @@ -2946,16 +2997,16 @@ } }, "node_modules/babel-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", - "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "30.3.0", + "@jest/transform": "30.4.1", "@types/babel__core": "^7.20.5", "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.3.0", + "babel-preset-jest": "30.4.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -2988,9 +3039,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", - "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", + "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", "dev": true, "license": "MIT", "dependencies": { @@ -3028,13 +3079,13 @@ } }, "node_modules/babel-preset-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", - "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", + "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "30.3.0", + "babel-plugin-jest-hoist": "30.4.0", "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { @@ -4627,18 +4678,18 @@ } }, "node_modules/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.3.0", + "@jest/expect-utils": "30.4.1", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -6081,16 +6132,16 @@ } }, "node_modules/jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", - "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", + "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.3.0", - "@jest/types": "30.3.0", + "@jest/core": "30.4.2", + "@jest/types": "30.4.1", "import-local": "^3.2.0", - "jest-cli": "30.3.0" + "jest-cli": "30.4.2" }, "bin": { "jest": "bin/jest.js" @@ -6108,14 +6159,14 @@ } }, "node_modules/jest-changed-files": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", - "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", + "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", "dev": true, "license": "MIT", "dependencies": { "execa": "^5.1.1", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "p-limit": "^3.1.0" }, "engines": { @@ -6123,29 +6174,29 @@ } }, "node_modules/jest-circus": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", - "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", + "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", + "jest-each": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "p-limit": "^3.1.0", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -6155,21 +6206,21 @@ } }, "node_modules/jest-cli": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", - "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", + "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/core": "30.4.2", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-config": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "yargs": "^17.7.2" }, "bin": { @@ -6188,33 +6239,33 @@ } }, "node_modules/jest-config": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", - "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", + "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", - "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.3.0", - "@jest/types": "30.3.0", - "babel-jest": "30.3.0", + "@jest/pattern": "30.4.0", + "@jest/test-sequencer": "30.4.1", + "@jest/types": "30.4.1", + "babel-jest": "30.4.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-circus": "30.3.0", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-runner": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-circus": "30.4.2", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-runner": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "parse-json": "^5.2.0", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -6239,9 +6290,9 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -6287,25 +6338,25 @@ } }, "node_modules/jest-diff": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", - "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.3.0", + "@jest/diff-sequences": "30.4.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-docblock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", + "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", "dev": true, "license": "MIT", "dependencies": { @@ -6316,56 +6367,56 @@ } }, "node_modules/jest-each": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", - "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", + "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "chalk": "^4.1.2", - "jest-util": "30.3.0", - "pretty-format": "30.3.0" + "jest-util": "30.4.1", + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", - "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", + "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0" + "jest-mock": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-haste-map": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", - "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", + "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "picomatch": "^4.0.3", "walker": "^1.0.8" }, @@ -6390,49 +6441,50 @@ } }, "node_modules/jest-leak-detector": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", - "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", + "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", - "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", + "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.3.0", - "pretty-format": "30.3.0" + "jest-diff": "30.4.1", + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-message-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", - "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", + "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", + "jest-util": "30.4.1", "picomatch": "^4.0.3", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -6454,15 +6506,15 @@ } }, "node_modules/jest-mock": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", - "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", + "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-util": "30.3.0" + "jest-util": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -6487,9 +6539,9 @@ } }, "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", + "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", "dev": true, "license": "MIT", "engines": { @@ -6497,18 +6549,18 @@ } }, "node_modules/jest-resolve": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", - "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", + "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", + "jest-haste-map": "30.4.1", "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "slash": "^3.0.0", "unrs-resolver": "^1.7.11" }, @@ -6517,46 +6569,46 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", - "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", + "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.3.0" + "jest-regex-util": "30.4.0", + "jest-snapshot": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", - "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", + "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/environment": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/environment": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-leak-detector": "30.3.0", - "jest-message-util": "30.3.0", - "jest-resolve": "30.3.0", - "jest-runtime": "30.3.0", - "jest-util": "30.3.0", - "jest-watcher": "30.3.0", - "jest-worker": "30.3.0", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-haste-map": "30.4.1", + "jest-leak-detector": "30.4.1", + "jest-message-util": "30.4.1", + "jest-resolve": "30.4.1", + "jest-runtime": "30.4.2", + "jest-util": "30.4.1", + "jest-watcher": "30.4.1", + "jest-worker": "30.4.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -6565,32 +6617,32 @@ } }, "node_modules/jest-runtime": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", - "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", + "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/globals": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/globals": "30.4.1", "@jest/source-map": "30.0.1", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.1.0", "collect-v8-coverage": "^1.0.2", "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -6599,9 +6651,9 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -6647,9 +6699,9 @@ } }, "node_modules/jest-snapshot": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", - "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", + "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", "dev": true, "license": "MIT", "dependencies": { @@ -6658,20 +6710,20 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.3.0", + "@jest/expect-utils": "30.4.1", "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/snapshot-utils": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.3.0", + "expect": "30.4.1", "graceful-fs": "^4.2.11", - "jest-diff": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "pretty-format": "30.3.0", + "jest-diff": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "pretty-format": "30.4.1", "semver": "^7.7.2", "synckit": "^0.11.8" }, @@ -6680,13 +6732,13 @@ } }, "node_modules/jest-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", - "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", + "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -6711,18 +6763,18 @@ } }, "node_modules/jest-validate": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", - "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", + "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -6742,19 +6794,19 @@ } }, "node_modules/jest-watcher": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", - "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", + "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "string-length": "^4.0.2" }, "engines": { @@ -6762,15 +6814,15 @@ } }, "node_modules/jest-worker": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", - "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", + "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -8116,15 +8168,16 @@ } }, "node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "30.0.5", + "@jest/schemas": "30.4.1", "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -8247,13 +8300,22 @@ "node": ">= 0.10" } }, - "node_modules/react-is": { + "node_modules/react-is-18": { + "name": "react-is", "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, "license": "MIT" }, + "node_modules/react-is-19": { + "name": "react-is", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", + "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "dev": true, + "license": "MIT" + }, "node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", @@ -8862,7 +8924,8 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/slash": { "version": "3.0.0", @@ -9889,38 +9952,41 @@ } }, "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { - "napi-postinstall": "^0.3.0" + "napi-postinstall": "^0.3.4" }, "funding": { "url": "https://opencollective.com/unrs-resolver" }, "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" } }, "node_modules/update-browserslist-db": { @@ -10665,9 +10731,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "dev": true }, "@babel/helper-string-parser": { @@ -10771,12 +10837,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -10852,12 +10918,12 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" } }, "@babel/runtime": { @@ -10945,20 +11011,20 @@ } }, "@emnapi/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", - "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "optional": true, "requires": { - "@emnapi/wasi-threads": "1.2.0", + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "@emnapi/runtime": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", - "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "optional": true, "requires": { @@ -10966,9 +11032,9 @@ } }, "@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "optional": true, "requires": { @@ -11240,103 +11306,104 @@ "dev": true }, "@jest/console": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", - "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", + "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", "dev": true, "requires": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0" } }, "@jest/core": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", - "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", + "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", "dev": true, "requires": { - "@jest/console": "30.3.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/pattern": "30.4.0", + "@jest/reporters": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", + "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.3.0", - "jest-config": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-resolve-dependencies": "30.3.0", - "jest-runner": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "jest-watcher": "30.3.0", - "pretty-format": "30.3.0", + "jest-changed-files": "30.4.1", + "jest-config": "30.4.2", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-resolve-dependencies": "30.4.2", + "jest-runner": "30.4.2", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "jest-watcher": "30.4.1", + "pretty-format": "30.4.1", "slash": "^3.0.0" } }, "@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", "dev": true }, "@jest/environment": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", - "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", + "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", "dev": true, "requires": { - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "30.3.0" + "jest-mock": "30.4.1" } }, "@jest/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", "dev": true, "requires": { - "expect": "30.3.0", - "jest-snapshot": "30.3.0" + "expect": "30.4.1", + "jest-snapshot": "30.4.1" } }, "@jest/expect-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", - "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "dev": true, "requires": { "@jest/get-type": "30.1.0" } }, "@jest/fake-timers": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", - "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", + "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", "dev": true, "requires": { - "@jest/types": "30.3.0", - "@sinonjs/fake-timers": "^15.0.0", + "@jest/types": "30.4.1", + "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" } }, "@jest/get-type": { @@ -11346,38 +11413,38 @@ "dev": true }, "@jest/globals": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", - "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", + "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", "dev": true, "requires": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/types": "30.3.0", - "jest-mock": "30.3.0" + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/types": "30.4.1", + "jest-mock": "30.4.1" } }, "@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", "dev": true, "requires": { "@types/node": "*", - "jest-regex-util": "30.0.1" + "jest-regex-util": "30.4.0" } }, "@jest/reporters": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", - "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", + "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", @@ -11390,18 +11457,18 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" }, "dependencies": { "brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -11433,21 +11500,21 @@ } }, "@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", "dev": true, "requires": { "@sinclair/typebox": "^0.34.0" } }, "@jest/snapshot-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", - "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", + "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", "dev": true, "requires": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -11465,59 +11532,59 @@ } }, "@jest/test-result": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", - "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", + "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", "dev": true, "requires": { - "@jest/console": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/types": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" } }, "@jest/test-sequencer": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", - "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", + "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", "dev": true, "requires": { - "@jest/test-result": "30.3.0", + "@jest/test-result": "30.4.1", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", + "jest-haste-map": "30.4.1", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", - "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", + "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", "dev": true, "requires": { "@babel/core": "^7.27.4", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@jridgewell/trace-mapping": "^0.3.25", "babel-plugin-istanbul": "^7.0.1", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", + "jest-haste-map": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" } }, "@jest/types": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", - "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", "dev": true, "requires": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -11571,15 +11638,13 @@ "integrity": "sha512-OxG84iSeR89zYLFeb+DCaFtZT+DDiIu+kTkqY8OYfhE5vpGLFX2sDVBRrAdos1IUqEoboDloDBR9+yU7hNRyog==" }, "@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "optional": true, "requires": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "@tybys/wasm-util": "^0.10.1" } }, "@opentelemetry/api": { @@ -11607,9 +11672,9 @@ "dev": true }, "@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true }, "@sinonjs/commons": { @@ -11622,9 +11687,9 @@ } }, "@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.1" @@ -11660,9 +11725,9 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" }, "@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "dev": true, "optional": true, "requires": { @@ -12144,138 +12209,161 @@ "dev": true }, "@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", "dev": true, "optional": true }, "@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", "dev": true, "optional": true }, "@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", "dev": true, "optional": true }, "@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", "dev": true, "optional": true }, "@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "dev": true, + "optional": true + }, + "@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "dev": true, + "optional": true + }, + "@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", "dev": true, "optional": true }, "@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "dev": true, + "optional": true + }, + "@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", "dev": true, "optional": true }, "@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", "dev": true, "optional": true, "requires": { - "@napi-rs/wasm-runtime": "^0.2.11" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" } }, "@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", "dev": true, "optional": true }, "@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", "dev": true, "optional": true }, "@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", "dev": true, "optional": true }, @@ -12528,15 +12616,15 @@ } }, "babel-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", - "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", "dev": true, "requires": { - "@jest/transform": "30.3.0", + "@jest/transform": "30.4.1", "@types/babel__core": "^7.20.5", "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.3.0", + "babel-preset-jest": "30.4.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -12556,9 +12644,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", - "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", + "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", "dev": true, "requires": { "@types/babel__core": "^7.20.5" @@ -12588,12 +12676,12 @@ } }, "babel-preset-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", - "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", + "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "30.3.0", + "babel-plugin-jest-hoist": "30.4.0", "babel-preset-current-node-syntax": "^1.2.0" } }, @@ -13636,17 +13724,17 @@ "dev": true }, "expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", "dev": true, "requires": { - "@jest/expect-utils": "30.3.0", + "@jest/expect-utils": "30.4.1", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" } }, "express": { @@ -14558,109 +14646,109 @@ } }, "jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", - "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", + "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", "dev": true, "requires": { - "@jest/core": "30.3.0", - "@jest/types": "30.3.0", + "@jest/core": "30.4.2", + "@jest/types": "30.4.1", "import-local": "^3.2.0", - "jest-cli": "30.3.0" + "jest-cli": "30.4.2" } }, "jest-changed-files": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", - "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", + "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", "dev": true, "requires": { "execa": "^5.1.1", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "p-limit": "^3.1.0" } }, "jest-circus": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", - "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", + "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", "dev": true, "requires": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", + "jest-each": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "p-limit": "^3.1.0", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "jest-cli": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", - "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", + "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", "dev": true, "requires": { - "@jest/core": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/core": "30.4.2", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-config": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "yargs": "^17.7.2" } }, "jest-config": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", - "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", + "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", "dev": true, "requires": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", - "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.3.0", - "@jest/types": "30.3.0", - "babel-jest": "30.3.0", + "@jest/pattern": "30.4.0", + "@jest/test-sequencer": "30.4.1", + "@jest/types": "30.4.1", + "babel-jest": "30.4.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-circus": "30.3.0", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-runner": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-circus": "30.4.2", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-runner": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "parse-json": "^5.2.0", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "dependencies": { "brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -14692,69 +14780,69 @@ } }, "jest-diff": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", - "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", "dev": true, "requires": { - "@jest/diff-sequences": "30.3.0", + "@jest/diff-sequences": "30.4.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" } }, "jest-docblock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", + "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", "dev": true, "requires": { "detect-newline": "^3.1.0" } }, "jest-each": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", - "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", + "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", "dev": true, "requires": { "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "chalk": "^4.1.2", - "jest-util": "30.3.0", - "pretty-format": "30.3.0" + "jest-util": "30.4.1", + "pretty-format": "30.4.1" } }, "jest-environment-node": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", - "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", + "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", "dev": true, "requires": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0" + "jest-mock": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1" } }, "jest-haste-map": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", - "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", + "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", "dev": true, "requires": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "fsevents": "^2.3.3", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "picomatch": "^4.0.3", "walker": "^1.0.8" }, @@ -14768,40 +14856,41 @@ } }, "jest-leak-detector": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", - "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", + "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", "dev": true, "requires": { "@jest/get-type": "30.1.0", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" } }, "jest-matcher-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", - "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", + "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", "dev": true, "requires": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.3.0", - "pretty-format": "30.3.0" + "jest-diff": "30.4.1", + "pretty-format": "30.4.1" } }, "jest-message-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", - "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", + "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", "dev": true, "requires": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", + "jest-util": "30.4.1", "picomatch": "^4.0.3", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -14815,14 +14904,14 @@ } }, "jest-mock": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", - "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", + "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", "dev": true, "requires": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-util": "30.3.0" + "jest-util": "30.4.1" } }, "jest-pnp-resolver": { @@ -14833,101 +14922,101 @@ "requires": {} }, "jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", + "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", "dev": true }, "jest-resolve": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", - "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", + "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", "dev": true, "requires": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", + "jest-haste-map": "30.4.1", "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "slash": "^3.0.0", "unrs-resolver": "^1.7.11" } }, "jest-resolve-dependencies": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", - "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", + "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", "dev": true, "requires": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.3.0" + "jest-regex-util": "30.4.0", + "jest-snapshot": "30.4.1" } }, "jest-runner": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", - "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", + "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", "dev": true, "requires": { - "@jest/console": "30.3.0", - "@jest/environment": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/environment": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-leak-detector": "30.3.0", - "jest-message-util": "30.3.0", - "jest-resolve": "30.3.0", - "jest-runtime": "30.3.0", - "jest-util": "30.3.0", - "jest-watcher": "30.3.0", - "jest-worker": "30.3.0", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-haste-map": "30.4.1", + "jest-leak-detector": "30.4.1", + "jest-message-util": "30.4.1", + "jest-resolve": "30.4.1", + "jest-runtime": "30.4.2", + "jest-util": "30.4.1", + "jest-watcher": "30.4.1", + "jest-worker": "30.4.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", - "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", + "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", "dev": true, "requires": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/globals": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/globals": "30.4.1", "@jest/source-map": "30.0.1", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.1.0", "collect-v8-coverage": "^1.0.2", "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, "dependencies": { "brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -14959,9 +15048,9 @@ } }, "jest-snapshot": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", - "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", + "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", "dev": true, "requires": { "@babel/core": "^7.27.4", @@ -14969,31 +15058,31 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.3.0", + "@jest/expect-utils": "30.4.1", "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/snapshot-utils": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.3.0", + "expect": "30.4.1", "graceful-fs": "^4.2.11", - "jest-diff": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "pretty-format": "30.3.0", + "jest-diff": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "pretty-format": "30.4.1", "semver": "^7.7.2", "synckit": "^0.11.8" } }, "jest-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", - "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", + "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", "dev": true, "requires": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -15010,17 +15099,17 @@ } }, "jest-validate": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", - "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", + "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", "dev": true, "requires": { "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "dependencies": { "camelcase": { @@ -15032,30 +15121,30 @@ } }, "jest-watcher": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", - "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", + "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", "dev": true, "requires": { - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "string-length": "^4.0.2" } }, "jest-worker": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", - "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", + "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", "dev": true, "requires": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -15947,14 +16036,15 @@ } }, "pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", "dev": true, "requires": { - "@jest/schemas": "30.0.5", + "@jest/schemas": "30.4.1", "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" }, "dependencies": { "ansi-styles": { @@ -16029,12 +16119,18 @@ "unpipe": "~1.0.0" } }, - "react-is": { - "version": "18.3.1", + "react-is-18": { + "version": "npm:react-is@18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, + "react-is-19": { + "version": "npm:react-is@19.2.7", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", + "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "dev": true + }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", @@ -17108,31 +17204,34 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "dev": true, - "requires": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1", - "napi-postinstall": "^0.3.0" + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "requires": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2", + "napi-postinstall": "^0.3.4" } }, "update-browserslist-db": { diff --git a/package.json b/package.json index f4686742..a8c7d95a 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", - "jest": "^30.3.0", + "jest": "^30.4.2", "lint-staged": "^17.0.5", "prettier": "3.8.1", "ts-jest": "^29.4.11", From 73ad87a4512c475e4c0a6c9ddad94893ff9b7f96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 23:39:37 +0000 Subject: [PATCH 21/30] build(deps-dev): bump eslint-plugin-prettier from 5.5.5 to 5.5.6 Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.5.5 to 5.5.6. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.5.5...v5.5.6) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-version: 5.5.6 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 48 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index a405e7e6..3a900947 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest": "^29.15.2", - "eslint-plugin-prettier": "^5.5.5", + "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", "jest": "^30.4.2", @@ -1565,13 +1565,13 @@ } }, "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node": "^14.18.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/pkgr" @@ -4434,14 +4434,14 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", - "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz", + "integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==", "dev": true, "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.1", - "synckit": "^0.11.12" + "synckit": "^0.11.13" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -9324,13 +9324,13 @@ } }, "node_modules/synckit": { - "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", + "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", "dev": true, "license": "MIT", "dependencies": { - "@pkgr/core": "^0.2.9" + "@pkgr/core": "^0.3.6" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -11660,9 +11660,9 @@ "optional": true }, "@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", "dev": true }, "@rtsao/scc": { @@ -13592,13 +13592,13 @@ } }, "eslint-plugin-prettier": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", - "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz", + "integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.1", - "synckit": "^0.11.12" + "synckit": "^0.11.13" } }, "eslint-plugin-unused-imports": { @@ -16812,12 +16812,12 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "synckit": { - "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", + "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", "dev": true, "requires": { - "@pkgr/core": "^0.2.9" + "@pkgr/core": "^0.3.6" } }, "tarn": { diff --git a/package.json b/package.json index a8c7d95a..71d30ac0 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest": "^29.15.2", - "eslint-plugin-prettier": "^5.5.5", + "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-unused-imports": "^4.4.1", "husky": "^9.1.7", "jest": "^30.4.2", From 1d58aaac1dfc3e548c125966afe2a4caefd292c4 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 9 Jun 2026 13:59:06 +0200 Subject: [PATCH 22/30] feat: add EXPERIMENT_ESF_SUBMITTED for experiment even type (#690) --- src/models/Event.ts | 1 + .../scicatProposal/consumers/ExperimentCreationQueueConsumer.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/models/Event.ts b/src/models/Event.ts index ec05ef3d..fea2c185 100644 --- a/src/models/Event.ts +++ b/src/models/Event.ts @@ -7,4 +7,5 @@ export enum Event { VISIT_UPDATED = 'VISIT_UPDATED', EXPERIMENT_CREATED = 'EXPERIMENT_CREATED', EXPERIMENT_UPDATED = 'EXPERIMENT_UPDATED', + EXPERIMENT_ESF_SUBMITTED = 'EXPERIMENT_ESF_SUBMITTED', } diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts index ecda5324..118dfbed 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts @@ -10,6 +10,7 @@ import { upsertExperimentInScicat } from '../consumerCallbacks/upsertProposalInS const EXPERIMENT_EVENT_TYPES = [ Event.EXPERIMENT_CREATED, Event.EXPERIMENT_UPDATED, + Event.EXPERIMENT_ESF_SUBMITTED, ]; const experimentTriggeringStatuses = From 0a8882f934396a2ce55c7299d2325929953b5b56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:33:04 +0000 Subject: [PATCH 23/30] build(deps): bump envalid from 8.1.1 to 8.2.0 Bumps [envalid](https://github.com/af/envalid) from 8.1.1 to 8.2.0. - [Release notes](https://github.com/af/envalid/releases) - [Commits](https://github.com/af/envalid/compare/v8.1.1...v8.2.0) --- updated-dependencies: - dependency-name: envalid dependency-version: 8.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3a900947..823698d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@user-office-software/duo-message-broker": "^1.9.0", "axios": "^1.16.0", "dotenv": "^17.3.1", - "envalid": "^8.1.1", + "envalid": "^8.2.0", "express": "^5.2.1", "kafkajs": "^2.2.4", "knex": "^3.2.4", @@ -4010,9 +4010,9 @@ } }, "node_modules/envalid": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/envalid/-/envalid-8.1.1.tgz", - "integrity": "sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/envalid/-/envalid-8.2.0.tgz", + "integrity": "sha512-CkPvea95dwMYE1wnKX5mQXkOpiMs9O+ncv8NqZy+gW7FuzpUp06KTdUHb18xFG8CqQHmfmRqGLF5DuGaBWNrSw==", "license": "MIT", "dependencies": { "tslib": "2.8.1" @@ -13281,9 +13281,9 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" }, "envalid": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/envalid/-/envalid-8.1.1.tgz", - "integrity": "sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/envalid/-/envalid-8.2.0.tgz", + "integrity": "sha512-CkPvea95dwMYE1wnKX5mQXkOpiMs9O+ncv8NqZy+gW7FuzpUp06KTdUHb18xFG8CqQHmfmRqGLF5DuGaBWNrSw==", "requires": { "tslib": "2.8.1" } diff --git a/package.json b/package.json index 71d30ac0..d1101b18 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@user-office-software/duo-message-broker": "^1.9.0", "axios": "^1.16.0", "dotenv": "^17.3.1", - "envalid": "^8.1.1", + "envalid": "^8.2.0", "express": "^5.2.1", "kafkajs": "^2.2.4", "knex": "^3.2.4", From 5b770824fff7b6df2e8a8499b302b871d6ae1439 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:38:39 +0000 Subject: [PATCH 24/30] build(deps): bump form-data from 4.0.5 to 4.0.6 Bumps [form-data](https://github.com/form-data/form-data) from 4.0.5 to 4.0.6. - [Release notes](https://github.com/form-data/form-data/releases) - [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md) - [Commits](https://github.com/form-data/form-data/compare/v4.0.5...v4.0.6) --- updated-dependencies: - dependency-name: form-data dependency-version: 4.0.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 823698d7..ef342d85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5010,16 +5010,16 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -5409,9 +5409,10 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -13952,15 +13953,15 @@ } }, "form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" } }, "forwarded": { @@ -14200,9 +14201,9 @@ } }, "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "requires": { "function-bind": "^1.1.2" } From be78072c936248c9d7b252737cac29363551827b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:45:57 +0000 Subject: [PATCH 25/30] build(deps-dev): bump @eslint/compat from 2.0.5 to 2.1.0 Bumps [@eslint/compat](https://github.com/eslint/rewrite/tree/HEAD/packages/compat) from 2.0.5 to 2.1.0. - [Release notes](https://github.com/eslint/rewrite/releases) - [Changelog](https://github.com/eslint/rewrite/blob/main/packages/compat/CHANGELOG.md) - [Commits](https://github.com/eslint/rewrite/commits/compat-v2.1.0/packages/compat) --- updated-dependencies: - dependency-name: "@eslint/compat" dependency-version: 2.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef342d85..a0eb5081 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "tsyringe": "^4.10.0" }, "devDependencies": { - "@eslint/compat": "^2.0.5", + "@eslint/compat": "^2.1.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^9.39.4", "@types/express": "^5.0.6", @@ -705,9 +705,9 @@ } }, "node_modules/@eslint/compat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.0.5.tgz", - "integrity": "sha512-IbHDbHJfkVNv6xjlET8AIVo/K1NQt7YT4Rp6ok/clyBGcpRx1l6gv0Rq3vBvYfPJIZt6ODf66Zq08FJNDpnzgg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.0.tgz", + "integrity": "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11058,9 +11058,9 @@ "dev": true }, "@eslint/compat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.0.5.tgz", - "integrity": "sha512-IbHDbHJfkVNv6xjlET8AIVo/K1NQt7YT4Rp6ok/clyBGcpRx1l6gv0Rq3vBvYfPJIZt6ODf66Zq08FJNDpnzgg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.0.tgz", + "integrity": "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==", "dev": true, "requires": { "@eslint/core": "^1.2.1" diff --git a/package.json b/package.json index d1101b18..a3da31d7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "author": "SIMS", "license": "MIT", "devDependencies": { - "@eslint/compat": "^2.0.5", + "@eslint/compat": "^2.1.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^9.39.4", "@types/express": "^5.0.6", From 7c157979ee0ae1100fbc17c80d6c9e5db271a7e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 23:32:56 +0000 Subject: [PATCH 26/30] build(deps): bump axios from 1.16.0 to 1.18.1 Bumps [axios](https://github.com/axios/axios) from 1.16.0 to 1.18.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.16.0...v1.18.1) --- updated-dependencies: - dependency-name: axios dependency-version: 1.18.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 58 +++++++++++++++++++++++++++++++++++++++++------ package.json | 2 +- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0eb5081..b48d7fed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", - "axios": "^1.16.0", + "axios": "^1.18.1", "dotenv": "^17.3.1", "envalid": "^8.2.0", "express": "^5.2.1", @@ -2721,6 +2721,18 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", @@ -2986,13 +2998,14 @@ } }, "node_modules/axios": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", - "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, @@ -5447,6 +5460,19 @@ "url": "https://opencollective.com/express" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -12429,6 +12455,14 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, "ajv": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", @@ -12607,12 +12641,13 @@ } }, "axios": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", - "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", "requires": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, @@ -14226,6 +14261,15 @@ "toidentifier": "~1.0.1" } }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", diff --git a/package.json b/package.json index a3da31d7..e2bead54 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "dependencies": { "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", - "axios": "^1.16.0", + "axios": "^1.18.1", "dotenv": "^17.3.1", "envalid": "^8.2.0", "express": "^5.2.1", From 27b6cd2e0a8ab590436a313fb9504eac0c5abbc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:33:10 +0000 Subject: [PATCH 27/30] build(deps-dev): bump @typescript-eslint/parser from 8.60.1 to 8.62.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.60.1 to 8.62.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.62.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.62.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 290 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 276 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index b48d7fed..01b6d120 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "@types/node": "^25.5.0", "@types/pg": "^8.20.0", "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.59.1", + "@typescript-eslint/parser": "^8.62.1", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", @@ -1961,16 +1961,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", - "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", + "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/typescript-estree": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", "debug": "^4.4.3" }, "engines": { @@ -1985,6 +1985,146 @@ "typescript": ">=4.8.4 <6.1.0" } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", + "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.62.1", + "@typescript-eslint/types": "^8.62.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", + "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", + "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", + "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", + "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.62.1", + "@typescript-eslint/tsconfig-utils": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", + "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.62.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/parser/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2003,6 +2143,35 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/parser/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -12031,18 +12200,94 @@ } }, "@typescript-eslint/parser": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", - "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", + "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/typescript-estree": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", "debug": "^4.4.3" }, "dependencies": { + "@typescript-eslint/project-service": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", + "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "dev": true, + "requires": { + "@typescript-eslint/tsconfig-utils": "^8.62.1", + "@typescript-eslint/types": "^8.62.1", + "debug": "^4.4.3" + } + }, + "@typescript-eslint/scope-manager": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", + "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1" + } + }, + "@typescript-eslint/tsconfig-utils": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", + "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "dev": true, + "requires": {} + }, + "@typescript-eslint/types": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", + "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", + "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "dev": true, + "requires": { + "@typescript-eslint/project-service": "8.62.1", + "@typescript-eslint/tsconfig-utils": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", + "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.62.1", + "eslint-visitor-keys": "^5.0.0" + } + }, + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true + }, + "brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "requires": { + "balanced-match": "^4.0.2" + } + }, "debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -12052,6 +12297,21 @@ "ms": "^2.1.3" } }, + "eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true + }, + "minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "requires": { + "brace-expansion": "^5.0.5" + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/package.json b/package.json index e2bead54..ba26b1bb 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@types/node": "^25.5.0", "@types/pg": "^8.20.0", "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.59.1", + "@typescript-eslint/parser": "^8.62.1", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", From ee32a5d41291b04be16b98a55b3a0e2c5ae65fee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 23:33:05 +0000 Subject: [PATCH 28/30] build(deps-dev): bump @typescript-eslint/parser from 8.62.1 to 8.63.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.62.1 to 8.63.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.63.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.63.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 138 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 01b6d120..1cd1fc69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "@types/node": "^25.5.0", "@types/pg": "^8.20.0", "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.62.1", + "@typescript-eslint/parser": "^8.63.0", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", @@ -1961,16 +1961,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", - "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz", + "integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/typescript-estree": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", "debug": "^4.4.3" }, "engines": { @@ -1986,14 +1986,14 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", - "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz", + "integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.62.1", - "@typescript-eslint/types": "^8.62.1", + "@typescript-eslint/tsconfig-utils": "^8.63.0", + "@typescript-eslint/types": "^8.63.0", "debug": "^4.4.3" }, "engines": { @@ -2008,14 +2008,14 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", - "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz", + "integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1" + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2026,9 +2026,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", - "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz", + "integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==", "dev": true, "license": "MIT", "engines": { @@ -2043,9 +2043,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", - "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz", + "integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==", "dev": true, "license": "MIT", "engines": { @@ -2057,16 +2057,16 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", - "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz", + "integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.62.1", - "@typescript-eslint/tsconfig-utils": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/project-service": "8.63.0", + "@typescript-eslint/tsconfig-utils": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2085,13 +2085,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", - "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz", + "integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -12200,62 +12200,62 @@ } }, "@typescript-eslint/parser": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", - "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz", + "integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/typescript-estree": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", "debug": "^4.4.3" }, "dependencies": { "@typescript-eslint/project-service": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", - "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz", + "integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==", "dev": true, "requires": { - "@typescript-eslint/tsconfig-utils": "^8.62.1", - "@typescript-eslint/types": "^8.62.1", + "@typescript-eslint/tsconfig-utils": "^8.63.0", + "@typescript-eslint/types": "^8.63.0", "debug": "^4.4.3" } }, "@typescript-eslint/scope-manager": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", - "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz", + "integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==", "dev": true, "requires": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1" + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0" } }, "@typescript-eslint/tsconfig-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", - "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz", + "integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==", "dev": true, "requires": {} }, "@typescript-eslint/types": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", - "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz", + "integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", - "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz", + "integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==", "dev": true, "requires": { - "@typescript-eslint/project-service": "8.62.1", - "@typescript-eslint/tsconfig-utils": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/project-service": "8.63.0", + "@typescript-eslint/tsconfig-utils": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -12264,12 +12264,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", - "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz", + "integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==", "dev": true, "requires": { - "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" } }, diff --git a/package.json b/package.json index ba26b1bb..3b801fcd 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@types/node": "^25.5.0", "@types/pg": "^8.20.0", "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.62.1", + "@typescript-eslint/parser": "^8.63.0", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", From 70e470b23a9f8354a498b3e372083a561dbe25ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 23:33:21 +0000 Subject: [PATCH 29/30] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.60.1 to 8.64.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.64.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.64.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 500 +++++++++++----------------------------------- package.json | 2 +- 2 files changed, 121 insertions(+), 381 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1cd1fc69..dd55a55e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@types/jest": "^30.0.0", "@types/node": "^25.5.0", "@types/pg": "^8.20.0", - "@typescript-eslint/eslint-plugin": "^8.60.1", + "@typescript-eslint/eslint-plugin": "^8.64.0", "@typescript-eslint/parser": "^8.63.0", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", @@ -1922,17 +1922,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", - "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", + "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/type-utils": "8.60.1", - "@typescript-eslint/utils": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/type-utils": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1945,7 +1945,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.60.1", + "@typescript-eslint/parser": "^8.64.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -1961,16 +1961,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz", - "integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", + "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.63.0", - "@typescript-eslint/types": "8.63.0", - "@typescript-eslint/typescript-estree": "8.63.0", - "@typescript-eslint/visitor-keys": "8.63.0", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "debug": "^4.4.3" }, "engines": { @@ -1985,146 +1985,6 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz", - "integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.63.0", - "@typescript-eslint/types": "^8.63.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz", - "integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.63.0", - "@typescript-eslint/visitor-keys": "8.63.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz", - "integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz", - "integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz", - "integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.63.0", - "@typescript-eslint/tsconfig-utils": "8.63.0", - "@typescript-eslint/types": "8.63.0", - "@typescript-eslint/visitor-keys": "8.63.0", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz", - "integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.63.0", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/@typescript-eslint/parser/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2143,35 +2003,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/parser/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2180,14 +2011,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/project-service": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", - "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", + "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.60.1", - "@typescript-eslint/types": "^8.60.1", + "@typescript-eslint/tsconfig-utils": "^8.64.0", + "@typescript-eslint/types": "^8.64.0", "debug": "^4.4.3" }, "engines": { @@ -2227,14 +2058,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", - "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", + "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1" + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2245,9 +2076,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", - "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", + "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", "dev": true, "license": "MIT", "engines": { @@ -2262,15 +2093,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", - "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", + "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2312,9 +2143,9 @@ "license": "MIT" }, "node_modules/@typescript-eslint/types": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", - "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", + "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", "dev": true, "license": "MIT", "engines": { @@ -2326,16 +2157,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", - "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", + "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.60.1", - "@typescript-eslint/tsconfig-utils": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/project-service": "8.64.0", + "@typescript-eslint/tsconfig-utils": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2364,9 +2195,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "dev": true, "license": "MIT", "dependencies": { @@ -2418,16 +2249,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", - "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", + "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1" + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2442,13 +2273,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", - "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", + "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/types": "8.64.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -9626,9 +9457,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -12176,16 +12007,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", - "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", + "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/type-utils": "8.60.1", - "@typescript-eslint/utils": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/type-utils": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -12200,94 +12031,18 @@ } }, "@typescript-eslint/parser": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz", - "integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", + "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "8.63.0", - "@typescript-eslint/types": "8.63.0", - "@typescript-eslint/typescript-estree": "8.63.0", - "@typescript-eslint/visitor-keys": "8.63.0", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "debug": "^4.4.3" }, "dependencies": { - "@typescript-eslint/project-service": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz", - "integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==", - "dev": true, - "requires": { - "@typescript-eslint/tsconfig-utils": "^8.63.0", - "@typescript-eslint/types": "^8.63.0", - "debug": "^4.4.3" - } - }, - "@typescript-eslint/scope-manager": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz", - "integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.63.0", - "@typescript-eslint/visitor-keys": "8.63.0" - } - }, - "@typescript-eslint/tsconfig-utils": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz", - "integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==", - "dev": true, - "requires": {} - }, - "@typescript-eslint/types": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz", - "integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz", - "integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==", - "dev": true, - "requires": { - "@typescript-eslint/project-service": "8.63.0", - "@typescript-eslint/tsconfig-utils": "8.63.0", - "@typescript-eslint/types": "8.63.0", - "@typescript-eslint/visitor-keys": "8.63.0", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "8.63.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz", - "integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.63.0", - "eslint-visitor-keys": "^5.0.0" - } - }, - "balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true - }, - "brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", - "dev": true, - "requires": { - "balanced-match": "^4.0.2" - } - }, "debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -12297,21 +12052,6 @@ "ms": "^2.1.3" } }, - "eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true - }, - "minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "requires": { - "brace-expansion": "^5.0.5" - } - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -12321,13 +12061,13 @@ } }, "@typescript-eslint/project-service": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", - "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", + "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", "dev": true, "requires": { - "@typescript-eslint/tsconfig-utils": "^8.60.1", - "@typescript-eslint/types": "^8.60.1", + "@typescript-eslint/tsconfig-utils": "^8.64.0", + "@typescript-eslint/types": "^8.64.0", "debug": "^4.4.3" }, "dependencies": { @@ -12349,31 +12089,31 @@ } }, "@typescript-eslint/scope-manager": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", - "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", + "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", "dev": true, "requires": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1" + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0" } }, "@typescript-eslint/tsconfig-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", - "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", + "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", "dev": true, "requires": {} }, "@typescript-eslint/type-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", - "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", + "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", "dev": true, "requires": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -12396,21 +12136,21 @@ } }, "@typescript-eslint/types": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", - "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", + "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", - "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", + "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", "dev": true, "requires": { - "@typescript-eslint/project-service": "8.60.1", - "@typescript-eslint/tsconfig-utils": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/project-service": "8.64.0", + "@typescript-eslint/tsconfig-utils": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -12425,9 +12165,9 @@ "dev": true }, "brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "dev": true, "requires": { "balanced-match": "^4.0.2" @@ -12460,24 +12200,24 @@ } }, "@typescript-eslint/utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", - "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", + "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1" + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0" } }, "@typescript-eslint/visitor-keys": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", - "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", + "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", "dev": true, "requires": { - "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/types": "8.64.0", "eslint-visitor-keys": "^5.0.0" }, "dependencies": { @@ -17183,9 +16923,9 @@ "requires": {} }, "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true } } diff --git a/package.json b/package.json index 3b801fcd..19a9c5b2 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@types/jest": "^30.0.0", "@types/node": "^25.5.0", "@types/pg": "^8.20.0", - "@typescript-eslint/eslint-plugin": "^8.60.1", + "@typescript-eslint/eslint-plugin": "^8.64.0", "@typescript-eslint/parser": "^8.63.0", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", From 9a382eb0a4a7c5b9feb3a78b329e4ed863b69c4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 23:33:08 +0000 Subject: [PATCH 30/30] build(deps): bump dotenv from 17.3.1 to 17.4.2 Bumps [dotenv](https://github.com/motdotla/dotenv) from 17.3.1 to 17.4.2. - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](https://github.com/motdotla/dotenv/compare/v17.3.1...v17.4.2) --- updated-dependencies: - dependency-name: dotenv dependency-version: 17.4.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd55a55e..6e664e55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", "axios": "^1.18.1", - "dotenv": "^17.3.1", + "dotenv": "^17.4.2", "envalid": "^8.2.0", "express": "^5.2.1", "kafkajs": "^2.2.4", @@ -3934,9 +3934,9 @@ } }, "node_modules/dotenv": { - "version": "17.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", - "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -13255,9 +13255,9 @@ "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==" }, "dotenv": { - "version": "17.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", - "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==" + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==" }, "dunder-proto": { "version": "1.0.1", diff --git a/package.json b/package.json index 19a9c5b2..5c476957 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@user-office-software/duo-logger": "^2.3.2", "@user-office-software/duo-message-broker": "^1.9.0", "axios": "^1.18.1", - "dotenv": "^17.3.1", + "dotenv": "^17.4.2", "envalid": "^8.2.0", "express": "^5.2.1", "kafkajs": "^2.2.4",