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 01/10] 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 a0eb508..b48d7fe 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 a3da31d..e2bead5 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 02/10] 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 b48d7fe..01b6d12 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 e2bead5..ba26b1b 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 03/10] 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 01b6d12..1cd1fc6 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 ba26b1b..3b801fc 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 04/10] 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 1cd1fc6..dd55a55 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 3b801fc..19a9c5b 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 05/10] 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 dd55a55..6e664e5 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 19a9c5b..5c47695 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", From 1c740592e5308450f291468e49cc07d5778f9571 Mon Sep 17 00:00:00 2001 From: Jekabs Karklins <58165815+jekabs-karklins@users.noreply.github.com> Date: Thu, 30 Jul 2026 13:36:21 +0200 Subject: [PATCH 06/10] feat(queue): add event type to log messages in QueueConsumer (#707) --- src/queue/consumers/QueueConsumer.spec.ts | 21 ++++++++++++++++----- src/queue/consumers/QueueConsumer.ts | 3 ++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/queue/consumers/QueueConsumer.spec.ts b/src/queue/consumers/QueueConsumer.spec.ts index 4aa2945..fe9eff7 100644 --- a/src/queue/consumers/QueueConsumer.spec.ts +++ b/src/queue/consumers/QueueConsumer.spec.ts @@ -82,33 +82,44 @@ describe('QueueConsumer', () => { }); it('should call onMessage when a message is received', async () => { + const eventType = 'PROPOSAL_CREATED'; + const message = { proposalPk: 1234 }; + await queueConsumer.start(); await messageBrokerMock.listenOn.mock.calls[0][1]( - 'testMessage', - {}, + eventType, + message, {} as any ); expect(logger.logInfo).toHaveBeenCalledWith('Received message on queue', { queueName: 'testQueue', + eventType, }); expect(logger.logException).not.toHaveBeenCalled(); - expect(queueConsumer.onMessage).toHaveBeenCalledWith('testMessage', {}, {}); + expect(queueConsumer.onMessage).toHaveBeenCalledWith( + eventType, + message, + {} + ); }); it('should log error if onMessage throws and rethrow the error', async () => { + const eventType = 'PROPOSAL_CREATED'; + const message = { proposalPk: 1234 }; const error = new Error('Test error'); queueConsumer.onMessage = jest.fn().mockRejectedValue(error); await queueConsumer.start(); await expect( - messageBrokerMock.listenOn.mock.calls[0][1]('testMessage', {}, {} as any) + messageBrokerMock.listenOn.mock.calls[0][1](eventType, message, {} as any) ).rejects.toThrow(error); expect(logger.logInfo).toHaveBeenCalledWith('Received message on queue', { queueName: 'testQueue', + eventType, }); expect(logger.logException).toHaveBeenCalledWith( 'Error while handling QueueConsumer callback: ', @@ -116,7 +127,7 @@ describe('QueueConsumer', () => { error: error.message, queue: 'testQueue', consumer: 'TestQueueConsumer', - args: ['testMessage', {}, {}], + args: [eventType, message, {}], } ); }); diff --git a/src/queue/consumers/QueueConsumer.ts b/src/queue/consumers/QueueConsumer.ts index abff40b..85c8288 100644 --- a/src/queue/consumers/QueueConsumer.ts +++ b/src/queue/consumers/QueueConsumer.ts @@ -65,7 +65,8 @@ export abstract class QueueConsumer { this.messageBroker.listenOn( queueName as Queue, async (...args) => { - logger.logInfo('Received message on queue', { queueName }); + const [eventType] = args; + logger.logInfo('Received message on queue', { queueName, eventType }); // Start tracking processing time const endTimer = processingDurationHistogram.startTimer({ From faa70b0c59772fb243345b7e2eb3e69b7ec5beab Mon Sep 17 00:00:00 2001 From: Jekabs Karklins <58165815+jekabs-karklins@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:03:04 +0200 Subject: [PATCH 07/10] feat: add affiliation to visitors and PI (#709) Co-authored-by: jekabskarklins --- README.md | 2 +- sample.env | 5 +- .../ExperimentCreationQueueConsumer.ts | 2 +- .../uoToScicatExperiment.mapper.spec.ts.snap | 100 ++++++++++++++++++ .../uoToScicatProposal.mapper.spec.ts.snap | 12 +++ .../uoToScicatExperiment.mapper.spec.ts | 72 +++++++++++++ .../mappers/uoToScicatExperiment.mapper.ts | 28 ++++- .../mappers/uoToScicatProposal.mapper.ts | 1 + .../queries/getExperiment.query.ts | 3 + .../userOfficeApi/type/uoExperiment.type.ts | 1 + 10 files changed, 222 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f3585d1..48528ab 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ To be able to start the connector locally you will need to: 1. Install all needed dependencies with `npm install` 2. Copy the missing matrix-js dependency `npm run fix-olm-dependency` -3. Start the application using `npm run start` +3. Start the application using the command `npm run start` diff --git a/sample.env b/sample.env index ba3de4e..c30f41c 100644 --- a/sample.env +++ b/sample.env @@ -17,6 +17,8 @@ SCICAT_LOGIN_ENDPOINT=/Users/login SCICAT_USERNAME= SCICAT_PASSWORD= SCICAT_PROPOSAL_TRIGGERING_STATUSES="SCHEDULING, ALLOCATED" +SCICAT_EXPERIMENT_TRIGGERING_STATUSES="ACTIVE" +SCICAT_JWT= PROPOSAL_FOLDERS_CREATION_GROUP_PREFIX="" PROPOSAL_FOLDERS_CREATION_TRIGGERING_STATUSES="PROPOSAL_ACCEPTED" @@ -36,6 +38,7 @@ SYNAPSE_OAUTH_ISSUER=https://server-scichat.swap.ess.eu ## The following variables enable the different functionalities available in the connector ## true or false ENABLE_SCICAT_PROPOSAL_UPSERT=false +ENABLE_SCICAT_EXPERIMENT_UPSERT=false ENABLE_SCICHAT_ROOM_CREATION=false ENABLE_NICOS_TO_SCICHAT_MESSAGES=false ENABLE_PROPOSAL_FOLDERS_CREATION=false @@ -59,4 +62,4 @@ ONE_IDENTITY_API_PASSWORD= VISA_QUEUE_NAME=dummy VISA_SYNCING_TRIGGERING_STATUSES="ALLOCATED" -VISA_DATABASE_URL=postgres://postgres:qwerty123@127.0.0.1:5434/visa \ No newline at end of file +VISA_DATABASE_URL=postgres://postgres:qwerty123@127.0.0.1:5434/visa diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts index 118dfbe..95888dc 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts @@ -22,7 +22,7 @@ export class ExperimentCreationQueueConsumer extends QueueConsumer { } getExchangeName(): string { - return process.env.USER_OFFICE_CORE_EXCHANGE_NAME as string; + return process.env.EXPERIMENT_CREATION_EXCHANGE_NAME as string; } onMessage: ConsumerCallback = async (type, message) => { 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 da2fb08..d7008eb 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 @@ -20,10 +20,42 @@ Test Abstract", "human_name": "Instrument Name", "value": "YMIR", }, + "local_contact_email": { + "human_name": "Local contact email", + "value": "junjie.quan@ess.eu", + }, + "local_contact_firstname": { + "human_name": "Local contact name", + "value": "Junjie", + }, + "local_contact_lastname": { + "human_name": "Local contact surname", + "value": "Quan", + }, "number_of_visitors": { "human_name": "Number of Visitors", "value": 1, }, + "pi_affiliation": { + "human_name": "PI Affiliation", + "value": "ESS", + }, + "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", + }, "status_experiment": { "human_name": "UOS Experiment Status", "value": "ACTIVE", @@ -32,6 +64,10 @@ Test Abstract", "human_name": "UOS Proposal Status", "value": "ALLOCATED", }, + "visitor_1_affiliation": { + "human_name": "Visitor 1 Affiliation", + "value": "ESS", + }, "visitor_1_email": { "human_name": "Visitor 1 Email", "value": "test@example.com", @@ -81,10 +117,42 @@ Test Abstract", "human_name": "Instrument Name", "value": "YMIR", }, + "local_contact_email": { + "human_name": "Local contact email", + "value": "junjie.quan@ess.eu", + }, + "local_contact_firstname": { + "human_name": "Local contact name", + "value": "Junjie", + }, + "local_contact_lastname": { + "human_name": "Local contact surname", + "value": "Quan", + }, "number_of_visitors": { "human_name": "Number of Visitors", "value": 0, }, + "pi_affiliation": { + "human_name": "PI Affiliation", + "value": "ESS", + }, + "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", + }, "status_experiment": { "human_name": "UOS Experiment Status", "value": "ACTIVE", @@ -126,10 +194,42 @@ Test Abstract", "human_name": "Instrument Name", "value": "YMIR", }, + "local_contact_email": { + "human_name": "Local contact email", + "value": "junjie.quan@ess.eu", + }, + "local_contact_firstname": { + "human_name": "Local contact name", + "value": "Junjie", + }, + "local_contact_lastname": { + "human_name": "Local contact surname", + "value": "Quan", + }, "number_of_visitors": { "human_name": "Number of Visitors", "value": 0, }, + "pi_affiliation": { + "human_name": "PI Affiliation", + "value": "ESS", + }, + "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", + }, "status_experiment": { "human_name": "UOS Experiment Status", "value": "ACTIVE", 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 index dce6907..06dd4d3 100644 --- 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 @@ -105,6 +105,10 @@ exports[`getCreateScicatProposalDto includes co-PI, DAU and instrument metadata "human_name": "Number of Instruments", "value": 1, }, + "pi_affiliation": { + "human_name": "PI Affiliation", + "value": "ESS", + }, "pi_email": { "human_name": "PI Email", "value": "john.doe@example.com", @@ -178,6 +182,10 @@ exports[`getCreateScicatProposalDto maps proposal to create DTO correctly 1`] = "human_name": "Number of Instruments", "value": 0, }, + "pi_affiliation": { + "human_name": "PI Affiliation", + "value": "ESS", + }, "pi_email": { "human_name": "PI Email", "value": "john.doe@example.com", @@ -251,6 +259,10 @@ exports[`getUpdateScicatProposalDto maps proposal to update DTO correctly 1`] = "human_name": "Number of Instruments", "value": 0, }, + "pi_affiliation": { + "human_name": "PI Affiliation", + "value": "ESS", + }, "pi_email": { "human_name": "PI Email", "value": "john.doe@example.com", 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 118e7f3..90026d1 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.spec.ts @@ -37,6 +37,14 @@ const createBaseUoExperiment = ( }, }, visit: null, + localContact: { + id: 8, + firstname: 'Junjie', + lastname: 'Quan', + email: 'junjie.quan@ess.eu', + oidcSub: 'junjiequan', + institution: 'Other', + }, ...overrides, }); @@ -77,6 +85,58 @@ describe('getCreateScicatExperimentDto', () => { expect(dto).toMatchSnapshot(); }); + it('maps the proposer institution to the pi_affiliation metadata entry', () => { + const dto = getCreateScicatExperimentDto( + createBaseUoExperiment(), + instrumentIds + ); + + expect(dto.metadata?.['pi_affiliation']).toEqual({ + human_name: 'PI Affiliation', + value: 'ESS', + }); + }); + + it('leaves the pi_affiliation value undefined when the proposer has no institution', () => { + const experiment = createBaseUoExperiment(); + delete experiment.proposal.proposer.institution; + + const dto = getCreateScicatExperimentDto(experiment, instrumentIds); + + expect(dto.metadata?.['pi_affiliation']).toEqual({ + human_name: 'PI Affiliation', + value: undefined, + }); + }); + + it('maps the local contact to metadata entries', () => { + const dto = getCreateScicatExperimentDto( + createBaseUoExperiment(), + instrumentIds + ); + + expect(dto.metadata?.['local_contact_firstname']).toEqual({ + human_name: 'Local contact name', + value: 'Junjie', + }); + expect(dto.metadata?.['local_contact_email']).toEqual({ + human_name: 'Local contact email', + value: 'junjie.quan@ess.eu', + }); + }); + + it('falls back to null local contact entries when no local contact is assigned', () => { + const dto = getCreateScicatExperimentDto( + createBaseUoExperiment({ localContact: null }), + instrumentIds + ); + + expect(dto.metadata?.['local_contact_firstname']).toEqual({ + human_name: 'Local contact name', + value: null, + }); + }); + it('skips visitor entries when user is null', () => { const dto = getCreateScicatExperimentDto( createBaseUoExperiment({ @@ -101,6 +161,18 @@ describe('getUpdateScicatExperimentDto', () => { expect(dto).toMatchSnapshot(); }); + it('maps the proposer institution to the pi_affiliation metadata entry', () => { + const dto = getUpdateScicatExperimentDto( + createBaseUoExperiment(), + instrumentIds + ); + + expect(dto.metadata?.['pi_affiliation']).toEqual({ + human_name: 'PI Affiliation', + value: 'ESS', + }); + }); + it('should not include proposalId', () => { const dto = getUpdateScicatExperimentDto( createBaseUoExperiment(), diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts index 673ed3c..61c9cc1 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatExperiment.mapper.ts @@ -19,7 +19,8 @@ import { scicatApi } from '../utils/scicatApi'; // ── Experiment ──────────────────────────────────────────────────────────────── // ────────────────────────────────────────────────────────────────────────────── const buildMetadata = (experiment: UOExperimentDto): MdEntry => { - const { proposal, instrument, visit } = experiment; + const { proposal, instrument, visit, localContact } = experiment; + const { proposer } = proposal; const registrations = visit?.registrations ?? []; const rows: [string, MdEntryValue][] = [ @@ -33,7 +34,27 @@ const buildMetadata = (experiment: UOExperimentDto): MdEntry => { 'UOS Experiment Status', experiment.status ), + 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('pi_affiliation', 'PI Affiliation', proposer.institution), metadataEntry('instrument_name', 'Instrument Name', instrument.name), + metadataEntry( + 'local_contact_firstname', + 'Local contact name', + localContact?.firstname || null + ), + metadataEntry( + 'local_contact_lastname', + 'Local contact surname', + localContact?.lastname || null + ), + metadataEntry( + 'local_contact_email', + 'Local contact email', + localContact?.email || null + ), metadataEntry( 'number_of_visitors', 'Number of Visitors', @@ -64,6 +85,11 @@ const buildMetadata = (experiment: UOExperimentDto): MdEntry => { `visitor_${i}_orcid`, `Visitor ${i} ORCID`, registration.user.oidcSub + ), + metadataEntry( + `visitor_${i}_affiliation`, + `Visitor ${i} Affiliation`, + registration.user.institution ) ); }); diff --git a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts index 186d818..37a8375 100644 --- a/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts +++ b/src/queue/consumers/scicat/scicatProposal/mappers/uoToScicatProposal.mapper.ts @@ -23,6 +23,7 @@ const buildMetadata = (proposal: UOProposalDto): MdEntry => { metadataEntry('pi_lastname', 'PI Last Name', proposer.lastname), metadataEntry('pi_email', 'PI Email', proposer.email), metadataEntry('pi_orcid', 'PI ORCID', proposer.oidcSub), + metadataEntry('pi_affiliation', 'PI Affiliation', proposer.institution), metadataEntry('number_of_co_is', 'Number of CoIs', users.length), metadataEntry( 'number_of_dau', diff --git a/src/services/userOfficeApi/queries/getExperiment.query.ts b/src/services/userOfficeApi/queries/getExperiment.query.ts index 3a3a62f..746a57c 100644 --- a/src/services/userOfficeApi/queries/getExperiment.query.ts +++ b/src/services/userOfficeApi/queries/getExperiment.query.ts @@ -30,6 +30,9 @@ fragment experiment on Experiment { proposalPk status localContactId + localContact { + ...basicUserDetails + } instrumentId createdAt updatedAt diff --git a/src/services/userOfficeApi/type/uoExperiment.type.ts b/src/services/userOfficeApi/type/uoExperiment.type.ts index 9c4e3a1..1fd85d2 100644 --- a/src/services/userOfficeApi/type/uoExperiment.type.ts +++ b/src/services/userOfficeApi/type/uoExperiment.type.ts @@ -32,6 +32,7 @@ export interface UOExperimentDto { UOProposalDto, 'proposalId' | 'title' | 'abstract' | 'status' | 'proposer' >; + localContact?: UOUser | null; visit?: { registrations: { status: string; From b85e77cb00f374086ddd0790246d46df863ded0b Mon Sep 17 00:00:00 2001 From: Janos Babik <143906591+janosbabik@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:00:36 +0200 Subject: [PATCH 08/10] fix(validateProposalMessage): ensure submitted status is a boolean (#708) --- .../utils/validateProposalMessage.spec.ts | 45 +++++++++++++++++++ .../utils/validateProposalMessage.ts | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/queue/consumers/utils/validateProposalMessage.spec.ts b/src/queue/consumers/utils/validateProposalMessage.spec.ts index 1f60886..f4e9a2d 100644 --- a/src/queue/consumers/utils/validateProposalMessage.spec.ts +++ b/src/queue/consumers/utils/validateProposalMessage.spec.ts @@ -29,4 +29,49 @@ describe('Validate messages', () => { }) ).not.toThrow(); }); + + it('should accept a false submitted status', () => { + expect(() => + validateProposalMessage({ + title: 'Test proposal', + abstract: 'Test abstract', + members: [], + proposalPk: 1, + shortCode: '123123', + instruments: [{ id: 1, shortCode: 'TEST', allocatedTime: 1 }], + newStatus: 'REVIEW', + callId: 123, + submitted: false, + proposer: { + id: 1, + firstName: 'Test', + lastName: 'User', + email: 'test.user@email.com', + oidcSub: 'testOidcSub', + }, + }) + ).not.toThrow(); + }); + + it('should throw when submitted status is missing', () => { + expect(() => + validateProposalMessage({ + title: 'Test proposal', + abstract: 'Test abstract', + members: [], + proposalPk: 1, + shortCode: '123123', + instruments: [{ id: 1, shortCode: 'TEST', allocatedTime: 1 }], + newStatus: 'REVIEW', + callId: 123, + proposer: { + id: 1, + firstName: 'Test', + lastName: 'User', + email: 'test.user@email.com', + oidcSub: 'testOidcSub', + }, + }) + ).toThrow('Proposal Submitted status is missing'); + }); }); diff --git a/src/queue/consumers/utils/validateProposalMessage.ts b/src/queue/consumers/utils/validateProposalMessage.ts index 5dee51b..aa063c7 100644 --- a/src/queue/consumers/utils/validateProposalMessage.ts +++ b/src/queue/consumers/utils/validateProposalMessage.ts @@ -33,7 +33,7 @@ export function validateProposalMessage( throw new Error('Proposal CallId is missing'); } - if (!proposalMessage.submitted) { + if (typeof proposalMessage.submitted !== 'boolean') { throw new Error('Proposal Submitted status is missing'); } From 0a0b045aea424d22b4e2109aeba1369b00698d06 Mon Sep 17 00:00:00 2001 From: Janos Babik <143906591+janosbabik@users.noreply.github.com> Date: Tue, 11 Aug 2026 09:32:29 +0200 Subject: [PATCH 09/10] fix: Fix startup error handling and correct the ExperimentCreationQueueConsumer's exchange name (#711) --- .github/workflows/build-push.yml | 109 ++++++++++++++---- .github/workflows/github-tag-and-release.yml | 12 +- .github/workflows/lint.yml | 6 +- .github/workflows/test-build.yml | 102 +++++++++++++--- src/queue/consumers/QueueConsumer.spec.ts | 27 +++++ src/queue/consumers/QueueConsumer.ts | 11 +- .../ExperimentCreationQueueConsumer.ts | 2 +- 7 files changed, 219 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 34e526f..cfe69f8 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -7,24 +7,91 @@ on: - develop - staging +permissions: + contents: read + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} + permissions: + contents: read + packages: write + + # Build each platform on a native runner instead of emulating arm64 with + # QEMU, which crashes intermittently during npm ci (see + # https://github.com/tonistiigi/binfmt/issues/215). + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + - platform: linux/arm64 + runner: ubuntu-24.04-arm # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 + + - name: Prepare platform pair + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> "$GITHUB_ENV" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v7 + with: + context: . + platforms: ${{ matrix.platform }} + outputs: type=image,name=ghcr.io/userofficeproject/connector,push-by-digest=true,name-canonical=true,push=true - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Export digest + run: | + mkdir -p "${{ runner.temp }}/digests" + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + needs: build + permissions: + contents: read + packages: write + + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} @@ -33,10 +100,10 @@ jobs: - name: Extract branch name id: extract_branch uses: swapActions/get-branch-name@v1 - + - name: Create image tags id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ghcr.io/userofficeproject/connector flavor: latest=true # adds :latest tag to outputs.tags @@ -44,21 +111,13 @@ jobs: type=sha,format=long,prefix= type=raw,value=${{ steps.extract_branch.outputs.branch }} - - name: Build and push - id: docker_build - uses: docker/build-push-action@v5 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'ghcr.io/userofficeproject/connector@sha256:%s ' *) - - name: Trigger pipeline - if: ${{ steps.extract_branch.outputs.branch == 'staging' }} # Only trigger on staging branch - uses: swapActions/trigger-swap-deployment@v1 - with: - repository: ${{ github.event.repository.name }} - environment: ${{ steps.extract_branch.outputs.branch }} - gh-trigger-url: ${{ secrets.GITLAB_TRIGGER_URL }} - gh-token: ${{ secrets.GITLAB_TRIGGER_TOKEN }} - image-tag: ${{ github.sha }} + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/userofficeproject/connector:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml index fb46e9a..0055931 100644 --- a/.github/workflows/github-tag-and-release.yml +++ b/.github/workflows/github-tag-and-release.yml @@ -5,14 +5,14 @@ on: - master env: - NODE_VERSION: 18.x + NODE_VERSION: 22.x jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Bump version and push tag id: tag_version @@ -28,20 +28,20 @@ jobs: body: ${{ steps.tag_version.outputs.changelog }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64/v8 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f116e1a..7d90297 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,7 +5,7 @@ on: branches: [develop, master] env: - NODE_VERSION: 18.x + NODE_VERSION: 22.x jobs: run-linters: @@ -14,10 +14,10 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v7 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 8d9f949..33a70a1 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -9,7 +9,10 @@ on: - staging env: - NODE_VERSION: 18.x + NODE_VERSION: 22.x + +permissions: + contents: read # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -19,10 +22,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Use Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v7 with: node-version: ${{ env.NODE_VERSION }} @@ -30,31 +33,102 @@ jobs: - run: npm test build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} needs: test + permissions: + contents: read + packages: write + + # Build each platform on a native runner instead of emulating arm64 with + # QEMU, which crashes intermittently during npm ci (see + # https://github.com/tonistiigi/binfmt/issues/215). + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + - platform: linux/arm64 + runner: ubuntu-24.04-arm steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Prepare platform pair + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> "$GITHUB_ENV" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GitHub Container Registry # Don't login if dependabot is creating the PR if: ${{ !startsWith(github.head_ref, 'dependabot') }} - uses: docker/login-action@v2 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v5 + - name: Build and push by digest + id: build + uses: docker/build-push-action@v7 + with: + platforms: ${{ matrix.platform }} + outputs: type=image,name=ghcr.io/userofficeproject/connector,push-by-digest=true,name-canonical=true,push=${{ !startsWith(github.head_ref, 'dependabot') }} + + - name: Export digest + if: ${{ !startsWith(github.head_ref, 'dependabot') }} + run: | + mkdir -p "${{ runner.temp }}/digests" + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + if: ${{ !startsWith(github.head_ref, 'dependabot') }} + uses: actions/upload-artifact@v4 with: - platforms: linux/amd64,linux/arm64 - push: ${{ !startsWith(github.head_ref, 'dependabot') }} - tags: ghcr.io/userofficeproject/connector:${{ github.head_ref }} + name: digests-${{ env.PLATFORM_PAIR }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + needs: build + # Nothing was pushed for dependabot PRs, so there is nothing to merge. + if: ${{ !startsWith(github.head_ref, 'dependabot') }} + permissions: + contents: read + packages: write + + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create \ + -t ghcr.io/userofficeproject/connector:${{ github.head_ref }} \ + $(printf 'ghcr.io/userofficeproject/connector@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/userofficeproject/connector:${{ github.head_ref }} diff --git a/src/queue/consumers/QueueConsumer.spec.ts b/src/queue/consumers/QueueConsumer.spec.ts index fe9eff7..c825808 100644 --- a/src/queue/consumers/QueueConsumer.spec.ts +++ b/src/queue/consumers/QueueConsumer.spec.ts @@ -37,6 +37,33 @@ describe('QueueConsumer', () => { ); }); + it('should log startup errors triggered by construction', async () => { + const exitSpy = jest + .spyOn(process, 'exit') + .mockImplementation((() => undefined) as never); + + class MissingQueueNameConsumer extends TestQueueConsumer { + getQueueName() { + return ''; + } + } + + new MissingQueueNameConsumer(messageBrokerMock); + await Promise.resolve(); + + expect(logger.logException).toHaveBeenCalledWith( + 'Error while starting QueueConsumer', + { + error: + 'Queue name variable not set for consumer MissingQueueNameConsumer', + consumer: 'MissingQueueNameConsumer', + } + ); + expect(exitSpy).toHaveBeenCalledWith(1); + + exitSpy.mockRestore(); + }); + it('should throw error if exchange name is not set', async () => { queueConsumer.getExchangeName = jest.fn(); diff --git a/src/queue/consumers/QueueConsumer.ts b/src/queue/consumers/QueueConsumer.ts index 85c8288..a9b2744 100644 --- a/src/queue/consumers/QueueConsumer.ts +++ b/src/queue/consumers/QueueConsumer.ts @@ -17,7 +17,16 @@ export abstract class QueueConsumer { constructor(messageBroker: MessageBroker) { this.messageBroker = messageBroker; logger.logInfo(`QueueConsumer ${this.constructor.name} created`, {}); - this.start(); + void this.start().catch((error) => { + logger.logException('Error while starting QueueConsumer', { + error: (error as Error).message, + consumer: this.constructor.name, + }); + + // Fail fast so the orchestrator restarts the process instead of leaving + // a silently broken consumer that no longer processes its queue. + process.exit(1); + }); } abstract getQueueName(): string; diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts index 95888dc..118dfbe 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts @@ -22,7 +22,7 @@ export class ExperimentCreationQueueConsumer extends QueueConsumer { } getExchangeName(): string { - return process.env.EXPERIMENT_CREATION_EXCHANGE_NAME as string; + return process.env.USER_OFFICE_CORE_EXCHANGE_NAME as string; } onMessage: ConsumerCallback = async (type, message) => { From cf4823ca205210bd736fa05e5cbd12741a145850 Mon Sep 17 00:00:00 2001 From: Janos Babik <143906591+janosbabik@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:24:58 +0200 Subject: [PATCH 10/10] fix: Await upsert operations in Experiment and Proposal consumers (#712) --- .../ExperimentCreationQueueConsumer.spec.ts | 87 +++++++++++++++++++ .../ExperimentCreationQueueConsumer.ts | 2 +- .../ProposalCreationQueueConsumer.spec.ts | 87 +++++++++++++++++++ .../ProposalCreationQueueConsumer.ts | 2 +- 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.spec.ts create mode 100644 src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.spec.ts diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.spec.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.spec.ts new file mode 100644 index 0000000..014c073 --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.spec.ts @@ -0,0 +1,87 @@ +jest.mock('../../../utils/hasTriggeringStatus'); +jest.mock('../../../utils/hasTriggeringType'); +jest.mock('../../../utils/validateExperimentMessage'); +jest.mock('../consumerCallbacks/upsertProposalInScicat'); +jest.mock('../../../QueueConsumer', () => ({ + QueueConsumer: jest.fn().mockImplementation(() => ({ + start: jest.fn(), + })), +})); + +import { MessageBroker } from '@user-office-software/duo-message-broker'; + +import { ExperimentCreationQueueConsumer } from './ExperimentCreationQueueConsumer'; +import { hasTriggringExperimentStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringType } from '../../../utils/hasTriggeringType'; +import { validateExperimentMessage } from '../../../utils/validateExperimentMessage'; +import { upsertExperimentInScicat } from '../consumerCallbacks/upsertProposalInScicat'; + +describe('ExperimentCreationQueueConsumer', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should not process the message when it does not have the correct type', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(false); + + const consumer = new ExperimentCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).resolves.not.toThrow(); + expect(upsertExperimentInScicat).not.toHaveBeenCalled(); + }); + + it('should not process the message when it does not have the correct status', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); + (hasTriggringExperimentStatus as jest.Mock).mockReturnValueOnce(false); + + const consumer = new ExperimentCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).resolves.not.toThrow(); + expect(upsertExperimentInScicat).not.toHaveBeenCalled(); + }); + + it('should upsert the experiment when the message has the correct type and status', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); + (hasTriggringExperimentStatus as jest.Mock).mockReturnValueOnce(true); + (validateExperimentMessage as jest.Mock).mockReturnValueOnce({ + experimentPk: 1, + }); + (upsertExperimentInScicat as jest.Mock).mockResolvedValueOnce(undefined); + + const consumer = new ExperimentCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).resolves.not.toThrow(); + expect(upsertExperimentInScicat).toHaveBeenCalledWith({ experimentPk: 1 }); + }); + + it('should propagate errors from the upsert so the message is not acknowledged', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); + (hasTriggringExperimentStatus as jest.Mock).mockReturnValueOnce(true); + (validateExperimentMessage as jest.Mock).mockReturnValueOnce({ + experimentPk: 1, + }); + (upsertExperimentInScicat as jest.Mock).mockRejectedValueOnce( + new Error('UOS GraphQL errors') + ); + + const consumer = new ExperimentCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).rejects.toThrow('UOS GraphQL errors'); + }); +}); diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts index 118dfbe..07c23eb 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ExperimentCreationQueueConsumer.ts @@ -43,6 +43,6 @@ export class ExperimentCreationQueueConsumer extends QueueConsumer { const experimentMessage = validateExperimentMessage(message); - upsertExperimentInScicat(experimentMessage); + await upsertExperimentInScicat(experimentMessage); }; } diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.spec.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.spec.ts new file mode 100644 index 0000000..d33444f --- /dev/null +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.spec.ts @@ -0,0 +1,87 @@ +jest.mock('../../../utils/hasTriggeringStatus'); +jest.mock('../../../utils/hasTriggeringType'); +jest.mock('../../../utils/validateProposalMessage'); +jest.mock('../consumerCallbacks/upsertProposalInScicat'); +jest.mock('../../../QueueConsumer', () => ({ + QueueConsumer: jest.fn().mockImplementation(() => ({ + start: jest.fn(), + })), +})); + +import { MessageBroker } from '@user-office-software/duo-message-broker'; + +import { ProposalCreationQueueConsumer } from './ProposalCreationQueueConsumer'; +import { hasTriggeringProposalStatus } from '../../../utils/hasTriggeringStatus'; +import { hasTriggeringType } from '../../../utils/hasTriggeringType'; +import { validateProposalMessage } from '../../../utils/validateProposalMessage'; +import { upsertProposalInScicat } from '../consumerCallbacks/upsertProposalInScicat'; + +describe('ProposalCreationQueueConsumer', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should not process the message when it does not have the correct type', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(false); + + const consumer = new ProposalCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).resolves.not.toThrow(); + expect(upsertProposalInScicat).not.toHaveBeenCalled(); + }); + + it('should not process the message when it does not have the correct status', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(false); + + const consumer = new ProposalCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).resolves.not.toThrow(); + expect(upsertProposalInScicat).not.toHaveBeenCalled(); + }); + + it('should upsert the proposal when the message has the correct type and status', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(true); + (validateProposalMessage as jest.Mock).mockReturnValueOnce({ + proposalPk: 1, + }); + (upsertProposalInScicat as jest.Mock).mockResolvedValueOnce(undefined); + + const consumer = new ProposalCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).resolves.not.toThrow(); + expect(upsertProposalInScicat).toHaveBeenCalledWith({ proposalPk: 1 }); + }); + + it('should propagate errors from the upsert so the message is not acknowledged', async () => { + (hasTriggeringType as jest.Mock).mockReturnValueOnce(true); + (hasTriggeringProposalStatus as jest.Mock).mockReturnValueOnce(true); + (validateProposalMessage as jest.Mock).mockReturnValueOnce({ + proposalPk: 1, + }); + (upsertProposalInScicat as jest.Mock).mockRejectedValueOnce( + new Error('UOS GraphQL errors') + ); + + const consumer = new ProposalCreationQueueConsumer({} as MessageBroker); + + await expect( + consumer.onMessage('type', { message: 'message' }, { + headers: {}, + } as any) + ).rejects.toThrow('UOS GraphQL errors'); + }); +}); diff --git a/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts b/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts index 0a700cb..589601e 100644 --- a/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts +++ b/src/queue/consumers/scicat/scicatProposal/consumers/ProposalCreationQueueConsumer.ts @@ -41,6 +41,6 @@ export class ProposalCreationQueueConsumer extends QueueConsumer { } const proposalMessage = validateProposalMessage(message); - upsertProposalInScicat(proposalMessage); + await upsertProposalInScicat(proposalMessage); }; }