From 9563820335aa7ab4e07f02704b465234c2784ee7 Mon Sep 17 00:00:00 2001 From: Christian Felder Date: Thu, 18 Dec 2025 23:40:07 +0100 Subject: [PATCH 001/120] Fixup optimistic concurrency control If the time send by the client is equal to the ressource on the server, the clients updated version is based on servers version with that time. or in other words: the client has taken into account the ressource on the server b/c the client should use the timestamp received with the ressource from the server. from the RFC: > The origin server MUST NOT perform the requested method > if the selected representation's last modification date is more > recent than the date provided in the field-value Client receives t0 Client sends update w/ t0 -> OK Server is on t1 Client received t0 (previously) Client sends update w/ t0 -> FAIL Change-Id: Ibdff18c17a8b43523cec88ac8b9c16a94fd77617 --- src/common/utils/check-unmodified-since.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utils/check-unmodified-since.ts b/src/common/utils/check-unmodified-since.ts index 70dab4743..bed35ad84 100644 --- a/src/common/utils/check-unmodified-since.ts +++ b/src/common/utils/check-unmodified-since.ts @@ -21,7 +21,7 @@ export function checkUnmodifiedSince( const headerDate = new Date(headerDateString); if (isNaN(headerDate.getTime())) return; - if (headerDate <= resourceDate) { + if (headerDate < resourceDate) { throw new PreconditionFailedException( "Resource has been modified on server", ); From 2b63e5e5b6351392e84240f07014b8a5cf0f55cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:18:17 +0000 Subject: [PATCH 002/120] build(deps-dev): bump @types/node from 25.0.10 to 25.2.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.0.10 to 25.2.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.2.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c5d752d8a..7afba69a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4916,9 +4916,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", - "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", + "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", "license": "MIT", "dependencies": { "undici-types": "~7.16.0" From 32b34d74434fd9697ce732ccdabec970646a9a76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:28:17 +0000 Subject: [PATCH 003/120] build(deps-dev): bump @types/nodemailer from 7.0.5 to 7.0.9 Bumps [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer) from 7.0.5 to 7.0.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer) --- updated-dependencies: - dependency-name: "@types/nodemailer" dependency-version: 7.0.9 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 5548 +++++++++++++++++---------------------------- 1 file changed, 2071 insertions(+), 3477 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7afba69a7..4c5a19e51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -242,4264 +242,2898 @@ "tslib": "^2.1.0" } }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, + "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "node_modules/@babel/core": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, + "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@aws-sdk/client-sesv2": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sesv2/-/client-sesv2-3.876.0.tgz", - "integrity": "sha512-cu8yNNX5q07K+81lMN5KR6iMduql0rX3SRYdOVcjOZ/35amPn4Q+Dyqs8guIhBupRMCxROmilpS5EMpe3QTqOA==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.876.0", - "@aws-sdk/credential-provider-node": "3.876.0", - "@aws-sdk/middleware-host-header": "3.873.0", - "@aws-sdk/middleware-logger": "3.876.0", - "@aws-sdk/middleware-recursion-detection": "3.873.0", - "@aws-sdk/middleware-user-agent": "3.876.0", - "@aws-sdk/region-config-resolver": "3.873.0", - "@aws-sdk/signature-v4-multi-region": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-endpoints": "3.873.0", - "@aws-sdk/util-user-agent-browser": "3.873.0", - "@aws-sdk/util-user-agent-node": "3.876.0", - "@smithy/config-resolver": "^4.1.5", - "@smithy/core": "^3.8.0", - "@smithy/fetch-http-handler": "^5.1.1", - "@smithy/hash-node": "^4.0.5", - "@smithy/invalid-dependency": "^4.0.5", - "@smithy/middleware-content-length": "^4.0.5", - "@smithy/middleware-endpoint": "^4.1.18", - "@smithy/middleware-retry": "^4.1.19", - "@smithy/middleware-serde": "^4.0.9", - "@smithy/middleware-stack": "^4.0.5", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/node-http-handler": "^4.1.1", - "@smithy/protocol-http": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.26", - "@smithy/util-defaults-mode-node": "^4.0.26", - "@smithy/util-endpoints": "^3.0.7", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-retry": "^4.0.7", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.876.0.tgz", - "integrity": "sha512-Vf0PMF7HVpvllrfPODnBZmlz6kT/y2AvOt1RQG3+qD0VrHWzShc5nwgRZ+yyP3xkKVhZsQ3sJapfZTFnjqMOYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.876.0", - "@aws-sdk/middleware-host-header": "3.873.0", - "@aws-sdk/middleware-logger": "3.876.0", - "@aws-sdk/middleware-recursion-detection": "3.873.0", - "@aws-sdk/middleware-user-agent": "3.876.0", - "@aws-sdk/region-config-resolver": "3.873.0", - "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-endpoints": "3.873.0", - "@aws-sdk/util-user-agent-browser": "3.873.0", - "@aws-sdk/util-user-agent-node": "3.876.0", - "@smithy/config-resolver": "^4.1.5", - "@smithy/core": "^3.8.0", - "@smithy/fetch-http-handler": "^5.1.1", - "@smithy/hash-node": "^4.0.5", - "@smithy/invalid-dependency": "^4.0.5", - "@smithy/middleware-content-length": "^4.0.5", - "@smithy/middleware-endpoint": "^4.1.18", - "@smithy/middleware-retry": "^4.1.19", - "@smithy/middleware-serde": "^4.0.9", - "@smithy/middleware-stack": "^4.0.5", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/node-http-handler": "^4.1.1", - "@smithy/protocol-http": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.26", - "@smithy/util-defaults-mode-node": "^4.0.26", - "@smithy/util-endpoints": "^3.0.7", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-retry": "^4.0.7", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "devOptional": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-sdk/core": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.876.0.tgz", - "integrity": "sha512-sVFBFkdoPOPyY13NaXO1E/R9O5J6ixzHnnRbqrbXYM2QQgLNPTKIiRtmVEuVoFV9YULg+/aKm7caix8m468y9w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.862.0", - "@aws-sdk/xml-builder": "3.873.0", - "@smithy/core": "^3.8.0", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/property-provider": "^4.0.5", - "@smithy/protocol-http": "^5.1.3", - "@smithy/signature-v4": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-utf8": "^4.0.0", - "fast-xml-parser": "5.2.5", - "tslib": "^2.6.2" - }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "devOptional": true, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.876.0.tgz", - "integrity": "sha512-cof7lwp2AlrAfRs0pt4W2KMS2VMBvEmpcti1UOFfSJIqkn+cyJliMJ8LHg22GI+kUexjvxdAqSbf3M7OHvEW+w==", + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/property-provider": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.876.0.tgz", - "integrity": "sha512-wzmef2NBp2+X1l8D4Q8hx1G8oI3+WdvLdPev9VnVpRYZxYGRWVPl++wvCBsCn/ZL0mdWopPkhHA3kFexQhMzvg==", + "node_modules/@babel/helpers": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", + "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/fetch-http-handler": "^5.1.1", - "@smithy/node-http-handler": "^4.1.1", - "@smithy/property-provider": "^4.0.5", - "@smithy/protocol-http": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/util-stream": "^4.2.4", - "tslib": "^2.6.2" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" } }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.876.0.tgz", - "integrity": "sha512-JHbW6fqnJsVjGHCyko7B0NVPT1nEAPxkM3CGjUcVGsHgJBkxOLVCMQqTRyHcDdeHR2qeojlLoOHRz97xIHQjYw==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "devOptional": true, + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/credential-provider-env": "3.876.0", - "@aws-sdk/credential-provider-http": "3.876.0", - "@aws-sdk/credential-provider-process": "3.876.0", - "@aws-sdk/credential-provider-sso": "3.876.0", - "@aws-sdk/credential-provider-web-identity": "3.876.0", - "@aws-sdk/nested-clients": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/credential-provider-imds": "^4.0.7", - "@smithy/property-provider": "^4.0.5", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=18.0.0" + "node": ">=6.0.0" } }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.876.0.tgz", - "integrity": "sha512-eHbNt1+Hi43e8ANnwf6toapLSxfMiyGq459y3Uh6i7NBOiWWKEsOVcgOfUC3RCoqeikxovt1tFM2cEElWUIOhg==", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/credential-provider-env": "3.876.0", - "@aws-sdk/credential-provider-http": "3.876.0", - "@aws-sdk/credential-provider-ini": "3.876.0", - "@aws-sdk/credential-provider-process": "3.876.0", - "@aws-sdk/credential-provider-sso": "3.876.0", - "@aws-sdk/credential-provider-web-identity": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/credential-provider-imds": "^4.0.7", - "@smithy/property-provider": "^4.0.5", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.876.0.tgz", - "integrity": "sha512-SMX4OlHvspu3gF4hxe7WAnZFhxpiCye+WlBSVoWfW/i9XNhtrZS1JMr29MK34GlCTk9qO7FlRwds/Z5k7xPpHg==", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/property-provider": "^4.0.5", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.876.0.tgz", - "integrity": "sha512-iP5dz9XqwePbgnh7Bdrq5e1319JpCRKLyomUfHH1XVeXkIHmwIJdmTj1Upeo1J8L/5cLHmhXAN6CTN11bLo8SA==", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/client-sso": "3.876.0", - "@aws-sdk/core": "3.876.0", - "@aws-sdk/token-providers": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/property-provider": "^4.0.5", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.12.13" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.876.0.tgz", - "integrity": "sha512-q/XSCP1uae5aB9veM8zcm6Gqu6A4ckX9ZbhHgCzURXVJDwp+nINW1hM9vppMjGw3ND9Ibx/adR+KfTI0TDMzqw==", + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/nested-clients": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/property-provider": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.873.0.tgz", - "integrity": "sha512-KZ/W1uruWtMOs7D5j3KquOxzCnV79KQW9MjJFZM/M0l6KI8J6V3718MXxFHsTjUE4fpdV6SeCNLV1lwGygsjJA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.862.0", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "node": ">=6.9.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.876.0.tgz", - "integrity": "sha512-cpWJhOuMSyz9oV25Z/CMHCBTgafDCbv7fHR80nlRrPdPZ8ETNsahwRgltXP1QJJ8r3X/c1kwpOR7tc+RabVzNA==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/types": "3.862.0", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.873.0.tgz", - "integrity": "sha512-OtgY8EXOzRdEWR//WfPkA/fXl0+WwE8hq0y9iw2caNyKPtca85dzrrZWnPqyBK/cpImosrpR1iKMYr41XshsCg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.862.0", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "node": ">=6.9.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.876.0.tgz", - "integrity": "sha512-h+TDs9EKAfXnrkogQpQz3o11zvs6Vh9+ehxyd35OcM7evnDeoV4GFjjnAKq+MxbBk/5Ewnvng+d6/WQDvMbj7Q==", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-arn-parser": "3.873.0", - "@smithy/core": "^3.8.0", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/protocol-http": "^5.1.3", - "@smithy/signature-v4": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-stream": "^4.2.4", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.876.0.tgz", - "integrity": "sha512-FR+8INfnbNv32QDQ5szxkWX6mB/QgezfNyx8LnAh1ErISZMmEFBxXXir+ZOfuV8vsmal1a6cy9qmnMNDaNnaNQ==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-endpoints": "3.873.0", - "@smithy/core": "^3.8.0", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/nested-clients": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.876.0.tgz", - "integrity": "sha512-R4TZrkM2gUElTsotk8mt3y7iLG8TNi1LL1wgVdEEWSLOYTaFyglGdoNBMtEeP7lmXilaTy00AbYF6BakJvSTHg==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.876.0", - "@aws-sdk/middleware-host-header": "3.873.0", - "@aws-sdk/middleware-logger": "3.876.0", - "@aws-sdk/middleware-recursion-detection": "3.873.0", - "@aws-sdk/middleware-user-agent": "3.876.0", - "@aws-sdk/region-config-resolver": "3.873.0", - "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-endpoints": "3.873.0", - "@aws-sdk/util-user-agent-browser": "3.873.0", - "@aws-sdk/util-user-agent-node": "3.876.0", - "@smithy/config-resolver": "^4.1.5", - "@smithy/core": "^3.8.0", - "@smithy/fetch-http-handler": "^5.1.1", - "@smithy/hash-node": "^4.0.5", - "@smithy/invalid-dependency": "^4.0.5", - "@smithy/middleware-content-length": "^4.0.5", - "@smithy/middleware-endpoint": "^4.1.18", - "@smithy/middleware-retry": "^4.1.19", - "@smithy/middleware-serde": "^4.0.9", - "@smithy/middleware-stack": "^4.0.5", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/node-http-handler": "^4.1.1", - "@smithy/protocol-http": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.26", - "@smithy/util-defaults-mode-node": "^4.0.26", - "@smithy/util-endpoints": "^3.0.7", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-retry": "^4.0.7", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.873.0.tgz", - "integrity": "sha512-q9sPoef+BBG6PJnc4x60vK/bfVwvRWsPgcoQyIra057S/QGjq5VkjvNk6H8xedf6vnKlXNBwq9BaANBXnldUJg==", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/types": "3.862.0", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/types": "^4.3.2", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.876.0.tgz", - "integrity": "sha512-OMDcuaVlC2rbze92w4QcNfuEA0IeT2GsT1ByZCwe+Y9tZwxzj7fCiOOU0UmJfa+juuQ/YBzVYxnkrkz3Rg6DEw==", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/protocol-http": "^5.1.3", - "@smithy/signature-v4": "^5.1.3", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.876.0.tgz", - "integrity": "sha512-iU08kaQbhXnY0CC2TBcr7y/2PqPwZP2CTWX/Rbq0NvhOyteikfh7ASC+bRfLUp0XMSHKvSb+w2dh8a0lvx4oHg==", + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/nested-clients": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/property-provider": "^4.0.5", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/types": { - "version": "3.862.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.862.0.tgz", - "integrity": "sha512-Bei+RL0cDxxV+lW2UezLbCYYNeJm6Nzee0TpW0FfyTRBhH9C1XQh4+x+IClriXvgBnRquTMMYsmJfvx8iyLKrg==", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.873.0.tgz", - "integrity": "sha512-qag+VTqnJWDn8zTAXX4wiVioa0hZDQMtbZcGRERVnLar4/3/VIKBhxX2XibNQXFu1ufgcRn4YntT/XEPecFWcg==", + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.873.0.tgz", - "integrity": "sha512-YByHrhjxYdjKRf/RQygRK1uh0As1FIi9+jXTcIEX/rBgN8mUByczr2u4QXBzw7ZdbdcOBMOkPnLRjNOWW1MkFg==", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/types": "3.862.0", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "@smithy/util-endpoints": "^3.0.7", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.873.0.tgz", - "integrity": "sha512-xcVhZF6svjM5Rj89T1WzkjQmrTF6dpR2UvIHPMTnSZoNe6CixejPZ6f0JJ2kAhO8H+dUHwNBlsUgOTIKiK/Syg==", + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.873.0.tgz", - "integrity": "sha512-AcRdbK6o19yehEcywI43blIBhOCSo6UgyWcuOJX5CFF8k39xm1ILCjQlRRjchLAxWrm0lU0Q7XV90RiMMFMZtA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.862.0", - "@smithy/types": "^4.3.2", - "bowser": "^2.11.0", - "tslib": "^2.6.2" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.876.0.tgz", - "integrity": "sha512-/ZIaeUt60JBdI0mNc7sZ8v3Tuzp8Pbe4gIAYnppGyF4KV8QA+Yu8tp2bGHfkKn150t1uvQ6P/4CwFfoGF34dzg==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.876.0", - "@aws-sdk/types": "3.862.0", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" }, "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.873.0.tgz", - "integrity": "sha512-kLO7k7cGJ6KaHiExSJWojZurF7SnGMDHXRuQunFnEoD0n1yB6Lqy/S/zHiQ7oJnBhPr9q0TW9qFkrsZb1Uc54w==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { - "node": ">=18.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", + "node_modules/@babel/runtime": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { + "node_modules/@babel/traverse": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", + "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", - "dev": true, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "devOptional": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true, + "license": "MIT" + }, + "node_modules/@casl/ability": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.8.0.tgz", + "integrity": "sha512-Ipt4mzI4gSgnomFdaPjaLgY2MWuXqAEZLrU6qqWBB7khGiBBuuEp6ytYDnq09bRXqcjaeeHiaCvCGFbBA2SpvA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "@ucast/mongo2js": "^1.3.0" }, - "engines": { - "node": ">=6.9.0" + "funding": { + "url": "https://github.com/stalniy/casl/blob/master/BACKERS.md" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/@casl/mongoose": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@casl/mongoose/-/mongoose-8.0.5.tgz", + "integrity": "sha512-dCUFBtNFLBKH01eDKFfC0DXfZGQimtFkxfzMfRAuURkbRM7aYOKzr3Yd5dTe30q2sDP6ocLtFKA0YM5DcprBnw==", + "license": "MIT", + "peerDependencies": { + "@casl/ability": "^6.7.0", + "mongoose": "^6.0.13 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true, "engines": { - "node": ">=6.9.0" + "node": ">=0.1.90" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@css-inline/css-inline": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline/-/css-inline-0.14.1.tgz", + "integrity": "sha512-u4eku+hnPqqHIGq/ZUQcaP0TrCbYeLIYBaK7qClNRGZbnh8RC4gVxLEIo8Pceo1nOK9E5G4Lxzlw5KnXcvflfA==", "engines": { - "node": ">=6.9.0" + "node": ">= 10" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "optionalDependencies": { + "@css-inline/css-inline-android-arm-eabi": "0.14.1", + "@css-inline/css-inline-android-arm64": "0.14.1", + "@css-inline/css-inline-darwin-arm64": "0.14.1", + "@css-inline/css-inline-darwin-x64": "0.14.1", + "@css-inline/css-inline-linux-arm-gnueabihf": "0.14.1", + "@css-inline/css-inline-linux-arm64-gnu": "0.14.1", + "@css-inline/css-inline-linux-arm64-musl": "0.14.1", + "@css-inline/css-inline-linux-x64-gnu": "0.14.1", + "@css-inline/css-inline-linux-x64-musl": "0.14.1", + "@css-inline/css-inline-win32-x64-msvc": "0.14.1" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "license": "MIT", + "node_modules/@css-inline/css-inline-android-arm-eabi": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm-eabi/-/css-inline-android-arm-eabi-0.14.1.tgz", + "integrity": "sha512-LNUR8TY4ldfYi0mi/d4UNuHJ+3o8yLQH9r2Nt6i4qeg1i7xswfL3n/LDLRXvGjBYqeEYNlhlBQzbPwMX1qrU6A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">= 10" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "devOptional": true, - "license": "MIT", + "node_modules/@css-inline/css-inline-android-arm64": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm64/-/css-inline-android-arm64-0.14.1.tgz", + "integrity": "sha512-tH5us0NYGoTNBHOUHVV7j9KfJ4DtFOeTLA3cM0XNoMtArNu2pmaaBMFJPqECzavfXkLc7x5Z22UPZYjoyHfvCA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">= 10" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "devOptional": true, - "license": "MIT", + "node_modules/@css-inline/css-inline-darwin-arm64": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-arm64/-/css-inline-darwin-arm64-0.14.1.tgz", + "integrity": "sha512-QE5W1YRIfRayFrtrcK/wqEaxNaqLULPI0gZB4ArbFRd3d56IycvgBasDTHPre5qL2cXCO3VyPx+80XyHOaVkag==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">= 10" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", + "node_modules/@css-inline/css-inline-darwin-x64": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-x64/-/css-inline-darwin-x64-0.14.1.tgz", + "integrity": "sha512-mAvv2sN8awNFsbvBzlFkZPbCNZ6GCWY5/YcIz7V5dPYw+bHHRbjnlkNTEZq5BsDxErVrMIGvz05PGgzuNvZvdQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">= 10" } }, - "node_modules/@babel/helpers": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", - "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" - }, + "node_modules/@css-inline/css-inline-linux-arm-gnueabihf": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm-gnueabihf/-/css-inline-linux-arm-gnueabihf-0.14.1.tgz", + "integrity": "sha512-AWC44xL0X7BgKvrWEqfSqkT2tJA5kwSGrAGT+m0gt11wnTYySvQ6YpX0fTY9i3ppYGu4bEdXFjyK2uY1DTQMHA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">= 10" } }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, + "node_modules/@css-inline/css-inline-linux-arm64-gnu": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-gnu/-/css-inline-linux-arm64-gnu-0.14.1.tgz", + "integrity": "sha512-drj0ciiJgdP3xKXvNAt4W+FH4KKMs8vB5iKLJ3HcH07sNZj58Sx++2GxFRS1el3p+GFp9OoYA6dgouJsGEqt0Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@css-inline/css-inline-linux-arm64-musl": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-musl/-/css-inline-linux-arm64-musl-0.14.1.tgz", + "integrity": "sha512-FzknI+st8eA8YQSdEJU9ykcM0LZjjigBuynVF5/p7hiMm9OMP8aNhWbhZ8LKJpKbZrQsxSGS4g9Vnr6n6FiSdQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, + "node_modules/@css-inline/css-inline-linux-x64-gnu": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-gnu/-/css-inline-linux-x64-gnu-0.14.1.tgz", + "integrity": "sha512-yubbEye+daDY/4vXnyASAxH88s256pPati1DfVoZpU1V0+KP0BZ1dByZOU1ktExurbPH3gZOWisAnBE9xon0Uw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@css-inline/css-inline-linux-x64-musl": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-musl/-/css-inline-linux-x64-musl-0.14.1.tgz", + "integrity": "sha512-6CRAZzoy1dMLPC/tns2rTt1ZwPo0nL/jYBEIAsYTCWhfAnNnpoLKVh5Nm+fSU3OOwTTqU87UkGrFJhObD/wobQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@css-inline/css-inline-win32-x64-msvc": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-x64-msvc/-/css-inline-win32-x64-msvc-0.14.1.tgz", + "integrity": "sha512-nzotGiaiuiQW78EzsiwsHZXbxEt6DiMUFcDJ6dhiliomXxnlaPyBfZb6/FMBgRJOf6sknDt/5695OttNmbMYzg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "license": "MIT", + "node_modules/@elastic/elasticsearch": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.19.1.tgz", + "integrity": "sha512-+1j9NnQVOX+lbWB8LhCM7IkUmjU05Y4+BmSLfusq0msCsQb1Va+OUKFCoOXjCJqQrcgdRdQCjYYyolQ/npQALQ==", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@elastic/transport": "^8.9.6", + "apache-arrow": "18.x - 21.x", + "tslib": "^2.4.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "license": "MIT", + "node_modules/@elastic/transport": { + "version": "8.9.6", + "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.9.6.tgz", + "integrity": "sha512-v71jgmZtgPg2ouXF5KTPxU1a6z7YYc8nazAS7jLySteC/vrShs1OJh6oEEeo5oDc19MYUofV/JV1h5vqJVBXOw==", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@opentelemetry/api": "1.x", + "debug": "^4.4.0", + "hpagent": "^1.2.0", + "ms": "^2.1.3", + "secure-json-parse": "^3.0.1", + "tslib": "^2.8.1", + "undici": "^6.21.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "node_modules/@emnapi/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", + "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "node_modules/@emnapi/runtime": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", + "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@eslint/core": "^0.17.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@types/json-schema": "^7.0.15" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "regenerator-runtime": "^0.14.0" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "node_modules/@faker-js/faker": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.2.0.tgz", + "integrity": "sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0", + "npm": ">=10" } }, - "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "node_modules/@hapi/address": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz", + "integrity": "sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" + "@hapi/hoek": "^11.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.0.0" } }, - "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@hapi/formula": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-3.0.2.tgz", + "integrity": "sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==", + "dev": true, + "license": "BSD-3-Clause" }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "node_modules/@hapi/hoek": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.7.tgz", + "integrity": "sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause" }, - "node_modules/@casl/ability": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.8.0.tgz", - "integrity": "sha512-Ipt4mzI4gSgnomFdaPjaLgY2MWuXqAEZLrU6qqWBB7khGiBBuuEp6ytYDnq09bRXqcjaeeHiaCvCGFbBA2SpvA==", - "license": "MIT", - "dependencies": { - "@ucast/mongo2js": "^1.3.0" - }, - "funding": { - "url": "https://github.com/stalniy/casl/blob/master/BACKERS.md" + "node_modules/@hapi/pinpoint": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.1.tgz", + "integrity": "sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/tlds": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.3.tgz", + "integrity": "sha512-QIvUMB5VZ8HMLZF9A2oWr3AFM430QC8oGd0L35y2jHpuW6bIIca6x/xL7zUf4J7L9WJ3qjz+iJII8ncaeMbpSg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@casl/mongoose": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@casl/mongoose/-/mongoose-8.0.5.tgz", - "integrity": "sha512-dCUFBtNFLBKH01eDKFfC0DXfZGQimtFkxfzMfRAuURkbRM7aYOKzr3Yd5dTe30q2sDP6ocLtFKA0YM5DcprBnw==", - "license": "MIT", - "peerDependencies": { - "@casl/ability": "^6.7.0", - "mongoose": "^6.0.13 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "node_modules/@hapi/topo": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-6.0.2.tgz", + "integrity": "sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^11.0.2" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, "engines": { - "node": ">=0.1.90" + "node": ">=18.18.0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=12" + "node": ">=18.18.0" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@css-inline/css-inline": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline/-/css-inline-0.14.1.tgz", - "integrity": "sha512-u4eku+hnPqqHIGq/ZUQcaP0TrCbYeLIYBaK7qClNRGZbnh8RC4gVxLEIo8Pceo1nOK9E5G4Lxzlw5KnXcvflfA==", - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@css-inline/css-inline-android-arm-eabi": "0.14.1", - "@css-inline/css-inline-android-arm64": "0.14.1", - "@css-inline/css-inline-darwin-arm64": "0.14.1", - "@css-inline/css-inline-darwin-x64": "0.14.1", - "@css-inline/css-inline-linux-arm-gnueabihf": "0.14.1", - "@css-inline/css-inline-linux-arm64-gnu": "0.14.1", - "@css-inline/css-inline-linux-arm64-musl": "0.14.1", - "@css-inline/css-inline-linux-x64-gnu": "0.14.1", - "@css-inline/css-inline-linux-x64-musl": "0.14.1", - "@css-inline/css-inline-win32-x64-msvc": "0.14.1" - } - }, - "node_modules/@css-inline/css-inline-android-arm-eabi": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm-eabi/-/css-inline-android-arm-eabi-0.14.1.tgz", - "integrity": "sha512-LNUR8TY4ldfYi0mi/d4UNuHJ+3o8yLQH9r2Nt6i4qeg1i7xswfL3n/LDLRXvGjBYqeEYNlhlBQzbPwMX1qrU6A==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-android-arm64": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm64/-/css-inline-android-arm64-0.14.1.tgz", - "integrity": "sha512-tH5us0NYGoTNBHOUHVV7j9KfJ4DtFOeTLA3cM0XNoMtArNu2pmaaBMFJPqECzavfXkLc7x5Z22UPZYjoyHfvCA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-darwin-arm64": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-arm64/-/css-inline-darwin-arm64-0.14.1.tgz", - "integrity": "sha512-QE5W1YRIfRayFrtrcK/wqEaxNaqLULPI0gZB4ArbFRd3d56IycvgBasDTHPre5qL2cXCO3VyPx+80XyHOaVkag==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-darwin-x64": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-x64/-/css-inline-darwin-x64-0.14.1.tgz", - "integrity": "sha512-mAvv2sN8awNFsbvBzlFkZPbCNZ6GCWY5/YcIz7V5dPYw+bHHRbjnlkNTEZq5BsDxErVrMIGvz05PGgzuNvZvdQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-linux-arm-gnueabihf": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm-gnueabihf/-/css-inline-linux-arm-gnueabihf-0.14.1.tgz", - "integrity": "sha512-AWC44xL0X7BgKvrWEqfSqkT2tJA5kwSGrAGT+m0gt11wnTYySvQ6YpX0fTY9i3ppYGu4bEdXFjyK2uY1DTQMHA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-linux-arm64-gnu": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-gnu/-/css-inline-linux-arm64-gnu-0.14.1.tgz", - "integrity": "sha512-drj0ciiJgdP3xKXvNAt4W+FH4KKMs8vB5iKLJ3HcH07sNZj58Sx++2GxFRS1el3p+GFp9OoYA6dgouJsGEqt0Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-linux-arm64-musl": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-musl/-/css-inline-linux-arm64-musl-0.14.1.tgz", - "integrity": "sha512-FzknI+st8eA8YQSdEJU9ykcM0LZjjigBuynVF5/p7hiMm9OMP8aNhWbhZ8LKJpKbZrQsxSGS4g9Vnr6n6FiSdQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-linux-x64-gnu": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-gnu/-/css-inline-linux-x64-gnu-0.14.1.tgz", - "integrity": "sha512-yubbEye+daDY/4vXnyASAxH88s256pPati1DfVoZpU1V0+KP0BZ1dByZOU1ktExurbPH3gZOWisAnBE9xon0Uw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-linux-x64-musl": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-musl/-/css-inline-linux-x64-musl-0.14.1.tgz", - "integrity": "sha512-6CRAZzoy1dMLPC/tns2rTt1ZwPo0nL/jYBEIAsYTCWhfAnNnpoLKVh5Nm+fSU3OOwTTqU87UkGrFJhObD/wobQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@css-inline/css-inline-win32-x64-msvc": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-x64-msvc/-/css-inline-win32-x64-msvc-0.14.1.tgz", - "integrity": "sha512-nzotGiaiuiQW78EzsiwsHZXbxEt6DiMUFcDJ6dhiliomXxnlaPyBfZb6/FMBgRJOf6sknDt/5695OttNmbMYzg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "license": "MIT", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@elastic/elasticsearch": { - "version": "8.19.1", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.19.1.tgz", - "integrity": "sha512-+1j9NnQVOX+lbWB8LhCM7IkUmjU05Y4+BmSLfusq0msCsQb1Va+OUKFCoOXjCJqQrcgdRdQCjYYyolQ/npQALQ==", - "license": "Apache-2.0", - "dependencies": { - "@elastic/transport": "^8.9.6", - "apache-arrow": "18.x - 21.x", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@elastic/transport": { - "version": "8.9.6", - "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.9.6.tgz", - "integrity": "sha512-v71jgmZtgPg2ouXF5KTPxU1a6z7YYc8nazAS7jLySteC/vrShs1OJh6oEEeo5oDc19MYUofV/JV1h5vqJVBXOw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "1.x", - "debug": "^4.4.0", - "hpagent": "^1.2.0", - "ms": "^2.1.3", - "secure-json-parse": "^3.0.1", - "tslib": "^2.8.1", - "undici": "^6.21.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@faker-js/faker": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.2.0.tgz", - "integrity": "sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/fakerjs" - } - ], - "license": "MIT", - "engines": { - "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0", - "npm": ">=10" - } - }, - "node_modules/@hapi/address": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz", - "integrity": "sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^11.0.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@hapi/formula": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-3.0.2.tgz", - "integrity": "sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/hoek": { - "version": "11.0.7", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.7.tgz", - "integrity": "sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/pinpoint": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.1.tgz", - "integrity": "sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/tlds": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.3.tgz", - "integrity": "sha512-QIvUMB5VZ8HMLZF9A2oWr3AFM430QC8oGd0L35y2jHpuW6bIIca6x/xL7zUf4J7L9WJ3qjz+iJII8ncaeMbpSg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@hapi/topo": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-6.0.2.tgz", - "integrity": "sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^11.0.2" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@inquirer/ansi": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", - "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/checkbox": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", - "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.2", - "@inquirer/core": "^10.3.2", - "@inquirer/figures": "^1.0.15", - "@inquirer/type": "^3.0.10", - "yoctocolors-cjs": "^2.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/confirm": { - "version": "5.1.21", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", - "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/type": "^3.0.10" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/core": { - "version": "10.3.2", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", - "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.2", - "@inquirer/figures": "^1.0.15", - "@inquirer/type": "^3.0.10", - "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", - "signal-exit": "^4.1.0", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/editor": { - "version": "4.2.23", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", - "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/external-editor": "^1.0.3", - "@inquirer/type": "^3.0.10" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/expand": { - "version": "4.0.23", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", - "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/type": "^3.0.10", - "yoctocolors-cjs": "^2.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/external-editor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", - "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^2.1.1", - "iconv-lite": "^0.7.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", - "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@inquirer/figures": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", - "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/input": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", - "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/type": "^3.0.10" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/number": { - "version": "3.0.23", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", - "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/type": "^3.0.10" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/password": { - "version": "4.0.23", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", - "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.2", - "@inquirer/core": "^10.3.2", - "@inquirer/type": "^3.0.10" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/prompts": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", - "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/checkbox": "^4.3.2", - "@inquirer/confirm": "^5.1.21", - "@inquirer/editor": "^4.2.23", - "@inquirer/expand": "^4.0.23", - "@inquirer/input": "^4.3.1", - "@inquirer/number": "^3.0.23", - "@inquirer/password": "^4.0.23", - "@inquirer/rawlist": "^4.1.11", - "@inquirer/search": "^3.2.2", - "@inquirer/select": "^4.4.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/rawlist": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", - "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/type": "^3.0.10", - "yoctocolors-cjs": "^2.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/search": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", - "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.2", - "@inquirer/figures": "^1.0.15", - "@inquirer/type": "^3.0.10", - "yoctocolors-cjs": "^2.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/select": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", - "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.2", - "@inquirer/core": "^10.3.2", - "@inquirer/figures": "^1.0.15", - "@inquirer/type": "^3.0.10", - "yoctocolors-cjs": "^2.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/type": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", - "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" + "node": ">=18.18" }, - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=12.22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@jest/console": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", - "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "slash": "^3.0.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" } }, - "node_modules/@jest/core": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", - "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.2.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-changed-files": "30.2.0", - "jest-config": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-resolve-dependencies": "30.2.0", - "jest-runner": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "jest-watcher": "30.2.0", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", - "slash": "^3.0.0" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "@types/node": ">=18" }, "peerDependenciesMeta": { - "node-notifier": { + "@types/node": { "optional": true } } }, - "node_modules/@jest/core/node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-mock": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "dev": true, "license": "MIT", "dependencies": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" + "node": ">=18" }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", - "@types/node": "*", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "peerDependencies": { + "@types/node": ">=18" }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dev": true, "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dev": true, "license": "MIT", "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^5.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "slash": "^3.0.0", - "string-length": "^4.0.2", - "v8-to-istanbul": "^9.0.1" + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "@types/node": ">=18" }, "peerDependenciesMeta": { - "node-notifier": { + "@types/node": { "optional": true } } }, - "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" } }, - "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/test-result": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", - "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.2.0", - "@jest/types": "30.2.0", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "slash": "^3.0.0" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, "engines": { - "node": ">=6.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsep-plugin/assignment": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", - "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", "engines": { - "node": ">= 10.16.0" + "node": ">=18" }, "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jsep-plugin/regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", - "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" + "node": "20 || >=22" } }, - "node_modules/@lukeed/csprng": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", - "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, "engines": { - "node": ">=8" + "node": "20 || >=22" } }, - "node_modules/@microsoft/tsdoc": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", - "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", - "license": "MIT" - }, - "node_modules/@mongodb-js/saslprep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.1.tgz", - "integrity": "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg==", - "license": "MIT", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dependencies": { - "sparse-bitfield": "^3.0.3" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@nestjs-modules/mailer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.0.2.tgz", - "integrity": "sha512-+z4mADQasg0H1ZaGu4zZTuKv2pu+XdErqx99PLFPzCDNTN/q9U59WPgkxVaHnsvKHNopLj5Xap7G4ZpptduoYw==", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dependencies": { - "@css-inline/css-inline": "0.14.1", - "glob": "10.3.12" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, - "optionalDependencies": { - "@types/ejs": "^3.1.5", - "@types/mjml": "^4.7.4", - "@types/pug": "^2.0.10", - "ejs": "^3.1.10", - "handlebars": "^4.7.8", - "liquidjs": "^10.11.1", - "mjml": "^4.15.3", - "preview-email": "^3.0.19", - "pug": "^3.0.2" + "engines": { + "node": ">=12" }, - "peerDependencies": { - "@nestjs/common": ">=7.0.9", - "@nestjs/core": ">=7.0.9", - "@types/ejs": ">=3.0.3", - "@types/mjml": ">=4.7.4", - "@types/pug": ">=2.0.6", - "ejs": ">=3.1.2", - "handlebars": ">=4.7.6", - "liquidjs": ">=10.8.2", - "mjml": ">=4.15.3", - "nodemailer": ">=6.4.6", - "preview-email": ">=3.0.19", - "pug": ">=3.0.1" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@nestjs/axios": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", - "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "license": "MIT", - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "axios": "^1.3.1", - "rxjs": "^7.0.0" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "node_modules/@nestjs/cli": { - "version": "11.0.16", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.16.tgz", - "integrity": "sha512-P0H+Vcjki6P5160E5QnMt3Q0X5FTg4PZkP99Ig4lm/4JWqfw32j3EXv3YBTJ2DmxLwOQ/IS9F7dzKpMAgzKTGg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.19", - "@angular-devkit/schematics": "19.2.19", - "@angular-devkit/schematics-cli": "19.2.19", - "@inquirer/prompts": "7.10.1", - "@nestjs/schematics": "^11.0.1", - "ansis": "4.2.0", - "chokidar": "4.0.3", - "cli-table3": "0.6.5", - "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "9.1.0", - "glob": "13.0.0", - "node-emoji": "1.11.0", - "ora": "5.4.1", - "tsconfig-paths": "4.2.0", - "tsconfig-paths-webpack-plugin": "4.2.0", - "typescript": "5.9.3", - "webpack": "5.104.1", - "webpack-node-externals": "3.0.0" - }, - "bin": { - "nest": "bin/nest.js" - }, "engines": { - "node": ">= 20.11" - }, - "peerDependencies": { - "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0", - "@swc/core": "^1.3.62" - }, - "peerDependenciesMeta": { - "@swc/cli": { - "optional": true - }, - "@swc/core": { - "optional": true - } + "node": ">=6" } }, - "node_modules/@nestjs/cli/node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/@nestjs/cli/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@nestjs/cli/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/@nestjs/cli/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "p-try": "^2.0.0" }, "engines": { - "node": "20 || >=22" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@nestjs/common": { - "version": "11.0.13", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.0.13.tgz", - "integrity": "sha512-cXqXJPQTcJIYqT8GtBYqjYY9sklCBqp/rh9z1R40E60gWnsU598YIQWkojSFRI9G7lT/+uF+jqSrg/CMPBk7QQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", "dependencies": { - "iterare": "1.2.1", - "tslib": "2.8.1", - "uid": "2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "class-transformer": "*", - "class-validator": "*", - "reflect-metadata": "^0.1.12 || ^0.2.0", - "rxjs": "^7.1.0" + "p-limit": "^2.2.0" }, - "peerDependenciesMeta": { - "class-transformer": { - "optional": true - }, - "class-validator": { - "optional": true - } + "engines": { + "node": ">=8" } }, - "node_modules/@nestjs/config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", - "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", - "dependencies": { - "dotenv": "16.4.7", - "dotenv-expand": "12.0.1", - "lodash": "4.17.21" - }, - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "rxjs": "^7.1.0" + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/@nestjs/config/node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "license": "BSD-2-Clause", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" + "node": ">=8" } }, - "node_modules/@nestjs/config/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" + "node_modules/@jest/console": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", + "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@nestjs/core": { - "version": "11.0.13", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.0.13.tgz", - "integrity": "sha512-1xjrsYjff4sg4MfvF+/NInOq+7oI1D1vK8Yj9wkrbBH1dM+h2At71tccbFfl/eJUt4ckZlH+XmROnt/T0daYcA==", - "hasInstallScript": true, + "node_modules/@jest/core": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", + "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@nuxt/opencollective": "0.4.1", - "fast-safe-stringify": "2.1.1", - "iterare": "1.2.1", - "path-to-regexp": "8.2.0", - "tslib": "2.8.1", - "uid": "2.0.2" + "@jest/console": "30.2.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.2.0", + "jest-config": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-resolve-dependencies": "30.2.0", + "jest-runner": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "jest-watcher": "30.2.0", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0" }, "engines": { - "node": ">= 20" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@nestjs/common": "^11.0.0", - "@nestjs/microservices": "^11.0.0", - "@nestjs/platform-express": "^11.0.0", - "@nestjs/websockets": "^11.0.0", - "reflect-metadata": "^0.1.12 || ^0.2.0", - "rxjs": "^7.1.0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - }, - "@nestjs/websockets": { + "node-notifier": { "optional": true } } }, - "node_modules/@nestjs/elasticsearch": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@nestjs/elasticsearch/-/elasticsearch-11.1.0.tgz", - "integrity": "sha512-NwMakVs8LeXUksaSNp0ejhv223yVCK4w9iqMBrsonKj2gl4sBIBrAgJq/aXhD9bJCNLYb+waoRAsxuuPxYcjXw==", + "node_modules/@jest/core/node_modules/ci-info": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", + "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", - "peerDependencies": { - "@elastic/elasticsearch": "^7.4.0 || ^8.0.0 || ^9.0.0", - "@nestjs/common": "^10.0.0 || ^11.0.0", - "rxjs": "^7.2.0" + "engines": { + "node": ">=8" } }, - "node_modules/@nestjs/event-emitter": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/event-emitter/-/event-emitter-3.0.1.tgz", - "integrity": "sha512-0Ln/x+7xkU6AJFOcQI9tIhUMXVF7D5itiaQGOyJbXtlAfAIt8gzDdJm+Im7cFzKoWkiW5nCXCPh6GSvdQd/3Dw==", + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", + "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "dev": true, + "license": "MIT", "dependencies": { - "eventemitter2": "6.4.9" + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0" }, - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "@nestjs/core": "^10.0.0 || ^11.0.0" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/jwt": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.2.tgz", - "integrity": "sha512-rK8aE/3/Ma45gAWfCksAXUNbOoSOUudU0Kn3rT39htPF7wsYXtKfjALKeKKJbFrIWbLjsbqfXX5bIJNvgBugGA==", + "node_modules/@jest/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "dev": true, "license": "MIT", "dependencies": { - "@types/jsonwebtoken": "9.0.10", - "jsonwebtoken": "9.0.3" + "expect": "30.2.0", + "jest-snapshot": "30.2.0" }, - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/mapped-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", - "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "class-transformer": "^0.4.0 || ^0.5.0", - "class-validator": "^0.13.0 || ^0.14.0", - "reflect-metadata": "^0.1.12 || ^0.2.0" + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" }, - "peerDependenciesMeta": { - "class-transformer": { - "optional": true - }, - "class-validator": { - "optional": true - } + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/mongoose": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-11.0.4.tgz", - "integrity": "sha512-LUOlUeSOfbjdIu22QwOmczv2CzJQr9LUBo2mOfbXrGCu2svpr5Hiu71zBFrb/9UC+H8BjGMKbBOq1nEbMF6ZJA==", + "node_modules/@jest/fake-timers": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", + "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "dev": true, "license": "MIT", - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "@nestjs/core": "^10.0.0 || ^11.0.0", - "mongoose": "^7.0.0 || ^8.0.0 || ^9.0.0", - "rxjs": "^7.0.0" + "dependencies": { + "@jest/types": "30.2.0", + "@sinonjs/fake-timers": "^13.0.0", + "@types/node": "*", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/passport": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz", - "integrity": "sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==", - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "passport": "^0.5.0 || ^0.6.0 || ^0.7.0" + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/platform-express": { - "version": "11.1.12", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.12.tgz", - "integrity": "sha512-GYK/vHI0SGz5m8mxr7v3Urx8b9t78Cf/dj5aJMZlGd9/1D9OI1hAl00BaphjEXINUJ/BQLxIlF2zUjrYsd6enQ==", + "node_modules/@jest/globals": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", + "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "dev": true, "license": "MIT", "dependencies": { - "cors": "2.8.5", - "express": "5.2.1", - "multer": "2.0.2", - "path-to-regexp": "8.3.0", - "tslib": "2.8.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/types": "30.2.0", + "jest-mock": "30.2.0" }, - "peerDependencies": { - "@nestjs/common": "^11.0.0", - "@nestjs/core": "^11.0.0" - } - }, - "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/schematics": { - "version": "11.0.9", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.9.tgz", - "integrity": "sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==", + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.17", - "@angular-devkit/schematics": "19.2.17", - "comment-json": "4.4.1", - "jsonc-parser": "3.3.1", - "pluralize": "8.0.0" + "@types/node": "*", + "jest-regex-util": "30.0.1" }, - "peerDependencies": { - "typescript": ">=4.8.2" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.17.tgz", - "integrity": "sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==", + "node_modules/@jest/reporters": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "chokidar": "^4.0.0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "chokidar": { + "node-notifier": { "optional": true } } }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.17.tgz", - "integrity": "sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==", + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.17", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" + "@sinclair/typebox": "^0.34.0" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/schematics/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@jest/snapshot-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", + "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@nestjs/swagger": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.2.5.tgz", - "integrity": "sha512-wCykbEybMqiYcvkyzPW4SbXKcwra9AGdajm0MvFgKR3W+gd1hfeKlo67g/s9QCRc/mqUU4KOE5Qtk7asMeFuiA==", "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "0.16.0", - "@nestjs/mapped-types": "2.1.0", - "js-yaml": "4.1.1", - "lodash": "4.17.21", - "path-to-regexp": "8.3.0", - "swagger-ui-dist": "5.31.0" - }, - "peerDependencies": { - "@fastify/static": "^8.0.0 || ^9.0.0", - "@nestjs/common": "^11.0.1", - "@nestjs/core": "^11.0.1", - "class-transformer": "*", - "class-validator": "*", - "reflect-metadata": "^0.1.12 || ^0.2.0" + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" }, - "peerDependenciesMeta": { - "@fastify/static": { - "optional": true - }, - "class-transformer": { - "optional": true - }, - "class-validator": { - "optional": true - } + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/swagger/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/@nestjs/swagger/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "dev": true, "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@nestjs/terminus": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-11.0.0.tgz", - "integrity": "sha512-c55LOo9YGovmQHtFUMa/vDaxGZ2cglMTZejqgHREaApt/GArTfgYYGwhRXPLq8ZwiQQlLuYB+79e9iA8mlDSLA==", "dependencies": { - "boxen": "5.1.2", - "check-disk-space": "3.4.0" - }, - "peerDependencies": { - "@grpc/grpc-js": "*", - "@grpc/proto-loader": "*", - "@mikro-orm/core": "*", - "@mikro-orm/nestjs": "*", - "@nestjs/axios": "^2.0.0 || ^3.0.0 || ^4.0.0", - "@nestjs/common": "^10.0.0 || ^11.0.0", - "@nestjs/core": "^10.0.0 || ^11.0.0", - "@nestjs/microservices": "^10.0.0 || ^11.0.0", - "@nestjs/mongoose": "^11.0.0", - "@nestjs/sequelize": "^10.0.0 || ^11.0.0", - "@nestjs/typeorm": "^10.0.0 || ^11.0.0", - "@prisma/client": "*", - "mongoose": "*", - "reflect-metadata": "0.1.x || 0.2.x", - "rxjs": "7.x", - "sequelize": "*", - "typeorm": "*" + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" }, - "peerDependenciesMeta": { - "@grpc/grpc-js": { - "optional": true - }, - "@grpc/proto-loader": { - "optional": true - }, - "@mikro-orm/core": { - "optional": true - }, - "@mikro-orm/nestjs": { - "optional": true - }, - "@nestjs/axios": { - "optional": true - }, - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/mongoose": { - "optional": true - }, - "@nestjs/sequelize": { - "optional": true - }, - "@nestjs/typeorm": { - "optional": true - }, - "@prisma/client": { - "optional": true - }, - "mongoose": { - "optional": true - }, - "sequelize": { - "optional": true - }, - "typeorm": { - "optional": true - } + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nestjs/testing": { - "version": "11.1.12", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.12.tgz", - "integrity": "sha512-W0M/i5nb9qRQpTQfJm+1mGT/+y4YezwwdcD7mxFG8JEZ5fz/ZEAk1Ayri2VBJKJUdo20B1ggnvqew4dlTMrSNg==", + "node_modules/@jest/test-result": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", + "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", "dev": true, "license": "MIT", "dependencies": { - "tslib": "2.8.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@nestjs/common": "^11.0.0", - "@nestjs/core": "^11.0.0", - "@nestjs/microservices": "^11.0.0", - "@nestjs/platform-express": "^11.0.0" + "@jest/console": "30.2.0", + "@jest/types": "30.2.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" }, - "peerDependenciesMeta": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - } + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@jest/test-sequencer": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", "dev": true, - "engines": { - "node": "^14.21.3 || >=16" + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "slash": "^3.0.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@nuxt/opencollective": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", - "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "node_modules/@jest/transform": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", + "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "dev": true, + "license": "MIT", "dependencies": { - "consola": "^3.2.3" - }, - "bin": { - "opencollective": "bin/opencollective.js" + "@babel/core": "^7.27.4", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" }, "engines": { - "node": "^14.18.0 || >=16.10.0", - "npm": ">=5.10.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@one-ini/wasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", - "optional": true - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, "engines": { - "node": ">=8.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@paralleldrive/cuid2": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", - "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "dev": true, + "license": "MIT", "dependencies": { - "@noble/hashes": "^1.1.5" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { - "node": ">=14" + "node": ">=6.0.0" } }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/@scarf/scarf": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", - "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", - "hasInstallScript": true + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, - "node_modules/@selderee/plugin-htmlparser2": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", - "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", - "optional": true, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", "dependencies": { - "domhandler": "^5.0.3", - "selderee": "^0.11.0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", + "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", + "engines": { + "node": ">= 10.16.0" }, - "funding": { - "url": "https://ko-fi.com/killymxi" + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" } }, - "node_modules/@sinclair/typebox": { - "version": "0.34.38", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.38.tgz", - "integrity": "sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==", - "dev": true, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", + "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", + "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", "license": "MIT" }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, + "node_modules/@mongodb-js/saslprep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.1.tgz", + "integrity": "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg==", + "license": "MIT", "dependencies": { - "type-detect": "4.0.8" + "sparse-bitfield": "^3.0.3" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "optional": true, "dependencies": { - "@sinonjs/commons": "^3.0.1" + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" } }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", - "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/@nestjs-modules/mailer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.0.2.tgz", + "integrity": "sha512-+z4mADQasg0H1ZaGu4zZTuKv2pu+XdErqx99PLFPzCDNTN/q9U59WPgkxVaHnsvKHNopLj5Xap7G4ZpptduoYw==", "dependencies": { - "@sinonjs/commons": "^3.0.1", - "type-detect": "^4.1.0" + "@css-inline/css-inline": "0.14.1", + "glob": "10.3.12" + }, + "optionalDependencies": { + "@types/ejs": "^3.1.5", + "@types/mjml": "^4.7.4", + "@types/pug": "^2.0.10", + "ejs": "^3.1.10", + "handlebars": "^4.7.8", + "liquidjs": "^10.11.1", + "mjml": "^4.15.3", + "preview-email": "^3.0.19", + "pug": "^3.0.2" + }, + "peerDependencies": { + "@nestjs/common": ">=7.0.9", + "@nestjs/core": ">=7.0.9", + "@types/ejs": ">=3.0.3", + "@types/mjml": ">=4.7.4", + "@types/pug": ">=2.0.6", + "ejs": ">=3.1.2", + "handlebars": ">=4.7.6", + "liquidjs": ">=10.8.2", + "mjml": ">=4.15.3", + "nodemailer": ">=6.4.6", + "preview-email": ">=3.0.19", + "pug": ">=3.0.1" } }, - "node_modules/@sinonjs/samsam/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "node_modules/@nestjs/axios": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", + "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "axios": "^1.3.1", + "rxjs": "^7.0.0" + } + }, + "node_modules/@nestjs/cli": { + "version": "11.0.16", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.16.tgz", + "integrity": "sha512-P0H+Vcjki6P5160E5QnMt3Q0X5FTg4PZkP99Ig4lm/4JWqfw32j3EXv3YBTJ2DmxLwOQ/IS9F7dzKpMAgzKTGg==", "dev": true, "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.19", + "@angular-devkit/schematics": "19.2.19", + "@angular-devkit/schematics-cli": "19.2.19", + "@inquirer/prompts": "7.10.1", + "@nestjs/schematics": "^11.0.1", + "ansis": "4.2.0", + "chokidar": "4.0.3", + "cli-table3": "0.6.5", + "commander": "4.1.1", + "fork-ts-checker-webpack-plugin": "9.1.0", + "glob": "13.0.0", + "node-emoji": "1.11.0", + "ora": "5.4.1", + "tsconfig-paths": "4.2.0", + "tsconfig-paths-webpack-plugin": "4.2.0", + "typescript": "5.9.3", + "webpack": "5.104.1", + "webpack-node-externals": "3.0.0" + }, + "bin": { + "nest": "bin/nest.js" + }, "engines": { - "node": ">=4" + "node": ">= 20.11" + }, + "peerDependencies": { + "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0", + "@swc/core": "^1.3.62" + }, + "peerDependenciesMeta": { + "@swc/cli": { + "optional": true + }, + "@swc/core": { + "optional": true + } } }, - "node_modules/@smithy/abort-controller": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.5.tgz", - "integrity": "sha512-jcrqdTQurIrBbUm4W2YdLVMQDoL0sA9DTxYd2s+R/y+2U9NLOP7Xf/YqfSg1FZhlZIYEnvk2mwbyvIfdLEPo8g==", + "node_modules/@nestjs/cli/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", "dev": true, - "license": "Apache-2.0", + "license": "BlueOak-1.0.0", "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" }, "engines": { - "node": ">=18.0.0" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@smithy/config-resolver": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.5.tgz", - "integrity": "sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg==", + "node_modules/@nestjs/cli/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.7", - "@smithy/util-middleware": "^4.2.7", - "tslib": "^2.6.2" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=18.0.0" + "node": "20 || >=22" } }, - "node_modules/@smithy/core": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.8.0.tgz", - "integrity": "sha512-EYqsIYJmkR1VhVE9pccnk353xhs+lB6btdutJEtsp7R055haMJp2yE16eSxw8fv+G0WUY6vqxyYOP8kOqawxYQ==", + "node_modules/@nestjs/cli/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "license": "Apache-2.0", + "license": "BlueOak-1.0.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.9", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-stream": "^4.2.4", - "@smithy/util-utf8": "^4.0.0", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/core/node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@smithy/core/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@smithy/credential-provider-imds": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.7.tgz", - "integrity": "sha512-dDzrMXA8d8riFNiPvytxn0mNwR4B3h8lgrQ5UjAGu6T9z/kRg/Xncf4tEQHE/+t25sY8IH3CowcmWi+1U5B1Gw==", + "node_modules/@nestjs/cli/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "dev": true, - "license": "Apache-2.0", + "license": "BlueOak-1.0.0", "dependencies": { - "@smithy/node-config-provider": "^4.1.4", - "@smithy/property-provider": "^4.0.5", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "tslib": "^2.6.2" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=18.0.0" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@smithy/fetch-http-handler": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.1.1.tgz", - "integrity": "sha512-61WjM0PWmZJR+SnmzaKI7t7G0UkkNFboDpzIdzSoy7TByUzlxo18Qlh9s71qug4AY4hlH/CwXdubMtkcNEb/sQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/common": { + "version": "11.0.13", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.0.13.tgz", + "integrity": "sha512-cXqXJPQTcJIYqT8GtBYqjYY9sklCBqp/rh9z1R40E60gWnsU598YIQWkojSFRI9G7lT/+uF+jqSrg/CMPBk7QQ==", "dependencies": { - "@smithy/protocol-http": "^5.1.3", - "@smithy/querystring-builder": "^4.0.5", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", - "tslib": "^2.6.2" + "iterare": "1.2.1", + "tslib": "2.8.1", + "uid": "2.0.2" }, - "engines": { - "node": ">=18.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "class-transformer": "*", + "class-validator": "*", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } } }, - "node_modules/@smithy/hash-node": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.5.tgz", - "integrity": "sha512-cv1HHkKhpyRb6ahD8Vcfb2Hgz67vNIXEp2vnhzfxLFGRukLCNEA5QdsorbUEzXma1Rco0u3rx5VTqbM06GcZqQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", + "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", "dependencies": { - "@smithy/types": "^4.3.2", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" + "dotenv": "16.4.7", + "dotenv-expand": "12.0.1", + "lodash": "4.17.21" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "rxjs": "^7.1.0" } }, - "node_modules/@smithy/invalid-dependency": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.5.tgz", - "integrity": "sha512-IVnb78Qtf7EJpoEVo7qJ8BEXQwgC4n3igeJNNKEj/MLYtapnx8A67Zt/J3RXAj2xSO1910zk0LdFiygSemuLow==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, + "node_modules/@nestjs/config/node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", "engines": { - "node": ">=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/@smithy/is-array-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/config/node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/@nestjs/core": { + "version": "11.0.13", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.0.13.tgz", + "integrity": "sha512-1xjrsYjff4sg4MfvF+/NInOq+7oI1D1vK8Yj9wkrbBH1dM+h2At71tccbFfl/eJUt4ckZlH+XmROnt/T0daYcA==", + "hasInstallScript": true, "dependencies": { - "tslib": "^2.6.2" + "@nuxt/opencollective": "0.4.1", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "path-to-regexp": "8.2.0", + "tslib": "2.8.1", + "uid": "2.0.2" }, "engines": { - "node": ">=18.0.0" + "node": ">= 20" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0", + "@nestjs/websockets": "^11.0.0", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + } } }, - "node_modules/@smithy/middleware-content-length": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.5.tgz", - "integrity": "sha512-l1jlNZoYzoCC7p0zCtBDE5OBXZ95yMKlRlftooE5jPWQn4YBPLgsp+oeHp7iMHaTGoUdFqmHOPa8c9G3gBsRpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node_modules/@nestjs/elasticsearch": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/elasticsearch/-/elasticsearch-11.1.0.tgz", + "integrity": "sha512-NwMakVs8LeXUksaSNp0ejhv223yVCK4w9iqMBrsonKj2gl4sBIBrAgJq/aXhD9bJCNLYb+waoRAsxuuPxYcjXw==", + "license": "MIT", + "peerDependencies": { + "@elastic/elasticsearch": "^7.4.0 || ^8.0.0 || ^9.0.0", + "@nestjs/common": "^10.0.0 || ^11.0.0", + "rxjs": "^7.2.0" } }, - "node_modules/@smithy/middleware-endpoint": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.18.tgz", - "integrity": "sha512-ZhvqcVRPZxnZlokcPaTwb+r+h4yOIOCJmx0v2d1bpVlmP465g3qpVSf7wxcq5zZdu4jb0H4yIMxuPwDJSQc3MQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/event-emitter": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/event-emitter/-/event-emitter-3.0.1.tgz", + "integrity": "sha512-0Ln/x+7xkU6AJFOcQI9tIhUMXVF7D5itiaQGOyJbXtlAfAIt8gzDdJm+Im7cFzKoWkiW5nCXCPh6GSvdQd/3Dw==", "dependencies": { - "@smithy/core": "^3.8.0", - "@smithy/middleware-serde": "^4.0.9", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "@smithy/util-middleware": "^4.0.5", - "tslib": "^2.6.2" + "eventemitter2": "6.4.9" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0" } }, - "node_modules/@smithy/middleware-retry": { - "version": "4.1.19", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.19.tgz", - "integrity": "sha512-X58zx/NVECjeuUB6A8HBu4bhx72EoUz+T5jTMIyeNKx2lf+Gs9TmWPNNkH+5QF0COjpInP/xSpJGJ7xEnAklQQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/jwt": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.2.tgz", + "integrity": "sha512-rK8aE/3/Ma45gAWfCksAXUNbOoSOUudU0Kn3rT39htPF7wsYXtKfjALKeKKJbFrIWbLjsbqfXX5bIJNvgBugGA==", + "license": "MIT", "dependencies": { - "@smithy/node-config-provider": "^4.1.4", - "@smithy/protocol-http": "^5.1.3", - "@smithy/service-error-classification": "^4.0.7", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-retry": "^4.0.7", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" + "@types/jsonwebtoken": "9.0.10", + "jsonwebtoken": "9.0.3" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" } }, - "node_modules/@smithy/middleware-retry/node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "dev": true, - "license": "MIT" + "node_modules/@nestjs/mapped-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", + "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } }, - "node_modules/@smithy/middleware-retry/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "node_modules/@nestjs/mongoose": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-11.0.4.tgz", + "integrity": "sha512-LUOlUeSOfbjdIu22QwOmczv2CzJQr9LUBo2mOfbXrGCu2svpr5Hiu71zBFrb/9UC+H8BjGMKbBOq1nEbMF6ZJA==", "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0", + "mongoose": "^7.0.0 || ^8.0.0 || ^9.0.0", + "rxjs": "^7.0.0" } }, - "node_modules/@smithy/middleware-serde": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.9.tgz", - "integrity": "sha512-uAFFR4dpeoJPGz8x9mhxp+RPjo5wW0QEEIPPPbLXiRRWeCATf/Km3gKIVR5vaP8bN1kgsPhcEeh+IZvUlBv6Xg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node_modules/@nestjs/passport": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz", + "integrity": "sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "passport": "^0.5.0 || ^0.6.0 || ^0.7.0" } }, - "node_modules/@smithy/middleware-stack": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.5.tgz", - "integrity": "sha512-/yoHDXZPh3ocRVyeWQFvC44u8seu3eYzZRveCMfgMOBcNKnAmOvjbL9+Cp5XKSIi9iYA9PECUuW2teDAk8T+OQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/platform-express": { + "version": "11.1.12", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.12.tgz", + "integrity": "sha512-GYK/vHI0SGz5m8mxr7v3Urx8b9t78Cf/dj5aJMZlGd9/1D9OI1hAl00BaphjEXINUJ/BQLxIlF2zUjrYsd6enQ==", + "license": "MIT", "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "cors": "2.8.5", + "express": "5.2.1", + "multer": "2.0.2", + "path-to-regexp": "8.3.0", + "tslib": "2.8.1" }, - "engines": { - "node": ">=18.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/core": "^11.0.0" } }, - "node_modules/@smithy/node-config-provider": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.7.tgz", - "integrity": "sha512-7r58wq8sdOcrwWe+klL9y3bc4GW1gnlfnFOuL7CXa7UzfhzhxKuzNdtqgzmTV+53lEp9NXh5hY/S4UgjLOzPfw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@smithy/node-http-handler": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.1.1.tgz", - "integrity": "sha512-RHnlHqFpoVdjSPPiYy/t40Zovf3BBHc2oemgD7VsVTFFZrU5erFFe0n52OANZZ/5sbshgD93sOh5r6I35Xmpaw==", + "node_modules/@nestjs/schematics": { + "version": "11.0.9", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.9.tgz", + "integrity": "sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/abort-controller": "^4.0.5", - "@smithy/protocol-http": "^5.1.3", - "@smithy/querystring-builder": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@angular-devkit/core": "19.2.17", + "@angular-devkit/schematics": "19.2.17", + "comment-json": "4.4.1", + "jsonc-parser": "3.3.1", + "pluralize": "8.0.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "typescript": ">=4.8.2" } }, - "node_modules/@smithy/property-provider": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.7.tgz", - "integrity": "sha512-jmNYKe9MGGPoSl/D7JDDs1C8b3dC8f/w78LbaVfoTtWy4xAd5dfjaFG9c9PWPihY4ggMQNQSMtzU77CNgAJwmA==", + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.17.tgz", + "integrity": "sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/types": "^4.11.0", - "tslib": "^2.6.2" + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "node_modules/@smithy/protocol-http": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.3.tgz", - "integrity": "sha512-fCJd2ZR7D22XhDY0l+92pUag/7je2BztPRQ01gU5bMChcyI0rlly7QFibnYHzcxDvccMjlpM/Q1ev8ceRIb48w==", + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.17.tgz", + "integrity": "sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@angular-devkit/core": "19.2.17", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@smithy/querystring-builder": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.5.tgz", - "integrity": "sha512-NJeSCU57piZ56c+/wY+AbAw6rxCCAOZLCIniRE7wqvndqxcKKDOXzwWjrY7wGKEISfhL9gBbAaWWgHsUGedk+A==", + "node_modules/@nestjs/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", - "@smithy/util-uri-escape": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "tslib": "^2.1.0" } }, - "node_modules/@smithy/querystring-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.5.tgz", - "integrity": "sha512-6SV7md2CzNG/WUeTjVe6Dj8noH32r4MnUeFKZrnVYsQxpGSIcphAanQMayi8jJLZAWm6pdM9ZXvKCpWOsIGg0w==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/swagger": { + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.2.5.tgz", + "integrity": "sha512-wCykbEybMqiYcvkyzPW4SbXKcwra9AGdajm0MvFgKR3W+gd1hfeKlo67g/s9QCRc/mqUU4KOE5Qtk7asMeFuiA==", + "license": "MIT", "dependencies": { - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" + "@microsoft/tsdoc": "0.16.0", + "@nestjs/mapped-types": "2.1.0", + "js-yaml": "4.1.1", + "lodash": "4.17.21", + "path-to-regexp": "8.3.0", + "swagger-ui-dist": "5.31.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@fastify/static": "^8.0.0 || ^9.0.0", + "@nestjs/common": "^11.0.1", + "@nestjs/core": "^11.0.1", + "class-transformer": "*", + "class-validator": "*", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } } }, - "node_modules/@smithy/service-error-classification": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.7.tgz", - "integrity": "sha512-XvRHOipqpwNhEjDf2L5gJowZEm5nsxC16pAZOeEcsygdjv9A2jdOh3YoDQvOXBGTsaJk6mNWtzWalOB9976Wlg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.2" - }, - "engines": { - "node": ">=18.0.0" + "node_modules/@nestjs/swagger/node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/@nestjs/swagger/node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.2.tgz", - "integrity": "sha512-M7iUUff/KwfNunmrgtqBfvZSzh3bmFgv/j/t1Y1dQ+8dNo34br1cqVEqy6v0mYEgi0DkGO7Xig0AnuOaEGVlcg==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nestjs/terminus": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-11.0.0.tgz", + "integrity": "sha512-c55LOo9YGovmQHtFUMa/vDaxGZ2cglMTZejqgHREaApt/GArTfgYYGwhRXPLq8ZwiQQlLuYB+79e9iA8mlDSLA==", "dependencies": { - "@smithy/types": "^4.11.0", - "tslib": "^2.6.2" + "boxen": "5.1.2", + "check-disk-space": "3.4.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@grpc/grpc-js": "*", + "@grpc/proto-loader": "*", + "@mikro-orm/core": "*", + "@mikro-orm/nestjs": "*", + "@nestjs/axios": "^2.0.0 || ^3.0.0 || ^4.0.0", + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0", + "@nestjs/microservices": "^10.0.0 || ^11.0.0", + "@nestjs/mongoose": "^11.0.0", + "@nestjs/sequelize": "^10.0.0 || ^11.0.0", + "@nestjs/typeorm": "^10.0.0 || ^11.0.0", + "@prisma/client": "*", + "mongoose": "*", + "reflect-metadata": "0.1.x || 0.2.x", + "rxjs": "7.x", + "sequelize": "*", + "typeorm": "*" + }, + "peerDependenciesMeta": { + "@grpc/grpc-js": { + "optional": true + }, + "@grpc/proto-loader": { + "optional": true + }, + "@mikro-orm/core": { + "optional": true + }, + "@mikro-orm/nestjs": { + "optional": true + }, + "@nestjs/axios": { + "optional": true + }, + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/mongoose": { + "optional": true + }, + "@nestjs/sequelize": { + "optional": true + }, + "@nestjs/typeorm": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "mongoose": { + "optional": true + }, + "sequelize": { + "optional": true + }, + "typeorm": { + "optional": true + } } }, - "node_modules/@smithy/signature-v4": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.3.tgz", - "integrity": "sha512-mARDSXSEgllNzMw6N+mC+r1AQlEBO3meEAkR/UlfAgnMzJUB3goRBWgip1EAMG99wh36MDqzo86SfIX5Y+VEaw==", + "node_modules/@nestjs/testing": { + "version": "11.1.12", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.12.tgz", + "integrity": "sha512-W0M/i5nb9qRQpTQfJm+1mGT/+y4YezwwdcD7mxFG8JEZ5fz/ZEAk1Ayri2VBJKJUdo20B1ggnvqew4dlTMrSNg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-uri-escape": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" + "tslib": "2.8.1" }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.10.tgz", - "integrity": "sha512-iW6HjXqN0oPtRS0NK/zzZ4zZeGESIFcxj2FkWed3mcK8jdSdHzvnCKXSjvewESKAgGKAbJRA+OsaqKhkdYRbQQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.8.0", - "@smithy/middleware-endpoint": "^4.1.18", - "@smithy/middleware-stack": "^4.0.5", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "@smithy/util-stream": "^4.2.4", - "tslib": "^2.6.2" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.11.0.tgz", - "integrity": "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/core": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0" }, - "engines": { - "node": ">=18.0.0" + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + } } }, - "node_modules/@smithy/url-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.5.tgz", - "integrity": "sha512-j+733Um7f1/DXjYhCbvNXABV53NyCRRA54C7bNEIxNPs0YjfRxeMKjjgm2jvTYrciZyCjsicHwQ6Q0ylo+NAUw==", + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/querystring-parser": "^4.0.5", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-base64": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" + "node": "^14.21.3 || >=16" }, - "engines": { - "node": ">=18.0.0" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@smithy/util-body-length-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@nuxt/opencollective": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", + "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", "dependencies": { - "tslib": "^2.6.2" + "consola": "^3.2.3" }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", - "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" + "bin": { + "opencollective": "bin/opencollective.js" }, "engines": { - "node": ">=18.0.0" + "node": "^14.18.0 || >=16.10.0", + "npm": ">=5.10.0" } }, - "node_modules/@smithy/util-buffer-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "optional": true }, - "node_modules/@smithy/util-config-provider": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", - "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", - "dev": true, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, "engines": { - "node": ">=18.0.0" + "node": ">=8.0.0" } }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.26", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.26.tgz", - "integrity": "sha512-xgl75aHIS/3rrGp7iTxQAOELYeyiwBu+eEgAk4xfKwJJ0L8VUjhO2shsDpeil54BOFsqmk5xfdesiewbUY5tKQ==", + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", + "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.5", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "@noble/hashes": "^1.1.5" } }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.26", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.26.tgz", - "integrity": "sha512-z81yyIkGiLLYVDetKTUeCZQ8x20EEzvQjrqJtb/mXnevLq2+w3XCEWTJ2pMp401b6BkEkHVfXb/cROBpVauLMQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/config-resolver": "^4.1.5", - "@smithy/credential-provider-imds": "^4.0.7", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/property-provider": "^4.0.5", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, "engines": { - "node": ">=18.0.0" + "node": ">=14" } }, - "node_modules/@smithy/util-endpoints": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.7.tgz", - "integrity": "sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg==", + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", - "tslib": "^2.6.2" - }, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" } }, - "node_modules/@smithy/util-hex-encoding": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@scarf/scarf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", + "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", + "hasInstallScript": true + }, + "node_modules/@selderee/plugin-htmlparser2": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", + "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "optional": true, "dependencies": { - "tslib": "^2.6.2" + "domhandler": "^5.0.3", + "selderee": "^0.11.0" }, - "engines": { - "node": ">=18.0.0" + "funding": { + "url": "https://ko-fi.com/killymxi" } }, - "node_modules/@smithy/util-middleware": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.7.tgz", - "integrity": "sha512-i1IkpbOae6NvIKsEeLLM9/2q4X+M90KV3oCFgWQI4q0Qz+yUZvsr+gZPdAEAtFhWQhAHpTsJO8DRJPuwVyln+w==", + "node_modules/@sinclair/typebox": { + "version": "0.34.38", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.38.tgz", + "integrity": "sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } + "license": "MIT" }, - "node_modules/@smithy/util-retry": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.7.tgz", - "integrity": "sha512-TTO6rt0ppK70alZpkjwy+3nQlTiqNfoXja+qwuAchIEAIoSZW8Qyd76dvBv3I5bCpE38APafG23Y/u270NspiQ==", + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.0.7", - "@smithy/types": "^4.3.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "type-detect": "4.0.8" } }, - "node_modules/@smithy/util-stream": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.4.tgz", - "integrity": "sha512-vSKnvNZX2BXzl0U2RgCLOwWaAP9x/ddd/XobPK02pCbzRm5s55M53uwb1rl/Ts7RXZvdJZerPkA+en2FDghLuQ==", + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", "dev": true, - "license": "Apache-2.0", + "license": "BSD-3-Clause", "dependencies": { - "@smithy/fetch-http-handler": "^5.1.1", - "@smithy/node-http-handler": "^4.1.1", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "@sinonjs/commons": "^3.0.1" } }, - "node_modules/@smithy/util-uri-escape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", + "node_modules/@sinonjs/samsam": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", + "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", "dev": true, - "license": "Apache-2.0", + "license": "BSD-3-Clause", "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" } }, - "node_modules/@smithy/util-utf8": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "tslib": "^2.6.2" - }, + "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=4" } }, "node_modules/@standard-schema/spec": { @@ -4936,13 +3570,12 @@ } }, "node_modules/@types/nodemailer": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.5.tgz", - "integrity": "sha512-7WtR4MFJUNN2UFy0NIowBRJswj5KXjXDhlZY43Hmots5eGu5q/dTeFd/I6GgJA/qj3RqO6dDy4SvfcV3fOVeIA==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.9.tgz", + "integrity": "sha512-vI8oF1M+8JvQhsId0Pc38BdUP2evenIIys7c7p+9OZXSPOH5c1dyINP1jT8xQ2xPuBUXmIC87s+91IZMDjH8Ow==", "dev": true, "license": "MIT", "dependencies": { - "@aws-sdk/client-sesv2": "^3.839.0", "@types/node": "*" } }, @@ -6487,13 +5120,6 @@ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "optional": true }, - "node_modules/bowser": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.12.1.tgz", - "integrity": "sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==", - "dev": true, - "license": "MIT" - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -8594,25 +7220,6 @@ } ] }, - "node_modules/fast-xml-parser": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", - "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^2.1.0" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -14668,19 +13275,6 @@ "node": ">=0.8.0" } }, - "node_modules/strnum": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", - "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, "node_modules/super-regex": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", From 0161f9589e747108d3108b4bb9b8e167bb0e6f9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:38:26 +0000 Subject: [PATCH 004/120] build(deps-dev): bump globals from 17.1.0 to 17.3.0 Bumps [globals](https://github.com/sindresorhus/globals) from 17.1.0 to 17.3.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v17.1.0...v17.3.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c5a19e51..ecb918d92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7842,9 +7842,9 @@ } }, "node_modules/globals": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.1.0.tgz", - "integrity": "sha512-8HoIcWI5fCvG5NADj4bDav+er9B9JMj2vyL2pI8D0eismKyUvPLTSs+Ln3wqhwcp306i73iyVnEKx3F6T47TGw==", + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", + "integrity": "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==", "dev": true, "license": "MIT", "engines": { From 7fe807cff210664f215ca6bc6bd127469dc3e6bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:48:46 +0000 Subject: [PATCH 005/120] 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.53.1 to 8.54.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.54.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.54.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 108 +++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index ecb918d92..b7ca9c3fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3739,17 +3739,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz", - "integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", + "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.53.1", - "@typescript-eslint/type-utils": "8.53.1", - "@typescript-eslint/utils": "8.53.1", - "@typescript-eslint/visitor-keys": "8.53.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/type-utils": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3762,7 +3762,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.53.1", + "@typescript-eslint/parser": "^8.54.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3778,16 +3778,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz", - "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", + "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.53.1", - "@typescript-eslint/types": "8.53.1", - "@typescript-eslint/typescript-estree": "8.53.1", - "@typescript-eslint/visitor-keys": "8.53.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3" }, "engines": { @@ -3803,14 +3803,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz", - "integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", + "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.53.1", - "@typescript-eslint/types": "^8.53.1", + "@typescript-eslint/tsconfig-utils": "^8.54.0", + "@typescript-eslint/types": "^8.54.0", "debug": "^4.4.3" }, "engines": { @@ -3825,14 +3825,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz", - "integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", + "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.53.1", - "@typescript-eslint/visitor-keys": "8.53.1" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3843,9 +3843,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz", - "integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", + "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", "dev": true, "license": "MIT", "engines": { @@ -3860,15 +3860,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz", - "integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", + "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.53.1", - "@typescript-eslint/typescript-estree": "8.53.1", - "@typescript-eslint/utils": "8.53.1", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3885,9 +3885,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", - "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", + "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", "dev": true, "license": "MIT", "engines": { @@ -3899,16 +3899,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz", - "integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", + "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.53.1", - "@typescript-eslint/tsconfig-utils": "8.53.1", - "@typescript-eslint/types": "8.53.1", - "@typescript-eslint/visitor-keys": "8.53.1", + "@typescript-eslint/project-service": "8.54.0", + "@typescript-eslint/tsconfig-utils": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -3953,16 +3953,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz", - "integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", + "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.53.1", - "@typescript-eslint/types": "8.53.1", - "@typescript-eslint/typescript-estree": "8.53.1" + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3977,13 +3977,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.53.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz", - "integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", + "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/types": "8.54.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { From d9c40ca8a8d4a788d24a0dc53eeac7ceb55ea4ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 16:19:56 +0000 Subject: [PATCH 006/120] build(deps): bump nodemailer and preview-email Bumps [nodemailer](https://github.com/nodemailer/nodemailer) and [preview-email](https://github.com/forwardemail/test-preview-emails-cross-browsers-ios-simulator-nodejs-javascript). These dependencies needed to be updated together. Updates `nodemailer` from 6.10.0 to 7.0.11 - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v6.10.0...v7.0.11) Updates `preview-email` from 3.1.0 to 3.1.1 - [Release notes](https://github.com/forwardemail/test-preview-emails-cross-browsers-ios-simulator-nodejs-javascript/releases) - [Commits](https://github.com/forwardemail/test-preview-emails-cross-browsers-ios-simulator-nodejs-javascript/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: nodemailer dependency-version: 7.0.11 dependency-type: indirect - dependency-name: preview-email dependency-version: 3.1.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 167 ++++++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 95 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7ca9c3fc..5eaba5118 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1530,23 +1530,6 @@ } } }, - "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", - "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/@inquirer/figures": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", @@ -3080,6 +3063,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "license": "MIT", "optional": true, "dependencies": { "domhandler": "^5.0.3", @@ -4489,6 +4473,18 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "node_modules/@zone-eu/mailsplit": { + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/@zone-eu/mailsplit/-/mailsplit-5.4.8.tgz", + "integrity": "sha512-eEyACj4JZ7sjzRvy26QhLgKEMWwQbsw1+QZnlLX+/gihcNH07lVPOcnwf5U6UAL7gkc//J3jVd76o/WS+taUiA==", + "license": "(MIT OR EUPL-1.1+)", + "optional": true, + "dependencies": { + "libbase64": "1.3.0", + "libmime": "5.3.7", + "libqp": "2.1.1" + } + }, "node_modules/abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", @@ -5098,22 +5094,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -6626,6 +6606,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.2.0.tgz", "integrity": "sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==", + "license": "MIT", "optional": true, "engines": { "node": ">=8.10.0" @@ -7999,6 +7980,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", + "license": "MIT", "optional": true, "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", @@ -8061,15 +8043,19 @@ } }, "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { @@ -9701,6 +9687,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", + "license": "MIT", "optional": true, "funding": { "url": "https://ko-fi.com/killymxi" @@ -9733,12 +9720,14 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.3.0.tgz", "integrity": "sha512-GgOXd0Eo6phYgh0DJtjQ2tO8dc0IVINtZJeARPeiIJqge+HdsWSuaDTe8ztQ7j/cONByDZ3zeB325AHiv5O0dg==", + "license": "MIT", "optional": true }, "node_modules/libmime": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.6.tgz", - "integrity": "sha512-j9mBC7eiqi6fgBPAGvKCXJKJSIASanYF4EeA4iBzSG0HxQxmXnR3KbyWqTn4CwsKSebqCv2f5XZfAO6sKzgvwA==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.7.tgz", + "integrity": "sha512-FlDb3Wtha8P01kTL3P9M+ZDNDWPKPmKHWaU/cG/lg5pfuAwdflVpZE+wm9m7pKmC5ww6s+zTxBKS1p6yl3KpSw==", + "license": "MIT", "optional": true, "dependencies": { "encoding-japanese": "2.2.0", @@ -9747,6 +9736,19 @@ "libqp": "2.1.1" } }, + "node_modules/libmime/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/libphonenumber-js": { "version": "1.12.6", "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.6.tgz", @@ -9756,6 +9758,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/libqp/-/libqp-2.1.1.tgz", "integrity": "sha512-0Wd+GPz1O134cP62YU2GTOPNA7Qgl09XwCqM5zpBv87ERCXdfDtyKXvV7c9U22yWJh44QZqBocFnXN11K96qow==", + "license": "MIT", "optional": true }, "node_modules/lines-and-columns": { @@ -9768,6 +9771,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", "optional": true, "dependencies": { "uc.micro": "^2.0.0" @@ -9966,41 +9970,22 @@ } }, "node_modules/mailparser": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.7.2.tgz", - "integrity": "sha512-iI0p2TCcIodR1qGiRoDBBwboSSff50vQAWytM5JRggLfABa4hHYCf3YVujtuzV454xrOP352VsAPIzviqMTo4Q==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.9.3.tgz", + "integrity": "sha512-AnB0a3zROum6fLaa52L+/K2SoRJVyFDk78Ea6q1D0ofcZLxWEWDtsS1+OrVqKbV7r5dulKL/AwYQccFGAPpuYQ==", + "license": "MIT", "optional": true, "dependencies": { + "@zone-eu/mailsplit": "5.4.8", "encoding-japanese": "2.2.0", "he": "1.2.0", "html-to-text": "9.0.5", - "iconv-lite": "0.6.3", - "libmime": "5.3.6", + "iconv-lite": "0.7.2", + "libmime": "5.3.7", "linkify-it": "5.0.0", - "mailsplit": "5.4.2", - "nodemailer": "6.9.16", + "nodemailer": "7.0.13", "punycode.js": "2.3.1", - "tlds": "1.255.0" - } - }, - "node_modules/mailparser/node_modules/nodemailer": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.16.tgz", - "integrity": "sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ==", - "optional": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/mailsplit": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.2.tgz", - "integrity": "sha512-4cczG/3Iu3pyl8JgQ76dKkisurZTmxMrA4dj/e8d2jKYcFTZ7MxOzg1gTioTDMPuFXwTrVuN/gxhkrO7wLg7qA==", - "optional": true, - "dependencies": { - "libbase64": "1.3.0", - "libmime": "5.3.6", - "libqp": "2.1.1" + "tlds": "1.261.0" } }, "node_modules/make-dir": { @@ -11192,9 +11177,10 @@ "license": "MIT" }, "node_modules/nodemailer": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.0.tgz", - "integrity": "sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", + "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", + "license": "MIT-0", "engines": { "node": ">=6.0.0" } @@ -11582,6 +11568,7 @@ "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", + "license": "MIT", "optional": true, "dependencies": { "leac": "^0.6.0", @@ -11735,6 +11722,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", + "license": "MIT", "optional": true, "funding": { "url": "https://ko-fi.com/killymxi" @@ -11920,17 +11908,18 @@ } }, "node_modules/preview-email": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.1.0.tgz", - "integrity": "sha512-ZtV1YrwscEjlrUzYrTSs6Nwo49JM3pXLM4fFOBSC3wSni+bxaWlw9/Qgk75PZO8M7cX2EybmL2iwvaV3vkAttw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.1.1.tgz", + "integrity": "sha512-nrdhnt+E9ClJ4khk9rNzqgsxubH7xSJSKoqXx/7aed2eghegNGNWkSGOelNgFgUtMz3LmKGks0waH2NuXWWmPg==", + "license": "MIT", "optional": true, "dependencies": { "ci-info": "^3.8.0", "display-notification": "2.0.0", "fixpack": "^4.0.0", "get-port": "5.1.1", - "mailparser": "^3.7.1", - "nodemailer": "^6.9.13", + "mailparser": "^3.9.1", + "nodemailer": "^7.0.12", "open": "7", "p-event": "4.2.0", "p-wait-for": "3.2.0", @@ -12122,6 +12111,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", "optional": true, "engines": { "node": ">=6" @@ -12204,22 +12194,6 @@ "node": ">= 0.10" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -12734,6 +12708,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", + "license": "MIT", "optional": true, "dependencies": { "parseley": "^0.12.0" @@ -13679,9 +13654,10 @@ } }, "node_modules/tlds": { - "version": "1.255.0", - "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.255.0.tgz", - "integrity": "sha512-tcwMRIioTcF/FcxLev8MJWxCp+GUALRhFEqbDoZrnowmKSGqPrl5pqS+Sut2m8BgJ6S4FExCSSpGffZ0Tks6Aw==", + "version": "1.261.0", + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.261.0.tgz", + "integrity": "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==", + "license": "MIT", "optional": true, "bin": { "tlds": "bin.js" @@ -14052,6 +14028,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT", "optional": true }, "node_modules/uglify-js": { From 6751a22d0d54d7d3c68d88e6fd77458656624023 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 19:58:18 +0000 Subject: [PATCH 007/120] build(deps): bump @isaacs/brace-expansion from 5.0.0 to 5.0.1 Bumps @isaacs/brace-expansion from 5.0.0 to 5.0.1. --- updated-dependencies: - dependency-name: "@isaacs/brace-expansion" dependency-version: 5.0.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5eaba5118..54e877a1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1737,9 +1737,9 @@ } }, "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" From 4adaee62521e8aafcc0e3787d1467e31db85b427 Mon Sep 17 00:00:00 2001 From: Carlo Minotti <50220438+minottic@users.noreply.github.com> Date: Wed, 4 Feb 2026 09:58:24 +0100 Subject: [PATCH 008/120] chore: improve mapper efficiency (#2519) --- src/common/utils/deep-mapper.util.ts | 25 ++++++++++--------- .../dto/published-data.obsolete.dto.ts | 10 +++++--- src/published-data/pipes/filter.pipe.ts | 9 +++++-- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/common/utils/deep-mapper.util.ts b/src/common/utils/deep-mapper.util.ts index 7c685b6fe..9c36ae381 100644 --- a/src/common/utils/deep-mapper.util.ts +++ b/src/common/utils/deep-mapper.util.ts @@ -1,26 +1,27 @@ -import { get } from "lodash"; +import { get, trim } from "lodash"; function mapDeep( source: T, - key: keyof U | string, - fieldsMap: Record, + key: keyof U & string, + fieldsMap: Partial>, ): T[keyof T] | unknown | null { if (!source) return null; + if (!fieldsMap[key]) return get(source, key); if (get(source, key)) return get(source, key); - const keysList = (fieldsMap[key] as string).split("."); - const initialValue = get(source, keysList[0]); + if (!fieldsMap[key].includes("[]")) return get(source, fieldsMap[key]); + const keysList = fieldsMap[key].split("[]"); + const initialValue = get(source, trim(keysList[0], ".")); + if (!initialValue) return; return keysList.slice(1).reduce((acc, currKey) => { - if (Array.isArray(acc)) { - return acc.map((item) => get(item, currKey)); - } - return get(acc, currKey); + if (!acc) return acc; + return acc.map((item: object) => get(item, trim(currKey, "."))); }, initialValue); } export function createDeepMapper( - fieldsMap: Record, + fieldsMap: Partial>, ) { - return (source: T, key: keyof U | string) => { - return mapDeep(source, key, fieldsMap); + return (source: T, key: string) => { + return mapDeep(source, key as keyof U & string, fieldsMap); }; } diff --git a/src/published-data/dto/published-data.obsolete.dto.ts b/src/published-data/dto/published-data.obsolete.dto.ts index 1cbe7cb33..3b26342c4 100644 --- a/src/published-data/dto/published-data.obsolete.dto.ts +++ b/src/published-data/dto/published-data.obsolete.dto.ts @@ -11,12 +11,14 @@ import { PublishedDataStatus } from "../interfaces/published-data.interface"; import { PublishedData } from "../schemas/published-data.schema"; import { createDeepMapper } from "src/common/utils/deep-mapper.util"; -export const publishedDataV3toV4FieldMap: Record = { +export const publishedDataV3toV4FieldMap: Partial< + Record +> = { pidArray: "datasetPids", - creator: "metadata.creators.name", - authors: "metadata.contributors.name", + creator: "metadata.creators.[].name", + authors: "metadata.contributors.[].name", publisher: "metadata.publisher.name", - relatedPublications: "metadata.relatedIdentifiers.relatedIdentifier", + relatedPublications: "metadata.relatedIdentifiers.[].relatedIdentifier", affiliation: "metadata.affiliation", publicationYear: "metadata.publicationYear", url: "metadata.url", diff --git a/src/published-data/pipes/filter.pipe.ts b/src/published-data/pipes/filter.pipe.ts index efa9c8940..5acbe70a8 100644 --- a/src/published-data/pipes/filter.pipe.ts +++ b/src/published-data/pipes/filter.pipe.ts @@ -5,7 +5,7 @@ import { } from "../schemas/published-data.schema"; import { publishedDataV3toV4FieldMap } from "../dto/published-data.obsolete.dto"; import { PipeTransform } from "@nestjs/common"; -import { isEmpty } from "lodash"; +import { isEmpty, mapValues } from "lodash"; import { IPublishedDataFilters } from "../interfaces/published-data.interface"; import { FilterQuery } from "mongoose"; @@ -22,8 +22,13 @@ class AppendFieldsToFilterPipe implements PipeTransform { } } +const publishedDataV3toV4FilterMap = mapValues( + publishedDataV3toV4FieldMap, + (val) => val?.replace(/\[\]\.?/g, ""), +); + export const V3_FILTER_PIPE = [ - new FilterPipe({ apiToDBMap: publishedDataV3toV4FieldMap }), + new FilterPipe({ apiToDBMap: publishedDataV3toV4FilterMap }), ]; export const V4_FILTER_PIPE = [ From 684a89ee9621b6792b26c1af07d3ee916da8a12f Mon Sep 17 00:00:00 2001 From: abdimo101 Date: Wed, 4 Feb 2026 11:38:56 +0100 Subject: [PATCH 009/120] refactor: add encoding/decoding for samples metadata keys (#2469) * encoding/decoding for samples metadata keys * eslint fix * updated tests * eslint fix x2 * reverted back the generator-tag for openapitools-generator * reverts the change about openapi-generators * encoding/decoding for samples metadata keys * eslint fix * updated tests * eslint fix x2 * reverted back the generator-tag for openapitools-generator * reverts the change about openapi-generators * using bulkWrite for sample and dataset migration scripts * using serializer instead of plainToInstance * wip: fixing test * fixed test --------- Co-authored-by: Abdi Abdulle --- ...260114145500-encode-sample-metadatakeys.js | 84 +++++++++++ ...0126111900-encode-dataset-metadatakeys.js} | 44 ++++-- src/samples/dto/output-sample.dto.ts | 15 +- src/samples/dto/update-sample.dto.ts | 5 +- src/samples/samples.controller.spec.ts | 66 +++++++-- src/samples/samples.controller.ts | 94 +++++++++--- src/samples/samples.service.ts | 24 ++- src/samples/schemas/sample.schema.ts | 6 + test/Sample.js | 139 +++++++++++++++++- 9 files changed, 416 insertions(+), 61 deletions(-) create mode 100644 migrations/20260114145500-encode-sample-metadatakeys.js rename migrations/{20251117155200-encode-metadatakeys.js => 20260126111900-encode-dataset-metadatakeys.js} (67%) diff --git a/migrations/20260114145500-encode-sample-metadatakeys.js b/migrations/20260114145500-encode-sample-metadatakeys.js new file mode 100644 index 000000000..50513823e --- /dev/null +++ b/migrations/20260114145500-encode-sample-metadatakeys.js @@ -0,0 +1,84 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +const { + encodeScientificMetadataKeys, + decodeScientificMetadataKeys, +} = require("../dist/common/utils"); + +module.exports = { + async up(db, client) { + const bulkOps = []; + + for await (const sample of db + .collection("Sample") + .find({ sampleCharacteristics: { $exists: true } })) { + const metadata = sample.sampleCharacteristics; + if (!metadata || typeof metadata !== "object") continue; + + let encodedMetadata; + try { + encodedMetadata = encodeScientificMetadataKeys(metadata); + } catch (err) { + console.error( + `Error encoding sampleCharacteristics for Sample (Id: ${sample._id}):`, + err, + ); + continue; + } + + console.log( + `Updating Sample (Id: ${sample._id}) with encoded sampleCharacteristics keys`, + ); + + bulkOps.push({ + updateOne: { + filter: { _id: sample._id }, + update: { $set: { sampleCharacteristics: encodedMetadata } }, + }, + }); + } + + if (bulkOps.length > 0) { + console.log(`Executing bulk update for ${bulkOps.length} samples`); + await db.collection("Sample").bulkWrite(bulkOps); + } + }, + + async down(db, client) { + const bulkOps = []; + + for await (const sample of db + .collection("Sample") + .find({ sampleCharacteristics: { $exists: true } })) { + const metadata = sample.sampleCharacteristics; + if (!metadata || typeof metadata !== "object") continue; + + let decodedMetadata; + + try { + decodedMetadata = decodeScientificMetadataKeys(metadata); + } catch (err) { + console.error( + `Error decoding sampleCharacteristics for Sample (Id: ${sample._id}):`, + err, + ); + continue; + } + + console.log( + `Reverting Sample (Id: ${sample._id}) to decoded sampleCharacteristics keys`, + ); + + bulkOps.push({ + updateOne: { + filter: { _id: sample._id }, + update: { $set: { sampleCharacteristics: decodedMetadata } }, + }, + }); + } + + if (bulkOps.length > 0) { + console.log(`Executing bulk revert for ${bulkOps.length} samples`); + await db.collection("Sample").bulkWrite(bulkOps); + } + }, +}; diff --git a/migrations/20251117155200-encode-metadatakeys.js b/migrations/20260126111900-encode-dataset-metadatakeys.js similarity index 67% rename from migrations/20251117155200-encode-metadatakeys.js rename to migrations/20260126111900-encode-dataset-metadatakeys.js index c5d20bc44..78433057e 100644 --- a/migrations/20251117155200-encode-metadatakeys.js +++ b/migrations/20260126111900-encode-dataset-metadatakeys.js @@ -6,6 +6,8 @@ const { module.exports = { async up(db, client) { + const bulkOps = []; + for await (const dataset of db .collection("Dataset") .find({ scientificMetadata: { $exists: true } })) { @@ -26,16 +28,24 @@ module.exports = { console.log( `Updating Dataset (Id: ${dataset._id}) with encoded scientificMetadata keys`, ); - await db - .collection("Dataset") - .updateOne( - { _id: dataset._id }, - { $set: { scientificMetadata: encodedMetadata } }, - ); - }; + + bulkOps.push({ + updateOne: { + filter: { _id: dataset._id }, + update: { $set: { scientificMetadata: encodedMetadata } }, + }, + }); + } + + if (bulkOps.length > 0) { + console.log(`Executing bulk update for ${bulkOps.length} datasets`); + await db.collection("Dataset").bulkWrite(bulkOps); + } }, async down(db, client) { + const bulkOps = []; + for await (const dataset of db .collection("Dataset") .find({ scientificMetadata: { $exists: true } })) { @@ -57,12 +67,18 @@ module.exports = { console.log( `Reverting Dataset (Id: ${dataset._id}) to decoded scientificMetadata keys`, ); - await db - .collection("Dataset") - .updateOne( - { _id: dataset._id }, - { $set: { scientificMetadata: decodedMetadata } }, - ); - }; + + bulkOps.push({ + updateOne: { + filter: { _id: dataset._id }, + update: { $set: { scientificMetadata: decodedMetadata } }, + }, + }); + } + + if (bulkOps.length > 0) { + console.log(`Executing bulk revert for ${bulkOps.length} datasets`); + await db.collection("Dataset").bulkWrite(bulkOps); + } }, }; diff --git a/src/samples/dto/output-sample.dto.ts b/src/samples/dto/output-sample.dto.ts index b871939ef..e92f9deb1 100644 --- a/src/samples/dto/output-sample.dto.ts +++ b/src/samples/dto/output-sample.dto.ts @@ -1,6 +1,8 @@ import { ApiProperty } from "@nestjs/swagger"; import { IsDateString, IsString } from "class-validator"; import { CreateSampleDto } from "./create-sample.dto"; +import { Transform } from "class-transformer"; +import { decodeScientificMetadataKeys } from "src/common/utils"; export class OutputSampleDto extends CreateSampleDto { @ApiProperty({ @@ -41,10 +43,19 @@ export class OutputSampleDto extends CreateSampleDto { @ApiProperty({ type: String, - required: true, + required: false, description: "Version of the API used when the dataset was created or last updated. API version is defined in code for each release. Managed by the system.", }) @IsString() - version: string; + version?: string; + + @ApiProperty({ + type: Object, + required: false, + default: {}, + description: "JSON object containing the sample characteristics metadata.", + }) + @Transform(({ value }) => decodeScientificMetadataKeys(value)) + declare sampleCharacteristics?: Record; } diff --git a/src/samples/dto/update-sample.dto.ts b/src/samples/dto/update-sample.dto.ts index 51d1e178e..1927055cc 100644 --- a/src/samples/dto/update-sample.dto.ts +++ b/src/samples/dto/update-sample.dto.ts @@ -1,6 +1,8 @@ import { PartialType } from "@nestjs/swagger"; import { IsBoolean, IsObject, IsOptional, IsString } from "class-validator"; import { OwnableDto } from "../../common/dto/ownable.dto"; +import { Transform } from "class-transformer"; +import { encodeScientificMetadataKeys } from "src/common/utils"; export class UpdateSampleDto extends OwnableDto { /** @@ -43,7 +45,8 @@ export class UpdateSampleDto extends OwnableDto { */ @IsObject() @IsOptional() - readonly sampleCharacteristics?: Record = {}; + @Transform(({ value }) => encodeScientificMetadataKeys(value)) + sampleCharacteristics?: Record; /** * Flag is true when data are made publicly available. diff --git a/src/samples/samples.controller.spec.ts b/src/samples/samples.controller.spec.ts index da3057982..6cd3a9c65 100644 --- a/src/samples/samples.controller.spec.ts +++ b/src/samples/samples.controller.spec.ts @@ -45,7 +45,7 @@ describe("SamplesController", () => { describe("update", () => { const sampleId = "sample123"; - const updateDto: PartialUpdateSampleDto = { name: "Updated Sample" }; + const updateDto: PartialUpdateSampleDto = { description: "Updated Sample" }; const mockRequest = {} as Request; it("should update sample when header is missing", async () => { @@ -53,11 +53,21 @@ describe("SamplesController", () => { _id: sampleId, updatedAt: new Date("2023-01-01"), } as SampleClass; - samplesService.findOne.mockResolvedValue(sample); - samplesService.update.mockResolvedValue({ ...sample, ...updateDto }); + + const updatedSample = { + ...sample, + ...updateDto, + toObject: jest.fn().mockReturnValue({ ...sample, ...updateDto }), + }; + + samplesService.findOne = jest.fn().mockResolvedValue(sample); + samplesService.update = jest.fn().mockResolvedValue(updatedSample); jest - .spyOn(controller, "checkPermissionsForSample") + .spyOn( + controller, + "checkPermissionsForSample" as keyof SamplesController, + ) .mockResolvedValue(sample); const result = await controller.update( @@ -66,11 +76,11 @@ describe("SamplesController", () => { updateDto, {}, ); - expect(result).toEqual({ ...sample, ...updateDto }); + expect(result).toBeDefined(); }); it("should throw NotFoundException if sample not found", async () => { - samplesService.findOne.mockResolvedValue(null); + samplesService.findOne = jest.fn().mockResolvedValue(null); await expect( controller.update(mockRequest, sampleId, updateDto, {}), @@ -82,10 +92,13 @@ describe("SamplesController", () => { _id: sampleId, updatedAt: new Date("2023-01-01"), } as SampleClass; - samplesService.findOne.mockResolvedValue(sample); + samplesService.findOne = jest.fn().mockResolvedValue(sample); jest - .spyOn(controller, "checkPermissionsForSample") + .spyOn( + controller, + "checkPermissionsForSample" as keyof SamplesController, + ) .mockResolvedValue(sample); const headers = { @@ -96,13 +109,24 @@ describe("SamplesController", () => { controller.update(mockRequest, sampleId, updateDto, headers), ).rejects.toThrow(HttpException); }); + it("should update sample if header date is invalid", async () => { const sample = { _id: sampleId, updatedAt: new Date() } as SampleClass; - samplesService.findOne.mockResolvedValue(sample); - samplesService.update.mockResolvedValue({ ...sample, ...updateDto }); + + const updatedSample = { + ...sample, + ...updateDto, + toObject: jest.fn().mockReturnValue({ ...sample, ...updateDto }), + }; + + samplesService.findOne = jest.fn().mockResolvedValue(sample); + samplesService.update = jest.fn().mockResolvedValue(updatedSample); jest - .spyOn(controller, "checkPermissionsForSample") + .spyOn( + controller, + "checkPermissionsForSample" as keyof SamplesController, + ) .mockResolvedValue(sample); const headers = { @@ -115,16 +139,26 @@ describe("SamplesController", () => { updateDto, headers, ); - expect(result).toEqual({ ...sample, ...updateDto }); + expect(result).toBeDefined(); }); it("should update sample if header date is not present", async () => { const sample = { _id: sampleId, updatedAt: new Date() } as SampleClass; - samplesService.findOne.mockResolvedValue(sample); - samplesService.update.mockResolvedValue({ ...sample, ...updateDto }); + + const updatedSample = { + ...sample, + ...updateDto, + toObject: jest.fn().mockReturnValue({ ...sample, ...updateDto }), + }; + + samplesService.findOne = jest.fn().mockResolvedValue(sample); + samplesService.update = jest.fn().mockResolvedValue(updatedSample); jest - .spyOn(controller, "checkPermissionsForSample") + .spyOn( + controller, + "checkPermissionsForSample" as keyof SamplesController, + ) .mockResolvedValue(sample); const result = await controller.update( @@ -133,7 +167,7 @@ describe("SamplesController", () => { updateDto, {}, ); - expect(result).toEqual({ ...sample, ...updateDto }); + expect(result).toBeDefined(); }); }); }); diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index f05cd5227..f814d219e 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -19,6 +19,8 @@ import { Header, NotFoundException, Headers, + ClassSerializerInterceptor, + SerializeOptions, } from "@nestjs/common"; import { SamplesService } from "./samples.service"; import { CreateSampleDto } from "./dto/create-sample.dto"; @@ -70,6 +72,8 @@ import { AuthenticatedPoliciesGuard } from "src/casl/guards/auth-check.guard"; import { CountApiResponse } from "src/common/types"; import { OutputAttachmentV3Dto } from "src/attachments/dto-obsolete/output-attachment.v3.dto"; import { checkUnmodifiedSince } from "src/common/utils/check-unmodified-since"; +import { OutputSampleDto } from "./dto/output-sample.dto"; +import { DatasetDocument } from "src/datasets/schemas/dataset.schema"; export class FindByIdAccessResponse { @ApiProperty({ type: Boolean }) @@ -79,6 +83,7 @@ export class FindByIdAccessResponse { @ApiBearerAuth() @ApiTags("samples") @Controller("samples") +@UseInterceptors(ClassSerializerInterceptor) export class SamplesController { constructor( private readonly attachmentsService: AttachmentsService, @@ -174,21 +179,23 @@ export class SamplesController { id: string, group: Action, ) { - const sample = await this.samplesService.findOne({ + const sampleDoc = await this.samplesService.findOne({ sampleId: id, }); - if (!sample) { + if (!sampleDoc) { throw new NotFoundException(`Sample: ${id} not found`); } - const canDoAction = this.permissionChecker(group, sample, request); + const sampleObj = sampleDoc.toObject(); + + const canDoAction = this.permissionChecker(group, sampleObj, request); if (!canDoAction) { throw new ForbiddenException("Unauthorized to this sample"); } - return sample; + return sampleObj; } private checkPermissionsForSampleCreate( @@ -269,6 +276,10 @@ export class SamplesController { ) @HttpCode(HttpStatus.CREATED) @Post() + @SerializeOptions({ + type: OutputSampleDto, + excludeExtraneousValues: false, + }) @ApiOperation({ summary: "It creates a new sample.", description: @@ -280,20 +291,23 @@ export class SamplesController { }) @ApiResponse({ status: HttpStatus.CREATED, - type: SampleClass, + type: OutputSampleDto, description: "Create a new sample and return its representation in SciCat", }) async create( @Req() request: Request, @Body() createSampleDto: CreateSampleDto, - ): Promise { + ): Promise { const sampleDTO = this.checkPermissionsForSampleCreate( request, createSampleDto, Action.SampleCreate, ); - return this.samplesService.create(sampleDTO); + const createdSample = await this.samplesService.create(sampleDTO); + const sampleObj = (createdSample as SampleDocument).toObject(); + + return sampleObj as OutputSampleDto; } // GET /samples @@ -302,6 +316,10 @@ export class SamplesController { ability.can(Action.SampleRead, SampleClass), ) @Get() + @SerializeOptions({ + type: OutputSampleDto, + excludeExtraneousValues: false, + }) @ApiOperation({ summary: "It returns a list of samples", description: @@ -317,17 +335,22 @@ export class SamplesController { }) @ApiResponse({ status: HttpStatus.OK, - type: SampleClass, + type: OutputSampleDto, isArray: true, description: "Return the samples requested", }) async findAll( @Req() request: Request, @Query("filter") filters?: string, - ): Promise { + ): Promise { const sampleFilters: IFilters = this.updateFiltersForList(request, JSON.parse(filters ?? "{}")); - return this.samplesService.findAll(sampleFilters); + const samples = await this.samplesService.findAll(sampleFilters); + + const samplesObj = (samples as SampleDocument[]).map((sample) => + sample.toObject(), + ); + return samplesObj as OutputSampleDto[]; } // GET /samples/count @@ -393,6 +416,10 @@ export class SamplesController { ability.can(Action.SampleRead, SampleClass), ) @Get("/fullquery") + @SerializeOptions({ + type: OutputSampleDto, + excludeExtraneousValues: false, + }) @ApiOperation({ summary: "It returns a list of samples matching the query provided.", description: @@ -418,14 +445,14 @@ export class SamplesController { }) @ApiResponse({ status: HttpStatus.OK, - type: SampleClass, + type: OutputSampleDto, isArray: true, description: "Return samples requested", }) async fullquery( @Req() request: Request, @Query() filters: { fields?: string; limits?: string }, - ): Promise { + ): Promise { const user: JWTUser = request.user as JWTUser; const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); @@ -461,7 +488,14 @@ export class SamplesController { fields, limits, }; - return this.samplesService.fullquery(parsedFilters); + + const samples = await this.samplesService.fullquery(parsedFilters); + + const samplesObj = (samples as SampleDocument[]).map((sample) => + sample.toObject(), + ); + + return samplesObj as OutputSampleDto[]; } // GET /samples/metadataKeys @@ -607,6 +641,10 @@ export class SamplesController { ) @Get("/:id") @Header("content-type", "application/json") + @SerializeOptions({ + type: OutputSampleDto, + excludeExtraneousValues: false, + }) @ApiOperation({ summary: "It returns the sample requested.", description: "It returns the sample requested through the id specified.", @@ -618,13 +656,13 @@ export class SamplesController { }) @ApiResponse({ status: HttpStatus.OK, - type: SampleClass, + type: OutputSampleDto, description: "Return sample with id specified", }) async findById( @Req() request: Request, @Param("id") id: string, - ): Promise { + ): Promise { const sample = await this.checkPermissionsForSample( request, id, @@ -675,6 +713,10 @@ export class SamplesController { ), ) @Patch("/:id") + @SerializeOptions({ + type: OutputSampleDto, + excludeExtraneousValues: false, + }) @ApiOperation({ summary: "It updates the sample.", description: @@ -691,7 +733,7 @@ export class SamplesController { }) @ApiResponse({ status: HttpStatus.OK, - type: SampleClass, + type: OutputSampleDto, description: "Update an existing sample and return its representation in SciCat", }) @@ -700,7 +742,7 @@ export class SamplesController { @Param("id") id: string, @Body() updateSampleDto: PartialUpdateSampleDto, @Headers() headers: Record, - ): Promise { + ): Promise { const sample = await this.checkPermissionsForSample( request, id, @@ -710,7 +752,14 @@ export class SamplesController { //checks if the resource is unmodified since clients timestamp checkUnmodifiedSince(sample.updatedAt, headers["if-unmodified-since"]); - return this.samplesService.update({ sampleId: id }, updateSampleDto); + const updatedSample = await this.samplesService.update( + { sampleId: id }, + updateSampleDto, + ); + + const sampleObj = (updatedSample as SampleDocument).toObject(); + + return sampleObj as OutputSampleDto; } // DELETE /samples/:id @@ -980,11 +1029,16 @@ export class SamplesController { } } - const dataset = await this.datasetsService.fullquery({ + const datasets = await this.datasetsService.fullquery({ where: { sampleId: id }, fields: fields, }); - return dataset; + + const datasetsObj = (datasets as DatasetDocument[]).map((dataset) => + dataset.toObject(), + ); + + return datasetsObj; } // PATCH /samples/:id/datasets/:fk diff --git a/src/samples/samples.service.ts b/src/samples/samples.service.ts index b88da181b..af7d136f6 100644 --- a/src/samples/samples.service.ts +++ b/src/samples/samples.service.ts @@ -12,12 +12,14 @@ import { createFullqueryFilter, extractMetadataKeys, parseLimitFilters, + decodeMetadataKeyStrings, } from "src/common/utils"; import { CreateSampleDto } from "./dto/create-sample.dto"; import { PartialUpdateSampleDto } from "./dto/update-sample.dto"; import { ISampleFields } from "./interfaces/sample-filters.interface"; import { SampleClass, SampleDocument } from "./schemas/sample.schema"; import { CountApiResponse } from "src/common/types"; +import { OutputSampleDto } from "./dto/output-sample.dto"; @Injectable({ scope: Scope.REQUEST }) export class SamplesService { @@ -38,7 +40,7 @@ export class SamplesService { async findAll( filter: IFilters, - ): Promise { + ): Promise { const whereFilter: FilterQuery = filter.where ?? {}; const { limit, skip, sort } = parseLimitFilters(filter.limits); @@ -67,7 +69,7 @@ export class SamplesService { async fullquery( filter: IFilters, - ): Promise { + ): Promise { const filterQuery: FilterQuery = createFullqueryFilter( this.sampleModel, @@ -108,7 +110,15 @@ export class SamplesService { filters.limits = lm; } - const samples = await this.findAll(filters); + const whereFilter: FilterQuery = filters.where ?? {}; + const { limit, skip, sort } = parseLimitFilters(filters.limits); + + const samples = await this.sampleModel + .find(whereFilter) + .limit(limit) + .skip(skip) + .sort(sort) + .exec(); const metadataKeys = extractMetadataKeys( samples, @@ -122,13 +132,15 @@ export class SamplesService { "metadataKeysReturnLimit", ); + const decodedKeys = decodeMetadataKeyStrings(metadataKeys); + if (metadataKey && metadataKey.length > 0) { const filterKey = metadataKey.toLowerCase(); - return metadataKeys + return decodedKeys .filter((key) => key.toLowerCase().includes(filterKey)) .slice(0, returnLimit); } else { - return metadataKeys.slice(0, returnLimit); + return decodedKeys.slice(0, returnLimit); } } @@ -139,7 +151,7 @@ export class SamplesService { async update( filter: FilterQuery, updateSampleDto: PartialUpdateSampleDto, - ): Promise { + ): Promise { const username = (this.request.user as JWTUser).username; const updateData = addUpdatedByField(updateSampleDto, username); diff --git a/src/samples/schemas/sample.schema.ts b/src/samples/schemas/sample.schema.ts index 5dd782dea..89cb0cee5 100644 --- a/src/samples/schemas/sample.schema.ts +++ b/src/samples/schemas/sample.schema.ts @@ -61,6 +61,12 @@ export class SampleClass extends OwnableClass { */ @Prop({ type: Object, required: false, default: {} }) sampleCharacteristics?: Record = {}; + + /** + * Version of the API used when the sample was created or last updated. + */ + @Prop({ type: String, required: false }) + version?: string; } export class SampleWithAttachmentsAndDatasets extends SampleClass { diff --git a/test/Sample.js b/test/Sample.js index 944acc635..d10dec2d0 100644 --- a/test/Sample.js +++ b/test/Sample.js @@ -4,10 +4,53 @@ const { TestData } = require("./TestData"); let accessTokenAdminIngestor = null, accessTokenArchiveManager = null, - sampleId = null, attachmentId = null, - datasetId = null; + datasetId = null, + sampleIdSpecial = null, + sampleIdNested = null; + +const SampleCorrectWithSpecialMetadataKeys = { + ...TestData.SampleCorrect, + sampleCharacteristics: { + "test field1": { + value: "test value", + unit: "", + }, + "test.field2": { + value: "test value", + unit: "", + }, + }, + description: "Sample with special characters in metadata keys", + ownerGroup: "group4", + accessGroups: ["group6"], +}; + +const SampleCorrectWithNestedMetadata = { + ...TestData.SampleCorrect, + sampleCharacteristics: { + "experiment test": { + "nested test1": { + value: "Test Value 1", + unit: "", + type: "string", + }, + "nested.test2": { + value: "Test Value 2", + unit: "", + type: "string", + }, + }, + regular_field: { + value: 1, + unit: "", + }, + }, + description: "Sample with nested metadata", + ownerGroup: "group4", + accessGroups: ["group6"], +}; describe("2200: Sample: Simple Sample", () => { before(async () => { @@ -216,4 +259,96 @@ describe("2200: Sample: Simple Sample", () => { .expect(TestData.SuccessfulDeleteStatusCode) .expect("Content-Type", /json/); }); + + it("0200: adds sample with special characters in metadata keys", async () => { + return request(appUrl) + .post("/api/v3/Samples") + .send(SampleCorrectWithSpecialMetadataKeys) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("sampleId").and.be.string; + sampleIdSpecial = res.body["sampleId"]; + }); + }); + + it("0210: retrieve sample and verify metadata keys are decoded", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleIdSpecial) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("sampleCharacteristics"); + res.body["sampleCharacteristics"].should.have.property("test field1"); + res.body["sampleCharacteristics"].should.have.property("test.field2"); + }); + }); + + it("0220: update sample and verify metadata keys are decoded", async () => { + const update = { + sampleCharacteristics: { + "test field1 updated": { + value: "test value", + unit: "", + }, + "test.field2.updated": { + value: "test value", + unit: "", + }, + }, + }; + return request(appUrl) + .patch("/api/v3/Samples/" + sampleIdSpecial) + .send(update) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("sampleCharacteristics"); + res.body["sampleCharacteristics"].should.have.property( + "test field1 updated", + ); + res.body["sampleCharacteristics"].should.have.property( + "test.field2.updated", + ); + }); + }); + + it("0230: adds sample with nested metadata keys", async () => { + return request(appUrl) + .post("/api/v3/Samples") + .send(SampleCorrectWithNestedMetadata) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have + .property("ownerGroup") + .and.equal(SampleCorrectWithNestedMetadata.ownerGroup); + res.body.should.have.property("sampleId").and.be.string; + sampleIdNested = res.body["sampleId"]; + }); + }); + + it("0240: retrieve sample and verify nested metadata keys are decoded", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleIdNested) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + const metadata = res.body.sampleCharacteristics; + + metadata.should.have.property("experiment test"); + metadata["experiment test"].should.have.property("nested test1"); + metadata["experiment test"].should.have.property("nested.test2"); + }); + }); }); From 8b10dfb4e92cfec27650ce0a11bb0618155b4eac Mon Sep 17 00:00:00 2001 From: Omkar Zade Date: Wed, 4 Feb 2026 15:31:25 +0100 Subject: [PATCH 010/120] fix(legacy-history): pass plain js object to legacy history adapter (#2521) fix(legacy-history): pass plain js object instead of mongoose document to convertGenericToObsoleteHistories --- src/datasets/datasets.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 689a29ce4..1b6023f25 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -617,7 +617,7 @@ export class DatasetsController { documentId: datasetId, subsystem: "Dataset", }), - currentDataset, + currentDataset.toObject(), ).reverse(); } From e7520dc856c525bea2189d6526f2ace7a2930c5b Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 6 Feb 2026 13:57:42 +0100 Subject: [PATCH 011/120] updated frontend configuration with default columns settings --- src/config/frontend.config.json | 222 +++++++++++++++++++++++++++++--- 1 file changed, 203 insertions(+), 19 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 6f6669638..373264f31 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -124,80 +124,215 @@ "columns": [ { "name": "select", - "order": 0, "type": "standard", + "width": 120, "enabled": true }, { "name": "pid", - "order": 1, "type": "standard", + "width": 130, "enabled": true }, { "name": "datasetName", - "order": 2, "type": "standard", + "width": 250, "enabled": true }, { "name": "runNumber", - "order": 3, "type": "standard", + "width": 120, "enabled": true }, { "name": "sourceFolder", - "order": 4, "type": "standard", - "enabled": true + "width": 200, + "enabled": false + }, + { + "name": "sourceFolderHost", + "type": "standard", + "width": 200, + "enabled": false }, { "name": "size", - "order": 5, "type": "standard", + "width": 150, "enabled": true }, { - "name": "creationTime", - "order": 6, + "name": "numberOfFiles", "type": "standard", - "enabled": true + "width": 120, + "enabled": false + }, + { + "name": "creationTime", + "type": "date", + "enabled": true, + "width": 200, + "format": "yyyy-mm-dd HH:MM" + }, + { + "name": "keywords", + "type": "list", + "enabled": false, + "width": 200 + }, + { + "name": "description", + "type": "hovercontent", + "enabled": false, + "width": 150 }, { "name": "type", - "order": 7, "type": "standard", - "enabled": true + "width": 200, + "enabled": false }, { "name": "image", - "order": 8, "type": "standard", + "width": 250, "enabled": true }, { - "name": "metadata", - "order": 9, + "name": "scientificMetadata", + "type": "hovercontent", + "width": 200, + "enabled": false + }, + { + "name": "scientificMetadataSchema", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "scientificMetadataValid", "type": "standard", + "width": 100, + "enabled": false + }, + { + "name": "owner", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "ownerEmail", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "orcidOfOwner", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "contactEmail", + "type": "standard", + "width": 200, "enabled": false }, { "name": "proposalId", - "order": 10, "type": "standard", + "width": 200, "enabled": true }, + { + "name": "proposalIds", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "license", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "isPublished", + "type": "standard", + "width": 100, + "enabled": false + }, + { + "name": "techniques", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "comment", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "dataQualityMetrics", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "principalInvestigator", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "startTime", + "type": "date", + "width": 200, + "enabled": false, + "format": "yyyy-mm-dd HH:MM" + }, + { + "name": "endTime", + "type": "date", + "width": 200, + "enabled": false, + "format": "yyyy-mm-dd HH:MM" + }, + { + "name": "creationLocation", + "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "sampleIds", + "type": "standard", + "width": 200, + "enabled": false + }, { "name": "ownerGroup", - "order": 11, "type": "standard", + "width": 200, "enabled": false }, { "name": "dataStatus", - "order": 12, "type": "standard", + "width": 200, + "enabled": false + }, + { + "name": "accessGroups", + "type": "standard", + "width": 200, "enabled": false } ], @@ -251,7 +386,7 @@ "columns": [ { "name": "proposalId", - "width": 180, + "width": 130, "enabled": true }, { @@ -281,6 +416,48 @@ "name": "numberOfDatasets", "width": 150, "enabled": true + }, + { + "name": "pi_firstname", + "width": 200, + "enabled": false + }, + { + "name": "pi_email", + "width": 150, + "enabled": false + }, + { + "name": "firstname", + "width": 200, + "enabled": false + }, + { + "name": "lastname", + "width": 200, + "enabled": false + }, + { + "name": "email", + "width": 150, + "enabled": false + }, + { + "name": "endTime", + "type": "date", + "format": "yyyy-MM-dd", + "width": 200, + "enabled": false + }, + { + "name": "parentProposalId", + "width": 130, + "enabled": false + }, + { + "name": "type", + "width": 200, + "enabled": false } ], "filters": [ @@ -338,7 +515,14 @@ "title": "Proposal Title", "abstract": "Abstract", "pi_lastname": "PI Last Name", + "pi_firstname": "PI First Name", + "pi_email": "PI Email", + "firstname": "Proposer First Name", + "lastname": "Proposer Last Name", + "email": "Proposer Email", + "endTime": "End Date", "type": "Type", + "parentProposalId": "Parent Proposal Id", "instrumentIds": "Instrument", "numberOfDatasets": "Number of Datasets" } From acc7e96c57b2b7ce04439a90e77f9a9fa8a93fa8 Mon Sep 17 00:00:00 2001 From: abdimo101 Date: Mon, 9 Feb 2026 10:44:17 +0100 Subject: [PATCH 012/120] feat(config): add documentation for frontend configuration options (#2513) * added documentation for frontend config flags * changed from flags to options * changed proposalDefaultTab to defaultTab and also updated the document --- docs/frontend-config-guide/frontend-config.md | 101 ++++++++++++++++++ src/config/frontend.config.json | 3 + 2 files changed, 104 insertions(+) create mode 100644 docs/frontend-config-guide/frontend-config.md diff --git a/docs/frontend-config-guide/frontend-config.md b/docs/frontend-config-guide/frontend-config.md new file mode 100644 index 000000000..832dc90a8 --- /dev/null +++ b/docs/frontend-config-guide/frontend-config.md @@ -0,0 +1,101 @@ +# Frontend Configuration Guide + +## Overview + +This guide documents frontend configuration options that control various UI behaviors and features in SciCat. These settings are defined in the configuration file specified by the `FRONTEND_CONFIG_FILE` environment variable (default `src/config/frontend.config.json`). + +**TODO:** Many of these configuration options were added a long time ago and may no longer be in use. This documentation should be reviewed and updated to reflect the current state of the application and remove obsolete configuration flags. + +## Configuration Options + +| **Configuration Options** | **Type** | **Default Value** | **Description** | +|------------------------|----------|-------------------|-----------------| +| **`defaultMainPage`** | object | | Defines the default landing page for authenticated and non-authenticated users. | +|     `nonAuthenticatedUser` | string | `"DATASETS"` | Default landing page for non-authenticated users. | +|     `authenticatedUser` | string | `"PROPOSALS"` | Default landing page for authenticated users. | +| `checkBoxFilterClickTrigger` | boolean | `false` | Enable/disable automatic filter application when clicking checkboxes in filters. | +| `accessTokenPrefix` | string | `"Bearer "` | Set the backend token prefix. Should be empty string for old backend or "Bearer " if using scicat-backend-next. | +| `addDatasetEnabled` | boolean | `false` | Show/hide the "Create Dataset" button in the Datasets Dashboard. | +| `archiveWorkflowEnabled` | boolean | `false` | Enable/disable the archive/retrieve workflow. | +| `datasetReduceEnabled` | boolean | `true` | Enable/disable the automatic Dataset reduction/analysis workflow. | +| `datasetJsonScientificMetadata` | boolean | `true` | | +| `editDatasetEnabled` | boolean | `true` | | +| `editDatasetSampleEnabled` | boolean | `true` | Enable/disable editing of which Sample a Dataset belongs to. | +| `editMetadataEnabled` | boolean | `true` | Enable/disable editing of Scientific Metadata. | +| `addSampleEnabled` | boolean | `false` | | +| `externalAuthEndpoint` | string | `"/api/v3/auth/msad"` | Endpoint used for third party authentication, e.g., LDAP. | +| `facility` | string | `"SciCat Vanilla"` | Facility running the SciCat instance. | +| `siteIcon` | string | `""` | Path to the site icon/logo image file. | +| `siteTitle` | string | `""` | Title displayed in the browser tab and header. | +| `siteSciCatLogo` | string | `"full"` | | +| `loginFacilityLabel` | string | `""` | Label for the facility login option. | +| `loginLdapLabel` | string | `""` | Label for the LDAP login option. | +| `loginLocalLabel` | string | `""` | Label for the local login option. | +| `loginFacilityEnabled` | boolean | `true` | Enable/disable facility login option. | +| `loginLdapEnabled` | boolean | `true` | Enable/disable LDAP login option. | +| `loginLocalEnabled` | boolean | `true` | Enable/disable local login option. | +| `fileColorEnabled` | boolean | `true` | Enable/disable file size color representation in the Datasets Dashboard. | +| `fileDownloadEnabled` | boolean | `true` | Enable/disable download workflow for Dataset datafiles. | +| `gettingStarted` | string | `null` | URL to Getting Started guide for SciCat, displayed on the Help page. | +| `ingestManual` | string | `null` | URL to Ingest Manual for SciCat, displayed on the Help page. | +| `jobsEnabled` | boolean | `true` | Enable/disable Job workflow. | +| `jsonMetadataEnabled` | boolean | `true` | Show/hide the "Show Metadata" button on the details pages, allowing users to see the JSON representation of the current document. | +| `jupyterHubUrl` | string | `""` | URL to Jupyter Hub instance used for data analysis. | +| `landingPage` | string | `""` | URL to the facility's Landing Page for Published Data. | +| `lbBaseURL` | string | `""` | URL to the SciCat Backend. | +| `logbookEnabled` | boolean | `true` | Enable/disable SciChat Logbook integration. | +| `loginFormEnabled` | boolean | `true` | Enable/disable the local Login form. Should be disabled if using oAuth2 for authentication. | +| `metadataPreviewEnabled` | boolean | `true` | Enable/disable Scientific Metadata preview on the Datasets Dashboard. | +| `metadataStructure` | string | `""` | Allow tree structure for Scientific Metadata. Set to empty string for flat structure, or "tree" for tree structure. | +| `multipleDownloadAction` | string | `""` | URL to service handling direct download of datafiles. | +| `multipleDownloadEnabled` | boolean | `true` | Enable/disable ability to download multiple datafiles. | +| `oAuth2Endpoints` | array | `[]` | List of endpoints used for oAuth2 authentication. Each endpoint should have `authURL` and `displayText` properties. | +| `policiesEnabled` | boolean | `true` | Enable/disable Dataset Policies workflow. | +| `retrieveDestinations` | array | `[]` | List of destinations for Dataset retrievals. | +| `riotBaseUrl` | string | `""` | URL to SciChat client. | +| `scienceSearchEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata. | +| `scienceSearchUnitsEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata using units. | +| `searchPublicDataEnabled` | boolean | `true` | Enable/disable filtering Datasets on public or non-public data. | +| `searchSamples` | boolean | `true` | Enable/disable searching Samples on Samples Dashboard. | +| `sftpHost` | string | `""` | URL to SFTP service used for downloading files exceeding maximum allowed file size. | +| `sourceFolder` | string | `""` | Default source folder path for datasets. | +| `maxDirectDownloadSize` | number | `0` | Set a maximum allowed file size for downloading datafiles over HTTP (in bytes). | +| `maxFileSizeWarning` | string | `""` | Warning message displayed when files exceed the maximum direct download size. Supports placeholders: ``, ``, ``. | +| `shareEnabled` | boolean | `true` | Enable/disable workflow for sharing Datasets with other users using their email address. | +| `shoppingCartEnabled` | boolean | `true` | Enable/disable the Dataset cart used for bulk actions. | +| `shoppingCartOnHeader` | boolean | `true` | Toggle Dataset cart placement, either on header or to the left on the Datasets Dashboard. | +| `tableSciDataEnabled` | boolean | `true` | Enable/disable Scientific Metadata table view on details pages. If disabled, Scientific Metadata is displayed as raw JSON. | +| `datasetDetailsShowMissingProposalId` | boolean | `false` | | +| `notificationInterceptorEnabled` | boolean | `true` | | +| `metadataEditingUnitListDisabled` | boolean | `true` | | +| `hideEmptyMetadataTable` | boolean | `false` | | +| `datafilesActionsEnabled` | boolean | `true` | Enable/disable custom datafile actions configuration. | +| `datafilesActions` | array | `[]` | Array of custom action configurations for datafiles. Each action can define download, notebook generation, or other custom behaviors. | +| `labelsLocalization` | object | `{}` | Localization configuration for labels in datasets and proposals. Maps field names to display labels. | +| `dateFormat` | string | `"yyyy-MM-dd HH:mm"` | Default date format used throughout the application. | +| **`mainMenu`** | object | | Configuration for main menu visibility based on user authentication status. | +|     **`nonAuthenticatedUser`** | object | | Menu configuration for non-authenticated users. | +|         `datasets` | boolean | `true` | Show/hide datasets menu item. | +|         `files` | boolean | `false` | Show/hide files menu item. | +|         `instruments` | boolean | `true` | Show/hide instruments menu item. | +|         `jobs` | boolean | `false` | Show/hide jobs menu item. | +|         `policies` | boolean | `false` | Show/hide policies menu item. | +|         `proposals` | boolean | `true` | Show/hide proposals menu item. | +|         `publishedData` | boolean | `true` | Show/hide published data menu item. | +|         `samples` | boolean | `false` | Show/hide samples menu item. | +|     **`authenticatedUser`** | object | | Menu configuration for authenticated users. | +|         `datasets` | boolean | `true` | Show/hide datasets menu item. | +|         `files` | boolean | `true` | Show/hide files menu item. | +|         `instruments` | boolean | `true` | Show/hide instruments menu item. | +|         `jobs` | boolean | `true` | Show/hide jobs menu item. | +|         `policies` | boolean | `false` | Show/hide policies menu item. | +|         `proposals` | boolean | `true` | Show/hide proposals menu item. | +|         `publishedData` | boolean | `true` | Show/hide published data menu item. | +|         `samples` | boolean | `true` | Show/hide samples menu item. | +| **`defaultTab`** | object | | Specifies which tab is shown by default when viewing different entities. | +|     `proposal` | string | `"details"` | Default tab for proposals. Valid values: `"details"`, `"datasets"`, `"relatedProposals"`, `"logbook"`. | + +## See Also + +- [Default List Settings Configuration](./default-list-settings.md) +- [Dynamic Dataset Detail Component Configuration](./dynamic-dataset-detail-component.md) \ No newline at end of file diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 6f6669638..00e81a7f6 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -550,5 +550,8 @@ "publishedData": true, "samples": true } + }, + "defaultTab": { + "proposal": "relatedProposals" } } From dba90e5231b8b78beeb6b28e168c472f87f7ff1d Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 9 Feb 2026 14:49:14 +0100 Subject: [PATCH 013/120] fix(migration): revert migration filename change (#2526) --- ...tadatakeys.js => 20251117155200-encode-metadatakeys.js} | 7 +++++++ 1 file changed, 7 insertions(+) rename migrations/{20260126111900-encode-dataset-metadatakeys.js => 20251117155200-encode-metadatakeys.js} (89%) diff --git a/migrations/20260126111900-encode-dataset-metadatakeys.js b/migrations/20251117155200-encode-metadatakeys.js similarity index 89% rename from migrations/20260126111900-encode-dataset-metadatakeys.js rename to migrations/20251117155200-encode-metadatakeys.js index 78433057e..d53b0e444 100644 --- a/migrations/20260126111900-encode-dataset-metadatakeys.js +++ b/migrations/20251117155200-encode-metadatakeys.js @@ -4,6 +4,13 @@ const { decodeScientificMetadataKeys, } = require("../dist/common/utils"); +/** + * + * This migration encodes the keys of the scientificMetadata field in the Dataset collection + * to ensure they are compatible with MongoDB's key restrictions. The up function encodes the keys, + * while the down function decodes them back to their original form. + */ + module.exports = { async up(db, client) { const bulkOps = []; From 49efc453bbaa51db69e5452d2c8eb28343f8f033 Mon Sep 17 00:00:00 2001 From: abdimo101 Date: Mon, 9 Feb 2026 19:17:36 +0100 Subject: [PATCH 014/120] refactor(config): set proposal default tab to details (#2527) set proposal default tab to details --- src/config/frontend.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 00e81a7f6..c6528db05 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -552,6 +552,6 @@ } }, "defaultTab": { - "proposal": "relatedProposals" + "proposal": "details" } } From d0e40bdfd42e5ef73e3c5e81a161c99d20338e52 Mon Sep 17 00:00:00 2001 From: Carlo Minotti <50220438+minottic@users.noreply.github.com> Date: Tue, 10 Feb 2026 10:04:16 +0100 Subject: [PATCH 015/120] feat: add error string in validate (#2525) --- src/datasets/datasets.controller.ts | 25 ++++++++++++++++++------- test/DatasetCustom.js | 1 + test/DerivedDataset.js | 3 ++- test/RawDataset.js | 1 + 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 1b6023f25..a85c9eed2 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -832,7 +832,7 @@ export class DatasetsController { | CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto | CreateDatasetDto, - ): Promise<{ valid: boolean }> { + ): Promise<{ valid: boolean; error?: string }> { await this.checkPermissionsForObsoleteDatasetCreate( request, createDatasetObsoleteDto, @@ -856,12 +856,23 @@ export class DatasetsController { ); const errorsTestCustomCorrect = await validate(dtoTestCustomCorrect); - const valid = - errorsTestRawCorrect.length == 0 || - errorsTestDerivedCorrect.length == 0 || - errorsTestCustomCorrect.length == 0; - - return { valid: valid }; + const joinErrors = (errors: ValidationError[]) => + errors + .flatMap((err) => + err.constraints ? Object.values(err.constraints) : [], + ) + .join("; "); + + let targetErrors: ValidationError[]; + if (createDatasetObsoleteDto.type === "raw") + targetErrors = errorsTestRawCorrect; + else if (createDatasetObsoleteDto.type === "derived") + targetErrors = errorsTestDerivedCorrect; + else targetErrors = errorsTestCustomCorrect; + + if (targetErrors.length > 0) + return { valid: false, error: joinErrors(targetErrors) }; + return { valid: true }; } // GET /datasets diff --git a/test/DatasetCustom.js b/test/DatasetCustom.js index 31b7f8f56..43ed94e89 100644 --- a/test/DatasetCustom.js +++ b/test/DatasetCustom.js @@ -207,6 +207,7 @@ describe("2400: CustomDataset: Custom Type Datasets", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("valid").and.equal(false); + res.body.should.have.property("error").and.equal("datasetName must be a string"); }); }); diff --git a/test/DerivedDataset.js b/test/DerivedDataset.js index deb16158d..0de7d93ea 100644 --- a/test/DerivedDataset.js +++ b/test/DerivedDataset.js @@ -83,7 +83,7 @@ describe("0700: DerivedDataset: Derived Datasets", () => { it("0110: adds a new minimal derived dataset", async () => { return request(appUrl) .post("/api/v3/Datasets") - .send({...TestData.DerivedCorrectMin, sourceFolder: "/data/derived/"}) + .send({ ...TestData.DerivedCorrectMin, sourceFolder: "/data/derived/" }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) @@ -221,6 +221,7 @@ describe("0700: DerivedDataset: Derived Datasets", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("valid").and.equal(false); + res.body.should.have.property("error").and.equal("each value in inputDatasets must be a string; each value in usedSoftware must be a string"); }); }); diff --git a/test/RawDataset.js b/test/RawDataset.js index d6a93ace5..c55347b8e 100644 --- a/test/RawDataset.js +++ b/test/RawDataset.js @@ -127,6 +127,7 @@ describe("1900: RawDataset: Raw Datasets", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("valid").and.equal(false); + res.body.should.have.property("error").and.equal("principalInvestigator must be a string; creationLocation must be a string"); }); }); From ff0e416e545b489294642fba68a5f59385107770 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 10 Feb 2026 15:32:27 +0100 Subject: [PATCH 016/120] needed changes to FE config --- src/config/frontend.config.json | 205 +++++++++++++++++++++++++++++--- 1 file changed, 186 insertions(+), 19 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 373264f31..a6ba5c47c 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -33,7 +33,10 @@ "jupyterHubUrl": "", "landingPage": "doi.ess.eu/detail/", "lbBaseURL": "http://localhost:3000", - "logbookEnabled": true, + "ingestorComponent": { + "ingestorEnabled": false + }, + "logbookEnabled": false, "loginFormEnabled": true, "metadataPreviewEnabled": true, "metadataStructure": "", @@ -69,57 +72,215 @@ { "id": "eed8efec-4354-11ef-a3b5-d75573a5d37f", "description": "This action let users download all files using the zip service", - "order": 4, + "order": 1, "label": "Download All", "files": "all", "mat_icon": "download", + "type": "form", "url": "https://zip.scicatproject.org/download/all", "target": "_blank", - "enabled": "#SizeLimit", + "variables" : { + "pid": "#Dataset0Pid", + "files": "#Dataset0FilesPath", + "totalSize": "#Dataset0FilesTotalSize", + "folder": "#Dataset0SourceFolder" + }, + "enabled": "#MaxDownloadableSize(@totalSize)", + "inputs" : { + "item[]" : "@pid", + "directory[]" : "@folder", + "files[]": "@files" + }, "authorization": ["#datasetAccess", "#datasetPublic"] }, { "id": "3072fafc-4363-11ef-b9f9-ebf568222d26", "description": "This action let users download selected files using the zip service", - "order": 3, + "order": 2, "label": "Download Selected", "files": "selected", "mat_icon": "download", + "type": "form", "url": "https://zip.scicatproject.org/download/selected", "target": "_blank", - "enabled": "#Selected && #SizeLimit", + "variables" : { + "pid": "#Dataset0Pid", + "files": "#Dataset0SelectedFilesPath", + "selected": "#Dataset0SelectedFilesCount", + "totalSize": "#Dataset0SelectedFilesTotalSize", + "folder": "#Dataset0SourceFolder" + }, + "inputs" : { + "auth_token" : "#tokenBearer", + "jwt" : "#jwt", + "item[]" : "@pid", + "directory[]" : "@folder", + "files[]": "@files" + }, + "enabled": "#Length(@files) && #MaxDownloadableSize(@totalSize)", "authorization": ["#datasetAccess", "#datasetPublic"] }, { "id": "4f974f0e-4364-11ef-9c63-03d19f813f4e", "description": "This action let users download jupyter notebook properly populated with dataset pid and all files using an instance of sciwyrm", - "order": 2, - "label": "Notebook All", + "order": 3, + "label": "Notebook All (Form)", + "files": "all", + "icon": "/assets/icons/jupyter_logo.png", + "type": "form", + "url": "https://www.scicat.info/notebook/all", + "target": "_blank", + "variables" : { + "pid": "#Dataset0Pid", + "files": "#Dataset0FilesPath", + "totalSize": "#Dataset0FilesTotalSize", + "folder": "#Dataset0SourceFolder" + }, + "enabled": "", + "inputs" : { + "auth_token" : "#token", + "jwt" : "#jwt", + "item[]" : "@pid", + "directory[]" : "@folder", + "files[]": "@files" + }, + "authorization": ["#datasetAccess", "#datasetPublic"] + }, + { + "id": "fa3ce6ee-482d-11ef-95e9-ff2c80dd50bd", + "order": 4, + "label": "Notebook Selected (Form)", + "files": "selected", + "icon": "/assets/icons/jupyter_logo.png", + "type": "form", + "url": "https://www.scicat.info/notebook/selected", + "target": "_blank", + "variables" : { + "pid": "#Dataset0Pid", + "files": "#Dataset0SelectedFilesPath", + "selected": "#Dataset0SelectedFilesCount", + "totalSize": "#Dataset0SelectedFilesTotalSize", + "folder": "#Dataset0SourceFolder" + }, + "inputs" : { + "auth_token" : "#token", + "jwt" : "#jwt", + "item[]" : "@pid", + "directory[]" : "@folder", + "files[]": "@files" + }, + "enabled": "#Length(@files) > 0", + "authorization": ["#datasetAccess", "#datasetPublic"] + }, + { + "id": "0cd5b592-0b1a-11f0-a42c-23e177127ee7", + "description": "This action let users download jupyter notebook properly populated with dataset pid and all files using an instance of sciwyrm", + "order": 5, + "label": "Notebook All (Download JSON)", "files": "all", "type": "json-download", "icon": "/assets/icons/jupyter_logo.png", - "url": "https://sciiwyrm.scicatproject.org/notebook", + "url": "https://www.sciwyrm.info/notebook", "target": "_blank", "authorization": ["#datasetAccess", "#datasetPublic"], - "payload": "{\"template_id\":\"c975455e-ede3-11ef-94fb-138c9cd51fc0\",\"parameters\":{\"dataset\":\"{{ datasetPid }}\",\"directory\":\"{{ sourceFolder }}\",\"files\": {{ filesPath }},\"jwt\":\"{{ jwt }}\",\"scicat_url\":\"https://staging.scicat.ess.url\",\"file_server_url\":\"sftserver2.esss.dk\",\"file_server_port\":\"22\"}}", - "filename": "{{ uuid }}.ipynb" + "variables" : { + "pid": "#Dataset0Pid", + "files": "#Dataset0FilesPath", + "folder": "#Dataset0SourceFolder" + }, + "payload": "{\"template_id\":\"c975455e-ede3-11ef-94fb-138c9cd51fc0\",\"parameters\":{\"dataset\":\"{{ @pid }}\",\"directory\":\"{{ @folder }}\",\"files\": {{ @files[] }},\"jwt\":\"{{ #jwt }}\",\"scicat_url\":\"https://staging.scicat.ess.url\",\"file_server_url\":\"sftserver2.esss.dk\",\"file_server_port\":\"22\"}}", + "filename": "{{ #uuid }}.ipynb" }, { - "id": "fa3ce6ee-482d-11ef-95e9-ff2c80dd50bd", + "id": "a414773a-a526-11f0-a7f2-ff1026e5dba9", "description": "This action let users download jupyter notebook properly populated with dataset pid and selected files using an instance of sciwyrm", - "order": 1, - "label": "Notebook Selected", - "files": "selected", + "order": 6, + "label": "Notebook Selected (Download JSON)", "type": "json-download", "icon": "/assets/icons/jupyter_logo.png", - "url": "https://sciwyrm.scicatproject.org/notebook", + "url": "https://www.sciwyrm.info/notebook", "target": "_blank", - "enabled": "#Selected", + "enabled": "#Length(@files) > 0", "authorization": ["#datasetAccess", "#datasetPublic"], - "payload": "{\"template_id\":\"c975455e-ede3-11ef-94fb-138c9cd51fc0\",\"parameters\":{\"dataset\":\"{{ datasetPid }}\",\"directory\":\"{{ sourceFolder }}\",\"files\": {{ filesPath }},\"jwt\":\"{{ jwt }}\",\"scicat_url\":\"https://staging.scicat.ess.url\",\"file_server_url\":\"sftserver2.esss.dk\",\"file_server_port\":\"22\"}}", - "filename": "{{ uuid }}.ipynb" + "variables" : { + "pid": "#Dataset0Pid", + "files": "#Dataset0SelectedFilesPath", + "selected": "#Dataset0SelectedFiles", + "folder": "#Dataset0SourceFolder" + }, + "payload": "{\"template_id\":\"c975455e-ede3-11ef-94fb-138c9cd51fc0\",\"parameters\":{\"dataset\":\"{{ @pid }}\",\"directory\":\"{{ @folder }}\",\"files\": {{ @files[] }},\"jwt\":\"{{ #jwt }}\",\"scicat_url\":\"https://staging.scicat.ess.url\",\"file_server_url\":\"sftserver2.esss.dk\",\"file_server_port\":\"22\"}}", + "filename": "{{ #uuid }}.ipynb" + }, + { + "id": "9c6a11b6-a526-11f0-8795-6f025b320cc3", + "description": "This action let users make a call an arbitrary URL and store the reply in the store", + "order": 7, + "label": "Publish", + "type": "xhr", + "mat_icon": "lock_open", + "method" : "PATCH", + "url": "http://localhost:3000/dataset/{{ @pid }}/", + "target": "_blank", + "enabled": "(#datasetOwner || #userIsAdmin) && !@isPublished", + "authorization": "#datasetOwner && !@isPublished", + "variables" : { + "pid": "@Dataset0Pid", + "isPublished" : "#Dataset[0]Field[isPublished]" + }, + "payload": "{\"isPublished\":\"true\"}", + "headers": { + "Content-Type": "application/json", + "Authorization": "#tokenBearer" + } + }, + { + "id": "94a1d694-a526-11f0-947b-038d53cd837a", + "description": "This action let users make a call an arbitrary URL and store the reply in the store", + "order": 8, + "label": "Unpublish", + "type": "xhr", + "mat_icon": "lock", + "method" : "PATCH", + "url": "http://localhost:3000/dataset/{{ @pid }}/", + "target": "_blank", + "enabled": "(#datasetOwner || #userIsAdmin) && @isPublished", + "authorization": "#datasetOwner && @isPublished", + "variables" : { + "pid": "#Dataset0Pid", + "isPublished" : "#Dataset[0]Field[isPublished]" + }, + "payload": "{\"isPublished\":\"false\"}", + "headers": { + "Content-Type": "application/json", + "Authorization": "#tokenBearer" + } + }, + { + "id": "c3bcbd40-a526-11f0-915a-93eeff0860ab", + "description": "This action let users jump to another URL entirely", + "order": 9, + "label": "ESS", + "type": "link", + "icon": "/assets/icons/button_ess.png", + "url": "https://ess.eu", + "target": "_blank" } ], + "datasetDetailsActionsEnabled": false, + "datasetDetailsActions": [], + "selectionActionsEnabled": true, + "selectionActions": [], + "labelMaps": { + "filters": { + "LocationFilter": "Location", + "PidFilter": "Pid", + "GroupFilter": "Group", + "TypeFilter": "Type", + "KeywordFilter": "Keyword", + "DateRangeFilter": "Start Date - End Date", + "TextFilter": "Text" + } + }, "defaultDatasetsListSettings": { "columns": [ { @@ -495,7 +656,13 @@ "metadataJsonView": "Metadata JsonView", "datasetName": "Dataset Name", "scientificMetadata.run_number.value": "Run Number", - "scientificMetadata.start_time": "Start Time" + "scientificMetadata.start_time": "Start Time", + "runNumber": "Run Number", + "size": "Size", + "image": "Image", + "proposalId": "Proposal Id", + "startTime": "Start Time", + "endTime": "End Time" }, "proposal": { "General Information": "Proposal Information", From b57572927a6267a57c0adfe423ef9da1633bdb84 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 10 Feb 2026 16:06:34 +0100 Subject: [PATCH 017/120] feat: metadata keys collection (#2384) * First draft of schema and dto for metadata keys * Added template for module, controller and service * fix lint and import url * added controller & dto * some lint fix * added migration script * improve migration script * add casl-ability for metadata-key and add missing fields for dto and schema * fix wrong swagger response type for attachment v4 endpoint * added findAll endpoint with casl ability * remove create, update, delete abilities for metadataKeys * remove corresponding action enum from the above commit * fix ApiResponse type for attachment and metadatakeys controller * update default frontend config for more compact table content * add access logic * integrate metadataKeys service with dataset * unit test fix * fix unit test * updated documentation * cleanup unused import * fix typo * create metadatakeys for dataset, instrument, proposal and samples * fix unit test * add unit tests for metadatakeys v4 * refactor metadatakeys service unit test to make it readable * add api test * fix api test * test1 * test2 * test * fix metadatakey api test --------- Co-authored-by: junjiequan --- docs/developer-guide/metadatakeys-module.md | 90 +++++++++ ...51120153452-add-updatedby-to-instrument.js | 9 +- ...153400-sync-metadata-keys-from-datasets.js | 98 ++++++++++ src/app.module.ts | 4 +- src/attachments/attachments.v4.controller.ts | 7 +- src/casl/action.enum.ts | 16 ++ src/casl/casl-ability.factory.ts | 56 +++++- src/common/schemas/ownable.schema.ts | 1 + src/config/frontend.config.json | 31 +++- .../runtime-config.controller.ts | 2 +- src/datasets/datasets.module.ts | 2 + src/datasets/datasets.service.spec.ts | 7 + src/datasets/datasets.service.ts | 75 ++++++-- src/instruments/instruments.module.ts | 2 + src/instruments/instruments.service.spec.ts | 7 + src/instruments/instruments.service.ts | 62 ++++++- .../dto/create-metadata-key.dto.ts | 22 +++ .../dto/output-metadata-key.dto.ts | 78 ++++++++ .../dto/update-metadata-key.dto.ts | 50 +++++ src/metadata-keys/metadatakeys.module.ts | 58 ++++++ .../metadatakeys.service.spec.ts | 141 ++++++++++++++ src/metadata-keys/metadatakeys.service.ts | 137 ++++++++++++++ .../metadatakeys.v4.controller.spec.ts | 125 +++++++++++++ .../metadatakeys.v4.controller.ts | 89 +++++++++ .../schemas/metadatakey.schema.ts | 103 +++++++++++ .../types/metadatakeys-filter-content.ts | 83 +++++++++ .../types/metadatakeys-lookup.ts | 41 +++++ src/proposals/proposals.module.ts | 2 + src/proposals/proposals.service.spec.ts | 7 + src/proposals/proposals.service.ts | 69 ++++++- src/samples/samples.module.ts | 2 + src/samples/samples.service.spec.ts | 7 + src/samples/samples.service.ts | 60 +++++- test/MetadataKeys.js | 174 ++++++++++++++++++ 34 files changed, 1668 insertions(+), 49 deletions(-) create mode 100644 docs/developer-guide/metadatakeys-module.md create mode 100644 migrations/20260116153400-sync-metadata-keys-from-datasets.js create mode 100644 src/metadata-keys/dto/create-metadata-key.dto.ts create mode 100644 src/metadata-keys/dto/output-metadata-key.dto.ts create mode 100644 src/metadata-keys/dto/update-metadata-key.dto.ts create mode 100644 src/metadata-keys/metadatakeys.module.ts create mode 100644 src/metadata-keys/metadatakeys.service.spec.ts create mode 100644 src/metadata-keys/metadatakeys.service.ts create mode 100644 src/metadata-keys/metadatakeys.v4.controller.spec.ts create mode 100644 src/metadata-keys/metadatakeys.v4.controller.ts create mode 100644 src/metadata-keys/schemas/metadatakey.schema.ts create mode 100644 src/metadata-keys/types/metadatakeys-filter-content.ts create mode 100644 src/metadata-keys/types/metadatakeys-lookup.ts create mode 100644 test/MetadataKeys.js diff --git a/docs/developer-guide/metadatakeys-module.md b/docs/developer-guide/metadatakeys-module.md new file mode 100644 index 000000000..f41dbe293 --- /dev/null +++ b/docs/developer-guide/metadatakeys-module.md @@ -0,0 +1,90 @@ +--- +title: MetadataKeys Synchronization Service Overview +audience: Technical +created_by: Junjie Quan +created_on: 2026-02-09 +--- + +## Overview & Problem Statement + +The Metadata Keys Module is a dedicated standalone component designed to manage and retrieve metadata keys across the platform. This module replaces the legacy GET /datasets/metadataKeys endpoint. + +### Problem Addressed + +The previous implementation in the Datasets service lacked a permission-based filtering layer. Because it attempted to return all global keys without ownership validation, it caused: + +- Performance: Significant latency when processing large datasets. +- Stability: Crashes occurred when retrieval limits were missing or improperly configured. +- Risks: Users could see metadata keys they did not have permissions to access. + +## Module Architecture + +This module consists of a dedicated Controller and Service layer that implements a robust permission-aware logic. + +### MetadataKeysController + +Provides the API interface for searching keys. Allowed filters can be found in `src/metadata-keys/metadatakeys.service.ts` and exmaple can be find in `src/metadata-keys/types/metadatakeys-filter-content.ts` + +- `Endpoint`: GET /metadatakeys (replaces /datasets/metadataKeys) +- `Method`: findAll +- `Endpoint Access`: Endpoint can be Accessed by any users + +### MetadataKeysService + +This handles the business logic and talks to the database. It is divided into user-facing search logic and internal data synchronization. + +#### Permission Layer (Applies to findAll only): + +When a user searches for keys, the service uses accessibleBy to automatically append access filters based on CASL permissions: + +- `Admins`: Can search and get all metadata keys in the system. +- `Authenticated Users`: Can only get keys where they are part of the ownerGroup or accessGroups. +- `Unauthenticated Users`: Can only get keys that are marked as isPublished. + +#### Service Methods: + +- `findAll`: The only public-facing method. It applies the permission layer and then uses a database aggregation pipeline to find and return the specific keys requested by the user. Every search is limited to 100 results by default, if limit is not provided. +- `insertManyFromSource`: An internal method that takes an original document (like a Dataset), extracts fields from **scientificMetadata**, **metadata**, and **customMetadata**, and creates new records in the Metadata Keys collection. +- `deleteMany`: Removes metadata key entries associated with a source document when that document is deleted from the system. +- `replaceManyFromSource`: Triggered when a source document (e.g., a Dataset or Proposal) is updated. It calls `deleteMany` and `insertManyFromSource` sequentially. + +## Usage Example + +To list all metadata keys associated with a dataset, the user must provide the sourceType and sourceId. If the fields array is provided, only those specific fields will be returned: + +```json +{ + "where": { + "sourceType": "dataset", + "sourceId": "datasetId" + }, + "fields": ["humanreadableName", "key"], + "limits": { + "limit": 10, + "skip": 0, + "sort": { + "createdAt": "asc | desc" + } + } +} +``` + +To retrieve a specific metadata key, use the following filter: + +```json +{ + "where": { + "sourceType": "dataset", + "sourceId": "datasetId", + "key": "metadata_key_name" + }, + "fields": ["key"], + "limits": { + "limit": 10, + "skip": 0, + "sort": { + "createdAt": "asc | desc" + } + } +} +``` diff --git a/migrations/20251120153452-add-updatedby-to-instrument.js b/migrations/20251120153452-add-updatedby-to-instrument.js index 3c5cfad64..ee43b520c 100644 --- a/migrations/20251120153452-add-updatedby-to-instrument.js +++ b/migrations/20251120153452-add-updatedby-to-instrument.js @@ -2,13 +2,12 @@ module.exports = { async up(db, client) { await db .collection("Instrument") - .updateMany( - { updatedBy: { $exists: false } }, - [{ $set: { updatedBy: "$createdBy" } }] - ); + .updateMany({ updatedBy: { $exists: false } }, [ + { $set: { updatedBy: "$createdBy" } }, + ]); }, async down(db, client) { // No path backward as it's not easy to find on down where updatedBy was added }, -}; \ No newline at end of file +}; diff --git a/migrations/20260116153400-sync-metadata-keys-from-datasets.js b/migrations/20260116153400-sync-metadata-keys-from-datasets.js new file mode 100644 index 000000000..64ba112c9 --- /dev/null +++ b/migrations/20260116153400-sync-metadata-keys-from-datasets.js @@ -0,0 +1,98 @@ +module.exports = { + async up(db) { + const DATASET_COL = "Dataset"; + const METAKEYS_COL = "MetadataKeys"; + + // Aggregation pipeline to extract metadata keys from datasets + const pipeline = [ + // 1) Only datasets that have scientificMetadata object + { $match: { scientificMetadata: { $exists: true, $type: "object" } } }, + + // 2) Prepare fields and convert scientificMetadata -> array + { + $project: { + sourceType: { $literal: "dataset" }, + sourceId: "$pid", + ownerGroup: 1, + accessGroups: 1, + isPublished: 1, + metaArr: { $objectToArray: "$scientificMetadata" }, // {k,v}[] + }, + }, + + // 3) One document per metadata key + { $unwind: "$metaArr" }, + + // 4) Shape final MetadataKeys document + { + $project: { + _id: { $concat: ["dataset_", "$sourceId", "_", "$metaArr.k"] }, // unique per dataset + sourceType: 1, + sourceId: 1, + key: "$metaArr.k", // metadata key name + userGroups: { + $setUnion: [ + [{ $ifNull: ["$ownerGroup", ""] }], + { $ifNull: ["$accessGroups", []] }, + ], + }, // owner + access groups fallback + isPublished: 1, + + // only include humanReadableName if exists + humanReadableName: { + $cond: [ + { $ifNull: ["$metaArr.v.human_name", false] }, + "$metaArr.v.human_name", + "$$REMOVE", + ], + }, + createdBy: { $literal: "migration" }, + createdAt: { $toDate: "$$NOW" }, + }, + }, + + // 5) Upsert into MetadataKeys + { + $merge: { + into: METAKEYS_COL, + on: "_id", // match by dataset id + whenMatched: [ + { + $set: { + sourceType: "$$new.sourceType", + sourceId: "$$new.sourceId", + key: "$$new.key", + userGroups: "$$new.userGroups", + isPublished: "$$new.isPublished", + humanReadableName: "$$new.humanReadableName", + updatedBy: { $literal: "migration" }, + updatedAt: { $toDate: "$$NOW" }, + }, + }, + ], + whenNotMatched: "insert", + }, + }, + ]; + + console.log("--- Syncing metadata keys from datasets ---"); + + const start = Date.now(); + const timer = setInterval(() => { + const sec = Math.floor((Date.now() - start) / 1000); + console.log(`Syncing... ${sec}s`); + }, 1000); // log every 1s + + await db + .collection(DATASET_COL) + .aggregate(pipeline, { allowDiskUse: true }) + .toArray(); + clearInterval(timer); + console.log("--- Syncing metadata keys from datasets completed ---"); + }, + + // Rollback: clear MetadataKeys collection + async down(db) { + await db.collection("MetadataKeys").deleteMany({}); + }, +}; diff --git a/src/app.module.ts b/src/app.module.ts index 054d8066a..8da5939a4 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -43,6 +43,7 @@ import { import { HistoryModule } from "./history/history.module"; import { MaskSensitiveDataInterceptorModule } from "./common/interceptors/mask-sensitive-data.interceptor"; import { RuntimeConfigModule } from "./config/runtime-config/runtime-config.module"; +import { MetadataKeysModule } from "./metadata-keys/metadatakeys.module"; @Module({ imports: [ @@ -51,7 +52,6 @@ import { RuntimeConfigModule } from "./config/runtime-config/runtime-config.modu isGlobal: true, cache: true, }), - RuntimeConfigModule, AuthModule, CaslModule, AttachmentsModule, @@ -70,6 +70,8 @@ import { RuntimeConfigModule } from "./config/runtime-config/runtime-config.modu DatasetsModule, InitialDatasetsModule, InstrumentsModule, + MetadataKeysModule, + RuntimeConfigModule, JobsModule, LogbooksModule, EventEmitterModule.forRoot(), diff --git a/src/attachments/attachments.v4.controller.ts b/src/attachments/attachments.v4.controller.ts index 5844510ad..ad85f69e0 100644 --- a/src/attachments/attachments.v4.controller.ts +++ b/src/attachments/attachments.v4.controller.ts @@ -40,7 +40,6 @@ import { IAttachmentFiltersV4, } from "./interfaces/attachment-filters.interface"; -import { OutputDatasetDto } from "src/datasets/dto/output-dataset.dto"; import { getSwaggerAttachmentFilterContent } from "./types/attachment-filter-contents"; import { FilterValidationPipe } from "src/common/pipes/filter-validation.pipe"; import { CreateAttachmentV4Dto } from "./dto/create-attachment.v4.dto"; @@ -232,7 +231,7 @@ export class AttachmentsV4Controller { }) @ApiResponse({ status: HttpStatus.OK, - type: OutputDatasetDto, + type: OutputAttachmentV4Dto, isArray: true, description: "Return the attachments requested", }) @@ -279,7 +278,7 @@ export class AttachmentsV4Controller { }) @ApiResponse({ status: HttpStatus.OK, - type: OutputDatasetDto, + type: OutputAttachmentV4Dto, isArray: true, description: "Return the attachments requested", }) @@ -324,7 +323,7 @@ export class AttachmentsV4Controller { }) @ApiResponse({ status: HttpStatus.OK, - type: Attachment, + type: OutputAttachmentV4Dto, description: "Return attachment with id specified", }) @Get("/:aid") diff --git a/src/casl/action.enum.ts b/src/casl/action.enum.ts index 3b17d3132..baed10fe5 100644 --- a/src/casl/action.enum.ts +++ b/src/casl/action.enum.ts @@ -266,4 +266,20 @@ export enum Action { HistoryReadPolicy = "history_read_policy", HistoryReadDatablock = "history_read_datablock", HistoryReadAttachment = "history_read_attachment", + + // ------------------------------------- + // MetadataKeys + // ------------------------------------- + // metadatakeys endpoint authorization + MetadataKeysReadEndpoint = "metadatakeys_read_endpoint", + // ------------------------------------- + // metadatakeys data instance authorization + MetadataKeysReadInstance = "metadatakeys_read_instance", + + // ------------------------------------- + // RuntimeConfig + // ------------------------------------- + // runtimeconfig endpoint authorization + RuntimeConfigReadEndpoint = "runtimeconfig_read_endpoint", + RuntimeConfigUpdateEndpoint = "runtimeconfig_update_endpoint", } diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index ed6b95789..43cd16da7 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -31,6 +31,7 @@ import { User } from "src/users/schemas/user.schema"; import { Action } from "./action.enum"; import { RuntimeConfig } from "src/config/runtime-config/schemas/runtime-config.schema"; import { accessibleBy } from "@casl/mongoose"; +import { MetadataKeyClass } from "src/metadata-keys/schemas/metadatakey.schema"; type Subjects = | string @@ -52,6 +53,7 @@ type Subjects = | typeof ElasticSearchActions | typeof Datablock | typeof RuntimeConfig + | typeof MetadataKeyClass > | "all"; type PossibleAbilities = [Action, Subjects]; @@ -88,6 +90,7 @@ export class CaslAbilityFactory { history: this.historyEndpointAccess, datablocks: this.datablockEndpointAccess, runtimeconfig: this.runtimeConfigEndpointAccess, + metadataKeys: this.metadataKeysEndpointAccess, }; endpointAccess(endpoint: string, user: JWTUser) { @@ -919,7 +922,7 @@ export class CaslAbilityFactory { createMongoAbility, ); - can(Action.Read, RuntimeConfig); + can(Action.RuntimeConfigReadEndpoint, RuntimeConfig); if ( user && user.currentGroups.some((g) => this.accessGroups?.admin.includes(g)) @@ -927,7 +930,7 @@ export class CaslAbilityFactory { /* / user that belongs to any of the group listed in ADMIN_GROUPS */ - can(Action.Update, RuntimeConfig); + can(Action.RuntimeConfigUpdateEndpoint, RuntimeConfig); } return build({ detectSubjectType: (item) => @@ -935,6 +938,19 @@ export class CaslAbilityFactory { }); } + metadataKeysEndpointAccess(user: JWTUser) { + const { can, build } = new AbilityBuilder( + createMongoAbility, + ); + + can(Action.MetadataKeysReadEndpoint, MetadataKeyClass); + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + policyEndpointAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, @@ -2374,4 +2390,40 @@ export class CaslAbilityFactory { item.constructor as ExtractSubjectType, }); } + + metadataKeyInstanceAccess(user: JWTUser) { + const { can, build } = new AbilityBuilder( + createMongoAbility, + ); + // ------------------------------------- + // any user can read public attachments + // ------------------------------------- + can(Action.MetadataKeysReadInstance, MetadataKeyClass, { + isPublished: true, + }); + if (user) { + if ( + user.currentGroups.some((g) => this.accessGroups?.admin.includes(g)) + ) { + // ------------------------------------- + // users belonging to any of the group listed in ADMIN_GROUPS + // ------------------------------------- + + can(Action.MetadataKeysReadInstance, MetadataKeyClass); + } else { + // ------------------------------------- + // users with no elevated permissions + // ------------------------------------- + + can(Action.MetadataKeysReadInstance, MetadataKeyClass, { + userGroups: { $in: user.currentGroups }, + }); + } + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } } diff --git a/src/common/schemas/ownable.schema.ts b/src/common/schemas/ownable.schema.ts index c0e6f686b..137c9b5f0 100644 --- a/src/common/schemas/ownable.schema.ts +++ b/src/common/schemas/ownable.schema.ts @@ -22,6 +22,7 @@ export class OwnableClass extends QueryableClass { @Prop({ type: [String], index: true, + default: [], }) accessGroups: string[] = []; diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index c6528db05..2779552b7 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -131,72 +131,84 @@ { "name": "pid", "order": 1, + "width": 160, "type": "standard", "enabled": true }, { "name": "datasetName", "order": 2, + "width": 260, "type": "standard", "enabled": true }, { "name": "runNumber", "order": 3, + "width": 120, "type": "standard", "enabled": true }, { "name": "sourceFolder", "order": 4, + "width": 170, "type": "standard", "enabled": true }, { "name": "size", "order": 5, + "width": 120, "type": "standard", "enabled": true }, { "name": "creationTime", "order": 6, + "width": 180, "type": "standard", "enabled": true }, { "name": "type", "order": 7, + "width": 120, "type": "standard", "enabled": true }, { "name": "image", "order": 8, + "width": 120, "type": "standard", "enabled": true }, { "name": "metadata", "order": 9, + "width": 120, "type": "standard", "enabled": false }, { "name": "proposalId", "order": 10, + "width": 120, "type": "standard", "enabled": true }, { "name": "ownerGroup", "order": 11, + "width": 120, "type": "standard", "enabled": false }, { "name": "dataStatus", "order": 12, + "width": 270, "type": "standard", "enabled": false } @@ -251,35 +263,40 @@ "columns": [ { "name": "proposalId", - "width": 180, + "width": 120, "enabled": true }, { "name": "title", - "width": 250, + "width": 210, + "enabled": true + }, + { + "name": "instrumentName", + "width": 130, "enabled": true }, { "name": "abstract", "type": "hoverContent", - "width": 150, + "width": 120, "enabled": true }, { "name": "startTime", "type": "date", "format": "yyyy-MM-dd", - "width": 200, + "width": 130, "enabled": true }, { - "name": "pi_lastname", + "name": "pi_lastname, pi_firstname", "enabled": true, - "width": 200 + "width": 150 }, { "name": "numberOfDatasets", - "width": 150, + "width": 120, "enabled": true } ], diff --git a/src/config/runtime-config/runtime-config.controller.ts b/src/config/runtime-config/runtime-config.controller.ts index fb13da0af..b4fbd835b 100644 --- a/src/config/runtime-config/runtime-config.controller.ts +++ b/src/config/runtime-config/runtime-config.controller.ts @@ -56,7 +56,7 @@ export class RuntimeConfigController { @UseGuards(PoliciesGuard) @CheckPolicies("runtimeconfig", (ability: AppAbility) => - ability.can(Action.Update, RuntimeConfig), + ability.can(Action.RuntimeConfigUpdateEndpoint, RuntimeConfig), ) @Put(":id") @ApiParam({ diff --git a/src/datasets/datasets.module.ts b/src/datasets/datasets.module.ts index c1c6df8d7..fe7d33286 100644 --- a/src/datasets/datasets.module.ts +++ b/src/datasets/datasets.module.ts @@ -24,6 +24,7 @@ import { ConfigModule, ConfigService } from "@nestjs/config"; import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; import { ProposalsModule } from "src/proposals/proposals.module"; import { HistoryModule } from "src/history/history.module"; +import { MetadataKeysModule } from "src/metadata-keys/metadatakeys.module"; @Module({ imports: [ @@ -33,6 +34,7 @@ import { HistoryModule } from "src/history/history.module"; OrigDatablocksModule, InitialDatasetsModule, HistoryModule, + MetadataKeysModule, ElasticSearchModule, ProposalsModule, forwardRef(() => LogbooksModule), diff --git a/src/datasets/datasets.service.spec.ts b/src/datasets/datasets.service.spec.ts index f6a815354..a38c9fabc 100644 --- a/src/datasets/datasets.service.spec.ts +++ b/src/datasets/datasets.service.spec.ts @@ -13,6 +13,7 @@ import { Request } from "express"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; import { plainToInstance } from "class-transformer"; import { ProposalsService } from "src/proposals/proposals.service"; +import { MetadataKeysService } from "src/metadata-keys/metadatakeys.service"; class InitialDatasetsServiceMock {} @@ -22,6 +23,11 @@ class CaslAbilityFactoryMock {} class ElasticSearchServiceMock {} +class MetadataKeysServiceMock { + insertManyFromSource = jest.fn().mockResolvedValue([]); + replaceManyFromSource = jest.fn().mockResolvedValue(undefined); +} + class ProposalsServiceMock { incrementNumberOfDatasets = jest.fn().mockResolvedValue(undefined); } @@ -119,6 +125,7 @@ describe("DatasetsService", () => { }, { provide: LogbooksService, useClass: LogbooksServiceMock }, { provide: ElasticSearchService, useClass: ElasticSearchServiceMock }, + { provide: MetadataKeysService, useClass: MetadataKeysServiceMock }, { provide: CaslAbilityFactory, useClass: CaslAbilityFactoryMock }, { provide: ProposalsService, useClass: ProposalsServiceMock }, ], diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index e586fcb5f..18d5b4196 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -59,6 +59,10 @@ import { DatasetLookupKeysEnum, } from "./types/dataset-lookup"; import { ProposalsService } from "src/proposals/proposals.service"; +import { + MetadataKeysService, + MetadataSourceDoc, +} from "src/metadata-keys/metadatakeys.service"; @Injectable({ scope: Scope.REQUEST }) export class DatasetsService { @@ -67,10 +71,11 @@ export class DatasetsService { private configService: ConfigService, @InjectModel(DatasetClass.name) private datasetModel: Model, + @Inject(REQUEST) private request: Request, + private datasetsAccessService: DatasetsAccessService, - @Inject(ElasticSearchService) private elasticSearchService: ElasticSearchService, - @Inject(REQUEST) private request: Request, + private metadataKeysService: MetadataKeysService, private proposalService: ProposalsService, ) { if (this.elasticSearchService.connected) { @@ -78,6 +83,20 @@ export class DatasetsService { } } + private createMetadataKeysInstance( + doc: UpdateQuery, + ): MetadataSourceDoc { + const source: MetadataSourceDoc = { + sourceType: "dataset", + sourceId: doc.pid, + ownerGroup: doc.owner, + accessGroups: doc.accessGroups || [], + isPublished: doc.isPublished || false, + metadata: doc.scientificMetadata ?? {}, + }; + return source; + } + addLookupFields( pipeline: PipelineStage[], datasetLookupFields?: (DatasetLookupKeysEnum | IDatasetRelation)[], @@ -164,18 +183,23 @@ export class DatasetsService { // insert created and updated fields addCreatedByFields(createDatasetDto, username), ); - if (this.ESClient && createdDataset) { - await this.ESClient.updateInsertDocument(createdDataset.toObject()); - } const savedDataset = await createdDataset.save(); + if (this.ESClient && createdDataset) { + await this.ESClient.updateInsertDocument(savedDataset.toObject()); + } + if (savedDataset.proposalIds && savedDataset.proposalIds.length > 0) { await this.proposalService.incrementNumberOfDatasets( savedDataset.proposalIds, ); } + this.metadataKeysService.insertManyFromSource( + this.createMetadataKeysInstance(savedDataset), + ); + return savedDataset; } @@ -384,12 +408,12 @@ export class DatasetsService { async findByIdAndReplace( id: string, updateDatasetDto: UpdateDatasetDto, - ): Promise { + ): Promise { const username = (this.request.user as JWTUser).username; const existingDataset = await this.datasetModel.findOne({ pid: id }).exec(); if (!existingDataset) { - throw new NotFoundException(); + throw new NotFoundException(`Dataset #${id} not found`); } // TODO: This might need a discussion. // NOTE: _id, pid and some other fields should not be touched in any case. @@ -414,9 +438,13 @@ export class DatasetsService { throw new NotFoundException(`Dataset #${id} not found`); } - if (this.ESClient && updatedDataset) { + if (this.ESClient) { await this.ESClient.updateInsertDocument(updatedDataset.toObject()); } + + await this.metadataKeysService.replaceManyFromSource( + this.createMetadataKeysInstance(updatedDataset), + ); // we were able to find the dataset and update it return updatedDataset; } @@ -451,27 +479,50 @@ export class DatasetsService { ) .exec(); - if (this.ESClient && patchedDataset) { + // check if we were able to find the dataset and update it + if (!patchedDataset) { + throw new NotFoundException(`Dataset #${id} not found`); + } + + if (this.ESClient) { await this.ESClient.updateInsertDocument(patchedDataset.toObject()); } + + await this.metadataKeysService.replaceManyFromSource( + this.createMetadataKeysInstance(patchedDataset), + ); // we were able to find the dataset and update it return patchedDataset; } // DELETE dataset async findByIdAndDelete(id: string): Promise { + const deletedDataset = await this.datasetModel + .findOneAndDelete({ + pid: id, + }) + .exec(); + + if (!deletedDataset) { + throw new NotFoundException(`Dataset #${id} not found`); + } + if (this.ESClient) { await this.ESClient.deleteDocument(id); } - const deletedDataset = await this.datasetModel.findOneAndDelete({ - pid: id, - }); if (deletedDataset?.proposalIds && deletedDataset.proposalIds.length > 0) { await this.proposalService.decrementNumberOfDatasets( deletedDataset.proposalIds, ); } + + // delete metadata keys associated with this dataset + await this.metadataKeysService.deleteMany({ + sourceId: id, + sourceType: "dataset", + }); + return deletedDataset; } // GET datasets without _id which is used for elastic search data synchronization diff --git a/src/instruments/instruments.module.ts b/src/instruments/instruments.module.ts index 4a8be983a..ef340cb82 100644 --- a/src/instruments/instruments.module.ts +++ b/src/instruments/instruments.module.ts @@ -10,12 +10,14 @@ import { InstrumentsController } from "./instruments.controller"; import { InstrumentsService } from "./instruments.service"; import { Instrument, InstrumentSchema } from "./schemas/instrument.schema"; import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; +import { MetadataKeysModule } from "src/metadata-keys/metadatakeys.module"; @Module({ controllers: [InstrumentsController], imports: [ CaslModule, ConfigModule, + MetadataKeysModule, MongooseModule.forFeature([ { name: GenericHistory.name, diff --git a/src/instruments/instruments.service.spec.ts b/src/instruments/instruments.service.spec.ts index 78085c396..88621504f 100644 --- a/src/instruments/instruments.service.spec.ts +++ b/src/instruments/instruments.service.spec.ts @@ -3,6 +3,12 @@ import { Test, TestingModule } from "@nestjs/testing"; import { Model } from "mongoose"; import { InstrumentsService } from "./instruments.service"; import { Instrument } from "./schemas/instrument.schema"; +import { MetadataKeysService } from "src/metadata-keys/metadatakeys.service"; + +class MetadataKeysServiceMock { + insertManyFromSource = jest.fn().mockResolvedValue([]); + replaceManyFromSource = jest.fn().mockResolvedValue(undefined); +} const mockInstrument: Instrument = { _id: "testPid", @@ -35,6 +41,7 @@ describe("InstrumentsService", () => { exec: jest.fn(), }, }, + { provide: MetadataKeysService, useClass: MetadataKeysServiceMock }, ], }).compile(); diff --git a/src/instruments/instruments.service.ts b/src/instruments/instruments.service.ts index e0d944067..921927dcc 100644 --- a/src/instruments/instruments.service.ts +++ b/src/instruments/instruments.service.ts @@ -1,6 +1,6 @@ -import { Injectable, Inject, Scope } from "@nestjs/common"; +import { Injectable, Inject, Scope, NotFoundException } from "@nestjs/common"; import { InjectModel } from "@nestjs/mongoose"; -import { FilterQuery, Model } from "mongoose"; +import { FilterQuery, Model, UpdateQuery } from "mongoose"; import { IFilters } from "src/common/interfaces/common.interface"; import { CountApiResponse } from "src/common/types"; import { @@ -14,21 +14,46 @@ import { Instrument, InstrumentDocument } from "./schemas/instrument.schema"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { REQUEST } from "@nestjs/core"; import { Request } from "express"; +import { + MetadataKeysService, + MetadataSourceDoc, +} from "src/metadata-keys/metadatakeys.service"; @Injectable({ scope: Scope.REQUEST }) export class InstrumentsService { constructor( @InjectModel(Instrument.name) private instrumentModel: Model, + private metadataKeysService: MetadataKeysService, @Inject(REQUEST) private request: Request, ) {} + private createMetadataKeysInstance( + doc: UpdateQuery, + ): MetadataSourceDoc { + const source: MetadataSourceDoc = { + sourceType: "instrument", + sourceId: doc.pid, + ownerGroup: doc.ownerGroup, + accessGroups: doc.accessGroups || [], + isPublished: doc.isPublished || false, + metadata: doc.customMetadata ?? {}, + }; + return source; + } + async create(createInstrumentDto: CreateInstrumentDto): Promise { const username = (this.request.user as JWTUser).username; const createdInstrument = new this.instrumentModel( addCreatedByFields(createInstrumentDto, username), ); - return createdInstrument.save(); + const savedInstrument = await createdInstrument.save(); + + await this.metadataKeysService.insertManyFromSource( + this.createMetadataKeysInstance(savedInstrument), + ); + + return savedInstrument; } async findAll(filter: IFilters): Promise { @@ -71,7 +96,8 @@ export class InstrumentsService { updateInstrumentDto: PartialUpdateInstrumentDto, ): Promise { const username = (this.request.user as JWTUser).username; - return this.instrumentModel + + const updatedInstrument = this.instrumentModel .findOneAndUpdate( filter, { @@ -83,9 +109,35 @@ export class InstrumentsService { { new: true, runValidators: true }, ) .exec(); + + if (!updatedInstrument) { + throw new NotFoundException( + `Instrument not found with filter: ${JSON.stringify(filter)}`, + ); + } + + await this.metadataKeysService.replaceManyFromSource( + this.createMetadataKeysInstance(updatedInstrument), + ); + + return updatedInstrument; } async remove(filter: FilterQuery): Promise { - return this.instrumentModel.findOneAndDelete(filter).exec(); + const deletedInstrument = await this.instrumentModel + .findOneAndDelete(filter) + .exec(); + + if (!deletedInstrument) { + throw new NotFoundException( + `Instrument not found with filter: ${JSON.stringify(filter)}`, + ); + } + + await this.metadataKeysService.deleteMany( + this.createMetadataKeysInstance(deletedInstrument), + ); + + return deletedInstrument; } } diff --git a/src/metadata-keys/dto/create-metadata-key.dto.ts b/src/metadata-keys/dto/create-metadata-key.dto.ts new file mode 100644 index 000000000..4e5ca5b2f --- /dev/null +++ b/src/metadata-keys/dto/create-metadata-key.dto.ts @@ -0,0 +1,22 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsString } from "class-validator"; +import { UpdateMetadataKeyDto } from "./update-metadata-key.dto"; + +export class CreateMetadataKeyDto extends UpdateMetadataKeyDto { + @ApiProperty({ + type: String, + required: true, + description: + "Type of item this key has been extracted from. Allowed values: Datasets, Proposals, Samples, Instruments.", + }) + @IsString() + sourceType: string; + + @ApiProperty({ + type: String, + required: true, + description: "Unique identifier of the source item this key is linked to.", + }) + @IsString() + sourceId: string; +} diff --git a/src/metadata-keys/dto/output-metadata-key.dto.ts b/src/metadata-keys/dto/output-metadata-key.dto.ts new file mode 100644 index 000000000..ad561ddc3 --- /dev/null +++ b/src/metadata-keys/dto/output-metadata-key.dto.ts @@ -0,0 +1,78 @@ +import { ApiProperty, PartialType } from "@nestjs/swagger"; +import { + ArrayNotEmpty, + IsArray, + IsBoolean, + IsOptional, + IsString, +} from "class-validator"; +import { QueryableClass } from "src/common/schemas/queryable.schema"; + +export class OutputMetadataKeyDto extends QueryableClass { + @ApiProperty({ + type: String, + required: true, + description: "Unique identifier of this metadata key.", + }) + @IsString() + declare id: string; + + @ApiProperty({ + type: String, + required: true, + description: "Metadata key.", + }) + @IsString() + key: string; + + @ApiProperty({ + type: String, + required: false, + description: "Human readable name associated with this metadata key.", + }) + @IsOptional() + @IsString() + humanReadableName?: string; + + @ApiProperty({ + type: [String], + required: true, + description: "List of user groups that can access this key.", + }) + @IsArray() + @ArrayNotEmpty() + @IsString({ + each: true, + }) + userGroups: string[]; + + @ApiProperty({ + type: String, + required: true, + description: + "Type of item this key has been extracted from. Allowed values: Datasets, Proposals, Samples, Instruments.", + }) + @IsString() + sourceType: string; + + @ApiProperty({ + type: String, + required: true, + description: "Unique identifier of the source item this key is linked to.", + }) + @IsString() + sourceId: string; + + @ApiProperty({ + type: Boolean, + required: true, + default: false, + description: "Flag is true when data are made publicly available.", + }) + @IsBoolean() + isPublished: boolean; +} + +export class PartialOutputMetadataKeyDto extends PartialType( + OutputMetadataKeyDto, +) {} diff --git a/src/metadata-keys/dto/update-metadata-key.dto.ts b/src/metadata-keys/dto/update-metadata-key.dto.ts new file mode 100644 index 000000000..eddaef17c --- /dev/null +++ b/src/metadata-keys/dto/update-metadata-key.dto.ts @@ -0,0 +1,50 @@ +import { ApiProperty, PartialType } from "@nestjs/swagger"; +import { + IsArray, + IsOptional, + IsString, + ArrayNotEmpty, + IsBoolean, +} from "class-validator"; + +export class UpdateMetadataKeyDto { + @ApiProperty({ + type: String, + required: true, + description: "Metadata key.", + }) + @IsString() + key: string; + + @ApiProperty({ + type: String, + required: false, + description: "Human readable name associated with this metadata key.", + }) + @IsOptional() + @IsString() + humanReadableName?: string; + + @ApiProperty({ + type: [String], + required: true, + description: "List of user groups that can access this key.", + }) + @IsArray() + @ArrayNotEmpty() + @IsString({ each: true }) + userGroups: string[]; + + @ApiProperty({ + type: Boolean, + required: true, + default: false, + description: "Flag is true when data are made publicly available.", + }) + @IsBoolean() + isPublished: boolean; +} + +export class PartialUpdateMetadataKeyDto extends PartialType( + UpdateMetadataKeyDto, +) {} diff --git a/src/metadata-keys/metadatakeys.module.ts b/src/metadata-keys/metadatakeys.module.ts new file mode 100644 index 000000000..4e5b9b8db --- /dev/null +++ b/src/metadata-keys/metadatakeys.module.ts @@ -0,0 +1,58 @@ +import { Module } from "@nestjs/common"; +import { + MetadataKeyClass, + MetadataKeySchema, +} from "./schemas/metadatakey.schema"; +import { MetadataKeysV4Controller } from "./metadatakeys.v4.controller"; +import { MetadataKeysService } from "./metadatakeys.service"; +import { HistoryModule } from "src/history/history.module"; +import { MongooseModule } from "@nestjs/mongoose"; +import { ConfigModule, ConfigService } from "@nestjs/config"; +import { + GenericHistory, + GenericHistorySchema, +} from "src/common/schemas/generic-history.schema"; +import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; +import { CaslModule } from "src/casl/casl.module"; + +@Module({ + imports: [ + CaslModule, + HistoryModule, + MongooseModule.forFeatureAsync([ + { + name: MetadataKeyClass.name, + imports: [ + ConfigModule, + MongooseModule.forFeature([ + { + name: GenericHistory.name, + schema: GenericHistorySchema, + }, + ]), + ], + inject: [ConfigService], + useFactory: (configService: ConfigService) => { + const schema = MetadataKeySchema; + + schema.pre("save", async function (next) { + if (!this._id) { + this._id = this.id; + } + + next(); + }); + + // Apply history plugin once if schema name matches TRACKABLES config + applyHistoryPluginOnce(schema, configService); + + return schema; + }, + }, + ]), + ], + exports: [MetadataKeysService], + controllers: [MetadataKeysV4Controller], + providers: [MetadataKeysService], +}) +export class MetadataKeysModule {} diff --git a/src/metadata-keys/metadatakeys.service.spec.ts b/src/metadata-keys/metadatakeys.service.spec.ts new file mode 100644 index 000000000..152b96727 --- /dev/null +++ b/src/metadata-keys/metadatakeys.service.spec.ts @@ -0,0 +1,141 @@ +import { Logger } from "@nestjs/common"; +import { getModelToken } from "@nestjs/mongoose"; +import { Test, TestingModule } from "@nestjs/testing"; +import { MetadataKeysService, MetadataSourceDoc } from "./metadatakeys.service"; +import { MetadataKeyClass } from "./schemas/metadatakey.schema"; + +class MetadataKeyModelMock { + aggregate = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue([{ key: "k1" }]), + }); + deleteMany = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue({ deletedCount: 2 }), + }); + insertMany = jest.fn().mockReturnValue([{ _id: "id1" }]); +} + +describe("MetadataKeysService", () => { + let service: MetadataKeysService; + let model: MetadataKeyModelMock; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + MetadataKeysService, + { + provide: getModelToken(MetadataKeyClass.name), + useClass: MetadataKeyModelMock, + }, + ], + }).compile(); + + service = await module.resolve(MetadataKeysService); + model = module.get( + getModelToken(MetadataKeyClass.name), + ) as unknown as MetadataKeyModelMock; + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); + + it("findAll builds aggregation pipeline and executes it", async () => { + const filter = { + where: { sourceType: "dataset" }, + fields: ["key"], + limits: { limit: 10, skip: 0, sort: { createdAt: "asc" } }, + }; + + const accessFilter = { userGroups: { $in: ["ess"] } }; + + const res = await service.findAll(filter, accessFilter); + + expect(model.aggregate).toHaveBeenCalledTimes(1); + + const pipeline = model.aggregate.mock.calls[0][0]; + expect(pipeline[0]).toEqual({ + $match: { $and: [accessFilter, filter.where] }, + }); + + expect(res).toEqual([{ key: "k1" }]); + }); + + it("deleteMany deletes and logs result", async () => { + const logSpy = jest.spyOn(Logger, "log").mockImplementation(); + + const filter = { sourceType: "dataset", sourceId: "sid" }; + const result = await service.deleteMany(filter); + + expect(model.deleteMany).toHaveBeenCalledWith(filter); + expect(result.deletedCount).toBe(2); + expect(logSpy).toHaveBeenCalled(); + }); + + it("insertManyFromSource does nothing when metadata is empty", async () => { + const doc: MetadataSourceDoc = { + sourceId: "sid", + sourceType: "dataset", + ownerGroup: "ess", + accessGroups: ["ess"], + isPublished: false, + metadata: {}, + }; + + const res = await service.insertManyFromSource(doc); + + expect(res).toBeUndefined(); + expect(model.insertMany).not.toHaveBeenCalled(); + }); + + it("insertManyFromSource creates metadata keys", async () => { + const doc: MetadataSourceDoc = { + sourceId: "sid", + sourceType: "dataset", + ownerGroup: "ess", + accessGroups: ["swap", "ess"], + isPublished: false, + metadata: { + key1: { human_name: "Key One" }, + key2: {}, + }, + }; + + const res = await service.insertManyFromSource(doc); + + expect(model.insertMany).toHaveBeenCalledTimes(1); + + const insertedDocs = model.insertMany.mock.calls[0][0]; + expect(insertedDocs).toHaveLength(2); + + expect(insertedDocs[0]).toMatchObject({ + key: "key1", + humanReadableName: "Key One", + sourceType: "dataset", + sourceId: "sid", + }); + + expect(res).toEqual([{ _id: "id1" }]); + }); + + it("replaceManyFromSource deletes then inserts", async () => { + const doc: MetadataSourceDoc = { + sourceId: "sid", + sourceType: "dataset", + ownerGroup: "ess", + accessGroups: ["swap"], + isPublished: false, + metadata: { key1: {} }, + }; + + const deleteSpy = jest.spyOn(service, "deleteMany"); + const insertSpy = jest.spyOn(service, "insertManyFromSource"); + + await service.replaceManyFromSource(doc); + + expect(deleteSpy).toHaveBeenCalledWith({ + sourceId: "sid", + sourceType: "dataset", + }); + expect(insertSpy).toHaveBeenCalledWith(doc); + }); +}); diff --git a/src/metadata-keys/metadatakeys.service.ts b/src/metadata-keys/metadatakeys.service.ts new file mode 100644 index 000000000..fc1b06076 --- /dev/null +++ b/src/metadata-keys/metadatakeys.service.ts @@ -0,0 +1,137 @@ +import { Injectable, Logger, Scope } from "@nestjs/common"; +import { InjectModel } from "@nestjs/mongoose"; +import { + MetadataKeyClass, + MetadataKeyDocument, +} from "./schemas/metadatakey.schema"; +import { + DeleteResult, + FilterQuery, + HydratedDocument, + Model, + PipelineStage, + QueryOptions, +} from "mongoose"; +import { isEmpty } from "lodash"; +import { + addCreatedByFields, + parsePipelineProjection, + parsePipelineSort, +} from "src/common/utils"; + +type ScientificMetadataEntry = { + human_name?: string; +}; + +export type MetadataSourceDoc = { + sourceId: string; + sourceType: string; + ownerGroup: string; + accessGroups: string[]; + isPublished: boolean; + metadata: Record; +}; + +@Injectable({ scope: Scope.REQUEST }) +export class MetadataKeysService { + constructor( + @InjectModel(MetadataKeyClass.name) + private metadataKeyModel: Model, + ) {} + + async findAll( + filter: FilterQuery, + accessFilter: FilterQuery, + ): Promise { + const whereFilter: FilterQuery = filter.where ?? {}; + const fieldsProjection: string[] = filter.fields ?? {}; + const limits: QueryOptions = filter.limits ?? { + limit: 100, + skip: 0, + sort: { createdAt: "desc" }, + }; + + const pipeline: PipelineStage[] = [ + { + $match: { + $and: [accessFilter, whereFilter], + }, + }, + ]; + if (!isEmpty(fieldsProjection)) { + const projection = parsePipelineProjection(fieldsProjection); + pipeline.push({ $project: projection }); + } + + if (!isEmpty(limits.sort)) { + const sort = parsePipelineSort(limits.sort); + pipeline.push({ $sort: sort }); + } + + pipeline.push({ $skip: limits.skip || 0 }); + + pipeline.push({ $limit: limits.limit || 100 }); + + const data = await this.metadataKeyModel + .aggregate(pipeline) + .exec(); + + return data; + } + + async deleteMany( + filter: FilterQuery, + ): Promise { + const result = await this.metadataKeyModel.deleteMany(filter).exec(); + + Logger.log( + `MetadataKeys deleted: ${result.deletedCount ?? 0} With filter:`, + { filter }, + ); + + return result; + } + + async insertManyFromSource( + doc: MetadataSourceDoc, + ): Promise[] | void> { + if (isEmpty(doc.metadata)) { + return; + } + const userGroups = Array.from( + new Set([doc.ownerGroup, ...(doc.accessGroups ?? [])].filter(Boolean)), + ) as string[]; + + const isPublished = doc.isPublished; + + const metadata = doc.metadata ?? {}; + + const docs = Object.entries(metadata).map(([key, entry]) => { + const createMetadataKeyDto = { + _id: `${doc.sourceType}_${doc.sourceId}_${key}`, + id: `${doc.sourceType}_${doc.sourceId}_${key}`, + sourceType: doc.sourceType, + sourceId: doc.sourceId, + key, + userGroups, + isPublished, + humanReadableName: (entry as ScientificMetadataEntry).human_name ?? "", + }; + return addCreatedByFields(createMetadataKeyDto, "system"); + }); + + Logger.log( + `Created ${docs.length} MetadataKeys from source ${doc.sourceType} with ID ${doc.sourceId}`, + ); + + return await this.metadataKeyModel.insertMany(docs); + } + + async replaceManyFromSource(doc: MetadataSourceDoc): Promise { + await this.deleteMany({ + sourceId: doc.sourceId, + sourceType: doc.sourceType, + }); + await this.insertManyFromSource(doc); + } +} diff --git a/src/metadata-keys/metadatakeys.v4.controller.spec.ts b/src/metadata-keys/metadatakeys.v4.controller.spec.ts new file mode 100644 index 000000000..761b07ba1 --- /dev/null +++ b/src/metadata-keys/metadatakeys.v4.controller.spec.ts @@ -0,0 +1,125 @@ +// metadatakeys.v4.controller.spec.ts +import { Test, TestingModule } from "@nestjs/testing"; +import { Request } from "express"; +import { accessibleBy } from "@casl/mongoose"; + +import { MetadataKeysV4Controller } from "./metadatakeys.v4.controller"; +import { MetadataKeysService } from "./metadatakeys.service"; +import { CaslAbilityFactory } from "src/casl/casl-ability.factory"; +import { Action } from "src/casl/action.enum"; +import { MetadataKeyClass } from "./schemas/metadatakey.schema"; +import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; + +jest.mock("@casl/mongoose", () => ({ + accessibleBy: jest.fn(), +})); + +class CaslAbilityFactoryMock { + metadataKeyInstanceAccess = jest.fn(); +} + +class MetadataKeysServiceMock { + findAll = jest.fn(); +} + +describe("MetadataKeysV4Controller", () => { + let controller: MetadataKeysV4Controller; + let metadatakeysService: MetadataKeysServiceMock; + let caslAbilityFactory: CaslAbilityFactoryMock; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [MetadataKeysV4Controller], + providers: [ + { provide: MetadataKeysService, useClass: MetadataKeysServiceMock }, + { provide: CaslAbilityFactory, useClass: CaslAbilityFactoryMock }, + ], + }).compile(); + + controller = module.get(MetadataKeysV4Controller); + metadatakeysService = module.get(MetadataKeysService); + caslAbilityFactory = module.get(CaslAbilityFactory); + }); + + it("should be defined", () => { + expect(controller).toBeDefined(); + }); + + it("findAll parses filter, builds accessFilter, and calls service.findAll with parsed filter and accessFilter", async () => { + const request = { user: { username: "u1" } } as unknown as Request; + const user = request.user as JWTUser; + const filterString = `{ + "where": { "sourceId": "testId", "sourceType": "dataset" }, + "limits": { + "limit": 10, + "skip": 0, + "sort": { + "createdAt": "asc" + } + } + }`; + const parsedFilter = JSON.parse(filterString); + + const abilities = {}; + caslAbilityFactory.metadataKeyInstanceAccess.mockReturnValue(abilities); + + const accessFilter = { isPublished: true }; + + const ofType = jest.fn().mockReturnValue(accessFilter); + + const accessibleByReturn = { + ofType, + }; + (accessibleBy as unknown as jest.Mock).mockReturnValue(accessibleByReturn); + + const expected = [{ key: "k1", humanReadableName: "Test K1" }] as unknown[]; + metadatakeysService.findAll.mockResolvedValue(expected); + + const result = await controller.findAll(request, filterString); + + expect(caslAbilityFactory.metadataKeyInstanceAccess).toHaveBeenCalledWith( + user, + ); + + expect(accessibleBy).toHaveBeenCalledWith( + abilities, + Action.MetadataKeysReadInstance, + ); + expect(ofType).toHaveBeenCalledWith(MetadataKeyClass); + + expect(metadatakeysService.findAll).toHaveBeenCalledWith( + parsedFilter, + accessFilter, + ); + + expect(result).toEqual(expected); + }); + + it('findAll uses "{}" when filter is missing', async () => { + const request = { user: { username: "u1" } } as unknown as Request; + + const abilities = {}; + caslAbilityFactory.metadataKeyInstanceAccess.mockReturnValue(abilities); + + const accessFilter = { isPublished: true }; + const accessibleByReturn = { + ofType: () => accessFilter, + }; + (accessibleBy as unknown as jest.Mock).mockReturnValue(accessibleByReturn); + + const expected: unknown[] = []; + metadatakeysService.findAll.mockResolvedValue(expected); + + const result = await controller.findAll( + request, + undefined as unknown as string, + ); + + expect(metadatakeysService.findAll).toHaveBeenCalledWith({}, accessFilter); + expect(result).toEqual(expected); + }); +}); diff --git a/src/metadata-keys/metadatakeys.v4.controller.ts b/src/metadata-keys/metadatakeys.v4.controller.ts new file mode 100644 index 000000000..5b6b299a4 --- /dev/null +++ b/src/metadata-keys/metadatakeys.v4.controller.ts @@ -0,0 +1,89 @@ +import { + Controller, + Get, + HttpStatus, + Req, + Query, + UseGuards, +} from "@nestjs/common"; +import { + ApiBearerAuth, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, +} from "@nestjs/swagger"; +import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; +import { MetadataKeysService } from "./metadatakeys.service"; +import { PoliciesGuard } from "src/casl/guards/policies.guard"; +import { OutputMetadataKeyDto } from "./dto/output-metadata-key.dto"; + +import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; +import { Request } from "express"; +import { getSwaggerMetadatakeysFilterContent } from "./types/metadatakeys-filter-content"; +import { MetadataKeyClass } from "./schemas/metadatakey.schema"; +import { Action } from "src/casl/action.enum"; +import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; +import { FilterValidationPipe } from "src/common/pipes/filter-validation.pipe"; +import { + ALLOWED_METADATAKEYS_FILTER_KEYS, + ALLOWED_METADATAKEYS_KEYS, +} from "./types/metadatakeys-lookup"; +import { accessibleBy } from "@casl/mongoose"; + +@ApiBearerAuth() +@ApiTags("metadata keys v4") +@Controller({ path: "metadatakeys", version: "4" }) +export class MetadataKeysV4Controller { + constructor( + private metadatakeysService: MetadataKeysService, + private caslAbilityFactory: CaslAbilityFactory, + ) {} + + @UseGuards(PoliciesGuard) + @CheckPolicies("metadataKeys", (ability: AppAbility) => + ability.can(Action.MetadataKeysReadEndpoint, MetadataKeyClass), + ) + @Get() + @ApiOperation({ summary: "List metadata keys by text query" }) + @ApiQuery({ + name: "filter", + description: "Database filters to apply when retrieving metadata keys", + required: false, + type: String, + content: getSwaggerMetadatakeysFilterContent(), + }) + @ApiResponse({ + status: HttpStatus.OK, + type: OutputMetadataKeyDto, + isArray: true, + description: "Return the metadata keys requested", + }) + async findAll( + @Req() request: Request, + @Query( + "filter", + new FilterValidationPipe( + ALLOWED_METADATAKEYS_KEYS, + ALLOWED_METADATAKEYS_FILTER_KEYS, + { + where: true, + include: false, + fields: true, + limits: true, + }, + ), + ) + filter: string, + ) { + const user: JWTUser = request.user as JWTUser; + const parsedFilter = JSON.parse(filter ?? "{}"); + const abilities = this.caslAbilityFactory.metadataKeyInstanceAccess(user); + const accessFilter = accessibleBy( + abilities, + Action.MetadataKeysReadInstance, + ).ofType(MetadataKeyClass); + + return this.metadatakeysService.findAll(parsedFilter, accessFilter); + } +} diff --git a/src/metadata-keys/schemas/metadatakey.schema.ts b/src/metadata-keys/schemas/metadatakey.schema.ts new file mode 100644 index 000000000..b4c6b6d39 --- /dev/null +++ b/src/metadata-keys/schemas/metadatakey.schema.ts @@ -0,0 +1,103 @@ +import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; +import { ApiProperty } from "@nestjs/swagger"; +import { Document } from "mongoose"; +import { QueryableClass } from "src/common/schemas/queryable.schema"; +import { v4 as uuidv4 } from "uuid"; + +export type MetadataKeyDocument = MetadataKeyClass & Document; + +@Schema({ + collection: "MetadataKeys", + minimize: false, + timestamps: true, + toJSON: { + getters: true, + }, +}) +export class MetadataKeyClass extends QueryableClass { + @ApiProperty({ type: String, default: () => uuidv4() }) + @Prop({ + type: String, + default: () => uuidv4(), + sparse: true, + }) + id: string; + + @Prop({ + type: String, + }) + _id: string; + + @ApiProperty({ + type: String, + required: true, + description: "Metadata key.", + }) + @Prop({ + type: String, + required: true, + index: true, + }) + key: string; + + @ApiProperty({ + type: String, + required: false, + description: "Human readable name associated with the metadata key.", + }) + @Prop({ + type: String, + required: false, + }) + humanReadableName?: string; + + @ApiProperty({ + type: [String], + required: true, + description: "List of user groups that can access this key.", + }) + @Prop({ + type: [String], + required: true, + }) + userGroups: string[]; + + @ApiProperty({ + type: String, + required: true, + description: + "Type of item this key has been extracted from. Allowed values: Datasets, Proposals, Samples, Instruments.", + }) + @Prop({ + type: String, + required: true, + index: true, + }) + sourceType: string; + + @ApiProperty({ + type: String, + required: true, + description: "Unique identifier of the source item this key is linked to.", + }) + @Prop({ + type: String, + required: true, + index: true, + }) + sourceId: string; + + @ApiProperty({ + type: Boolean, + required: true, + description: "Flag is true when data are made publicly available.", + }) + @Prop({ type: Boolean, required: true }) + isPublished: boolean; +} + +export const MetadataKeySchema = SchemaFactory.createForClass(MetadataKeyClass); + +MetadataKeySchema.index({ sourceType: 1, sourceId: 1 }); +MetadataKeySchema.index({ sourceType: 1, userGroups: 1, key: 1 }); +MetadataKeySchema.index({ sourceType: 1, userGroups: 1, humanReadableName: 1 }); diff --git a/src/metadata-keys/types/metadatakeys-filter-content.ts b/src/metadata-keys/types/metadatakeys-filter-content.ts new file mode 100644 index 000000000..b7a38afab --- /dev/null +++ b/src/metadata-keys/types/metadatakeys-filter-content.ts @@ -0,0 +1,83 @@ +import { + ContentObject, + SchemaObject, +} from "@nestjs/swagger/dist/interfaces/open-api-spec.interface"; +import { boolean } from "mathjs"; + +const FILTERS: Record<"limits" | "fields" | "where" | "include", object> = { + where: { + type: "object", + example: { + sourceType: "dataset", + sourceId: "datasetId", + key: "metadata_key_name", + }, + }, + include: {}, + fields: { + type: "array", + items: { + type: "string", + example: "key", + }, + }, + limits: { + type: "object", + properties: { + limit: { + type: "number", + example: 10, + }, + skip: { + type: "number", + example: 0, + }, + sort: { + type: "object", + properties: { + createdAt: { + type: "string", + example: "asc | desc", + }, + }, + }, + }, + }, +}; + +/** + * NOTE: This is disabled only for the official sdk package generation as the schema validation complains about the content field. + * But we want to have it when we run the application as it improves swagger documentation and usage a lot. + * We use "content" property as it is described in the swagger specification: https://swagger.io/docs/specification/v3_0/describing-parameters/#schema-vs-content:~:text=explode%3A%20false-,content,-is%20used%20in + */ +export const getSwaggerMetadatakeysFilterContent = ( + filtersToInclude: Record = { + where: true, + include: false, + fields: true, + limits: true, + }, +): ContentObject | undefined => { + if (boolean(process.env.SDK_PACKAGE_SWAGGER_HELPERS_DISABLED ?? false)) { + return undefined; + } + + const filterContent: Record = { + "application/json": { + schema: { + type: "object", + properties: {}, + }, + }, + }; + + for (const filtersKey in filtersToInclude) { + const key = filtersKey as keyof typeof FILTERS; + + if (filtersToInclude[key] && FILTERS[key]) { + filterContent["application/json"].schema.properties![key] = FILTERS[key]; + } + } + + return filterContent; +}; diff --git a/src/metadata-keys/types/metadatakeys-lookup.ts b/src/metadata-keys/types/metadatakeys-lookup.ts new file mode 100644 index 000000000..5698a80f7 --- /dev/null +++ b/src/metadata-keys/types/metadatakeys-lookup.ts @@ -0,0 +1,41 @@ +import { PipelineStage } from "mongoose"; +import { OutputMetadataKeyDto } from "../dto/output-metadata-key.dto"; + +export enum MetadataKeysLookupKeysEnum {} + +export const METADATA_KEYS_LOOKUP_FIELDS: Record< + MetadataKeysLookupKeysEnum, + PipelineStage.Lookup | undefined +> = {}; + +// Metadata keys specific keys that are allowed +export const ALLOWED_METADATAKEYS_KEYS = [ + ...Object.keys(new OutputMetadataKeyDto()), +]; + +// Allowed keys taken from mongoose QuerySelector. +export const ALLOWED_METADATAKEYS_FILTER_KEYS: Record = { + where: [ + "where", + "$in", + "$or", + "$and", + "$nor", + "$match", + "$eq", + "$gt", + "$gte", + "$lt", + "$lte", + "$ne", + "$nin", + "$not", + "$exists", + "$regex", + "$options", + "$elemMatch", + ], + include: [], + limits: ["limits", "limit", "skip", "sort"], + fields: ["fields"], +}; diff --git a/src/proposals/proposals.module.ts b/src/proposals/proposals.module.ts index d1086eb3c..00c0cbaf5 100644 --- a/src/proposals/proposals.module.ts +++ b/src/proposals/proposals.module.ts @@ -12,11 +12,13 @@ import { GenericHistorySchema, } from "src/common/schemas/generic-history.schema"; import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; +import { MetadataKeysModule } from "src/metadata-keys/metadatakeys.module"; @Module({ imports: [ CaslModule, AttachmentsModule, + MetadataKeysModule, forwardRef(() => DatasetsModule), MongooseModule.forFeature([ { diff --git a/src/proposals/proposals.service.spec.ts b/src/proposals/proposals.service.spec.ts index 736369e04..670ba5007 100644 --- a/src/proposals/proposals.service.spec.ts +++ b/src/proposals/proposals.service.spec.ts @@ -3,6 +3,12 @@ import { Test, TestingModule } from "@nestjs/testing"; import { Model } from "mongoose"; import { ProposalsService } from "./proposals.service"; import { ProposalClass } from "./schemas/proposal.schema"; +import { MetadataKeysService } from "src/metadata-keys/metadatakeys.service"; + +class MetadataKeysServiceMock { + insertManyFromSource = jest.fn().mockResolvedValue([]); + replaceManyFromSource = jest.fn().mockResolvedValue(undefined); +} const mockProposal: ProposalClass = { proposalId: "ABCDEF", @@ -47,6 +53,7 @@ describe("ProposalsService", () => { exec: jest.fn(), }, }, + { provide: MetadataKeysService, useClass: MetadataKeysServiceMock }, ], }).compile(); diff --git a/src/proposals/proposals.service.ts b/src/proposals/proposals.service.ts index c51c4ad19..e2c2f0d8c 100644 --- a/src/proposals/proposals.service.ts +++ b/src/proposals/proposals.service.ts @@ -1,8 +1,14 @@ -import { Inject, Injectable, Scope } from "@nestjs/common"; +import { Inject, Injectable, NotFoundException, Scope } from "@nestjs/common"; import { REQUEST } from "@nestjs/core"; import { Request } from "express"; import { InjectModel } from "@nestjs/mongoose"; -import { FilterQuery, Model, PipelineStage, QueryOptions } from "mongoose"; +import { + FilterQuery, + Model, + PipelineStage, + QueryOptions, + UpdateQuery, +} from "mongoose"; import { IFacets, IFilters } from "src/common/interfaces/common.interface"; import { createFullfacetPipeline, @@ -17,15 +23,34 @@ import { IProposalFields } from "./interfaces/proposal-filters.interface"; import { ProposalClass, ProposalDocument } from "./schemas/proposal.schema"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { CreateMeasurementPeriodDto } from "./dto/create-measurement-period.dto"; +import { + MetadataKeysService, + MetadataSourceDoc, +} from "src/metadata-keys/metadatakeys.service"; @Injectable({ scope: Scope.REQUEST }) export class ProposalsService { constructor( @InjectModel(ProposalClass.name) private proposalModel: Model, + private metadataKeysService: MetadataKeysService, @Inject(REQUEST) private request: Request, ) {} + private createMetadataKeysInstance( + doc: UpdateQuery, + ): MetadataSourceDoc { + const source: MetadataSourceDoc = { + sourceType: "proposal", + sourceId: doc.proposalId, + ownerGroup: doc.ownerGroup, + accessGroups: doc.accessGroups || [], + isPublished: doc.isPublished || false, + metadata: doc.metadata ?? {}, + }; + return source; + } + async create(createProposalDto: CreateProposalDto): Promise { const username = (this.request.user as JWTUser).username; if (createProposalDto.MeasurementPeriodList) { @@ -40,7 +65,12 @@ export class ProposalsService { const createdProposal = new this.proposalModel( addCreatedByFields(createProposalDto, username), ); - return createdProposal.save(); + const savedProposal = await createdProposal.save(); + + this.metadataKeysService.insertManyFromSource( + this.createMetadataKeysInstance(savedProposal), + ); + return savedProposal; } async findAll( @@ -119,9 +149,7 @@ export class ProposalsService { ): Promise { const username = (this.request.user as JWTUser).username; - // Use findOneAndUpdate instead of manually updating the document - // This ensures the history plugin middleware is triggered - return this.proposalModel + const updatedProposal = await this.proposalModel .findOneAndUpdate( filter, { @@ -135,10 +163,37 @@ export class ProposalsService { }, ) .exec(); + + if (!updatedProposal) { + throw new NotFoundException( + `Proposal not found with filter: ${JSON.stringify(filter)}`, + ); + } + + await this.metadataKeysService.replaceManyFromSource( + this.createMetadataKeysInstance(updatedProposal), + ); + + return updatedProposal; } async remove(filter: FilterQuery): Promise { - return this.proposalModel.findOneAndDelete(filter).exec(); + const deletedProposal = await this.proposalModel + .findOneAndDelete(filter) + .exec(); + + if (!deletedProposal) { + throw new NotFoundException( + `Proposal not found with filter: ${JSON.stringify(filter)}`, + ); + } + + this.metadataKeysService.deleteMany({ + sourceType: "proposal", + sourceId: deletedProposal.proposalId, + }); + + return deletedProposal; } async incrementNumberOfDatasets(proposalIds: string[]) { diff --git a/src/samples/samples.module.ts b/src/samples/samples.module.ts index 1157b1236..100deb8f6 100644 --- a/src/samples/samples.module.ts +++ b/src/samples/samples.module.ts @@ -12,6 +12,7 @@ import { SamplesController } from "./samples.controller"; import { SamplesService } from "./samples.service"; import { SampleClass, SampleSchema } from "./schemas/sample.schema"; import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; +import { MetadataKeysModule } from "src/metadata-keys/metadatakeys.module"; @Module({ imports: [ @@ -19,6 +20,7 @@ import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plug AttachmentsModule, DatasetsModule, ConfigModule, + MetadataKeysModule, MongooseModule.forFeatureAsync([ { name: SampleClass.name, diff --git a/src/samples/samples.service.spec.ts b/src/samples/samples.service.spec.ts index 707da68d9..68d39220e 100644 --- a/src/samples/samples.service.spec.ts +++ b/src/samples/samples.service.spec.ts @@ -6,6 +6,7 @@ import { SamplesService } from "./samples.service"; import { SampleClass } from "./schemas/sample.schema"; import { ScientificRelation } from "src/common/scientific-relation.enum"; import * as utils from "../common/utils"; +import { MetadataKeysService } from "src/metadata-keys/metadatakeys.service"; jest.mock("../common/utils", () => { const mockUtils = jest.requireActual("../common/utils"); @@ -25,6 +26,11 @@ jest.mock("../common/utils", () => { }; }); +class MetadataKeysServiceMock { + insertManyFromSource = jest.fn().mockResolvedValue([]); + replaceManyFromSource = jest.fn().mockResolvedValue(undefined); +} + const mockSample: SampleClass = { _id: "testId", sampleId: "testId", @@ -60,6 +66,7 @@ describe("SamplesService", () => { exec: jest.fn(), }, }, + { provide: MetadataKeysService, useClass: MetadataKeysServiceMock }, ], }).compile(); diff --git a/src/samples/samples.service.ts b/src/samples/samples.service.ts index af7d136f6..36cc88548 100644 --- a/src/samples/samples.service.ts +++ b/src/samples/samples.service.ts @@ -1,9 +1,9 @@ -import { Injectable, Inject, Scope } from "@nestjs/common"; +import { Injectable, Inject, Scope, NotFoundException } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import { REQUEST } from "@nestjs/core"; import { Request } from "express"; import { InjectModel } from "@nestjs/mongoose"; -import { FilterQuery, Model, QueryOptions } from "mongoose"; +import { FilterQuery, Model, QueryOptions, UpdateQuery } from "mongoose"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { IFilters } from "src/common/interfaces/common.interface"; import { @@ -20,22 +20,46 @@ import { ISampleFields } from "./interfaces/sample-filters.interface"; import { SampleClass, SampleDocument } from "./schemas/sample.schema"; import { CountApiResponse } from "src/common/types"; import { OutputSampleDto } from "./dto/output-sample.dto"; +import { + MetadataKeysService, + MetadataSourceDoc, +} from "src/metadata-keys/metadatakeys.service"; @Injectable({ scope: Scope.REQUEST }) export class SamplesService { constructor( @InjectModel(SampleClass.name) private sampleModel: Model, private configService: ConfigService, + private metadataKeysService: MetadataKeysService, @Inject(REQUEST) private request: Request, ) {} + private createMetadataKeysInstance( + doc: UpdateQuery, + ): MetadataSourceDoc { + const source: MetadataSourceDoc = { + sourceType: "sample", + sourceId: doc.sampleId, + ownerGroup: doc.ownerGroup, + accessGroups: doc.accessGroups || [], + isPublished: doc.isPublished || false, + metadata: doc.sampleCharacteristics ?? {}, + }; + return source; + } + async create(createSampleDto: CreateSampleDto): Promise { const username = (this.request.user as JWTUser).username; const createdSample = new this.sampleModel( addCreatedByFields(createSampleDto, username), ); + const savedSample = await createdSample.save(); - return createdSample.save(); + this.metadataKeysService.insertManyFromSource( + this.createMetadataKeysInstance(savedSample), + ); + + return savedSample; } async findAll( @@ -161,16 +185,42 @@ export class SamplesService { updatedAt: new Date(), }; - return this.sampleModel + const updatedSample = await this.sampleModel .findOneAndUpdate( filter, { $set: updateDataMongoose }, { new: true, runValidators: true }, ) .exec(); + + if (!updatedSample) { + throw new NotFoundException( + `Sample not found with filter: ${JSON.stringify(filter)}`, + ); + } + + await this.metadataKeysService.replaceManyFromSource( + this.createMetadataKeysInstance(updatedSample), + ); + + return updatedSample; } async remove(filter: FilterQuery): Promise { - return this.sampleModel.findOneAndDelete(filter).exec(); + const deletedSample = await this.sampleModel + .findOneAndDelete(filter) + .exec(); + + if (!deletedSample) { + throw new NotFoundException( + `Sample not found with filter: ${JSON.stringify(filter)}`, + ); + } + + this.metadataKeysService.deleteMany({ + sourceType: "sample", + sourceId: deletedSample.sampleId, + }); + return deletedSample; } } diff --git a/test/MetadataKeys.js b/test/MetadataKeys.js new file mode 100644 index 000000000..c62e117f0 --- /dev/null +++ b/test/MetadataKeys.js @@ -0,0 +1,174 @@ +"use strict"; +const utils = require("./LoginUtils"); +const { TestData } = require("./TestData"); + +let accessTokenAdminIngestor = null; +let accessTokenUser1 = null; +let datasetIdPrivate = null; +let datasetIdUser1 = null; + +describe("MetadataKeys v4 ACL", () => { + before(async () => { + db.collection("MetadataKeys").deleteMany({}); + + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + }); + + it("0000: create a private dataset v3 has scientific metadata for admin", async () => { + return request(appUrl) + .post("/api/v3/Datasets") + .send(TestData.RawCorrectRandom) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.EntryCreatedStatusCode) + .then((res) => { + res.body.should.have + .property("datasetName") + .and.equal(TestData.RawCorrectRandom.datasetName); + + datasetIdPrivate = encodeURIComponent(res.body["pid"]); + }); + }); + + it("0001: create a public dataset v4 has scientific metadata for unauthenticated user", async () => { + const publicDataset = { ...TestData.RawCorrectV4, isPublished: true }; + return request(appUrl) + .post("/api/v4/Datasets") + .send(publicDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.EntryCreatedStatusCode) + .then((res) => { + res.body.should.have + .property("datasetName") + .and.equal(publicDataset.datasetName); + }); + }); + + it("0002: create a private dataset v4 has scientific metadata for user1", async () => { + const user1Dataset = { ...TestData.RawCorrectV4, accessGroups: ["group1"] }; + return request(appUrl) + .post("/api/v4/Datasets") + .send(user1Dataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.EntryCreatedStatusCode) + .then((res) => { + res.body.should.have + .property("datasetName") + .and.equal(user1Dataset.datasetName); + + datasetIdUser1 = encodeURIComponent(res.body["pid"]); + }); + }); + + it("0010: should allow admin to list all metadata keys", async () => { + const filter = { + limits: { limit: 10, skip: 0, sort: { createdAt: "desc" } }, + }; + + return request(appUrl) + .get( + `/api/v4/metadatakeys?filter=${encodeURIComponent(JSON.stringify(filter))}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").that.satisfies((arr) => { + const values = arr.map((item) => item.isPublished); + return values.includes(true) && values.includes(false); + }); + }); + }); + + it("0020: should allow unauthenticated user to list only published metadata keys", async () => { + const filter = { + where: { sourceType: "dataset" }, + limits: { limit: 10, skip: 0, sort: { createdAt: "desc" } }, + }; + + return request(appUrl) + .get( + `/api/v4/metadatakeys?filter=${encodeURIComponent(JSON.stringify(filter))}`, + ) + .set("Accept", "application/json") + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").that.satisfies((arr) => { + return arr.every((item) => item.isPublished === true); + }); + }); + }); + + it("0030: should allow authenticated user to list metadata keys they have access", async () => { + const filter = { limits: { limit: 1, skip: 0 } }; + + return request(appUrl) + .get( + `/api/v4/metadatakeys?filter=${encodeURIComponent(JSON.stringify(filter))}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").that.satisfies((arr) => { + return arr.every((item) => { + return ( + item.isPublished === true || item.userGroups.includes("group1") + ); + }); + }); + }); + }); + + it("0040: should return empty array when user queries keys they don't have access to", async () => { + const filter = { + where: { sourceType: "dataset", sourceId: datasetIdPrivate }, + limits: { limit: 10, skip: 0 }, + }; + + return request(appUrl) + .get( + `/api/v4/metadatakeys?filter=${encodeURIComponent(JSON.stringify(filter))}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").and.have.length(0); + }); + }); + + it("0040: should return metadatakeys with correct access for user1", async () => { + const filter = { + where: { sourceType: "dataset", sourceId: `${datasetIdUser1}` }, + limits: { limit: 10, skip: 0 }, + }; + + return request(appUrl) + .get(`/api/v4/metadatakeys?filter=${JSON.stringify(filter)}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").and.have.length.of.at.least(1); + }); + }); +}); From 33381261af930c1b6d130adbd3517f1c018731c7 Mon Sep 17 00:00:00 2001 From: Carlo Minotti <50220438+minottic@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:43:40 +0100 Subject: [PATCH 018/120] fix: batch bulk writes to avoid OOM (#2528) --- .../20251117155200-encode-metadatakeys.js | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/migrations/20251117155200-encode-metadatakeys.js b/migrations/20251117155200-encode-metadatakeys.js index d53b0e444..9d08fea9e 100644 --- a/migrations/20251117155200-encode-metadatakeys.js +++ b/migrations/20251117155200-encode-metadatakeys.js @@ -13,7 +13,10 @@ const { module.exports = { async up(db, client) { - const bulkOps = []; + let bulkOps = []; + const BATCH_SIZE = 10000; + let modifiedCount = 0; + let unModifiedCount = 0; for await (const dataset of db .collection("Dataset") @@ -32,26 +35,42 @@ module.exports = { continue; } - console.log( - `Updating Dataset (Id: ${dataset._id}) with encoded scientificMetadata keys`, - ); - bulkOps.push({ updateOne: { filter: { _id: dataset._id }, update: { $set: { scientificMetadata: encodedMetadata } }, }, }); + + if (bulkOps.length === BATCH_SIZE) { + const bulkWriteResult = await db.collection("Dataset").bulkWrite(bulkOps, { + ordered: false + }); + modifiedCount += bulkWriteResult.modifiedCount; + unModifiedCount += BATCH_SIZE - bulkWriteResult.modifiedCount; + + bulkOps = []; + console.log("migrating, count, unModifiedCount: ", + modifiedCount, + unModifiedCount, + ); + } } if (bulkOps.length > 0) { console.log(`Executing bulk update for ${bulkOps.length} datasets`); - await db.collection("Dataset").bulkWrite(bulkOps); + const bulkWriteResult = await db.collection("Dataset").bulkWrite(bulkOps, { ordered: false }); + modifiedCount += bulkWriteResult.modifiedCount; + unModifiedCount += bulkOps.length - bulkWriteResult.modifiedCount; } + console.log("FINISHED: count, unModifiedCount: ", modifiedCount, unModifiedCount); }, async down(db, client) { - const bulkOps = []; + let bulkOps = []; + const BATCH_SIZE = 10000; + let modifiedCount = 0; + let unModifiedCount = 0; for await (const dataset of db .collection("Dataset") @@ -71,21 +90,34 @@ module.exports = { continue; } - console.log( - `Reverting Dataset (Id: ${dataset._id}) to decoded scientificMetadata keys`, - ); - bulkOps.push({ updateOne: { filter: { _id: dataset._id }, update: { $set: { scientificMetadata: decodedMetadata } }, }, }); + + if (bulkOps.length === BATCH_SIZE) { + const bulkWriteResult = await db.collection("Dataset").bulkWrite(bulkOps, { + ordered: false + }); + modifiedCount += bulkWriteResult.modifiedCount; + unModifiedCount += BATCH_SIZE - bulkWriteResult.modifiedCount; + + bulkOps = []; + console.log("migrating, count, unModifiedCount: ", + modifiedCount, + unModifiedCount, + ); + } } if (bulkOps.length > 0) { console.log(`Executing bulk revert for ${bulkOps.length} datasets`); - await db.collection("Dataset").bulkWrite(bulkOps); + const bulkWriteResult = await db.collection("Dataset").bulkWrite(bulkOps, { ordered: false }); + modifiedCount += bulkWriteResult.modifiedCount; + unModifiedCount += bulkOps.length - bulkWriteResult.modifiedCount; } + console.log("FINISHED: count, unModifiedCount: ", modifiedCount, unModifiedCount); }, }; From 60bd6103232e1cd88963889305effb0bf92a8b3e Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 11 Feb 2026 11:22:50 +0100 Subject: [PATCH 019/120] fix: add @IsNotEmpty() to sourceFolder to prevent empty string (#2529) --- src/datasets/dto/update-dataset-obsolete.dto.ts | 2 ++ src/datasets/dto/update-dataset.dto.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/datasets/dto/update-dataset-obsolete.dto.ts b/src/datasets/dto/update-dataset-obsolete.dto.ts index 8482d650f..fe6ca09e8 100644 --- a/src/datasets/dto/update-dataset-obsolete.dto.ts +++ b/src/datasets/dto/update-dataset-obsolete.dto.ts @@ -11,6 +11,7 @@ import { IsDateString, IsEmail, IsInt, + IsNotEmpty, IsNumber, IsObject, IsOptional, @@ -75,6 +76,7 @@ export class UpdateDatasetObsoleteDto extends OwnableDto { "Absolute file path on file server containing the files of this dataset, e.g. /some/path/to/sourcefolder. In case of a single file dataset, e.g. HDF5 data, it contains the path up to, but excluding the filename. Trailing slashes are removed.", }) @IsString() + @IsNotEmpty() readonly sourceFolder: string; @ApiProperty({ diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index 4ddf008ab..1fc2a098d 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -11,6 +11,7 @@ import { IsDateString, IsEmail, IsInt, + IsNotEmpty, IsNumber, IsObject, IsOptional, @@ -77,6 +78,7 @@ export class UpdateDatasetDto extends OwnableDto { "Absolute file path on file server containing the files of this dataset, e.g. /some/path/to/sourcefolder. In case of a single file dataset, e.g. HDF5 data, it contains the path up to, but excluding the filename. Trailing slashes are removed.", }) @IsString() + @IsNotEmpty() readonly sourceFolder: string; @ApiProperty({ From 5331045fe1a03b4eb28a7dd689fe85be07baf524 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 19:24:54 +0000 Subject: [PATCH 020/120] build(deps): bump axios from 1.13.2 to 1.13.5 Bumps [axios](https://github.com/axios/axios) from 1.13.2 to 1.13.5. - [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.13.2...v1.13.5) --- updated-dependencies: - dependency-name: axios dependency-version: 1.13.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54e877a1a..abe0110c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4855,13 +4855,13 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -7452,15 +7452,16 @@ "license": "MIT" }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, From adec3925d7459c61a6c6e4c26633f85fb97c6648 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 12 Feb 2026 12:54:25 +0100 Subject: [PATCH 021/120] fixed linting --- src/config/frontend.config.json | 76 ++++++++++++++++----------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index a6ba5c47c..899f183a5 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -286,214 +286,214 @@ { "name": "select", "type": "standard", - "width": 120, + "width": 120, "enabled": true }, { "name": "pid", "type": "standard", - "width": 130, + "width": 130, "enabled": true }, { "name": "datasetName", "type": "standard", - "width": 250, + "width": 250, "enabled": true }, { "name": "runNumber", "type": "standard", - "width": 120, + "width": 120, "enabled": true }, { "name": "sourceFolder", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "sourceFolderHost", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "size", "type": "standard", - "width": 150, + "width": 150, "enabled": true }, { "name": "numberOfFiles", "type": "standard", - "width": 120, + "width": 120, "enabled": false }, { "name": "creationTime", "type": "date", "enabled": true, - "width": 200, - "format": "yyyy-mm-dd HH:MM" + "width": 200, + "format": "yyyy-mm-dd HH:MM" }, { "name": "keywords", "type": "list", "enabled": false, - "width": 200 + "width": 200 }, { "name": "description", "type": "hovercontent", "enabled": false, - "width": 150 + "width": 150 }, { "name": "type", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "image", "type": "standard", - "width": 250, + "width": 250, "enabled": true }, { "name": "scientificMetadata", "type": "hovercontent", - "width": 200, + "width": 200, "enabled": false }, { "name": "scientificMetadataSchema", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "scientificMetadataValid", "type": "standard", - "width": 100, + "width": 100, "enabled": false }, { "name": "owner", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "ownerEmail", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "orcidOfOwner", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "contactEmail", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "proposalId", "type": "standard", - "width": 200, + "width": 200, "enabled": true }, { "name": "proposalIds", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "license", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "isPublished", "type": "standard", - "width": 100, + "width": 100, "enabled": false }, { "name": "techniques", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "comment", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "dataQualityMetrics", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "principalInvestigator", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "startTime", "type": "date", - "width": 200, + "width": 200, "enabled": false, - "format": "yyyy-mm-dd HH:MM" + "format": "yyyy-mm-dd HH:MM" }, { "name": "endTime", "type": "date", - "width": 200, + "width": 200, "enabled": false, - "format": "yyyy-mm-dd HH:MM" + "format": "yyyy-mm-dd HH:MM" }, { "name": "creationLocation", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "sampleIds", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "ownerGroup", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "dataStatus", "type": "standard", - "width": 200, + "width": 200, "enabled": false }, { "name": "accessGroups", "type": "standard", - "width": 200, + "width": 200, "enabled": false } ], From 658b9714790160d8b4117cfe4ffef0ed3f7365c7 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Feb 2026 13:47:07 +0100 Subject: [PATCH 022/120] updated frontend default config --- src/config/frontend.config.json | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index b84086661..0554e687c 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -6,16 +6,19 @@ "checkBoxFilterClickTrigger": false, "accessTokenPrefix": "Bearer ", "addDatasetEnabled": false, + "allowConfigOverrides": true, "archiveWorkflowEnabled": false, "datasetReduceEnabled": true, "datasetJsonScientificMetadata": true, "editDatasetEnabled": true, "editDatasetSampleEnabled": true, "editMetadataEnabled": true, + "editPublishedData": true, "addSampleEnabled": false, "externalAuthEndpoint": "/api/v3/auth/msad", "facility": "SciCat Vanilla", "siteIcon": "site-header-logo.png", + "siteHeaderLogoUrl": "https://my.facility.site", "siteTitle": "Local development", "siteSciCatLogo": "full", "loginFacilityLabel": "SciCat Vanilla", @@ -34,10 +37,18 @@ "landingPage": "doi.ess.eu/detail/", "lbBaseURL": "http://localhost:3000", "ingestorComponent": { - "ingestorEnabled": false + "ingestorEnabled": false, + "ingestorAutodiscoveryOptions": [ + { + "mailDomain": "university.ch", + "description": "University/facility of Choice", + "facilityBackend": "http://localhost:8888" + } + ] }, "logbookEnabled": false, "loginFormEnabled": true, + "thumbnailFetchLimitPerPage": 100, "metadataPreviewEnabled": true, "metadataStructure": "", "multipleDownloadAction": "http:/127.0.0.1:3012/zip", @@ -56,10 +67,10 @@ "searchPublicDataEnabled": true, "searchSamples": true, "sftpHost": "login.esss.dk", + "shareEnabled": false, "sourceFolder": "/data/ess", "maxDirectDownloadSize": 5000000000, "maxFileSizeWarning": "Some files are above and cannot be downloaded directly. These file can be downloaded via sftp host: in directory: ", - "shareEnabled": true, "shoppingCartEnabled": true, "shoppingCartOnHeader": true, "tableSciDataEnabled": true, @@ -270,7 +281,7 @@ "datasetDetailsActions": [], "selectionActionsEnabled": true, "selectionActions": [], - "labelMaps": { + "labelMaps": { "filters": { "LocationFilter": "Location", "PidFilter": "Pid", @@ -406,7 +417,6 @@ }, { "name": "proposalId", - "width": 120, "type": "standard", "width": 200, "enabled": true From 0180dd50036b6e85dbbcf9bebe3edd9f4cab3abb Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Feb 2026 15:37:47 +0100 Subject: [PATCH 023/120] changed filter field to text area in swagger for origdatablocks v4 --- src/origdatablocks/origdatablocks.v4.controller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/origdatablocks/origdatablocks.v4.controller.ts b/src/origdatablocks/origdatablocks.v4.controller.ts index 5bde65bc7..3486f5471 100644 --- a/src/origdatablocks/origdatablocks.v4.controller.ts +++ b/src/origdatablocks/origdatablocks.v4.controller.ts @@ -501,7 +501,7 @@ export class OrigDatablocksV4Controller { description: "Database filters to apply when retrieving origdatablocks", required: false, type: String, - example: getSwaggerOrigDatablockFilterContent(), + content: getSwaggerOrigDatablockFilterContent(), }) @ApiResponse({ status: HttpStatus.OK, @@ -526,6 +526,7 @@ export class OrigDatablocksV4Controller { request.user as JWTUser, parsedFilter, ); + console.log("origdatablocks findAll",JSON.stringify(mergedFilter)); const origdatablocks = await this.origDatablocksService.findAllComplete(mergedFilter); From dd92db8744bb2ac852ca35d6effe80f2acaa1d29 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Feb 2026 16:25:58 +0100 Subject: [PATCH 024/120] fixed linting issues --- src/origdatablocks/origdatablocks.v4.controller.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/origdatablocks/origdatablocks.v4.controller.ts b/src/origdatablocks/origdatablocks.v4.controller.ts index 3486f5471..a45577b28 100644 --- a/src/origdatablocks/origdatablocks.v4.controller.ts +++ b/src/origdatablocks/origdatablocks.v4.controller.ts @@ -526,7 +526,6 @@ export class OrigDatablocksV4Controller { request.user as JWTUser, parsedFilter, ); - console.log("origdatablocks findAll",JSON.stringify(mergedFilter)); const origdatablocks = await this.origDatablocksService.findAllComplete(mergedFilter); From 0e7921b6cf08d4d22a6db827c15b6d8976391f89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 12:49:31 +0000 Subject: [PATCH 025/120] build(deps): bump qs from 6.14.1 to 6.14.2 Bumps [qs](https://github.com/ljharb/qs) from 6.14.1 to 6.14.2. - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.14.1...v6.14.2) --- updated-dependencies: - dependency-name: qs dependency-version: 6.14.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index abe0110c5..a8805e00d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12136,9 +12136,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" From 8d094f25604890c07fe3255411818f9c11bac950 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:08:49 +0000 Subject: [PATCH 026/120] build(deps): bump the nestjs group with 4 updates Bumps the nestjs group with 4 updates: [@nestjs/config](https://github.com/nestjs/config), [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express), [@nestjs/swagger](https://github.com/nestjs/swagger) and [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing). Updates `@nestjs/config` from 4.0.2 to 4.0.3 - [Release notes](https://github.com/nestjs/config/releases) - [Commits](https://github.com/nestjs/config/compare/4.0.2...4.0.3) Updates `@nestjs/platform-express` from 11.1.12 to 11.1.13 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.13/packages/platform-express) Updates `@nestjs/swagger` from 11.2.5 to 11.2.6 - [Release notes](https://github.com/nestjs/swagger/releases) - [Commits](https://github.com/nestjs/swagger/compare/11.2.5...11.2.6) Updates `@nestjs/testing` from 11.1.12 to 11.1.13 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.13/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/config" dependency-version: 4.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/platform-express" dependency-version: 11.1.13 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/swagger" dependency-version: 11.2.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/testing" dependency-version: 11.1.13 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 77 ++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8805e00d..46ac372e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2582,37 +2582,20 @@ } }, "node_modules/@nestjs/config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", - "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.3.tgz", + "integrity": "sha512-FQ3M3Ohqfl+nHAn5tp7++wUQw0f2nAk+SFKe8EpNRnIifPqvfJP6JQxPKtFLMOHbyer4X646prFG4zSRYEssQQ==", + "license": "MIT", "dependencies": { - "dotenv": "16.4.7", - "dotenv-expand": "12.0.1", - "lodash": "4.17.21" + "dotenv": "17.2.3", + "dotenv-expand": "12.0.3", + "lodash": "4.17.23" }, "peerDependencies": { "@nestjs/common": "^10.0.0 || ^11.0.0", "rxjs": "^7.1.0" } }, - "node_modules/@nestjs/config/node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/@nestjs/config/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, "node_modules/@nestjs/core": { "version": "11.0.13", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.0.13.tgz", @@ -2730,12 +2713,12 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.12", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.12.tgz", - "integrity": "sha512-GYK/vHI0SGz5m8mxr7v3Urx8b9t78Cf/dj5aJMZlGd9/1D9OI1hAl00BaphjEXINUJ/BQLxIlF2zUjrYsd6enQ==", + "version": "11.1.13", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.13.tgz", + "integrity": "sha512-LYmi43BrAs1n74kLCUfXcHag7s1CmGETcFbf9IVyA/KWXAuAH95G3wEaZZiyabOLFNwq4ifnRGnIwUwW7cz3+w==", "license": "MIT", "dependencies": { - "cors": "2.8.5", + "cors": "2.8.6", "express": "5.2.1", "multer": "2.0.2", "path-to-regexp": "8.3.0", @@ -2835,15 +2818,15 @@ } }, "node_modules/@nestjs/swagger": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.2.5.tgz", - "integrity": "sha512-wCykbEybMqiYcvkyzPW4SbXKcwra9AGdajm0MvFgKR3W+gd1hfeKlo67g/s9QCRc/mqUU4KOE5Qtk7asMeFuiA==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.2.6.tgz", + "integrity": "sha512-oiXOxMQqDFyv1AKAqFzSo6JPvMEs4uA36Eyz/s2aloZLxUjcLfUMELSLSNQunr61xCPTpwEOShfmO7NIufKXdA==", "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.16.0", "@nestjs/mapped-types": "2.1.0", "js-yaml": "4.1.1", - "lodash": "4.17.21", + "lodash": "4.17.23", "path-to-regexp": "8.3.0", "swagger-ui-dist": "5.31.0" }, @@ -2867,12 +2850,6 @@ } } }, - "node_modules/@nestjs/swagger/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, "node_modules/@nestjs/swagger/node_modules/path-to-regexp": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", @@ -2953,9 +2930,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "11.1.12", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.12.tgz", - "integrity": "sha512-W0M/i5nb9qRQpTQfJm+1mGT/+y4YezwwdcD7mxFG8JEZ5fz/ZEAk1Ayri2VBJKJUdo20B1ggnvqew4dlTMrSNg==", + "version": "11.1.13", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.13.tgz", + "integrity": "sha512-bOWP8nLEZAOEEX8jAZGBCc1yU0+nv4g2ipc+QEzkVUe3eEEUKHKaeGafJ3GtDuGavlZKfkXEqflZuICdavu5dQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6089,15 +6066,20 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cosmiconfig": { @@ -6439,9 +6421,10 @@ } }, "node_modules/dotenv-expand": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz", - "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz", + "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==", + "license": "BSD-2-Clause", "dependencies": { "dotenv": "^16.4.5" }, From 4447cb9db01b4c3bed14c2c6468c613e8a2dd631 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 16 Feb 2026 17:15:39 +0100 Subject: [PATCH 027/120] changed default content-type order for dataset PATCH --- src/datasets/datasets.v4.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datasets/datasets.v4.controller.ts b/src/datasets/datasets.v4.controller.ts index b0ebc9311..1f0805f74 100644 --- a/src/datasets/datasets.v4.controller.ts +++ b/src/datasets/datasets.v4.controller.ts @@ -769,7 +769,7 @@ Set \`content-type\` header to \`application/merge-patch+json\` if you would lik description: "Id of the dataset to modify", type: String, }) - @ApiConsumes("application/merge-patch+json", "application/json") + @ApiConsumes("application/json", "application/merge-patch+json") @ApiBody({ description: "Fields that needs to be updated in the dataset. Only the fields that needs to be updated have to be passed in.", From bd3da2261069a6c377a053b34292674375707fd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:18:57 +0000 Subject: [PATCH 028/120] build(deps): bump ajv from 8.17.1 to 8.18.0 Bumps [ajv](https://github.com/ajv-validator/ajv) from 8.17.1 to 8.18.0. - [Release notes](https://github.com/ajv-validator/ajv/releases) - [Commits](https://github.com/ajv-validator/ajv/compare/v8.17.1...v8.18.0) --- updated-dependencies: - dependency-name: ajv dependency-version: 8.18.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46ac372e5..54df791d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -150,6 +150,23 @@ } } }, + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@angular-devkit/core/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -2807,6 +2824,23 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@nestjs/schematics/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@nestjs/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -4527,9 +4561,10 @@ } }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", From e886d2189ffdcc79219e8ea26e0f842e74a5e58f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:29:06 +0000 Subject: [PATCH 029/120] build(deps-dev): bump @types/nodemailer from 7.0.9 to 7.0.10 Bumps [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer) from 7.0.9 to 7.0.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer) --- updated-dependencies: - dependency-name: "@types/nodemailer" dependency-version: 7.0.10 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54df791d0..a9202e8f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3565,9 +3565,9 @@ } }, "node_modules/@types/nodemailer": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.9.tgz", - "integrity": "sha512-vI8oF1M+8JvQhsId0Pc38BdUP2evenIIys7c7p+9OZXSPOH5c1dyINP1jT8xQ2xPuBUXmIC87s+91IZMDjH8Ow==", + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.10.tgz", + "integrity": "sha512-tP+9WggTFN22Zxh0XFyst7239H0qwiRCogsk7v9aQS79sYAJY+WEbTHbNYcxUMaalHKmsNpxmoTe35hBEMMd6g==", "dev": true, "license": "MIT", "dependencies": { From 686df34b17775d3e26a03e1e84139d86f5486bfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:39:05 +0000 Subject: [PATCH 030/120] build(deps-dev): bump @faker-js/faker from 10.2.0 to 10.3.0 Bumps [@faker-js/faker](https://github.com/faker-js/faker) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/faker-js/faker/releases) - [Changelog](https://github.com/faker-js/faker/blob/next/CHANGELOG.md) - [Commits](https://github.com/faker-js/faker/compare/v10.2.0...v10.3.0) --- updated-dependencies: - dependency-name: "@faker-js/faker" dependency-version: 10.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9202e8f8..cebff3ced 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1263,9 +1263,9 @@ } }, "node_modules/@faker-js/faker": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.2.0.tgz", - "integrity": "sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.3.0.tgz", + "integrity": "sha512-It0Sne6P3szg7JIi6CgKbvTZoMjxBZhcv91ZrqrNuaZQfB5WoqYYbzCUOq89YR+VY8juY9M1vDWmDDa2TzfXCw==", "dev": true, "funding": [ { From 6ee7aa4815e919b32f389a791feca8bc790a4ca4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:49:17 +0000 Subject: [PATCH 031/120] build(deps): bump dotenv from 17.2.3 to 17.3.1 Bumps [dotenv](https://github.com/motdotla/dotenv) from 17.2.3 to 17.3.1. - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](https://github.com/motdotla/dotenv/compare/v17.2.3...v17.3.1) --- updated-dependencies: - dependency-name: dotenv dependency-version: 17.3.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index cebff3ced..7bb9098d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2613,6 +2613,18 @@ "rxjs": "^7.1.0" } }, + "node_modules/@nestjs/config/node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/@nestjs/core": { "version": "11.0.13", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.0.13.tgz", @@ -6428,9 +6440,9 @@ } }, "node_modules/dotenv": { - "version": "17.2.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", - "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", "license": "BSD-2-Clause", "engines": { "node": ">=12" From cbe018465d3481ed78a778d9d74f54d5b8cefb47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:59:21 +0000 Subject: [PATCH 032/120] build(deps): bump mathjs from 15.1.0 to 15.1.1 Bumps [mathjs](https://github.com/josdejong/mathjs) from 15.1.0 to 15.1.1. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v15.1.0...v15.1.1) --- updated-dependencies: - dependency-name: mathjs dependency-version: 15.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7bb9098d2..f18aa211c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10059,9 +10059,9 @@ } }, "node_modules/mathjs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.1.0.tgz", - "integrity": "sha512-HfnAcScQm9drGryodlDqeS3WAl4gUTYGDcOtcqL/8s23MZ28Ib1i8XnYK3ZdjNuaW/L4BAp9lIp8vxAMrcuu1w==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.1.1.tgz", + "integrity": "sha512-rM668DTtpSzMVoh/cKAllyQVEbBApM5g//IMGD8vD7YlrIz9ITRr3SrdhjaDxcBNTdyETWwPebj2unZyHD7ZdA==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.26.10", From fd2378876485b7bfacbcb173436ed76e99557498 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 17:09:17 +0000 Subject: [PATCH 033/120] build(deps): bump jsonpath-plus from 10.3.0 to 10.4.0 Bumps [jsonpath-plus](https://github.com/s3u/JSONPath) from 10.3.0 to 10.4.0. - [Release notes](https://github.com/s3u/JSONPath/releases) - [Changelog](https://github.com/JSONPath-Plus/JSONPath/blob/main/CHANGES.md) - [Commits](https://github.com/s3u/JSONPath/compare/v10.3.0...v10.4.0) --- updated-dependencies: - dependency-name: jsonpath-plus dependency-version: 10.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f18aa211c..92e631372 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9521,9 +9521,10 @@ } }, "node_modules/jsonpath-plus": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", - "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.4.0.tgz", + "integrity": "sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==", + "license": "MIT", "dependencies": { "@jsep-plugin/assignment": "^1.3.0", "@jsep-plugin/regex": "^1.0.4", From c55bcb668ef41ec2092cc03aac1702e6eb0e55dd Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 18 Feb 2026 08:19:18 +0100 Subject: [PATCH 034/120] remove metadata keys endpoint migration script --- ...153400-sync-metadata-keys-from-datasets.js | 98 ------------------- 1 file changed, 98 deletions(-) delete mode 100644 migrations/20260116153400-sync-metadata-keys-from-datasets.js diff --git a/migrations/20260116153400-sync-metadata-keys-from-datasets.js b/migrations/20260116153400-sync-metadata-keys-from-datasets.js deleted file mode 100644 index 64ba112c9..000000000 --- a/migrations/20260116153400-sync-metadata-keys-from-datasets.js +++ /dev/null @@ -1,98 +0,0 @@ -module.exports = { - async up(db) { - const DATASET_COL = "Dataset"; - const METAKEYS_COL = "MetadataKeys"; - - // Aggregation pipeline to extract metadata keys from datasets - const pipeline = [ - // 1) Only datasets that have scientificMetadata object - { $match: { scientificMetadata: { $exists: true, $type: "object" } } }, - - // 2) Prepare fields and convert scientificMetadata -> array - { - $project: { - sourceType: { $literal: "dataset" }, - sourceId: "$pid", - ownerGroup: 1, - accessGroups: 1, - isPublished: 1, - metaArr: { $objectToArray: "$scientificMetadata" }, // {k,v}[] - }, - }, - - // 3) One document per metadata key - { $unwind: "$metaArr" }, - - // 4) Shape final MetadataKeys document - { - $project: { - _id: { $concat: ["dataset_", "$sourceId", "_", "$metaArr.k"] }, // unique per dataset - sourceType: 1, - sourceId: 1, - key: "$metaArr.k", // metadata key name - userGroups: { - $setUnion: [ - [{ $ifNull: ["$ownerGroup", ""] }], - { $ifNull: ["$accessGroups", []] }, - ], - }, // owner + access groups fallback - isPublished: 1, - - // only include humanReadableName if exists - humanReadableName: { - $cond: [ - { $ifNull: ["$metaArr.v.human_name", false] }, - "$metaArr.v.human_name", - "$$REMOVE", - ], - }, - createdBy: { $literal: "migration" }, - createdAt: { $toDate: "$$NOW" }, - }, - }, - - // 5) Upsert into MetadataKeys - { - $merge: { - into: METAKEYS_COL, - on: "_id", // match by dataset id - whenMatched: [ - { - $set: { - sourceType: "$$new.sourceType", - sourceId: "$$new.sourceId", - key: "$$new.key", - userGroups: "$$new.userGroups", - isPublished: "$$new.isPublished", - humanReadableName: "$$new.humanReadableName", - updatedBy: { $literal: "migration" }, - updatedAt: { $toDate: "$$NOW" }, - }, - }, - ], - whenNotMatched: "insert", - }, - }, - ]; - - console.log("--- Syncing metadata keys from datasets ---"); - - const start = Date.now(); - const timer = setInterval(() => { - const sec = Math.floor((Date.now() - start) / 1000); - console.log(`Syncing... ${sec}s`); - }, 1000); // log every 1s - - await db - .collection(DATASET_COL) - .aggregate(pipeline, { allowDiskUse: true }) - .toArray(); - clearInterval(timer); - console.log("--- Syncing metadata keys from datasets completed ---"); - }, - - // Rollback: clear MetadataKeys collection - async down(db) { - await db.collection("MetadataKeys").deleteMany({}); - }, -}; From 91fb850ad61787c1340763a2c2fe0e198d413654 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 23 Feb 2026 12:56:28 +0100 Subject: [PATCH 035/120] feat(auth): implement tokenlogin endpoint (#2531) * created auth providers folder and moved access-group-provider to the providers folder with updated import path * created openid-client provider service and cleaned up old flow * revert path change * revert path change for access-grou-provider * 1. created openid-client module and moved oidc auth logic within the module 2. installed nestJS throttlerModule to control oidc/token endpoint rate limit * remove duplicated openid auth logic from client service * typo fix * client secret is not mandatory * fix failing unit test * add oidc token login unit test --- package-lock.json | 12 + package.json | 1 + src/app.module.ts | 12 + ...ess-group-from-graphql-api-call.service.ts | 2 +- ...s-group-from-multiple-providers.service.ts | 2 +- .../access-group-from-payload.service.ts | 2 +- .../access-group.service.ts | 2 +- src/auth/auth.controller.spec.ts | 12 + src/auth/auth.controller.ts | 19 ++ src/auth/auth.module.ts | 26 +- src/auth/auth.service.spec.ts | 59 ++++- src/auth/auth.service.ts | 42 ++- src/auth/dto/idToken.dto.ts | 16 ++ src/auth/strategies/ldap.strategy.ts | 2 +- src/auth/strategies/local.strategy.ts | 1 - src/auth/strategies/oidc.strategy.ts | 248 +----------------- .../interfaces/oidc-user.interface.ts | 0 .../openid-client/openid-auth.service.ts | 221 ++++++++++++++++ .../openid-client/openid-client.module.ts | 14 + .../openid-client/openid-client.service.ts | 57 ++++ 20 files changed, 484 insertions(+), 266 deletions(-) create mode 100644 src/auth/dto/idToken.dto.ts rename src/{auth => common/openid-client}/interfaces/oidc-user.interface.ts (100%) create mode 100644 src/common/openid-client/openid-auth.service.ts create mode 100644 src/common/openid-client/openid-client.module.ts create mode 100644 src/common/openid-client/openid-client.service.ts diff --git a/package-lock.json b/package-lock.json index 92e631372..a24cbeff4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@nestjs/platform-express": "^11", "@nestjs/swagger": "^11.1.1", "@nestjs/terminus": "^11", + "@nestjs/throttler": "^6.5.0", "@types/json-merge-patch": "^1.0.0", "@types/jsonschema": "^1.1.1", "@user-office-software/duo-logger": "^2.1.1", @@ -3003,6 +3004,17 @@ } } }, + "node_modules/@nestjs/throttler": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@nestjs/throttler/-/throttler-6.5.0.tgz", + "integrity": "sha512-9j0ZRfH0QE1qyrj9JjIRDz5gQLPqq9yVC2nHsrosDVAfI5HHw08/aUAWx9DZLSdQf4HDkmhTTEGLrRFHENvchQ==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", + "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", + "reflect-metadata": "^0.1.13 || ^0.2.0" + } + }, "node_modules/@noble/hashes": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", diff --git a/package.json b/package.json index 0f48c6701..454031ca3 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@nestjs/platform-express": "^11", "@nestjs/swagger": "^11.1.1", "@nestjs/terminus": "^11", + "@nestjs/throttler": "^6.5.0", "@types/json-merge-patch": "^1.0.0", "@types/jsonschema": "^1.1.1", "@user-office-software/duo-logger": "^2.1.1", diff --git a/src/app.module.ts b/src/app.module.ts index 8da5939a4..814ad397f 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -44,6 +44,8 @@ import { HistoryModule } from "./history/history.module"; import { MaskSensitiveDataInterceptorModule } from "./common/interceptors/mask-sensitive-data.interceptor"; import { RuntimeConfigModule } from "./config/runtime-config/runtime-config.module"; import { MetadataKeysModule } from "./metadata-keys/metadatakeys.module"; +import { OidcClientModule } from "./common/openid-client/openid-client.module"; +import { ThrottlerModule } from "@nestjs/throttler"; @Module({ imports: [ @@ -53,6 +55,7 @@ import { MetadataKeysModule } from "./metadata-keys/metadatakeys.module"; cache: true, }), AuthModule, + OidcClientModule, CaslModule, AttachmentsModule, CommonModule, @@ -164,6 +167,15 @@ import { MetadataKeysModule } from "./metadata-keys/metadatakeys.module"; MaskSensitiveDataInterceptorModule, (env: NodeJS.ProcessEnv) => env.MASK_PERSONAL_INFO === "yes", ), + ThrottlerModule.forRoot({ + throttlers: [ + { + name: "login", + ttl: 1000, + limit: 1, + }, + ], + }), ], controllers: [], providers: [ diff --git a/src/auth/access-group-provider/access-group-from-graphql-api-call.service.ts b/src/auth/access-group-provider/access-group-from-graphql-api-call.service.ts index 0d29f28f2..b0bd1d032 100644 --- a/src/auth/access-group-provider/access-group-from-graphql-api-call.service.ts +++ b/src/auth/access-group-provider/access-group-from-graphql-api-call.service.ts @@ -2,9 +2,9 @@ import { AccessGroupService as AccessGroupService } from "./access-group.service import { Injectable, Logger } from "@nestjs/common"; ///import fetch from "node-fetch"; -import { UserPayload } from "../interfaces/userPayload.interface"; import { HttpService } from "@nestjs/axios"; import { firstValueFrom } from "rxjs"; +import { UserPayload } from "src/auth/interfaces/userPayload.interface"; /** * This service is used to fetch access groups from a GraphQL API. */ diff --git a/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts b/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts index 60cf7f289..0c932e39b 100644 --- a/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts +++ b/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts @@ -1,6 +1,6 @@ import { Injectable } from "@nestjs/common"; -import { UserPayload } from "../interfaces/userPayload.interface"; import { AccessGroupService } from "./access-group.service"; +import { UserPayload } from "src/auth/interfaces/userPayload.interface"; /** * This service is used to get the access groups from multiple providers. diff --git a/src/auth/access-group-provider/access-group-from-payload.service.ts b/src/auth/access-group-provider/access-group-from-payload.service.ts index e36f5a87a..bc07ebb42 100644 --- a/src/auth/access-group-provider/access-group-from-payload.service.ts +++ b/src/auth/access-group-provider/access-group-from-payload.service.ts @@ -1,8 +1,8 @@ //import { AccessGroupService as AccessGroupService } from "./access-group.service"; import { Injectable, Logger } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; -import { UserPayload } from "../interfaces/userPayload.interface"; import { AccessGroupService } from "./access-group.service"; +import { UserPayload } from "src/auth/interfaces/userPayload.interface"; /** * This service is used to get the access groups from the payload of the IDP. diff --git a/src/auth/access-group-provider/access-group.service.ts b/src/auth/access-group-provider/access-group.service.ts index c29b7da54..055a02c25 100644 --- a/src/auth/access-group-provider/access-group.service.ts +++ b/src/auth/access-group-provider/access-group.service.ts @@ -1,4 +1,4 @@ -import { UserPayload } from "../interfaces/userPayload.interface"; +import { UserPayload } from "src/auth/interfaces/userPayload.interface"; export abstract class AccessGroupService { abstract getAccessGroups( diff --git a/src/auth/auth.controller.spec.ts b/src/auth/auth.controller.spec.ts index da0bc005d..57eac5474 100644 --- a/src/auth/auth.controller.spec.ts +++ b/src/auth/auth.controller.spec.ts @@ -4,6 +4,7 @@ import { AuthService } from "./auth.service"; import { Response } from "express"; import { Session } from "express-session"; import { ConfigService } from "@nestjs/config"; +import { ThrottlerModule } from "@nestjs/throttler"; class AuthServiceMock { login() { @@ -29,6 +30,17 @@ describe("AuthController", () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ + imports: [ + ThrottlerModule.forRoot({ + throttlers: [ + { + name: "login", + ttl: 1000, + limit: 1, + }, + ], + }), + ], controllers: [AuthController], providers: [ ConfigService, diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 88e868804..8ef18d690 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -6,6 +6,7 @@ import { Res, Req, HttpCode, + Body, } from "@nestjs/common"; import { LocalAuthGuard } from "./guards/local-auth.guard"; import { AuthService } from "./auth.service"; @@ -17,6 +18,7 @@ import { ApiResponse, ApiTags, ApiQuery, + ApiOkResponse, } from "@nestjs/swagger"; import { CredentialsDto } from "./dto/credentials.dto"; import { LdapAuthGuard } from "./guards/ldap.guard"; @@ -25,6 +27,8 @@ import { User } from "src/users/schemas/user.schema"; import { OidcAuthGuard } from "./guards/oidc.guard"; import { Request, Response } from "express"; import { ReturnedAuthLoginDto } from "./dto/returnedLogin.dto"; +import { IdTokenDto } from "./dto/idToken.dto"; +import { ThrottlerGuard } from "@nestjs/throttler"; @ApiBearerAuth() @ApiTags("auth") @@ -91,6 +95,21 @@ export class AuthController { // this function is invoked when the oidc is set as an auth method. It's behaviour comes from the oidc strategy } + @AllowAny() + @UseGuards(ThrottlerGuard) + @ApiBody({ type: IdTokenDto }) + @ApiOkResponse({ + description: + "Successfully authenticated via OIDC. Returns SciCat access token.", + type: ReturnedAuthLoginDto, + }) + @Post("oidc/token") + async oidcTokenLogin( + @Body() idTokenDto: IdTokenDto, + ): Promise { + return this.authService.oidcTokenLogin(idTokenDto.idToken); + } + @AllowAny() @UseGuards(OidcAuthGuard) @Get("oidc/callback") diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index b6cb1eccc..3f9747d1d 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -8,37 +8,31 @@ import { JwtModule } from "@nestjs/jwt"; import { JwtStrategy } from "./strategies/jwt.strategy"; import { LdapStrategy } from "./strategies/ldap.strategy"; import { ConfigService } from "@nestjs/config"; -import { UsersService } from "src/users/users.service"; import { OidcConfig } from "src/config/configuration"; -import { BuildOpenIdClient, OidcStrategy } from "./strategies/oidc.strategy"; +import { OidcStrategy } from "./strategies/oidc.strategy"; import { accessGroupServiceFactory } from "./access-group-provider/access-group-service-factory"; -import { AccessGroupService } from "./access-group-provider/access-group.service"; import { CaslModule } from "src/casl/casl.module"; import { SessionMiddleware } from "./middlewares/session.middleware"; +import { OidcClientService } from "../common/openid-client/openid-client.service"; +import { OidcAuthService } from "src/common/openid-client/openid-auth.service"; const OidcStrategyFactory = { provide: "OidcStrategy", useFactory: async ( - authService: AuthService, + oidcClientService: OidcClientService, + oidcAuthService: OidcAuthService, configService: ConfigService, - userService: UsersService, - accessGroupService: AccessGroupService, ) => { if (!configService.get("oidc")?.issuer) { return null; } - const clientBuilder = new BuildOpenIdClient(configService); - const client = await clientBuilder.build(); - const strategy = new OidcStrategy( - authService, - client, - configService, - userService, - accessGroupService, - ); + + const client = await oidcClientService.getClient(); + + const strategy = new OidcStrategy(client, configService, oidcAuthService); return strategy; }, - inject: [AuthService, ConfigService, UsersService, AccessGroupService], + inject: [OidcClientService, OidcAuthService, ConfigService], }; @Module({ diff --git a/src/auth/auth.service.spec.ts b/src/auth/auth.service.spec.ts index fb8afe31e..61d0d1768 100644 --- a/src/auth/auth.service.spec.ts +++ b/src/auth/auth.service.spec.ts @@ -3,13 +3,31 @@ import { JwtService } from "@nestjs/jwt"; import { Test, TestingModule } from "@nestjs/testing"; import { UsersService } from "src/users/users.service"; import { AuthService } from "./auth.service"; +import { OidcClientService } from "src/common/openid-client/openid-client.service"; +import { OidcAuthService } from "src/common/openid-client/openid-auth.service"; -class JwtServiceMock {} +class JwtServiceMock { + sign = jest.fn(); +} -class UsersServiceMock {} +class UsersServiceMock { + findByIdUserSettings = jest.fn().mockResolvedValue({}); + createUserSettings = jest.fn().mockResolvedValue({}); +} +class OidcClientServiceMock { + getClient = jest.fn(); +} + +class OidcAuthServiceMock { + validate = jest.fn(); +} describe("AuthService", () => { let authService: AuthService; + let oidcClientService: OidcClientServiceMock; + let oidcAuthService: OidcAuthServiceMock; + let jwtService: JwtServiceMock; + let configService: ConfigService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -18,13 +36,50 @@ describe("AuthService", () => { ConfigService, { provide: JwtService, useClass: JwtServiceMock }, { provide: UsersService, useClass: UsersServiceMock }, + { provide: OidcClientService, useClass: OidcClientServiceMock }, + { provide: OidcAuthService, useClass: OidcAuthServiceMock }, ], }).compile(); authService = module.get(AuthService); + oidcClientService = module.get(OidcClientService); + oidcAuthService = module.get(OidcAuthService); + jwtService = module.get(JwtService); + configService = module.get(ConfigService); }); it("should be defined", () => { expect(authService).toBeDefined(); }); + + describe("Oidc Token Login", () => { + const mockIdToken = "valid-id-token"; + const mockUser = { _id: "user_123", email: "test@example.com" }; + const mockAccessToken = "signed-jwt-token"; + const mockExpiresIn = 3600; + + it("should successfully validate token and return auth login dto", async () => { + const postLoginSpy = jest.spyOn(authService, "postLoginTasks"); + + const mockClient = { + callback: jest.fn().mockResolvedValue({ id_token: mockIdToken }), + }; + oidcClientService.getClient.mockResolvedValue(mockClient); + + jest.spyOn(configService, "get").mockImplementation((key: string) => { + if (key === "oidc.callbackURL") return "http://localhost/callback"; + if (key === "jwt.expiresIn") return mockExpiresIn; + return null; + }); + + oidcAuthService.validate.mockResolvedValue(mockUser); + jwtService.sign.mockReturnValue(mockAccessToken); + + const result = await authService.oidcTokenLogin(mockIdToken); + + expect(result.access_token).toBe(mockAccessToken); + expect(result.userId).toBe(mockUser._id); + expect(postLoginSpy).toHaveBeenCalledWith(mockUser); + }); + }); }); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 25f565d9c..d403fab7f 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -1,4 +1,10 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; +import { + HttpException, + HttpStatus, + Injectable, + Logger, + UnauthorizedException, +} from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import { JwtService } from "@nestjs/jwt"; import { compare } from "bcrypt"; @@ -7,16 +13,20 @@ import { UsersService } from "../users/users.service"; import { Request } from "express"; import { OidcConfig } from "src/config/configuration"; import { flattenObject, parseBoolean } from "src/common/utils"; -import { Issuer } from "openid-client"; +import { Issuer, TokenSet } from "openid-client"; import { ReturnedAuthLoginDto } from "./dto/returnedLogin.dto"; import { ReturnedUserDto } from "src/users/dto/returned-user.dto"; import { CreateUserSettingsDto } from "src/users/dto/create-user-settings.dto"; +import { OidcClientService } from "../common/openid-client/openid-client.service"; +import { OidcAuthService } from "src/common/openid-client/openid-auth.service"; @Injectable() export class AuthService { constructor( private configService: ConfigService, private usersService: UsersService, + private oidcClientService: OidcClientService, + private oidcAuthService: OidcAuthService, private jwtService: JwtService, ) {} @@ -56,6 +66,34 @@ export class AuthService { }; } + async oidcTokenLogin(idToken: string): Promise { + let tokenSet: TokenSet; + const client = await this.oidcClientService.getClient(); + const callbackUrl = this.configService.get("oidc.callbackURL"); + + try { + tokenSet = await client.callback(callbackUrl, { id_token: idToken }, {}); + } catch (error) { + throw new UnauthorizedException( + `Invalid idToken: ${(error as Error).message}`, + ); + } + const user = await this.oidcAuthService.validate(tokenSet); + const expiresIn = this.configService.get("jwt.expiresIn"); + const accessToken = this.jwtService.sign(user, { expiresIn }); + await this.postLoginTasks(user); + + return { + access_token: accessToken, + id: accessToken, + expires_in: expiresIn, + ttl: expiresIn, + created: new Date().toISOString(), + userId: user._id, + user: user as ReturnedUserDto, + }; + } + async logout(req: Request) { const logoutURL = this.configService.get("logoutURL") || ""; const expressSessionSecret = this.configService.get( diff --git a/src/auth/dto/idToken.dto.ts b/src/auth/dto/idToken.dto.ts new file mode 100644 index 000000000..7f4a1ac00 --- /dev/null +++ b/src/auth/dto/idToken.dto.ts @@ -0,0 +1,16 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsNotEmpty, IsString } from "class-validator"; + +export class IdTokenDto { + @ApiProperty({ + required: true, + description: + "OpenID Connect ID Token issued by the external identity provider for SciCat user authentication. " + + "The token must contain the user's identity claims (e.g., subject, email, name) and is verified " + + "by the backend to authenticate the user and generate a SciCat JWT access token.", + example: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", + }) + @IsString() + @IsNotEmpty() + readonly idToken: string; +} diff --git a/src/auth/strategies/ldap.strategy.ts b/src/auth/strategies/ldap.strategy.ts index 1aab8bed3..babbbd171 100644 --- a/src/auth/strategies/ldap.strategy.ts +++ b/src/auth/strategies/ldap.strategy.ts @@ -16,7 +16,7 @@ import { LdapConfig } from "src/config/configuration"; @Injectable() export class LdapStrategy extends PassportStrategy(Strategy, "ldap") { constructor( - private configService: ConfigService, + configService: ConfigService, private usersService: UsersService, private accessGroupService: AccessGroupService, ) { diff --git a/src/auth/strategies/local.strategy.ts b/src/auth/strategies/local.strategy.ts index da8452632..dcab0cf03 100644 --- a/src/auth/strategies/local.strategy.ts +++ b/src/auth/strategies/local.strategy.ts @@ -15,7 +15,6 @@ export class LocalStrategy extends PassportStrategy(Strategy) { constructor( private authService: AuthService, private rolesService: RolesService, - //private configService: ConfigService, private usersService: UsersService, private accessGroupService: AccessGroupService, ) { diff --git a/src/auth/strategies/oidc.strategy.ts b/src/auth/strategies/oidc.strategy.ts index 974e36b8a..c19f85a10 100644 --- a/src/auth/strategies/oidc.strategy.ts +++ b/src/auth/strategies/oidc.strategy.ts @@ -1,66 +1,20 @@ -import { - Injectable, - Logger, - InternalServerErrorException, -} from "@nestjs/common"; +import { Injectable } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import { PassportStrategy } from "@nestjs/passport"; -import { FilterQuery } from "mongoose"; -import { CreateUserIdentityDto } from "src/users/dto/create-user-identity.dto"; -import { CreateUserDto } from "src/users/dto/create-user.dto"; -import { User, UserDocument, UserSchema } from "src/users/schemas/user.schema"; -import { UsersService } from "src/users/users.service"; -import { - Strategy, - Client, - TokenSet, - Issuer, - IdTokenClaims, - UserinfoResponse, -} from "openid-client"; -import { AuthService } from "../auth.service"; -import { Profile } from "passport"; -import { UserProfile } from "src/users/schemas/user-profile.schema"; -import { OidcConfig } from "src/config/configuration"; -import { AccessGroupService } from "../access-group-provider/access-group.service"; -import { UserPayload } from "../interfaces/userPayload.interface"; -import { - IOidcUserInfoMapping, - IOidcUserQueryMapping, -} from "../interfaces/oidc-user.interface"; - -type extendedIdTokenClaims = IdTokenClaims & - UserinfoResponse & { - groups?: string[]; - }; -type OidcProfile = Profile & UserProfile; -export class BuildOpenIdClient { - constructor(private configService: ConfigService) {} - async build() { - const oidcConfig = this.configService.get("oidc"); - const trustIssuer = await Issuer.discover( - `${oidcConfig?.issuer}/.well-known/openid-configuration`, - ); - const client = new trustIssuer.Client({ - client_id: oidcConfig?.clientID as string, - client_secret: oidcConfig?.clientSecret as string, - }); - return client; - } -} +import { User } from "src/users/schemas/user.schema"; +import { Strategy, Client, TokenSet } from "openid-client"; +import { OidcConfig } from "src/config/configuration"; +import { OidcAuthService } from "src/common/openid-client/openid-auth.service"; @Injectable() export class OidcStrategy extends PassportStrategy(Strategy, "oidc") { - client: Client; authStrategy = "oidc"; constructor( - private readonly authService: AuthService, client: Client, - private configService: ConfigService, - private usersService: UsersService, - private accessGroupService: AccessGroupService, + configService: ConfigService, + private oidcAuthService: OidcAuthService, ) { const oidcConfig = configService.get("oidc"); super({ @@ -72,195 +26,9 @@ export class OidcStrategy extends PassportStrategy(Strategy, "oidc") { passReqToCallback: false, usePKCE: false, }); - - this.client = client; } async validate(tokenset: TokenSet): Promise> { - const userinfo: extendedIdTokenClaims = tokenset.claims(); - - const oidcConfig = this.configService.get("oidc"); - - const userProfile = this.parseUserInfo(userinfo); - - const userPayload: UserPayload = { - userId: userProfile.id, - username: userProfile.username, - email: userProfile.email, - accessGroupProperty: oidcConfig?.accessGroupProperty, - payload: userinfo, - }; - userProfile.accessGroups = - await this.accessGroupService.getAccessGroups(userPayload); - - const userFilter: FilterQuery = - this.parseQueryFilter(userProfile); - - let user = await this.usersService.findOne(userFilter); - - if (!user) { - const createUser: CreateUserDto = { - username: userProfile.username, - email: userProfile.email as string, - authStrategy: "oidc", - }; - - const newUser = await this.usersService.create(createUser); - if (!newUser) { - throw new InternalServerErrorException( - "Could not create User from OIDC response.", - ); - } - Logger.log("Created oidc user ", newUser.username); - - const createUserIdentity: CreateUserIdentityDto = { - authStrategy: "oidc", - credentials: {}, - externalId: userProfile.id, - profile: userProfile, - provider: userProfile.provider || "oidc", - userId: newUser._id, - }; - - await this.usersService.createUserIdentity(createUserIdentity); - Logger.log("Created user identity for oidc user with id ", newUser._id); - - user = newUser; - } else { - await this.usersService.updateUser( - { username: userProfile.username }, - user._id, - ); - await this.usersService.updateUserIdentity( - { - profile: userProfile, - externalId: userProfile.id, - provider: userProfile.provider || "oidc", - }, - user._id, - ); - } - - const jsonUser = JSON.parse(JSON.stringify(user)); - const { ...returnUser } = jsonUser; - returnUser.userId = returnUser._id; - - return returnUser; - } - - getUserPhoto(thumbnailPhoto: string) { - return thumbnailPhoto - ? "data:image/jpeg;base64," + - Buffer.from(thumbnailPhoto, "binary").toString("base64") - : "no photo"; - } - - parseUserInfo(userinfo: extendedIdTokenClaims) { - const profile = {} as OidcProfile; - - const customUserInfoFields = this.configService.get( - "oidc.userInfoMapping", - ); - - // To dynamically map user info fields based on environment variables, - // set mappings like OIDC_USERINFO_MAPPING_FIELD_USERNAME=family_name. - // This assigns userinfo.family_name to oidcUser.username. - - const oidcUser: IOidcUserInfoMapping = { - id: userinfo["sub"] ?? (userinfo["user_id"] as string) ?? "", - username: userinfo["preferred_username"] ?? userinfo["name"] ?? "", - displayName: userinfo["name"] ?? "", - familyName: userinfo["family_name"] ?? "", - email: userinfo["email"] ?? "", - thumbnailPhoto: (userinfo["thumbnailPhoto"] as string) ?? "", - provider: userinfo["iss"] ?? "", - groups: userinfo["groups"] ?? [], - }; - - if (customUserInfoFields) { - Object.entries(customUserInfoFields).forEach( - ([sourceField, targetField]) => { - if (typeof targetField === "string" && targetField in userinfo) { - oidcUser[sourceField] = userinfo[targetField] as string; - } else if (Array.isArray(targetField) && targetField.length) { - const values = targetField - .filter((field) => field in userinfo) - .map((field) => userinfo[field] as string); - - if (values.length) { - oidcUser[sourceField] = values.join("_"); - } - } - }, - ); - } - - // Prior to OpenID Connect Basic Client Profile 1.0 - draft 22, the "sub" - // claim was named "user_id". Many providers still use the old name, so - // fallback to that. https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims - - if (!oidcUser.id) { - throw new Error("Could not find sub or user_id in userinfo response"); - } - - profile.emails = oidcUser.email ? [{ value: oidcUser.email }] : []; - profile.thumbnailPhoto = this.getUserPhoto(oidcUser.thumbnailPhoto); - profile.oidcClaims = userinfo; - - const oidcUserProfile = { ...oidcUser, ...profile }; - - return oidcUserProfile; - } - - parseQueryFilter(userProfile: OidcProfile) { - const userQuery = - this.configService.get("oidc.userQuery"); - const allowedOperators = ["and", "or"]; - const defaultFilter = - userQuery && allowedOperators.includes(userQuery.operator) - ? { - [`$${userQuery.operator}`]: [ - { username: userProfile.username }, - { email: userProfile.email }, - ], - } - : { - $or: [ - { username: userProfile.username }, - { email: userProfile.email }, - ], - }; - - if ( - !userQuery?.operator || - (userQuery?.filter && userQuery.filter.length < 1) - ) { - return defaultFilter; - } - const operator = "$" + userQuery.operator.toLowerCase(); - const filter = userQuery.filter.reduce( - (acc: Record[], mapping: string) => { - const [filterField, userProfileField] = mapping.split(":"); - if (userProfileField in userProfile && UserSchema.path(filterField)) { - acc.push({ - [filterField]: userProfile[userProfileField as keyof UserProfile], - }); - } - return acc; - }, - [], - ); - - if (filter.length === 0 || !allowedOperators.includes(userQuery.operator)) { - Logger.log( - `Executing default userQuery filter: $${JSON.stringify(defaultFilter)}`, - "OidcStrategy", - ); - return defaultFilter; - } - - const customFilter = { [operator]: filter }; - Logger.log(userQuery, "Executing custom userQuery filter", "OidcStrategy"); - return customFilter; + return this.oidcAuthService.validate(tokenset); } } diff --git a/src/auth/interfaces/oidc-user.interface.ts b/src/common/openid-client/interfaces/oidc-user.interface.ts similarity index 100% rename from src/auth/interfaces/oidc-user.interface.ts rename to src/common/openid-client/interfaces/oidc-user.interface.ts diff --git a/src/common/openid-client/openid-auth.service.ts b/src/common/openid-client/openid-auth.service.ts new file mode 100644 index 000000000..202c029d9 --- /dev/null +++ b/src/common/openid-client/openid-auth.service.ts @@ -0,0 +1,221 @@ +import { + Injectable, + InternalServerErrorException, + Logger, +} from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { IdTokenClaims, TokenSet, UserinfoResponse } from "openid-client"; +import { Profile } from "passport"; +import { OidcConfig } from "src/config/configuration"; +import { UserProfile } from "src/users/schemas/user-profile.schema"; +import { User, UserDocument, UserSchema } from "src/users/schemas/user.schema"; +import { + IOidcUserInfoMapping, + IOidcUserQueryMapping, +} from "./interfaces/oidc-user.interface"; +import { AccessGroupService } from "src/auth/access-group-provider/access-group.service"; +import { UsersService } from "src/users/users.service"; +import { FilterQuery } from "mongoose"; +import { UserPayload } from "src/auth/interfaces/userPayload.interface"; +import { CreateUserIdentityDto } from "src/users/dto/create-user-identity.dto"; +import { CreateUserDto } from "src/users/dto/create-user.dto"; + +export type extendedIdTokenClaims = IdTokenClaims & + UserinfoResponse & { + groups?: string[]; + }; +export type OidcProfile = Profile & UserProfile; + +@Injectable() +export class OidcAuthService { + constructor( + private configService: ConfigService, + private accessGroupService: AccessGroupService, + private usersService: UsersService, + ) {} + + async validate(tokenset: TokenSet): Promise> { + const userinfo: extendedIdTokenClaims = tokenset.claims(); + + const oidcConfig = this.configService.get("oidc"); + + const userProfile = this.parseUserInfo(userinfo); + + const userPayload: UserPayload = { + userId: userProfile.id, + username: userProfile.username, + email: userProfile.email, + accessGroupProperty: oidcConfig?.accessGroupProperty, + payload: userinfo, + }; + userProfile.accessGroups = + await this.accessGroupService.getAccessGroups(userPayload); + + const userFilter: FilterQuery = + this.parseQueryFilter(userProfile); + + let user = await this.usersService.findOne(userFilter); + + if (!user) { + const createUser: CreateUserDto = { + username: userProfile.username, + email: userProfile.email as string, + authStrategy: "oidc", + }; + + const newUser = await this.usersService.create(createUser); + if (!newUser) { + throw new InternalServerErrorException( + "Could not create User from OIDC response.", + ); + } + Logger.log("Created oidc user ", newUser.username); + + const createUserIdentity: CreateUserIdentityDto = { + authStrategy: "oidc", + credentials: {}, + externalId: userProfile.id, + profile: userProfile, + provider: userProfile.provider || "oidc", + userId: newUser._id, + }; + + await this.usersService.createUserIdentity(createUserIdentity); + Logger.log("Created user identity for oidc user with id ", newUser._id); + + user = newUser; + } else { + await this.usersService.updateUser( + { username: userProfile.username }, + user._id, + ); + await this.usersService.updateUserIdentity( + { + profile: userProfile, + externalId: userProfile.id, + provider: userProfile.provider || "oidc", + }, + user._id, + ); + } + + const jsonUser = JSON.parse(JSON.stringify(user)); + const { ...returnUser } = jsonUser; + returnUser.userId = returnUser._id; + + return returnUser; + } + + getUserPhoto(thumbnailPhoto: string) { + return thumbnailPhoto + ? "data:image/jpeg;base64," + + Buffer.from(thumbnailPhoto, "binary").toString("base64") + : "no photo"; + } + + parseUserInfo(userinfo: extendedIdTokenClaims) { + const profile = {} as OidcProfile; + + const customUserInfoFields = this.configService.get( + "oidc.userInfoMapping", + ); + + // To dynamically map user info fields based on environment variables, + // set mappings like OIDC_USERINFO_MAPPING_FIELD_USERNAME=family_name. + // This assigns userinfo.family_name to oidcUser.username. + + const oidcUser: IOidcUserInfoMapping = { + id: userinfo["sub"] ?? (userinfo["user_id"] as string) ?? "", + username: userinfo["preferred_username"] ?? userinfo["name"] ?? "", + displayName: userinfo["name"] ?? "", + familyName: userinfo["family_name"] ?? "", + email: userinfo["email"] ?? "", + thumbnailPhoto: (userinfo["thumbnailPhoto"] as string) ?? "", + provider: userinfo["iss"] ?? "", + groups: userinfo["groups"] ?? [], + }; + + if (customUserInfoFields) { + Object.entries(customUserInfoFields).forEach( + ([sourceField, targetField]) => { + if (typeof targetField === "string" && targetField in userinfo) { + oidcUser[sourceField] = userinfo[targetField] as string; + } else if (Array.isArray(targetField) && targetField.length) { + const values = targetField + .filter((field) => field in userinfo) + .map((field) => userinfo[field] as string); + + if (values.length) { + oidcUser[sourceField] = values.join("_"); + } + } + }, + ); + } + + // Prior to OpenID Connect Basic Client Profile 1.0 - draft 22, the "sub" + // claim was named "user_id". Many providers still use the old name, so + // fallback to that. https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims + + if (!oidcUser.id) { + throw new Error("Could not find sub or user_id in userinfo response"); + } + + profile.emails = oidcUser.email ? [{ value: oidcUser.email }] : []; + profile.thumbnailPhoto = this.getUserPhoto(oidcUser.thumbnailPhoto); + profile.oidcClaims = userinfo; + + const oidcUserProfile = { ...oidcUser, ...profile }; + + return oidcUserProfile; + } + + parseQueryFilter(userProfile: OidcProfile) { + const userQuery = + this.configService.get("oidc.userQuery"); + const allowedOperators = ["and", "or"]; + const defaultFilter = + userQuery && allowedOperators.includes(userQuery.operator) + ? { + [`$${userQuery.operator}`]: [ + { username: userProfile.username }, + { email: userProfile.email }, + ], + } + : { + $or: [ + { username: userProfile.username }, + { email: userProfile.email }, + ], + }; + + if (!userQuery?.operator || !userQuery.filter.length) { + return defaultFilter; + } + const operator = "$" + userQuery.operator.toLowerCase(); + const filter = userQuery.filter.reduce( + (acc: Record[], mapping: string) => { + const [filterField, userProfileField] = mapping.split(":"); + if (userProfileField in userProfile && UserSchema.path(filterField)) { + acc.push({ + [filterField]: userProfile[userProfileField as keyof UserProfile], + }); + } + return acc; + }, + [], + ); + + if (filter.length === 0 || !allowedOperators.includes(userQuery.operator)) { + Logger.log( + `Executing default userQuery filter: $${JSON.stringify(defaultFilter)}`, + "OidcStrategy", + ); + return defaultFilter; + } + + const customFilter = { [operator]: filter }; + Logger.log(userQuery, "Executing custom userQuery filter", "OidcStrategy"); + return customFilter; + } +} diff --git a/src/common/openid-client/openid-client.module.ts b/src/common/openid-client/openid-client.module.ts new file mode 100644 index 000000000..30e2ac741 --- /dev/null +++ b/src/common/openid-client/openid-client.module.ts @@ -0,0 +1,14 @@ +import { Global } from "@nestjs/common"; +import { Module } from "@nestjs/common"; +import { OidcClientService } from "./openid-client.service"; +import { accessGroupServiceFactory } from "src/auth/access-group-provider/access-group-service-factory"; +import { UsersModule } from "src/users/users.module"; +import { OidcAuthService } from "./openid-auth.service"; + +@Global() +@Module({ + imports: [UsersModule], + providers: [OidcClientService, OidcAuthService, accessGroupServiceFactory], + exports: [OidcClientService, OidcAuthService], +}) +export class OidcClientModule {} diff --git a/src/common/openid-client/openid-client.service.ts b/src/common/openid-client/openid-client.service.ts new file mode 100644 index 000000000..da5d3f370 --- /dev/null +++ b/src/common/openid-client/openid-client.service.ts @@ -0,0 +1,57 @@ +import { Injectable } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { + Client, + IdTokenClaims, + Issuer, + UserinfoResponse, + custom, +} from "openid-client"; +import { Profile } from "passport"; +import { OidcConfig } from "src/config/configuration"; +import { UserProfile } from "src/users/schemas/user-profile.schema"; + +export type extendedIdTokenClaims = IdTokenClaims & + UserinfoResponse & { + groups?: string[]; + }; +export type OidcProfile = Profile & UserProfile; + +@Injectable() +export class OidcClientService { + private client: Client | null = null; + private oidcConfig?: OidcConfig; + + constructor(private configService: ConfigService) { + this.oidcConfig = this.configService.get("oidc"); + + // Set a reasonable timeout for HTTP requests made by the openid-client library + custom.setHttpOptionsDefaults({ + timeout: 7000, + }); + } + + async getClient(): Promise { + if (this.client) return this.client; + + if (!this.oidcConfig?.clientID) { + throw new Error("OIDC clientID not defined in the configuration."); + } + try { + const issuer = await Issuer.discover( + `${this.oidcConfig.issuer}/.well-known/openid-configuration`, + ); + + this.client = new issuer.Client({ + client_id: this.oidcConfig.clientID, + client_secret: this.oidcConfig.clientSecret, + }); + + return this.client; + } catch (err) { + throw new Error( + `OIDC issuer discovery failed: ${err instanceof Error ? err.message : err}`, + ); + } + } +} From b6c2e7a6c2eff0fc1286ebfadd401b4af052bda3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:30:54 +0000 Subject: [PATCH 036/120] 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.54.0 to 8.56.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.56.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.56.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 160 +++++++++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index a24cbeff4..d83e8015e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3758,17 +3758,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", - "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", + "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/type-utils": "8.54.0", - "@typescript-eslint/utils": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/type-utils": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3781,8 +3781,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.54.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -3797,16 +3797,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", - "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", + "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3" }, "engines": { @@ -3817,19 +3817,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", - "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.54.0", - "@typescript-eslint/types": "^8.54.0", + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", "debug": "^4.4.3" }, "engines": { @@ -3844,14 +3844,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", - "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3862,9 +3862,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", - "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", "dev": true, "license": "MIT", "engines": { @@ -3879,15 +3879,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", - "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", + "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3899,14 +3899,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", - "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -3918,16 +3918,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", - "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.54.0", - "@typescript-eslint/tsconfig-utils": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -3945,24 +3945,37 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/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/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", + "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -3972,16 +3985,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", - "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3991,19 +4004,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", - "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4013,6 +4026,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/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/@ucast/core": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz", From 29156fd1a3f82dc7d8f460bce240fe74bc2d605b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:42:33 +0000 Subject: [PATCH 037/120] build(deps-dev): bump wait-on from 9.0.3 to 9.0.4 Bumps [wait-on](https://github.com/jeffbski/wait-on) from 9.0.3 to 9.0.4. - [Release notes](https://github.com/jeffbski/wait-on/releases) - [Commits](https://github.com/jeffbski/wait-on/compare/v9.0.3...v9.0.4) --- updated-dependencies: - dependency-name: wait-on dependency-version: 9.0.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index d83e8015e..9e1777d74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1315,9 +1315,9 @@ "license": "BSD-3-Clause" }, "node_modules/@hapi/tlds": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.3.tgz", - "integrity": "sha512-QIvUMB5VZ8HMLZF9A2oWr3AFM430QC8oGd0L35y2jHpuW6bIIca6x/xL7zUf4J7L9WJ3qjz+iJII8ncaeMbpSg==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.6.tgz", + "integrity": "sha512-xdi7A/4NZokvV0ewovme3aUO5kQhW9pQ2YD1hRqZGhhSi5rBv4usHYidVocXSi9eihYsznZxLtAiEYYUL6VBGw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -3156,9 +3156,9 @@ } }, "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, @@ -9303,9 +9303,9 @@ } }, "node_modules/joi": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.0.1.tgz", - "integrity": "sha512-IiQpRyypSnLisQf3PwuN2eIHAsAIGZIrLZkd4zdvIar2bDyhM91ubRjy8a3eYablXsh9BeI/c7dmPYHca5qtoA==", + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-18.0.2.tgz", + "integrity": "sha512-RuCOQMIt78LWnktPoeBL0GErkNaJPTBGcYuyaBvUOQSpcpcLfWrHPPihYdOGbV5pam9VTWbeoF7TsGiHugcjGA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -14387,15 +14387,15 @@ } }, "node_modules/wait-on": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-9.0.3.tgz", - "integrity": "sha512-13zBnyYvFDW1rBvWiJ6Av3ymAaq8EDQuvxZnPIw3g04UqGi4TyoIJABmfJ6zrvKo9yeFQExNkOk7idQbDJcuKA==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-9.0.4.tgz", + "integrity": "sha512-k8qrgfwrPVJXTeFY8tl6BxVHiclK11u72DVKhpybHfUL/K6KM4bdyK9EhIVYGytB5MJe/3lq4Tf0hrjM+pvJZQ==", "dev": true, "license": "MIT", "dependencies": { - "axios": "^1.13.2", - "joi": "^18.0.1", - "lodash": "^4.17.21", + "axios": "^1.13.5", + "joi": "^18.0.2", + "lodash": "^4.17.23", "minimist": "^1.2.8", "rxjs": "^7.8.2" }, From b9f6ab100de9ff0c9952db16b49bc7b4e18fb7ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:53:42 +0000 Subject: [PATCH 038/120] build(deps-dev): bump @types/nodemailer from 7.0.10 to 7.0.11 Bumps [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer) from 7.0.10 to 7.0.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer) --- updated-dependencies: - dependency-name: "@types/nodemailer" dependency-version: 7.0.11 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e1777d74..4b91c16ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3589,9 +3589,9 @@ } }, "node_modules/@types/nodemailer": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.10.tgz", - "integrity": "sha512-tP+9WggTFN22Zxh0XFyst7239H0qwiRCogsk7v9aQS79sYAJY+WEbTHbNYcxUMaalHKmsNpxmoTe35hBEMMd6g==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.11.tgz", + "integrity": "sha512-E+U4RzR2dKrx+u3N4DlsmLaDC6mMZOM/TPROxA0UAPiTgI0y4CEFBmZE+coGWTjakDriRsXG368lNk1u9Q0a2g==", "dev": true, "license": "MIT", "dependencies": { From 77f84dac630c9088aa2d17cfe6de255f56ded948 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:05:17 +0000 Subject: [PATCH 039/120] build(deps-dev): bump @stylistic/eslint-plugin from 5.7.1 to 5.9.0 Bumps [@stylistic/eslint-plugin](https://github.com/eslint-stylistic/eslint-stylistic/tree/HEAD/packages/eslint-plugin) from 5.7.1 to 5.9.0. - [Release notes](https://github.com/eslint-stylistic/eslint-stylistic/releases) - [Changelog](https://github.com/eslint-stylistic/eslint-stylistic/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint-stylistic/eslint-stylistic/commits/v5.9.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@stylistic/eslint-plugin" dependency-version: 5.9.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b91c16ab..e886a6594 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3163,14 +3163,14 @@ "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.7.1.tgz", - "integrity": "sha512-zjTUwIsEfT+k9BmXwq1QEFYsb4afBlsI1AXFyWQBgggMzwBFOuu92pGrE5OFx90IOjNl+lUbQoTG7f8S0PkOdg==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.9.0.tgz", + "integrity": "sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/types": "^8.53.1", + "@typescript-eslint/types": "^8.56.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "estraverse": "^5.3.0", @@ -3180,7 +3180,7 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "eslint": ">=9.0.0" + "eslint": "^9.0.0 || ^10.0.0" } }, "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { From e11f10574ebce124772222681ba0b3f3c4c95637 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:16:49 +0000 Subject: [PATCH 040/120] build(deps): bump rimraf from 6.1.2 to 6.1.3 Bumps [rimraf](https://github.com/isaacs/rimraf) from 6.1.2 to 6.1.3. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v6.1.2...v6.1.3) --- updated-dependencies: - dependency-name: rimraf dependency-version: 6.1.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 78 +++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index e886a6594..cdb6739a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1749,6 +1749,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, "license": "MIT", "engines": { "node": "20 || >=22" @@ -1758,6 +1759,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", + "dev": true, "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" @@ -10298,9 +10300,10 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -12435,12 +12438,12 @@ "dev": true }, "node_modules/rimraf": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", - "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^13.0.0", + "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { @@ -12453,58 +12456,79 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/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==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/rimraf/node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rimraf/node_modules/lru-cache": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", - "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", - "license": "ISC", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", + "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rimraf/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" From 159a39482557714cd9e4843044824208ba1c9103 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:28:46 +0000 Subject: [PATCH 041/120] build(deps): bump the nestjs group with 3 updates Bumps the nestjs group with 3 updates: [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express), [@nestjs/terminus](https://github.com/nestjs/terminus) and [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing). Updates `@nestjs/platform-express` from 11.1.13 to 11.1.14 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.14/packages/platform-express) Updates `@nestjs/terminus` from 11.0.0 to 11.1.1 - [Release notes](https://github.com/nestjs/terminus/releases) - [Changelog](https://github.com/nestjs/terminus/blob/master/CHANGELOG.md) - [Commits](https://github.com/nestjs/terminus/compare/11.0.0...11.1.1) Updates `@nestjs/testing` from 11.1.13 to 11.1.14 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.14/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-version: 11.1.14 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/terminus" dependency-version: 11.1.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nestjs - dependency-name: "@nestjs/testing" dependency-version: 11.1.14 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index cdb6739a5..344432f33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2745,9 +2745,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.13", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.13.tgz", - "integrity": "sha512-LYmi43BrAs1n74kLCUfXcHag7s1CmGETcFbf9IVyA/KWXAuAH95G3wEaZZiyabOLFNwq4ifnRGnIwUwW7cz3+w==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.14.tgz", + "integrity": "sha512-Fs+/j+mBSBSXErOQJ/YdUn/HqJGSJ4pGfiJyYOyz04l42uNVnqEakvu1kXLbxMabR6vd6/h9d6Bi4tso9p7o4Q==", "license": "MIT", "dependencies": { "cors": "2.8.6", @@ -2910,9 +2910,10 @@ } }, "node_modules/@nestjs/terminus": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-11.0.0.tgz", - "integrity": "sha512-c55LOo9YGovmQHtFUMa/vDaxGZ2cglMTZejqgHREaApt/GArTfgYYGwhRXPLq8ZwiQQlLuYB+79e9iA8mlDSLA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-11.1.1.tgz", + "integrity": "sha512-Ssql79H+EQY/Wg108eJqN4NiNsO/tLrj+qbzOWSQUf2JE4vJQ2RG3WTqUOrYjfjWmVHD3+Ys0+azed7LSMKScw==", + "license": "MIT", "dependencies": { "boxen": "5.1.2", "check-disk-space": "3.4.0" @@ -2979,9 +2980,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "11.1.13", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.13.tgz", - "integrity": "sha512-bOWP8nLEZAOEEX8jAZGBCc1yU0+nv4g2ipc+QEzkVUe3eEEUKHKaeGafJ3GtDuGavlZKfkXEqflZuICdavu5dQ==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.14.tgz", + "integrity": "sha512-cQxX0ronsTbpfHz8/LYOVWXxoTxv6VoxrnuZoQaVX7QV2PSMqxWE7/9jSQR0GcqAFUEmFP34c6EJqfkjfX/k4Q==", "dev": true, "license": "MIT", "dependencies": { From 0a4d86dd771f7ed0b0b5f6d50907efa29fb055b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 04:39:28 +0000 Subject: [PATCH 042/120] build(deps): bump bn.js from 4.12.2 to 4.12.3 Bumps [bn.js](https://github.com/indutny/bn.js) from 4.12.2 to 4.12.3. - [Release notes](https://github.com/indutny/bn.js/releases) - [Changelog](https://github.com/indutny/bn.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/indutny/bn.js/compare/v4.12.2...v4.12.3) --- updated-dependencies: - dependency-name: bn.js dependency-version: 4.12.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 344432f33..80c1869f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5130,9 +5130,9 @@ } }, "node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", "license": "MIT" }, "node_modules/body-parser": { From 0a4255adaa224b5ee189b1ea641377a3580b2d94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 04:49:54 +0000 Subject: [PATCH 043/120] build(deps-dev): bump minimatch from 3.1.2 to 3.1.4 Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.1.2 to 3.1.4. - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.4) --- updated-dependencies: - dependency-name: minimatch dependency-version: 3.1.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 203 +++++++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 73 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80c1869f1..5ff0109cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1745,29 +1745,6 @@ } } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", - "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2512,6 +2489,29 @@ } } }, + "node_modules/@nestjs/cli/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/@nestjs/cli/node_modules/brace-expansion": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@nestjs/cli/node_modules/glob": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", @@ -2541,16 +2541,16 @@ } }, "node_modules/@nestjs/cli/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", + "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3972,9 +3972,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", - "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "license": "ISC", "dependencies": { @@ -5055,7 +5055,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -7359,9 +7360,10 @@ } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", + "license": "ISC", "optional": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -7871,21 +7873,34 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/glob/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==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -9362,14 +9377,27 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/js-beautify/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==", + "license": "MIT", + "optional": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/js-beautify/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "license": "MIT", "optional": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/js-beautify/node_modules/glob": { @@ -9408,12 +9436,13 @@ } }, "node_modules/js-beautify/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "license": "ISC", "optional": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -10281,10 +10310,11 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "devOptional": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -10393,14 +10423,27 @@ "mjml-cli": "bin/mjml" } }, + "node_modules/mjml-cli/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==", + "license": "MIT", + "optional": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/mjml-cli/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "license": "MIT", "optional": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/mjml-cli/node_modules/chokidar": { @@ -10440,12 +10483,13 @@ } }, "node_modules/mjml-cli/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "license": "ISC", "optional": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -10868,14 +10912,27 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/mocha/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/mocha/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/mocha/node_modules/glob": { @@ -10914,13 +10971,13 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -12505,9 +12562,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", - "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", + "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" From 391bdaef71e7e554b259068c429d3cf124f2f6f9 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 2 Mar 2026 15:17:59 +0100 Subject: [PATCH 044/120] fix: update ESLint rules and fix malfunctioning unit test for attachment v4 controller (#2568) * fix: update ESLint rules and fix malfunctioning unit test for attachment v4 controller * partially fix es lint error & skips lint check for test files * remove unnecessary job step --- eslint.config.mjs | 4 +- package.json | 4 +- .../attachments.v4.controller.spec.ts | 56 +++++++++++-------- src/casl/casl-ability.factory.ts | 1 + 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 7262a459b..45f098bf3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -73,8 +73,8 @@ export default [ ], "@typescript-eslint/no-unused-vars": [ - "warn", - { "argsIgnorePattern": "^_" }, + "error", + { argsIgnorePattern: "^_" }, ], }, }, diff --git a/package.json b/package.json index 454031ca3..7d9412641 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,8 @@ "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "start:test": "dotenv -o -e test/config/.env -e test/config/.env.override -- npm run start", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"", - "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "lint": "eslint \"src/**/*.ts\"", + "lint:fix": "eslint \"src/**/*.ts\" \"test/**/*.js\" --fix", "test": "jest", "test:watch": "jest --watch --maxWorkers=25%", "test:cov": "jest --coverage --maxWorkers=50%", diff --git a/src/attachments/attachments.v4.controller.spec.ts b/src/attachments/attachments.v4.controller.spec.ts index df06a21e7..97632a30f 100644 --- a/src/attachments/attachments.v4.controller.spec.ts +++ b/src/attachments/attachments.v4.controller.spec.ts @@ -7,6 +7,7 @@ import { Attachment } from "./schemas/attachment.schema"; import * as jmp from "json-merge-patch"; import { CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; +import { Request } from "express"; describe("AttachmentsController - findOneAndUpdate", () => { let controller: AttachmentsV4Controller; @@ -14,15 +15,22 @@ describe("AttachmentsController - findOneAndUpdate", () => { const mockAttachment: Attachment = { _id: "123", - name: "Test Attachment", - description: "Initial", + aid: "aid-123", + ownerGroup: "group1", + accessGroups: ["group1"], + isPublished: false, + thumbnail: "Test Attachment", + caption: "Test Caption", + createdBy: "user1", + updatedBy: "user1", + createdAt: new Date("2025-08-01T10:00:00Z"), updatedAt: new Date("2025-09-01T10:00:00Z"), // other fields... }; const mockUpdatedAttachment = { ...mockAttachment, - description: "Updated", + caption: "Updated", }; const mockCaslAbilityFactory = { @@ -31,10 +39,6 @@ describe("AttachmentsController - findOneAndUpdate", () => { }), }; - const mockAttachmentsV4Service = { - findOneAndUpdate: jest.fn(), - }; - beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [AttachmentsV4Controller], @@ -60,25 +64,30 @@ describe("AttachmentsController - findOneAndUpdate", () => { // Mock permission check jest - .spyOn(controller, "checkPermissionsForAttachment") + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .spyOn(controller as any, "checkPermissionsForAttachment") .mockResolvedValue(mockAttachment); }); it("should update attachment with application/json", async () => { - const dto: PartialUpdateAttachmentV4Dto = { description: "Updated" }; - const headers = { "content-type": "application/json" }; + const dto: PartialUpdateAttachmentV4Dto = { caption: "Updated" }; - const result = await controller.findOneAndUpdate({ headers }, "123", dto); + const req = { + headers: { "content-type": "application/json" }, + } as Partial as Request; + const result = await controller.findOneAndUpdate(req, "123", dto); expect(result).toEqual(mockUpdatedAttachment); expect(service.findOneAndUpdate).toHaveBeenCalledWith({ _id: "123" }, dto); }); it("should update attachment with application/merge-patch+json", async () => { - const dto = { description: null }; - const headers = { "content-type": "application/merge-patch+json" }; + const dto = { caption: "Updated" }; + const req = { + headers: { "content-type": "application/merge-patch+json" }, + } as Partial as Request; - await controller.findOneAndUpdate({ headers }, "123", dto); + await controller.findOneAndUpdate(req, "123", dto); const expectedPatched = jmp.apply(mockAttachment, dto); expect(service.findOneAndUpdate).toHaveBeenCalledWith( @@ -88,15 +97,16 @@ describe("AttachmentsController - findOneAndUpdate", () => { }); it("should throw PRECONDITION_FAILED if If-Unmodified-Since is older than updatedAt", async () => { - const dto = { name: "Should Fail" }; - const headers = { - "content-type": "application/json", - "if-unmodified-since": "2000-01-01T00:00:00Z", - }; - - await expect( - controller.findOneAndUpdate({ headers }, "123", dto), - ).rejects.toThrow( + const dto = { caption: "Should Fail" }; + + const req = { + headers: { + "content-type": "application/json", + "if-unmodified-since": "2000-01-01T00:00:00Z", + }, + } as Partial as Request; + + await expect(controller.findOneAndUpdate(req, "123", dto)).rejects.toThrow( new HttpException( "Resource has been modified on server", HttpStatus.PRECONDITION_FAILED, diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 43cd16da7..3da7cf5ca 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -938,6 +938,7 @@ export class CaslAbilityFactory { }); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars metadataKeysEndpointAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, From 56d2c02a585dbe49c66a3b03962436d478eeff67 Mon Sep 17 00:00:00 2001 From: abdimo101 Date: Mon, 2 Mar 2026 15:27:28 +0100 Subject: [PATCH 045/120] docs(frontend-config): update frontend config documentation (#2535) * update frontend config option descriptions and mark deprecated options * added options related to detailed documentations --- docs/frontend-config-guide/frontend-config.md | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/docs/frontend-config-guide/frontend-config.md b/docs/frontend-config-guide/frontend-config.md index 832dc90a8..6c4940674 100644 --- a/docs/frontend-config-guide/frontend-config.md +++ b/docs/frontend-config-guide/frontend-config.md @@ -4,8 +4,6 @@ This guide documents frontend configuration options that control various UI behaviors and features in SciCat. These settings are defined in the configuration file specified by the `FRONTEND_CONFIG_FILE` environment variable (default `src/config/frontend.config.json`). -**TODO:** Many of these configuration options were added a long time ago and may no longer be in use. This documentation should be reviewed and updated to reflect the current state of the application and remove obsolete configuration flags. - ## Configuration Options | **Configuration Options** | **Type** | **Default Value** | **Description** | @@ -17,24 +15,24 @@ This guide documents frontend configuration options that control various UI beha | `accessTokenPrefix` | string | `"Bearer "` | Set the backend token prefix. Should be empty string for old backend or "Bearer " if using scicat-backend-next. | | `addDatasetEnabled` | boolean | `false` | Show/hide the "Create Dataset" button in the Datasets Dashboard. | | `archiveWorkflowEnabled` | boolean | `false` | Enable/disable the archive/retrieve workflow. | -| `datasetReduceEnabled` | boolean | `true` | Enable/disable the automatic Dataset reduction/analysis workflow. | -| `datasetJsonScientificMetadata` | boolean | `true` | | -| `editDatasetEnabled` | boolean | `true` | | -| `editDatasetSampleEnabled` | boolean | `true` | Enable/disable editing of which Sample a Dataset belongs to. | +| `datasetReduceEnabled` | boolean | `true` | Show/hide the "Reduce" tab. | +| `datasetJsonScientificMetadata` | boolean | `true` | Show/hide the "Scientific Metadata (JSON)" tab. | +| `editDatasetEnabled` | boolean | `true` | Show/hide the "Edit" buttons in the Datasets Details page | +| `editDatasetSampleEnabled` | boolean | `true` | **Deprecated** Enable/disable editing of which Sample a Dataset belongs to. | | `editMetadataEnabled` | boolean | `true` | Enable/disable editing of Scientific Metadata. | -| `addSampleEnabled` | boolean | `false` | | +| `addSampleEnabled` | boolean | `false` | Show/hide the "Create Sample" button in the Sample Dashboard | | `externalAuthEndpoint` | string | `"/api/v3/auth/msad"` | Endpoint used for third party authentication, e.g., LDAP. | | `facility` | string | `"SciCat Vanilla"` | Facility running the SciCat instance. | -| `siteIcon` | string | `""` | Path to the site icon/logo image file. | -| `siteTitle` | string | `""` | Title displayed in the browser tab and header. | -| `siteSciCatLogo` | string | `"full"` | | +| `siteIcon` | string | `""` | **Deprecated** Path to the site icon/logo image file. | +| `siteTitle` | string | `""` | Title displayed in the header. | +| `siteSciCatLogo` | string | `""` | **Deprecated** Set to `"icon"` for icon-only display; full logo shown otherwise. | | `loginFacilityLabel` | string | `""` | Label for the facility login option. | | `loginLdapLabel` | string | `""` | Label for the LDAP login option. | | `loginLocalLabel` | string | `""` | Label for the local login option. | | `loginFacilityEnabled` | boolean | `true` | Enable/disable facility login option. | | `loginLdapEnabled` | boolean | `true` | Enable/disable LDAP login option. | -| `loginLocalEnabled` | boolean | `true` | Enable/disable local login option. | -| `fileColorEnabled` | boolean | `true` | Enable/disable file size color representation in the Datasets Dashboard. | +| `loginLocalEnabled` | boolean | `true` | **Deprecated** Enable/disable local login option. | +| `fileColorEnabled` | boolean | `true` | **Deprecated** Enable/disable file size color representation in the Datasets Dashboard. | | `fileDownloadEnabled` | boolean | `true` | Enable/disable download workflow for Dataset datafiles. | | `gettingStarted` | string | `null` | URL to Getting Started guide for SciCat, displayed on the Help page. | | `ingestManual` | string | `null` | URL to Ingest Manual for SciCat, displayed on the Help page. | @@ -55,7 +53,7 @@ This guide documents frontend configuration options that control various UI beha | `riotBaseUrl` | string | `""` | URL to SciChat client. | | `scienceSearchEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata. | | `scienceSearchUnitsEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata using units. | -| `searchPublicDataEnabled` | boolean | `true` | Enable/disable filtering Datasets on public or non-public data. | +| `searchPublicDataEnabled` | boolean | `true` | **Deprecated** Enable/disable filtering Datasets on public or non-public data. | | `searchSamples` | boolean | `true` | Enable/disable searching Samples on Samples Dashboard. | | `sftpHost` | string | `""` | URL to SFTP service used for downloading files exceeding maximum allowed file size. | | `sourceFolder` | string | `""` | Default source folder path for datasets. | @@ -65,14 +63,17 @@ This guide documents frontend configuration options that control various UI beha | `shoppingCartEnabled` | boolean | `true` | Enable/disable the Dataset cart used for bulk actions. | | `shoppingCartOnHeader` | boolean | `true` | Toggle Dataset cart placement, either on header or to the left on the Datasets Dashboard. | | `tableSciDataEnabled` | boolean | `true` | Enable/disable Scientific Metadata table view on details pages. If disabled, Scientific Metadata is displayed as raw JSON. | -| `datasetDetailsShowMissingProposalId` | boolean | `false` | | -| `notificationInterceptorEnabled` | boolean | `true` | | -| `metadataEditingUnitListDisabled` | boolean | `true` | | -| `hideEmptyMetadataTable` | boolean | `false` | | +| `datasetDetailsShowMissingProposalId` | boolean | `false` | Show/hide the ProposalId property even when the proposal no longer exists | +| `notificationInterceptorEnabled` | boolean | `true` | Enable/disable a snackbar when creating, updating or deleting entities | +| `metadataEditingUnitListDisabled` | boolean | `true` | Enable/disable the unitlist dropdown in metadata edit view | +| `hideEmptyMetadataTable` | boolean | `false` | Show/hide metadata tables when it is empty | | `datafilesActionsEnabled` | boolean | `true` | Enable/disable custom datafile actions configuration. | | `datafilesActions` | array | `[]` | Array of custom action configurations for datafiles. Each action can define download, notebook generation, or other custom behaviors. | +| `defaultDatasetsListSettings` | object | `{}` | Configuration for datasets list columns, filters, and conditions. **Detailed documentation:** [Default List Settings Configuration](./default-list-settings.md) | +| `defaultProposalsListSettings` | object | `{}` | Configuration for proposals list columns and filters. **Detailed documentation:** [Default List Settings Configuration](./default-list-settings.md) | | `labelsLocalization` | object | `{}` | Localization configuration for labels in datasets and proposals. Maps field names to display labels. | | `dateFormat` | string | `"yyyy-MM-dd HH:mm"` | Default date format used throughout the application. | +| `datasetDetailComponent` | object | `{}` | Configuration for customizing the dataset detail page layout and components. **Detailed documentation:** [Dynamic Dataset Detail Component Configuration](./dynamic-dataset-detail-component.md) | | **`mainMenu`** | object | | Configuration for main menu visibility based on user authentication status. | |     **`nonAuthenticatedUser`** | object | | Menu configuration for non-authenticated users. | |         `datasets` | boolean | `true` | Show/hide datasets menu item. | @@ -93,9 +94,4 @@ This guide documents frontend configuration options that control various UI beha |         `publishedData` | boolean | `true` | Show/hide published data menu item. | |         `samples` | boolean | `true` | Show/hide samples menu item. | | **`defaultTab`** | object | | Specifies which tab is shown by default when viewing different entities. | -|     `proposal` | string | `"details"` | Default tab for proposals. Valid values: `"details"`, `"datasets"`, `"relatedProposals"`, `"logbook"`. | - -## See Also - -- [Default List Settings Configuration](./default-list-settings.md) -- [Dynamic Dataset Detail Component Configuration](./dynamic-dataset-detail-component.md) \ No newline at end of file +|     `proposal` | string | `"details"` | Default tab for proposals. Valid values: `"details"`, `"datasets"`, `"relatedProposals"`, `"logbook"`. | \ No newline at end of file From c05e68f1322b0e990740550cf3db211011443d58 Mon Sep 17 00:00:00 2001 From: fpotier <58594145+fpotier@users.noreply.github.com> Date: Mon, 2 Mar 2026 15:58:04 +0100 Subject: [PATCH 046/120] ci: only pull ES image if enabled (#2567) --- .github/workflows/test.yml | 1 + CI/ESS/docker-compose.api.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 33221bfdb..48931c943 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -131,6 +131,7 @@ jobs: - name: API tests env: ELASTICSEARCH_ENABLED: ${{ matrix.elasticsearch_enabled }} + COMPOSE_PROFILES: ${{ matrix.elasticsearch_enabled == 'yes' && 'elasticsearch' || ''}} CLUSTER_NAME: es-cluster ES_PASSWORD: duo-password MEM_LIMIT: 4G diff --git a/CI/ESS/docker-compose.api.yaml b/CI/ESS/docker-compose.api.yaml index c8c0d2e47..f969b2e09 100644 --- a/CI/ESS/docker-compose.api.yaml +++ b/CI/ESS/docker-compose.api.yaml @@ -6,6 +6,8 @@ services: ports: - "27017:27017" es01: + profiles: + - elasticsearch depends_on: - mongodb image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} From e9c851806a43b785de142c2027b446d8151ad314 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:36:06 +0000 Subject: [PATCH 047/120] build(deps-dev): bump @eslint/eslintrc from 3.3.3 to 3.3.4 Bumps [@eslint/eslintrc](https://github.com/eslint/eslintrc) from 3.3.3 to 3.3.4. - [Release notes](https://github.com/eslint/eslintrc/releases) - [Changelog](https://github.com/eslint/eslintrc/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslintrc/compare/eslintrc-v3.3.3...eslintrc-v3.3.4) --- updated-dependencies: - dependency-name: "@eslint/eslintrc" dependency-version: 3.3.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5ff0109cc..0725a7657 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1169,20 +1169,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", + "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.3", "strip-json-comments": "^3.1.1" }, "engines": { @@ -1193,10 +1193,11 @@ } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1224,7 +1225,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@eslint/js": { "version": "9.39.2", From bfe7435099531fdf78728dff18ba3d3c0ef8e2ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:46:39 +0000 Subject: [PATCH 048/120] build(deps-dev): bump @types/lodash from 4.17.23 to 4.17.24 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.23 to 4.17.24. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-version: 4.17.24 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0725a7657..408c6ad9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3521,9 +3521,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==", + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", "dev": true, "license": "MIT" }, From dea86069c9a8efe9b63430879d979c34ef2f4aac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:58:02 +0000 Subject: [PATCH 049/120] build(deps-dev): bump @types/node from 25.2.0 to 25.3.3 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.2.0 to 25.3.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.3.3 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 408c6ad9c..5bd4be344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3574,12 +3574,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", - "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/node-fetch": { @@ -14229,9 +14229,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "license": "MIT" }, "node_modules/universalify": { From 938c547ca9fb9b01778c17e5f1834b162dd1e8bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:09:36 +0000 Subject: [PATCH 050/120] 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.56.0 to 8.56.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 126 +++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5bd4be344..49463e889 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3763,17 +3763,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", - "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/type-utils": "8.56.0", - "@typescript-eslint/utils": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3786,7 +3786,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.0", + "@typescript-eslint/parser": "^8.56.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3802,16 +3802,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", - "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "engines": { @@ -3827,14 +3827,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -3849,14 +3849,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3867,9 +3867,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -3884,15 +3884,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", - "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3909,9 +3909,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", "engines": { @@ -3923,18 +3923,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -3961,9 +3961,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { @@ -3974,32 +3974,32 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4014,13 +4014,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.56.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { From 091d60fd1d7fe7ffd4d5b76a6db2a3520a89b83b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:20:33 +0000 Subject: [PATCH 051/120] build(deps-dev): bump globals from 17.3.0 to 17.4.0 Bumps [globals](https://github.com/sindresorhus/globals) from 17.3.0 to 17.4.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v17.3.0...v17.4.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.4.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 49463e889..49f911857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7912,9 +7912,9 @@ } }, "node_modules/globals": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", - "integrity": "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", "dev": true, "license": "MIT", "engines": { From bc77219a96771db52352edf9f1ac21548dc1d988 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:27:40 +0000 Subject: [PATCH 052/120] build(deps): bump actions/upload-artifact from 6 to 7 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release-and-publish-sdk.yml | 4 ++-- .github/workflows/upload-sdk-artifact.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 9de500d47..b586f7a52 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -146,7 +146,7 @@ jobs: - name: Download the Swagger schema run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: swagger-schema-${{ github.sha }} path: ./swagger-schema.json @@ -187,7 +187,7 @@ jobs: fi ) - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: sdk-${{ matrix.generator }}-${{ github.sha }} path: ./sdk diff --git a/.github/workflows/upload-sdk-artifact.yml b/.github/workflows/upload-sdk-artifact.yml index 843cfd565..146e81f61 100644 --- a/.github/workflows/upload-sdk-artifact.yml +++ b/.github/workflows/upload-sdk-artifact.yml @@ -43,7 +43,7 @@ jobs: - name: Download the Swagger schema run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: swagger-schema-${{ github.sha }} path: ./swagger-schema.json @@ -81,7 +81,7 @@ jobs: fi ) - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 if: github.event_name == 'push' with: name: sdk-${{ matrix.generator }}-${{ github.sha }} From 586a9a366f9fe0374ccdcb80f42c3bc67b298367 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:37:18 +0000 Subject: [PATCH 053/120] build(deps): bump actions/download-artifact from 7 to 8 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release-and-publish-sdk.yml | 6 +++--- .github/workflows/upload-sdk-artifact.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index b586f7a52..c86d55a30 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -164,7 +164,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: swagger-schema-${{ github.sha }} path: . @@ -213,7 +213,7 @@ jobs: registry-url: "https://registry.npmjs.org/" - name: Download TypeScript SDK Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: sdk-${{ matrix.sdk_type }}-${{ github.sha }} path: ./sdk @@ -253,7 +253,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Download Python SDK Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: sdk-${{ matrix.sdk_type }}-${{ github.sha }} path: ./sdk diff --git a/.github/workflows/upload-sdk-artifact.yml b/.github/workflows/upload-sdk-artifact.yml index 146e81f61..b219dcbda 100644 --- a/.github/workflows/upload-sdk-artifact.yml +++ b/.github/workflows/upload-sdk-artifact.yml @@ -60,7 +60,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: swagger-schema-${{ github.sha }} path: . From 3489e58ff4bec0deb26bc2e12cab5c3e03a19202 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:51:33 +0000 Subject: [PATCH 054/120] build(deps-dev): bump @types/supertest from 6.0.3 to 7.2.0 Bumps [@types/supertest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest) from 6.0.3 to 7.2.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/supertest) --- updated-dependencies: - dependency-name: "@types/supertest" dependency-version: 7.2.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 49f911857..3fe5b620b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "@types/nodemailer": "^7.0.1", "@types/passport-jwt": "^4.0.0", "@types/passport-local": "^1.0.34", - "@types/supertest": "^6.0.1", + "@types/supertest": "^7.2.0", "@types/uuid": "^11.0.0", "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", @@ -3702,10 +3702,11 @@ } }, "node_modules/@types/supertest": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.3.tgz", - "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.0.tgz", + "integrity": "sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw==", "dev": true, + "license": "MIT", "dependencies": { "@types/methods": "^1.1.4", "@types/superagent": "^8.1.0" diff --git a/package.json b/package.json index 7d9412641..9dcabf2ad 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "@types/nodemailer": "^7.0.1", "@types/passport-jwt": "^4.0.0", "@types/passport-local": "^1.0.34", - "@types/supertest": "^6.0.1", + "@types/supertest": "^7.2.0", "@types/uuid": "^11.0.0", "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", From c4dd43d70b7258d8300a53151fb0f6ba94dc3841 Mon Sep 17 00:00:00 2001 From: Carlo Minotti <50220438+minottic@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:24:17 +0100 Subject: [PATCH 055/120] fix: stricter date validation for encode --- src/common/pipes/filter.pipe.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/pipes/filter.pipe.ts b/src/common/pipes/filter.pipe.ts index 253d41beb..004bdc5de 100644 --- a/src/common/pipes/filter.pipe.ts +++ b/src/common/pipes/filter.pipe.ts @@ -153,7 +153,8 @@ export class WherePipe extends FilterPipeAbstract { }, }, valueFn: (val: unknown) => { - if (typeof val !== "string") return val; + if (typeof val !== "string" || !/^\d{4}-\d{2}-\d{2}/.test(val)) + return val; const dateFromString = new Date(val); return isNaN(dateFromString.getTime()) ? val : dateFromString; }, From 4e0dfd7a365ae0926d3e77dfda9b86a5a237de8c Mon Sep 17 00:00:00 2001 From: minottic Date: Fri, 6 Mar 2026 16:04:03 +0000 Subject: [PATCH 056/120] fix: avoid register endpoint to override nested --- .../published-data.v4.controller.ts | 15 ++++++-- test/jest-e2e-tests/publishedData.e2e-spec.ts | 38 ++++++++++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/published-data/published-data.v4.controller.ts b/src/published-data/published-data.v4.controller.ts index 824a7829a..bfa0372bd 100644 --- a/src/published-data/published-data.v4.controller.ts +++ b/src/published-data/published-data.v4.controller.ts @@ -58,6 +58,7 @@ import { } from "./schemas/published-data.schema"; import { V4_FILTER_PIPE } from "./pipes/filter.pipe"; import { ILimitsFilter } from "src/common/interfaces/common.interface"; +import { cloneDeep } from "lodash"; @ApiBearerAuth() @ApiTags("published data v4") @@ -569,12 +570,18 @@ export class PublishedDataV4Controller { await this.validateMetadata(publishedData.metadata); + const mergePatchRequest = cloneDeep(request); + mergePatchRequest.headers["content-type"] = "application/merge-patch+json"; await Promise.all( publishedData.datasetPids.map(async (pid) => { - await this.datasetsController.findByIdAndUpdate(request, pid, { - isPublished: true, - datasetlifecycle: { publishedOn: data.registeredTime }, - }); + await this.datasetsController.findByIdAndUpdate( + mergePatchRequest, + pid, + { + isPublished: true, + datasetlifecycle: { publishedOn: data.registeredTime }, + }, + ); }), ); diff --git a/test/jest-e2e-tests/publishedData.e2e-spec.ts b/test/jest-e2e-tests/publishedData.e2e-spec.ts index e4ab81a91..7959fca47 100644 --- a/test/jest-e2e-tests/publishedData.e2e-spec.ts +++ b/test/jest-e2e-tests/publishedData.e2e-spec.ts @@ -8,6 +8,10 @@ import request from "supertest"; import { getToken } from "../LoginUtils"; import { TestData } from "../TestData"; import { createTestingApp, createTestingModuleFactory } from "./utlis"; +import { CreateDatasetObsoleteDto } from "src/datasets/dto/create-dataset-obsolete.dto"; +import { DatasetSchema } from "src/datasets/schemas/dataset.schema"; +import { PublishedDataSchema } from "src/published-data/schemas/published-data.schema"; +import { omit } from "lodash"; describe.each([undefined, "", "https://api.test.datacite.org/dois"])( "Published data datacite test (url: %p)", @@ -18,6 +22,7 @@ describe.each([undefined, "", "https://api.test.datacite.org/dois"])( let httpService: HttpService; let doi: string; + let dataset: CreateDatasetObsoleteDto; beforeAll(async () => { if (registerDoiUri) { @@ -40,9 +45,19 @@ describe.each([undefined, "", "https://api.test.datacite.org/dois"])( }); beforeAll(async () => { + const createDatasetResponse = await request(app.getHttpServer()) + .post("/api/v3/datasets") + .send(TestData.RawCorrectMin) + .auth(token, { type: "bearer" }) + .set("Accept", "application/json") + .expect(TestData.EntryCreatedStatusCode); + dataset = createDatasetResponse.body; await request(app.getHttpServer()) .post("/api/v4/PublishedData") - .send(TestData.PublishedDataV4) + .send({ + ...TestData.PublishedDataV4, + datasetPids: [createDatasetResponse.body.pid], + }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${token}` }) .expect(TestData.EntryCreatedStatusCode) @@ -53,6 +68,12 @@ describe.each([undefined, "", "https://api.test.datacite.org/dois"])( afterAll(async () => { if (mongoConnection.db) await mongoConnection.db.dropDatabase(); await app.close(); + + // Remove pre-save hooks added by forFeatureAsync factories to prevent + // stale closures from accumulating across describe.each iterations + for (const schema of [DatasetSchema, PublishedDataSchema]) { + schema.s.hooks._pres.get("save")?.splice(0); + } }); it("Should register this new published data", async () => { @@ -74,6 +95,21 @@ describe.each([undefined, "", "https://api.test.datacite.org/dois"])( .set({ Authorization: `Bearer ${token}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/); + + await request(app.getHttpServer()) + .get("/api/v3/datasets/" + encodeURIComponent(dataset.pid as string)) + .auth(token, { type: "bearer" }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + expect(omit(res.body.datasetlifecycle, "publishedOn")).toEqual( + omit(dataset!.datasetlifecycle, "publishedOn"), + ); + expect(res.body.isPublished).toEqual(true); + expect(res.body.datasetlifecycle.publishedOn).not.toEqual( + dataset!.datasetlifecycle.publishedOn, + ); + }); }); it("Should fetch this new published data", async () => { From 92e8d1cb34ab1e206450f73a57e24e6a5896110f Mon Sep 17 00:00:00 2001 From: Carlo Minotti <50220438+minottic@users.noreply.github.com> Date: Mon, 9 Mar 2026 09:49:37 +0100 Subject: [PATCH 057/120] fix: datablock find forwards correct id (#2590) --- src/datablocks/datablocks.controller.ts | 4 +- src/datasets/datasets.controller.ts | 3 +- test/Datablock.js | 53 ++++++++++++++++++++++++- test/DerivedDatasetDatablock.js | 14 +++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/datablocks/datablocks.controller.ts b/src/datablocks/datablocks.controller.ts index 4694eae81..cc83338a8 100644 --- a/src/datablocks/datablocks.controller.ts +++ b/src/datablocks/datablocks.controller.ts @@ -234,7 +234,7 @@ export class DatablocksController { const user: JWTUser = request.user as JWTUser; const abilities = this.caslAbilityFactory.datablockInstanceAccess(user); - const instance = await this.datablocksService.findOne({ _id: id }); + const instance = await this.datablocksService.findOne({ where: { _id: id } }); if (!instance) { throw new NotFoundException(); } @@ -260,7 +260,7 @@ export class DatablocksController { @Body() updateDatablockDto: PartialUpdateDatablockDto, ): Promise { try { - const instance = await this.datablocksService.findOne({ _id: id }); + const instance = await this.datablocksService.findOne({ where: { _id: id } }); const user: JWTUser = request.user as JWTUser; const ability = this.caslAbilityFactory.datablockInstanceAccess(user); diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index a85c9eed2..84e57fa52 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -2620,8 +2620,7 @@ export class DatasetsController { ); if (!dataset) throw new NotFoundException(`dataset: ${pid} not found`); - const datablockBeforeUpdate = await this.datablocksService.findOne({ - _id: did, + const datablockBeforeUpdate = await this.datablocksService.findOne({where: {_id: did,} }); if (!datablockBeforeUpdate) throw new NotFoundException(`datablock: ${did} not found`); diff --git a/test/Datablock.js b/test/Datablock.js index af0818b95..bc47fd19f 100644 --- a/test/Datablock.js +++ b/test/Datablock.js @@ -34,7 +34,7 @@ describe("Datablocks", () => { .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) - + await request(appUrl) .post("/api/v3/Datasets") .send(TestData.RawCorrect) @@ -115,6 +115,24 @@ describe("Datablocks", () => { }); }); + ["filter", "where"].forEach((queryKey, index) => { + it(`004${(index + 1) * 3}: should count datablocks associated with dataset`, async () => { + var filter = { where: { _id: datablockId2 } }; + + return request(appUrl) + .get( + `/api/v3/datablocks/count?${queryKey}=${encodeURIComponent(JSON.stringify(filter))} `, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => + res.body.should.have.property("count").and.equal(1) + ); + }); + }); + it("0050: should fetch datablocks associated with dataset", async () => { var filter = { where: { datasetId: datasetId } }; @@ -135,6 +153,22 @@ describe("Datablocks", () => { }); }); + ["datablockId", "datablockId2"].forEach((dbId, index) => { + it(`005${(index + 1) * 3}: should fetch datablock by id`, async () => { + const datablocks = { datablockId: datablockId, datablockId2: datablockId2 }; + const id = datablocks[dbId]; + return request(appUrl) + .get(`/api/v3/datablocks/${encodeURIComponent(id)}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => + res.body.should.have.property("id").and.equal(id) + ); + }); + }); + it("0060: The size and numFiles fields in the dataset should be correctly updated", async () => { return request(appUrl) .get("/api/v3/Datasets/" + encodeURIComponent(datasetId)) @@ -158,6 +192,23 @@ describe("Datablocks", () => { }); }); + ["datablockId", "datablockId2"].forEach((dbId, index) => { + it(`006${(index + 1) * 3}: should update datablock by id`, async () => { + const datablocks = { datablockId: datablockId, datablockId2: datablockId2 }; + const version = `new-version-${index}`; + return request(appUrl) + .patch(`/api/v3/datablocks/${encodeURIComponent(datablocks[dbId])}`) + .send({ version: version }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => + res.body.should.have.property("version").and.equal(version) + ); + }); + }); + it("0070: should delete first datablock", async () => { return request(appUrl) .delete(`/api/v3/datablocks/${datablockId}`) diff --git a/test/DerivedDatasetDatablock.js b/test/DerivedDatasetDatablock.js index 4882820d7..056640c2a 100644 --- a/test/DerivedDatasetDatablock.js +++ b/test/DerivedDatasetDatablock.js @@ -385,6 +385,20 @@ describe("0750: DerivedDatasetDatablock: Test Datablocks and their relation to d }); }); + it("193: should patch datablock by id", async () => { + const version = "new-version"; + return request(appUrl) + .patch(`/api/v3/Datasets/${datasetPid}/datablocks/${datablockId1}`) + .send({ version: version, dataFileList: TestData.DataBlockCorrect.dataFileList }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => + res.body.should.have.property("version").and.equal(version) + ); + }); + it("195: Should delete second datablock", async () => { await request(appUrl) .delete(`/api/v3/Datasets/${datasetPid}/datablocks/${datablockId2}`) From 297b7fcd07b93b21be8648941426af6931500758 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 09:09:04 +0000 Subject: [PATCH 058/120] build(deps): bump multer and @nestjs/platform-express Bumps [multer](https://github.com/expressjs/multer) to 2.1.1 and updates ancestor dependency [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express). These dependencies need to be updated together. Updates `multer` from 2.0.2 to 2.1.1 - [Release notes](https://github.com/expressjs/multer/releases) - [Changelog](https://github.com/expressjs/multer/blob/main/CHANGELOG.md) - [Commits](https://github.com/expressjs/multer/compare/v2.0.2...v2.1.1) Updates `@nestjs/platform-express` from 11.1.14 to 11.1.16 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.16/packages/platform-express) --- updated-dependencies: - dependency-name: multer dependency-version: 2.1.1 dependency-type: indirect - dependency-name: "@nestjs/platform-express" dependency-version: 11.1.16 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3fe5b620b..4c556d42b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2747,14 +2747,14 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.14", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.14.tgz", - "integrity": "sha512-Fs+/j+mBSBSXErOQJ/YdUn/HqJGSJ4pGfiJyYOyz04l42uNVnqEakvu1kXLbxMabR6vd6/h9d6Bi4tso9p7o4Q==", + "version": "11.1.16", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.16.tgz", + "integrity": "sha512-IOegr5+ZfUiMKgk+garsSU4MOkPRhm46e6w8Bp1GcO4vCdl9Piz6FlWAzKVfa/U3Hn/DdzSVJOW3TWcQQFdBDw==", "license": "MIT", "dependencies": { "cors": "2.8.6", "express": "5.2.1", - "multer": "2.0.2", + "multer": "2.1.1", "path-to-regexp": "8.3.0", "tslib": "2.8.1" }, @@ -10866,18 +10866,6 @@ "mjml-section": "4.15.3" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mocha": { "version": "11.7.5", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", @@ -11107,21 +11095,22 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", - "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz", + "integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==", "license": "MIT", "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", - "mkdirp": "^0.5.6", - "object-assign": "^4.1.1", - "type-is": "^1.6.18", - "xtend": "^4.0.2" + "type-is": "^1.6.18" }, "engines": { "node": ">= 10.16.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/multer/node_modules/media-typer": { @@ -15045,15 +15034,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", From 834370f834bb5ec35ffda12798cd5ab49e8fa254 Mon Sep 17 00:00:00 2001 From: Emil Gunnarsson Date: Fri, 6 Mar 2026 12:53:27 +0100 Subject: [PATCH 059/120] refactor: remove unused code using Action.DatasetReadManyOwner --- src/datasets/datasets-access.service.ts | 7 ----- src/datasets/datasets.controller.ts | 37 +------------------------ src/datasets/datasets.v4.controller.ts | 19 ------------- src/proposals/proposals.controller.ts | 8 +----- src/samples/samples.controller.ts | 7 ----- 5 files changed, 2 insertions(+), 76 deletions(-) diff --git a/src/datasets/datasets-access.service.ts b/src/datasets/datasets-access.service.ts index 7d23c49a3..edad74296 100644 --- a/src/datasets/datasets-access.service.ts +++ b/src/datasets/datasets-access.service.ts @@ -194,7 +194,6 @@ export class DatasetsAccessService { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); if (!canViewAny) { if (canViewAccess) { @@ -208,12 +207,6 @@ export class DatasetsAccessService { ], }, }); - } else if (canViewOwner) { - fieldValue.$lookup.pipeline?.unshift({ - $match: { - ownerGroup: { $in: currentUser.currentGroups }, - }, - }); } else { fieldValue.$lookup.pipeline?.unshift({ $match: { diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 84e57fa52..d3307e7a5 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -168,7 +168,7 @@ export class DatasetsController { const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); - const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); + const canViewAccess = ability.can( Action.DatasetReadManyAccess, DatasetClass, @@ -205,11 +205,6 @@ export class DatasetsController { }, ]; } - } else if (canViewOwner) { - mergedFilters.where = { - ...mergedFilters.where, - ownerGroup: { $in: user.currentGroups }, - }; } else if (canViewPublic) { mergedFilters.where = { ...mergedFilters.where, @@ -982,16 +977,9 @@ export class DatasetsController { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); if (canViewAccess) { fields.userGroups = fields.userGroups ?? []; fields.userGroups.push(...user.currentGroups); - } else if (canViewOwner) { - fields.ownerGroup = fields.ownerGroup ?? []; - fields.ownerGroup.push(...user.currentGroups); } else { fields.isPublished = true; } @@ -1064,17 +1052,10 @@ export class DatasetsController { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); if (canViewAccess) { fields.userGroups = fields.userGroups ?? []; fields.userGroups.push(...user.currentGroups); - } else if (canViewOwner) { - fields.ownerGroup = fields.ownerGroup ?? []; - fields.ownerGroup.push(...user.currentGroups); } else { fields.isPublished = true; } @@ -1135,31 +1116,15 @@ export class DatasetsController { const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { - // delete fields.isPublished; const canViewAccess = ability.can( Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); - // const canViewPublic = ability.can( - // Action.DatasetReadManyPublic, - // DatasetClass, - // ); if (canViewAccess) { fields.userGroups?.push(...user.currentGroups); - // fields.sharedWith = user.email; - // fields.isPublished = true; //are they in or? - } else if (canViewOwner) { - fields.ownerGroup?.push(...user.currentGroups); } - // else if (canViewPublic) { - // fields.isPublished = true; - // } } const parsedFilters: IFilters = { diff --git a/src/datasets/datasets.v4.controller.ts b/src/datasets/datasets.v4.controller.ts index 1f0805f74..bf9219786 100644 --- a/src/datasets/datasets.v4.controller.ts +++ b/src/datasets/datasets.v4.controller.ts @@ -218,7 +218,6 @@ export class DatasetsV4Controller { ): IDatasetFiltersV4 { const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); - const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( Action.DatasetReadManyAccess, DatasetClass, @@ -251,11 +250,6 @@ export class DatasetsV4Controller { }, ]; } - } else if (canViewOwner) { - filter.where = { - ...filter.where, - ownerGroup: { $in: user.currentGroups }, - }; } } @@ -495,17 +489,10 @@ export class DatasetsV4Controller { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); if (canViewAccess) { fields.userGroups = fields.userGroups ?? []; fields.userGroups.push(...user.currentGroups); - } else if (canViewOwner) { - fields.ownerGroup = fields.ownerGroup ?? []; - fields.ownerGroup.push(...user.currentGroups); } } @@ -567,15 +554,9 @@ export class DatasetsV4Controller { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); if (canViewAccess) { fields.userGroups?.push(...user.currentGroups); - } else if (canViewOwner) { - fields.ownerGroup?.push(...user.currentGroups); } } diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index ae661246d..116ef289c 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -982,10 +982,7 @@ export class ProposalsController { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); + const canViewPublic = ability.can( Action.DatasetReadManyPublic, DatasetClass, @@ -994,9 +991,6 @@ export class ProposalsController { fields.userGroups = user.currentGroups ?? []; fields.userGroups.push(...user.currentGroups); // fields.sharedWith = user.email; - } else if (canViewOwner) { - fields.ownerGroup = user.currentGroups ?? []; - fields.ownerGroup.push(...user.currentGroups); } else if (canViewPublic) { fields.isPublished = true; } diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index f814d219e..d857db811 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -1009,10 +1009,6 @@ export class SamplesController { Action.DatasetReadManyAccess, DatasetClass, ); - const canViewOwner = ability.can( - Action.DatasetReadManyOwner, - DatasetClass, - ); const canViewPublic = ability.can( Action.DatasetReadManyPublic, DatasetClass, @@ -1021,9 +1017,6 @@ export class SamplesController { fields.userGroups = user.currentGroups ?? []; fields.userGroups.push(...user.currentGroups); // fields.sharedWith = user.email; - } else if (canViewOwner) { - fields.ownerGroup = user.currentGroups ?? []; - fields.ownerGroup.push(...user.currentGroups); } else if (canViewPublic) { fields.isPublished = true; } From d26700682da93ed1902399fd8be7c7881dfad6be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:40:51 +0000 Subject: [PATCH 060/120] build(deps-dev): bump @types/node from 25.3.3 to 25.3.5 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.3.3 to 25.3.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.3.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c556d42b..d0aaeae05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3574,9 +3574,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", + "version": "25.3.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz", + "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", "license": "MIT", "dependencies": { "undici-types": "~7.18.0" From bf605ea849c87067c5492f6527424744293e841e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:52:41 +0000 Subject: [PATCH 061/120] build(deps-dev): bump @stylistic/eslint-plugin from 5.9.0 to 5.10.0 Bumps [@stylistic/eslint-plugin](https://github.com/eslint-stylistic/eslint-stylistic/tree/HEAD/packages/eslint-plugin) from 5.9.0 to 5.10.0. - [Release notes](https://github.com/eslint-stylistic/eslint-stylistic/releases) - [Changelog](https://github.com/eslint-stylistic/eslint-stylistic/blob/v5.10.0/CHANGELOG.md) - [Commits](https://github.com/eslint-stylistic/eslint-stylistic/commits/v5.10.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@stylistic/eslint-plugin" dependency-version: 5.10.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d0aaeae05..9c5fedabd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3168,9 +3168,9 @@ "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.9.0.tgz", - "integrity": "sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", "dev": true, "license": "MIT", "dependencies": { From d1093f59bf46818638752d13891aaee1b1a33801 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:04:02 +0000 Subject: [PATCH 062/120] build(deps-dev): bump @eslint/eslintrc from 3.3.4 to 3.3.5 Bumps [@eslint/eslintrc](https://github.com/eslint/eslintrc) from 3.3.4 to 3.3.5. - [Release notes](https://github.com/eslint/eslintrc/releases) - [Changelog](https://github.com/eslint/eslintrc/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslintrc/compare/eslintrc-v3.3.4...eslintrc-v3.3.5) --- updated-dependencies: - dependency-name: "@eslint/eslintrc" dependency-version: 3.3.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c5fedabd..a2e81c6a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1169,9 +1169,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", - "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "dev": true, "license": "MIT", "dependencies": { @@ -1182,7 +1182,7 @@ "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.3", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -10313,9 +10313,9 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", - "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "devOptional": true, "license": "ISC", "dependencies": { From 6e0e4304688bc9d75eabef6ebf45f3afd819b154 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:14:57 +0000 Subject: [PATCH 063/120] build(deps): bump class-validator from 0.14.3 to 0.15.1 Bumps [class-validator](https://github.com/typestack/class-validator) from 0.14.3 to 0.15.1. - [Release notes](https://github.com/typestack/class-validator/releases) - [Changelog](https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md) - [Commits](https://github.com/typestack/class-validator/compare/v0.14.3...v0.15.1) --- updated-dependencies: - dependency-name: class-validator dependency-version: 0.15.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 49 ++++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2e81c6a8..4864eff68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "amqplib": "^0.10.5", "bcrypt": "^6.0.0", "class-transformer": "^0.5.1", - "class-validator": "^0.14.0", + "class-validator": "^0.15.1", "connect-mongo": "^6.0.0", "dotenv": "^17.2.0", "express-session": "^1.17.3", @@ -2706,25 +2706,6 @@ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" } }, - "node_modules/@nestjs/mapped-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", - "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "class-transformer": "^0.4.0 || ^0.5.0", - "class-validator": "^0.13.0 || ^0.14.0", - "reflect-metadata": "^0.1.12 || ^0.2.0" - }, - "peerDependenciesMeta": { - "class-transformer": { - "optional": true - }, - "class-validator": { - "optional": true - } - } - }, "node_modules/@nestjs/mongoose": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-11.0.4.tgz", @@ -2901,6 +2882,26 @@ } } }, + "node_modules/@nestjs/swagger/node_modules/@nestjs/mapped-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", + "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/swagger/node_modules/path-to-regexp": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", @@ -5649,14 +5650,14 @@ "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" }, "node_modules/class-validator": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz", - "integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.15.1.tgz", + "integrity": "sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==", "license": "MIT", "dependencies": { "@types/validator": "^13.15.3", "libphonenumber-js": "^1.11.1", - "validator": "^13.15.20" + "validator": "^13.15.22" } }, "node_modules/clean-css": { diff --git a/package.json b/package.json index 9dcabf2ad..21e6223f2 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "amqplib": "^0.10.5", "bcrypt": "^6.0.0", "class-transformer": "^0.5.1", - "class-validator": "^0.14.0", + "class-validator": "^0.15.1", "connect-mongo": "^6.0.0", "dotenv": "^17.2.0", "express-session": "^1.17.3", From cbe4dc1ca432c80da004da5ef5ce4bc70403182e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:25:58 +0000 Subject: [PATCH 064/120] build(deps-dev): bump @nestjs/testing in the nestjs group Bumps the nestjs group with 1 update: [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing). Updates `@nestjs/testing` from 11.1.14 to 11.1.16 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.16/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/testing" dependency-version: 11.1.16 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4864eff68..6a8344bed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2983,9 +2983,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "11.1.14", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.14.tgz", - "integrity": "sha512-cQxX0ronsTbpfHz8/LYOVWXxoTxv6VoxrnuZoQaVX7QV2PSMqxWE7/9jSQR0GcqAFUEmFP34c6EJqfkjfX/k4Q==", + "version": "11.1.16", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.16.tgz", + "integrity": "sha512-E7/aUCxzeMSJV80L5GWGIuiMyR/1ncS7uOIetAImfbS4ATE1/h2GBafk0qpk+vjFtPIbtoh9BWDGICzUEU5jDA==", "dev": true, "license": "MIT", "dependencies": { From a467ce10953beacba5278e466b00aca267e91a4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:36:30 +0000 Subject: [PATCH 065/120] build(deps-dev): bump sinon from 21.0.1 to 21.0.2 Bumps [sinon](https://github.com/sinonjs/sinon) from 21.0.1 to 21.0.2. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v21.0.1...v21.0.2) --- updated-dependencies: - dependency-name: sinon dependency-version: 21.0.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6a8344bed..6585d7afc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3141,9 +3141,9 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", - "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-9.0.2.tgz", + "integrity": "sha512-H/JSxa4GNKZuuU41E3b8Y3tbSEx8y4uq4UH1C56ONQac16HblReJomIvv3Ud7ANQHQmkeSowY49Ij972e/pGxQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -13055,16 +13055,16 @@ "license": "MIT" }, "node_modules/sinon": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.1.tgz", - "integrity": "sha512-Z0NVCW45W8Mg5oC/27/+fCqIHFnW8kpkFOq0j9XJIev4Ld0mKmERaZv5DMLAb9fGCevjKwaEeIQz5+MBXfZcDw==", + "version": "21.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.2.tgz", + "integrity": "sha512-VHV4UaoxIe5jrMd89Y9duI76T5g3Lp+ET+ctLhLDaZtSznDPah1KKpRElbdBV4RwqWSw2vadFiVs9Del7MbVeQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^15.1.0", - "@sinonjs/samsam": "^8.0.3", - "diff": "^8.0.2", + "@sinonjs/fake-timers": "^15.1.1", + "@sinonjs/samsam": "^9.0.2", + "diff": "^8.0.3", "supports-color": "^7.2.0" }, "funding": { @@ -13073,9 +13073,9 @@ } }, "node_modules/sinon/node_modules/@sinonjs/fake-timers": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.0.tgz", - "integrity": "sha512-cqfapCxwTGsrR80FEgOoPsTonoefMBY7dnUEbQ+GRcved0jvkJLzvX6F4WtN+HBqbPX/SiFsIRUp+IrCW/2I2w==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -13083,9 +13083,9 @@ } }, "node_modules/sinon/node_modules/diff": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", - "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", "dev": true, "license": "BSD-3-Clause", "engines": { From 8cc688a552e685614f8625a9f584ba142a1e9fac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 21:09:48 +0000 Subject: [PATCH 066/120] build(deps): bump docker/build-push-action from 6 to 7 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6...v7) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy.yml | 2 +- .github/workflows/release-and-publish-sdk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5c04d6690..5e6230e75 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -37,7 +37,7 @@ jobs: tags: type=sha,format=long,prefix= # adds : tag to outputs.tags - name: Build and push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64/v8 diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index c86d55a30..19376028b 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -85,7 +85,7 @@ jobs: type=raw,value={{date 'YYYY_MM'}},prefix=r_ - name: Build and push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64/v8 From 2dc9778b3af6048101c530a174047f8de80798f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 21:19:56 +0000 Subject: [PATCH 067/120] build(deps): bump docker/login-action from 3 to 4 Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy.yml | 2 +- .github/workflows/release-and-publish-sdk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5e6230e75..5efd0bae7 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -22,7 +22,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to GHCR - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 19376028b..69c4c0b0b 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -56,7 +56,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} From 8efca3976481d5457d84cd12a38a7e5354a07aca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 21:29:32 +0000 Subject: [PATCH 068/120] build(deps): bump docker/setup-buildx-action from 3 to 4 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy.yml | 2 +- .github/workflows/release-and-publish-sdk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5efd0bae7..67c40cd55 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,7 +19,7 @@ jobs: platforms: arm64 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GHCR uses: docker/login-action@v4 diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 69c4c0b0b..fc5e9a2f0 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -53,7 +53,7 @@ jobs: uses: docker/setup-qemu-action@v3 - 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@v4 From 668e6490ad01ccd097b8eb1f0e2605f766f92271 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 21:39:16 +0000 Subject: [PATCH 069/120] build(deps): bump docker/metadata-action from 5 to 6 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy.yml | 2 +- .github/workflows/release-and-publish-sdk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 67c40cd55..e7155978a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,7 +30,7 @@ jobs: - name: Create image tags id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ghcr.io/scicatproject/backend-next flavor: latest=true # adds :latest tag to outputs.tags diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index fc5e9a2f0..8e11ab532 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -75,7 +75,7 @@ jobs: ## https://github.com/docker/metadata-action - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ghcr.io/scicatproject/backend-next tags: | From b0b94b11ac03279a6cba6c77033affb39c309c04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 21:48:36 +0000 Subject: [PATCH 070/120] build(deps): bump docker/setup-qemu-action from 3 to 4 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy.yml | 2 +- .github/workflows/release-and-publish-sdk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e7155978a..64e99f5a0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 with: platforms: arm64 diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 8e11ab532..1310ccd65 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -50,7 +50,7 @@ jobs: ## The setup-qemu-action simplifies the setup of QEMU for cross-platform builds ## https://github.com/docker/setup-qemu-action - 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@v4 From 7bf17120007ebecbe043b5cd79865f8c4fba142c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 01:10:44 +0000 Subject: [PATCH 071/120] build(deps): bump liquidjs from 10.21.0 to 10.25.0 Bumps [liquidjs](https://github.com/harttle/liquidjs) from 10.21.0 to 10.25.0. - [Release notes](https://github.com/harttle/liquidjs/releases) - [Changelog](https://github.com/harttle/liquidjs/blob/master/CHANGELOG.md) - [Commits](https://github.com/harttle/liquidjs/compare/v10.21.0...v10.25.0) --- updated-dependencies: - dependency-name: liquidjs dependency-version: 10.25.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6585d7afc..92a291fda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9884,9 +9884,10 @@ } }, "node_modules/liquidjs": { - "version": "10.21.0", - "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.21.0.tgz", - "integrity": "sha512-DouqxNU2jfoZzb1LinVjOc/f6ssitGIxiDJT+kEKyYqPSSSd+WmGOAhtWbVm1/n75svu4aQ+FyQ3ctd3wh1bbw==", + "version": "10.25.0", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.0.tgz", + "integrity": "sha512-XpO7AiGULTG4xcTlwkcTI5JreFG7b6esLCLp+aUSh7YuQErJZEoUXre9u9rbdb0057pfWG4l0VursvLd5Q/eAw==", + "license": "MIT", "optional": true, "dependencies": { "commander": "^10.0.0" @@ -9896,7 +9897,7 @@ "liquidjs": "bin/liquid.js" }, "engines": { - "node": ">=14" + "node": ">=16" }, "funding": { "type": "opencollective", From 707f0776d6598d83b762a130a8654f172c96d107 Mon Sep 17 00:00:00 2001 From: Emil Gunnarsson Date: Mon, 9 Mar 2026 13:37:36 +0100 Subject: [PATCH 072/120] only add https if needed to landingpage --- .../published-data.v4.controller.spec.ts | 13 +++++++++++++ src/published-data/published-data.v4.controller.ts | 9 +++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/published-data/published-data.v4.controller.spec.ts b/src/published-data/published-data.v4.controller.spec.ts index eb125bd38..eb3fa3974 100644 --- a/src/published-data/published-data.v4.controller.spec.ts +++ b/src/published-data/published-data.v4.controller.spec.ts @@ -51,6 +51,10 @@ describe("PublishedDataController", () => { ...defaultUrl, metadata: { landingPage: "custom-landingpage/" }, }; + const customLandingPageWithProtocol: PublishedData = { + ...defaultUrl, + metadata: { landingPage: "https://custom-landingpage/" }, + }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -90,4 +94,13 @@ describe("PublishedDataController", () => { `https://${customLandingPage.metadata!.landingPage}${encodeURIComponent(customLandingPage.doi)}`, ); }); + + it("should not double-prefix https:// when 'landingPage' already includes a protocol", () => { + expect( + controller.doiRegistrationJSON(customLandingPageWithProtocol), + ).toHaveProperty( + "data.attributes.url", + `${customLandingPageWithProtocol.metadata!.landingPage}${encodeURIComponent(customLandingPageWithProtocol.doi)}`, + ); + }); }); diff --git a/src/published-data/published-data.v4.controller.ts b/src/published-data/published-data.v4.controller.ts index bfa0372bd..db5343ea8 100644 --- a/src/published-data/published-data.v4.controller.ts +++ b/src/published-data/published-data.v4.controller.ts @@ -740,9 +740,14 @@ export class PublishedDataV4Controller { landingPage, } = metadata ?? {}; + const landingPageBase = + typeof landingPage === "string" && + (landingPage.startsWith("https://") || landingPage.startsWith("http://")) + ? landingPage + : `https://${landingPage}`; const url = landingPage - ? `https://${landingPage}${encodeURIComponent(doi)}` - : `${this.configService.get("publicURLprefix")}${encodeURIComponent(doi)}`; + ? `${landingPageBase}${encodeURIComponent(doi)}` + : `${this.configService.get("publicURLprefix")}${encodeURIComponent(doi)}`; const descriptionsArray = [ { description: abstract, descriptionType: "Abstract", lang: "en" }, From c6f5345bb727b5b408e428bbd265ae322fa8de56 Mon Sep 17 00:00:00 2001 From: Emil Gunnarsson Date: Tue, 10 Mar 2026 09:38:18 +0100 Subject: [PATCH 073/120] fix: eslint errors due to new version --- src/datablocks/datablocks.controller.ts | 8 ++++++-- src/datasets/datasets.controller.ts | 4 ++-- src/proposals/proposals.controller.ts | 2 +- src/published-data/published-data.v4.controller.ts | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/datablocks/datablocks.controller.ts b/src/datablocks/datablocks.controller.ts index cc83338a8..a474323a6 100644 --- a/src/datablocks/datablocks.controller.ts +++ b/src/datablocks/datablocks.controller.ts @@ -234,7 +234,9 @@ export class DatablocksController { const user: JWTUser = request.user as JWTUser; const abilities = this.caslAbilityFactory.datablockInstanceAccess(user); - const instance = await this.datablocksService.findOne({ where: { _id: id } }); + const instance = await this.datablocksService.findOne({ + where: { _id: id }, + }); if (!instance) { throw new NotFoundException(); } @@ -260,7 +262,9 @@ export class DatablocksController { @Body() updateDatablockDto: PartialUpdateDatablockDto, ): Promise { try { - const instance = await this.datablocksService.findOne({ where: { _id: id } }); + const instance = await this.datablocksService.findOne({ + where: { _id: id }, + }); const user: JWTUser = request.user as JWTUser; const ability = this.caslAbilityFactory.datablockInstanceAccess(user); diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index d3307e7a5..0d179fafc 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -1116,7 +1116,6 @@ export class DatasetsController { const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { - const canViewAccess = ability.can( Action.DatasetReadManyAccess, DatasetClass, @@ -2585,7 +2584,8 @@ export class DatasetsController { ); if (!dataset) throw new NotFoundException(`dataset: ${pid} not found`); - const datablockBeforeUpdate = await this.datablocksService.findOne({where: {_id: did,} + const datablockBeforeUpdate = await this.datablocksService.findOne({ + where: { _id: did }, }); if (!datablockBeforeUpdate) throw new NotFoundException(`datablock: ${did} not found`); diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 116ef289c..dfad2a957 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -982,7 +982,7 @@ export class ProposalsController { Action.DatasetReadManyAccess, DatasetClass, ); - + const canViewPublic = ability.can( Action.DatasetReadManyPublic, DatasetClass, diff --git a/src/published-data/published-data.v4.controller.ts b/src/published-data/published-data.v4.controller.ts index db5343ea8..79346a164 100644 --- a/src/published-data/published-data.v4.controller.ts +++ b/src/published-data/published-data.v4.controller.ts @@ -746,8 +746,8 @@ export class PublishedDataV4Controller { ? landingPage : `https://${landingPage}`; const url = landingPage - ? `${landingPageBase}${encodeURIComponent(doi)}` - : `${this.configService.get("publicURLprefix")}${encodeURIComponent(doi)}`; + ? `${landingPageBase}${encodeURIComponent(doi)}` + : `${this.configService.get("publicURLprefix")}${encodeURIComponent(doi)}`; const descriptionsArray = [ { description: abstract, descriptionType: "Abstract", lang: "en" }, From 4b0aad485b487753588f211645dde56284392f2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 04:15:37 +0000 Subject: [PATCH 074/120] build(deps): bump undici from 6.23.0 to 6.24.0 Bumps [undici](https://github.com/nodejs/undici) from 6.23.0 to 6.24.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.23.0...v6.24.0) --- updated-dependencies: - dependency-name: undici dependency-version: 6.24.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92a291fda..f7c13904a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14212,9 +14212,9 @@ } }, "node_modules/undici": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", - "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.0.tgz", + "integrity": "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==", "license": "MIT", "engines": { "node": ">=18.17" From f1ea831c03e2e43c00ab733aca3a55f8226d5f12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:25:36 +0000 Subject: [PATCH 075/120] build(deps-dev): bump jest from 30.2.0 to 30.3.0 Bumps [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) from 30.2.0 to 30.3.0. - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v30.3.0/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-version: 30.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 902 ++++++++++++++++++++++++++++------------------ 1 file changed, 561 insertions(+), 341 deletions(-) diff --git a/package-lock.json b/package-lock.json index f7c13904a..3922279ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -412,9 +412,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { @@ -579,13 +579,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -705,13 +705,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1053,21 +1053,21 @@ } }, "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", + "integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.1.0", + "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", + "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", "dev": true, "license": "MIT", "optional": true, @@ -1076,9 +1076,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", "dev": true, "license": "MIT", "optional": true, @@ -1938,17 +1938,17 @@ } }, "node_modules/@jest/console": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", - "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", + "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0" }, "engines": { @@ -1956,39 +1956,38 @@ } }, "node_modules/@jest/core": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", - "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", + "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.2.0", + "@jest/console": "30.3.0", "@jest/pattern": "30.0.1", - "@jest/reporters": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/reporters": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.2.0", - "jest-config": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", + "jest-changed-files": "30.3.0", + "jest-config": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-resolve-dependencies": "30.2.0", - "jest-runner": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "jest-watcher": "30.2.0", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "jest-resolve": "30.3.0", + "jest-resolve-dependencies": "30.3.0", + "jest-runner": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "jest-watcher": "30.3.0", + "pretty-format": "30.3.0", "slash": "^3.0.0" }, "engines": { @@ -2004,9 +2003,9 @@ } }, "node_modules/@jest/core/node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -2020,9 +2019,9 @@ } }, "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, "license": "MIT", "engines": { @@ -2030,39 +2029,39 @@ } }, "node_modules/@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", + "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "30.2.0" + "jest-mock": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", "dev": true, "license": "MIT", "dependencies": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" + "expect": "30.3.0", + "jest-snapshot": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", "dev": true, "license": "MIT", "dependencies": { @@ -2073,18 +2072,18 @@ } }, "node_modules/@jest/fake-timers": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", + "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", + "@jest/types": "30.3.0", + "@sinonjs/fake-timers": "^15.0.0", "@types/node": "*", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -2101,16 +2100,16 @@ } }, "node_modules/@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", + "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/types": "30.3.0", + "jest-mock": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -2131,32 +2130,32 @@ } }, "node_modules/@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", + "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", "collect-v8-coverage": "^1.0.2", "exit-x": "^0.2.2", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -2173,6 +2172,70 @@ } } }, + "node_modules/@jest/reporters/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@jest/schemas": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", @@ -2187,13 +2250,13 @@ } }, "node_modules/@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", + "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -2218,14 +2281,14 @@ } }, "node_modules/@jest/test-result": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", - "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", + "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/types": "30.3.0", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" }, @@ -2234,15 +2297,15 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", + "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.2.0", + "@jest/test-result": "30.3.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "slash": "^3.0.0" }, "engines": { @@ -2250,24 +2313,23 @@ } }, "node_modules/@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", + "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@jridgewell/trace-mapping": "^0.3.25", "babel-plugin-istanbul": "^7.0.1", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", + "jest-util": "30.3.0", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -2277,9 +2339,9 @@ } }, "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", "dependencies": { @@ -3131,9 +3193,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -4732,6 +4794,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -4935,16 +4998,16 @@ } }, "node_modules/babel-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", - "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", + "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "30.2.0", + "@jest/transform": "30.3.0", "@types/babel__core": "^7.20.5", "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.2.0", + "babel-preset-jest": "30.3.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -4977,9 +5040,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", - "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", + "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", "dev": true, "license": "MIT", "dependencies": { @@ -5017,13 +5080,13 @@ } }, "node_modules/babel-preset-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", - "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", + "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "30.2.0", + "babel-plugin-jest-hoist": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { @@ -5638,9 +5701,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz", - "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", "dev": true, "license": "MIT" }, @@ -5819,9 +5882,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, "license": "MIT" }, @@ -6291,9 +6354,9 @@ "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" }, "node_modules/dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -7118,18 +7181,18 @@ } }, "node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -8623,16 +8686,16 @@ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" }, "node_modules/jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", - "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", + "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.2.0", - "@jest/types": "30.2.0", + "@jest/core": "30.3.0", + "@jest/types": "30.3.0", "import-local": "^3.2.0", - "jest-cli": "30.2.0" + "jest-cli": "30.3.0" }, "bin": { "jest": "bin/jest.js" @@ -8650,14 +8713,14 @@ } }, "node_modules/jest-changed-files": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", - "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", + "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", "dev": true, "license": "MIT", "dependencies": { "execa": "^5.1.1", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "p-limit": "^3.1.0" }, "engines": { @@ -8665,29 +8728,29 @@ } }, "node_modules/jest-circus": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", - "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", + "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", + "jest-each": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "p-limit": "^3.1.0", - "pretty-format": "30.2.0", + "pretty-format": "30.3.0", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -8697,21 +8760,21 @@ } }, "node_modules/jest-cli": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", - "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", + "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/core": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", + "jest-config": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "yargs": "^17.7.2" }, "bin": { @@ -8730,34 +8793,33 @@ } }, "node_modules/jest-config": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", - "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", + "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.2.0", - "@jest/types": "30.2.0", - "babel-jest": "30.2.0", + "@jest/test-sequencer": "30.3.0", + "@jest/types": "30.3.0", + "babel-jest": "30.3.0", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-circus": "30.2.0", + "jest-circus": "30.3.0", "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", + "jest-environment-node": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-runner": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "micromatch": "^4.0.8", + "jest-resolve": "30.3.0", + "jest-runner": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "parse-json": "^5.2.0", - "pretty-format": "30.2.0", + "pretty-format": "30.3.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -8781,10 +8843,20 @@ } } }, + "node_modules/jest-config/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/jest-config/node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -8797,17 +8869,71 @@ "node": ">=8" } }, + "node_modules/jest-config/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-config/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -8827,36 +8953,36 @@ } }, "node_modules/jest-each": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", - "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", + "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", - "jest-util": "30.2.0", - "pretty-format": "30.2.0" + "jest-util": "30.3.0", + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", - "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", + "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0" + "jest-mock": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -8966,21 +9092,21 @@ } }, "node_modules/jest-haste-map": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", - "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", + "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "graceful-fs": "^4.2.11", "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "micromatch": "^4.0.8", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", + "picomatch": "^4.0.3", "walker": "^1.0.8" }, "engines": { @@ -8990,50 +9116,63 @@ "fsevents": "^2.3.3" } }, + "node_modules/jest-haste-map/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-leak-detector": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", - "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", + "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -9041,16 +9180,29 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-message-util/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-util": "30.2.0" + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -9085,18 +9237,18 @@ } }, "node_modules/jest-resolve": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", - "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", + "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "slash": "^3.0.0", "unrs-resolver": "^1.7.11" }, @@ -9105,46 +9257,46 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", - "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", + "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", "dev": true, "license": "MIT", "dependencies": { "jest-regex-util": "30.0.1", - "jest-snapshot": "30.2.0" + "jest-snapshot": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", - "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", + "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.2.0", - "@jest/environment": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/environment": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-leak-detector": "30.2.0", - "jest-message-util": "30.2.0", - "jest-resolve": "30.2.0", - "jest-runtime": "30.2.0", - "jest-util": "30.2.0", - "jest-watcher": "30.2.0", - "jest-worker": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-leak-detector": "30.3.0", + "jest-message-util": "30.3.0", + "jest-resolve": "30.3.0", + "jest-runtime": "30.3.0", + "jest-util": "30.3.0", + "jest-watcher": "30.3.0", + "jest-worker": "30.3.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -9153,32 +9305,32 @@ } }, "node_modules/jest-runtime": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", - "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", + "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/globals": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/globals": "30.3.0", "@jest/source-map": "30.0.1", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.1.0", "collect-v8-coverage": "^1.0.2", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", + "jest-resolve": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -9186,10 +9338,74 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest-snapshot": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", - "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", + "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9198,20 +9414,20 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/snapshot-utils": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.2.0", + "expect": "30.3.0", "graceful-fs": "^4.2.11", - "jest-diff": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "pretty-format": "30.2.0", + "jest-diff": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "pretty-format": "30.3.0", "semver": "^7.7.2", "synckit": "^0.11.8" }, @@ -9220,18 +9436,18 @@ } }, "node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -9253,38 +9469,51 @@ "node": ">=8" } }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-validate": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", - "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", + "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-watcher": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", - "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", + "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "string-length": "^4.0.2" }, "engines": { @@ -9292,15 +9521,15 @@ } }, "node_modules/jest-worker": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", - "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", + "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -11169,9 +11398,9 @@ } }, "node_modules/napi-postinstall": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", - "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, "license": "MIT", "bin": { @@ -12005,9 +12234,9 @@ } }, "node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13073,16 +13302,6 @@ "url": "https://opencollective.com/sinon" } }, - "node_modules/sinon/node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, "node_modules/sinon/node_modules/diff": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", @@ -14114,6 +14333,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, From 46ee9c301e9e4ae9adfe012e6f4d47091c2e8e60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:31:08 +0000 Subject: [PATCH 076/120] 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.56.1 to 8.57.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.57.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.57.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 108 +++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3922279ed..c4a80ece4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3827,17 +3827,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", - "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", + "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/type-utils": "8.56.1", - "@typescript-eslint/utils": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/type-utils": "8.57.0", + "@typescript-eslint/utils": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3850,7 +3850,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.1", + "@typescript-eslint/parser": "^8.57.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3866,16 +3866,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", - "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz", + "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", "debug": "^4.4.3" }, "engines": { @@ -3891,14 +3891,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", - "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", + "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.1", - "@typescript-eslint/types": "^8.56.1", + "@typescript-eslint/tsconfig-utils": "^8.57.0", + "@typescript-eslint/types": "^8.57.0", "debug": "^4.4.3" }, "engines": { @@ -3913,14 +3913,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", - "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", + "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1" + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3931,9 +3931,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", - "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", + "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", "dev": true, "license": "MIT", "engines": { @@ -3948,15 +3948,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", - "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", + "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/utils": "8.57.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3973,9 +3973,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", - "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz", + "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", "dev": true, "license": "MIT", "engines": { @@ -3987,16 +3987,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", - "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", + "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.1", - "@typescript-eslint/tsconfig-utils": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/project-service": "8.57.0", + "@typescript-eslint/tsconfig-utils": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -4054,16 +4054,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", - "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz", + "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1" + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4078,13 +4078,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", - "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", + "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/types": "8.57.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { From e5a3763026eae3ead9d7ecd095c0f52f1a5448e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:37:11 +0000 Subject: [PATCH 077/120] build(deps): bump the nestjs group with 2 updates Bumps the nestjs group with 2 updates: [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) and [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing). Updates `@nestjs/platform-express` from 11.1.16 to 11.1.17 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.17/packages/platform-express) Updates `@nestjs/testing` from 11.1.16 to 11.1.17 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.17/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-version: 11.1.17 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/testing" dependency-version: 11.1.17 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4a80ece4..f51731d7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2790,9 +2790,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.16", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.16.tgz", - "integrity": "sha512-IOegr5+ZfUiMKgk+garsSU4MOkPRhm46e6w8Bp1GcO4vCdl9Piz6FlWAzKVfa/U3Hn/DdzSVJOW3TWcQQFdBDw==", + "version": "11.1.17", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.17.tgz", + "integrity": "sha512-mAf4eOsSBsTOn/VbrUO1gsjW6dVh91qqXPMXun4dN8SnNjf7PTQagM9o8d6ab8ZBpNe6UdZftdrZoDetU+n4Qg==", "license": "MIT", "dependencies": { "cors": "2.8.6", @@ -3045,9 +3045,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "11.1.16", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.16.tgz", - "integrity": "sha512-E7/aUCxzeMSJV80L5GWGIuiMyR/1ncS7uOIetAImfbS4ATE1/h2GBafk0qpk+vjFtPIbtoh9BWDGICzUEU5jDA==", + "version": "11.1.17", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.17.tgz", + "integrity": "sha512-lNffw+z+2USewmw4W0tsK+Rq94A2N4PiHbcqoRUu5y8fnqxQeIWGHhjo5BFCqj7eivqJBhT7WdRydxVq4rAHzg==", "dev": true, "license": "MIT", "dependencies": { From c0e341777149af7ece9d6f1459068e685c7e1ba8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:42:09 +0000 Subject: [PATCH 078/120] build(deps-dev): bump sinon from 21.0.2 to 21.0.3 Bumps [sinon](https://github.com/sinonjs/sinon) from 21.0.2 to 21.0.3. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v21.0.2...v21.0.3) --- updated-dependencies: - dependency-name: sinon dependency-version: 21.0.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index f51731d7e..27013c356 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3203,9 +3203,9 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-9.0.2.tgz", - "integrity": "sha512-H/JSxa4GNKZuuU41E3b8Y3tbSEx8y4uq4UH1C56ONQac16HblReJomIvv3Ud7ANQHQmkeSowY49Ij972e/pGxQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-9.0.3.tgz", + "integrity": "sha512-ZgYY7Dc2RW+OUdnZ1DEHg00lhRt+9BjymPKHog4PRFzr1U3MbK57+djmscWyKxzO1qfunHqs4N45WWyKIFKpiQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -13285,15 +13285,15 @@ "license": "MIT" }, "node_modules/sinon": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.2.tgz", - "integrity": "sha512-VHV4UaoxIe5jrMd89Y9duI76T5g3Lp+ET+ctLhLDaZtSznDPah1KKpRElbdBV4RwqWSw2vadFiVs9Del7MbVeQ==", + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.3.tgz", + "integrity": "sha512-0x8TQFr8EjADhSME01u1ZK31yv2+bd6Z5NrBCHVM+n4qL1wFqbxftmeyi3bwlr49FbbzRfrqSFOpyHCOh/YmYA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", "@sinonjs/fake-timers": "^15.1.1", - "@sinonjs/samsam": "^9.0.2", + "@sinonjs/samsam": "^9.0.3", "diff": "^8.0.3", "supports-color": "^7.2.0" }, From 3ec377967b4a3f8342b4ca117eb276eea1dad398 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:45:30 +0000 Subject: [PATCH 079/120] build(deps-dev): bump @types/node from 25.3.5 to 25.5.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.3.5 to 25.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.5.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27013c356..cbd59f0c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3637,9 +3637,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.3.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz", - "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "license": "MIT", "dependencies": { "undici-types": "~7.18.0" From 4c8709b85c52623c97a301f367f4ed0c635b8178 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:49:05 +0000 Subject: [PATCH 080/120] build(deps-dev): bump eslint from 9.39.2 to 10.0.3 Bumps [eslint](https://github.com/eslint/eslint) from 9.39.2 to 10.0.3. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v9.39.2...v10.0.3) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.0.3 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 239 +++++++++++++++++++++++++++++++++------------- package.json | 2 +- 2 files changed, 176 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index cbd59f0c9..1c2123b0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,7 +92,7 @@ "chai-http": "^5.1.1", "concurrently": "^9.0.0", "dotenv-cli": "^11.0.0", - "eslint": "^9.0.0", + "eslint": "^10.0.3", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.0.0", "globals": "^17.0.0", @@ -1128,44 +1128,83 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.23.3", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz", + "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.7", + "@eslint/object-schema": "^3.0.3", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^10.2.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-array/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/@eslint/config-array/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.3.tgz", + "integrity": "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0" + "@eslint/core": "^1.1.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", + "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/eslintrc": { @@ -1242,27 +1281,27 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz", + "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", + "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0", + "@eslint/core": "^1.1.1", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@faker-js/faker": { @@ -3448,6 +3487,13 @@ "@types/estree": "*" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -4633,9 +4679,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -6886,33 +6932,30 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.3.tgz", + "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", - "@eslint/plugin-kit": "^0.4.1", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.3", + "@eslint/config-helpers": "^0.5.2", + "@eslint/core": "^1.1.1", + "@eslint/plugin-kit": "^0.6.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", + "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.1.1", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -6922,8 +6965,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -6931,7 +6973,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" @@ -6993,17 +7035,19 @@ } }, "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -7023,10 +7067,11 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -7038,11 +7083,82 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/eslint/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/eslint/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/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/eslint/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/espree": { "version": "10.4.0", @@ -7076,10 +7192,11 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -10218,12 +10335,6 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", diff --git a/package.json b/package.json index 21e6223f2..2152819ec 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "chai-http": "^5.1.1", "concurrently": "^9.0.0", "dotenv-cli": "^11.0.0", - "eslint": "^9.0.0", + "eslint": "^10.0.3", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.0.0", "globals": "^17.0.0", From 99daa1467391e7adae0683109a4d72b01380dea6 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 17 Mar 2026 14:52:36 +0100 Subject: [PATCH 081/120] docs(statusBanner): update frontend config with statusBanner (#2620) --- docs/frontend-config-guide/frontend-config.md | 180 +++++++++--------- src/config/frontend.config.json | 64 ++++--- 2 files changed, 124 insertions(+), 120 deletions(-) diff --git a/docs/frontend-config-guide/frontend-config.md b/docs/frontend-config-guide/frontend-config.md index 6c4940674..a0ece39fb 100644 --- a/docs/frontend-config-guide/frontend-config.md +++ b/docs/frontend-config-guide/frontend-config.md @@ -6,92 +6,94 @@ This guide documents frontend configuration options that control various UI beha ## Configuration Options -| **Configuration Options** | **Type** | **Default Value** | **Description** | -|------------------------|----------|-------------------|-----------------| -| **`defaultMainPage`** | object | | Defines the default landing page for authenticated and non-authenticated users. | -|     `nonAuthenticatedUser` | string | `"DATASETS"` | Default landing page for non-authenticated users. | -|     `authenticatedUser` | string | `"PROPOSALS"` | Default landing page for authenticated users. | -| `checkBoxFilterClickTrigger` | boolean | `false` | Enable/disable automatic filter application when clicking checkboxes in filters. | -| `accessTokenPrefix` | string | `"Bearer "` | Set the backend token prefix. Should be empty string for old backend or "Bearer " if using scicat-backend-next. | -| `addDatasetEnabled` | boolean | `false` | Show/hide the "Create Dataset" button in the Datasets Dashboard. | -| `archiveWorkflowEnabled` | boolean | `false` | Enable/disable the archive/retrieve workflow. | -| `datasetReduceEnabled` | boolean | `true` | Show/hide the "Reduce" tab. | -| `datasetJsonScientificMetadata` | boolean | `true` | Show/hide the "Scientific Metadata (JSON)" tab. | -| `editDatasetEnabled` | boolean | `true` | Show/hide the "Edit" buttons in the Datasets Details page | -| `editDatasetSampleEnabled` | boolean | `true` | **Deprecated** Enable/disable editing of which Sample a Dataset belongs to. | -| `editMetadataEnabled` | boolean | `true` | Enable/disable editing of Scientific Metadata. | -| `addSampleEnabled` | boolean | `false` | Show/hide the "Create Sample" button in the Sample Dashboard | -| `externalAuthEndpoint` | string | `"/api/v3/auth/msad"` | Endpoint used for third party authentication, e.g., LDAP. | -| `facility` | string | `"SciCat Vanilla"` | Facility running the SciCat instance. | -| `siteIcon` | string | `""` | **Deprecated** Path to the site icon/logo image file. | -| `siteTitle` | string | `""` | Title displayed in the header. | -| `siteSciCatLogo` | string | `""` | **Deprecated** Set to `"icon"` for icon-only display; full logo shown otherwise. | -| `loginFacilityLabel` | string | `""` | Label for the facility login option. | -| `loginLdapLabel` | string | `""` | Label for the LDAP login option. | -| `loginLocalLabel` | string | `""` | Label for the local login option. | -| `loginFacilityEnabled` | boolean | `true` | Enable/disable facility login option. | -| `loginLdapEnabled` | boolean | `true` | Enable/disable LDAP login option. | -| `loginLocalEnabled` | boolean | `true` | **Deprecated** Enable/disable local login option. | -| `fileColorEnabled` | boolean | `true` | **Deprecated** Enable/disable file size color representation in the Datasets Dashboard. | -| `fileDownloadEnabled` | boolean | `true` | Enable/disable download workflow for Dataset datafiles. | -| `gettingStarted` | string | `null` | URL to Getting Started guide for SciCat, displayed on the Help page. | -| `ingestManual` | string | `null` | URL to Ingest Manual for SciCat, displayed on the Help page. | -| `jobsEnabled` | boolean | `true` | Enable/disable Job workflow. | -| `jsonMetadataEnabled` | boolean | `true` | Show/hide the "Show Metadata" button on the details pages, allowing users to see the JSON representation of the current document. | -| `jupyterHubUrl` | string | `""` | URL to Jupyter Hub instance used for data analysis. | -| `landingPage` | string | `""` | URL to the facility's Landing Page for Published Data. | -| `lbBaseURL` | string | `""` | URL to the SciCat Backend. | -| `logbookEnabled` | boolean | `true` | Enable/disable SciChat Logbook integration. | -| `loginFormEnabled` | boolean | `true` | Enable/disable the local Login form. Should be disabled if using oAuth2 for authentication. | -| `metadataPreviewEnabled` | boolean | `true` | Enable/disable Scientific Metadata preview on the Datasets Dashboard. | -| `metadataStructure` | string | `""` | Allow tree structure for Scientific Metadata. Set to empty string for flat structure, or "tree" for tree structure. | -| `multipleDownloadAction` | string | `""` | URL to service handling direct download of datafiles. | -| `multipleDownloadEnabled` | boolean | `true` | Enable/disable ability to download multiple datafiles. | -| `oAuth2Endpoints` | array | `[]` | List of endpoints used for oAuth2 authentication. Each endpoint should have `authURL` and `displayText` properties. | -| `policiesEnabled` | boolean | `true` | Enable/disable Dataset Policies workflow. | -| `retrieveDestinations` | array | `[]` | List of destinations for Dataset retrievals. | -| `riotBaseUrl` | string | `""` | URL to SciChat client. | -| `scienceSearchEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata. | -| `scienceSearchUnitsEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata using units. | -| `searchPublicDataEnabled` | boolean | `true` | **Deprecated** Enable/disable filtering Datasets on public or non-public data. | -| `searchSamples` | boolean | `true` | Enable/disable searching Samples on Samples Dashboard. | -| `sftpHost` | string | `""` | URL to SFTP service used for downloading files exceeding maximum allowed file size. | -| `sourceFolder` | string | `""` | Default source folder path for datasets. | -| `maxDirectDownloadSize` | number | `0` | Set a maximum allowed file size for downloading datafiles over HTTP (in bytes). | -| `maxFileSizeWarning` | string | `""` | Warning message displayed when files exceed the maximum direct download size. Supports placeholders: ``, ``, ``. | -| `shareEnabled` | boolean | `true` | Enable/disable workflow for sharing Datasets with other users using their email address. | -| `shoppingCartEnabled` | boolean | `true` | Enable/disable the Dataset cart used for bulk actions. | -| `shoppingCartOnHeader` | boolean | `true` | Toggle Dataset cart placement, either on header or to the left on the Datasets Dashboard. | -| `tableSciDataEnabled` | boolean | `true` | Enable/disable Scientific Metadata table view on details pages. If disabled, Scientific Metadata is displayed as raw JSON. | -| `datasetDetailsShowMissingProposalId` | boolean | `false` | Show/hide the ProposalId property even when the proposal no longer exists | -| `notificationInterceptorEnabled` | boolean | `true` | Enable/disable a snackbar when creating, updating or deleting entities | -| `metadataEditingUnitListDisabled` | boolean | `true` | Enable/disable the unitlist dropdown in metadata edit view | -| `hideEmptyMetadataTable` | boolean | `false` | Show/hide metadata tables when it is empty | -| `datafilesActionsEnabled` | boolean | `true` | Enable/disable custom datafile actions configuration. | -| `datafilesActions` | array | `[]` | Array of custom action configurations for datafiles. Each action can define download, notebook generation, or other custom behaviors. | -| `defaultDatasetsListSettings` | object | `{}` | Configuration for datasets list columns, filters, and conditions. **Detailed documentation:** [Default List Settings Configuration](./default-list-settings.md) | -| `defaultProposalsListSettings` | object | `{}` | Configuration for proposals list columns and filters. **Detailed documentation:** [Default List Settings Configuration](./default-list-settings.md) | -| `labelsLocalization` | object | `{}` | Localization configuration for labels in datasets and proposals. Maps field names to display labels. | -| `dateFormat` | string | `"yyyy-MM-dd HH:mm"` | Default date format used throughout the application. | -| `datasetDetailComponent` | object | `{}` | Configuration for customizing the dataset detail page layout and components. **Detailed documentation:** [Dynamic Dataset Detail Component Configuration](./dynamic-dataset-detail-component.md) | -| **`mainMenu`** | object | | Configuration for main menu visibility based on user authentication status. | -|     **`nonAuthenticatedUser`** | object | | Menu configuration for non-authenticated users. | -|         `datasets` | boolean | `true` | Show/hide datasets menu item. | -|         `files` | boolean | `false` | Show/hide files menu item. | -|         `instruments` | boolean | `true` | Show/hide instruments menu item. | -|         `jobs` | boolean | `false` | Show/hide jobs menu item. | -|         `policies` | boolean | `false` | Show/hide policies menu item. | -|         `proposals` | boolean | `true` | Show/hide proposals menu item. | -|         `publishedData` | boolean | `true` | Show/hide published data menu item. | -|         `samples` | boolean | `false` | Show/hide samples menu item. | -|     **`authenticatedUser`** | object | | Menu configuration for authenticated users. | -|         `datasets` | boolean | `true` | Show/hide datasets menu item. | -|         `files` | boolean | `true` | Show/hide files menu item. | -|         `instruments` | boolean | `true` | Show/hide instruments menu item. | -|         `jobs` | boolean | `true` | Show/hide jobs menu item. | -|         `policies` | boolean | `false` | Show/hide policies menu item. | -|         `proposals` | boolean | `true` | Show/hide proposals menu item. | -|         `publishedData` | boolean | `true` | Show/hide published data menu item. | -|         `samples` | boolean | `true` | Show/hide samples menu item. | -| **`defaultTab`** | object | | Specifies which tab is shown by default when viewing different entities. | -|     `proposal` | string | `"details"` | Default tab for proposals. Valid values: `"details"`, `"datasets"`, `"relatedProposals"`, `"logbook"`. | \ No newline at end of file +| **Configuration Options** | **Type** | **Default Value** | **Description** | +| --------------------------------------------------------------- | -------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **`defaultMainPage`** | object | | Defines the default landing page for authenticated and non-authenticated users. | +|     `nonAuthenticatedUser` | string | `"DATASETS"` | Default landing page for non-authenticated users. | +|     `authenticatedUser` | string | `"PROPOSALS"` | Default landing page for authenticated users. | +| `statusBannerMessage` | string | `""` | Message displayed in the dismissible status banner. If not provided, the banner will not be shown. | +| `statusBannerCode` | string | `INFO` | Defines the statusBanner style. Supported values: `INFO` or `WARN`. Defaults to `INFO` if not provided. | +| `checkBoxFilterClickTrigger` | boolean | `false` | Enable/disable automatic filter application when clicking checkboxes in filters. | +| `accessTokenPrefix` | string | `"Bearer "` | Set the backend token prefix. Should be empty string for old backend or "Bearer " if using scicat-backend-next. | +| `addDatasetEnabled` | boolean | `false` | Show/hide the "Create Dataset" button in the Datasets Dashboard. | +| `archiveWorkflowEnabled` | boolean | `false` | Enable/disable the archive/retrieve workflow. | +| `datasetReduceEnabled` | boolean | `true` | Show/hide the "Reduce" tab. | +| `datasetJsonScientificMetadata` | boolean | `true` | Show/hide the "Scientific Metadata (JSON)" tab. | +| `editDatasetEnabled` | boolean | `true` | Show/hide the "Edit" buttons in the Datasets Details page | +| `editDatasetSampleEnabled` | boolean | `true` | **Deprecated** Enable/disable editing of which Sample a Dataset belongs to. | +| `editMetadataEnabled` | boolean | `true` | Enable/disable editing of Scientific Metadata. | +| `addSampleEnabled` | boolean | `false` | Show/hide the "Create Sample" button in the Sample Dashboard | +| `externalAuthEndpoint` | string | `"/api/v3/auth/msad"` | Endpoint used for third party authentication, e.g., LDAP. | +| `facility` | string | `"SciCat Vanilla"` | Facility running the SciCat instance. | +| `siteIcon` | string | `""` | **Deprecated** Path to the site icon/logo image file. | +| `siteTitle` | string | `""` | Title displayed in the header. | +| `siteSciCatLogo` | string | `""` | **Deprecated** Set to `"icon"` for icon-only display; full logo shown otherwise. | +| `loginFacilityLabel` | string | `""` | Label for the facility login option. | +| `loginLdapLabel` | string | `""` | Label for the LDAP login option. | +| `loginLocalLabel` | string | `""` | Label for the local login option. | +| `loginFacilityEnabled` | boolean | `true` | Enable/disable facility login option. | +| `loginLdapEnabled` | boolean | `true` | Enable/disable LDAP login option. | +| `loginLocalEnabled` | boolean | `true` | **Deprecated** Enable/disable local login option. | +| `fileColorEnabled` | boolean | `true` | **Deprecated** Enable/disable file size color representation in the Datasets Dashboard. | +| `fileDownloadEnabled` | boolean | `true` | Enable/disable download workflow for Dataset datafiles. | +| `gettingStarted` | string | `null` | URL to Getting Started guide for SciCat, displayed on the Help page. | +| `ingestManual` | string | `null` | URL to Ingest Manual for SciCat, displayed on the Help page. | +| `jobsEnabled` | boolean | `true` | Enable/disable Job workflow. | +| `jsonMetadataEnabled` | boolean | `true` | Show/hide the "Show Metadata" button on the details pages, allowing users to see the JSON representation of the current document. | +| `jupyterHubUrl` | string | `""` | URL to Jupyter Hub instance used for data analysis. | +| `landingPage` | string | `""` | URL to the facility's Landing Page for Published Data. | +| `lbBaseURL` | string | `""` | URL to the SciCat Backend. | +| `logbookEnabled` | boolean | `true` | Enable/disable SciChat Logbook integration. | +| `loginFormEnabled` | boolean | `true` | Enable/disable the local Login form. Should be disabled if using oAuth2 for authentication. | +| `metadataPreviewEnabled` | boolean | `true` | Enable/disable Scientific Metadata preview on the Datasets Dashboard. | +| `metadataStructure` | string | `""` | Allow tree structure for Scientific Metadata. Set to empty string for flat structure, or "tree" for tree structure. | +| `multipleDownloadAction` | string | `""` | URL to service handling direct download of datafiles. | +| `multipleDownloadEnabled` | boolean | `true` | Enable/disable ability to download multiple datafiles. | +| `oAuth2Endpoints` | array | `[]` | List of endpoints used for oAuth2 authentication. Each endpoint should have `authURL` and `displayText` properties. | +| `policiesEnabled` | boolean | `true` | Enable/disable Dataset Policies workflow. | +| `retrieveDestinations` | array | `[]` | List of destinations for Dataset retrievals. | +| `riotBaseUrl` | string | `""` | URL to SciChat client. | +| `scienceSearchEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata. | +| `scienceSearchUnitsEnabled` | boolean | `true` | Enable/disable filtering documents on Scientific Metadata using units. | +| `searchPublicDataEnabled` | boolean | `true` | **Deprecated** Enable/disable filtering Datasets on public or non-public data. | +| `searchSamples` | boolean | `true` | Enable/disable searching Samples on Samples Dashboard. | +| `sftpHost` | string | `""` | URL to SFTP service used for downloading files exceeding maximum allowed file size. | +| `sourceFolder` | string | `""` | Default source folder path for datasets. | +| `maxDirectDownloadSize` | number | `0` | Set a maximum allowed file size for downloading datafiles over HTTP (in bytes). | +| `maxFileSizeWarning` | string | `""` | Warning message displayed when files exceed the maximum direct download size. Supports placeholders: ``, ``, ``. | +| `shareEnabled` | boolean | `true` | Enable/disable workflow for sharing Datasets with other users using their email address. | +| `shoppingCartEnabled` | boolean | `true` | Enable/disable the Dataset cart used for bulk actions. | +| `shoppingCartOnHeader` | boolean | `true` | Toggle Dataset cart placement, either on header or to the left on the Datasets Dashboard. | +| `tableSciDataEnabled` | boolean | `true` | Enable/disable Scientific Metadata table view on details pages. If disabled, Scientific Metadata is displayed as raw JSON. | +| `datasetDetailsShowMissingProposalId` | boolean | `false` | Show/hide the ProposalId property even when the proposal no longer exists | +| `notificationInterceptorEnabled` | boolean | `true` | Enable/disable a snackbar when creating, updating or deleting entities | +| `metadataEditingUnitListDisabled` | boolean | `true` | Enable/disable the unitlist dropdown in metadata edit view | +| `hideEmptyMetadataTable` | boolean | `false` | Show/hide metadata tables when it is empty | +| `datafilesActionsEnabled` | boolean | `true` | Enable/disable custom datafile actions configuration. | +| `datafilesActions` | array | `[]` | Array of custom action configurations for datafiles. Each action can define download, notebook generation, or other custom behaviors. | +| `defaultDatasetsListSettings` | object | `{}` | Configuration for datasets list columns, filters, and conditions. **Detailed documentation:** [Default List Settings Configuration](./default-list-settings.md) | +| `defaultProposalsListSettings` | object | `{}` | Configuration for proposals list columns and filters. **Detailed documentation:** [Default List Settings Configuration](./default-list-settings.md) | +| `labelsLocalization` | object | `{}` | Localization configuration for labels in datasets and proposals. Maps field names to display labels. | +| `dateFormat` | string | `"yyyy-MM-dd HH:mm"` | Default date format used throughout the application. | +| `datasetDetailComponent` | object | `{}` | Configuration for customizing the dataset detail page layout and components. **Detailed documentation:** [Dynamic Dataset Detail Component Configuration](./dynamic-dataset-detail-component.md) | +| **`mainMenu`** | object | | Configuration for main menu visibility based on user authentication status. | +|     **`nonAuthenticatedUser`** | object | | Menu configuration for non-authenticated users. | +|         `datasets` | boolean | `true` | Show/hide datasets menu item. | +|         `files` | boolean | `false` | Show/hide files menu item. | +|         `instruments` | boolean | `true` | Show/hide instruments menu item. | +|         `jobs` | boolean | `false` | Show/hide jobs menu item. | +|         `policies` | boolean | `false` | Show/hide policies menu item. | +|         `proposals` | boolean | `true` | Show/hide proposals menu item. | +|         `publishedData` | boolean | `true` | Show/hide published data menu item. | +|         `samples` | boolean | `false` | Show/hide samples menu item. | +|     **`authenticatedUser`** | object | | Menu configuration for authenticated users. | +|         `datasets` | boolean | `true` | Show/hide datasets menu item. | +|         `files` | boolean | `true` | Show/hide files menu item. | +|         `instruments` | boolean | `true` | Show/hide instruments menu item. | +|         `jobs` | boolean | `true` | Show/hide jobs menu item. | +|         `policies` | boolean | `false` | Show/hide policies menu item. | +|         `proposals` | boolean | `true` | Show/hide proposals menu item. | +|         `publishedData` | boolean | `true` | Show/hide published data menu item. | +|         `samples` | boolean | `true` | Show/hide samples menu item. | +| **`defaultTab`** | object | | Specifies which tab is shown by default when viewing different entities. | +|     `proposal` | string | `"details"` | Default tab for proposals. Valid values: `"details"`, `"datasets"`, `"relatedProposals"`, `"logbook"`. | diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 0554e687c..b96a307a5 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -3,10 +3,12 @@ "nonAuthenticatedUser": "DATASETS", "authenticatedUser": "PROPOSALS" }, + "statusBannerMessage": "", + "statusBannerCode": "INFO", "checkBoxFilterClickTrigger": false, "accessTokenPrefix": "Bearer ", "addDatasetEnabled": false, - "allowConfigOverrides": true, + "allowConfigOverrides": true, "archiveWorkflowEnabled": false, "datasetReduceEnabled": true, "datasetJsonScientificMetadata": true, @@ -90,16 +92,16 @@ "type": "form", "url": "https://zip.scicatproject.org/download/all", "target": "_blank", - "variables" : { + "variables": { "pid": "#Dataset0Pid", "files": "#Dataset0FilesPath", "totalSize": "#Dataset0FilesTotalSize", "folder": "#Dataset0SourceFolder" }, "enabled": "#MaxDownloadableSize(@totalSize)", - "inputs" : { - "item[]" : "@pid", - "directory[]" : "@folder", + "inputs": { + "item[]": "@pid", + "directory[]": "@folder", "files[]": "@files" }, "authorization": ["#datasetAccess", "#datasetPublic"] @@ -114,18 +116,18 @@ "type": "form", "url": "https://zip.scicatproject.org/download/selected", "target": "_blank", - "variables" : { + "variables": { "pid": "#Dataset0Pid", "files": "#Dataset0SelectedFilesPath", "selected": "#Dataset0SelectedFilesCount", "totalSize": "#Dataset0SelectedFilesTotalSize", "folder": "#Dataset0SourceFolder" }, - "inputs" : { - "auth_token" : "#tokenBearer", - "jwt" : "#jwt", - "item[]" : "@pid", - "directory[]" : "@folder", + "inputs": { + "auth_token": "#tokenBearer", + "jwt": "#jwt", + "item[]": "@pid", + "directory[]": "@folder", "files[]": "@files" }, "enabled": "#Length(@files) && #MaxDownloadableSize(@totalSize)", @@ -141,18 +143,18 @@ "type": "form", "url": "https://www.scicat.info/notebook/all", "target": "_blank", - "variables" : { + "variables": { "pid": "#Dataset0Pid", "files": "#Dataset0FilesPath", "totalSize": "#Dataset0FilesTotalSize", "folder": "#Dataset0SourceFolder" }, "enabled": "", - "inputs" : { - "auth_token" : "#token", - "jwt" : "#jwt", - "item[]" : "@pid", - "directory[]" : "@folder", + "inputs": { + "auth_token": "#token", + "jwt": "#jwt", + "item[]": "@pid", + "directory[]": "@folder", "files[]": "@files" }, "authorization": ["#datasetAccess", "#datasetPublic"] @@ -166,18 +168,18 @@ "type": "form", "url": "https://www.scicat.info/notebook/selected", "target": "_blank", - "variables" : { + "variables": { "pid": "#Dataset0Pid", "files": "#Dataset0SelectedFilesPath", "selected": "#Dataset0SelectedFilesCount", "totalSize": "#Dataset0SelectedFilesTotalSize", "folder": "#Dataset0SourceFolder" }, - "inputs" : { - "auth_token" : "#token", - "jwt" : "#jwt", - "item[]" : "@pid", - "directory[]" : "@folder", + "inputs": { + "auth_token": "#token", + "jwt": "#jwt", + "item[]": "@pid", + "directory[]": "@folder", "files[]": "@files" }, "enabled": "#Length(@files) > 0", @@ -194,7 +196,7 @@ "url": "https://www.sciwyrm.info/notebook", "target": "_blank", "authorization": ["#datasetAccess", "#datasetPublic"], - "variables" : { + "variables": { "pid": "#Dataset0Pid", "files": "#Dataset0FilesPath", "folder": "#Dataset0SourceFolder" @@ -213,7 +215,7 @@ "target": "_blank", "enabled": "#Length(@files) > 0", "authorization": ["#datasetAccess", "#datasetPublic"], - "variables" : { + "variables": { "pid": "#Dataset0Pid", "files": "#Dataset0SelectedFilesPath", "selected": "#Dataset0SelectedFiles", @@ -229,14 +231,14 @@ "label": "Publish", "type": "xhr", "mat_icon": "lock_open", - "method" : "PATCH", + "method": "PATCH", "url": "http://localhost:3000/dataset/{{ @pid }}/", "target": "_blank", "enabled": "(#datasetOwner || #userIsAdmin) && !@isPublished", "authorization": "#datasetOwner && !@isPublished", - "variables" : { + "variables": { "pid": "@Dataset0Pid", - "isPublished" : "#Dataset[0]Field[isPublished]" + "isPublished": "#Dataset[0]Field[isPublished]" }, "payload": "{\"isPublished\":\"true\"}", "headers": { @@ -251,14 +253,14 @@ "label": "Unpublish", "type": "xhr", "mat_icon": "lock", - "method" : "PATCH", + "method": "PATCH", "url": "http://localhost:3000/dataset/{{ @pid }}/", "target": "_blank", "enabled": "(#datasetOwner || #userIsAdmin) && @isPublished", "authorization": "#datasetOwner && @isPublished", - "variables" : { + "variables": { "pid": "#Dataset0Pid", - "isPublished" : "#Dataset[0]Field[isPublished]" + "isPublished": "#Dataset[0]Field[isPublished]" }, "payload": "{\"isPublished\":\"false\"}", "headers": { From 963355c9e322b3d8d51192844b4808fd1c350f27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 10:41:33 +0000 Subject: [PATCH 082/120] build(deps-dev): bump flatted from 3.3.3 to 3.4.2 Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.3 to 3.4.2. - [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2) --- updated-dependencies: - dependency-name: flatted dependency-version: 3.4.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c2123b0a..137f27e98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7697,10 +7697,11 @@ "integrity": "sha512-dLVCAISd5mhls514keQzmEG6QHmUUsNuWsb4tFafIUwvvgDjXhtfAYSKOzt5SWOy+qByV5pbsDZ+Vb7HUOBEdA==" }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" }, "node_modules/fn.name": { "version": "1.1.0", From 7138c4cf778c63b0927b67eb59bea314d783eec4 Mon Sep 17 00:00:00 2001 From: abdimo101 Date: Mon, 23 Mar 2026 15:19:54 +0100 Subject: [PATCH 083/120] feat(config): add sort property for columns default list settings (#2587) added sort property --- docs/frontend-config-guide/default-list-settings.md | 2 +- src/config/frontend.config.json | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/frontend-config-guide/default-list-settings.md b/docs/frontend-config-guide/default-list-settings.md index f84d19e21..f3f57c043 100644 --- a/docs/frontend-config-guide/default-list-settings.md +++ b/docs/frontend-config-guide/default-list-settings.md @@ -21,7 +21,7 @@ Defines how each field is displayed in the list table. | `width` | `number` | Default width of the column. | `200` | | `format` | `string` | Optional property used **only** when `type` is set to `date`. Defines how ISO date strings are displayed (e.g. `yyyy-MM-dd`).
it fallsback to `dateFormat` or `yyyy-MM-dd HH:mm` for dataset and `yyyy-MM-dd` for proposal | `"yyyy-MM-dd"` | | `enabled` | `boolean` | Whether the column is displayed by default. | `true` | - +| `sort` | `string` | Optional property to define the default sort direction for a specific column. Accepts `"asc"` or `"desc"`.
**Note:** Only one column in the `defaultProposalsListSettings` or `defaultDatasetsListSettings` should have this property defined. If not specified anywhere, the table defaults to sorting by the `createdAt` column in descending order. | `"desc"` | --- ### **Filters** diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index b96a307a5..56e67de1e 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -470,7 +470,8 @@ "type": "date", "width": 200, "enabled": false, - "format": "yyyy-mm-dd HH:MM" + "format": "yyyy-mm-dd HH:MM", + "sort": "desc" }, { "name": "endTime", @@ -584,7 +585,8 @@ "type": "date", "format": "yyyy-MM-dd", "width": 130, - "enabled": true + "enabled": true, + "sort": "desc" }, { "name": "pi_lastname, pi_firstname", From 35fa06ac204f17d23b5dcb54a3f66cf8d397ae71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:25:03 +0000 Subject: [PATCH 084/120] build(deps-dev): bump @typescript-eslint/parser from 8.57.0 to 8.57.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.57.0 to 8.57.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.57.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.57.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 183 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 137f27e98..4d519059e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3912,16 +3912,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz", - "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", + "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3" }, "engines": { @@ -3936,6 +3936,175 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", + "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.57.1", + "@typescript-eslint/types": "^8.57.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.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", + "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.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.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", + "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "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.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", + "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "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.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", + "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.57.1", + "@typescript-eslint/tsconfig-utils": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.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.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", + "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.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.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "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.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/project-service": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", From f99e70c8bb03c96da110774793d84eeae5968309 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:30:43 +0000 Subject: [PATCH 085/120] build(deps-dev): bump eslint from 10.0.3 to 10.1.0 Bumps [eslint](https://github.com/eslint/eslint) from 10.0.3 to 10.1.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.0.3...v10.1.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d519059e..6b4c8b9d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7101,16 +7101,16 @@ } }, "node_modules/eslint": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.3.tgz", - "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz", + "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.3", - "@eslint/config-helpers": "^0.5.2", + "@eslint/config-helpers": "^0.5.3", "@eslint/core": "^1.1.1", "@eslint/plugin-kit": "^0.6.1", "@humanfs/node": "^0.16.6", @@ -7123,7 +7123,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", - "espree": "^11.1.1", + "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", From 233d426df617d7f6fe3dbb37c320030a92cf92c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:33:54 +0000 Subject: [PATCH 086/120] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.57.0 to 8.57.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.57.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 241 +++++++--------------------------------------- 1 file changed, 36 insertions(+), 205 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b4c8b9d0..ffe6c74e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3873,17 +3873,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", - "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", + "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/type-utils": "8.57.0", - "@typescript-eslint/utils": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/type-utils": "8.57.1", + "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3896,7 +3896,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.0", + "@typescript-eslint/parser": "^8.57.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3936,7 +3936,7 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "node_modules/@typescript-eslint/project-service": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", @@ -3958,7 +3958,7 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", @@ -3976,7 +3976,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", @@ -3993,185 +3993,16 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", - "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.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.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.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/type-utils": { "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", + "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.57.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.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "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.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", - "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.0", - "@typescript-eslint/types": "^8.57.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.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", - "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.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/tsconfig-utils": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", - "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", - "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.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", - "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/utils": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/utils": "8.57.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -4188,9 +4019,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz", - "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", + "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", "dev": true, "license": "MIT", "engines": { @@ -4202,16 +4033,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", - "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", + "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.0", - "@typescript-eslint/tsconfig-utils": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", + "@typescript-eslint/project-service": "8.57.1", + "@typescript-eslint/tsconfig-utils": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -4269,16 +4100,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz", - "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", + "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0" + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4293,13 +4124,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", - "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", + "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/types": "8.57.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { From d4cb68a5a43a7ec89675ae6984f713bee01955a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:37:45 +0000 Subject: [PATCH 087/120] build(deps): bump @nestjs-modules/mailer in the nestjs group Bumps the nestjs group with 1 update: [@nestjs-modules/mailer](https://github.com/nest-modules/mailer). Updates `@nestjs-modules/mailer` from 2.0.2 to 2.3.0 - [Release notes](https://github.com/nest-modules/mailer/releases) - [Commits](https://github.com/nest-modules/mailer/compare/v2.0.2...@nestjs-modules/mailer@2.3.0) --- updated-dependencies: - dependency-name: "@nestjs-modules/mailer" dependency-version: 2.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 3013 ++++++++++++++++++++++++++++----------------- 1 file changed, 1891 insertions(+), 1122 deletions(-) diff --git a/package-lock.json b/package-lock.json index ffe6c74e0..e47dd6fe2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -264,7 +264,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -721,12 +721,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -840,32 +838,35 @@ } }, "node_modules/@css-inline/css-inline": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline/-/css-inline-0.14.1.tgz", - "integrity": "sha512-u4eku+hnPqqHIGq/ZUQcaP0TrCbYeLIYBaK7qClNRGZbnh8RC4gVxLEIo8Pceo1nOK9E5G4Lxzlw5KnXcvflfA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline/-/css-inline-0.20.0.tgz", + "integrity": "sha512-WABsvMSBs/DDadwhAUDw6uXwUE6w4DC/bnC4E2Y2rqbCTw5E1PPfj6VksnSCALkv9ynZfYGYYO4+Rvhmn5kgpw==", + "license": "MIT", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@css-inline/css-inline-android-arm-eabi": "0.14.1", - "@css-inline/css-inline-android-arm64": "0.14.1", - "@css-inline/css-inline-darwin-arm64": "0.14.1", - "@css-inline/css-inline-darwin-x64": "0.14.1", - "@css-inline/css-inline-linux-arm-gnueabihf": "0.14.1", - "@css-inline/css-inline-linux-arm64-gnu": "0.14.1", - "@css-inline/css-inline-linux-arm64-musl": "0.14.1", - "@css-inline/css-inline-linux-x64-gnu": "0.14.1", - "@css-inline/css-inline-linux-x64-musl": "0.14.1", - "@css-inline/css-inline-win32-x64-msvc": "0.14.1" + "@css-inline/css-inline-android-arm-eabi": "0.20.0", + "@css-inline/css-inline-android-arm64": "0.20.0", + "@css-inline/css-inline-darwin-arm64": "0.20.0", + "@css-inline/css-inline-darwin-x64": "0.20.0", + "@css-inline/css-inline-linux-arm-gnueabihf": "0.20.0", + "@css-inline/css-inline-linux-arm64-gnu": "0.20.0", + "@css-inline/css-inline-linux-arm64-musl": "0.20.0", + "@css-inline/css-inline-linux-x64-gnu": "0.20.0", + "@css-inline/css-inline-linux-x64-musl": "0.20.0", + "@css-inline/css-inline-win32-arm64-msvc": "0.20.0", + "@css-inline/css-inline-win32-x64-msvc": "0.20.0" } }, "node_modules/@css-inline/css-inline-android-arm-eabi": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm-eabi/-/css-inline-android-arm-eabi-0.14.1.tgz", - "integrity": "sha512-LNUR8TY4ldfYi0mi/d4UNuHJ+3o8yLQH9r2Nt6i4qeg1i7xswfL3n/LDLRXvGjBYqeEYNlhlBQzbPwMX1qrU6A==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm-eabi/-/css-inline-android-arm-eabi-0.20.0.tgz", + "integrity": "sha512-w1+cicyd2xGzuOcFYxL9Yp3E/KT6opGpdhaKo1vFAepyn8zHrpAR3c1DHH1RWSWK3ZVcD3ne1naqJXQa4k/9uw==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -875,12 +876,13 @@ } }, "node_modules/@css-inline/css-inline-android-arm64": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm64/-/css-inline-android-arm64-0.14.1.tgz", - "integrity": "sha512-tH5us0NYGoTNBHOUHVV7j9KfJ4DtFOeTLA3cM0XNoMtArNu2pmaaBMFJPqECzavfXkLc7x5Z22UPZYjoyHfvCA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm64/-/css-inline-android-arm64-0.20.0.tgz", + "integrity": "sha512-V6ELV+DEjhYPqRcyCezUcMDSrXINMSCL4RBseEqWG18WhOZ9GoGd5XFpZzciQhHq/2MQS+06Jcc6RX59k7QS5g==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -890,12 +892,13 @@ } }, "node_modules/@css-inline/css-inline-darwin-arm64": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-arm64/-/css-inline-darwin-arm64-0.14.1.tgz", - "integrity": "sha512-QE5W1YRIfRayFrtrcK/wqEaxNaqLULPI0gZB4ArbFRd3d56IycvgBasDTHPre5qL2cXCO3VyPx+80XyHOaVkag==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-arm64/-/css-inline-darwin-arm64-0.20.0.tgz", + "integrity": "sha512-hT8Mtwp4PJ9mMYFDG/xg7KCa7nPqseJdXaajxXVjXB8+6oemxgx+7TUO7HSfmeY4Ox7X2vaNfaIfti4ySgNvyg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -905,12 +908,13 @@ } }, "node_modules/@css-inline/css-inline-darwin-x64": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-x64/-/css-inline-darwin-x64-0.14.1.tgz", - "integrity": "sha512-mAvv2sN8awNFsbvBzlFkZPbCNZ6GCWY5/YcIz7V5dPYw+bHHRbjnlkNTEZq5BsDxErVrMIGvz05PGgzuNvZvdQ==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-x64/-/css-inline-darwin-x64-0.20.0.tgz", + "integrity": "sha512-caFvVySabHZG4N1QUysbhWp2+VstMlYLysZYfAX0I6c9QfWcr+OZThoGOO2gC9lYy6QMCTBSD+9t+iceH9oBQw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -920,12 +924,13 @@ } }, "node_modules/@css-inline/css-inline-linux-arm-gnueabihf": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm-gnueabihf/-/css-inline-linux-arm-gnueabihf-0.14.1.tgz", - "integrity": "sha512-AWC44xL0X7BgKvrWEqfSqkT2tJA5kwSGrAGT+m0gt11wnTYySvQ6YpX0fTY9i3ppYGu4bEdXFjyK2uY1DTQMHA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm-gnueabihf/-/css-inline-linux-arm-gnueabihf-0.20.0.tgz", + "integrity": "sha512-9/TdB6cHgJ285uL7Y+1XjdJGjIQOeF9/YNq47N+azf2SiYdA3ahGYBmZhCGtYG7aBTJly9iJCxjP9ZZN8+Lajw==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -935,12 +940,13 @@ } }, "node_modules/@css-inline/css-inline-linux-arm64-gnu": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-gnu/-/css-inline-linux-arm64-gnu-0.14.1.tgz", - "integrity": "sha512-drj0ciiJgdP3xKXvNAt4W+FH4KKMs8vB5iKLJ3HcH07sNZj58Sx++2GxFRS1el3p+GFp9OoYA6dgouJsGEqt0Q==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-gnu/-/css-inline-linux-arm64-gnu-0.20.0.tgz", + "integrity": "sha512-umcG26teSSUxWGQm7sECI8KweUgBgq9Cqd6yNMTNzqC1K56ZhW3Iwi7QewVNGOpVPXoGsywIIwIuY9lyed1Jdw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -950,12 +956,13 @@ } }, "node_modules/@css-inline/css-inline-linux-arm64-musl": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-musl/-/css-inline-linux-arm64-musl-0.14.1.tgz", - "integrity": "sha512-FzknI+st8eA8YQSdEJU9ykcM0LZjjigBuynVF5/p7hiMm9OMP8aNhWbhZ8LKJpKbZrQsxSGS4g9Vnr6n6FiSdQ==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-musl/-/css-inline-linux-arm64-musl-0.20.0.tgz", + "integrity": "sha512-wHQykZw3pX2R5Yp5VChOWzVXXO3XPdgWkQH1B9QBmft926EOkZpwxvubeAYy9I89qJzzdGNqiRl26+AUP88J3A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -965,12 +972,13 @@ } }, "node_modules/@css-inline/css-inline-linux-x64-gnu": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-gnu/-/css-inline-linux-x64-gnu-0.14.1.tgz", - "integrity": "sha512-yubbEye+daDY/4vXnyASAxH88s256pPati1DfVoZpU1V0+KP0BZ1dByZOU1ktExurbPH3gZOWisAnBE9xon0Uw==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-gnu/-/css-inline-linux-x64-gnu-0.20.0.tgz", + "integrity": "sha512-lHQZ+31CN3XJTn5MMFv1NYjyvuhAWEvul0fAYyppw4haA1TM+9UuA9jXdjqWXp26ItmainUnDMBlNLYQwMYt7g==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -980,12 +988,13 @@ } }, "node_modules/@css-inline/css-inline-linux-x64-musl": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-musl/-/css-inline-linux-x64-musl-0.14.1.tgz", - "integrity": "sha512-6CRAZzoy1dMLPC/tns2rTt1ZwPo0nL/jYBEIAsYTCWhfAnNnpoLKVh5Nm+fSU3OOwTTqU87UkGrFJhObD/wobQ==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-musl/-/css-inline-linux-x64-musl-0.20.0.tgz", + "integrity": "sha512-DO/cba/zndTY3s86nNNfeHx7DvrvLb+IxhkQWTr29IQeiUgbawCH9X3B/4Li2eo/sEx/imOOnYDdXYu8PeX2Fg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -994,13 +1003,30 @@ "node": ">= 10" } }, + "node_modules/@css-inline/css-inline-win32-arm64-msvc": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-arm64-msvc/-/css-inline-win32-arm64-msvc-0.20.0.tgz", + "integrity": "sha512-1o8xla5ljVHS7SguH6nTV6uoAIMRZv+2MrcxfLRObpkUtCO7oKXDeWnia7XlmnLhDX8Ncx5bDOenZb1N35kCiA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@css-inline/css-inline-win32-x64-msvc": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-x64-msvc/-/css-inline-win32-x64-msvc-0.14.1.tgz", - "integrity": "sha512-nzotGiaiuiQW78EzsiwsHZXbxEt6DiMUFcDJ6dhiliomXxnlaPyBfZb6/FMBgRJOf6sknDt/5695OttNmbMYzg==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-x64-msvc/-/css-inline-win32-x64-msvc-0.20.0.tgz", + "integrity": "sha512-pdO/QXLRwuq/RxO5PSFMhmWGJSQOvkiDyV4RrewEkE7SOCY8HAYNhx1T0y0pj2WzxuVdbNQbpwiCHAdQNplUJw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1790,6 +1816,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "devOptional": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1806,6 +1833,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "devOptional": true, "engines": { "node": ">=12" }, @@ -1816,12 +1844,14 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "devOptional": true }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "devOptional": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1838,6 +1868,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "devOptional": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -2243,22 +2274,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@jest/reporters/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/@jest/reporters/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -2400,7 +2415,7 @@ "version": "0.3.12", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -2411,7 +2426,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -2420,7 +2435,7 @@ "version": "0.3.11", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -2431,13 +2446,13 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.29", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2503,37 +2518,121 @@ } }, "node_modules/@nestjs-modules/mailer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.0.2.tgz", - "integrity": "sha512-+z4mADQasg0H1ZaGu4zZTuKv2pu+XdErqx99PLFPzCDNTN/q9U59WPgkxVaHnsvKHNopLj5Xap7G4ZpptduoYw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.3.0.tgz", + "integrity": "sha512-C9FQOz+GKSIgJKWfUVJHuOCfbhhcQxitHcH1+Gl/nSVR/w+PhvrC/dk4h+pwB//5KYe4aPeE7Ia1slgIVjeAJQ==", + "license": "MIT", "dependencies": { - "@css-inline/css-inline": "0.14.1", - "glob": "10.3.12" + "@css-inline/css-inline": "0.20.0", + "glob": "13.0.6", + "tslib": "^2.8.1" }, "optionalDependencies": { "@types/ejs": "^3.1.5", "@types/mjml": "^4.7.4", "@types/pug": "^2.0.10", - "ejs": "^3.1.10", + "ejs": "^5.0.1", "handlebars": "^4.7.8", - "liquidjs": "^10.11.1", - "mjml": "^4.15.3", - "preview-email": "^3.0.19", - "pug": "^3.0.2" + "liquidjs": "^10.25.0", + "mjml": "^5.0.0-alpha.4", + "nunjucks": "^3.2.4", + "preview-email": "^3.1.1", + "pug": "^3.0.4" }, "peerDependencies": { "@nestjs/common": ">=7.0.9", "@nestjs/core": ">=7.0.9", + "@nestjs/event-emitter": ">=2.0.0", + "@nestjs/terminus": ">=10.0.0", "@types/ejs": ">=3.0.3", "@types/mjml": ">=4.7.4", "@types/pug": ">=2.0.6", + "bullmq": ">=4.0.0", "ejs": ">=3.1.2", "handlebars": ">=4.7.6", "liquidjs": ">=10.8.2", "mjml": ">=4.15.3", "nodemailer": ">=6.4.6", + "nunjucks": ">=3.2.0", "preview-email": ">=3.0.19", "pug": ">=3.0.1" + }, + "peerDependenciesMeta": { + "@nestjs/event-emitter": { + "optional": true + }, + "@nestjs/terminus": { + "optional": true + }, + "@types/ejs": { + "optional": true + }, + "@types/mjml": { + "optional": true + }, + "@types/pug": { + "optional": true + }, + "bullmq": { + "optional": true + }, + "ejs": { + "optional": true + }, + "handlebars": { + "optional": true + }, + "liquidjs": { + "optional": true + }, + "mjml": { + "optional": true + }, + "nunjucks": { + "optional": true + }, + "preview-email": { + "optional": true + }, + "pug": { + "optional": true + } + } + }, + "node_modules/@nestjs-modules/mailer/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@nestjs-modules/mailer/node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, "node_modules/@nestjs/axios": { @@ -3149,12 +3248,6 @@ "npm": ">=5.10.0" } }, - "node_modules/@one-ini/wasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", - "optional": true - }, "node_modules/@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", @@ -3770,6 +3863,13 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, + "node_modules/@types/relateurl": { + "version": "0.2.33", + "resolved": "https://registry.npmjs.org/@types/relateurl/-/relateurl-0.2.33.tgz", + "integrity": "sha512-bTQCKsVbIdzLqZhLkF5fcJQreE4y1ro4DIyVrlDNSCJRRwHhB8Z+4zXXa8jN6eDvc2HbRsEYgbvrnGvi54EpSw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -4661,6 +4761,13 @@ "libqp": "2.1.1" } }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "license": "MIT", + "optional": true + }, "node_modules/abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", @@ -4682,7 +4789,7 @@ "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5002,6 +5109,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "license": "MIT", "optional": true }, "node_modules/assert-plus": { @@ -5146,6 +5254,7 @@ "version": "3.0.0-canary-5", "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "license": "MIT", "optional": true, "dependencies": { "@babel/types": "^7.9.6" @@ -5195,7 +5304,7 @@ "version": "2.9.7", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -5224,6 +5333,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", "optional": true, "engines": { "node": ">=8" @@ -5277,6 +5387,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC", "optional": true }, "node_modules/boxen": { @@ -5342,7 +5453,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -5371,7 +5482,7 @@ "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "opencollective", @@ -5521,21 +5632,11 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } }, - "node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "optional": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -5547,11 +5648,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001760", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", - "dev": true, + "devOptional": true, "funding": [ { "type": "opencollective", @@ -5670,21 +5784,26 @@ } }, "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "license": "MIT", "optional": true, "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=18.17" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -5694,6 +5813,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", "optional": true, "dependencies": { "boolbase": "^1.0.0", @@ -5707,6 +5827,26 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -5769,27 +5909,6 @@ "validator": "^13.15.22" } }, - "node_modules/clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "optional": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", @@ -5985,6 +6104,13 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT", + "optional": true + }, "node_modules/colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", @@ -6099,7 +6225,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "devOptional": true + "dev": true }, "node_modules/concat-stream": { "version": "2.0.0", @@ -6156,16 +6282,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "optional": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, "node_modules/connect-mongo": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-6.0.0.tgz", @@ -6320,6 +6436,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "devOptional": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6329,10 +6446,24 @@ "node": ">= 8" } }, + "node_modules/css-declaration-sorter": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.1.tgz", + "integrity": "sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==", + "license": "ISC", + "optional": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", "optional": true, "dependencies": { "boolbase": "^1.0.0", @@ -6345,10 +6476,25 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "license": "MIT", + "optional": true, + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", "optional": true, "engines": { "node": ">= 6" @@ -6357,36 +6503,183 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "optional": true, + "bin": { + "cssesc": "bin/cssesc" + }, "engines": { - "node": ">= 12" + "node": ">=4" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/cssnano": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.3.tgz", + "integrity": "sha512-mLFHQAzyapMVFLiJIn7Ef4C2UCEvtlTlbyILR6B5ZsUAV3D/Pa761R5uC1YPhyBkRd3eqaDm2ncaNrD7R4mTRg==", "license": "MIT", + "optional": true, "dependencies": { - "ms": "^2.1.3" + "cssnano-preset-default": "^7.0.11", + "lilconfig": "^3.1.3" }, "engines": { - "node": ">=6.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.32" } }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, + "node_modules/cssnano-preset-default": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.11.tgz", + "integrity": "sha512-waWlAMuCakP7//UCY+JPrQS1z0OSLeOXk2sKWJximKWGupVxre50bzPlvpbUwZIDylhf/ptf0Pk+Yf7C+hoa3g==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.1", + "postcss-calc": "^10.1.1", + "postcss-colormin": "^7.0.6", + "postcss-convert-values": "^7.0.9", + "postcss-discard-comments": "^7.0.6", + "postcss-discard-duplicates": "^7.0.2", + "postcss-discard-empty": "^7.0.1", + "postcss-discard-overridden": "^7.0.1", + "postcss-merge-longhand": "^7.0.5", + "postcss-merge-rules": "^7.0.8", + "postcss-minify-font-values": "^7.0.1", + "postcss-minify-gradients": "^7.0.1", + "postcss-minify-params": "^7.0.6", + "postcss-minify-selectors": "^7.0.6", + "postcss-normalize-charset": "^7.0.1", + "postcss-normalize-display-values": "^7.0.1", + "postcss-normalize-positions": "^7.0.1", + "postcss-normalize-repeat-style": "^7.0.1", + "postcss-normalize-string": "^7.0.1", + "postcss-normalize-timing-functions": "^7.0.1", + "postcss-normalize-unicode": "^7.0.6", + "postcss-normalize-url": "^7.0.1", + "postcss-normalize-whitespace": "^7.0.1", + "postcss-ordered-values": "^7.0.2", + "postcss-reduce-initial": "^7.0.6", + "postcss-reduce-transforms": "^7.0.1", + "postcss-svgo": "^7.1.1", + "postcss-unique-selectors": "^7.0.5" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/cssnano-preset-lite": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/cssnano-preset-lite/-/cssnano-preset-lite-4.0.4.tgz", + "integrity": "sha512-iV7xT9JEk0OJwRWuSV2Y48IkntNjvoiscoioFDcgmuoIvpZV8gIg1++GBHTj72HgmDCALH8y9ELgt+aFM2Nh9g==", + "license": "MIT", + "optional": true, + "dependencies": { + "cssnano-utils": "^5.0.1", + "postcss-discard-comments": "^7.0.4", + "postcss-discard-empty": "^7.0.1", + "postcss-normalize-whitespace": "^7.0.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/cssnano-utils": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.1.tgz", + "integrity": "sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "optional": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0", + "optional": true + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -6488,6 +6781,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT", "optional": true }, "node_modules/dezalgo": { @@ -6537,6 +6831,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "license": "MIT", "optional": true }, "node_modules/dom-serializer": { @@ -6665,7 +6960,8 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "devOptional": true }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", @@ -6676,83 +6972,29 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", - "optional": true, - "dependencies": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" - }, - "bin": { - "editorconfig": "bin/editorconfig" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/editorconfig/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/editorconfig/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/editorconfig/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "optional": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-5.0.1.tgz", + "integrity": "sha512-COqBPFMxuPTPspXl2DkVYaDS3HtrD1GpzOGkNTJ1IYkifq/r9h8SVEFrjA3D9/VJGOEoMQcrlhpntcSUrM8k6A==", + "license": "Apache-2.0", "optional": true, - "dependencies": { - "jake": "^10.8.5" - }, "bin": { "ejs": "bin/cli.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.12.18" } }, "node_modules/electron-to-chromium": { "version": "1.5.267", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/emittery": { @@ -6797,6 +7039,33 @@ "node": ">=8.10.0" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", @@ -6822,11 +7091,21 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, + "devOptional": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -6892,6 +7171,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", + "license": "MIT", "optional": true, "engines": { "node": ">=10" @@ -7524,38 +7804,6 @@ "node": ">=16.0.0" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "optional": true, - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", - "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", @@ -7733,6 +7981,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "devOptional": true, "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" @@ -8019,21 +8268,17 @@ } }, "node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8068,9 +8313,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -8079,16 +8324,41 @@ "node": "18 || 20 || >=22" } }, + "node_modules/glob/node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", - "license": "ISC", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8221,33 +8491,6 @@ "dev": true, "license": "MIT" }, - "node_modules/html-minifier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", - "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", - "optional": true, - "dependencies": { - "camel-case": "^3.0.0", - "clean-css": "^4.2.1", - "commander": "^2.19.0", - "he": "^1.2.0", - "param-case": "^2.1.1", - "relateurl": "^0.2.7", - "uglify-js": "^3.5.1" - }, - "bin": { - "html-minifier": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/html-minifier/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "optional": true - }, "node_modules/html-to-text": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", @@ -8265,17 +8508,106 @@ "node": ">=14" } }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "node_modules/htmlnano": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-3.2.0.tgz", + "integrity": "sha512-ZUCyB3w9EdpkaePGuYTBF7hT1MWdcz7y0/h2Cnl1MKLwbyj7aIM+Eq7SRg+ILF1mvR7zJKu06lw9zpgCxOFymw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/relateurl": "^0.2.33", + "commander": "^14.0.0", + "cosmiconfig": "^9.0.0", + "posthtml": "^0.16.5" + }, + "bin": { + "htmlnano": "dist/bin.js" + }, + "peerDependencies": { + "cssnano": "^7.0.0", + "postcss": "^8.3.11", + "purgecss": "^8.0.0", + "relateurl": "^0.2.7", + "srcset": "^5.0.1", + "svgo": "^4.0.0", + "terser": "^5.21.0", + "uncss": "^0.17.3" + }, + "peerDependenciesMeta": { + "cssnano": { + "optional": true + }, + "postcss": { + "optional": true + }, + "purgecss": { + "optional": true + }, + "relateurl": { + "optional": true + }, + "srcset": { + "optional": true + }, + "svgo": { + "optional": true + }, + "terser": { + "optional": true + }, + "uncss": { + "optional": true + } + } + }, + "node_modules/htmlnano/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20" + } + }, + "node_modules/htmlnano/node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], "optional": true, "dependencies": { "domelementtype": "^2.3.0", @@ -8363,7 +8695,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, + "devOptional": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -8451,12 +8783,13 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "devOptional": true }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", "optional": true, "dependencies": { "binary-extensions": "^2.0.0" @@ -8581,6 +8914,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "license": "ISC", + "optional": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -8683,7 +9023,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -8764,15 +9105,14 @@ } }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "devOptional": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -8780,24 +9120,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "optional": true, - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/javascript-natural-sort": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", @@ -9009,22 +9331,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-config/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest-config/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -9488,22 +9794,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-runtime/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest-runtime/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -9698,145 +9988,18 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/js-beautify": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz", - "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==", - "optional": true, - "dependencies": { - "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", - "glob": "^10.4.2", - "js-cookie": "^3.0.5", - "nopt": "^7.2.1" - }, - "bin": { - "css-beautify": "js/bin/css-beautify.js", - "html-beautify": "js/bin/html-beautify.js", - "js-beautify": "js/bin/js-beautify.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/js-beautify/node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "optional": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/js-beautify/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==", - "license": "MIT", - "optional": true, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/js-beautify/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/js-beautify/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "optional": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/js-beautify/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "optional": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-beautify/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", - "license": "ISC", - "optional": true, - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/js-beautify/node_modules/nopt": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", - "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", - "optional": true, - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "license": "MIT", "optional": true }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "devOptional": true }, "node_modules/js-yaml": { "version": "4.1.1", @@ -9898,7 +10061,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "devOptional": true }, "node_modules/json-schema-traverse": { "version": "1.0.0", @@ -10000,31 +10163,47 @@ } }, "node_modules/juice": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/juice/-/juice-10.0.1.tgz", - "integrity": "sha512-ZhJT1soxJCkOiO55/mz8yeBKTAJhRzX9WBO+16ZTqNTONnnVlUPyVBIzQ7lDRjaBdTbid+bAnyIon/GM3yp4cA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/juice/-/juice-11.1.1.tgz", + "integrity": "sha512-4SBfZqKcc6DrIS+5b/WiGoWaZsdUPBH+e6SbRlNjJpaIRtfoBhYReAtobIEW6mcLeFFDXLBJMuZwkJLkBJjs2w==", + "license": "MIT", "optional": true, "dependencies": { - "cheerio": "1.0.0-rc.12", - "commander": "^6.1.0", + "cheerio": "1.0.0", + "commander": "^12.1.0", + "entities": "^7.0.0", "mensch": "^0.3.4", "slick": "^1.12.2", - "web-resource-inliner": "^6.0.1" + "web-resource-inliner": "^8.0.0" }, "bin": { "juice": "bin/juice" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.17" } }, "node_modules/juice/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", "optional": true, "engines": { - "node": ">= 6" + "node": ">=18" + } + }, + "node_modules/juice/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "optional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/jwa": { @@ -10214,14 +10393,27 @@ "license": "MIT", "optional": true }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/linkify-it": { - "version": "5.0.0", + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "devOptional": true + }, + "node_modules/linkify-it": { + "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "license": "MIT", @@ -10334,13 +10526,20 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "devOptional": true }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT", + "optional": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -10383,12 +10582,6 @@ "node": ">=0.1.90" } }, - "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "optional": true - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -10498,6 +10691,13 @@ "node": ">= 18" } }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0", + "optional": true + }, "node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", @@ -10528,6 +10728,7 @@ "version": "0.3.4", "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==", + "license": "MIT", "optional": true }, "node_modules/merge-descriptors": { @@ -10659,7 +10860,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "devOptional": true, + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -10686,116 +10887,107 @@ } }, "node_modules/mjml": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml/-/mjml-4.15.3.tgz", - "integrity": "sha512-bW2WpJxm6HS+S3Yu6tq1DUPFoTxU9sPviUSmnL7Ua+oVO3WA5ILFWqvujUlz+oeuM+HCwEyMiP5xvKNPENVjYA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml/-/mjml-5.0.0-beta.2.tgz", + "integrity": "sha512-f8ImzVBa/Kp3IHUw82fDn2kvxHz351F53suF1KGP0imOjU0iKgMoYJGs0BwzHhOhW+XO4zw4btRMsSJc2LOBbQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "mjml-cli": "4.15.3", - "mjml-core": "4.15.3", - "mjml-migrate": "4.15.3", - "mjml-preset-core": "4.15.3", - "mjml-validator": "4.15.3" + "@babel/runtime": "^7.28.4", + "mjml-cli": "5.0.0-beta.2", + "mjml-core": "5.0.0-beta.2", + "mjml-preset-core": "5.0.0-beta.2", + "mjml-validator": "5.0.0-beta.2" }, "bin": { "mjml": "bin/mjml" } }, "node_modules/mjml-accordion": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-accordion/-/mjml-accordion-4.15.3.tgz", - "integrity": "sha512-LPNVSj1LyUVYT9G1gWwSw3GSuDzDsQCu0tPB2uDsq4VesYNnU6v3iLCQidMiR6azmIt13OEozG700ygAUuA6Ng==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-accordion/-/mjml-accordion-5.0.0-beta.2.tgz", + "integrity": "sha512-uThyWaQOkZu6143NIt17WINo574kY71NACI53N6wtHaNQJ8h8JxmxM3H/hkFhy2jO2ziYUBZhg9+pcOp8SWGQg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-body": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-body/-/mjml-body-4.15.3.tgz", - "integrity": "sha512-7pfUOVPtmb0wC+oUOn4xBsAw4eT5DyD6xqaxj/kssu6RrFXOXgJaVnDPAI9AzIvXJ/5as9QrqRGYAddehwWpHQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-body/-/mjml-body-5.0.0-beta.2.tgz", + "integrity": "sha512-jBt1hu1Pnqm74PuwaDN2Fhs2Ub7LSM6YaoUUAVYpd/paex7h09dxGRH3XdQoTnVGbhztshk7LSsRzcfcTen8uQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-button": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-button/-/mjml-button-4.15.3.tgz", - "integrity": "sha512-79qwn9AgdGjJR1vLnrcm2rq2AsAZkKC5JPwffTMG+Nja6zGYpTDZFZ56ekHWr/r1b5WxkukcPj2PdevUug8c+Q==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-button/-/mjml-button-5.0.0-beta.2.tgz", + "integrity": "sha512-T9L4n6pl8s1Lg7xbsvbfVd736E+MJbRglUbMLexE7CemkAzKYN2uttKO1qaFPtxvPUzE+ZCNT1G1WdAZ+9noBw==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-carousel": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-carousel/-/mjml-carousel-4.15.3.tgz", - "integrity": "sha512-3ju6I4l7uUhPRrJfN3yK9AMsfHvrYbRkcJ1GRphFHzUj37B2J6qJOQUpzA547Y4aeh69TSb7HFVf1t12ejQxVw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-carousel/-/mjml-carousel-5.0.0-beta.2.tgz", + "integrity": "sha512-kSpRIf/1C2Hi3MmN/sibxgpwDjuyxRA5w4CNv5r9t+j6P6ZOJA5HB5s1NEFxzzaAg/ymzaf5viSIQCaLpymOfw==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-cli": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-cli/-/mjml-cli-4.15.3.tgz", - "integrity": "sha512-+V2TDw3tXUVEptFvLSerz125C2ogYl8klIBRY1m5BHd4JvGVf3yhx8N3PngByCzA6PGcv/eydGQN+wy34SHf0Q==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-cli/-/mjml-cli-5.0.0-beta.2.tgz", + "integrity": "sha512-G72mqob9JWgOiqUInFjD+G53FzAIzNvJbYobkzFh8MC6u5vn7GB2gUd/knZuvwQzIIbGkfuMDWVjcS/vFNPAlA==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "chokidar": "^3.0.0", - "glob": "^10.3.10", - "html-minifier": "^4.0.0", - "js-beautify": "^1.6.14", + "glob": "^10.5.0", "lodash": "^4.17.21", "minimatch": "^9.0.3", - "mjml-core": "4.15.3", - "mjml-migrate": "4.15.3", - "mjml-parser-xml": "4.15.3", - "mjml-validator": "4.15.3", + "mjml-core": "5.0.0-beta.2", + "mjml-parser-xml": "5.0.0-beta.2", + "mjml-preset-core": "5.0.0-beta.2", + "mjml-validator": "5.0.0-beta.2", "yargs": "^17.7.2" }, "bin": { "mjml-cli": "bin/mjml" } }, - "node_modules/mjml-cli/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==", - "license": "MIT", - "optional": true, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/mjml-cli/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "optional": true, "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" + "balanced-match": "^1.0.0" } }, "node_modules/mjml-cli/node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", "optional": true, "dependencies": { "anymatch": "~3.1.2", @@ -10816,10 +11008,33 @@ "fsevents": "~2.3.2" } }, + "node_modules/mjml-cli/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "optional": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mjml-cli/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", "optional": true, "dependencies": { "is-glob": "^4.0.1" @@ -10829,13 +11044,13 @@ } }, "node_modules/mjml-cli/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "optional": true, "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -10848,6 +11063,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "optional": true, "engines": { "node": ">=8.6" @@ -10860,6 +11076,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", "optional": true, "dependencies": { "picomatch": "^2.2.1" @@ -10869,204 +11086,205 @@ } }, "node_modules/mjml-column": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-column/-/mjml-column-4.15.3.tgz", - "integrity": "sha512-hYdEFdJGHPbZJSEysykrevEbB07yhJGSwfDZEYDSbhQQFjV2tXrEgYcFD5EneMaowjb55e3divSJxU4c5q4Qgw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-column/-/mjml-column-5.0.0-beta.2.tgz", + "integrity": "sha512-ZlcJJoFL/rxJlhfa6Sm21aWWo4nNUF9R/z7+dBZxDyYsp3tgiKFeiGtGxme9WBdvizkXqmJ+nnXKYHmRwqIP3A==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-core": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-core/-/mjml-core-4.15.3.tgz", - "integrity": "sha512-Dmwk+2cgSD9L9GmTbEUNd8QxkTZtW9P7FN/ROZW/fGZD6Hq6/4TB0zEspg2Ow9eYjZXO2ofOJ3PaQEEShKV0kQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-core/-/mjml-core-5.0.0-beta.2.tgz", + "integrity": "sha512-93d2GWeWdLEbHGXBa6haVleV/ZAj5EI0lEzY8KOGGFvJQoSrvTUna5fhiNop0CkCpohAWEJsR7PjTAS3URqxGA==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "cheerio": "1.0.0-rc.12", + "@babel/runtime": "^7.28.4", + "cheerio": "1.0.0", + "cssnano": "^7.1.2", + "cssnano-preset-lite": "^4.0.4", "detect-node": "^2.0.4", - "html-minifier": "^4.0.0", - "js-beautify": "^1.6.14", - "juice": "^10.0.0", + "htmlnano": "^3.2.0", + "juice": "^11.0.0", "lodash": "^4.17.21", - "mjml-migrate": "4.15.3", - "mjml-parser-xml": "4.15.3", - "mjml-validator": "4.15.3" + "mjml-parser-xml": "5.0.0-beta.2", + "mjml-validator": "5.0.0-beta.2", + "postcss": "^8.5.8", + "prettier": "^3.8.1" } }, "node_modules/mjml-divider": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-divider/-/mjml-divider-4.15.3.tgz", - "integrity": "sha512-vh27LQ9FG/01y0b9ntfqm+GT5AjJnDSDY9hilss2ixIUh0FemvfGRfsGVeV5UBVPBKK7Ffhvfqc7Rciob9Spzw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-divider/-/mjml-divider-5.0.0-beta.2.tgz", + "integrity": "sha512-zGgN7uAqYmzQK6fqjtGLEctQ6OqV6JlvbsqL892FsO7v6r6DZapDBnNdUYz1b6j0tkZqfNMzIptGCfD/Om58Mg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-group": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-group/-/mjml-group-4.15.3.tgz", - "integrity": "sha512-HSu/rKnGZVKFq3ciT46vi1EOy+9mkB0HewO4+P6dP/Y0UerWkN6S3UK11Cxsj0cAp0vFwkPDCdOeEzRdpFEkzA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-group/-/mjml-group-5.0.0-beta.2.tgz", + "integrity": "sha512-TZ/S8SkPBGA+7Rq5FSjNZHnPTu3pIJElUiu+acW5Y7tmSeYkPocCyG+3Nxr+2GNBeVHvhlcq+nXTFJpujlfkoQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head/-/mjml-head-4.15.3.tgz", - "integrity": "sha512-o3mRuuP/MB5fZycjD3KH/uXsnaPl7Oo8GtdbJTKtH1+O/3pz8GzGMkscTKa97l03DAG2EhGrzzLcU2A6eshwFw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head/-/mjml-head-5.0.0-beta.2.tgz", + "integrity": "sha512-xLy2+uFTdGgMlmSZFB05ng/H1xeUp1MiPgDlEYiowcp4r27zVuGDT2VUZIQkH5cv7UasEMXfMTJZ23qAvERjjg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-attributes": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-attributes/-/mjml-head-attributes-4.15.3.tgz", - "integrity": "sha512-2ISo0r5ZKwkrvJgDou9xVPxxtXMaETe2AsAA02L89LnbB2KC0N5myNsHV0sEysTw9+CfCmgjAb0GAI5QGpxKkQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-attributes/-/mjml-head-attributes-5.0.0-beta.2.tgz", + "integrity": "sha512-BO07AJuxcFJu6YJcyNIDOEuWv1KIFVSv4taEujy0T9iVMuudTHdpsUdkgPIfZx3G7Amn+zvcJCY6xLtFpis5LQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-breakpoint": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-breakpoint/-/mjml-head-breakpoint-4.15.3.tgz", - "integrity": "sha512-Eo56FA5C2v6ucmWQL/JBJ2z641pLOom4k0wP6CMZI2utfyiJ+e2Uuinj1KTrgDcEvW4EtU9HrfAqLK9UosLZlg==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-breakpoint/-/mjml-head-breakpoint-5.0.0-beta.2.tgz", + "integrity": "sha512-bBcnqVz9RlkhUMWpdsJmmQGc61mxhZrwD6RublSZJMOX9W3x/XrfGzcJDs0RN9oLQjySBrSOYySnDozaPCxbyQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-font": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-font/-/mjml-head-font-4.15.3.tgz", - "integrity": "sha512-CzV2aDPpiNIIgGPHNcBhgyedKY4SX3BJoTwOobSwZVIlEA6TAWB4Z9WwFUmQqZOgo1AkkiTHPZQvGcEhFFXH6g==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-font/-/mjml-head-font-5.0.0-beta.2.tgz", + "integrity": "sha512-J18AEbHMD7XMhYSEhZlJwmjpOoLFoQSb4ywLX5k5Gp75KH3H4NsqV/UVFZiCPdi6rksWaa0T2Vhn2cdHnHuyrg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-html-attributes": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-html-attributes/-/mjml-head-html-attributes-4.15.3.tgz", - "integrity": "sha512-MDNDPMBOgXUZYdxhosyrA2kudiGO8aogT0/cODyi2Ed9o/1S7W+je11JUYskQbncqhWKGxNyaP4VWa+6+vUC/g==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-html-attributes/-/mjml-head-html-attributes-5.0.0-beta.2.tgz", + "integrity": "sha512-CVYgy3J/d5GQt7b7K1GZMl0hoeKalvByvZLkH2IJdjxThBUC+14JEoyjaW7auiFEScUnx3CpymPs9ozExH/PnA==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-preview": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-preview/-/mjml-head-preview-4.15.3.tgz", - "integrity": "sha512-J2PxCefUVeFwsAExhrKo4lwxDevc5aKj888HBl/wN4EuWOoOg06iOGCxz4Omd8dqyFsrqvbBuPqRzQ+VycGmaA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-preview/-/mjml-head-preview-5.0.0-beta.2.tgz", + "integrity": "sha512-33I+Pujw+HSCPBNYtTCSzbBN2WxoIP1AMfXYN7infBFqUAdXf2btAHddB77JfopQS5U3/7Ufxjd3GzYtKBa86g==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-style": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-style/-/mjml-head-style-4.15.3.tgz", - "integrity": "sha512-9J+JuH+mKrQU65CaJ4KZegACUgNIlYmWQYx3VOBR/tyz+8kDYX7xBhKJCjQ1I4wj2Tvga3bykd89Oc2kFZ5WOw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-style/-/mjml-head-style-5.0.0-beta.2.tgz", + "integrity": "sha512-rySJtKbUpt6MXnZ2dQFRFnEPSfWu9MtlAKpdgqOS91LgE/j1L6rUh7iYW3DI3eS9lyV45etDOIvNhdIM+KaYfw==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-head-title": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-title/-/mjml-head-title-4.15.3.tgz", - "integrity": "sha512-IM59xRtsxID4DubQ0iLmoCGXguEe+9BFG4z6y2xQDrscIa4QY3KlfqgKGT69ojW+AVbXXJPEVqrAi4/eCsLItQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-head-title/-/mjml-head-title-5.0.0-beta.2.tgz", + "integrity": "sha512-o0TU17mRHCRChSu6uiKfPUPrgNpzA3pUv3vGEDn4zINSx+W6UJbuKRotgkptuWrfDrHwqx2yNsFs3t7WZ86GkA==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-hero": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-hero/-/mjml-hero-4.15.3.tgz", - "integrity": "sha512-9cLAPuc69yiuzNrMZIN58j+HMK1UWPaq2i3/Fg2ZpimfcGFKRcPGCbEVh0v+Pb6/J0+kf8yIO0leH20opu3AyQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-hero/-/mjml-hero-5.0.0-beta.2.tgz", + "integrity": "sha512-kH2z02VtOacH/c8IT+EsHJMf4Ce9ZXp0ErR0FgwpaeSpG+XHw2Ov8s61abXOh7QFdPUkhgVUydqz2+nQBp0nwg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-image": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-image/-/mjml-image-4.15.3.tgz", - "integrity": "sha512-g1OhSdofIytE9qaOGdTPmRIp7JsCtgO0zbsn1Fk6wQh2gEL55Z40j/VoghslWAWTgT2OHFdBKnMvWtN6U5+d2Q==", - "optional": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-migrate": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-migrate/-/mjml-migrate-4.15.3.tgz", - "integrity": "sha512-sr/+35RdxZroNQVegjpfRHJ5hda9XCgaS4mK2FGO+Mb1IUevKfeEPII3F/cHDpNwFeYH3kAgyqQ22ClhGLWNBA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-image/-/mjml-image-5.0.0-beta.2.tgz", + "integrity": "sha512-eLF6vv5lvdxU1y3ahAx3QJIhW1G57Ou7Ur9UGZ5W5bnjIbS77GjHqMMO95hVPAdw54j8YGuwGUAj7cI+ZrRozg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "js-beautify": "^1.6.14", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3", - "mjml-parser-xml": "4.15.3", - "yargs": "^17.7.2" - }, - "bin": { - "migrate": "lib/cli.js" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-navbar": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-navbar/-/mjml-navbar-4.15.3.tgz", - "integrity": "sha512-VsKH/Jdlf8Yu3y7GpzQV5n7JMdpqvZvTSpF6UQXL0PWOm7k6+LX+sCZimOfpHJ+wCaaybpxokjWZ71mxOoCWoA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-navbar/-/mjml-navbar-5.0.0-beta.2.tgz", + "integrity": "sha512-+3UaYTYGpQMKCVyqt/mp+WDs7lE2n0mmbIYrADxmfnRPrixu4zz72TSMvdHKL0hSRP/IIC2tUOh6+pxihV0mJQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-parser-xml": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-parser-xml/-/mjml-parser-xml-4.15.3.tgz", - "integrity": "sha512-Tz0UX8/JVYICLjT+U8J1f/TFxIYVYjzZHeh4/Oyta0pLpRLeZlxEd71f3u3kdnulCKMP4i37pFRDmyLXAlEuLw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-parser-xml/-/mjml-parser-xml-5.0.0-beta.2.tgz", + "integrity": "sha512-CVWdHy75ftf0GGvDT4juX5AQMvzH/bx3zlNos37hB0v7onJ1bjHfFzDYedzzll00aGhOM1HiMGmX0mrObhYKqQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "detect-node": "2.1.0", "htmlparser2": "^9.1.0", - "lodash": "^4.17.15" + "lodash": "^4.17.21" } }, "node_modules/mjml-parser-xml/node_modules/htmlparser2": { @@ -11080,6 +11298,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "optional": true, "dependencies": { "domelementtype": "^2.3.0", @@ -11089,124 +11308,133 @@ } }, "node_modules/mjml-preset-core": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-4.15.3.tgz", - "integrity": "sha512-1zZS8P4O0KweWUqNS655+oNnVMPQ1Rq1GaZq5S9JfwT1Vh/m516lSmiTW9oko6gGHytt5s6Yj6oOeu5Zm8FoLw==", - "optional": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "mjml-accordion": "4.15.3", - "mjml-body": "4.15.3", - "mjml-button": "4.15.3", - "mjml-carousel": "4.15.3", - "mjml-column": "4.15.3", - "mjml-divider": "4.15.3", - "mjml-group": "4.15.3", - "mjml-head": "4.15.3", - "mjml-head-attributes": "4.15.3", - "mjml-head-breakpoint": "4.15.3", - "mjml-head-font": "4.15.3", - "mjml-head-html-attributes": "4.15.3", - "mjml-head-preview": "4.15.3", - "mjml-head-style": "4.15.3", - "mjml-head-title": "4.15.3", - "mjml-hero": "4.15.3", - "mjml-image": "4.15.3", - "mjml-navbar": "4.15.3", - "mjml-raw": "4.15.3", - "mjml-section": "4.15.3", - "mjml-social": "4.15.3", - "mjml-spacer": "4.15.3", - "mjml-table": "4.15.3", - "mjml-text": "4.15.3", - "mjml-wrapper": "4.15.3" + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-5.0.0-beta.2.tgz", + "integrity": "sha512-yZyH8t7BcTKgLXyelU71Ye2IvuQGlhqv8hOEUIiw66ZMcnWWnWJlcaVEkaFPSnIX/IwLNyXIM4LQ1ZHSX3rgxg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@babel/runtime": "^7.28.4", + "mjml-accordion": "5.0.0-beta.2", + "mjml-body": "5.0.0-beta.2", + "mjml-button": "5.0.0-beta.2", + "mjml-carousel": "5.0.0-beta.2", + "mjml-column": "5.0.0-beta.2", + "mjml-divider": "5.0.0-beta.2", + "mjml-group": "5.0.0-beta.2", + "mjml-head": "5.0.0-beta.2", + "mjml-head-attributes": "5.0.0-beta.2", + "mjml-head-breakpoint": "5.0.0-beta.2", + "mjml-head-font": "5.0.0-beta.2", + "mjml-head-html-attributes": "5.0.0-beta.2", + "mjml-head-preview": "5.0.0-beta.2", + "mjml-head-style": "5.0.0-beta.2", + "mjml-head-title": "5.0.0-beta.2", + "mjml-hero": "5.0.0-beta.2", + "mjml-image": "5.0.0-beta.2", + "mjml-navbar": "5.0.0-beta.2", + "mjml-raw": "5.0.0-beta.2", + "mjml-section": "5.0.0-beta.2", + "mjml-social": "5.0.0-beta.2", + "mjml-spacer": "5.0.0-beta.2", + "mjml-table": "5.0.0-beta.2", + "mjml-text": "5.0.0-beta.2", + "mjml-wrapper": "5.0.0-beta.2" } }, "node_modules/mjml-raw": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-raw/-/mjml-raw-4.15.3.tgz", - "integrity": "sha512-IGyHheOYyRchBLiAEgw3UM11kFNmBSMupu2BDdejC6ZiDhEAdG+tyERlsCwDPYtXanvFpGWULIu3XlsUPc+RZw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-raw/-/mjml-raw-5.0.0-beta.2.tgz", + "integrity": "sha512-H4gN+wJRKS7BKlX8vdXCzyrLiCi6qeTDDDB3nm6CwSg5bxlE+19bVHHUXHxBjkeV5acipXDhbaCIHLUfeRFN0g==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-section": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-section/-/mjml-section-4.15.3.tgz", - "integrity": "sha512-JfVPRXH++Hd933gmQfG8JXXCBCR6fIzC3DwiYycvanL/aW1cEQ2EnebUfQkt5QzlYjOkJEH+JpccAsq3ln6FZQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-section/-/mjml-section-5.0.0-beta.2.tgz", + "integrity": "sha512-Z7x56JTcn2yKvqlcL7gRQrcyLimQC4BZJKk3JQN8xIByZucRfVfmE5L+2KA78+uc7NMnNKIPl7eXYECun6fM8A==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-social": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-social/-/mjml-social-4.15.3.tgz", - "integrity": "sha512-7sD5FXrESOxpT9Z4Oh36bS6u/geuUrMP1aCg2sjyAwbPcF1aWa2k9OcatQfpRf6pJEhUZ18y6/WBBXmMVmSzXg==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-social/-/mjml-social-5.0.0-beta.2.tgz", + "integrity": "sha512-006HWAszTUP7vNJvQnPrX1CvOvWAy9AEfhAVlkNKyEkr/F+z1Qpq+dVE7W1jXsq7GUeWT6AIr6EQrmKRXe+19A==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-spacer": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-spacer/-/mjml-spacer-4.15.3.tgz", - "integrity": "sha512-3B7Qj+17EgDdAtZ3NAdMyOwLTX1jfmJuY7gjyhS2HtcZAmppW+cxqHUBwCKfvSRgTQiccmEvtNxaQK+tfyrZqA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-spacer/-/mjml-spacer-5.0.0-beta.2.tgz", + "integrity": "sha512-mKpxKWPHYlgd65hFLNddzgjqykqB/4crfrkAdWP06nCsLZpxRe94jLVyKHHwfCv8XUGsg+Srh+79kfQYSF7kig==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-table": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-table/-/mjml-table-4.15.3.tgz", - "integrity": "sha512-FLx7DcRKTdKdcOCbMyBaeudeHaHpwPveRrBm6WyQe3LXx6FfdmOh59i71/16LFQMgBOD3N4/UJkzxLzlTJzMqQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-table/-/mjml-table-5.0.0-beta.2.tgz", + "integrity": "sha512-o+EiFn4q+Pjbbi3jQLpLs65Ss3TGW/0Z/7GGBL35L4sLDJ/+4ek0pgkTjmWlS6SgXSy2Oua9MCZj2qX3MjfzWQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-text": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-text/-/mjml-text-4.15.3.tgz", - "integrity": "sha512-+C0hxCmw9kg0XzT6vhE5mFkK6y225nC8UEQcN94K0fBCjPKkM+HqZMwGX205fzdGRi+Bxa55b/VhrIVwdv+8vw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-text/-/mjml-text-5.0.0-beta.2.tgz", + "integrity": "sha512-gLoZTMucbK/ffuUFJiKBpm7Pi+m9zyjqL/RKePUExzH8Ad5qDCqjND2QFKuuSLy8jp02qjnKVudbtWnF2H3ALQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3" + "mjml-core": "5.0.0-beta.2" } }, "node_modules/mjml-validator": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-validator/-/mjml-validator-4.15.3.tgz", - "integrity": "sha512-Xb72KdqRwjv/qM2rJpV22syyP2N3cRQ9VVDrN6u2FSzLq02buFNxmSPJ7CKhat3PrUNdVHU75KZwOf/tz4UEhA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-validator/-/mjml-validator-5.0.0-beta.2.tgz", + "integrity": "sha512-zVztkHNlkxkOre+7p5BRL71Y+1EKUs1awpyw2T+Cs7UAimWiaFiB9FhGEdnTffTc/HWfrmSKp3wq4W1zbuSRsg==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9" + "@babel/runtime": "^7.28.4" } }, "node_modules/mjml-wrapper": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-wrapper/-/mjml-wrapper-4.15.3.tgz", - "integrity": "sha512-ditsCijeHJrmBmObtJmQ18ddLxv5oPyMTdPU8Di8APOnD2zPk7Z4UAuJSl7HXB45oFiivr3MJf4koFzMUSZ6Gg==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/mjml-wrapper/-/mjml-wrapper-5.0.0-beta.2.tgz", + "integrity": "sha512-dXgxXZpyRkrSdL6z8xqzMiF3WacJ+DYlqEgtAVmRd4lUAB/UlgNLrpzQDpmFKxc0is8JB2lB6hF7APO1nT7BBQ==", + "license": "MIT", "optional": true, "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.28.4", "lodash": "^4.17.21", - "mjml-core": "4.15.3", - "mjml-section": "4.15.3" + "mjml-core": "5.0.0-beta.2", + "mjml-section": "5.0.0-beta.2" } }, "node_modules/mocha": { @@ -11289,21 +11517,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", @@ -11509,6 +11722,25 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "optional": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-postinstall": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", @@ -11550,15 +11782,6 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "optional": true }, - "node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "optional": true, - "dependencies": { - "lower-case": "^1.1.1" - } - }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -11639,7 +11862,7 @@ "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/nodemailer": { @@ -11677,6 +11900,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", "optional": true, "dependencies": { "boolbase": "^1.0.0" @@ -11966,20 +12190,11 @@ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" }, - "node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "optional": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, + "devOptional": true, "dependencies": { "callsites": "^3.0.0" }, @@ -11991,7 +12206,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -12006,12 +12221,13 @@ } }, "node_modules/parse5": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", - "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", "optional": true, "dependencies": { - "entities": "^4.5.0" + "entities": "^6.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -12021,6 +12237,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", "optional": true, "dependencies": { "domhandler": "^5.0.3", @@ -12030,6 +12247,32 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "optional": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "optional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/parseley": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", @@ -12132,6 +12375,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "devOptional": true, "engines": { "node": ">=8" } @@ -12146,6 +12390,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "devOptional": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -12160,7 +12405,8 @@ "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "devOptional": true }, "node_modules/path-to-regexp": { "version": "8.2.0", @@ -12198,7 +12444,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true + "devOptional": true }, "node_modules/picomatch": { "version": "4.0.2", @@ -12299,51 +12545,668 @@ "node": ">=4" } }, - "node_modules/precond": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, "engines": { - "node": ">= 0.6" + "node": "^10 || ^12 || >=14" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, + "node_modules/postcss-calc": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz", + "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">= 0.8.0" + "node": "^18.12 || ^20.9 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" } }, - "node_modules/prettier": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", - "dev": true, + "node_modules/postcss-colormin": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.6.tgz", + "integrity": "sha512-oXM2mdx6IBTRm39797QguYzVEWzbdlFiMNfq88fCCN1Wepw3CYmJ/1/Ifa/KjWo+j5ZURDl2NTldLJIw51IeNQ==", "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=14" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "peerDependencies": { + "postcss": "^8.4.32" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", - "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", - "dev": true, + "node_modules/postcss-convert-values": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.9.tgz", + "integrity": "sha512-l6uATQATZaCa0bckHV+r6dLXfWtUBKXxO3jK+AtxxJJtgMPD+VhhPCCx51I4/5w8U5uHV67g3w7PXj+V3wlMlg==", "license": "MIT", + "optional": true, "dependencies": { - "fast-diff": "^1.1.2" + "browserslist": "^4.28.1", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" - } + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-comments": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.6.tgz", + "integrity": "sha512-Sq+Fzj1Eg5/CPf1ERb0wS1Im5cvE2gDXCE+si4HCn1sf+jpQZxDI4DXEp8t77B/ImzDceWE2ebJQFXdqZ6GRJw==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.2.tgz", + "integrity": "sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-empty": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.1.tgz", + "integrity": "sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.1.tgz", + "integrity": "sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.5.tgz", + "integrity": "sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.5" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-merge-rules": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.8.tgz", + "integrity": "sha512-BOR1iAM8jnr7zoQSlpeBmCsWV5Uudi/+5j7k05D0O/WP3+OFMPD86c1j/20xiuRtyt45bhxw/7hnhZNhW2mNFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.1", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.1.tgz", + "integrity": "sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.1.tgz", + "integrity": "sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==", + "license": "MIT", + "optional": true, + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-params": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.6.tgz", + "integrity": "sha512-YOn02gC68JijlaXVuKvFSCvQOhTpblkcfDre2hb/Aaa58r2BIaK4AtE/cyZf2wV7YKAG+UlP9DT+By0ry1E4VQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "cssnano-utils": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.6.tgz", + "integrity": "sha512-lIbC0jy3AAwDxEgciZlBullDiMBeBCT+fz5G8RcA9MWqh/hfUkpOI3vNDUNEZHgokaoiv0juB9Y8fGcON7rU/A==", + "license": "MIT", + "optional": true, + "dependencies": { + "cssesc": "^3.0.0", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.1.tgz", + "integrity": "sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.1.tgz", + "integrity": "sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.1.tgz", + "integrity": "sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.1.tgz", + "integrity": "sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-string": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.1.tgz", + "integrity": "sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.1.tgz", + "integrity": "sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.6.tgz", + "integrity": "sha512-z6bwTV84YW6ZvvNoaNLuzRW4/uWxDKYI1iIDrzk6D2YTL7hICApy+Q1LP6vBEsljX8FM7YSuV9qI79XESd4ddQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-url": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.1.tgz", + "integrity": "sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.1.tgz", + "integrity": "sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-ordered-values": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.2.tgz", + "integrity": "sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==", + "license": "MIT", + "optional": true, + "dependencies": { + "cssnano-utils": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.6.tgz", + "integrity": "sha512-G6ZyK68AmrPdMB6wyeA37ejnnRG2S8xinJrZJnOv+IaRKf6koPAVbQsiC7MfkmXaGmF1UO+QCijb27wfpxuRNg==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.1.tgz", + "integrity": "sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "optional": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.1.tgz", + "integrity": "sha512-zU9H9oEDrUFKa0JB7w+IYL7Qs9ey1mZyjhbf0KLxwJDdDRtoPvCmaEfknzqfHj44QS9VD6c5sJnBAVYTLRg/Sg==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^4.0.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.5.tgz", + "integrity": "sha512-3QoYmEt4qg/rUWDn6Tc8+ZVPmbp4G1hXDtCNWDx0st8SjtCbRcxRXDDM1QrEiXGG3A45zscSJFb4QH90LViyxg==", + "license": "MIT", + "optional": true, + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT", + "optional": true + }, + "node_modules/posthtml": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.7.tgz", + "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "posthtml-parser": "^0.11.0", + "posthtml-render": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/posthtml-parser": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", + "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "htmlparser2": "^7.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/posthtml-parser/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "optional": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/posthtml-parser/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "optional": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/posthtml-parser/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/posthtml-parser/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/posthtml-parser/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "license": "BSD-2-Clause", + "optional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/posthtml-parser/node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/posthtml-render": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", + "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-json": "^2.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "devOptional": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } }, "node_modules/pretty-format": { "version": "30.3.0", @@ -12418,12 +13281,6 @@ "asap": "~2.0.3" } }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "optional": true - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -12442,12 +13299,13 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/pug": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", - "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "license": "MIT", "optional": true, "dependencies": { - "pug-code-gen": "^3.0.3", + "pug-code-gen": "^3.0.4", "pug-filters": "^4.0.0", "pug-lexer": "^5.0.1", "pug-linker": "^4.0.0", @@ -12461,6 +13319,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "license": "MIT", "optional": true, "dependencies": { "constantinople": "^4.0.1", @@ -12469,9 +13328,10 @@ } }, "node_modules/pug-code-gen": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", - "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "license": "MIT", "optional": true, "dependencies": { "constantinople": "^4.0.1", @@ -12548,6 +13408,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "license": "MIT", "optional": true }, "node_modules/pug-strip-comments": { @@ -12723,20 +13584,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "optional": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12806,122 +13653,44 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } }, "node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/rimraf": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", - "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "glob": "^13.0.3", - "package-json-from-dist": "^1.0.1" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/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==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", - "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", - "license": "BlueOak-1.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, "dependencies": { - "brace-expansion": "^5.0.2" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/rimraf/node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/rimraf": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -13121,6 +13890,16 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=11.0.0" + } + }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -13269,6 +14048,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "devOptional": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -13280,6 +14060,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "devOptional": true, "engines": { "node": ">=8" } @@ -13374,6 +14155,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "devOptional": true, "engines": { "node": ">=14" }, @@ -13437,6 +14219,7 @@ "version": "1.12.2", "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", + "license": "MIT (http://mootools.net/license.txt)", "optional": true, "engines": { "node": "*" @@ -13451,6 +14234,16 @@ "node": ">= 8" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -13595,6 +14388,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -13608,6 +14402,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -13630,6 +14425,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "devOptional": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -13645,6 +14441,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -13656,6 +14453,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "devOptional": true, "engines": { "node": ">=12" }, @@ -13727,6 +14525,23 @@ "node": ">=0.8.0" } }, + "node_modules/stylehacks": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.8.tgz", + "integrity": "sha512-I3f053GBLIiS5Fg6OMFhq/c+yW+5Hc2+1fgq7gElDMMSqwlRb3tBf2ef6ucLStYRpId4q//bQO1FjcyNyy4yDQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserslist": "^4.28.1", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, "node_modules/super-regex": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", @@ -13803,6 +14618,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "license": "MIT", + "optional": true, + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=16" + } + }, "node_modules/swagger-ui-dist": { "version": "5.31.0", "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.31.0.tgz", @@ -13890,7 +14741,7 @@ "version": "5.46.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -14013,14 +14864,14 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/terser/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -14030,7 +14881,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -14484,7 +15335,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -14615,7 +15466,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "opencollective", @@ -14642,12 +15493,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "optional": true - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -14716,6 +15561,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", + "license": "MIT", "optional": true, "engines": { "node": ">=10" @@ -14789,6 +15635,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -14847,159 +15694,40 @@ } }, "node_modules/web-resource-inliner": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz", - "integrity": "sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-8.0.0.tgz", + "integrity": "sha512-Ezr98sqXW/+OCGoUEXuOKVR+oVFlSdn1tIySEEJdiSAw4IjrW8hQkwARSSBJTSB5Us5dnytDgL0ZDliAYBhaNA==", + "license": "MIT", "optional": true, "dependencies": { "ansi-colors": "^4.1.1", "escape-goat": "^3.0.0", - "htmlparser2": "^5.0.0", + "htmlparser2": "^9.1.0", "mime": "^2.4.6", - "node-fetch": "^2.6.0", "valid-data-url": "^3.0.0" }, "engines": { "node": ">=10.0.0" } }, - "node_modules/web-resource-inliner/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "optional": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/dom-serializer/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "optional": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/domhandler": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", - "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", - "optional": true, - "dependencies": { - "domelementtype": "^2.0.1" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "optional": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/domutils/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "optional": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "optional": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/web-resource-inliner/node_modules/htmlparser2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz", - "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==", - "optional": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^3.3.0", - "domutils": "^2.4.2", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/fb55/htmlparser2?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "optional": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" } - } - }, - "node_modules/web-resource-inliner/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "optional": true - }, - "node_modules/web-resource-inliner/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "optional": true - }, - "node_modules/web-resource-inliner/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + ], + "license": "MIT", "optional": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/web-streams-polyfill": { @@ -15167,6 +15895,43 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, "node_modules/whatwg-url": { "version": "14.2.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", @@ -15183,6 +15948,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "devOptional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -15253,6 +16019,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "license": "MIT", "optional": true, "dependencies": { "@babel/parser": "^7.9.6", @@ -15313,6 +16080,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -15329,6 +16097,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, From 10eb7f13f5572453d93b8841c39aaa82de80d763 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 24 Mar 2026 15:16:53 +0100 Subject: [PATCH 088/120] fix: update import path for nestjs mailer after package version update (#2631) fix import path for nestjs mailer after package version update --- package-lock.json | 69 +++++++++++++++++++++++++++++++++++++++++++++++ src/app.module.ts | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index e47dd6fe2..0e8dc37e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2599,6 +2599,32 @@ } } }, + "node_modules/@nestjs-modules/mailer/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/@nestjs-modules/mailer/node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -2609,6 +2635,20 @@ "node": ">= 6" } }, + "node_modules/@nestjs-modules/mailer/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@nestjs-modules/mailer/node_modules/nunjucks": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", @@ -2635,6 +2675,34 @@ } } }, + "node_modules/@nestjs-modules/mailer/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@nestjs-modules/mailer/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/@nestjs/axios": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", @@ -3270,6 +3338,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" diff --git a/src/app.module.ts b/src/app.module.ts index 814ad397f..1295cbfae 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -22,7 +22,7 @@ import { JobsModule } from "./jobs/jobs.module"; import { InstrumentsModule } from "./instruments/instruments.module"; import { MailerModule } from "@nestjs-modules/mailer"; import { join } from "path"; -import { HandlebarsAdapter } from "@nestjs-modules/mailer/dist/adapters/handlebars.adapter"; +import { HandlebarsAdapter } from "@nestjs-modules/mailer/adapters/handlebars.adapter"; import { handlebarsHelpers } from "./common/handlebars-helpers"; import { CommonModule } from "./common/common.module"; import { RabbitMQModule } from "./common/rabbitmq/rabbitmq.module"; From 17f5ab17ac115a83f5d85bc13214184949e78847 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 14:18:16 +0000 Subject: [PATCH 089/120] build(deps): bump glob from 10.4.5 to 10.5.0 Bumps [glob](https://github.com/isaacs/node-glob) from 10.4.5 to 10.5.0. - [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md) - [Commits](https://github.com/isaacs/node-glob/compare/v10.4.5...v10.5.0) --- updated-dependencies: - dependency-name: glob dependency-version: 10.5.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 77 +++-------------------------------------------- 1 file changed, 5 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0e8dc37e3..7b57ec76b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2599,32 +2599,6 @@ } } }, - "node_modules/@nestjs-modules/mailer/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/@nestjs-modules/mailer/node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -2635,20 +2609,6 @@ "node": ">= 6" } }, - "node_modules/@nestjs-modules/mailer/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@nestjs-modules/mailer/node_modules/nunjucks": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", @@ -2675,34 +2635,6 @@ } } }, - "node_modules/@nestjs-modules/mailer/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/@nestjs/axios": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", @@ -3338,7 +3270,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -11567,10 +11498,12 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", From 3ab62726a9f8f4da3b6d9bde8f0a05a9782fe9c2 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 24 Mar 2026 16:26:19 +0100 Subject: [PATCH 090/120] fix: package lockfile --- package-lock.json | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/package-lock.json b/package-lock.json index 7b57ec76b..c92fd2010 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2599,6 +2599,32 @@ } } }, + "node_modules/@nestjs-modules/mailer/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/@nestjs-modules/mailer/node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -2609,6 +2635,20 @@ "node": ">= 6" } }, + "node_modules/@nestjs-modules/mailer/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@nestjs-modules/mailer/node_modules/nunjucks": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", @@ -2635,6 +2675,34 @@ } } }, + "node_modules/@nestjs-modules/mailer/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@nestjs-modules/mailer/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/@nestjs/axios": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", @@ -3270,6 +3338,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" From 75cefe25b23f04f2db9e182527b85a6384099241 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:25:37 +0000 Subject: [PATCH 091/120] refactor: allow additional authorized parties in the tokenlogin endpoint (#2586) * Allow additional authorized parties in tokenlogin endpoint via OIDC_ADDITIONAL_AUTHORIZED_PARTIES env var Co-authored-by: Junjiequan <78078898+Junjiequan@users.noreply.github.com> * es lint fix * add e2e test for oidc * add --wait for coantiners ready * test * test2 * test * fix mount path * test * cp local-test-realm * disable health check for keycloack * fix health check command * test * test * test * test * test * test * move oauth test from jest to mocha * remove keycloak from docker compose local * enable Oauth test only for github runner * user auth-mock-server instead of real keycloack * remove mount * import mock-oauth2-server * test * clean up * update doc * minor clean up * use correct syntax for health check * fix import path for nestjs mailer after package version update --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Junjiequan <78078898+Junjiequan@users.noreply.github.com> Co-authored-by: junjiequan --- .env.example | 1 + .github/workflows/test.yml | 2 +- CI/ESS/docker-compose.api.yaml | 70 ++++++++++++ README.md | 1 + .../openid-client/openid-client.service.ts | 17 ++- src/config/configuration.ts | 6 ++ test/Oauth.js | 102 ++++++++++++++++++ test/config/.env | 6 ++ ...dc.e2e-spec.ts => oidcSession.e2e-spec.ts} | 2 +- 9 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 test/Oauth.js rename test/jest-e2e-tests/{oidc.e2e-spec.ts => oidcSession.e2e-spec.ts} (97%) diff --git a/.env.example b/.env.example index df65e82ec..f130bbd0f 100644 --- a/.env.example +++ b/.env.example @@ -33,6 +33,7 @@ LDAP_SEARCH_BASE= LDAP_SEARCH_FILTER="(LDAPUsername={{username}})" OIDC_ISSUER="" OIDC_CLIENT_ID="" +OIDC_ADDITIONAL_AUTHORIZED_PARTIES="client1, client2" OIDC_CLIENT_SECRET="" OIDC_CALLBACK_URL="" OIDC_SCOPE="" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 48931c943..5c4fb6cd8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -139,5 +139,5 @@ jobs: # Start mongo container and app before running api tests run: | cp CI/ESS/docker-compose.api.yaml docker-compose.yaml - docker compose up --build -d + docker compose up --build -d --wait npm run test:api diff --git a/CI/ESS/docker-compose.api.yaml b/CI/ESS/docker-compose.api.yaml index f969b2e09..4f78a2950 100644 --- a/CI/ESS/docker-compose.api.yaml +++ b/CI/ESS/docker-compose.api.yaml @@ -1,4 +1,74 @@ services: + mock-oauth: + image: ghcr.io/navikt/mock-oauth2-server:latest + ports: + - "8080:8080" + environment: + SERVER_PORT: 8080 + JSON_CONFIG: | + { + "interactiveLogin": false, + "httpServer": "NettyWrapper", + "tokenCallbacks": [ + { + "issuerId": "local-test", + "tokenExpiry": 3600, + "requestMappings": [ + { + "requestParam": "client_id", + "match": "scicat-client-test", + "claims": { + "sub": "test-username", + "preferred_username": "test-username", + "email": "test@test.com", + "aud": "scicat-client-test", + "azp": "scicat-client-test" + } + }, + { + "requestParam": "client_id", + "match": "additional-authorized-client-test-1", + "claims": { + "sub": "test-username", + "preferred_username": "test-username", + "email": "test@test.com", + "aud": "scicat-client-test", + "azp": "additional-authorized-client-test-1" + } + }, + { + "requestParam": "client_id", + "match": "additional-authorized-client-test-2", + "claims": { + "sub": "test-username", + "preferred_username": "test-username", + "email": "test@test.com", + "aud": "scicat-client-test", + "azp": "additional-authorized-client-test-2" + } + }, + { + "requestParam": "client_id", + "match": "untrusted-client-test", + "claims": { + "sub": "test-username", + "preferred_username": "test-username", + "email": "test@test.com", + "aud": "untrusted-client-test", + "azp": "untrusted-client-test" + } + } + ] + } + ] + } + healthcheck: + test: ["CMD", "wget", "-q", "-O-", "http://localhost:8080/local-test/.well-known/openid-configuration"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 10s + mongodb: image: mongo:latest volumes: diff --git a/README.md b/README.md index 7bfc22269..0fd22810e 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `LDAP_SEARCH_FILTER` | string | Yes | Search filter for your LDAP server. | | | `OIDC_ISSUER` | string | Yes | URL of the OIDC server providing the authentication service. Example: https://identity.esss.dk/realm/ess. | | | `OIDC_CLIENT_ID` | string | Yes | Identity of the client used to obtain the user token. Example: scicat. | | +| `OIDC_ADDITIONAL_AUTHORIZED_PARTIES` | string | No | Comma-separated list of additional OIDC client IDs allowed to present tokens to this backend. Used for token exchange scenarios where a third-party client obtains a token on behalf of a user. The client ID must appear as the `azp` claim in the token. Example: `additional-client1, additional-client2`. | | | `OIDC_CLIENT_SECRET` | string | Yes | Secret to provide to the OIDC service to obtain the user token. Example: Aa1JIw3kv3mQlGFWhRrE3gOdkH6xreAwro. | | | `OIDC_CALLBACK_URL` | string | Yes | SciCat callback URL to redirect to after a successful login. Example: http://myscicat/api/v3/oidc/callback. | | | `OIDC_SCOPE` | string | Yes | Space-separated list of info returned by the OIDC service. Example: "openid profile email". | | diff --git a/src/common/openid-client/openid-client.service.ts b/src/common/openid-client/openid-client.service.ts index da5d3f370..ca8ddce8e 100644 --- a/src/common/openid-client/openid-client.service.ts +++ b/src/common/openid-client/openid-client.service.ts @@ -42,10 +42,19 @@ export class OidcClientService { `${this.oidcConfig.issuer}/.well-known/openid-configuration`, ); - this.client = new issuer.Client({ - client_id: this.oidcConfig.clientID, - client_secret: this.oidcConfig.clientSecret, - }); + this.client = new issuer.Client( + { + client_id: this.oidcConfig.clientID, + client_secret: this.oidcConfig.clientSecret, + }, + undefined, // use issuer's JWKS + this.oidcConfig.additionalAuthorizedParties?.length + ? { + additionalAuthorizedParties: + this.oidcConfig.additionalAuthorizedParties, + } + : undefined, + ); return this.client; } catch (err) { diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 1115bfbc1..1ef060662 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -344,6 +344,12 @@ const configuration = () => { operator: process.env.OIDC_USERQUERY_OPERATOR || "or", // Example: "or" or "and" filter: oidcUserQueryFilter.split(",").map((v) => v.trim()) ?? [], // Example: "username:username, email:email" }, + additionalAuthorizedParties: process.env + .OIDC_ADDITIONAL_AUTHORIZED_PARTIES + ? process.env.OIDC_ADDITIONAL_AUTHORIZED_PARTIES.split(",") + .map((v) => v.trim()) + .filter(Boolean) + : undefined, // Example: "public-client-id" or "client1,client2" }, logbook: { enabled: diff --git a/test/Oauth.js b/test/Oauth.js new file mode 100644 index 000000000..536b33f81 --- /dev/null +++ b/test/Oauth.js @@ -0,0 +1,102 @@ +const { TestData } = require("./TestData"); + +const isCI = process.env.CI === "true"; + +describe("OIDC E2E", () => { + before(function () { + if (!isCI) this.skip(); + }); + + const keycloakUrl = "http://localhost:8080"; + + const testUser = { + username: "test-username", + password: "test-password", + email: "test@test.com", + }; + const tokenBody = (clientId) => { + return { + grant_type: "password", + client_id: clientId, + client_secret: clientId === "scicat-client-test" ? "secret" : undefined, + username: testUser.username, + password: testUser.password, + scope: "openid", + }; + }; + + it("should exchange scicat token from main client", async () => { + const res = await request(keycloakUrl) + .post("/local-test/token") + .type("form") + .send(tokenBody("scicat-client-test")) + .expect(TestData.EntryValidStatusCode) + .expect("Content-Type", /json/); + + // Avoid hitting rate limits + await new Promise((resolve) => setTimeout(resolve, 1000)); + + return request(appUrl) + .post("/api/v3/auth/oidc/token") + .send({ idToken: res.body.id_token }) + .set("Accept", "application/json") + .expect(TestData.EntryCreatedStatusCode) + .then((res) => res.body.user.email === testUser.email); + }); + + it("should exchange scicat token from first additional authorized client", async () => { + const res = await request(keycloakUrl) + .post("/local-test/token") + .type("form") + .send(tokenBody("additional-authorized-client-test-1")) + .expect(TestData.EntryValidStatusCode) + .expect("Content-Type", /json/); + + // Avoid hitting rate limits + await new Promise((resolve) => setTimeout(resolve, 1000)); + + return request(appUrl) + .post("/api/v3/auth/oidc/token") + .send({ idToken: res.body.id_token }) + .set("Accept", "application/json") + .expect(TestData.EntryCreatedStatusCode) + .then((res) => res.body.user.email === testUser.email); + }); + + it("should exchange scicat token from second additional authorized client", async () => { + const res = await request(keycloakUrl) + .post("/local-test/token") + .type("form") + .send(tokenBody("additional-authorized-client-test-2")) + .expect(TestData.EntryValidStatusCode) + .expect("Content-Type", /json/); + + // Avoid hitting rate limits + await new Promise((resolve) => setTimeout(resolve, 1000)); + + return request(appUrl) + .post("/api/v3/auth/oidc/token") + .send({ idToken: res.body.id_token }) + .set("Accept", "application/json") + .expect(TestData.EntryCreatedStatusCode) + .then((res) => res.body.user.email === testUser.email); + }); + + it("should reject token exchange from untrusted client", async () => { + const res = await request(keycloakUrl) + .post("/local-test/token") + .type("form") + .send(tokenBody("untrusted-client-test")) + .expect(TestData.EntryValidStatusCode) + .expect("Content-Type", /json/); + + // Avoid hitting rate limits + await new Promise((resolve) => setTimeout(resolve, 1000)); + + return request(appUrl) + .post("/api/v3/auth/oidc/token") + .send({ idToken: res.body.id_token }) + .set("Accept", "application/json") + .expect(TestData.UnauthorizedStatusCode); + }); +}); diff --git a/test/config/.env b/test/config/.env index ae29b1da9..ba42bcba3 100644 --- a/test/config/.env +++ b/test/config/.env @@ -1,3 +1,9 @@ +OIDC_ISSUER=http://localhost:8080/local-test +OIDC_CLIENT_ID=scicat-client-test +OIDC_CLIENT_SECRET=secret +OIDC_SCOPE=openid profile email +OIDC_ADDITIONAL_AUTHORIZED_PARTIES=additional-authorized-client-test-1, additional-authorized-client-test-2 + ADMIN_GROUPS=admin,adminingestor CREATE_DATASET_GROUPS=group1,group2,group3 CREATE_DATASET_PRIVILEGED_GROUPS=datasetIngestor,group3 diff --git a/test/jest-e2e-tests/oidc.e2e-spec.ts b/test/jest-e2e-tests/oidcSession.e2e-spec.ts similarity index 97% rename from test/jest-e2e-tests/oidc.e2e-spec.ts rename to test/jest-e2e-tests/oidcSession.e2e-spec.ts index c27619ab0..49e9b0c8f 100644 --- a/test/jest-e2e-tests/oidc.e2e-spec.ts +++ b/test/jest-e2e-tests/oidcSession.e2e-spec.ts @@ -12,7 +12,7 @@ import { TestData } from "../TestData"; import { MongoClient } from "mongodb"; ["mongo", "memory"].forEach((store) => { - describe(`OIDC test ${store}`, () => { + describe(`OIDC session test ${store}`, () => { let app: INestApplication; let mongoConnection: Connection; let mongoClient: MongoClient; From ca508f40719566eb198272d46559bcbc7031b466 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 25 Mar 2026 09:36:23 +0100 Subject: [PATCH 092/120] fix: move oauth mock test env variables to CI (#2633) --- .github/workflows/test.yml | 6 ++++++ test/config/.env | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c4fb6cd8..5c4e82ea1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -136,6 +136,12 @@ jobs: ES_PASSWORD: duo-password MEM_LIMIT: 4G STACK_VERSION: 8.8.2 + OIDC_ISSUER: http://localhost:8080/local-test + OIDC_CLIENT_ID: scicat-client-test + OIDC_CLIENT_SECRET: secret + OIDC_SCOPE: openid profile email + OIDC_ADDITIONAL_AUTHORIZED_PARTIES: additional-authorized-client-test-1, additional-authorized-client-test-2 + # Start mongo container and app before running api tests run: | cp CI/ESS/docker-compose.api.yaml docker-compose.yaml diff --git a/test/config/.env b/test/config/.env index ba42bcba3..ae29b1da9 100644 --- a/test/config/.env +++ b/test/config/.env @@ -1,9 +1,3 @@ -OIDC_ISSUER=http://localhost:8080/local-test -OIDC_CLIENT_ID=scicat-client-test -OIDC_CLIENT_SECRET=secret -OIDC_SCOPE=openid profile email -OIDC_ADDITIONAL_AUTHORIZED_PARTIES=additional-authorized-client-test-1, additional-authorized-client-test-2 - ADMIN_GROUPS=admin,adminingestor CREATE_DATASET_GROUPS=group1,group2,group3 CREATE_DATASET_PRIVILEGED_GROUPS=datasetIngestor,group3 From 43cfc318b14e31556ca972310c83b0f668e90ee4 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 26 Mar 2026 13:18:22 +0100 Subject: [PATCH 093/120] BREAKING CHANGE: migrate elasticsearch to opensearch (#2562) * renaming elasticSearch to Opensearch * refactor opensearch query logic * load settings & mappings from json file * Set opensearchService optional in datasetService * fix unit test * update api test for opensearch * fix opensearch api test * added missing host for api test * fix api test * isIndexExists to return boolean value instead of body & fix opensearch API test * revert removed testData * fix api test * update unit tests * minor type correction for createFullfacetPipeline * add interface IDatasetOpenSearchPipeline for opensearch fullfacet pipe builder * remove unused configs & update env example * remove unused compose files & replace es image from all compose files & replace ES envs with OS envs * fix for permission filter * update default OS password for local development and remove .env.opensearch file * correct prepare:local command * update opensearch doc * update documentation * add api test for search query * centralize os query condition in one place * test1 * test * change dataset name in TestData.js used for api test * add OPENSEARCH_REFRESH="wait_for" for API test * avoid multi os config loading * run os connection retry on background * remove isAdmin * fix os api test * add bulk sync * user cursor for data sync * default dataSyncBatchSize to 1000 * added dataset opensearch dto * minor text change * add excludeExtraneousValues ot plainToInstance * update package * fix for inconsistant mongodb version across different packages * fix unit test * Use correct PickType for dataset-opensearch dto --- .env.example | 24 +- .github/workflows/test.yml | 15 +- .gitignore | 1 + CI/E2E/.env.backend-next.example | 15 +- CI/E2E/.env.elastic-search | 6 - CI/E2E/backend.env | 15 +- CI/E2E/docker-compose-local-no-es.yaml | 27 - CI/E2E/docker-compose-local.yaml | 41 +- CI/E2E/docker-compose.yaml | 37 +- CI/ESS/docker-compose.api.yaml | 29 +- CI/ESS/docker-compose.yaml | 25 +- README.md | 20 +- docker-compose.dev.yaml | 4 +- docs/developer-guide/opensearch-guidelines.md | 174 + docs/index.md | 106 +- opensearchConfig.example.json | 64 + package-lock.json | 3643 ++++++++++------- package.json | 8 +- src/casl/casl-ability.factory.ts | 10 +- src/common/types.ts | 3 +- src/common/utils.ts | 31 +- src/config/configuration.ts | 31 +- src/datasets/datasets.controller.ts | 14 +- src/datasets/datasets.module.ts | 9 +- src/datasets/datasets.service.spec.ts | 6 +- src/datasets/datasets.service.ts | 279 +- src/datasets/datasets.v4.controller.spec.ts | 3 +- .../interfaces/dataset-filters.interface.ts | 4 + src/elastic-search/Elasticsearch_guide.md | 211 - .../configuration/datasetFieldMapping.ts | 113 - .../configuration/indexSetting.ts | 126 - src/elastic-search/dto/create-index.dto.ts | 13 - src/elastic-search/dto/delete-index.dto.ts | 13 - src/elastic-search/dto/get-index.dto.ts | 13 - src/elastic-search/dto/index.ts | 13 - src/elastic-search/dto/search.dto.ts | 91 - src/elastic-search/dto/sync-data.dto.ts | 13 - src/elastic-search/dto/update-index.dto.ts | 13 - .../elastic-search.controller.ts | 137 - src/elastic-search/elastic-search.service.ts | 432 -- src/elastic-search/helpers/utils.ts | 255 -- .../interfaces/es-common.type.ts | 107 - .../interfaces/mappingInterface.type.ts | 16 - src/elastic-search/providers/fields.enum.ts | 38 - .../providers/query-builder.service.ts | 248 -- src/opensearch/dto/create-index.dto.ts | 20 + src/opensearch/dto/dataset-opensearch.dto.ts | 17 + src/opensearch/dto/update-index.dto.ts | 30 + src/opensearch/interfaces/os-common.type.ts | 5 + src/opensearch/opensearch.controller.ts | 196 + .../opensearch.module.ts} | 13 +- .../opensearch.service.spec.ts} | 22 +- src/opensearch/opensearch.service.ts | 386 ++ src/opensearch/opensearch.subject.ts | 1 + src/opensearch/providers/fields.enum.ts | 4 + .../providers/query-builder.service.spec.ts | 6 - .../providers/query-builder.service.ts | 92 + .../utils/dataset-opensearch.utils.ts | 16 + src/policies/policies.service.spec.ts | 2 +- .../published-data.controller.spec.ts | 4 +- test/DatasetV4.js | 54 +- test/ElasticSearch.js | 254 -- test/OpenSearch.js | 249 ++ test/TestData.js | 59 +- test/config/.env | 12 +- 65 files changed, 3986 insertions(+), 3952 deletions(-) delete mode 100644 CI/E2E/.env.elastic-search delete mode 100644 CI/E2E/docker-compose-local-no-es.yaml create mode 100644 docs/developer-guide/opensearch-guidelines.md create mode 100644 opensearchConfig.example.json delete mode 100644 src/elastic-search/Elasticsearch_guide.md delete mode 100644 src/elastic-search/configuration/datasetFieldMapping.ts delete mode 100644 src/elastic-search/configuration/indexSetting.ts delete mode 100644 src/elastic-search/dto/create-index.dto.ts delete mode 100644 src/elastic-search/dto/delete-index.dto.ts delete mode 100644 src/elastic-search/dto/get-index.dto.ts delete mode 100644 src/elastic-search/dto/index.ts delete mode 100644 src/elastic-search/dto/search.dto.ts delete mode 100644 src/elastic-search/dto/sync-data.dto.ts delete mode 100644 src/elastic-search/dto/update-index.dto.ts delete mode 100644 src/elastic-search/elastic-search.controller.ts delete mode 100644 src/elastic-search/elastic-search.service.ts delete mode 100644 src/elastic-search/helpers/utils.ts delete mode 100644 src/elastic-search/interfaces/es-common.type.ts delete mode 100644 src/elastic-search/interfaces/mappingInterface.type.ts delete mode 100644 src/elastic-search/providers/fields.enum.ts delete mode 100644 src/elastic-search/providers/query-builder.service.ts create mode 100644 src/opensearch/dto/create-index.dto.ts create mode 100644 src/opensearch/dto/dataset-opensearch.dto.ts create mode 100644 src/opensearch/dto/update-index.dto.ts create mode 100644 src/opensearch/interfaces/os-common.type.ts create mode 100644 src/opensearch/opensearch.controller.ts rename src/{elastic-search/elastic-search.module.ts => opensearch/opensearch.module.ts} (52%) rename src/{elastic-search/elastic-search.service.spec.ts => opensearch/opensearch.service.spec.ts} (62%) create mode 100644 src/opensearch/opensearch.service.ts create mode 100644 src/opensearch/opensearch.subject.ts create mode 100644 src/opensearch/providers/fields.enum.ts rename src/{elastic-search => opensearch}/providers/query-builder.service.spec.ts (91%) create mode 100644 src/opensearch/providers/query-builder.service.ts create mode 100644 src/opensearch/utils/dataset-opensearch.utils.ts delete mode 100644 test/ElasticSearch.js create mode 100644 test/OpenSearch.js diff --git a/.env.example b/.env.example index f130bbd0f..8e71efa0b 100644 --- a/.env.example +++ b/.env.example @@ -85,19 +85,17 @@ MS365_CLIENT_ID= MS365_CLIENT_SECRET= POLICY_PUBLICATION_SHIFT=3 years POLICY_RETENTION_SHIFT=-1 (indefinitely) -ELASTICSEARCH_ENABLED=<"yes"|"no"> -ES_HOST="https://localhost:9200" -ES_USERNAME="elastic" -ES_PASSWORD="duo-password" -ES_PORT=9200 -MONGODB_COLLECTION="Dataset" -ES_MAX_RESULT=100000 -ES_FIELDS_LIMIT=400000 -ES_INDEX="dataset" -ES_REFRESH=<"wait_for"|"false"> -STACK_VERSION="8.8.2" -CLUSTER_NAME="es-cluster" -MEM_LIMIT="4G" + +# "wait_for": waits for index refresh before returning, recommended for development and testing. +# "false": returns immediately without waiting, recommended for production. +OPENSEARCH_REFRESH=<"wait_for"|"false"> +OPENSEARCH_ENABLED=<"yes"|"no"> +OPENSEARCH_ENABLED="https://localhost:9200" +OPENSEARCH_ENABLED="admin" +OPENSEARCH_ENABLED="Scicat_default_password_2026" +OPENSEARCH_DEFAULT_INDEX="dataset" +OPENSEARCH_DATA_SYNC_BATCH_SIZE=50000 + FRONTEND_CONFIG_FILE="./src/config/frontend.config.json" FRONTEND_THEME_FILE="./src/config/frontend.theme.json" LOGGERS_CONFIG_FILE="loggers.json" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c4e82ea1..7f6bbe6de 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,14 +103,14 @@ jobs: run: npm run build api_tests: - name: API tests with ElasticSearch enabled - ${{ matrix.elasticsearch_enabled }} + name: API tests with OpenSearch enabled - ${{ matrix.opensearch_enabled }} needs: [install-and-cache] runs-on: ubuntu-latest strategy: fail-fast: false matrix: - elasticsearch_enabled: ["yes", "no"] + opensearch_enabled: ["yes", "no"] steps: - name: Checkout code @@ -130,12 +130,8 @@ jobs: - name: API tests env: - ELASTICSEARCH_ENABLED: ${{ matrix.elasticsearch_enabled }} - COMPOSE_PROFILES: ${{ matrix.elasticsearch_enabled == 'yes' && 'elasticsearch' || ''}} - CLUSTER_NAME: es-cluster - ES_PASSWORD: duo-password - MEM_LIMIT: 4G - STACK_VERSION: 8.8.2 + COMPOSE_PROFILES: ${{ matrix.opensearch_enabled == 'yes' && 'opensearch' || ''}} + OPENSEARCH_ENABLED: ${{ matrix.opensearch_enabled }} OIDC_ISSUER: http://localhost:8080/local-test OIDC_CLIENT_ID: scicat-client-test OIDC_CLIENT_SECRET: secret @@ -144,6 +140,7 @@ jobs: # Start mongo container and app before running api tests run: | + cp opensearchConfig.example.json opensearchConfig.json cp CI/ESS/docker-compose.api.yaml docker-compose.yaml docker compose up --build -d --wait - npm run test:api + OPENSEARCH_ENABLED=${{ matrix.opensearch_enabled }} npm run test:api diff --git a/.gitignore b/.gitignore index 3adbab30e..13e09a0a3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ jobConfig.json jobConfig.yaml metricsConfig.json publishedDataConfig.json +openSearchConfig.json # Configs .env diff --git a/CI/E2E/.env.backend-next.example b/CI/E2E/.env.backend-next.example index 2d9a8d313..652ab6cc5 100644 --- a/CI/E2E/.env.backend-next.example +++ b/CI/E2E/.env.backend-next.example @@ -39,12 +39,9 @@ DATASET_CREATION_VALIDATION_REGEX="^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][ PROPOSAL_GROUPS="proposalingestor" SAMPLE_GROUPS="" -ELASTICSEARCH_ENABLED='yes' -ES_HOST=http://es01:9200 -ES_USERNAME=elastic -ES_PASSWORD=duo-password -MONGODB_COLLECTION=Dataset -ES_MAX_RESULT=210000 -ES_FIELDS_LIMIT=400000 -ES_INDEX="dataset" -ES_REFRESH="wait_for" \ No newline at end of file +OPENSEARCH_ENABLED='yes' +OPENSEARCH_DEFAULT_INDEX="dataset" +OPENSEARCH_HOST=https://localhost:9200 +OPENSEARCH_USERNAME=admin +OPENSEARCH_PASSWORD=Scicat_default_password_2026 +OPENSEARCH_REFRESH="wait_for" \ No newline at end of file diff --git a/CI/E2E/.env.elastic-search b/CI/E2E/.env.elastic-search deleted file mode 100644 index d51156aa8..000000000 --- a/CI/E2E/.env.elastic-search +++ /dev/null @@ -1,6 +0,0 @@ -STACK_VERSION=8.8.2 -ES_PORT=9200 -CLUSTER_NAME=es-cluster -MEM_LIMIT=4G -ES_USERNAME=elastic -ES_PASSWORD=duo-password \ No newline at end of file diff --git a/CI/E2E/backend.env b/CI/E2E/backend.env index c6166a164..f97fe1c0f 100644 --- a/CI/E2E/backend.env +++ b/CI/E2E/backend.env @@ -36,12 +36,9 @@ DATASET_CREATION_VALIDATION_REGEX="^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][ PROPOSAL_GROUPS="proposalingestor" SAMPLE_GROUPS="" -ELASTICSEARCH_ENABLED='yes' -ES_HOST=http://es01:9200 -ES_USERNAME=elastic -ES_PASSWORD=duo-password -MONGODB_COLLECTION=Dataset -ES_MAX_RESULT=210000 -ES_FIELDS_LIMIT=400000 -ES_INDEX="dataset" -ES_REFRESH="wait_for" +OPENSEARCH_ENABLED=yes +OPENSEARCH_DEFAULT_INDEX="dataset" +OPENSEARCH_HOST=https://localhost:9200 +OPENSEARCH_USERNAME=admin +OPENSEARCH_PASSWORD=Scicat_default_password_2026 +OPENSEARCH_REFRESH="wait_for" \ No newline at end of file diff --git a/CI/E2E/docker-compose-local-no-es.yaml b/CI/E2E/docker-compose-local-no-es.yaml deleted file mode 100644 index 473cd43e4..000000000 --- a/CI/E2E/docker-compose-local-no-es.yaml +++ /dev/null @@ -1,27 +0,0 @@ -version: "3.2" -services: - mongodb: - image: bitnami/mongodb:latest - volumes: - - "mongodb_data:/bitnami" - ports: - - "27017:27017" - scichat-loopback: - image: dacat/scichat-loopback:e2e - command: - [ - "./wait-for-it.sh", - "mongodb:27017", - "--", - "node", - "-r", - "dotenv/config", - "." - ] - volumes: - - ".env.scichat-loopback:/home/node/app/.env" - depends_on: - - mongodb -volumes: - mongodb_data: - driver: local diff --git a/CI/E2E/docker-compose-local.yaml b/CI/E2E/docker-compose-local.yaml index f4f7c8e82..e8ce2a091 100644 --- a/CI/E2E/docker-compose-local.yaml +++ b/CI/E2E/docker-compose-local.yaml @@ -1,11 +1,12 @@ version: "3.2" services: mongodb: - image: bitnami/mongodb:latest + image: mongo:latest volumes: - - "mongodb_data:/bitnami" + - "mongodb_data:/data/db" ports: - "27017:27017" + scichat-loopback: image: dacat/scichat-loopback:e2e command: @@ -23,28 +24,44 @@ services: depends_on: - mongodb - es01: + opensearch: depends_on: - mongodb - image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + image: opensearchproject/opensearch:3.5.0 ports: - - ${ES_PORT}:9200 + - 9200:9200 environment: - - node.name=es01 - - ES_JAVA_OPTS=-Xms2g -Xmx2g - - cluster.name=${CLUSTER_NAME} - - cluster.initial_master_nodes=es01 - - ELASTIC_PASSWORD=${ES_PASSWORD} + - node.name=opensearch + - discovery.type=single-node + - cluster.name=os-cluster - bootstrap.memory_lock=true - mem_limit: ${MEM_LIMIT} + - OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g + - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Scicat_default_password_2026 + volumes: + - opensearch_data:/usr/share/opensearch/data + mem_limit: 4G ulimits: memlock: soft: -1 hard: -1 + + # Web UI for OpenSearch + # Enable this service if you want to use OpenSearch Dashboards to visualize and debug your OpenSearch data. + # Access it at http://localhost:5601 + # opensearch-dashboards: + # image: opensearchproject/opensearch-dashboards:3.5.0 + # ports: + # - "5601:5601" + # environment: + # - OPENSEARCH_HOSTS=https://opensearch:9200 + # - OPENSEARCH_USERNAME=admin + # - OPENSEARCH_PASSWORD=Scicat_default_password_2026 + # - OPENSEARCH_SSL_VERIFICATIONMODE=none + volumes: mongodb_data: driver: local - es01: + opensearch_data: driver: local diff --git a/CI/E2E/docker-compose.yaml b/CI/E2E/docker-compose.yaml index 9435844ef..f5d10923d 100644 --- a/CI/E2E/docker-compose.yaml +++ b/CI/E2E/docker-compose.yaml @@ -8,11 +8,11 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock mongodb: - image: "bitnami/mongodb:latest" + image: "mongo:latest" ports: - "27017:27017" volumes: - - "mongodb_data:/bitnami" + - "mongodb_data:/data/db" healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh mongodb:27017/test --quiet interval: 10s @@ -63,35 +63,28 @@ services: - "traefik.http.routers.frontend.rule=PathPrefix(`/`)" - "traefik.http.routers.frontend.entrypoints=web" - es01: - image: docker.elastic.co/elasticsearch/elasticsearch:8.8.2 + opensearch: + depends_on: + - mongodb + image: opensearchproject/opensearch:3.5.0 ports: - 9200:9200 environment: - - xpack.security.enabled=false - - node.name=es01 - - ES_JAVA_OPTS=-Xms512m -Xmx512m - - cluster.name=es-cluster - - cluster.initial_master_nodes=es01 + - node.name=opensearch + - discovery.type=single-node + - cluster.name=os-cluster - bootstrap.memory_lock=true - mem_limit: 1g + - OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g + - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Scicat_default_password_2026 + volumes: + - opensearch_data:/usr/share/opensearch/data + mem_limit: 4G ulimits: memlock: soft: -1 hard: -1 - healthcheck: - test: - [ - "CMD-SHELL", - "curl -s -X GET 'http://es01:9200/_cluster/health?pretty' | grep status | grep -q '\\(green\\|yellow\\)'" - ] - interval: 30s - timeout: 10s - start_period: 60s - retries: 4 - volumes: mongodb_data: driver: local - es01: + opensearch_data: driver: local diff --git a/CI/ESS/docker-compose.api.yaml b/CI/ESS/docker-compose.api.yaml index 4f78a2950..40a364e4c 100644 --- a/CI/ESS/docker-compose.api.yaml +++ b/CI/ESS/docker-compose.api.yaml @@ -72,31 +72,36 @@ services: mongodb: image: mongo:latest volumes: - - mongodb_data:/bitnami + - "mongodb_data:/data/db" ports: - "27017:27017" - es01: + opensearch: profiles: - - elasticsearch + - opensearch depends_on: - mongodb - image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + image: opensearchproject/opensearch:3.5.0 ports: - "9200:9200" environment: - - node.name=es01 - - ES_JAVA_OPTS=-Xms2g -Xmx2g - - cluster.name=${CLUSTER_NAME} - - cluster.initial_master_nodes=es01 - - ELASTIC_PASSWORD=${ES_PASSWORD} + - node.name=opensearch + - discovery.type=single-node + - cluster.name=os-test-cluster - bootstrap.memory_lock=true - mem_limit: ${MEM_LIMIT} + - OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g + - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Scicat_default_password_2026 + mem_limit: 4G ulimits: memlock: soft: -1 hard: -1 + healthcheck: + test: ["CMD-SHELL", "curl -sk -u admin:Scicat_default_password_2026 https://localhost:9200/_cluster/health || exit 1"] + interval: 10s + timeout: 10s + retries: 10 + start_period: 30s volumes: mongodb_data: driver: local - es01: - driver: local + diff --git a/CI/ESS/docker-compose.yaml b/CI/ESS/docker-compose.yaml index 2e8f9796f..b412a700f 100644 --- a/CI/ESS/docker-compose.yaml +++ b/CI/ESS/docker-compose.yaml @@ -27,22 +27,27 @@ services: depends_on: - mongodb - es01: + opensearch: depends_on: - mongodb - image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + image: opensearchproject/opensearch:3.5.0 + ports: + - 9200:9200 environment: - - node.name=es01 - - ES_JAVA_OPTS=-Xms2g -Xmx2g - - cluster.name=${CLUSTER_NAME} - - cluster.initial_master_nodes=es01 - - ELASTIC_PASSWORD=${ES_PASSWORD} + - node.name=opensearch + - discovery.type=single-node + - cluster.name=os-cluster - bootstrap.memory_lock=true - mem_limit: ${MEM_LIMIT} + - OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g + - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Scicat_default_password_2026 + volumes: + - opensearch_data:/usr/share/opensearch/data + mem_limit: 4G ulimits: memlock: soft: -1 hard: -1 + # catanie: # build: # context: catanie @@ -114,5 +119,5 @@ volumes: driver: local rabbitmq_data: driver: local - es01: - driver: local + opensearch_data: + driver: local \ No newline at end of file diff --git a/README.md b/README.md index 0fd22810e..98a0c3570 100644 --- a/README.md +++ b/README.md @@ -238,19 +238,13 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) |`MS365_CLIENT_SECRET`| string | Yes | Client Secret for sending emails over Microsoft Graph API | | |`POLICY_PUBLICATION_SHIFT`| integer | Yes | Embargo period expressed in years. | 3 years | |`POLICY_RETENTION_SHIFT`| integer | Yes | Retention period (how long the facility will hold on to data) expressed in years. | -1 (indefinitely) | -|`ELASTICSEARCH_ENABLED`| string | | Flag to enable/disable the Elasticsearch endpoints. Values "yes" or "no". | "no" | -|`ES_HOST`| string | | Host of Elasticsearch server instance. |"https://localhost:9200"| -|`ES_USERNAME`| string | Yes | Elasticsearch username. | "elastic" | -|`ES_PASSWORD`| string | | Elasticsearch password. |"duo-password"| -|`ES_PORT`| number | | Elasticsearch port. |9200| -|`MONGODB_COLLECTION`| string | | Collection name to be mapped into specified Elasticsearch index. Used for data synchronization between MongoDB and Elasticsearch index. |"Dataset"| -|`ES_MAX_RESULT`| number | Yes | Maximum records that can be indexed into Elasticsearch. | 10000 | -|`ES_FIELDS_LIMIT`| number | Yes | The total number of fields in an index. | 1000 | -|`ES_INDEX`| string | | Setting default index for the application |"dataset"| -|`ES_REFRESH`| string | | If set to`wait_for`, Elasticsearch will wait till data is inserted into the specified index before returning a response. | false | -|`STACK_VERSION` | string | Yes | Defines the Elasticsearch version to deploy | "8.8.2" | -|`CLUSTER_NAME` | string | Yes | Sets the name of the Elasticsearch cluster | "es-cluster" | -|`MEM_LIMIT`| string | Yes | Specifies the max memory for Elasticsearch container (or process) | "4G" | +|`OPENSEARCH_ENABLED`| string | | Controls whether OpenSearch is enabled on application startup. If not provided or set to `no`, OpenSearch will not be instantiated.| "no" | +|`OPENSEARCH_DEFAULT_INDEX`| string | | Specifies the default index. If not provided, a default index named `dataset` will be created automatically. | "dataset" | +|`OPENSEARCH_HOST`| string | | Host of Opensearch server instance. | | +|`OPENSEARCH_USERNAME`| string | Yes | Username for OpenSearch authentication. Defaults to `admin` in standard deployments but can be configured to use a custom user with appropriate permissions. | "admin" | +|`OPENSEARCH_PASSWORD`| string | | Password used for OpenSearch authentication. Must match `OPENSEARCH_INITIAL_ADMIN_PASSWORD` used when creating the OpenSearch container. | | +|`OPENSEARCH_REFRESH`| string | | Controls index refresh behavior. `wait_for`waits for the next refresh cycle before returning, which is useful for development and testing.`false`skips waiting and is recommended for production. Defaults to false. | false | +|`OPENSEARCH_DATA_SYNC_BATCH_SIZE`| number | | Number of documents fetched from MongoDB per batch during OpenSearch data sync. | 1000 | |`FRONTEND_CONFIG_FILE`| string | | The file name for frontend configuration, located in the`/src/config`directory by default. | "./src/config/frontend.config.json" | |`FRONTEND_THEME_FILE`| string | | The file name for frontend theme, located in the`/src/config`directory by default. | "./src/config/frontend.theme.json" | |`LOGGERS_CONFIG_FILE`| string | | The file name for loggers configuration, located in the project root directory. | "loggers.json" | diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index bf2d7cf96..dfdcb76ac 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -1,8 +1,8 @@ services: mongodb: - image: docker.io/bitnami/mongodb:4.2 + image: mongo:latest volumes: - - mongodb_data:/bitnami + - "mongodb_data:/data/db" backend: build: context: . diff --git a/docs/developer-guide/opensearch-guidelines.md b/docs/developer-guide/opensearch-guidelines.md new file mode 100644 index 000000000..8a26aeccb --- /dev/null +++ b/docs/developer-guide/opensearch-guidelines.md @@ -0,0 +1,174 @@ +--- +title: OpenSearch Integration +audience: Technical +created_by: Junjie Quan +created_on: 2026-03-17 +--- + +# OpenSearch Integration + +## Overview + +SciCat now includes an OpenSearch integration to support search functionality within the platform. The transition from Elasticsearch to OpenSearch was made following the Elasticsearch license change in order to maintain the use of fully open-source components in the project. + +The current OpenSearch integration supports partial text search for datasets. + +Text search currently targets only the following fields: + +- `datasetName` +- `description` + +All other filters and queries continue to be executed using MongoDB queries. + +SciCat uses the official OpenSearch JavaScript client `@opensearch-project/opensearch@^3.5.1` for indexing, synchronization, and search operations. This version is compatible with OpenSearch v3.5.0. + +To be able to start application with OpenSearch you will need to: + +## Getting Started + +To start the application with OpenSearch: + +1. Run `npm run prepare:local` to start the OpenSearch cluster as a Docker container. +2. Set `OPENSEARCH_ENABLED=yes` and provide values for all required environment variables: `OPENSEARCH_HOST`, `OPENSEARCH_USERNAME`, and `OPENSEARCH_PASSWORD`. + > **Note:** `OPENSEARCH_PASSWORD` must match `OPENSEARCH_INITIAL_ADMIN_PASSWORD` set when creating the OpenSearch container. +3. Start the application with `npm run start`. On successful connection you will see: + +``` + [Nest] 80126 - 03/17/2026, 3:09:41 PM LOG [Opensearch] Opensearch Connected +``` + +4. Open the Swagger page at `http://localhost:3000/explorer` and authorize with an `admin` token. +5. Execute `POST /opensearch/create-index` to create the index. + > **Note:** This step can be skipped if you want to use the default index `dataset`. +6. Execute `POST /opensearch/sync-database` to sync data from MongoDB into OpenSearch. On success you will see: + +```json +{ + "total": 21670, + "failed": 0, + "retry": 0, + "successful": 21670, + "noop": 0, + "time": 4777, + "bytes": 279159021, + "aborted": false +} +``` + +## Environment Configuration + +OpenSearch behavior is controlled using environment variables. +To enable OpenSearch, set `OPENSEARCH_ENABLED=yes` and provide values for all required environment variables: `OPENSEARCH_HOST`, `OPENSEARCH_USERNAME`, and `OPENSEARCH_PASSWORD`. + +| Variable | Example | Description | Required | +| --------------------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `OPENSEARCH_ENABLED` | `"yes" \| "no"` | Controls whether OpenSearch is enabled on application startup. If not provided or set to `no`, OpenSearch will not be instantiated. | Yes | +| `OPENSEARCH_DEFAULT_INDEX` | `dataset` | Specifies the default index. If not provided, a default index named `dataset` will be created automatically. | No | +| `OPENSEARCH_HOST` | `https://localhost:9200` | Specifies the OpenSearch server endpoint. | Yes | +| `OPENSEARCH_USERNAME` | `"admin"` | Username for OpenSearch authentication. Defaults to `admin` in standard deployments but can be configured to use a custom user with appropriate permissions. | Yes | +| `OPENSEARCH_PASSWORD` | `Scicat-password2026` | Password used for OpenSearch authentication. Must match `OPENSEARCH_INITIAL_ADMIN_PASSWORD` used when creating the OpenSearch container. | Yes | +| `OPENSEARCH_REFRESH` | `"wait_for" \| "false"` | Controls index refresh behavior. `wait_for` waits for the next refresh cycle before returning, which is useful for development and testing. `false` skips waiting and is recommended for production. Defaults to false. | No | +| `OPENSEARCH_DATA_SYNC_BATCH_SIZE` | 1000 | Number of documents fetched from MongoDB per batch during OpenSearch data sync. Defaults to 10000 | No | + +## Index Configuration + +OpenSearch index settings and mappings can be customized using a configuration file. + +An optional `opensearchConfig.json` file can be mounted to `/home/node/app/opensearchConfig.json` in the container (or placed in the project root when running locally) to define custom index settings and mappings. + +If not provided, a default configuration will be loaded from `opensearchConfig.example.json` in the root, supporting partial text search on `datasetName` and `description`. + +For full configuration options, see: +https://docs.opensearch.org/latest/install-and-configure/configuring-opensearch/index/ + +## Query Logic + +Search queries follow the process below. + +### Access Filtering + +Before performing text search, results are filtered based on user access permissions: + +1. If the user belongs to one or more `userGroups`, these are applied as access filters. +2. If the user has no groups and is not an admin, the `isPublished` filter is applied. +3. Admin users bypass group-based access filters, which means queries are executed against a larger dataset. This is a known limitation and may result in slower response times for admin search requests. + +### Text Search + +After access filtering, OpenSearch performs a partial text search on the following fields: + +- `datasetName` +- `description` + +These fields are currently hardcoded in the `MustFields` enum (`src/opensearch/providers/fields.enum.ts`) and are not configurable. + +## API Endpoints + +All OpenSearch endpoints are restricted to admin users. + +### Create Index + +**POST** `/opensearch/create-index` + +- `index` (body, required): Target index name. default: `dataset` +- `settings` (body, optional): Index settings to apply. If not provided, defaults from `opensearchConfig.json` are used. + +--- + +### Sync Database + +**POST** `/opensearch/sync-database` + +Synchronizes datasets from MongoDB to OpenSearch. + +- `index` (query, optional): Index name. default: `dataset` + +--- + +### Search + +**POST** `/opensearch/search` + +Performs partial text search on datasets. + +- `textQuery` (query): Search text (applies to `datasetName` and `description`) +- `index` (query, optional): Target index name. default: `dataset` +- `limit` (query, optional): Max results +- `skip` (query, optional): Offset + +Returns matching dataset `_id`s. + +--- + +### Delete Index + +**POST** `/opensearch/delete-index` + +Deletes an index. + +- `index` (query): Target index name. + +--- + +### Get Index Configuration + +**GET** `/opensearch/get-index` + +Retrieves index settings and mappings. + +- `index` (query): Target index name. default: `dataset` + +--- + +### Update Index Settings + +**POST** `/opensearch/update-index` + +Updates index settings. Closes the index, applies the new settings, then reopens it. + +- `index` (body, required): Target index name. default: `dataset` +- `settings` (body, optional): Index settings to apply. If not provided, defaults from `opensearchConfig.json` are used. + +--- + +If you encounter performance issues related to OpenSearch, please open a [GitHub issue](https://github.com/SciCatProject/backend/issues) or report them at the SciCat meeting. diff --git a/docs/index.md b/docs/index.md index 6946b0615..22e9632ac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -131,7 +131,7 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `JWT_SECRET` | string | | The secret for your JWT token, used for authorization. | | | `JWT_EXPIRES_IN` | number | Yes | How long, in seconds, the JWT token is valid. | 3600 | | `LDAP_URL` | string | Yes | The URL to your LDAP server. | | -| `LDAP_BIND_DN` | string | Yes | Bind_DN for your LDAP server. | | +| `LDAP_BIND_DN` | string | Yes | Bind*DN for your LDAP server. | | | `LDAP_BIND_CREDENTIALS` | string | Yes | Credentials for your LDAP server. | | | `LDAP_SEARCH_BASE` | string | Yes | Search base for your LDAP server. | | | `LDAP_SEARCH_FILTER` | string | Yes | Search filter for your LDAP server. | | @@ -142,59 +142,57 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `OIDC_SCOPE` | string | Yes | Space-separated list of info returned by the OIDC service. Example: "openid profile email". | | | `OIDC_SUCCESS_URL` | string | Yes | SciCat Frontend auth-callback URL. Required to pass user credentials to SciCat Frontend after OIDC login. Example: https://myscicatfrontend/auth-callback. Must be `frontend-base-url/auth-callback` or `frontend-base-url/login` for the official SciCat frontend. | | | `OIDC_RETURN_URL` | string | Yes | The path segment within the SciCat Frontend to redirect to, passed as query param in `OIDC_SUCCESS_URL` and handled by frontend. Example: /datasets. | | -| `OIDC_FRONTEND_CLIENTS` | string | Yes | Comma separated list of additional frontend OIDC clients for this backend. Example: scilog,maxiv. Their success and return URLs can be configured by setting `OIDC_${CLIENT}_SUCCESS_URL` (E.g. `OIDC_SCILOG_SUCCESS_URL`) and `OIDC_${CLIENT}_RETURN_URL` | | -| `OIDC_ACCESS_GROUPS` | string | Yes | Functionality is still unclear. | | -| `OIDC_ACCESS_GROUPS_PROPERTY` | string | Yes | Target field to get the access groups value from OIDC response. | | -| `OIDC_USERINFO_MAPPING_FIELD_USERNAME` | string | Yes | Comma-separated list of fields from the OIDC response to use as the user's profile username. Example: `OIDC_USERINFO_MAPPING_FIELD_USERNAME="iss, sub"`. | "preferred_username" \|\| "name" | -| `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME` | string | Yes | Field from the OIDC response to use as the user's profile display name. Example: `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME="preferred_username"`. | "name" | -| `OIDC_USERINFO_MAPPING_FIELD_EMAIL` | string | Yes | Field from the OIDC response to use as the user's profile email. | "email" | -| `OIDC_USERINFO_MAPPING_FIELD_FAMILYNAME` | string | Yes | Field from the OIDC response to use as the user's profile family name. | "family_name" | -| `OIDC_USERINFO_MAPPING_FIELD_ID` | string | Yes | Field from the OIDC response to use as the user's profile ID. | "sub" \|\| "user_id" | -| `OIDC_USERINFO_MAPPING_FIELD_THUMBNAILPHOTO`| string | Yes | Field from the OIDC response to use as the user's profile thumbnail photo. | "thumbnailPhoto" | -| `OIDC_USERINFO_MAPPING_FIELD_PROVIDER` | string | Yes | Field from the OIDC response to use as the user's profile provider. | "iss" | -| `OIDC_USERINFO_MAPPING_FIELD_GROUP` | string | Yes | Field from the OIDC response to use as the user's profile group. | "groups" | -| `OIDC_USERQUERY_OPERATOR` | string | Yes | Specifies the operator ("or" or "and") for UserModel.findOne queries, determining the logic used to match fields like "username" or "email". Example: `UserModel.findOne({$or: {"username":"testUser", "email":"test@test.com"}})`. | "or" | -| `OIDC_USERQUERY_FILTER` | string | Yes | Defines key-value pairs for UserModel.findOne queries, using a "key:value" format. Example: `OIDC_USERQUERY_FILTER="username:sub, email:email"`. | "username:username, email:email" | -| `LOGBOOK_ENABLED` | string | Yes | Flag to enable/disable the Logbook endpoints. Values "yes" or "no". | "no" | -| `LOGBOOK_BASE_URL` | string | Yes | The base URL to the Logbook API. Only required if Logbook is enabled. | | -| `METADATA_KEYS_RETURN_LIMIT` | number | Yes | The return limit for the `/Datasets/metadataKeys` endpoint. | | -| `METADATA_PARENT_INSTANCES_RETURN_LIMIT` | number | Yes | The return limit of Datasets to extract metadata keys from for the `/Datasets/metadataKeys` endpoint. | | -| `MONGODB_URI` | string | | The URI for your MongoDB instance. | | -| `OAI_PROVIDER_ROUTE` | string | Yes | URI to OAI provider, used for the `/publisheddata/:id/resync` endpoint. | | -| `PID_PREFIX` | string | | The facility PID prefix, with trailing slash. | | -| `PUBLIC_URL_PREFIX` | string | | The base URL to the facility Landing Page. | | -| `PORT` | number | Yes | The port on which you want to access the app. | 3000 | -| `RABBITMQ_ENABLED` | string | Yes | Flag to enable/disable RabbitMQ consumer. Values "yes" or "no". | "no" | -| `RABBITMQ_HOSTNAME` | string | Yes | The hostname of the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | -| `RABBITMQ_USERNAME` | string | Yes | The username used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | -| `RABBITMQ_PASSWORD` | string | Yes | The password used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | -| `REGISTER_DOI_URI` | string | | URI to the organization that registers the facility's DOIs. | | -| `REGISTER_METADATA_URI` | string | | URI to the organization that registers the facility's published data metadata. | | -| `SITE` | string | | The name of your site. | | -| `EMAIL_TYPE` | string | Yes | The type of your email provider. Options are "smtp" or "ms365". | "smtp" | -| `EMAIL_FROM` | string | Yes | Email address that emails should be sent from. | | -| `EMAIL_REPLYTO` | string | Yes | Email 'Reply-To' field. | | -| `SMTP_HOST` | string | Yes | Host of SMTP server. | | -| `SMTP_MESSAGE_FROM` | string | Yes | (Deprecated) Alternate spelling of EMAIL_FROM.| | -| `SMTP_PORT` | number | Yes | Port of SMTP server. | 587 | -| `SMTP_SECURE` | bool | Yes | Use encrypted SMTPS. | "no" | -| `MS365_TENANT_ID` | string | Yes | Tenant ID for sending emails over Microsoft Graph API. | | -| `MS365_CLIENT_ID` | string | Yes | Client ID for sending emails over Microsoft Graph API | | -| `MS365_CLIENT_SECRET` | string | Yes | Client Secret for sending emails over Microsoft Graph API | | -| `POLICY_PUBLICATION_SHIFT` | integer | Yes | Embargo period expressed in years. | 3 years | -| `POLICY_RETENTION_SHIFT` | integer | Yes | Retention period (how long the facility will hold on to data) expressed in years. | -1 (indefinitely) | -| `ELASTICSEARCH_ENABLED` | string | | Flag to enable/disable the Elasticsearch endpoints. Values "yes" or "no". | "no" | -| `ES_HOST` | string | | Host of Elasticsearch server instance. | | -| `ES_USERNAME` | string | Yes | Elasticsearch username. | "elastic" | -| `ES_PASSWORD` | string | | Elasticsearch password. | | -| `MONGODB_COLLECTION` | string | | Collection name to be mapped into specified Elasticsearch index. Used for data synchronization between MongoDB and Elasticsearch index. | | -| `ES_MAX_RESULT` | number | | Maximum records that can be indexed into Elasticsearch. | 10000 | -| `ES_FIELDS_LIMIT` | number | | The total number of fields in an index. | 1000 | -| `ES_REFRESH` | string | | If set to `wait_for`, Elasticsearch will wait till data is inserted into the specified index before returning a response. | false | -| `LOGGERS_CONFIG_FILE` | string | | The file name for loggers configuration, located in the project root directory. | "loggers.json" | -| `PROPOSAL_TYPES_FILE` | string | | The file name for proposal types configuration, located in the project root directory. | "proposalTypes.json" | -| `SWAGGER_PATH` | string | Yes | swaggerPath is the path where the swagger UI will be available. | "explorer"| -| `MAX_FILE_UPLOAD_SIZE` | string | Yes | Maximum allowed file upload size. | "16mb"| +| `OIDC_FRONTEND_CLIENTS` | string | Yes | Comma separated list of additional frontend OIDC clients for this backend. Example: scilog,maxiv. Their success and return URLs can be configured by setting `OIDC*${CLIENT}_SUCCESS_URL` (E.g. `OIDC_SCILOG_SUCCESS_URL`) and `OIDC_${CLIENT}\_RETURN_URL`| | +|`OIDC_ACCESS_GROUPS`| string | Yes | Functionality is still unclear. | | +|`OIDC_ACCESS_GROUPS_PROPERTY`| string | Yes | Target field to get the access groups value from OIDC response. | | +|`OIDC_USERINFO_MAPPING_FIELD_USERNAME`| string | Yes | Comma-separated list of fields from the OIDC response to use as the user's profile username. Example:`OIDC_USERINFO_MAPPING_FIELD_USERNAME="iss, sub"`. | "preferred_username" \|\| "name" | +| `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`| string | Yes | Field from the OIDC response to use as the user's profile display name. Example:`OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME="preferred_username"`. | "name" | +| `OIDC_USERINFO_MAPPING_FIELD_EMAIL`| string | Yes | Field from the OIDC response to use as the user's profile email. | "email" | +|`OIDC_USERINFO_MAPPING_FIELD_FAMILYNAME`| string | Yes | Field from the OIDC response to use as the user's profile family name. | "family_name" | +|`OIDC_USERINFO_MAPPING_FIELD_ID`| string | Yes | Field from the OIDC response to use as the user's profile ID. | "sub" \|\| "user_id" | +|`OIDC_USERINFO_MAPPING_FIELD_THUMBNAILPHOTO`| string | Yes | Field from the OIDC response to use as the user's profile thumbnail photo. | "thumbnailPhoto" | +| `OIDC_USERINFO_MAPPING_FIELD_PROVIDER`| string | Yes | Field from the OIDC response to use as the user's profile provider. | "iss" | +|`OIDC_USERINFO_MAPPING_FIELD_GROUP`| string | Yes | Field from the OIDC response to use as the user's profile group. | "groups" | +|`OIDC_USERQUERY_OPERATOR`| string | Yes | Specifies the operator ("or" or "and") for UserModel.findOne queries, determining the logic used to match fields like "username" or "email". Example:`UserModel.findOne({$or: {"username":"testUser", "email":"test@test.com"}})`. | "or" | +| `OIDC_USERQUERY_FILTER`| string | Yes | Defines key-value pairs for UserModel.findOne queries, using a "key:value" format. Example:`OIDC_USERQUERY_FILTER="username:sub, email:email"`. | "username:username, email:email" | +| `LOGBOOK_ENABLED`| string | Yes | Flag to enable/disable the Logbook endpoints. Values "yes" or "no". | "no" | +|`LOGBOOK_BASE_URL`| string | Yes | The base URL to the Logbook API. Only required if Logbook is enabled. | | +|`METADATA_KEYS_RETURN_LIMIT`| number | Yes | The return limit for the`/Datasets/metadataKeys`endpoint. | | +|`METADATA_PARENT_INSTANCES_RETURN_LIMIT`| number | Yes | The return limit of Datasets to extract metadata keys from for the`/Datasets/metadataKeys`endpoint. | | +|`MONGODB_URI`| string | | The URI for your MongoDB instance. | | +|`OAI_PROVIDER_ROUTE`| string | Yes | URI to OAI provider, used for the`/publisheddata/:id/resync`endpoint. | | +|`PID_PREFIX`| string | | The facility PID prefix, with trailing slash. | | +|`PUBLIC_URL_PREFIX`| string | | The base URL to the facility Landing Page. | | +|`PORT`| number | Yes | The port on which you want to access the app. | 3000 | +|`RABBITMQ_ENABLED`| string | Yes | Flag to enable/disable RabbitMQ consumer. Values "yes" or "no". | "no" | +|`RABBITMQ_HOSTNAME`| string | Yes | The hostname of the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | +|`RABBITMQ_USERNAME`| string | Yes | The username used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | +|`RABBITMQ_PASSWORD`| string | Yes | The password used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | +|`REGISTER_DOI_URI`| string | | URI to the organization that registers the facility's DOIs. | | +|`REGISTER_METADATA_URI`| string | | URI to the organization that registers the facility's published data metadata. | | +|`SITE`| string | | The name of your site. | | +|`EMAIL_TYPE`| string | Yes | The type of your email provider. Options are "smtp" or "ms365". | "smtp" | +|`EMAIL_FROM`| string | Yes | Email address that emails should be sent from. | | +|`EMAIL_REPLYTO`| string | Yes | Email 'Reply-To' field. | | +|`SMTP_HOST`| string | Yes | Host of SMTP server. | | +|`SMTP_MESSAGE_FROM`| string | Yes | (Deprecated) Alternate spelling of EMAIL_FROM.| | +|`SMTP_PORT`| number | Yes | Port of SMTP server. | 587 | +|`SMTP_SECURE`| bool | Yes | Use encrypted SMTPS. | "no" | +|`MS365_TENANT_ID`| string | Yes | Tenant ID for sending emails over Microsoft Graph API. | | +|`MS365_CLIENT_ID`| string | Yes | Client ID for sending emails over Microsoft Graph API | | +|`MS365_CLIENT_SECRET`| string | Yes | Client Secret for sending emails over Microsoft Graph API | | +|`POLICY_PUBLICATION_SHIFT`| integer | Yes | Embargo period expressed in years. | 3 years | +|`POLICY_RETENTION_SHIFT`| integer | Yes | Retention period (how long the facility will hold on to data) expressed in years. | -1 (indefinitely) | +|`OPENSEARCH_ENABLED`| string | | Controls whether OpenSearch is enabled on application startup. If not provided or set to `no`, OpenSearch will not be instantiated.| "no" | +|`OPENSEARCH_DEFAULT_INDEX`| string | | Specifies the default index. If not provided, a default index named `dataset` will be created automatically. | "dataset" | +|`OPENSEARCH_HOST`| string | | Host of Opensearch server instance. | | +|`OPENSEARCH_USERNAME`| string | Yes | Username for OpenSearch authentication. Defaults to `admin` in standard deployments but can be configured to use a custom user with appropriate permissions. | "admin" | +|`OPENSEARCH_PASSWORD`| string | | Password used for OpenSearch authentication. Must match `OPENSEARCH_INITIAL_ADMIN_PASSWORD` used when creating the OpenSearch container. | | +|`OPENSEARCH_REFRESH`| string | | Controls index refresh behavior. `wait_for`waits for the next refresh cycle before returning, which is useful for development and testing.`false`skips waiting and is recommended for production. Defaults to false. | false | +|`LOGGERS_CONFIG_FILE`| string | | The file name for loggers configuration, located in the project root directory. | "loggers.json" | +|`PROPOSAL_TYPES_FILE`| string | | The file name for proposal types configuration, located in the project root directory. | "proposalTypes.json" | +|`SWAGGER_PATH`| string | Yes | swaggerPath is the path where the swagger UI will be available. | "explorer"| +|`MAX_FILE_UPLOAD_SIZE` | string | Yes | Maximum allowed file upload size. | "16mb"| ## Migrating from the old SciCat Backend diff --git a/opensearchConfig.example.json b/opensearchConfig.example.json new file mode 100644 index 000000000..5e851410a --- /dev/null +++ b/opensearchConfig.example.json @@ -0,0 +1,64 @@ +{ + "settings": { + "index": { + "max_result_window": 2000000, + "number_of_replicas": 0 + }, + "analysis": { + "analyzer": { + "autocomplete": { + "type": "custom", + "tokenizer": "autocomplete", + "filter": ["word_delimiter", "lowercase"] + }, + "autocomplete_search": { + "type": "custom", + "tokenizer": "keyword", + "filter": ["lowercase"] + } + }, + "tokenizer": { + "autocomplete": { + "type": "edge_ngram", + "min_gram": 2, + "max_gram": 150, + "token_chars": ["letter", "digit", "symbol", "punctuation"] + } + }, + "filter": { + "word_delimiter": { + "type": "word_delimiter_graph", + "split_on_case_change": false, + "split_on_numerics": false, + "preserve_original": true, + "type_table": [". => ALPHA"] + } + } + } + }, + "mappings": { + "properties": { + "description": { + "type": "text", + "analyzer": "autocomplete", + "search_analyzer": "autocomplete_search" + }, + "datasetName": { + "type": "text", + "analyzer": "autocomplete", + "search_analyzer": "autocomplete_search" + }, + "isPublished": { + "type": "boolean" + }, + "ownerGroup": { + "type": "keyword", + "ignore_above": 256 + }, + "accessGroups": { + "type": "keyword", + "ignore_above": 256 + } + } + } +} diff --git a/package-lock.json b/package-lock.json index c92fd2010..cba1b1aab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,11 @@ "dependencies": { "@casl/ability": "^6.3.2", "@casl/mongoose": "^8.0.4", - "@elastic/elasticsearch": "^8.15.0", "@nestjs-modules/mailer": "^2", "@nestjs/axios": "^4", "@nestjs/common": "^11", "@nestjs/config": "^4", "@nestjs/core": "^11", - "@nestjs/elasticsearch": "^11", "@nestjs/event-emitter": "^3", "@nestjs/jwt": "^11", "@nestjs/mongoose": "^11.0.4", @@ -26,6 +24,7 @@ "@nestjs/swagger": "^11.1.1", "@nestjs/terminus": "^11", "@nestjs/throttler": "^6.5.0", + "@opensearch-project/opensearch": "^3.5.1", "@types/json-merge-patch": "^1.0.0", "@types/jsonschema": "^1.1.1", "@user-office-software/duo-logger": "^2.1.1", @@ -110,20 +109,49 @@ "wait-on": "^9.0.1" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "node_modules/@angular-devkit/schematics": { + "version": "19.2.19", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.19.tgz", + "integrity": "sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@angular-devkit/core": "19.2.19", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" }, "engines": { - "node": ">=6.0.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli": { + "version": "19.2.19", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.19.tgz", + "integrity": "sha512-7q9UY6HK6sccL9F3cqGRUwKhM7b/XfD2YcVaZ2WD7VMaRlRm85v6mRjSrfKIAwxcQU0UK27kMc79NIIqaHjzxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.19", + "@angular-devkit/schematics": "19.2.19", + "@inquirer/prompts": "7.3.2", + "ansi-colors": "4.1.3", + "symbol-observable": "4.0.0", + "yargs-parser": "21.1.1" + }, + "bin": { + "schematics": "bin/schematics.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/core": { + "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core": { "version": "19.2.19", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", @@ -151,7 +179,37 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/ajv": { + "node_modules/@angular-devkit/schematics-cli/node_modules/@inquirer/prompts": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", + "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.1.2", + "@inquirer/confirm": "^5.1.6", + "@inquirer/editor": "^4.2.7", + "@inquirer/expand": "^4.0.9", + "@inquirer/input": "^4.1.6", + "@inquirer/number": "^3.0.9", + "@inquirer/password": "^4.0.9", + "@inquirer/rawlist": "^4.0.9", + "@inquirer/search": "^3.0.9", + "@inquirer/select": "^4.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", @@ -168,7 +226,41 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/core/node_modules/rxjs": { + "node_modules/@angular-devkit/schematics-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", @@ -178,76 +270,83 @@ "tslib": "^2.1.0" } }, - "node_modules/@angular-devkit/schematics": { + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.19.tgz", - "integrity": "sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", + "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", + "ajv": "8.17.1", + "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" }, "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "node_modules/@angular-devkit/schematics-cli": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.19.tgz", - "integrity": "sha512-7q9UY6HK6sccL9F3cqGRUwKhM7b/XfD2YcVaZ2WD7VMaRlRm85v6mRjSrfKIAwxcQU0UK27kMc79NIIqaHjzxA==", + "node_modules/@angular-devkit/schematics/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", - "@angular-devkit/schematics": "19.2.19", - "@inquirer/prompts": "7.3.2", - "ansi-colors": "4.1.3", - "symbol-observable": "4.0.0", - "yargs-parser": "21.1.1" - }, - "bin": { - "schematics": "bin/schematics.js" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/@inquirer/prompts": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", - "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "@inquirer/checkbox": "^4.1.2", - "@inquirer/confirm": "^5.1.6", - "@inquirer/editor": "^4.2.7", - "@inquirer/expand": "^4.0.9", - "@inquirer/input": "^4.1.6", - "@inquirer/number": "^3.0.9", - "@inquirer/password": "^4.0.9", - "@inquirer/rawlist": "^4.0.9", - "@inquirer/search": "^3.0.9", - "@inquirer/select": "^4.0.9" + "readdirp": "^4.0.1" }, "engines": { - "node": ">=18" + "node": ">= 14.16.0" }, - "peerDependencies": { - "@types/node": ">=18" + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { @@ -261,13 +360,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -276,9 +375,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -286,22 +385,22 @@ } }, "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -321,19 +420,20 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -343,13 +443,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -380,29 +480,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -432,9 +532,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "devOptional": true, "license": "MIT", "engines": { @@ -452,27 +552,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", - "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "devOptional": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.0" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -537,13 +637,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -730,33 +830,33 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -764,14 +864,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -784,6 +884,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@casl/ability": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.8.0.tgz", @@ -810,6 +920,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.1.90" @@ -820,6 +931,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -832,6 +944,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1036,52 +1149,20 @@ } }, "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz", + "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", "license": "MIT", "dependencies": { - "colorspace": "1.1.x", + "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } }, - "node_modules/@elastic/elasticsearch": { - "version": "8.19.1", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.19.1.tgz", - "integrity": "sha512-+1j9NnQVOX+lbWB8LhCM7IkUmjU05Y4+BmSLfusq0msCsQb1Va+OUKFCoOXjCJqQrcgdRdQCjYYyolQ/npQALQ==", - "license": "Apache-2.0", - "dependencies": { - "@elastic/transport": "^8.9.6", - "apache-arrow": "18.x - 21.x", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@elastic/transport": { - "version": "8.9.6", - "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.9.6.tgz", - "integrity": "sha512-v71jgmZtgPg2ouXF5KTPxU1a6z7YYc8nazAS7jLySteC/vrShs1OJh6oEEeo5oDc19MYUofV/JV1h5vqJVBXOw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "1.x", - "debug": "^4.4.0", - "hpagent": "^1.2.0", - "ms": "^2.1.3", - "secure-json-parse": "^3.0.1", - "tslib": "^2.8.1", - "undici": "^6.21.1" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@emnapi/core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", - "integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", "dev": true, "license": "MIT", "optional": true, @@ -1091,9 +1172,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", - "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", "dev": true, "license": "MIT", "optional": true, @@ -1136,6 +1217,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1279,6 +1361,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -1294,9 +1377,9 @@ "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "dev": true, "license": "MIT", "engines": { @@ -1331,9 +1414,9 @@ } }, "node_modules/@faker-js/faker": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.3.0.tgz", - "integrity": "sha512-It0Sne6P3szg7JIi6CgKbvTZoMjxBZhcv91ZrqrNuaZQfB5WoqYYbzCUOq89YR+VY8juY9M1vDWmDDa2TzfXCw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.4.0.tgz", + "integrity": "sha512-sDBWI3yLy8EcDzgobvJTWq1MJYzAkQdpjXuPukga9wXonhpMRvd1Izuo2Qgwey2OiEoRIBr35RMU9HJRoOHzpw==", "dev": true, "funding": [ { @@ -1406,41 +1489,31 @@ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" + "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1450,10 +1523,11 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -1817,6 +1891,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "devOptional": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1829,11 +1904,25 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1845,13 +1934,15 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "devOptional": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1864,11 +1955,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -1933,9 +2041,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -2003,6 +2111,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2072,22 +2181,6 @@ } } }, - "node_modules/@jest/core/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/diff-sequences": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", @@ -2274,6 +2367,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@jest/reporters/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/@jest/reporters/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -2290,6 +2390,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@jest/reporters/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@jest/schemas": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", @@ -2412,9 +2529,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2422,11 +2539,23 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -2443,15 +2572,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "devOptional": true + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "devOptional": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2463,6 +2593,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", + "license": "MIT", "engines": { "node": ">= 10.16.0" }, @@ -2474,6 +2605,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", + "license": "MIT", "engines": { "node": ">= 10.16.0" }, @@ -2485,6 +2617,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "license": "MIT", "engines": { "node": ">=8" } @@ -2496,9 +2629,9 @@ "license": "MIT" }, "node_modules/@mongodb-js/saslprep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.1.tgz", - "integrity": "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" @@ -2759,6 +2892,51 @@ } } }, + "node_modules/@nestjs/cli/node_modules/@angular-devkit/core": { + "version": "19.2.19", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", + "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@nestjs/cli/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -2770,9 +2948,9 @@ } }, "node_modules/@nestjs/cli/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { @@ -2782,6 +2960,46 @@ "node": "18 || 20 || >=22" } }, + "node_modules/@nestjs/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nestjs/cli/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/@nestjs/cli/node_modules/glob": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", @@ -2800,20 +3018,33 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@nestjs/cli/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "node_modules/@nestjs/cli/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "engines": { - "node": "20 || >=22" + "node": ">= 0.6" + } + }, + "node_modules/@nestjs/cli/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, "node_modules/@nestjs/cli/node_modules/minimatch": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", - "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -2826,44 +3057,141 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@nestjs/cli/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "node_modules/@nestjs/cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, + "license": "MIT", "engines": { - "node": "20 || >=22" + "node": ">= 14.18.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@nestjs/common": { - "version": "11.0.13", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.0.13.tgz", - "integrity": "sha512-cXqXJPQTcJIYqT8GtBYqjYY9sklCBqp/rh9z1R40E60gWnsU598YIQWkojSFRI9G7lT/+uF+jqSrg/CMPBk7QQ==", + "node_modules/@nestjs/cli/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "iterare": "1.2.1", - "tslib": "2.8.1", - "uid": "2.0.2" + "tslib": "^2.1.0" + } + }, + "node_modules/@nestjs/cli/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/nest" + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@nestjs/cli/node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" }, "peerDependencies": { - "class-transformer": "*", - "class-validator": "*", - "reflect-metadata": "^0.1.12 || ^0.2.0", - "rxjs": "^7.1.0" + "ajv": "^8.0.0" }, "peerDependenciesMeta": { - "class-transformer": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/webpack": { + "version": "5.104.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", + "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.4", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/@nestjs/common": { + "version": "11.1.17", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.17.tgz", + "integrity": "sha512-hLODw5Abp8OQgA+mUO4tHou4krKgDtUcM9j5Ihxncst9XeyxYBTt2bwZm4e4EQr5E352S4Fyy6V3iFx9ggxKAg==", + "license": "MIT", + "dependencies": { + "file-type": "21.3.2", + "iterare": "1.2.1", + "load-esm": "1.0.3", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "class-transformer": ">=0.4.1", + "class-validator": ">=0.13.2", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "class-transformer": { "optional": true }, "class-validator": { @@ -2899,15 +3227,16 @@ } }, "node_modules/@nestjs/core": { - "version": "11.0.13", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.0.13.tgz", - "integrity": "sha512-1xjrsYjff4sg4MfvF+/NInOq+7oI1D1vK8Yj9wkrbBH1dM+h2At71tccbFfl/eJUt4ckZlH+XmROnt/T0daYcA==", + "version": "11.1.17", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.17.tgz", + "integrity": "sha512-lD5mAYekTTurF3vDaa8C2OKPnjiz4tsfxIc5XlcSUzOhkwWf6Ay3HKvt6FmvuWQam6uIIHX52Clg+e6tAvf/cg==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "@nuxt/opencollective": "0.4.1", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", - "path-to-regexp": "8.2.0", + "path-to-regexp": "8.3.0", "tslib": "2.8.1", "uid": "2.0.2" }, @@ -2938,21 +3267,11 @@ } } }, - "node_modules/@nestjs/elasticsearch": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@nestjs/elasticsearch/-/elasticsearch-11.1.0.tgz", - "integrity": "sha512-NwMakVs8LeXUksaSNp0ejhv223yVCK4w9iqMBrsonKj2gl4sBIBrAgJq/aXhD9bJCNLYb+waoRAsxuuPxYcjXw==", - "license": "MIT", - "peerDependencies": { - "@elastic/elasticsearch": "^7.4.0 || ^8.0.0 || ^9.0.0", - "@nestjs/common": "^10.0.0 || ^11.0.0", - "rxjs": "^7.2.0" - } - }, "node_modules/@nestjs/event-emitter": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@nestjs/event-emitter/-/event-emitter-3.0.1.tgz", "integrity": "sha512-0Ln/x+7xkU6AJFOcQI9tIhUMXVF7D5itiaQGOyJbXtlAfAIt8gzDdJm+Im7cFzKoWkiW5nCXCPh6GSvdQd/3Dw==", + "license": "MIT", "dependencies": { "eventemitter2": "6.4.9" }, @@ -2990,6 +3309,7 @@ "version": "11.0.5", "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz", "integrity": "sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==", + "license": "MIT", "peerDependencies": { "@nestjs/common": "^10.0.0 || ^11.0.0", "passport": "^0.5.0 || ^0.6.0 || ^0.7.0" @@ -3016,16 +3336,6 @@ "@nestjs/core": "^11.0.0" } }, - "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/@nestjs/schematics": { "version": "11.0.9", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.9.tgz", @@ -3107,6 +3417,40 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@nestjs/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nestjs/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nestjs/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -3170,16 +3514,6 @@ } } }, - "node_modules/@nestjs/swagger/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/@nestjs/terminus": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-11.1.1.tgz", @@ -3294,6 +3628,7 @@ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "dev": true, + "license": "MIT", "engines": { "node": "^14.21.3 || >=16" }, @@ -3305,6 +3640,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "license": "MIT", "dependencies": { "consola": "^3.2.3" }, @@ -3316,20 +3652,30 @@ "npm": ">=5.10.0" } }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "node_modules/@opensearch-project/opensearch": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-3.5.1.tgz", + "integrity": "sha512-6bf+HcuERzAtHZxrm6phjref54ABse39BpkDie/YO3AUFMCBrb3SK5okKSdT5n3+nDRuEEQLhQCl0RQV3s1qpA==", "license": "Apache-2.0", + "dependencies": { + "aws4": "^1.11.0", + "debug": "^4.3.1", + "hpagent": "^1.2.0", + "json11": "^2.0.0", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0" + }, "engines": { - "node": ">=8.0.0" + "node": ">=14", + "yarn": "^1.22.10" } }, "node_modules/@paralleldrive/cuid2": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", - "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", + "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", "dev": true, + "license": "MIT", "dependencies": { "@noble/hashes": "^1.1.5" } @@ -3361,7 +3707,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", - "hasInstallScript": true + "hasInstallScript": true, + "license": "Apache-2.0" }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", @@ -3378,9 +3725,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.34.38", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.38.tgz", - "integrity": "sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true, "license": "MIT" }, @@ -3389,6 +3736,7 @@ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } @@ -3424,6 +3772,16 @@ "node": ">=4" } }, + "node_modules/@so-ric/colorspace": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz", + "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", + "license": "MIT", + "dependencies": { + "color": "^5.0.2", + "text-hex": "1.0.x" + } + }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", @@ -3453,9 +3811,9 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -3465,37 +3823,56 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", "dependencies": { - "tslib": "^2.8.0" + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", @@ -3509,9 +3886,10 @@ } }, "node_modules/@types/amqplib": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.10.7.tgz", - "integrity": "sha512-IVj3avf9AQd2nXCx0PGk/OYq7VmHiyNxWFSb5HhU9ATh+i+gHWvVcljFTcTWQ/dyHJCTrzCixde+r/asL2ErDA==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.10.8.tgz", + "integrity": "sha512-vtDp8Pk1wsE/AuQ8/Rgtm6KUZYqcnTgNvEHwzCkX8rL7AGsC6zqAfKAAJhUZXFhM/Pp++tbnUHiam/8vVpPztA==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3572,10 +3950,11 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -3592,21 +3971,12 @@ "assertion-error": "^2.0.1" } }, - "node_modules/@types/command-line-args": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", - "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==" - }, - "node_modules/@types/command-line-usage": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz", - "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==" - }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3615,18 +3985,21 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/ejs": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz", "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==", + "license": "MIT", "optional": true }, "node_modules/@types/eslint": { @@ -3634,6 +4007,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -3644,6 +4018,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -3676,10 +4051,11 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", - "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", + "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3708,13 +4084,15 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -3724,6 +4102,7 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -3743,7 +4122,8 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json-merge-patch": { "version": "1.0.0", @@ -3755,13 +4135,15 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/jsonpath-plus": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/@types/jsonpath-plus/-/jsonpath-plus-5.0.5.tgz", "integrity": "sha512-aaqqDf5LcGOtAfEntO5qKZS6ixT0MpNhUXNwbVPdLf7ET9hKsufJq+buZr7eXSnWoLRyGzVj2Yz2hbjVSK3wsA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/jsonschema": { "version": "1.1.1", @@ -3769,6 +4151,7 @@ "integrity": "sha512-JPP6H7/h/uXzAow+NbD/jqA3tA1Fj3u2C0KiFAlQ+rtl2QhozxMEz0aPjKnr4YyAB8/6s0Xm9UPa0fFUB0y1OA==", "deprecated": "This is a stub types definition for jsonschema (https://github.com/tdegrunt/jsonschema). jsonschema provides its own type definitions, so you don't need @types/jsonschema installed!", "dev": true, + "license": "MIT", "dependencies": { "jsonschema": "*" } @@ -3787,6 +4170,7 @@ "version": "2.2.5", "resolved": "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-2.2.5.tgz", "integrity": "sha512-Lv/nD6QDCmcT+V1vaTRnEKE8UgOilVv5pHcQuzkU1LcRe4mbHHuUo/KHi0LKrpdHhQY8FJzryF38fcVdeUIrzg==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3809,34 +4193,32 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mjml": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/@types/mjml/-/mjml-4.7.4.tgz", "integrity": "sha512-vyi1vzWgMzFMwZY7GSZYX0GU0dmtC8vLHwpgk+NWmwbwRSrlieVyJ9sn5elodwUfklJM7yGl0zQeet1brKTWaQ==", + "license": "MIT", "optional": true, "dependencies": { "@types/mjml-core": "*" } }, "node_modules/@types/mjml-core": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/@types/mjml-core/-/mjml-core-4.15.1.tgz", - "integrity": "sha512-qu8dUksU8yXX18qMTFINkM4uoz7WQYC5F14lcWeSNmWbulaGG0KG19yeZwpx75b9RJXr8WI/FRHH0LyQTU9JbA==", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/@types/mjml-core/-/mjml-core-4.15.2.tgz", + "integrity": "sha512-Q7SxFXgoX979HP57DEVsRI50TV8x1V4lfCA4Up9AvfINDM5oD/X9ARgfoyX1qS987JCnDLv85JjkqAjt3hZSiQ==", + "license": "MIT", "optional": true }, "node_modules/@types/mocha": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/ms": { "version": "2.1.0", @@ -3879,6 +4261,7 @@ "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.17.tgz", "integrity": "sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*" } @@ -3888,6 +4271,7 @@ "resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-4.0.1.tgz", "integrity": "sha512-Y0Ykz6nWP4jpxgEUYq8NoVZeCQPo1ZndJLfapI249g1jHChvRfZRO/LS3tqu26YgAS/laI1qx98sYGz0IalRXQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/jsonwebtoken": "*", "@types/passport-strategy": "*" @@ -3898,6 +4282,7 @@ "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.38.tgz", "integrity": "sha512-nsrW4A963lYE7lNTv9cr5WmiUD1ibYJvWrpE13oxApFsRt77b0RdtZvKbCdNIY4v/QZ6TRQWaDDEwV1kCTmcXg==", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*", "@types/passport": "*", @@ -3909,6 +4294,7 @@ "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz", "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*", "@types/passport": "*" @@ -3918,19 +4304,22 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "license": "MIT", "optional": true }, "node_modules/@types/qs": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", - "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", - "dev": true + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==", + "dev": true, + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/relateurl": { "version": "0.2.33", @@ -3940,12 +4329,12 @@ "optional": true }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/mime": "^1", "@types/node": "*" } }, @@ -3972,6 +4361,7 @@ "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/cookiejar": "^2.1.5", "@types/methods": "^1.1.4", @@ -4016,21 +4406,24 @@ "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", "dependencies": { "@types/webidl-conversions": "*" } }, "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -4039,20 +4432,21 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -4065,7 +4459,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.1", + "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -4081,16 +4475,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", - "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -4106,14 +4500,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -4128,14 +4522,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4146,9 +4540,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, "license": "MIT", "engines": { @@ -4163,15 +4557,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -4188,9 +4582,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true, "license": "MIT", "engines": { @@ -4202,16 +4596,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -4269,16 +4663,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4293,13 +4687,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -4326,32 +4720,36 @@ "node_modules/@ucast/core": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz", - "integrity": "sha512-ons5CwXZ/51wrUPfoduC+cO7AS1/wRb0ybpQJ9RrssossDxVy4t49QxWoWgfBDvVKsz9VXzBk9z0wqTdZ+Cq8g==" + "integrity": "sha512-ons5CwXZ/51wrUPfoduC+cO7AS1/wRb0ybpQJ9RrssossDxVy4t49QxWoWgfBDvVKsz9VXzBk9z0wqTdZ+Cq8g==", + "license": "Apache-2.0" }, "node_modules/@ucast/js": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@ucast/js/-/js-3.0.4.tgz", - "integrity": "sha512-TgG1aIaCMdcaEyckOZKQozn1hazE0w90SVdlpIJ/er8xVumE11gYAtSbw/LBeUnA4fFnFWTcw3t6reqseeH/4Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@ucast/js/-/js-3.1.0.tgz", + "integrity": "sha512-eJ7yQeYtMK85UZjxoxBEbTWx6UMxEXKbjVyp+NlzrT5oMKV5Gpo/9bjTl3r7msaXTVC8iD9NJacqJ8yp7joX+Q==", + "license": "Apache-2.0", "dependencies": { - "@ucast/core": "^1.0.0" + "@ucast/core": "1.10.2" } }, "node_modules/@ucast/mongo": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/@ucast/mongo/-/mongo-2.4.3.tgz", "integrity": "sha512-XcI8LclrHWP83H+7H2anGCEeDq0n+12FU2mXCTz6/Tva9/9ddK/iacvvhCyW6cijAAOILmt0tWplRyRhVyZLsA==", + "license": "Apache-2.0", "dependencies": { "@ucast/core": "^1.4.1" } }, "node_modules/@ucast/mongo2js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@ucast/mongo2js/-/mongo2js-1.4.0.tgz", - "integrity": "sha512-vR9RJ3BHlkI3RfKJIZFdVktxWvBCQRiSTeJSWN9NPxP5YJkpfXvcBWAMLwvyJx4HbB+qib5/AlSDEmQiuQyx2w==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@ucast/mongo2js/-/mongo2js-1.4.1.tgz", + "integrity": "sha512-9aeg5cmqwRQnKCXHN6I17wk83Rcm487bHelaG8T4vfpWneAI469wSI3Srnbu+PuZ5znWRbnwtVq9RgPL+bN6CA==", + "license": "Apache-2.0", "dependencies": { - "@ucast/core": "^1.6.1", - "@ucast/js": "^3.0.0", - "@ucast/mongo": "^2.4.0" + "@ucast/core": "1.10.2", + "@ucast/js": "3.1.0", + "@ucast/mongo": "2.4.3" } }, "node_modules/@ungap/structured-clone": { @@ -4665,6 +5063,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" @@ -4674,25 +5073,29 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", @@ -4703,13 +5106,15 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -4722,6 +5127,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -4731,6 +5137,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } @@ -4739,13 +5146,15 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -4762,6 +5171,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", @@ -4775,6 +5185,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -4787,6 +5198,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", @@ -4801,6 +5213,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" @@ -4810,13 +5223,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@zone-eu/mailsplit": { "version": "5.4.8", @@ -4840,12 +5255,14 @@ "node_modules/abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", - "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" @@ -4885,15 +5302,17 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, @@ -4922,6 +5341,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -4939,6 +5359,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -4950,6 +5371,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/alce/-/alce-1.2.0.tgz", "integrity": "sha512-XppPf2S42nO2WhvKzlwzlfcApcXHzjlod30pKmcWjRgLOtqoe5DMuqdiYoM6AgyXksc6A6pV4v1L/WW217e57w==", + "license": "MIT", "optional": true, "dependencies": { "esprima": "^1.2.0", @@ -4998,6 +5420,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", "dependencies": { "string-width": "^4.1.0" } @@ -5007,6 +5430,7 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5027,10 +5451,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -5039,6 +5477,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5064,6 +5503,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "devOptional": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -5073,10 +5513,11 @@ } }, "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -5084,38 +5525,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/apache-arrow": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-18.1.0.tgz", - "integrity": "sha512-v/ShMp57iBnBp4lDgV8Jx3d3Q5/Hac25FWmQ98eMahUiHPXcvwIMKJD0hBIgclm/FCG+LwPkAKtkRO1O/W0YGg==", - "dependencies": { - "@swc/helpers": "^0.5.11", - "@types/command-line-args": "^5.2.3", - "@types/command-line-usage": "^5.0.4", - "@types/node": "^20.13.0", - "command-line-args": "^5.2.1", - "command-line-usage": "^7.0.1", - "flatbuffers": "^24.3.25", - "json-bignum": "^0.0.3", - "tslib": "^2.6.2" - }, - "bin": { - "arrow2csv": "bin/arrow2csv.js" - } - }, - "node_modules/apache-arrow/node_modules/@types/node": { - "version": "20.17.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz", - "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/apache-arrow/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" - }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -5126,20 +5535,14 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "engines": { - "node": ">=6" - } + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/array-timsort": { "version": "1.0.3", @@ -5152,12 +5555,14 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" } @@ -5185,6 +5590,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -5202,17 +5608,25 @@ "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", @@ -5336,6 +5750,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "license": "MIT", "dependencies": { "precond": "0.2" }, @@ -5347,7 +5762,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -5367,16 +5783,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", - "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "version": "2.10.10", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.10.tgz", + "integrity": "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==", "devOptional": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/bcrypt": { @@ -5396,7 +5816,8 @@ "node_modules/bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -5416,6 +5837,7 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -5429,9 +5851,9 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", - "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", @@ -5440,7 +5862,7 @@ "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", + "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, @@ -5463,6 +5885,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "license": "MIT", "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", @@ -5480,32 +5903,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/boxen/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/boxen/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5534,6 +5936,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "devOptional": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -5545,7 +5948,8 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/browserslist": { "version": "4.28.1", @@ -5566,6 +5970,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -5585,6 +5990,7 @@ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -5597,6 +6003,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -5629,6 +6036,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -5643,12 +6051,14 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/buffer-more-ints": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", - "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", + "license": "MIT" }, "node_modules/busboy": { "version": "1.6.0", @@ -5674,6 +6084,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -5686,6 +6097,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -5702,6 +6114,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5710,6 +6123,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -5731,9 +6145,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001760", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", - "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", "devOptional": true, "funding": [ { @@ -5784,6 +6198,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5795,20 +6210,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk-template": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", - "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", - "dependencies": { - "chalk": "^4.1.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/chalk-template?sponsor=1" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -5823,6 +6224,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "license": "MIT", "optional": true, "dependencies": { "is-regex": "^1.0.3" @@ -5840,6 +6242,7 @@ "resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz", "integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -5848,6 +6251,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.4.0.tgz", "integrity": "sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==", + "license": "MIT", "engines": { "node": ">=16" } @@ -5896,39 +6300,42 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cheerio/node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "license": "MIT", "optional": true, "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "dependencies": { - "readdirp": "^4.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/chrome-trace-event": { @@ -5936,21 +6343,23 @@ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/sibiraj-s" } ], - "optional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5965,7 +6374,8 @@ "node_modules/class-transformer": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", - "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==", + "license": "MIT" }, "node_modules/class-validator": { "version": "0.15.1", @@ -5982,6 +6392,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -5994,6 +6405,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -6006,6 +6418,7 @@ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -6017,6 +6430,7 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -6042,6 +6456,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "devOptional": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -6051,23 +6466,12 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6085,6 +6489,7 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -6094,6 +6499,7 @@ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz", "integrity": "sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==", "dev": true, + "license": "MIT", "dependencies": { "is-regexp": "^3.0.0" }, @@ -6123,19 +6529,23 @@ "license": "MIT" }, "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz", + "integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "color-convert": "^3.1.3", + "color-string": "^2.1.3" + }, + "engines": { + "node": ">=18" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -6146,32 +6556,50 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz", + "integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==", "license": "MIT", "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/color-string/node_modules/color-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", + "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", + "license": "MIT", + "engines": { + "node": ">=12.20" } }, "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", + "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=14.6" } }, "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", + "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } }, "node_modules/colord": { "version": "2.9.3", @@ -6180,20 +6608,11 @@ "license": "MIT", "optional": true }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "license": "MIT", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -6201,65 +6620,22 @@ "node": ">= 0.8" } }, - "node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": ">= 6" } }, - "node_modules/command-line-usage": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", - "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", - "dependencies": { - "array-back": "^6.2.2", - "chalk-template": "^0.4.0", - "table-layout": "^4.1.0", - "typical": "^7.1.1" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/command-line-usage/node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "engines": { - "node": ">=12.17" - } - }, - "node_modules/command-line-usage/node_modules/typical": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", - "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", - "engines": { - "node": ">=12.17" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/comment-json": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz", - "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==", - "dev": true, - "license": "MIT", + "node_modules/comment-json": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz", + "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==", + "dev": true, + "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", @@ -6270,9 +6646,10 @@ } }, "node_modules/complex.js": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz", - "integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz", + "integrity": "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==", + "license": "MIT", "engines": { "node": "*" }, @@ -6286,6 +6663,7 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -6294,7 +6672,8 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-stream": { "version": "2.0.0", @@ -6341,6 +6720,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6372,6 +6752,7 @@ "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" } @@ -6380,6 +6761,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "license": "MIT", "optional": true, "dependencies": { "@babel/parser": "^7.6.0", @@ -6387,20 +6769,23 @@ } }, "node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "dependencies": { - "safe-buffer": "5.2.1" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6410,6 +6795,7 @@ "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6421,12 +6807,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6435,6 +6823,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", "engines": { "node": ">=6.6.0" } @@ -6443,7 +6832,8 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", @@ -6474,6 +6864,7 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, + "license": "MIT", "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -6499,13 +6890,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "devOptional": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6723,6 +7116,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -6749,6 +7143,7 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6757,9 +7152,10 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" }, "node_modules/dedent": { "version": "1.7.2", @@ -6780,6 +7176,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", "optional": true, "engines": { "node": ">=4.0.0" @@ -6789,13 +7186,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6805,6 +7204,7 @@ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -6816,6 +7216,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -6824,6 +7225,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6832,6 +7234,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "license": "MIT", "optional": true, "engines": { "node": ">=8" @@ -6842,6 +7245,7 @@ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6858,6 +7262,7 @@ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", "dev": true, + "license": "ISC", "dependencies": { "asap": "^2.0.0", "wrappy": "1" @@ -6887,6 +7292,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/display-notification/-/display-notification-2.0.0.tgz", "integrity": "sha512-TdmtlAcdqy1NU+j7zlkDdMnCL878zriLaBmoD9quOoq1ySSSGv03l0hXK5CvIFZlIfFI/hizqdQuW+Num7xuhw==", + "license": "MIT", "optional": true, "dependencies": { "escape-string-applescript": "^1.0.0", @@ -6907,6 +7313,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", "optional": true, "dependencies": { "domelementtype": "^2.3.0", @@ -6927,12 +7334,14 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "BSD-2-Clause", "optional": true }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", "optional": true, "dependencies": { "domelementtype": "^2.3.0" @@ -6948,6 +7357,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", "optional": true, "dependencies": { "dom-serializer": "^2.0.0", @@ -7017,6 +7427,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -7030,7 +7441,8 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", @@ -7044,7 +7456,8 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/ejs": { "version": "5.0.1", @@ -7060,9 +7473,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.322", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.322.tgz", + "integrity": "sha512-vFU34OcrvMcH66T+dYC3G4nURmgfDVewMIu6Q2urXpumAPSMmzvcn04KVVV8Opikq8Vs5nUbO/8laNhNRqSzYw==", "devOptional": true, "license": "ISC" }, @@ -7082,7 +7495,8 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/enabled": { "version": "2.0.0", @@ -7094,6 +7508,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7136,13 +7551,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -7152,6 +7568,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "optional": true, "engines": { "node": ">=0.12" @@ -7171,10 +7588,11 @@ } }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "devOptional": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -7183,6 +7601,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7191,6 +7610,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7206,6 +7626,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -7217,6 +7638,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -7232,6 +7654,7 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7252,17 +7675,20 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/escape-latex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", - "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "license": "MIT" }, "node_modules/escape-string-applescript": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", "integrity": "sha512-4/hFwoYaC6TkpDn9A3pTC52zQPArFeXuIfhUtCGYdauTzXVP9H3BDr3oO/QzQehMpLDC7srvYgfwvImPFGfvBA==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -7273,6 +7699,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -7532,6 +7959,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -7558,6 +7986,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -7570,6 +7999,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -7579,6 +8009,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -7587,6 +8018,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7594,13 +8026,15 @@ "node_modules/eventemitter2": { "version": "6.4.9", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -7733,12 +8167,14 @@ "node_modules/express-session/node_modules/cookie-signature": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" }, "node_modules/express-session/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -7746,12 +8182,14 @@ "node_modules/express-session/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/extend-object": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/extend-object/-/extend-object-1.0.0.tgz", "integrity": "sha512-0dHDIXC7y7LDmCh/lp1oYkmv73K25AMugQI07r8eFopkW6f7Ufn1q+ETMsJjnV9Am14SlElkqy3O92r6xEaxPw==", + "license": "MIT", "optional": true }, "node_modules/extsprintf": { @@ -7760,12 +8198,14 @@ "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", "engines": [ "node >=0.6.0" - ] + ], + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/fast-diff": { "version": "1.3.0", @@ -7778,23 +8218,26 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -7804,13 +8247,15 @@ "type": "opencollective", "url": "https://opencollective.com/fastify" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } @@ -7853,6 +8298,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -7866,6 +8312,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" }, @@ -7873,6 +8320,24 @@ "node": ">=16.0.0" } }, + "node_modules/file-type": { + "version": "21.3.2", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.2.tgz", + "integrity": "sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", @@ -7906,6 +8371,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7914,9 +8380,10 @@ } }, "node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", @@ -7926,18 +8393,11 @@ "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dependencies": { - "array-back": "^3.0.1" + "node": ">= 18.0.0" }, - "engines": { - "node": ">=4.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/find-up": { @@ -7945,6 +8405,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -7960,6 +8421,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fixpack/-/fixpack-4.0.0.tgz", "integrity": "sha512-5SM1+H2CcuJ3gGEwTiVo/+nd/hYpNj9Ch3iMDOQ58ndY+VGQ2QdvaUTkd3otjZvYnd/8LF/HkJ5cx7PBq0orCQ==", + "license": "MIT", "optional": true, "dependencies": { "alce": "1.2.0", @@ -7977,6 +8439,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", "optional": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7991,6 +8454,7 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } @@ -8000,6 +8464,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -8008,11 +8473,6 @@ "node": ">=16" } }, - "node_modules/flatbuffers": { - "version": "24.12.23", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.12.23.tgz", - "integrity": "sha512-dLVCAISd5mhls514keQzmEG6QHmUUsNuWsb4tFafIUwvvgDjXhtfAYSKOzt5SWOy+qByV5pbsDZ+Vb7HUOBEdA==" - }, "node_modules/flatted": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", @@ -8051,6 +8511,7 @@ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "devOptional": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" @@ -8067,6 +8528,7 @@ "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.1.0.tgz", "integrity": "sha512-mpafl89VFPJmhnJ1ssH+8wmM2b50n+Rew5x42NeI2U78aRWgtkEtGmctp7iT16UjquJTjorEmIfESj3DxdW84Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.7", "chalk": "^4.1.2", @@ -8089,6 +8551,36 @@ "webpack": "^5.11.0" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", @@ -8109,6 +8601,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8117,6 +8610,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -8128,6 +8622,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" }, @@ -8140,6 +8635,7 @@ "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", "dev": true, + "license": "MIT", "dependencies": { "@paralleldrive/cuid2": "^2.2.2", "dezalgo": "^1.0.4", @@ -8156,16 +8652,18 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fraction.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.2.2.tgz", - "integrity": "sha512-uXBDv5knpYmv/2gLzWQ5mBHGBRk9wcKTeWu6GLTUEQfjCxO09uM/mHDrojlL+Q1mVGIIFo149Gba7od1XPgSzQ==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "license": "MIT", "engines": { - "node": ">= 12" + "node": "*" }, "funding": { "type": "github", @@ -8176,6 +8674,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8185,6 +8684,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -8195,10 +8695,11 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", + "dev": true, + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -8212,6 +8713,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -8224,6 +8726,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8233,6 +8736,7 @@ "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-0.1.1.tgz", "integrity": "sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -8244,6 +8748,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/gelf-pro/-/gelf-pro-1.4.0.tgz", "integrity": "sha512-VXQ1DHQjQr8/Xil83hHgozqeCcVrggGAA6A8hgjojQSatiF6PErR+nnYv/DCBxFBolO6licomD7Abaj0Iec7Qg==", + "license": "MIT", "dependencies": { "lodash": "~4.17.21" } @@ -8253,6 +8758,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -8262,6 +8768,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "devOptional": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -8270,6 +8777,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -8303,6 +8811,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=8" @@ -8315,6 +8824,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -8358,6 +8868,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -8393,15 +8904,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/glob/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/glob/node_modules/minimatch": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", @@ -8417,22 +8919,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob/node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globals": { "version": "17.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", @@ -8450,6 +8936,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8461,12 +8948,14 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "license": "MIT", "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -8487,6 +8976,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -8495,6 +8985,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -8503,6 +8994,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8514,6 +9006,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -8528,6 +9021,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -8540,6 +9034,7 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "devOptional": true, + "license": "MIT", "bin": { "he": "bin/he" } @@ -8577,16 +9072,36 @@ "node": ">=14" } }, - "node_modules/htmlnano": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-3.2.0.tgz", - "integrity": "sha512-ZUCyB3w9EdpkaePGuYTBF7hT1MWdcz7y0/h2Cnl1MKLwbyj7aIM+Eq7SRg+ILF1mvR7zJKu06lw9zpgCxOFymw==", + "node_modules/html-to-text/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], "license": "MIT", "optional": true, "dependencies": { - "@types/relateurl": "^0.2.33", - "commander": "^14.0.0", - "cosmiconfig": "^9.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/htmlnano": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-3.2.0.tgz", + "integrity": "sha512-ZUCyB3w9EdpkaePGuYTBF7hT1MWdcz7y0/h2Cnl1MKLwbyj7aIM+Eq7SRg+ILF1mvR7zJKu06lw9zpgCxOFymw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/relateurl": "^0.2.33", + "commander": "^14.0.0", + "cosmiconfig": "^9.0.0", "posthtml": "^0.16.5" }, "bin": { @@ -8667,9 +9182,9 @@ } }, "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -8677,12 +9192,13 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "optional": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/http-errors": { @@ -8735,7 +9251,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -8749,13 +9264,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -8765,6 +9282,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "devOptional": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -8801,6 +9319,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -8820,12 +9339,14 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC", "optional": true }, "node_modules/ip-regex": { @@ -8833,6 +9354,7 @@ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8844,6 +9366,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -8852,7 +9375,8 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -8871,6 +9395,7 @@ "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", "optional": true, "dependencies": { "hasown": "^2.0.2" @@ -8886,6 +9411,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", "optional": true, "bin": { "is-docker": "cli.js" @@ -8901,6 +9427,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "license": "MIT", "optional": true, "dependencies": { "acorn": "^7.1.1", @@ -8911,6 +9438,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", "optional": true, "bin": { "acorn": "bin/acorn" @@ -8924,6 +9452,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8932,6 +9461,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -8951,6 +9481,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "devOptional": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -8963,6 +9494,7 @@ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8972,6 +9504,7 @@ "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz", "integrity": "sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==", "dev": true, + "license": "MIT", "dependencies": { "ip-regex": "^5.0.0", "super-regex": "^0.2.0" @@ -8995,6 +9528,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -9014,6 +9548,7 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9022,12 +9557,14 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT", "optional": true }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", "optional": true, "dependencies": { "call-bound": "^1.0.2", @@ -9047,6 +9584,7 @@ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -9058,6 +9596,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -9070,6 +9609,7 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -9081,6 +9621,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", "optional": true, "dependencies": { "is-docker": "^2.0.0" @@ -9093,13 +9634,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -9169,6 +9712,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "license": "ISC", "engines": { "node": ">=6" } @@ -9192,7 +9736,8 @@ "node_modules/javascript-natural-sort": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", - "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "license": "MIT" }, "node_modules/jest": { "version": "30.3.0", @@ -9362,22 +9907,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/jest-config/node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-config/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -9400,6 +9929,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jest-config/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/jest-config/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -9416,20 +9952,85 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jest-config/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest-diff": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", - "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.3.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.3.0" + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { @@ -9494,86 +10095,6 @@ "mkdirp": "^3.0.1" } }, - "node_modules/jest-file-snapshot/node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-file-snapshot/node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-file-snapshot/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-file-snapshot/node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-file-snapshot/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-file-snapshot/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -9610,9 +10131,9 @@ } }, "node_modules/jest-haste-map/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -9652,6 +10173,22 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/jest-diff": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.3.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, "node_modules/jest-message-util": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", @@ -9674,9 +10211,9 @@ } }, "node_modules/jest-message-util/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -9863,6 +10400,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jest-runtime/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/jest-runtime/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -9879,6 +10423,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jest-runtime/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest-snapshot": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", @@ -9912,6 +10473,22 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.3.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, "node_modules/jest-util": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", @@ -9930,26 +10507,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-util/node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -10031,9 +10592,9 @@ } }, "node_modules/joi": { - "version": "18.0.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.0.2.tgz", - "integrity": "sha512-RuCOQMIt78LWnktPoeBL0GErkNaJPTBGcYuyaBvUOQSpcpcLfWrHPPihYdOGbV5pam9VTWbeoF7TsGiHugcjGA==", + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-18.1.1.tgz", + "integrity": "sha512-pJkBiPtNo+o0h19LfSvUN46Y5zY+ck99AtHwch9n2HqVLNRgP0ZMyIH8FRMoP+HV8hy/+AG99dXFfwpf83iZfQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10043,7 +10604,7 @@ "@hapi/pinpoint": "^2.0.1", "@hapi/tlds": "^1.1.1", "@hapi/topo": "^6.0.2", - "@standard-schema/spec": "^1.0.0" + "@standard-schema/spec": "^1.1.0" }, "engines": { "node": ">= 20" @@ -10053,6 +10614,7 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -10068,7 +10630,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.1", @@ -10086,6 +10649,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", + "license": "MIT", "engines": { "node": ">= 10.16.0" } @@ -10103,19 +10667,12 @@ "node": ">=6" } }, - "node_modules/json-bignum": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", - "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-merge-patch": { "version": "1.0.2", @@ -10130,24 +10687,37 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/json11": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/json11/-/json11-2.0.2.tgz", + "integrity": "sha512-HIrd50UPYmP6sqLuLbFVm75g16o0oZrVfxrsY0EEys22klz8mRoWlX9KAEDOSOR9Q34rcxsyC8oDveGrCz5uLQ==", + "license": "MIT", + "bin": { + "json11": "dist/cli.mjs" + } }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -10159,13 +10729,15 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -10195,6 +10767,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", + "license": "MIT", "engines": { "node": "*" } @@ -10225,6 +10798,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "license": "MIT", "optional": true, "dependencies": { "is-promise": "^2.0.0", @@ -10310,6 +10884,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -10336,6 +10911,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.3.3.tgz", "integrity": "sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg==", + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" }, @@ -10347,6 +10923,7 @@ "version": "5.0.5", "resolved": "https://registry.npmjs.org/ldapauth-fork/-/ldapauth-fork-5.0.5.tgz", "integrity": "sha512-LWUk76+V4AOZbny/3HIPQtGPWZyA3SW2tRhsWIBi9imP22WJktKLHV1ofd8Jo/wY7Ve6vAT7FCI5mEn3blZTjw==", + "license": "MIT", "dependencies": { "@types/ldapjs": "^2.2.2", "bcryptjs": "^2.4.0", @@ -10361,6 +10938,7 @@ "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -10370,6 +10948,7 @@ "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.3.3.tgz", "integrity": "sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg==", "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", "dependencies": { "abstract-logging": "^2.0.0", "asn1": "^0.2.4", @@ -10409,6 +10988,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -10451,9 +11031,10 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.12.6", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.6.tgz", - "integrity": "sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==" + "version": "1.12.40", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.40.tgz", + "integrity": "sha512-HKGs7GowShNls3Zh+7DTr6wYpPk5jC78l508yQQY3e8ZgJChM3A9JZghmMJZuK+5bogSfuTafpjksGSR3aMIEg==", + "license": "MIT" }, "node_modules/libqp": { "version": "2.1.1", @@ -10479,7 +11060,8 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/linkify-it": { "version": "5.0.0", @@ -10492,9 +11074,9 @@ } }, "node_modules/liquidjs": { - "version": "10.25.0", - "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.0.tgz", - "integrity": "sha512-XpO7AiGULTG4xcTlwkcTI5JreFG7b6esLCLp+aUSh7YuQErJZEoUXre9u9rbdb0057pfWG4l0VursvLd5Q/eAw==", + "version": "10.25.1", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.1.tgz", + "integrity": "sha512-D+jsJvkGigFn8qNUgh8U6XNHhGFBp+p8Dk26ea/Hl+XrjFVSg9OXlN31hGAfS3MYQ3Kr8Xi9sEVBVQa/VTVSmg==", "license": "MIT", "optional": true, "dependencies": { @@ -10516,11 +11098,31 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, + "node_modules/load-esm": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz", + "integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "engines": { + "node": ">=13.2.0" + } + }, "node_modules/loader-runner": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", @@ -10540,6 +11142,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -10556,51 +11159,54 @@ "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", @@ -10614,6 +11220,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -10675,14 +11282,15 @@ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/mailparser": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.9.3.tgz", - "integrity": "sha512-AnB0a3zROum6fLaa52L+/K2SoRJVyFDk78Ea6q1D0ofcZLxWEWDtsS1+OrVqKbV7r5dulKL/AwYQccFGAPpuYQ==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.9.5.tgz", + "integrity": "sha512-i5mXdEqDrh7I095uiQiebOrc00AOIJRLlpze1nBb82oZpI4GaCJIn9ypXR2bqb/Ayr7q+nmT6k11yYU5Age/Gg==", "license": "MIT", "optional": true, "dependencies": { @@ -10693,7 +11301,7 @@ "iconv-lite": "0.7.2", "libmime": "5.3.7", "linkify-it": "5.0.0", - "nodemailer": "7.0.13", + "nodemailer": "8.0.3", "punycode.js": "2.3.1", "tlds": "1.261.0" } @@ -10718,13 +11326,15 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -10733,6 +11343,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -10771,6 +11382,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -10780,6 +11392,7 @@ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -10804,6 +11417,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -10815,13 +11429,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -10831,6 +11447,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -10840,10 +11457,11 @@ } }, "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -10871,9 +11489,9 @@ } }, "node_modules/migrate-mongo/node_modules/commander": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", - "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "license": "MIT", "engines": { "node": ">=20" @@ -10884,6 +11502,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "devOptional": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -10895,19 +11514,25 @@ "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/mimic-fn": { @@ -10915,6 +11540,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10942,6 +11568,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11052,31 +11679,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/mjml-cli/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "optional": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/mjml-cli/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -11099,18 +11701,12 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mjml-cli/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/mjml-cli/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC", - "optional": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } + "optional": true }, "node_modules/mjml-cli/node_modules/minimatch": { "version": "9.0.9", @@ -11128,30 +11724,21 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mjml-cli/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mjml-cli/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", + "node_modules/mjml-cli/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", "optional": true, "dependencies": { - "picomatch": "^2.2.1" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mjml-column": { @@ -11356,26 +11943,6 @@ "lodash": "^4.17.21" } }, - "node_modules/mjml-parser-xml/node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, "node_modules/mjml-preset-core": { "version": "5.0.0-beta.2", "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-5.0.0-beta.2.tgz", @@ -11506,6 +12073,22 @@ "mjml-section": "5.0.0-beta.2" } }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mocha": { "version": "11.7.5", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", @@ -11543,27 +12126,30 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/mocha/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==", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "node_modules/mocha/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" + "readdirp": "^4.0.1" }, "engines": { - "node": "18 || 20 || >=22" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/mocha/node_modules/glob": { @@ -11588,14 +12174,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/mocha/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -11604,11 +12197,43 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -11669,15 +12294,16 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz", "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==", + "license": "Apache-2.0", "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^14.1.0 || ^13.0.0" } }, "node_modules/mongoose": { - "version": "8.20.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.20.3.tgz", - "integrity": "sha512-AQk63Ry4YM/lWJRt/D5P7UiRjKT+z+vD0NkNKgeQ35TioBC7kuI6wBzhu6/kyrNXg+WotFidW1icEWLNC1rUfg==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.23.0.tgz", + "integrity": "sha512-Bul4Ha6J8IqzFrb0B1xpVzkC3S0sk43dmLSnhFOn8eJlZiLwL5WO6cRymmjaADdCMjUcCpj2ce8hZI6O4ZFSug==", "license": "MIT", "dependencies": { "bson": "^6.10.4", @@ -11700,6 +12326,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -11719,7 +12346,8 @@ "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/multer": { "version": "2.1.1", @@ -11832,12 +12460,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -11845,24 +12475,27 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "license": "MIT", "optional": true }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-addon-api": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", - "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.6.0.tgz", + "integrity": "sha512-gBVjCaqDlRUk0EwoPNKzIr9KkS9041G/q31IBShPs1Xz6UTA+EXdZADbzqAJQrpDRq71CIMnOP5VMut3SL0z5Q==", "license": "MIT", "engines": { "node": "^18 || ^20 || >= 21" @@ -11872,6 +12505,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", "funding": [ { "type": "github", @@ -11882,6 +12516,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } @@ -11891,6 +12526,7 @@ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.21" } @@ -11899,6 +12535,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -11927,19 +12564,20 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "devOptional": true, "license": "MIT" }, "node_modules/nodemailer": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", - "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.3.tgz", + "integrity": "sha512-JQNBqvK+bj3NMhUFR3wmCl3SYcOeMotDiwDBvIoCuQdF0PvlIY0BH+FJ2CG7u4cXKPChplE78oowlH/Otsc4ZQ==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -11950,6 +12588,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11967,23 +12606,60 @@ "node": ">=8" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", "optional": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "engines": { + "node": ">= 6" } }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11992,6 +12668,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -12000,6 +12677,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12008,9 +12686,10 @@ } }, "node_modules/oidc-token-hash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.1.0.tgz", - "integrity": "sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.2.0.tgz", + "integrity": "sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw==", + "license": "MIT", "engines": { "node": "^10.13.0 || >=12.0.0" } @@ -12019,6 +12698,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -12039,6 +12719,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -12057,6 +12738,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -12071,6 +12753,7 @@ "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "license": "MIT", "optional": true, "dependencies": { "is-docker": "^2.0.0", @@ -12087,6 +12770,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz", "integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==", + "license": "MIT", "dependencies": { "jose": "^4.15.9", "lru-cache": "^6.0.0", @@ -12101,6 +12785,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -12111,13 +12796,15 @@ "node_modules/openid-client/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -12135,6 +12822,7 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -12153,22 +12841,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-event": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "license": "MIT", "optional": true, "dependencies": { "p-timeout": "^3.1.0" @@ -12184,6 +12861,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", "optional": true, "engines": { "node": ">=4" @@ -12194,6 +12872,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -12209,6 +12888,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -12223,6 +12903,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", "optional": true, "dependencies": { "p-finally": "^1.0.0" @@ -12245,6 +12926,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz", "integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==", + "license": "MIT", "optional": true, "dependencies": { "p-timeout": "^3.0.0" @@ -12259,13 +12941,15 @@ "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "devOptional": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -12278,6 +12962,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -12362,6 +13047,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12370,6 +13056,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", + "license": "MIT", "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", @@ -12387,6 +13074,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.1.tgz", "integrity": "sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==", + "license": "MIT", "dependencies": { "jsonwebtoken": "^9.0.0", "passport-strategy": "^1.0.0" @@ -12396,6 +13084,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/passport-ldapauth/-/passport-ldapauth-3.0.1.tgz", "integrity": "sha512-TRRx3BHi8GC8MfCT9wmghjde/EGeKjll7zqHRRfGRxXbLcaDce2OftbQrFG7/AWaeFhR6zpZHtBQ/IkINdLVjQ==", + "license": "MIT", "dependencies": { "ldapauth-fork": "^5.0.1", "passport-strategy": "^1.0.0" @@ -12428,6 +13117,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12447,6 +13137,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12455,36 +13146,42 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT", "optional": true }, "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "devOptional": true, + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "devOptional": true + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "engines": { - "node": ">=16" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/path-type": { @@ -12492,6 +13189,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12515,13 +13213,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -12534,6 +13234,7 @@ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -12612,6 +13313,7 @@ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -13246,6 +13948,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -13330,6 +14033,32 @@ "node": ">=14" } }, + "node_modules/preview-email/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/preview-email/node_modules/nodemailer": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", + "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", + "license": "MIT-0", + "optional": true, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/preview-email/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -13338,6 +14067,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "optional": true, "bin": { "uuid": "dist/bin/uuid" @@ -13347,6 +14077,7 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", "optional": true, "dependencies": { "asap": "~2.0.3" @@ -13356,6 +14087,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -13367,7 +14099,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/pug": { "version": "3.0.4", @@ -13419,12 +14152,14 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "license": "MIT", "optional": true }, "node_modules/pug-filters": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "license": "MIT", "optional": true, "dependencies": { "constantinople": "^4.0.1", @@ -13438,6 +14173,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "license": "MIT", "optional": true, "dependencies": { "character-parser": "^2.2.0", @@ -13449,6 +14185,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "license": "MIT", "optional": true, "dependencies": { "pug-error": "^2.0.0", @@ -13459,6 +14196,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "license": "MIT", "optional": true, "dependencies": { "object-assign": "^4.1.1", @@ -13469,6 +14207,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "license": "MIT", "optional": true, "dependencies": { "pug-error": "^2.0.0", @@ -13486,6 +14225,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "license": "MIT", "optional": true, "dependencies": { "pug-error": "^2.0.0" @@ -13495,12 +14235,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "license": "MIT", "optional": true }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { "node": ">=6" } @@ -13533,9 +14275,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -13550,12 +14292,14 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" }, "node_modules/random-bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -13565,6 +14309,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -13573,6 +14318,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -13596,6 +14342,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { "deep-extend": "^0.6.0", @@ -13611,6 +14358,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -13638,28 +14386,43 @@ } }, "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">= 14.18.0" + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.6" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/reflect-metadata": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13668,6 +14431,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13675,15 +14439,17 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", "optional": true, "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -13725,6 +14491,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -13734,6 +14501,7 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -13746,7 +14514,8 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/rimraf": { "version": "6.1.3", @@ -13771,6 +14540,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", @@ -13785,12 +14555,14 @@ "node_modules/router/node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" }, "node_modules/run-applescript": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz", "integrity": "sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==", + "license": "MIT", "optional": true, "dependencies": { "execa": "^0.10.0" @@ -13803,6 +14575,7 @@ "version": "6.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "license": "MIT", "optional": true, "dependencies": { "nice-try": "^1.0.4", @@ -13819,6 +14592,7 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "license": "MIT", "optional": true, "dependencies": { "cross-spawn": "^6.0.0", @@ -13837,6 +14611,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=4" @@ -13846,6 +14621,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -13855,6 +14631,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "license": "MIT", "optional": true, "dependencies": { "path-key": "^2.0.0" @@ -13867,6 +14644,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "license": "MIT", "optional": true, "engines": { "node": ">=4" @@ -13876,6 +14654,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver" @@ -13885,6 +14664,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "license": "MIT", "optional": true, "dependencies": { "shebang-regex": "^1.0.0" @@ -13897,6 +14677,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -13906,12 +14687,14 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC", "optional": true }, "node_modules/run-applescript/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", "optional": true, "dependencies": { "isexe": "^2.0.0" @@ -13924,6 +14707,7 @@ "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } @@ -13945,7 +14729,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-stable-stringify": { "version": "2.5.0", @@ -13959,7 +14744,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sax": { "version": "1.6.0", @@ -13976,6 +14762,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13990,10 +14777,11 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14010,6 +14798,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -14018,28 +14807,20 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/secure-json-parse": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-3.0.2.tgz", - "integrity": "sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", "license": "BSD-3-Clause" }, "node_modules/seedrandom": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "license": "MIT" }, "node_modules/selderee": { "version": "0.11.0", @@ -14055,9 +14836,9 @@ } }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -14067,24 +14848,29 @@ } }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/serialize-javascript": { @@ -14092,14 +14878,16 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", @@ -14108,18 +14896,24 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "devOptional": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -14132,6 +14926,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14153,6 +14948,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -14171,6 +14967,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -14186,6 +14983,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -14203,6 +15001,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -14220,35 +15019,22 @@ "node_modules/sift": { "version": "17.1.3", "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", - "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "devOptional": true, + "license": "ISC", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT" - }, "node_modules/sinon": { "version": "21.0.3", "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.3.tgz", @@ -14268,9 +15054,9 @@ } }, "node_modules/sinon/node_modules/diff": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", - "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -14282,6 +15068,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14301,6 +15088,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } @@ -14402,18 +15190,14 @@ } }, "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -14428,23 +15212,11 @@ "node": ">=10" } }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -14460,6 +15232,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "devOptional": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -14469,22 +15242,11 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -14492,27 +15254,13 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "devOptional": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -14520,18 +15268,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "devOptional": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -14546,6 +15282,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -14566,6 +15303,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -14596,6 +15334,22 @@ "node": ">=0.8.0" } }, + "node_modules/strtok3": { + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/stylehacks": { "version": "7.0.8", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.8.tgz", @@ -14618,6 +15372,7 @@ "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", "integrity": "sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==", "dev": true, + "license": "MIT", "dependencies": { "clone-regexp": "^3.0.0", "function-timeout": "^0.1.0", @@ -14670,6 +15425,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -14681,6 +15437,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "optional": true, "engines": { "node": ">= 0.4" @@ -14738,6 +15495,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz", "integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==", + "license": "MIT", "dependencies": { "swagger-ui-dist": ">=5.0.0" }, @@ -14774,30 +15532,10 @@ "url": "https://opencollective.com/synckit" } }, - "node_modules/table-layout": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", - "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", - "dependencies": { - "array-back": "^6.2.2", - "wordwrapjs": "^5.1.0" - }, - "engines": { - "node": ">=12.17" - } - }, - "node_modules/table-layout/node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "engines": { - "node": ">=12.17" - } - }, "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", "dev": true, "license": "MIT", "engines": { @@ -14809,9 +15547,9 @@ } }, "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", + "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", "devOptional": true, "license": "BSD-2-Clause", "dependencies": { @@ -14828,16 +15566,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", + "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "engines": { @@ -14978,7 +15715,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -15007,6 +15744,7 @@ "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", "dev": true, + "license": "MIT", "dependencies": { "convert-hrtime": "^5.0.0" }, @@ -15020,7 +15758,8 @@ "node_modules/tiny-emitter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "license": "MIT" }, "node_modules/tinyglobby": { "version": "0.2.15", @@ -15040,9 +15779,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -15066,13 +15805,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "devOptional": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -15084,6 +15825,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } @@ -15092,12 +15834,32 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "license": "MIT", "optional": true }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/tr46": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz", - "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", "dependencies": { "punycode": "^2.3.1" }, @@ -15110,6 +15872,7 @@ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, + "license": "MIT", "bin": { "tree-kill": "cli.js" } @@ -15147,9 +15910,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -15251,6 +16014,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -15290,10 +16054,11 @@ } }, "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -15303,6 +16068,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -15317,6 +16083,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", @@ -15332,6 +16099,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15339,13 +16107,15 @@ "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -15358,15 +16128,15 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -15379,6 +16149,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", @@ -15389,9 +16160,10 @@ } }, "node_modules/typed-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", - "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.2.tgz", + "integrity": "sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==", + "license": "MIT", "engines": { "node": ">= 18" } @@ -15416,14 +16188,6 @@ "node": ">=14.17" } }, - "node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "engines": { - "node": ">=8" - } - }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -15435,6 +16199,7 @@ "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -15447,6 +16212,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "license": "MIT", "dependencies": { "@lukeed/csprng": "^1.0.0" }, @@ -15458,6 +16224,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "license": "MIT", "dependencies": { "random-bytes": "~1.0.0" }, @@ -15465,11 +16232,24 @@ "node": ">= 0.8" } }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/undici": { - "version": "6.24.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.0.tgz", - "integrity": "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", + "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==", "license": "MIT", + "optional": true, "engines": { "node": ">=18.17" } @@ -15485,6 +16265,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -15534,9 +16315,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", - "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "devOptional": true, "funding": [ { @@ -15569,6 +16350,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -15577,6 +16359,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -15585,12 +16368,14 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -15603,6 +16388,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/esm/bin/uuid" } @@ -15611,7 +16397,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.3.0", @@ -15639,9 +16426,9 @@ } }, "node_modules/validator": { - "version": "13.15.23", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", - "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", + "version": "13.15.26", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz", + "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -15651,6 +16438,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -15662,6 +16450,7 @@ "engines": [ "node >=0.6.0" ], + "license": "MIT", "dependencies": { "verror": "1.10.0" } @@ -15669,7 +16458,8 @@ "node_modules/vasync/node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" }, "node_modules/vasync/node_modules/verror": { "version": "1.10.0", @@ -15678,6 +16468,7 @@ "engines": [ "node >=0.6.0" ], + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -15688,6 +16479,7 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -15700,7 +16492,8 @@ "node_modules/verror/node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" }, "node_modules/void-elements": { "version": "3.1.0", @@ -15737,14 +16530,15 @@ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, "license": "MIT", "dependencies": { @@ -15760,6 +16554,7 @@ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } @@ -15781,30 +16576,11 @@ "node": ">=10.0.0" } }, - "node_modules/web-resource-inliner/node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -15813,16 +16589,18 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" } }, "node_modules/webpack": { - "version": "5.104.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", - "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", + "version": "5.105.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.4.tgz", + "integrity": "sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -15830,11 +16608,11 @@ "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", + "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.4", + "enhanced-resolve": "^5.20.0", "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -15846,9 +16624,9 @@ "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", - "watchpack": "^2.4.4", - "webpack-sources": "^3.3.3" + "terser-webpack-plugin": "^5.3.17", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.4" }, "bin": { "webpack": "bin/webpack.js" @@ -15871,14 +16649,15 @@ "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", + "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", "dev": true, "license": "MIT", "engines": { @@ -15891,6 +16670,7 @@ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -15908,6 +16688,8 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -15921,6 +16703,8 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=4.0" } @@ -15930,6 +16714,8 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -15939,6 +16725,8 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -15952,6 +16740,7 @@ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -16007,6 +16796,7 @@ "version": "14.2.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" @@ -16020,6 +16810,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "devOptional": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -16034,6 +16825,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "license": "MIT", "dependencies": { "string-width": "^4.0.0" }, @@ -16042,13 +16834,13 @@ } }, "node_modules/winston": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", - "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", + "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", + "@dabh/diagnostics": "^2.0.8", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", @@ -16107,6 +16899,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -16114,20 +16907,13 @@ "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" - }, - "node_modules/wordwrapjs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", - "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", - "engines": { - "node": ">=12.17" - } + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" }, "node_modules/workerpool": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.2.tgz", - "integrity": "sha512-Xz4Nm9c+LiBHhDR5bDLnNzmj6+5F+cyEAWPMkbs2awq/dYazR/efelZzUAjB/y3kNHL+uzkHvxVVpaOfGCPV7A==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "dev": true, "license": "Apache-2.0" }, @@ -16152,6 +16938,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -16164,35 +16951,11 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "5.0.1", @@ -16213,6 +16976,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -16229,6 +16993,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "devOptional": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -16247,6 +17012,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -16256,6 +17022,7 @@ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -16271,6 +17038,7 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -16280,6 +17048,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 2152819ec..68246c718 100644 --- a/package.json +++ b/package.json @@ -30,18 +30,16 @@ "test:api": "npm run test:api:jest --maxWorkers=50% && concurrently -k -s first \"wait-on http://localhost:3000/explorer/ && npm run test:api:mocha\" \"npm run start:test\"", "test:api:jest": "dotenv -o -e test/config/.env -e test/config/.env.override -- jest --config ./test/config/jest-e2e.json --maxWorkers=50%", "test:api:mocha": "dotenv -o -e test/config/.env -e test/config/.env.override -- mocha --config ./test/config/.mocharc.js -r chai/register-should.js", - "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp test/config/functionalAccounts.json functionalAccounts.json && cp proposalTypes.example.json proposalTypes.json && cp publishedDataConfig.example.json publishedDataConfig.json" + "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml up -d && cp test/config/functionalAccounts.json functionalAccounts.json && cp proposalTypes.example.json proposalTypes.json && cp publishedDataConfig.example.json publishedDataConfig.json" }, "dependencies": { "@casl/ability": "^6.3.2", "@casl/mongoose": "^8.0.4", - "@elastic/elasticsearch": "^8.15.0", "@nestjs-modules/mailer": "^2", "@nestjs/axios": "^4", "@nestjs/common": "^11", "@nestjs/config": "^4", "@nestjs/core": "^11", - "@nestjs/elasticsearch": "^11", "@nestjs/event-emitter": "^3", "@nestjs/jwt": "^11", "@nestjs/mongoose": "^11.0.4", @@ -50,6 +48,7 @@ "@nestjs/swagger": "^11.1.1", "@nestjs/terminus": "^11", "@nestjs/throttler": "^6.5.0", + "@opensearch-project/opensearch": "^3.5.1", "@types/json-merge-patch": "^1.0.0", "@types/jsonschema": "^1.1.1", "@user-office-software/duo-logger": "^2.1.1", @@ -90,7 +89,8 @@ }, "socks": { "ip": "^2.0.2" - } + }, + "mongodb": "6.20.0" }, "devDependencies": { "@eslint/eslintrc": "^3.1.0", diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 3da7cf5ca..b95cfd510 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -15,7 +15,6 @@ import { JobConfig } from "src/config/job-config/jobconfig.interface"; import { JobConfigService } from "src/config/job-config/jobconfig.service"; import { Datablock } from "src/datablocks/schemas/datablock.schema"; import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { ElasticSearchActions } from "src/elastic-search/dto"; import { Instrument } from "src/instruments/schemas/instrument.schema"; import { JobClass } from "src/jobs/schemas/job.schema"; import { CreateJobAuth, UpdateJobAuth } from "src/jobs/types/jobs-auth.enum"; @@ -32,6 +31,7 @@ import { Action } from "./action.enum"; import { RuntimeConfig } from "src/config/runtime-config/schemas/runtime-config.schema"; import { accessibleBy } from "@casl/mongoose"; import { MetadataKeyClass } from "src/metadata-keys/schemas/metadatakey.schema"; +import { Opensearch } from "src/opensearch/opensearch.subject"; type Subjects = | string @@ -50,7 +50,7 @@ type Subjects = | typeof User | typeof UserIdentity | typeof UserSettings - | typeof ElasticSearchActions + | typeof Opensearch | typeof Datablock | typeof RuntimeConfig | typeof MetadataKeyClass @@ -76,7 +76,7 @@ export class CaslAbilityFactory { [endpoint: string]: (user: JWTUser) => AppAbility; } = { datasets: this.datasetEndpointAccess, - "elastic-search": this.elasticSearchEndpointAccess, + opensearch: this.opensearchEndpointAccess, jobs: this.jobsEndpointAccess, instruments: this.instrumentEndpointAccess, logbooks: this.logbookEndpointAccess, @@ -328,7 +328,7 @@ export class CaslAbilityFactory { }); } - elasticSearchEndpointAccess(user: JWTUser) { + opensearchEndpointAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -340,7 +340,7 @@ export class CaslAbilityFactory { /* / user that belongs to any of the group listed in ADMIN_GROUPS */ - can(Action.Manage, ElasticSearchActions); + can(Action.Manage, Opensearch); } return build({ detectSubjectType: (item) => diff --git a/src/common/types.ts b/src/common/types.ts index f2c4ea9d0..a716b66d6 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -1,6 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; import { ValidationError } from "class-validator"; -import { IFullFacets } from "src/elastic-search/interfaces/es-common.type"; export class FullFacetFilters { @ApiPropertyOptional() @@ -23,7 +22,7 @@ class TotalSets { totalSets: number; } -export class FullFacetResponse implements IFullFacets { +export class FullFacetResponse { @ApiProperty({ type: TotalSets, isArray: true }) all: [TotalSets]; diff --git a/src/common/utils.ts b/src/common/utils.ts index fc1e48234..9d118df66 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -700,6 +700,17 @@ export const createFullqueryFilter = ( }; const pipelineHandler = { + handleOpensearchIdList: ( + pipeline: PipelineStage[], + fields: Y, + key: string, + ) => { + const match = { + $match: { _id: { $in: fields[key as keyof Y] as string[] } }, + }; + return pipeline.unshift(match); + }, + handleTextSearch: ( pipeline: PipelineStage[], model: Model, @@ -836,11 +847,14 @@ export const createFullfacetPipeline = ( } switch (key) { + case "openSearchIdList": + pipelineHandler.handleOpensearchIdList(pipeline, fields, key); + break; case "text": - pipelineHandler.handleTextSearch(pipeline, model, fields, key); + pipelineHandler.handleTextSearch(pipeline, model, fields, key); break; case idField: - pipelineHandler.handleIdFieldSearch( + pipelineHandler.handleIdFieldSearch( pipeline, model, fields, @@ -849,17 +863,22 @@ export const createFullfacetPipeline = ( ); break; case "mode": - pipelineHandler.handleModeSearch(pipeline, fields, key, idField); + pipelineHandler.handleModeSearch(pipeline, fields, key, idField); break; case "userGroups": - pipelineHandler.handleUserGroupSearch(pipeline, model, fields, key); + pipelineHandler.handleUserGroupSearch( + pipeline, + model, + fields, + key, + ); break; case "scientific": case "sampleCharacteristics": - pipelineHandler.handleScientificQuery(pipeline, fields, key); + pipelineHandler.handleScientificQuery(pipeline, fields, key); break; default: - pipelineHandler.handleGenericSearch(pipeline, model, fields, key); + pipelineHandler.handleGenericSearch(pipeline, model, fields, key); } }); diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 1ef060662..3bb154bab 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -72,6 +72,7 @@ const configuration = () => { const jsonConfigMap: { [key: string]: object | object[] | boolean } = { datasetTypes: {}, proposalTypes: {}, + opensearchConfig: {}, }; const jsonConfigFileList: { [key: string]: string } = { frontendConfig: @@ -84,6 +85,8 @@ const configuration = () => { metricsConfig: process.env.METRICS_CONFIG_FILE || "metricsConfig.json", publishedDataConfig: process.env.PUBLISHED_DATA_CONFIG_FILE || "publishedDataConfig.json", + opensearchConfig: + process.env.OPENSEARCH_CONFIG_FILE || "opensearchConfig.json", }; Object.keys(jsonConfigFileList).forEach((key) => { const filePath = jsonConfigFileList[key]; @@ -98,7 +101,11 @@ const configuration = () => { jsonConfigMap[key] = false; } } else { - if (key === "publishedDataConfig") { + const configsWithExampleFallback = [ + "publishedDataConfig", + "opensearchConfig", + ]; + if (configsWithExampleFallback.includes(key)) { console.warn( `Configuration file ${filePath} does not exist. Trying to use the example ${key}.example.json file`, ); @@ -378,16 +385,17 @@ const configuration = () => { username: process.env.RABBITMQ_USERNAME, password: process.env.RABBITMQ_PASSWORD, }, - elasticSearch: { - enabled: process.env.ELASTICSEARCH_ENABLED ?? "no", - username: process.env.ES_USERNAME, - password: process.env.ES_PASSWORD, - host: process.env.ES_HOST, - refresh: process.env.ES_REFRESH, - maxResultWindow: parseInt(process.env.ES_MAX_RESULT || "100000", 10), - fieldsLimit: parseInt(process.env.ES_FIELDS_LIMIT || "100000", 10), - mongoDBCollection: process.env.MONGODB_COLLECTION, - defaultIndex: process.env.ES_INDEX ?? "dataset", + opensearch: { + enabled: process.env.OPENSEARCH_ENABLED ?? "no", + username: process.env.OPENSEARCH_USERNAME ?? "admin", + password: process.env.OPENSEARCH_PASSWORD, + host: process.env.OPENSEARCH_HOST, + refresh: process.env.OPENSEARCH_REFRESH, + defaultIndex: process.env.OPENSEARCH_DEFAULT_INDEX ?? "dataset", + dataSyncBatchSize: parseInt( + process.env.OPENSEARCH_DATA_SYNC_BATCH_SIZE || "1000", + 10, + ), }, metrics: { // Note: `process.env.METRICS_ENABLED` is directly used for conditional module loading in @@ -426,6 +434,7 @@ const configuration = () => { frontendConfig: jsonConfigMap.frontendConfig, frontendTheme: jsonConfigMap.frontendTheme, publishedDataConfig: jsonConfigMap.publishedDataConfig, + opensearchConfig: jsonConfigMap.opensearchConfig, }; return merge(config, localconfiguration); }; diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 0d179fafc..3254364d0 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -969,6 +969,11 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); + const parsedFilters: IFilters = { + fields: fields, + limits: JSON.parse(filters.limits ?? "{}"), + }; + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); @@ -985,12 +990,7 @@ export class DatasetsController { } } - const parsedFilters: IFilters = { - fields: fields, - limits: JSON.parse(filters.limits ?? "{}"), - }; - - const datasets = await this.datasetsService.fullquery(parsedFilters); + const datasets = await this.datasetsService.opensearchQuery(parsedFilters); let outputDatasets: OutputDatasetObsoleteDto[] = []; @@ -1065,7 +1065,7 @@ export class DatasetsController { fields: fields, facets: JSON.parse(filters.facets ?? "[]"), }; - return this.datasetsService.fullFacet(parsedFilters); + return this.datasetsService.opensearchFacet(parsedFilters); } // GET /datasets/metadataKeys diff --git a/src/datasets/datasets.module.ts b/src/datasets/datasets.module.ts index fe7d33286..0dbf18028 100644 --- a/src/datasets/datasets.module.ts +++ b/src/datasets/datasets.module.ts @@ -11,7 +11,6 @@ import { InitialDatasetsModule } from "src/initial-datasets/initial-datasets.mod import { LogbooksModule } from "src/logbooks/logbooks.module"; import { PoliciesService } from "src/policies/policies.service"; import { PoliciesModule } from "src/policies/policies.module"; -import { ElasticSearchModule } from "src/elastic-search/elastic-search.module"; import { DatasetsV4Controller } from "./datasets.v4.controller"; import { DatasetsPublicV4Controller } from "./datasets-public.v4.controller"; import { DatasetsAccessService } from "./datasets-access.service"; @@ -20,11 +19,12 @@ import { GenericHistory, GenericHistorySchema, } from "src/common/schemas/generic-history.schema"; -import { ConfigModule, ConfigService } from "@nestjs/config"; +import { ConditionalModule, ConfigModule, ConfigService } from "@nestjs/config"; import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; import { ProposalsModule } from "src/proposals/proposals.module"; import { HistoryModule } from "src/history/history.module"; import { MetadataKeysModule } from "src/metadata-keys/metadatakeys.module"; +import { OpensearchModule } from "src/opensearch/opensearch.module"; @Module({ imports: [ @@ -35,7 +35,10 @@ import { MetadataKeysModule } from "src/metadata-keys/metadatakeys.module"; InitialDatasetsModule, HistoryModule, MetadataKeysModule, - ElasticSearchModule, + ConditionalModule.registerWhen( + OpensearchModule, + (env: NodeJS.ProcessEnv) => env.OPENSEARCH_ENABLED === "yes", + ), ProposalsModule, forwardRef(() => LogbooksModule), MongooseModule.forFeatureAsync([ diff --git a/src/datasets/datasets.service.spec.ts b/src/datasets/datasets.service.spec.ts index a38c9fabc..d5cfef7ab 100644 --- a/src/datasets/datasets.service.spec.ts +++ b/src/datasets/datasets.service.spec.ts @@ -4,7 +4,6 @@ import { Test, TestingModule } from "@nestjs/testing"; import { Model } from "mongoose"; import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.service"; import { LogbooksService } from "src/logbooks/logbooks.service"; -import { ElasticSearchService } from "src/elastic-search/elastic-search.service"; import { DatasetsService } from "./datasets.service"; import { DatasetClass } from "./schemas/dataset.schema"; import { CaslAbilityFactory } from "src/casl/casl-ability.factory"; @@ -14,6 +13,7 @@ import { CreateDatasetDto } from "./dto/create-dataset.dto"; import { plainToInstance } from "class-transformer"; import { ProposalsService } from "src/proposals/proposals.service"; import { MetadataKeysService } from "src/metadata-keys/metadatakeys.service"; +import { OpensearchService } from "src/opensearch/opensearch.service"; class InitialDatasetsServiceMock {} @@ -21,8 +21,6 @@ class LogbooksServiceMock {} class CaslAbilityFactoryMock {} -class ElasticSearchServiceMock {} - class MetadataKeysServiceMock { insertManyFromSource = jest.fn().mockResolvedValue([]); replaceManyFromSource = jest.fn().mockResolvedValue(undefined); @@ -124,7 +122,7 @@ describe("DatasetsService", () => { useClass: InitialDatasetsServiceMock, }, { provide: LogbooksService, useClass: LogbooksServiceMock }, - { provide: ElasticSearchService, useClass: ElasticSearchServiceMock }, + { provide: OpensearchService, useValue: null }, { provide: MetadataKeysService, useClass: MetadataKeysServiceMock }, { provide: CaslAbilityFactory, useClass: CaslAbilityFactoryMock }, { provide: ProposalsService, useClass: ProposalsServiceMock }, diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 18d5b4196..7ca344075 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -2,7 +2,9 @@ import { BadRequestException, Inject, Injectable, + Logger, NotFoundException, + Optional, Scope, } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; @@ -34,7 +36,6 @@ import { parsePipelineSort, decodeMetadataKeyStrings, } from "src/common/utils"; -import { ElasticSearchService } from "src/elastic-search/elastic-search.service"; import { DatasetsAccessService } from "./datasets-access.service"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; import { @@ -50,6 +51,7 @@ import { IDatasetFields, IDatasetFilters, IDatasetFiltersV4, + IDatasetOpenSearchPipeline, IDatasetRelation, IDatasetScopes, } from "./interfaces/dataset-filters.interface"; @@ -63,10 +65,20 @@ import { MetadataKeysService, MetadataSourceDoc, } from "src/metadata-keys/metadatakeys.service"; +import { OpensearchService } from "src/opensearch/opensearch.service"; +import type { IndexSettings } from "@opensearch-project/opensearch/api/_types/indices._common"; +import type { TypeMapping } from "@opensearch-project/opensearch/api/_types/_common.mapping"; +import { BulkStats } from "@opensearch-project/opensearch/lib/Helpers"; +import { DatasetOpenSearchDto } from "src/opensearch/dto/dataset-opensearch.dto"; +import { plainToInstance } from "class-transformer"; +import { DATASET_OPENSEARCH_PROJECTION } from "../opensearch/utils/dataset-opensearch.utils"; @Injectable({ scope: Scope.REQUEST }) export class DatasetsService { - private ESClient: ElasticSearchService | null; + private readonly osDefaultIndex: string; + private readonly isOsEnabled: boolean; + private readonly osSyncBatchSize: number; + constructor( private configService: ConfigService, @InjectModel(DatasetClass.name) @@ -74,13 +86,16 @@ export class DatasetsService { @Inject(REQUEST) private request: Request, private datasetsAccessService: DatasetsAccessService, - private elasticSearchService: ElasticSearchService, + @Optional() private opensearchService: OpensearchService, private metadataKeysService: MetadataKeysService, private proposalService: ProposalsService, ) { - if (this.elasticSearchService.connected) { - this.ESClient = this.elasticSearchService; - } + this.osDefaultIndex = + this.configService.get("opensearch.defaultIndex") || "dataset"; + this.isOsEnabled = + this.configService.get("opensearch.enabled") === "yes" || false; + this.osSyncBatchSize = + this.configService.get("opensearch.dataSyncBatchSize") || 1000; } private createMetadataKeysInstance( @@ -186,8 +201,12 @@ export class DatasetsService { const savedDataset = await createdDataset.save(); - if (this.ESClient && createdDataset) { - await this.ESClient.updateInsertDocument(savedDataset.toObject()); + if (this.opensearchService && createdDataset) { + await this.opensearchService.updateInsertDocument( + plainToInstance(DatasetOpenSearchDto, savedDataset.toObject(), { + excludeExtraneousValues: true, + }), + ); } if (savedDataset.proposalIds && savedDataset.proposalIds.length > 0) { @@ -277,8 +296,6 @@ export class DatasetsService { filter: IFilters, extraWhereClause: FilterQuery = {}, ): Promise { - let datasets; - const filterQuery: FilterQuery = createFullqueryFilter( this.datasetModel, @@ -292,28 +309,48 @@ export class DatasetsService { }; const modifiers: QueryOptions = parseLimitFilters(filter.limits); - const isFieldsEmpty = Object.keys(whereClause).length === 0; + const datasets = await this.datasetModel + .find(whereClause, null, modifiers) + .exec(); - // NOTE: if Elastic search DB is empty we should use default mongo query - const canPerformElasticSearchQueries = await this.isElasticSearchDBEmpty(); + return datasets; + } - if (!this.ESClient || isFieldsEmpty || !canPerformElasticSearchQueries) { - datasets = await this.datasetModel - .find(whereClause, null, modifiers) - .exec(); - } else { - const esResult = await this.ESClient.search( - filter.fields as IDatasetFields, - modifiers.limit, - modifiers.skip, - modifiers.sort, + async opensearchQuery( + filter: IFilters, + ): Promise { + if ( + !this.isOsEnabled || + !filter.fields?.text || + !this.opensearchService.connected() || + !(await this.opensearchService.isPopulated()) + ) { + return this.fullquery(filter); + } + + const { text, isPublished, userGroups } = filter.fields || {}; + + const mongoQuery: FilterQuery = + createFullqueryFilter( + this.datasetModel, + "pid", + filter.fields as FilterQuery, ); - datasets = await this.datasetModel - .find({ pid: { $in: esResult.data } }) - .sort(modifiers.sort) - .exec(); - } + const modifiers: QueryOptions = parseLimitFilters(filter.limits); + + delete mongoQuery.$text; + + const osResult = await this.opensearchService.search( + { text, userGroups, isPublished }, + this.osDefaultIndex, + modifiers.limit, + modifiers.skip, + ); + const datasets = await this.datasetModel + .find({ pid: { $in: osResult.data }, ...mongoQuery }) + .sort(modifiers.sort) + .exec(); return datasets; } @@ -321,34 +358,61 @@ export class DatasetsService { async fullFacet( filters: IFacets, ): Promise[]> { - let data; - const fields = filters.fields ?? {}; const facets = filters.facets ?? []; - // NOTE: if fields contains no value, we should use mongo query to optimize performance. - // however, fields always contain "mode" key, so we need to check if there's more than one key - const isFieldsEmpty = Object.keys(fields).length === 1; - - // NOTE: if Elastic search DB is empty we should use default mongo query - const canPerformElasticSearchQueries = await this.isElasticSearchDBEmpty(); + const pipeline = createFullfacetPipeline( + this.datasetModel, + "pid", + fields, + facets, + "", + ); - if (!this.ESClient || isFieldsEmpty || !canPerformElasticSearchQueries) { - const pipeline = createFullfacetPipeline( - this.datasetModel, - "pid", - fields, - facets, - "", - ); + return await this.datasetModel.aggregate(pipeline).exec(); + } - data = await this.datasetModel.aggregate(pipeline).exec(); - } else { - const facetResult = await this.ESClient.aggregate(fields); + async opensearchFacet( + filters: IFacets, + ): Promise[]> { + const osConfig = + this.configService.get<{ + settings: IndexSettings; + mappings: TypeMapping; + }>("opensearchConfig") || null; + const osMaxResultWindow = Number( + osConfig?.settings?.index?.max_result_window, + ); - data = facetResult; + if ( + !this.isOsEnabled || + !filters.fields?.text || + !this.opensearchService.connected() || + !(await this.opensearchService.isPopulated()) + ) { + return this.fullFacet(filters); } - return data; + const fields = filters.fields ?? {}; + const facets = filters.facets ?? []; + + const osResult = await this.opensearchService.search( + { + text: fields.text, + userGroups: fields.userGroups, + isPublished: fields.isPublished, + }, + this.osDefaultIndex, + osMaxResultWindow, + ); + + fields.openSearchIdList = osResult.data; + delete fields.text; + const pipeline = createFullfacetPipeline< + DatasetDocument, + IDatasetOpenSearchPipeline + >(this.datasetModel, "pid", fields, facets, ""); + + return await this.datasetModel.aggregate(pipeline).exec(); } async updateAll( @@ -388,17 +452,7 @@ export class DatasetsService { ): Promise<{ count: number }> { const whereFilter: RootFilterQuery = filter.where ?? {}; let count = 0; - if (this.ESClient && !filter.where) { - const totalDocCount = await this.datasetModel.countDocuments(); - - const { totalCount } = await this.ESClient.search( - whereFilter as IDatasetFields, - totalDocCount, - ); - count = totalCount; - } else { - count = await this.datasetModel.countDocuments(whereFilter).exec(); - } + count = await this.datasetModel.countDocuments(whereFilter).exec(); return { count }; } @@ -438,8 +492,12 @@ export class DatasetsService { throw new NotFoundException(`Dataset #${id} not found`); } - if (this.ESClient) { - await this.ESClient.updateInsertDocument(updatedDataset.toObject()); + if (this.opensearchService) { + await this.opensearchService.updateInsertDocument( + plainToInstance(DatasetOpenSearchDto, updatedDataset.toObject(), { + excludeExtraneousValues: true, + }), + ); } await this.metadataKeysService.replaceManyFromSource( @@ -484,8 +542,12 @@ export class DatasetsService { throw new NotFoundException(`Dataset #${id} not found`); } - if (this.ESClient) { - await this.ESClient.updateInsertDocument(patchedDataset.toObject()); + if (this.opensearchService) { + await this.opensearchService.updateInsertDocument( + plainToInstance(DatasetOpenSearchDto, patchedDataset.toObject(), { + excludeExtraneousValues: true, + }), + ); } await this.metadataKeysService.replaceManyFromSource( @@ -507,8 +569,8 @@ export class DatasetsService { throw new NotFoundException(`Dataset #${id} not found`); } - if (this.ESClient) { - await this.ESClient.deleteDocument(id); + if (this.opensearchService) { + await this.opensearchService.deleteDocument(id); } if (deletedDataset?.proposalIds && deletedDataset.proposalIds.length > 0) { @@ -525,15 +587,6 @@ export class DatasetsService { return deletedDataset; } - // GET datasets without _id which is used for elastic search data synchronization - async getDatasetsWithoutId(): Promise { - try { - const datasets = this.datasetModel.find({}, { _id: 0 }).lean().exec(); - return datasets; - } catch (error) { - throw new NotFoundException(error); - } - } // Get metadata keys async metadataKeys( @@ -599,9 +652,77 @@ export class DatasetsService { } } - async isElasticSearchDBEmpty() { - if (!this.ESClient) return; - const count = await this.ESClient.getCount(); - return count.count > 0; + async syncDatasetsToOpensearch(index: string) { + try { + await this.opensearchService.checkIndexExists(index); + + const bulkOperationFinalResult: BulkStats = { + total: 0, + failed: 0, + retry: 0, + successful: 0, + noop: 0, + time: 0, + bytes: 0, + aborted: false, + }; + + const cursor = this.datasetModel + .find({}, DATASET_OPENSEARCH_PROJECTION) + .lean() + .cursor({ batchSize: this.osSyncBatchSize }); + + let batch: DatasetClass[] = []; + let isCursorExhausted = false; + + while (!isCursorExhausted) { + const doc = await cursor.next(); + + if (doc) { + batch.push(doc as DatasetClass); + } else { + isCursorExhausted = true; + } + + // Condition: Is the batch full OR are we at the very end with a non-empty tail? + const isBatchReady = batch.length >= this.osSyncBatchSize; + const isFinalBatch = isCursorExhausted && batch.length > 0; + + if (!isBatchReady && !isFinalBatch) { + continue; + } + + // Single source of truth for the bulk operation + const bulk = + await this.opensearchService.performBulkOperation( + batch, + index, + ); + + // Aggregate bulk stats + bulkOperationFinalResult.total += bulk.total; + bulkOperationFinalResult.failed += bulk.failed; + bulkOperationFinalResult.retry += bulk.retry; + bulkOperationFinalResult.successful += bulk.successful; + bulkOperationFinalResult.noop += bulk.noop; + bulkOperationFinalResult.time += bulk.time; + bulkOperationFinalResult.bytes += bulk.bytes; + bulkOperationFinalResult.aborted = bulk.aborted; + + Logger.log( + `Synced ${bulkOperationFinalResult.total} datasets to OpenSearch (Final Batch: ${isFinalBatch})`, + "OpensearchSync", + ); + + batch = []; + } + + return bulkOperationFinalResult; + } catch (error: unknown) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error"; + Logger.error(`Sync failed: ${errorMessage}`, "OpensearchSync"); + throw error; + } } } diff --git a/src/datasets/datasets.v4.controller.spec.ts b/src/datasets/datasets.v4.controller.spec.ts index 2e3f765de..c18e18d03 100644 --- a/src/datasets/datasets.v4.controller.spec.ts +++ b/src/datasets/datasets.v4.controller.spec.ts @@ -28,7 +28,8 @@ describe("DatasetsController", () => { ], }).compile(); - controller = module.get(DatasetsV4Controller); + controller = + await module.resolve(DatasetsV4Controller); }); it("should be defined", () => { diff --git a/src/datasets/interfaces/dataset-filters.interface.ts b/src/datasets/interfaces/dataset-filters.interface.ts index ebbe4ac1f..7d1954482 100644 --- a/src/datasets/interfaces/dataset-filters.interface.ts +++ b/src/datasets/interfaces/dataset-filters.interface.ts @@ -43,6 +43,10 @@ export interface IDatasetFields { [key: string]: unknown; } +export type IDatasetOpenSearchPipeline = Omit & { + openSearchIdList?: string[]; +}; + export type IDatasetScopesV4 = | IOrigDatablockFiltersV4 | IFiltersV4 diff --git a/src/elastic-search/Elasticsearch_guide.md b/src/elastic-search/Elasticsearch_guide.md deleted file mode 100644 index 1b43155cd..000000000 --- a/src/elastic-search/Elasticsearch_guide.md +++ /dev/null @@ -1,211 +0,0 @@ -# Getting started - -To be able to start application with Elasticsearch you will need to: - -1. Start with `npm prepare:local` to executes docker-compose file which pull and run Elasticsearch cluster as a docker container. -2. Start the application with `npm run start` - -# Check the .env file - -Following environment variables are required to run Elasticsearch with Scicat Backend: - -| `Variables` | Values | Description | -| ------------------------ | :--------------------- | :------------------------------------------------------------------------------------------------------------- | -| `ELASTICSEARCH_ENABLED` | `yes` or `no` | Flag to enable/disable the ElasticSearch service | -| `ES_HOST ` | https://localhost:9200 | Use `http` if `xpack.security.enabled` set to `false` | -| `ES_USERNAME` (optional) | elastic | Elasticsearch cluster username. Can be customized with docker image environment values with `ELASTIC_USERNAME` | -| `ES_PASSWORD` | password | Elasticsearch cluster password. Can be customized with docker image environment values `ELASTIC_PASSWORD` | -| `MONGODB_COLLECTION ` | Dataset | Collection name to be mapped into specified Elasticsearch index | -| `ES_MAX_RESULT ` | 210000 | Maximum records can be indexed into Elasticsearch. If not set, default is `10000` | -| `ES_FIELDS_LIMIT ` | 400000 | The total number of fields in an index. If not set, default is `1000` | -| `ES_INDEX ` | dataset | Setting default index for the application | -| `ES_REFRESH ` | wait_for | Wait for the change to become visible - CRUD actions | -| | | - -## \*\* NOTE \*\* - -`ES_REFRESH="wait_for"` is used for better testing flow. For production it should be set to false. Detailed docs about this setting can be found: [docs-refresh](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-refresh.html) - -# Steps to synchronize data with Elasitcsearch - -To enable search queries in Elasticsearch, you should adhere to the following steps: - -1. Open Swagger page `http://localhost:3000/explorer`, Authorize with `admin` token -2. Open elastic-search endpoints and execute `create-index`. - _**NOTE:**_ This step can be skipped if you want to use default index `dataset` -3. execute `sync-database` to sync data into the given index. - -If you see the following response, it means Elasticsearch is ready for use. - -``` -{ - "total": 21670, - "failed": 0, - "retry": 0, - "successful": 21670, - "noop": 0, - "time": 4777, - "bytes": 279159021, - "aborted": false -} -``` - -# Index, analysis and mapping settings - -Index settings in Elasticsearch are used to define various configurations and behaviors for an index. Index settings are vital for optimizing Elasticsearch's performance, relevance of search results, and resource management, ensuring that the index operates efficiently and effectively according to the specific needs of the application using it. - -Pre-defined index settings & dynamic mapping for nested objects can be found `/src/elastic-search/configuration/indexSetting.ts` - -Fields to be mapped into Elasticsearch index can be found `/src/elastic-search/configuration/datasetFieldMapping.ts` - -**Index settings:** - -``` -export const defaultElasticSettings = { - index: { - max_result_window: process.env.ES_MAX_RESULT || 2000000, - number_of_replicas: 0, - mapping: { - total_fields: { - limit: process.env.ES_FIELDS_LIMIT || 2000000, - }, - nested_fields: { - limit: 1000, - }, - }, - }, - analysis: { - analyzer: { - autocomplete: { - tokenizer: "autocomplete", - filter: ["lowercase"], - }, - autocomplete_search: { - tokenizer: "lowercase", - }, - }, - tokenizer: { - autocomplete: autocomplete_tokenizer, - }, - }, -} as IndicesIndexSettingsAnalysis; -``` - -| `Object` | Description | -| ----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `index` | It contains settings that determine how an Elasticsearch index works, like how many results you can get from a search and how many copies of the data it should store. More details in [index modules](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html) | -| `index.max_result_window` | Determines the maximum number of documents returned in a query. `Default is 10000` | -| `index.number_of_replicas` | Sets the number of replica shards. `Default is 1` | -| `index.mapping.total_fields.limit` | Sets the maximum number of fields an index can have. `Default is 1000` | -| `index.mapping.nested_fields.limit` | Sets the maximum number of nested fields. `Default is 50` | -| `analysis` | It defines how text data is processed before it is indexed, including custom analyzers and tokenizers which control the conversion of text into tokens or terms. More details in [analyzer](https://www.elastic.co/guide/en/elasticsearch/reference/current/analyzer.html) and [analysis](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/analysis.html) | - -
- -**Dynamic mapping:** - -Dynamic mapping is currently only used for scientific field. More details in [Dynamic template](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/dynamic-templates.html) - -``` -export const dynamic_template: Record[] = [ - { - string_as_keyword: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "string", - mapping: { - type: "keyword", - ignore_above: 256, - }, - }, - }, - { - long_as_double: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "long", - mapping: { - type: "double", - coerce: true, - ignore_malformed: true, - }, - }, - }, - { - date_as_keyword: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "date", - mapping: { - type: "keyword", - ignore_above: 256, - }, - }, - }, -]; -``` - -# APIs - -`NOTE: All requests require admin permissions.` - -For search query integration it is suggested to use client search service directly, which can be found `/src/elastic-search/elastic-search.service.ts` - -**Following table is existing controller endpoints:** - -| endpoint | parameters | request | description | -| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | ------------------------------------------------- | -| /api/v3/elastic-search/create-index?index= | `string` | query | Create an index with this name | -| /api/v3/elastic-search/sync-database?index= | `string` | query | Sync datasets into elastic search with this index | -| /api/v3/elastic-search/search | `{ "text": "", "ownerGroup": [], "creationLocation": [], "type": [], "keywords": [], "isPublished": false, "scientific": [{"lhs": "", "relation": "", "rhs": 0, "unit": ""}]}` | body | Search query | -| /api/v3/elastic-search/delete-index | `string` | query | Delete an index with this name | -| /api/v3/elastic-search/get-index | `string` | query | Get an index settings with this name | -| /api/v3/elastic-search/update-index | `to be updated` | to be updated | to be updated | - -# Setting up a local Elasticsearch cluster - -## Docker Configuration - -For local development, you can spin up an Elasticsearch cluster using Docker with the following configuration: - -_Elasticsearch image configuration can be found in `./CI/E2E/docker-compose-local.yaml`_ - -``` -es01: - image: docker.elastic.co/elasticsearch/elasticsearch:8.8.2 - ports: - - 9200:9200 - environment: - - xpack.security.enabled=false - - node.name=es01 - - ES_JAVA_OPTS=-Xms2g -Xmx2g - - cluster.name=es-cluster - - cluster.initial_master_nodes=es01 - - ELASTIC_PASSWORD=password - - bootstrap.memory_lock=true - mem_limit: 4g - ulimits: - memlock: - soft: -1 - hard: -1 -``` - -| **`Settings`** | **`Description`** | -| ---------------------------- | -------------------------------------------------------------------------------------- | -| Image Version | Docker image for Elasticsearch: `docker.elastic.co/elasticsearch/elasticsearch:8.8.2`. | -| Port | Container-to-host port mapping: `9200:9200`. | -| mem_limit | Maximum container memory, influenced by `ES_JAVA_OPTS`. | -| ulimits.memlock (soft, hard) | Memory locking limits: `-1` for unlimited. | -| **`Variables`** | **`Description`** | -| xpack.security.enabled | Toggle for Elasticsearch security; `false` disables authentication for development. | -| node.name | Unique Elasticsearch node name; essential for cluster node identification. | -| ES_JAVA_OPTS | JVM heap memory settings for Elasticsearch performance (e.g., `-Xms2g -Xmx2g`). | -| cluster.name | Name of the Elasticsearch cluster for node grouping. | -| ELASTIC_PASSWORD | Password for the 'elastic' user; not needed if security is disabled. | -| bootstrap.memory_lock | Prevents swapping Elasticsearch memory to disk when enabled. | - -## Using Helm for Kubernetes - -For those looking to deploy on Kubernetes, refer to the official [Helm chart documentation](https://github.com/elastic/helm-charts/tree/main/elasticsearch) for Elasticsearch. Helm charts provide a more production-ready setup and can manage complex configurations. - -**More configuration information:** - -- [More complicated examples with docker-compose configuration](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/docker.html) -- [More service configures for production](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/important-settings.html) diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts deleted file mode 100644 index bed10c389..000000000 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { MappingObject } from "../interfaces/mappingInterface.type"; - -export const datasetMappings: MappingObject = { - description: { - type: "text", - analyzer: "autocomplete", - search_analyzer: "autocomplete_search", - fields: { - keyword: { - type: "keyword", - ignore_above: 256, - }, - }, - }, - datasetName: { - type: "text", - analyzer: "autocomplete", - search_analyzer: "autocomplete_search", - fields: { - keyword: { - type: "keyword", - ignore_above: 256, - }, - }, - }, - pid: { - type: "keyword", - ignore_above: 256, - }, - creationTime: { - type: "date", - }, - endTime: { - type: "date", - }, - scientificMetadata: { - type: "nested", - dynamic: true, - properties: {}, - }, - history: { - type: "nested", - dynamic: false, - }, - proposalIds: { - type: "keyword", - ignore_above: 256, - }, - sampleIds: { - type: "keyword", - ignore_above: 256, - }, - instrumentIds: { - type: "keyword", - ignore_above: 256, - }, - sourceFolder: { - type: "keyword", - ignore_above: 256, - }, - isPublished: { - type: "boolean", - }, - type: { - type: "keyword", - ignore_above: 256, - }, - keywords: { - type: "keyword", - ignore_above: 256, - }, - creationLocation: { - type: "keyword", - ignore_above: 256, - }, - ownerGroup: { - type: "keyword", - ignore_above: 256, - }, - accessGroups: { - type: "keyword", - ignore_above: 256, - }, - sharedWith: { - type: "keyword", - ignore_above: 256, - }, - ownerEmail: { - type: "keyword", - ignore_above: 256, - }, - size: { - type: "long", - }, - runNumber: { - type: "keyword", - ignore_above: 256, - }, - // NOTE: below fields are for backward compatibility - // and should be removed when obsolete dto is removed - proposalId: { - type: "keyword", - ignore_above: 256, - }, - sampleId: { - type: "keyword", - ignore_above: 256, - }, - instrumentId: { - type: "keyword", - ignore_above: 256, - }, -}; diff --git a/src/elastic-search/configuration/indexSetting.ts b/src/elastic-search/configuration/indexSetting.ts deleted file mode 100644 index 07ce39ac6..000000000 --- a/src/elastic-search/configuration/indexSetting.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { - AnalysisEdgeNGramTokenizer, - AnalysisPatternReplaceCharFilter, - IndicesIndexSettingsAnalysis, - MappingDynamicTemplate, -} from "@elastic/elasticsearch/lib/api/types"; - -//Tokenizers -export const autocomplete_tokenizer: AnalysisEdgeNGramTokenizer = { - type: "edge_ngram", - min_gram: 2, - max_gram: 40, - token_chars: ["letter", "digit", "symbol", "punctuation"], -}; - -//Filters -export const special_character_filter: AnalysisPatternReplaceCharFilter = { - pattern: "[^A-Za-z0-9]", - type: "pattern_replace", - replacement: "", -}; - -//Dynamic templates -export const dynamic_template: Record[] = [ - // NOTE: date as keyword is temporary solution for date format inconsistency issue in the scientificMetadata field - { - date_as_keyword: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "date", - mapping: { - type: "keyword", - }, - }, - }, - { - long_as_double: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "long", - mapping: { - type: "double", - coerce: true, - ignore_malformed: true, - }, - }, - }, - { - double_as_double: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "double", - mapping: { - type: "double", - coerce: true, - ignore_malformed: true, - }, - }, - }, - { - string_as_keyword_level2: { - path_match: "scientificMetadata.*.*", - match_mapping_type: "string", - mapping: { - type: "text", - analyzer: "case_sensitive", - search_analyzer: "case_sensitive", - fields: { - keyword: { - type: "keyword", - ignore_above: 256, - }, - }, - }, - }, - }, - { - string_as_keyword_level1: { - path_match: "scientificMetadata.*", - match_mapping_type: "string", - mapping: { - type: "text", - analyzer: "case_sensitive", - search_analyzer: "case_sensitive", - fields: { - keyword: { - type: "keyword", - ignore_above: 256, - }, - }, - }, - }, - }, -]; - -//Index Settings -export const defaultElasticSettings = { - index: { - max_result_window: process.env.ES_MAX_RESULT || 2000000, - number_of_replicas: 0, - mapping: { - total_fields: { - limit: process.env.ES_FIELDS_LIMIT || 2000000, - }, - nested_fields: { - limit: 1000, - }, - }, - }, - analysis: { - analyzer: { - autocomplete: { - tokenizer: "autocomplete", - filter: ["lowercase"], - }, - autocomplete_search: { - tokenizer: "lowercase", - }, - case_sensitive: { - type: "custom", - tokenizer: "standard", - filter: [], - }, - }, - tokenizer: { - autocomplete: autocomplete_tokenizer, - }, - }, -} as IndicesIndexSettingsAnalysis; diff --git a/src/elastic-search/dto/create-index.dto.ts b/src/elastic-search/dto/create-index.dto.ts deleted file mode 100644 index 3f63ac65d..000000000 --- a/src/elastic-search/dto/create-index.dto.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsString } from "class-validator"; - -export class CreateIndexDto { - @ApiProperty({ - type: String, - required: true, - default: "dataset", - description: "Create an index with this name", - }) - @IsString() - readonly index: string; -} diff --git a/src/elastic-search/dto/delete-index.dto.ts b/src/elastic-search/dto/delete-index.dto.ts deleted file mode 100644 index 433511d9b..000000000 --- a/src/elastic-search/dto/delete-index.dto.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsString } from "class-validator"; - -export class DeleteIndexDto { - @ApiProperty({ - type: String, - required: true, - default: "dataset", - description: "Delete an index with this name", - }) - @IsString() - readonly index: string; -} diff --git a/src/elastic-search/dto/get-index.dto.ts b/src/elastic-search/dto/get-index.dto.ts deleted file mode 100644 index 3ce9849ad..000000000 --- a/src/elastic-search/dto/get-index.dto.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsString } from "class-validator"; - -export class GetIndexDto { - @ApiProperty({ - type: String, - required: true, - default: "dataset", - description: "Get an index with this name", - }) - @IsString() - readonly index: string; -} diff --git a/src/elastic-search/dto/index.ts b/src/elastic-search/dto/index.ts deleted file mode 100644 index ea3e4ea1c..000000000 --- a/src/elastic-search/dto/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CreateIndexDto } from "../dto/create-index.dto"; -import { DeleteIndexDto } from "../dto/delete-index.dto"; -import { GetIndexDto } from "../dto/get-index.dto"; -import { SyncDatabaseDto } from "../dto/sync-data.dto"; -import { UpdateIndexDto } from "../dto/update-index.dto"; - -export class ElasticSearchActions { - createIndex: CreateIndexDto; - deleteIndex: DeleteIndexDto; - updateIndex: UpdateIndexDto; - syncDatabase: SyncDatabaseDto; - getIndexSettings: GetIndexDto; -} diff --git a/src/elastic-search/dto/search.dto.ts b/src/elastic-search/dto/search.dto.ts deleted file mode 100644 index 13270eba5..000000000 --- a/src/elastic-search/dto/search.dto.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsArray, IsOptional } from "class-validator"; - -export class SearchDto { - @ApiProperty({ - type: String, - required: false, - default: "", - description: "text query", - }) - readonly text: string; - - @ApiProperty({ - type: Array, - required: false, - default: [], - description: "ownerGroup", - }) - @IsOptional() - readonly ownerGroup: []; - - @ApiProperty({ - type: Array, - required: false, - default: [], - description: "creationLocation", - }) - @IsOptional() - readonly creationLocation: []; - - @ApiProperty({ - type: Array, - required: false, - default: [], - description: "type", - }) - @IsOptional() - readonly type: []; - - @ApiProperty({ - type: Array, - required: false, - default: [], - description: "keywords", - }) - @IsOptional() - readonly keywords: []; - - @ApiProperty({ - type: Boolean, - required: false, - default: false, - description: "isPublished", - }) - @IsOptional() - readonly isPublished: boolean; - - @ApiProperty({ - type: Array, - items: { - type: "object", - properties: { - lhs: { type: "string" }, - relation: { type: "string" }, - rhs: { - type: "number", - description: "This can be either a number or a string", - }, - unit: { type: "string" }, - }, - }, - required: false, - default: [ - { - lhs: "", - relation: "", - rhs: 0, - unit: "", - }, - ], - description: "scientificMetadata condition", - }) - @IsOptional() - @IsArray() - readonly scientific: Array<{ - lhs: string; - relation: string; - rhs: number | string; - unit: string; - }>; -} diff --git a/src/elastic-search/dto/sync-data.dto.ts b/src/elastic-search/dto/sync-data.dto.ts deleted file mode 100644 index 1bdf3ff34..000000000 --- a/src/elastic-search/dto/sync-data.dto.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsString } from "class-validator"; - -export class SyncDatabaseDto { - @ApiProperty({ - type: String, - required: true, - default: "dataset", - description: "Sync datasets into elastic search with this index", - }) - @IsString() - readonly index: string; -} diff --git a/src/elastic-search/dto/update-index.dto.ts b/src/elastic-search/dto/update-index.dto.ts deleted file mode 100644 index b6f264e24..000000000 --- a/src/elastic-search/dto/update-index.dto.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsString } from "class-validator"; - -export class UpdateIndexDto { - @ApiProperty({ - type: String, - required: true, - default: "dataset", - description: "Update an index with this name", - }) - @IsString() - readonly index: string; -} diff --git a/src/elastic-search/elastic-search.controller.ts b/src/elastic-search/elastic-search.controller.ts deleted file mode 100644 index de2498da6..000000000 --- a/src/elastic-search/elastic-search.controller.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { - Controller, - HttpCode, - HttpStatus, - Post, - Body, - Get, - Query, - UseInterceptors, - UseGuards, -} from "@nestjs/common"; -import { ApiTags, ApiBearerAuth, ApiBody, ApiResponse } from "@nestjs/swagger"; -import { Action } from "src/casl/action.enum"; -import { AppAbility } from "src/casl/casl-ability.factory"; -import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; -import { PoliciesGuard } from "src/casl/guards/policies.guard"; -import { DatasetsService } from "src/datasets/datasets.service"; -import { SubDatasetsPublicInterceptor } from "src/datasets/interceptors/datasets-public.interceptor"; -import { IDatasetFields } from "src/datasets/interfaces/dataset-filters.interface"; -import { ElasticSearchActions } from "./dto"; -import { CreateIndexDto } from "./dto/create-index.dto"; -import { DeleteIndexDto } from "./dto/delete-index.dto"; -import { GetIndexDto } from "./dto/get-index.dto"; - -import { SearchDto } from "./dto/search.dto"; -import { SyncDatabaseDto } from "./dto/sync-data.dto"; -import { UpdateIndexDto } from "./dto/update-index.dto"; -import { ElasticSearchService } from "./elastic-search.service"; - -@ApiBearerAuth() -@ApiTags("elastic-search") -@Controller("elastic-search") -export class ElasticSearchServiceController { - constructor( - private readonly elasticSearchService: ElasticSearchService, - private readonly datasetService: DatasetsService, - ) {} - - @UseGuards(PoliciesGuard) - @CheckPolicies("elastic-search", (ability: AppAbility) => - ability.can(Action.Manage, ElasticSearchActions), - ) - @HttpCode(HttpStatus.CREATED) - @ApiResponse({ - status: HttpStatus.CREATED, - description: "Create index", - }) - @Post("/create-index") - async createIndex(@Query() { index }: CreateIndexDto) { - const esIndex = index.trim(); - - return this.elasticSearchService.createIndex(esIndex); - } - - @UseGuards(PoliciesGuard) - @CheckPolicies("elastic-search", (ability: AppAbility) => - ability.can(Action.Manage, ElasticSearchActions), - ) - @HttpCode(HttpStatus.OK) - @ApiResponse({ - status: 200, - description: "Sync data to the index", - }) - @Post("/sync-database") - async syncDatabase(@Query() { index }: SyncDatabaseDto) { - const esIndex = index.trim(); - const collectionData = await this.datasetService.getDatasetsWithoutId(); - - return this.elasticSearchService.syncDatabase(collectionData, esIndex); - } - - @UseGuards(PoliciesGuard) - @CheckPolicies("elastic-search", (ability: AppAbility) => - ability.can(Action.Manage, ElasticSearchActions), - ) - @HttpCode(HttpStatus.OK) - @UseInterceptors(SubDatasetsPublicInterceptor) - @ApiBody({ - type: SearchDto, - }) - @ApiResponse({ - status: 200, - description: "Search with elasticsearch to get restuls in PIDs", - }) - @Post("/search") - async fetchESResults(@Body() searchDto: IDatasetFields) { - return this.elasticSearchService.search(searchDto); - } - - @UseGuards(PoliciesGuard) - @CheckPolicies("elastic-search", (ability: AppAbility) => - ability.can(Action.Manage, ElasticSearchActions), - ) - @HttpCode(HttpStatus.OK) - @ApiResponse({ - status: 200, - description: "Delete index", - }) - @Post("/delete-index") - async deleteIndex(@Query() { index }: DeleteIndexDto) { - const esIndex = index.trim(); - - return this.elasticSearchService.deleteIndex(esIndex); - } - - @UseGuards(PoliciesGuard) - @CheckPolicies("elastic-search", (ability: AppAbility) => - ability.can(Action.Manage, ElasticSearchActions), - ) - @HttpCode(HttpStatus.OK) - @ApiResponse({ - status: 200, - description: "Get current index setting", - }) - @Get("/get-index") - async getIndex(@Query() { index }: GetIndexDto) { - const esIndex = index.trim(); - - return this.elasticSearchService.getIndexSettings(esIndex); - } - - @UseGuards(PoliciesGuard) - @CheckPolicies("elastic-search", (ability: AppAbility) => - ability.can(Action.Manage, ElasticSearchActions), - ) - @HttpCode(HttpStatus.OK) - @ApiResponse({ - status: 200, - description: "Update index to the latest settings", - }) - @Post("/update-index") - async updateIndex(@Query() { index }: UpdateIndexDto) { - const esIndex = index.trim(); - - return this.elasticSearchService.updateIndex(esIndex); - } -} diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts deleted file mode 100644 index f6743ec38..000000000 --- a/src/elastic-search/elastic-search.service.ts +++ /dev/null @@ -1,432 +0,0 @@ -import { - HttpException, - HttpStatus, - Injectable, - Logger, - OnModuleInit, -} from "@nestjs/common"; - -import { Client } from "@elastic/elasticsearch"; -import { SearchQueryService } from "./providers/query-builder.service"; -import { - SearchRequest, - AggregationsAggregate, - SortOrder, -} from "@elastic/elasticsearch/lib/api/types"; -import { IDatasetFields } from "src/datasets/interfaces/dataset-filters.interface"; -import { - defaultElasticSettings, - dynamic_template, -} from "./configuration/indexSetting"; -import { datasetMappings } from "./configuration/datasetFieldMapping"; -import { - DatasetClass, - DatasetDocument, -} from "src/datasets/schemas/dataset.schema"; -import { ConfigService } from "@nestjs/config"; -import { sleep } from "src/common/utils"; -import { - initialSyncTransform, - transformFacets, - addValueType, -} from "./helpers/utils"; - -import { SortFields } from "./providers/fields.enum"; - -@Injectable() -export class ElasticSearchService implements OnModuleInit { - private esService: Client; - private host: string; - private username: string; - private password: string; - private refresh: "false" | "wait_for"; - public defaultIndex: string; - public esEnabled: boolean; - public connected = false; - - constructor( - private readonly searchService: SearchQueryService, - private readonly configService: ConfigService, - ) { - this.host = this.configService.get("elasticSearch.host") || ""; - this.username = - this.configService.get("elasticSearch.username") || ""; - this.password = - this.configService.get("elasticSearch.password") || ""; - this.esEnabled = - this.configService.get("elasticSearch.enabled") === "yes" - ? true - : false; - this.refresh = - this.configService.get<"false" | "wait_for">("elasticSearch.refresh") || - "false"; - - this.defaultIndex = - this.configService.get("elasticSearch.defaultIndex") || ""; - - if ( - this.esEnabled && - (!this.host || !this.username || !this.password || !this.defaultIndex) - ) { - Logger.error( - "Missing ENVIRONMENT variables for elastic search connection", - "ElasticSearch", - ); - } - } - - async onModuleInit() { - if (!this.esEnabled) { - this.connected = false; - return; - } - - try { - await this.retryConnection(3, 3000); - const isIndexExists = await this.isIndexExists(this.defaultIndex); - if (!isIndexExists) { - await this.createIndex(this.defaultIndex); - Logger.log( - `New index ${this.defaultIndex}is created `, - "ElasticSearch", - ); - } - this.connected = true; - Logger.log("Elasticsearch Connected", "ElasticSearch"); - } catch (error) { - Logger.error(error, "onModuleInit failed-> ElasticSearchService"); - } - } - - private async connect() { - const connection = new Client({ - node: this.host, - auth: { - username: this.username, - password: this.password, - }, - tls: { - rejectUnauthorized: false, - }, - }); - await connection.ping(); - this.esService = connection; - } - private async retryConnection(maxRetries: number, interval: number) { - let retryCount = 0; - while (maxRetries > retryCount) { - await sleep(interval); - try { - await this.connect(); - break; - } catch (error) { - Logger.error(`Retry attempt ${retryCount + 1} failed:`, error); - retryCount++; - } - } - - if (retryCount === maxRetries) { - throw new HttpException( - "Max retries reached; check Elasticsearch config.", - HttpStatus.BAD_REQUEST, - ); - } - } - - async isIndexExists(index = this.defaultIndex) { - return await this.esService.indices.exists({ - index, - }); - } - - async createIndex(index = this.defaultIndex) { - try { - await this.esService.indices.create({ - index, - body: { - settings: defaultElasticSettings, - mappings: { - dynamic: true, - dynamic_templates: dynamic_template, - numeric_detection: false, - date_detection: true, - dynamic_date_formats: [ - "yyyy-MM-dd'T'HH:mm:ss|| yyyy-MM-dd HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZ||yyyy-MM-dd'T'HH:mm:ss.SSS'Z'||yyyy-MM-dd'T'HH:mm:ss.SSS", - ], - properties: datasetMappings, - }, - }, - }); - Logger.log( - `Elasticsearch Index Created-> Index: ${index}`, - "Elasticsearch", - ); - return HttpStatus.CREATED; - } catch (error) { - throw new HttpException( - `createIndex failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - async syncDatabase(collection: DatasetClass[], index = this.defaultIndex) { - const indexExists = await this.esService.indices.exists({ index }); - if (!indexExists) { - throw new Error("Index not found"); - } - - const bulkResponse = await this.performBulkOperation(collection, index); - - Logger.log( - JSON.stringify(bulkResponse, null, 0), - "Elasticsearch Data Synchronization Response", - ); - - return bulkResponse; - } - - async getCount(index = this.defaultIndex) { - try { - return await this.esService.count({ index }); - } catch (error) { - throw new HttpException( - `getCount failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - async updateIndex(index = this.defaultIndex) { - try { - await this.esService.indices.close({ - index, - }); - await this.esService.indices.putSettings({ - index, - body: { settings: defaultElasticSettings }, - }); - - await this.esService.indices.putMapping({ - index, - dynamic: true, - body: { - properties: datasetMappings, - dynamic_templates: dynamic_template, - }, - }); - - await this.esService.indices.open({ - index, - }); - Logger.log( - `Elasticsearch Index Updated-> Index: ${index}`, - "Elasticsearch", - ); - } catch (error) { - throw new HttpException( - `updateIndex failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - async getIndexSettings(index = this.defaultIndex) { - try { - return await this.esService.indices.getSettings({ index }); - } catch (error) { - throw new HttpException( - `getIndexSettings failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - async deleteIndex(index = this.defaultIndex) { - try { - await this.esService.indices.delete({ index }); - Logger.log( - `Elasticsearch Index Deleted-> Index: ${index} `, - "Elasticsearch", - ); - return { success: true, message: `Index ${index} deleted` }; - } catch (error) { - throw new HttpException( - `deleteIndex failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - async search( - searchParam: IDatasetFields, - limit = 20, - skip = 0, - sort?: Record, - ): Promise<{ totalCount: number; data: (string | undefined)[] }> { - const defaultMinScore = searchParam.text ? 1 : 0; - - try { - const isSortEmpty = !sort || JSON.stringify(sort) === "{}"; - const searchQuery = this.searchService.buildSearchQuery(searchParam); - const searchOptions = { - track_scores: true, - sort: [{ _score: { order: "desc" } }], - query: searchQuery.query, - from: skip, - size: limit, - min_score: defaultMinScore, - track_total_hits: true, - _source: [""], - } as SearchRequest; - - if (!isSortEmpty) { - const sortField = Object.keys(sort)[0]; - const sortDirection = Object.values(sort)[0]; - - // NOTE: To sort datasetName field we need to use datasetName.keyword field, - // as elasticsearch does not have good support for text type field sorting - const isDatasetName = sortField === SortFields.DatasetName; - const fieldForSorting = isDatasetName - ? SortFields.DatasetNameKeyword - : sortField; - - const isNestedField = fieldForSorting.includes( - SortFields.ScientificMetadata, - ); - - if (isNestedField) { - searchOptions.sort = [ - { - [`${SortFields.ScientificMetadataRunNumberValue}`]: { - order: sortDirection, - nested: { - path: SortFields.ScientificMetadata, - }, - }, - }, - ]; - } else { - searchOptions.sort = [ - { [fieldForSorting]: { order: sortDirection } }, - ]; - } - } - - const body = await this.esService.search(searchOptions); - - const totalCount = body.hits.hits.length || 0; - - const data = body.hits.hits.map((item) => item._id || ""); - return { - totalCount, - data, - }; - } catch (error) { - throw new HttpException( - `SearchService || search query issue || -> search ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - async aggregate(searchParam: IDatasetFields) { - try { - const searchQuery = this.searchService.buildSearchQuery(searchParam); - const facetPipeline = this.searchService.buildFullFacetPipeline(); - - const searchOptions = { - query: searchQuery.query, - size: 0, - aggs: facetPipeline, - _source: [""], - } as SearchRequest; - - const body = await this.esService.search(searchOptions); - - const transformedFacets = transformFacets( - body.aggregations as AggregationsAggregate, - ); - - return transformedFacets; - } catch (error) { - throw new HttpException( - `SearchService || aggregate query issue || -> aggregate ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - async updateInsertDocument(data: Partial) { - //NOTE: Replace all keys with lower case, also replace spaces and dot with underscore - delete data._id; - const transformedScientificMetadata = addValueType( - data.scientificMetadata as Record, - ); - - const transformedData = { - ...data, - scientificMetadata: transformedScientificMetadata, - }; - try { - await this.esService.index({ - index: this.defaultIndex, - id: data.pid, - document: transformedData, - refresh: this.refresh, - }); - - Logger.log( - `Document Update/inserted-> Document_id: ${data.pid} update/inserted on index: ${this.defaultIndex}`, - "Elasticsearch", - ); - } catch (error) { - throw new HttpException( - `updateDocument failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - async deleteDocument(id: string) { - try { - await this.esService.delete({ - index: this.defaultIndex, - id, - refresh: this.refresh, - }); - Logger.log( - `Document Deleted-> Document_id: ${id} deleted on index: ${this.defaultIndex}`, - "Elasticsearch", - ); - } catch (error) { - throw new HttpException( - `deleteDocument failed-> ElasticSearchService ${error}`, - HttpStatus.BAD_REQUEST, - ); - } - } - - // *** NOTE: below are helper methods *** - - async performBulkOperation(collection: DatasetClass[], index: string) { - const result = await this.esService.helpers.bulk({ - retries: 5, - wait: 10000, - datasource: collection, - onDocument(doc: DatasetClass) { - return [ - { - index: { - _index: index, - _id: doc.pid, - }, - }, - initialSyncTransform(doc), - ]; - }, - onDrop(doc) { - console.debug(`${doc.document.pid}`, doc.error?.reason); - }, - }); - return result; - } -} diff --git a/src/elastic-search/helpers/utils.ts b/src/elastic-search/helpers/utils.ts deleted file mode 100644 index 48817e625..000000000 --- a/src/elastic-search/helpers/utils.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { - AggregationsAggregate, - AggregationsFrequentItemSetsBucketKeys, -} from "@elastic/elasticsearch/lib/api/types"; -import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { - IFilter, - ITransformedFullFacets, - nestedQueryObject, - ScientificQuery, -} from "../interfaces/es-common.type"; -import { isObject } from "lodash"; - -export const transformKey = (key: string): string => { - return key.trim().replace(/[.]/g, "\\.").replace(/ /g, "_").toLowerCase(); -}; -export const addValueType = (obj: Record) => { - const newObj: Record = {}; - - for (const [key, value] of Object.entries(obj)) { - const newKey = transformKey(key); - - const isNumberValueType = - typeof (value as Record)?.value === "number"; - const isStringValueType = - typeof (value as Record)?.value === "string"; - - if (isObject(value)) { - if (isNumberValueType) { - (value as Record)["value_type"] = "number"; - } else if (isStringValueType) { - (value as Record)["value_type"] = "string"; - } else { - (value as Record)["value_type"] = "unknown"; - } - } - - newObj[newKey] = value; - } - - return newObj; -}; - -export const transformMiddleKey = (key: string) => { - const parts = key.trim().split("."); - const firstPart = parts[0]; - const lastPart = parts[parts.length - 1]; - - const middlePartRaw = parts.slice(1, parts.length - 1).join("."); - const middlePart = transformKey(middlePartRaw); - - let transformedKey = firstPart; - if (middlePart) { - transformedKey += `.${middlePart}`; - } - transformedKey += `.${lastPart}`; - - return { transformedKey, firstPart, middlePart, lastPart }; -}; - -export const initialSyncTransform = (obj: DatasetClass) => { - const modifedDocInArray = !!obj.scientificMetadata - ? Object.entries(obj.scientificMetadata as Record).map( - ([key, value]) => { - const transformedKey = transformKey(key); - - if (!isObject(value)) { - return [transformedKey, { value: value, unit: "" }]; - } - - if ("value" in value) { - if (typeof value.value === "number") { - return [transformedKey, { ...value, value_type: "number" }]; - } - if (typeof value.value === "string") { - return [transformedKey, { ...value, value_type: "string" }]; - } - } - - return [transformedKey, { ...value, value_type: "unknown" }]; - }, - ) - : []; - - const modifiedDocInObject = { - ...obj, - scientificMetadata: - modifedDocInArray.length > 0 ? Object.fromEntries(modifedDocInArray) : {}, - }; - - return modifiedDocInObject; -}; - -const extractNestedQueryOperationValue = (query: nestedQueryObject) => { - const field = Object.keys(query)[0]; - const operationWithPrefix = Object.keys(query[field])[0]; - - const value = - typeof query[field][operationWithPrefix] === "string" - ? (query[field][operationWithPrefix] as string).trim() - : query[field][operationWithPrefix]; - - const operation = operationWithPrefix.replace("$", ""); - - return { operation, value, field }; -}; - -export const convertToElasticSearchQuery = ( - scientificQuery: ScientificQuery, -): IFilter[] => { - const filters: IFilter[] = []; - - for (const field in scientificQuery) { - const query = scientificQuery[field]; - - if (field === "$and" && Array.isArray(query)) { - query.forEach((query: { $or: nestedQueryObject[] }) => { - const shouldQueries = query.$or.map((orQuery: nestedQueryObject) => { - const { operation, value, field } = - extractNestedQueryOperationValue(orQuery); - const filterType = operation === "eq" ? "term" : "range"; - - // NOTE: if value is not a number, we use keyword field for exact match - const targetField = - typeof value !== "number" ? `${field}.keyword` : field; - return { - [filterType]: { - [targetField]: - operation === "eq" ? value : { [operation]: value }, - }, - }; - }); - filters.push({ - bool: { - should: shouldQueries, - minimum_should_match: 1, - }, - }); - }); - } else if (field === "$or" && Array.isArray(query)) { - const shouldQueries = query.map((query: nestedQueryObject) => { - const { operation, value, field } = - extractNestedQueryOperationValue(query); - const filterType = operation === "eq" ? "term" : "range"; - - // NOTE: if value is not a number, we use keyword field for exact match - const targetField = - typeof value !== "number" ? `${field}.keyword` : field; - return { - [filterType]: { - [targetField]: operation === "eq" ? value : { [operation]: value }, - }, - }; - }); - filters.push({ - bool: { - should: shouldQueries, - minimum_should_match: 1, - }, - }); - } else if ( - Object.keys(query).length > 1 && - !Array.isArray(query) && - isObject(query) - ) { - const { transformedKey, firstPart, middlePart, lastPart } = - transformMiddleKey(field); - - const rangeOps: Record = {}; - - Object.keys(query).forEach((op) => { - const val = query[op]; - rangeOps[op.replace("$", "")] = - typeof val === "number" ? val : Number(val); - }); - - if (lastPart === "valueSI" || lastPart === "value") { - filters.push({ - term: { - [`${firstPart}.${middlePart}.value_type`]: "number", - }, - }); - } - filters.push({ - range: { [transformedKey]: rangeOps }, - }); - } else { - const operation = Object.keys(query)[0]; - const value = - typeof (query as Record)[operation] === "string" - ? (query as Record)[operation].trim() - : (query as Record)[operation]; - const esOperation = operation.replace("$", ""); - - // NOTE: - // trasnformedKey = "scientificMetadata.someKey.value" - // firstPart = "scientificMetadata", - // middlePart = "someKey" - // lastPart = "value" - const { transformedKey, firstPart, middlePart, lastPart } = - transformMiddleKey(field); - - if (lastPart === "valueSI" || lastPart === "value") { - const numberFilter = { - term: { - [`${firstPart}.${middlePart}.value_type`]: - typeof value === "number" ? "number" : "string", - }, - }; - filters.push(numberFilter); - } - - // NOTE: if value is not a number, we use keyword field for exact match for term queries - // for range queries we can skip this as string values will not be accepted - const targetField = - typeof value !== "number" ? `${field}.keyword` : field; - - const filter = - esOperation === "eq" - ? { - term: { [`${targetField}`]: value }, - } - : { - range: { [`${transformedKey}`]: { [esOperation]: value } }, - }; - - filters.push(filter); - } - } - return filters; -}; - -export const transformFacets = ( - aggregation: AggregationsAggregate, -): Record[] => { - const transformed = Object.entries(aggregation).reduce( - (acc, [key, value]) => { - const isBucketArray = Array.isArray(value.buckets); - - acc[key] = isBucketArray - ? value.buckets.map( - (bucket: AggregationsFrequentItemSetsBucketKeys) => ({ - _id: bucket.key, - count: bucket.doc_count, - }), - ) - : [{ totalSets: value.value }]; - - return acc; - }, - {} as ITransformedFullFacets, - ); - - return [transformed]; -}; diff --git a/src/elastic-search/interfaces/es-common.type.ts b/src/elastic-search/interfaces/es-common.type.ts deleted file mode 100644 index e751ea0ca..000000000 --- a/src/elastic-search/interfaces/es-common.type.ts +++ /dev/null @@ -1,107 +0,0 @@ -export type searchType = - | "text" - | "keyword" - | "long" - | "integer" - | "date" - | "boolean" - | "object" - | "flattened" - | "nested"; - -export type ObjectType = { - begin: string; - end: string; -}; - -export type NumberRangeType = { - min: string; - max: string; -}; - -export interface IShould { - terms?: { - [key: string]: string[] | undefined; - }; - term?: { - [key: string]: string | undefined; - }; - range?: { - [key: string]: { - gte?: string | number; - lte?: string | number; - }; - }; -} - -export interface IBoolShould { - bool: { - should: IShould[]; - minimum_should_match?: number; - }; -} - -export interface IFilter { - terms?: { - [key: string]: string[]; - }; - term?: { - [key: string]: boolean | string; - }; - range?: { - [key: string]: { - gte?: string | number; - lte?: string | number; - }; - }; - match?: { - [key: string]: string | number; - }; - nested?: { - path: string; - query: { - bool: { - must: ( - | { term?: { [key: string]: string } } - | { range?: { [key: string]: { [key: string]: string | number } } } - )[]; - }; - }; - }; - bool?: { - should: IShould[]; - minimum_should_match?: number; - }; -} - -export interface IFullFacets { - [key: string]: { - terms?: { - field: string; - order: { - _key?: string; - _count?: string; - }; - }; - value_count?: { - field: "pid"; - }; - }; -} - -export interface ITransformedFullFacets { - [key: string]: - | { - _id: string; - count: number; - } - | { totalSets: number }; -} - -export interface ScientificQuery { - [key: string]: Record | "$and" | "$or"; -} - -export interface nestedQueryObject { - [key: string]: Record; -} diff --git a/src/elastic-search/interfaces/mappingInterface.type.ts b/src/elastic-search/interfaces/mappingInterface.type.ts deleted file mode 100644 index b4a62b0f3..000000000 --- a/src/elastic-search/interfaces/mappingInterface.type.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { searchType } from "./es-common.type"; - -export interface MappingProperty { - type: searchType; - fields?: { - keyword: { - type: searchType; - ignore_above: number; - }; - }; - [key: string]: unknown; -} - -export interface MappingObject { - [key: string]: MappingProperty; -} diff --git a/src/elastic-search/providers/fields.enum.ts b/src/elastic-search/providers/fields.enum.ts deleted file mode 100644 index 8030407ab..000000000 --- a/src/elastic-search/providers/fields.enum.ts +++ /dev/null @@ -1,38 +0,0 @@ -export enum FilterFields { - Keywords = "keywords", - Pid = "pid", - Type = "type", - CreationLocation = "creationLocation", - CreationTime = "creationTime", - OwnerGroup = "ownerGroup", - AccessGroups = "accessGroups", - ScientificMetadata = "scientific", - IsPublished = "isPublished", - DatasetName = "datasetName", - Mode = "mode", -} - -export enum MustFields { - DatasetName = "datasetName", - Description = "description", -} - -export enum ShouldFields { - SharedWith = "sharedWith", - UserGroups = "userGroups", -} - -export enum FacetFields { - Type = "type", - CreationLocation = "creationLocation", - OwnerGroup = "ownerGroup", - AccessGroups = "accessGroups", - Keywords = "keywords", -} - -export enum SortFields { - DatasetName = "datasetName", - DatasetNameKeyword = "datasetName.keyword", - ScientificMetadata = "scientificMetadata", - ScientificMetadataRunNumberValue = "scientificMetadata.runnumber.value", -} diff --git a/src/elastic-search/providers/query-builder.service.ts b/src/elastic-search/providers/query-builder.service.ts deleted file mode 100644 index 47b83fc86..000000000 --- a/src/elastic-search/providers/query-builder.service.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { QueryDslQueryContainer } from "@elastic/elasticsearch/lib/api/types"; -import { IDatasetFields } from "src/datasets/interfaces/dataset-filters.interface"; -import { - IBoolShould, - IFilter, - IFullFacets, - IShould, - NumberRangeType, - ObjectType, - ScientificQuery, -} from "../interfaces/es-common.type"; -import { - FilterFields, - MustFields, - FacetFields, - ShouldFields, -} from "./fields.enum"; - -import { mapScientificQuery } from "src/common/utils"; -import { IScientificFilter } from "src/common/interfaces/common.interface"; -import { convertToElasticSearchQuery } from "../helpers/utils"; - -@Injectable() -export class SearchQueryService { - readonly filterFields = [...Object.values(FilterFields)]; - readonly mustFields = [...Object.values(MustFields)]; - readonly shouldFields = [...Object.values(ShouldFields)]; - readonly facetFields = [...Object.values(FacetFields)]; - readonly textQuerySplitMethod = /[ ,]+/; - - public buildSearchQuery(searchParam: IDatasetFields) { - try { - const { ...fields } = searchParam; - - const filter = this.buildFilterFields(fields); - const should = this.buildShouldFields(fields); - const must = this.buildTextQuery(fields); - - // NOTE: The final query flow is as follows: - // step 1. Build filter fields conditions must match all filter fields - // step 2. Build should fields conditions must match at least one should field - // step 3. Build text query conditions must match all text query fields - return this.constructFinalQuery(filter, should, must); - } catch (err) { - Logger.error("Elastic search build search query failed"); - throw err; - } - } - private buildFilterFields(fields: Partial): IFilter[] { - const filter: IFilter[] = []; - - Object.entries(fields).forEach(([key, value]) => { - if (this.shouldFields.includes(key as ShouldFields) || key === "text") { - return; - } - - const filterQueries = this.buildTermsFilter(key, value); - filter.push(...filterQueries); - }); - - return filter; - } - - private buildShouldFields(fields: Partial) { - const shouldFilter: IShould[] = []; - if (fields["sharedWith"]) { - const termFilter = { terms: { sharedWith: fields["sharedWith"] } }; - - shouldFilter.push(termFilter); - } - - if (fields["userGroups"]) { - const ownerGroup = { terms: { ownerGroup: fields["userGroups"] } }; - const accessGroups = { terms: { accessGroups: fields["userGroups"] } }; - - shouldFilter.push(ownerGroup, accessGroups); - } - return { bool: { should: shouldFilter, minimum_should_match: 1 } }; - } - - private buildTextQuery( - fields: Partial, - ): QueryDslQueryContainer[] { - let wildcardQueries: QueryDslQueryContainer[] = []; - const { text } = fields; - - //NOTE: if text field is present, we query both datasetName and description fields - if (text) { - wildcardQueries = this.buildWildcardQueries(text); - } - - return wildcardQueries.length > 0 - ? [{ bool: { should: wildcardQueries, minimum_should_match: 1 } }] - : []; - } - - private splitSearchText(text: string): string[] { - return text - .toLowerCase() - .trim() - .split(this.textQuerySplitMethod) - .filter(Boolean); - } - - private buildWildcardQueries(text: string): QueryDslQueryContainer[] { - const terms = this.splitSearchText(text); - return terms.flatMap((term) => - this.mustFields.map((fieldName) => ({ - wildcard: { [fieldName]: { value: `*${term}*` } }, - })), - ); - } - - private buildTermsFilter(fieldName: string, values: unknown) { - const filterArray: IFilter[] = []; - - if (Array.isArray(values) && values.length === 0) { - return filterArray; - } - - switch (fieldName) { - case FilterFields.ScientificMetadata: - const scientificFilterQuery = mapScientificQuery( - fieldName, - values as IScientificFilter[], - ); - - const esScientificFilterQuery = convertToElasticSearchQuery( - scientificFilterQuery as ScientificQuery, - ); - filterArray.push({ - nested: { - path: "scientificMetadata", - query: { - bool: { - must: esScientificFilterQuery, - }, - }, - }, - }); - break; - - case FilterFields.CreationTime: - filterArray.push({ - range: { - [fieldName]: { - gte: (values as ObjectType).begin, - lte: (values as ObjectType).end, - }, - }, - }); - break; - - case FilterFields.Pid: - filterArray.push({ - term: { - [fieldName]: values as string, - }, - }); - break; - - case FilterFields.IsPublished: - filterArray.push({ - term: { - [fieldName]: values as boolean, - }, - }); - break; - default: - if (Array.isArray(values)) { - filterArray.push({ - terms: { - [fieldName]: values, - }, - }); - } - if (typeof values === "string" || typeof values === "number") { - filterArray.push({ - match: { - [fieldName]: values as string | number, - }, - }); - } - - if ( - values && - typeof values === "object" && - ("min" in values || - "max" in values || - "begin" in values || - "end" in values) - ) { - filterArray.push({ - range: { - [fieldName]: { - gte: - (values as NumberRangeType).min ?? - (values as ObjectType).begin, - lte: - (values as NumberRangeType).max ?? (values as ObjectType).end, - }, - }, - }); - } - break; - } - return filterArray; - } - - private constructFinalQuery( - filter: IFilter[], - should: IBoolShould, - query: QueryDslQueryContainer[], - ) { - const finalQuery = { - query: { - bool: { - filter: [...filter, should], - must: query, - }, - }, - }; - return finalQuery; - } - - public buildFullFacetPipeline(facetFields = this.facetFields) { - const pipeline: IFullFacets = { - all: { - value_count: { - field: "pid", - }, - }, - }; - - for (const field of facetFields) { - pipeline[field] = { - terms: { - field: field, - order: { - _count: "desc", - }, - }, - }; - } - return pipeline; - } -} diff --git a/src/opensearch/dto/create-index.dto.ts b/src/opensearch/dto/create-index.dto.ts new file mode 100644 index 000000000..2812b90c5 --- /dev/null +++ b/src/opensearch/dto/create-index.dto.ts @@ -0,0 +1,20 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsObject, IsOptional } from "class-validator"; +import { UpdateIndexDto } from "./update-index.dto"; +import type { TypeMapping } from "@opensearch-project/opensearch/api/_types/_common.mapping"; + +export class CreateIndexDto extends UpdateIndexDto { + @ApiProperty({ + description: "Index mappings", + type: Object, + example: { + properties: { + datasetName: { type: "text" }, + ownerGroup: { type: "keyword" }, + }, + }, + }) + @IsObject() + @IsOptional() + mappings: TypeMapping; +} diff --git a/src/opensearch/dto/dataset-opensearch.dto.ts b/src/opensearch/dto/dataset-opensearch.dto.ts new file mode 100644 index 000000000..d86f668a2 --- /dev/null +++ b/src/opensearch/dto/dataset-opensearch.dto.ts @@ -0,0 +1,17 @@ +import { PickType } from "@nestjs/swagger"; +import { Expose } from "class-transformer"; +import { OutputDatasetDto } from "src/datasets/dto/output-dataset.dto"; + +import { DATASET_OPENSEARCH_FIELDS } from "src/opensearch/utils/dataset-opensearch.utils"; + +export class DatasetOpenSearchDto extends PickType( + OutputDatasetDto, + DATASET_OPENSEARCH_FIELDS, +) { + @Expose() pid: string; + @Expose() description?: string; + @Expose() datasetName: string; + @Expose() isPublished?: boolean; + @Expose() ownerGroup: string; + @Expose() accessGroups: string[]; +} diff --git a/src/opensearch/dto/update-index.dto.ts b/src/opensearch/dto/update-index.dto.ts new file mode 100644 index 000000000..0d278a0e8 --- /dev/null +++ b/src/opensearch/dto/update-index.dto.ts @@ -0,0 +1,30 @@ +import { ApiProperty } from "@nestjs/swagger"; +import type { IndexSettings } from "@opensearch-project/opensearch/api/_types/indices._common"; +import { IsObject, IsOptional, IsString } from "class-validator"; + +export class UpdateIndexDto { + @ApiProperty({ + type: String, + required: true, + default: "dataset", + description: "Update an index with this name", + }) + @IsString() + @IsOptional() + index: string; + + @ApiProperty({ + description: "Index settings to update", + type: Object, + example: { + index: { + number_of_replicas: 1, + refresh_interval: "1s", + max_result_window: 1000000, + }, + }, + }) + @IsObject() + @IsOptional() + settings: IndexSettings; +} diff --git a/src/opensearch/interfaces/os-common.type.ts b/src/opensearch/interfaces/os-common.type.ts new file mode 100644 index 000000000..2420e3d77 --- /dev/null +++ b/src/opensearch/interfaces/os-common.type.ts @@ -0,0 +1,5 @@ +export interface ISearchFilter { + userGroups?: string[]; + isPublished?: boolean; + text?: string; +} diff --git a/src/opensearch/opensearch.controller.ts b/src/opensearch/opensearch.controller.ts new file mode 100644 index 000000000..d451486a4 --- /dev/null +++ b/src/opensearch/opensearch.controller.ts @@ -0,0 +1,196 @@ +import { + Controller, + HttpCode, + HttpStatus, + Post, + Get, + Query, + UseInterceptors, + UseGuards, + Body, +} from "@nestjs/common"; +import { + ApiTags, + ApiBearerAuth, + ApiResponse, + ApiQuery, + ApiBody, + ApiOperation, +} from "@nestjs/swagger"; +import { Action } from "src/casl/action.enum"; +import { AppAbility } from "src/casl/casl-ability.factory"; +import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; +import { PoliciesGuard } from "src/casl/guards/policies.guard"; +import { DatasetsService } from "src/datasets/datasets.service"; +import { SubDatasetsPublicInterceptor } from "src/datasets/interceptors/datasets-public.interceptor"; +import { CreateIndexDto } from "./dto/create-index.dto"; + +import { UpdateIndexDto } from "./dto/update-index.dto"; +import { OpensearchService } from "./opensearch.service"; +import { Opensearch } from "./opensearch.subject"; + +@ApiBearerAuth() +@ApiTags("opensearch") +@Controller("opensearch") +export class OpensearchController { + constructor( + private readonly opensearchService: OpensearchService, + private readonly datasetService: DatasetsService, + ) {} + + @UseGuards(PoliciesGuard) + @CheckPolicies("opensearch", (ability: AppAbility) => + ability.can(Action.Manage, Opensearch), + ) + @HttpCode(HttpStatus.CREATED) + @ApiBody({ + description: `If settings and mappings are not provided, + they will be loaded from the opensearchConfig.json file. + To use the default config, simply omit settings and mappings from the request body.`, + type: CreateIndexDto, + }) + @ApiResponse({ + status: HttpStatus.CREATED, + description: "Create index", + }) + @Post("/create-index") + async createIndex(@Body() createIndexDto: CreateIndexDto) { + return this.opensearchService.createIndex(createIndexDto); + } + + @UseGuards(PoliciesGuard) + @CheckPolicies("opensearch", (ability: AppAbility) => + ability.can(Action.Manage, Opensearch), + ) + @ApiOperation({ + summary: "Sync data from MongoDB to OpenSearch", + description: `Syncs the dataset collection to the specified OpenSearch index. + Defaults to the index configured in OPENSEARCH_DEFAULT_INDEX. + Currently only supports the dataset collection.`, + }) + @ApiQuery({ + name: "index", + description: "The OpenSearch index name to sync the data into", + default: "dataset", + type: String, + }) + @HttpCode(HttpStatus.OK) + @ApiResponse({ + status: 200, + description: "Successfully synced data from MongoDB to OpenSearch", + }) + @Post("/sync-database") + async syncDatabase(@Query("index") index: string) { + const esIndex = index.trim(); + // NOTE: for now, we will only sync datasets to opensearch, + // but this can be easily extended to other data in the future if needed + return await this.datasetService.syncDatasetsToOpensearch(esIndex); + } + + @UseGuards(PoliciesGuard) + @CheckPolicies("opensearch", (ability: AppAbility) => + ability.can(Action.Manage, Opensearch), + ) + @HttpCode(HttpStatus.OK) + @UseInterceptors(SubDatasetsPublicInterceptor) + @ApiQuery({ + name: "textQuery", + description: "Partial search text for datasetName and description fields", + type: String, + }) + @ApiQuery({ + name: "index", + description: "The index name to search", + default: "dataset", + required: false, + type: String, + }) + @ApiQuery({ + name: "limit", + description: "The maximum number of results to return", + required: false, + type: Number, + }) + @ApiQuery({ + name: "skip", + description: "The number of results to skip", + required: false, + type: Number, + }) + @ApiResponse({ + status: 200, + description: + "Successfully retrieved search results in _ids from Opensearch.", + }) + @Post("/search") + async fetchOSResults( + @Query("index") index: string, + @Query("limit") limit: number, + @Query("skip") skip: number, + @Query("textQuery") text: string, + ) { + return this.opensearchService.search({ text }, index, limit, skip); + } + + @UseGuards(PoliciesGuard) + @CheckPolicies("opensearch", (ability: AppAbility) => + ability.can(Action.Manage, Opensearch), + ) + @HttpCode(HttpStatus.OK) + @ApiQuery({ + name: "index", + description: "The index name to delete", + default: "dataset", + type: String, + }) + @ApiResponse({ + status: 200, + description: "Delete index", + }) + @Post("/delete-index") + async deleteIndex(@Query("index") index: string) { + return this.opensearchService.deleteIndex(index.trim()); + } + + @UseGuards(PoliciesGuard) + @CheckPolicies("opensearch", (ability: AppAbility) => + ability.can(Action.Manage, Opensearch), + ) + @HttpCode(HttpStatus.OK) + @ApiQuery({ + name: "index", + description: "The index name to get the config for", + default: "dataset", + type: String, + }) + @ApiResponse({ + status: 200, + description: "Get index config including settings and mappings", + }) + @Get("/get-index") + async getIndex(@Query("index") index: string) { + return this.opensearchService.getIndexConfig(index.trim()); + } + + @UseGuards(PoliciesGuard) + @CheckPolicies("opensearch", (ability: AppAbility) => + ability.can(Action.Manage, Opensearch), + ) + @HttpCode(HttpStatus.OK) + @ApiBody({ + description: ` + If settings are not provided, + they will be loaded from the opensearchConfig.json file. + To use the default config, simply omit settings from the request body. + for more details: https://docs.opensearch.org/latest/install-and-configure/configuring-opensearch/index-settings/`, + type: UpdateIndexDto, + }) + @ApiResponse({ + status: 200, + description: "Successfully updated index settings", + }) + @Post("/update-index") + async updateIndex(@Body() updateIndexDto: UpdateIndexDto) { + return this.opensearchService.updateIndexSettings(updateIndexDto); + } +} diff --git a/src/elastic-search/elastic-search.module.ts b/src/opensearch/opensearch.module.ts similarity index 52% rename from src/elastic-search/elastic-search.module.ts rename to src/opensearch/opensearch.module.ts index b3e774ada..21497f941 100644 --- a/src/elastic-search/elastic-search.module.ts +++ b/src/opensearch/opensearch.module.ts @@ -2,14 +2,15 @@ import { Module, forwardRef } from "@nestjs/common"; import { CaslModule } from "src/casl/casl.module"; import { ConfigModule } from "@nestjs/config"; import { DatasetsModule } from "src/datasets/datasets.module"; -import { ElasticSearchServiceController } from "./elastic-search.controller"; -import { ElasticSearchService } from "./elastic-search.service"; + import { SearchQueryService } from "./providers/query-builder.service"; +import { OpensearchService } from "./opensearch.service"; +import { OpensearchController } from "./opensearch.controller"; @Module({ imports: [forwardRef(() => DatasetsModule), ConfigModule, CaslModule], - controllers: [ElasticSearchServiceController], - providers: [ElasticSearchService, SearchQueryService], - exports: [ElasticSearchService, SearchQueryService], + controllers: [OpensearchController], + providers: [OpensearchService, SearchQueryService], + exports: [OpensearchService, SearchQueryService], }) -export class ElasticSearchModule {} +export class OpensearchModule {} diff --git a/src/elastic-search/elastic-search.service.spec.ts b/src/opensearch/opensearch.service.spec.ts similarity index 62% rename from src/elastic-search/elastic-search.service.spec.ts rename to src/opensearch/opensearch.service.spec.ts index b86762852..0f327b5b7 100644 --- a/src/elastic-search/elastic-search.service.spec.ts +++ b/src/opensearch/opensearch.service.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from "@nestjs/testing"; import { ConfigService } from "@nestjs/config"; -import { ElasticSearchService } from "./elastic-search.service"; +import { OpensearchService } from "./opensearch.service"; import { SearchQueryService } from "./providers/query-builder.service"; import { DatasetsService } from "src/datasets/datasets.service"; @@ -8,23 +8,23 @@ import { DatasetsService } from "src/datasets/datasets.service"; class SearchQueryServiceMock {} class DatasetsServiceMock {} -describe("ElasticSearchService", () => { - let service: ElasticSearchService; +describe("OpensearchService", () => { + let service: OpensearchService; const mockConfigService = { get: () => ({ - "elasticSearch.host": "fake", - "elasticSearch.username": "fake", - "elasticSearch.password": "fake", - "elasticSearch.enabled": "yes", - "elasticSearch.defaultIndex": "fake", + "opensearch.host": "fake", + "opensearch.username": "fake", + "opensearch.password": "fake", + "opensearch.enabled": "yes", + "opensearch.defaultIndex": "fake", }), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ - ElasticSearchService, + OpensearchService, { provide: ConfigService, useValue: mockConfigService, @@ -37,10 +37,10 @@ describe("ElasticSearchService", () => { ], }).compile(); - service = module.get(ElasticSearchService); + service = module.get(OpensearchService); }); - it("should properly load ElasticSearchService", () => { + it("should properly load OpensearchService", () => { expect(service).toBeDefined(); }); }); diff --git a/src/opensearch/opensearch.service.ts b/src/opensearch/opensearch.service.ts new file mode 100644 index 000000000..d2dd82e9f --- /dev/null +++ b/src/opensearch/opensearch.service.ts @@ -0,0 +1,386 @@ +import { + HttpException, + HttpStatus, + Injectable, + Logger, + OnModuleInit, +} from "@nestjs/common"; +import { Client } from "@opensearch-project/opensearch"; + +import { SearchQueryService } from "./providers/query-builder.service"; + +import { + DatasetClass, + DatasetDocument, +} from "src/datasets/schemas/dataset.schema"; +import { ConfigService } from "@nestjs/config"; +import { sleep } from "src/common/utils"; + +import type { IndexSettings } from "@opensearch-project/opensearch/api/_types/indices._common"; +import { ISearchFilter } from "./interfaces/os-common.type"; +import { CreateIndexDto } from "./dto/create-index.dto"; +import { UpdateIndexDto } from "./dto/update-index.dto"; +import type { TypeMapping } from "@opensearch-project/opensearch/api/_types/_common.mapping"; + +@Injectable() +export class OpensearchService implements OnModuleInit { + private osClient: Client; + private host: string; + private username: string; + private password: string; + private refresh: "false" | "wait_for"; + private osConfigs: { + settings: IndexSettings; + mappings: TypeMapping; + } | null; + + public defaultIndex: string; + + constructor( + private readonly searchService: SearchQueryService, + private readonly configService: ConfigService, + ) { + this.host = this.configService.get("opensearch.host") || ""; + this.username = this.configService.get("opensearch.username") || ""; + this.password = this.configService.get("opensearch.password") || ""; + + this.refresh = + this.configService.get<"false" | "wait_for">("opensearch.refresh") || + "false"; + + this.defaultIndex = + this.configService.get("opensearch.defaultIndex") || "dataset"; + + this.osConfigs = + this.configService.get<{ + settings: IndexSettings; + mappings: TypeMapping; + }>("opensearchConfig") || null; + + if (!this.host || !this.username || !this.password || !this.defaultIndex) { + Logger.warn( + `Missing Opensearch configuration for host: ${this.host}, username: ${this.username}, + password: ${this.password} or defaultIndex: ${this.defaultIndex}`, + "Opensearch", + ); + } + if (!this.osConfigs) { + Logger.warn( + `Missing Opensearch index configuration, using default settings and mappings`, + "Opensearch", + ); + } + } + + onModuleInit() { + this.initWithRetry(); + } + + private async connect() { + const connection = new Client({ + node: this.host, + auth: { + username: this.username, + password: this.password, + }, + ssl: { + rejectUnauthorized: false, + }, + }); + + await connection.ping(); + + this.osClient = connection; + } + private async initWithRetry( + maxRetries = 10, + initialDelayMs = 5000, + maxDelayMs = 60000, + ) { + let delayMs = initialDelayMs; + let retryCount = 0; + + while (retryCount < maxRetries) { + try { + await this.connect(); + + const isIndexExists = await this.isIndexExists(this.defaultIndex); + if (!isIndexExists) { + await this.createIndex({ + index: this.defaultIndex, + settings: this.osConfigs?.settings || {}, + mappings: this.osConfigs?.mappings || {}, + }); + Logger.log(`New index ${this.defaultIndex} is created`, "Opensearch"); + } + + Logger.log("Opensearch Connected", "Opensearch"); + return; + } catch (error) { + retryCount++; + Logger.warn( + `Opensearch connection failed (attempt ${retryCount}/${maxRetries}), retrying in ${delayMs / 1000}s...`, + error, + ); + await sleep(delayMs); + delayMs = Math.min(delayMs * 2, maxDelayMs); + } + } + + Logger.error( + `Opensearch failed to connect after ${maxRetries} attempts, running without it`, + "Opensearch", + ); + } + + connected() { + return !!this.osClient; + } + + async isIndexExists(index = this.defaultIndex) { + const { body: indexExists } = await this.osClient.indices.exists({ index }); + return indexExists; + } + + async isPopulated(index = this.defaultIndex) { + const { body } = await this.getCount(index); + + if (body.count > 0) { + return true; + } + Logger.error( + `Opensearch is enabled but index ${index} is empty`, + "Opensearch", + ); + + return false; + } + + async createIndex(createIndexDto: CreateIndexDto) { + const index = createIndexDto.index.trim(); + const { settings, mappings } = createIndexDto; + + try { + const newIndex = await this.osClient.indices.create({ + index, + body: { + settings: settings || this.osConfigs?.settings, + mappings: mappings || this.osConfigs?.mappings, + }, + }); + Logger.log(`Opensearch Index Created-> Index: ${index}`, "Opensearch"); + + return newIndex; + } catch (error) { + throw new HttpException( + `createIndex failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + async syncDatabase(collection: DatasetClass[], index = this.defaultIndex) { + const indexExists = await this.osClient.indices.exists({ index }); + if (!indexExists) { + throw new Error("Index not found"); + } + + const bulkResponse = await this.performBulkOperation(collection, index); + + Logger.log( + JSON.stringify(bulkResponse, null, 0), + "Opensearch Data Synchronization Response", + ); + + return bulkResponse; + } + + async getCount(index = this.defaultIndex) { + try { + return await this.osClient.count({ index }); + } catch (error) { + throw new HttpException( + `getCount failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async updateIndexSettings(updateIndexDto: UpdateIndexDto) { + const index = updateIndexDto.index.trim(); + + try { + await this.osClient.indices.close({ + index, + }); + await this.osClient.indices.putSettings({ + index, + body: { settings: updateIndexDto.settings || this.osConfigs?.settings }, + }); + + await this.osClient.indices.open({ + index, + }); + + const { settings } = await this.getIndexConfig(index); + + return settings; + } catch (error) { + throw new HttpException( + `updateIndexSettings failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async getIndexConfig(index = this.defaultIndex) { + try { + const [settings, mappings] = await Promise.all([ + this.osClient.indices.getSettings({ index }), + this.osClient.indices.getMapping({ index }), + ]); + + return { + settings: settings.body[index].settings, + mappings: mappings.body[index].mappings, + }; + } catch (error) { + throw new HttpException( + `getIndexConfig failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async deleteIndex(index = this.defaultIndex) { + try { + await this.osClient.indices.delete({ index }); + Logger.log(`Opensearch Index Deleted-> Index: ${index} `, "Opensearch"); + return { success: true, message: `Index ${index} deleted` }; + } catch (error) { + throw new HttpException( + `deleteIndex failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async search( + filter: ISearchFilter, + index = this.defaultIndex, + limit = 1000, + skip = 0, + ): Promise<{ totalCount: number; data: (string | undefined)[] }> { + try { + const searchQuery = this.searchService.buildSearchQuery(filter); + const searchOptions = { + track_scores: true, + sort: [{ _score: { order: "desc" } }] as unknown as Record< + string, + unknown + >[], + query: searchQuery.query, + from: skip, + size: limit, + min_score: 0.1, + track_total_hits: true, + _source: [""], + }; + + const { body } = await this.osClient.search({ + index, + body: searchOptions, + }); + + const totalCount = body.hits.hits.length || 0; + + const data = body.hits.hits.map((item) => item._id || ""); + + return { + totalCount, + data, + }; + } catch (error) { + throw new HttpException( + `SearchService || search query issue || -> search ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async updateInsertDocument(data: Partial) { + try { + await this.osClient.index({ + index: this.defaultIndex, + id: data.pid, + body: data, + refresh: this.refresh, + }); + + Logger.log( + `Document Update/inserted-> Document_id: ${data.pid} update/inserted on index: ${this.defaultIndex}`, + "Opensearch", + ); + } catch (error) { + throw new HttpException( + `updateDocument failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async deleteDocument(id: string, index = this.defaultIndex) { + try { + await this.osClient.delete({ + index, + id, + refresh: this.refresh, + }); + Logger.log( + `Document Deleted-> Document_id: ${id} deleted on index: ${index}`, + "Opensearch", + ); + } catch (error) { + throw new HttpException( + `deleteDocument failed-> OpensearchService ${error}`, + HttpStatus.BAD_REQUEST, + ); + } + } + + async checkIndexExists(index: string) { + const { body: indexExists } = await this.osClient.indices.exists({ index }); + + if (!indexExists) { + throw new Error(`Index ${index} not found`); + } + } + + // *** NOTE: below are helper methods *** + + async performBulkOperation( + collection: T[], + index: string, + ) { + const result = await this.osClient.helpers.bulk({ + retries: 5, + wait: 10000, + datasource: collection, + onDocument(doc: T) { + const { _id: mongoId, ...body } = doc; + return [ + { + index: { + _index: index, + _id: mongoId, + }, + }, + body, + ]; + }, + onDrop(doc) { + console.debug(`${doc.document._id}`, doc.error?.reason); + }, + }); + return result; + } +} diff --git a/src/opensearch/opensearch.subject.ts b/src/opensearch/opensearch.subject.ts new file mode 100644 index 000000000..f55619a9f --- /dev/null +++ b/src/opensearch/opensearch.subject.ts @@ -0,0 +1 @@ +export class Opensearch {} diff --git a/src/opensearch/providers/fields.enum.ts b/src/opensearch/providers/fields.enum.ts new file mode 100644 index 000000000..027a3d454 --- /dev/null +++ b/src/opensearch/providers/fields.enum.ts @@ -0,0 +1,4 @@ +export enum MustFields { + DatasetName = "datasetName", + Description = "description", +} diff --git a/src/elastic-search/providers/query-builder.service.spec.ts b/src/opensearch/providers/query-builder.service.spec.ts similarity index 91% rename from src/elastic-search/providers/query-builder.service.spec.ts rename to src/opensearch/providers/query-builder.service.spec.ts index bb65f6bda..d47ade637 100644 --- a/src/elastic-search/providers/query-builder.service.spec.ts +++ b/src/opensearch/providers/query-builder.service.spec.ts @@ -7,18 +7,12 @@ describe("SearchQueryService", () => { const mockSearchQueryWithoutFilters = { text: "fake text", ownerGroup: ["fake"], - creationLocation: ["fake"], - type: ["fake"], - keywords: ["fake"], isPublished: false, }; const mockSearcQueryhWitoutText = { text: "", ownerGroup: ["fake"], - creationLocation: ["fake"], - type: ["fake"], - keywords: ["fake"], isPublished: false, }; diff --git a/src/opensearch/providers/query-builder.service.ts b/src/opensearch/providers/query-builder.service.ts new file mode 100644 index 000000000..7e5455d5a --- /dev/null +++ b/src/opensearch/providers/query-builder.service.ts @@ -0,0 +1,92 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { MustFields } from "./fields.enum"; + +import { QueryContainer } from "@opensearch-project/opensearch/api/_types/_common.query_dsl"; +import { ISearchFilter } from "../interfaces/os-common.type"; + +@Injectable() +export class SearchQueryService { + readonly mustFields = [...Object.values(MustFields)]; + readonly textQuerySplitMethod = /[ ,]+/; + + public buildSearchQuery(filter: ISearchFilter) { + try { + const accessFilter = this.buildFilterFields(filter); + const textQuery = this.buildTextQuery(filter); + + return this.constructFinalQuery(accessFilter, textQuery); + } catch (err) { + Logger.error("Open search build search query failed", err); + throw err; + } + } + private buildFilterFields(fields: ISearchFilter): QueryContainer[] { + const filter: QueryContainer[] = []; + + if (fields.userGroups && fields.userGroups.length > 0) { + filter.push({ + bool: { + should: [ + { terms: { ownerGroup: fields.userGroups } }, + { terms: { accessGroup: fields.userGroups } }, + ], + minimum_should_match: 1, + }, + }); + } + if (fields.isPublished) { + filter.push({ + term: { + isPublished: true, + }, + }); + } + + return filter; + } + + private buildTextQuery(filter: ISearchFilter): QueryContainer[] { + let wildcardQueries: QueryContainer[] = []; + + if (filter.text) { + wildcardQueries = this.buildWildcardQueries(filter.text); + } + + return wildcardQueries.length > 0 + ? [{ bool: { should: wildcardQueries, minimum_should_match: 1 } }] + : []; + } + + private splitSearchText(text: string): string[] { + return text + .toLowerCase() + .trim() + .split(this.textQuerySplitMethod) + .filter(Boolean); + } + + private buildWildcardQueries(text: string): QueryContainer[] { + const terms = this.splitSearchText(text); + return terms.flatMap((term) => + this.mustFields.map((fieldName) => ({ + wildcard: { [fieldName]: { value: `*${term}*` } }, + })), + ); + } + + private constructFinalQuery( + accessFilter: QueryContainer[], + textQuery: QueryContainer[], + ) { + const finalQuery = { + query: { + bool: { + filter: accessFilter, + must: textQuery, + }, + }, + }; + + return finalQuery; + } +} diff --git a/src/opensearch/utils/dataset-opensearch.utils.ts b/src/opensearch/utils/dataset-opensearch.utils.ts new file mode 100644 index 000000000..210cc8e99 --- /dev/null +++ b/src/opensearch/utils/dataset-opensearch.utils.ts @@ -0,0 +1,16 @@ +// It controlles which fields of the dataset document should be included +// when sending it to Opensearch. +export const DATASET_OPENSEARCH_FIELDS = [ + "pid", + "description", + "datasetName", + "isPublished", + "ownerGroup", + "accessGroups", +] as const; + +// OUTPUT EXAMPLE: +// { description: 1, datasetName: 1, isPublished: 1, ownerGroup: 1, accessGroups: 1 } +export const DATASET_OPENSEARCH_PROJECTION = Object.fromEntries( + DATASET_OPENSEARCH_FIELDS.map((key) => [key, 1]), +); diff --git a/src/policies/policies.service.spec.ts b/src/policies/policies.service.spec.ts index 9ca0c1877..0fd9ca384 100644 --- a/src/policies/policies.service.spec.ts +++ b/src/policies/policies.service.spec.ts @@ -56,7 +56,7 @@ describe("PoliciesService", () => { ], }).compile(); - service = module.get(PoliciesService); + service = await module.resolve(PoliciesService); policyModel = module.get>(getModelToken("Policy")); }); diff --git a/src/published-data/published-data.controller.spec.ts b/src/published-data/published-data.controller.spec.ts index b17ec39b3..accf61202 100644 --- a/src/published-data/published-data.controller.spec.ts +++ b/src/published-data/published-data.controller.spec.ts @@ -38,7 +38,9 @@ describe("PublishedDataController", () => { ], }).compile(); - controller = module.get(PublishedDataController); + controller = await module.resolve( + PublishedDataController, + ); }); it("should be defined", () => { diff --git a/test/DatasetV4.js b/test/DatasetV4.js index 36bb6aed0..6755a54cb 100644 --- a/test/DatasetV4.js +++ b/test/DatasetV4.js @@ -314,7 +314,7 @@ describe("2500: Datasets v4 tests", () => { it("0126: adds a new dataset with scientificMetadata", async () => { return request(appUrl) .post("/api/v4/datasets") - .send(TestData.ScientificMetadataForElasticSearchV4) + .send(TestData.DatasetWithScientificMetadataV4) .auth(accessTokenAdminIngestor, { type: "bearer" }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) @@ -331,7 +331,7 @@ describe("2500: Datasets v4 tests", () => { it("0127: should be able to add a new dataset with non-empty datasetLifecycle", async () => { const newDataset = { - ...TestData.ScientificMetadataForElasticSearchV4, + ...TestData.DatasetWithScientificMetadataV4, datasetlifecycle: { archivable: false, retrievable: true, @@ -423,7 +423,7 @@ describe("2500: Datasets v4 tests", () => { .send(proposalBody) .auth(accessTokenAdminIngestor, { type: "bearer" }); const proposalId = proposalRes.body.proposalId; - + const dataset = { ...TestData.DerivedCorrectMinV4, proposalIds: [proposalId], @@ -442,7 +442,7 @@ describe("2500: Datasets v4 tests", () => { .post("/api/v4/datasets") .send({ ...TestData.DerivedCorrectMinV4, proposalIds: [] }) .auth(accessTokenAdminIngestor, { type: "bearer" }); - + const res2 = await request(appUrl) .post("/api/v4/datasets") .send({ ...TestData.DerivedCorrectMinV4 }) @@ -458,9 +458,14 @@ describe("2500: Datasets v4 tests", () => { const proposalAfter = await request(appUrl) .get(`/api/v3/proposals/${encodeURIComponent(proposalId)}`) .auth(accessTokenAdminIngestor, { type: "bearer" }); - console.log("DEBUG numberOfDatasets: ", proposalAfter.body.numberOfDatasets); + console.log( + "DEBUG numberOfDatasets: ", + proposalAfter.body.numberOfDatasets, + ); console.log("DEBUG initialCount: ", initialCount); - proposalAfter.body.should.have.property("numberOfDatasets").and.equal(initialCount); + proposalAfter.body.should.have + .property("numberOfDatasets") + .and.equal(initialCount); }); }); @@ -775,13 +780,15 @@ describe("2500: Datasets v4 tests", () => { it("0211: should fetch dataset relation fields if provided in the filter as obj and add scopes", async () => { const filter = { where: { pid: derivedDatasetMinPid }, - include: [{ - relation: "instruments", - scope: { - where: - { uniqueName: TestData.InstrumentCorrect1.uniqueName }, fields: ["uniqueName"] - } - }], + include: [ + { + relation: "instruments", + scope: { + where: { uniqueName: TestData.InstrumentCorrect1.uniqueName }, + fields: ["uniqueName"], + }, + }, + ], }; const instrument1 = await request(appUrl) @@ -790,7 +797,7 @@ describe("2500: Datasets v4 tests", () => { .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) + .expect("Content-Type", /json/); const instrument2 = await request(appUrl) .post("/api/v3/Instruments") @@ -798,7 +805,7 @@ describe("2500: Datasets v4 tests", () => { .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) + .expect("Content-Type", /json/); await request(appUrl) .patch(`/api/v4/datasets/${encodeURIComponent(derivedDatasetMinPid)}`) @@ -818,18 +825,19 @@ describe("2500: Datasets v4 tests", () => { const [firstDataset] = res.body; firstDataset.should.have.property("pid"); - firstDataset.should.have.property("instruments").eql([{ - _id: instrument1.body.id, - uniqueName: TestData.InstrumentCorrect1.uniqueName - }] - ); + firstDataset.should.have.property("instruments").eql([ + { + _id: instrument1.body.id, + uniqueName: TestData.InstrumentCorrect1.uniqueName, + }, + ]); firstDataset.should.not.have.property("datablocks"); }); }); it("0212: should fetch specific dataset fields excluding fields provided in field", async () => { const filter = { - fields: {datasetName: 0, contactEmail: 1}, + fields: { datasetName: 0, contactEmail: 1 }, }; return request(appUrl) @@ -1096,7 +1104,9 @@ describe("2500: Datasets v4 tests", () => { .then((res) => { res.body.should.be.a("object"); res.body.should.have.property("message"); - res.body.message.should.match(/Invalid \$project :: caused by :: Path collision at origdatablocks/); + res.body.message.should.match( + /Invalid \$project :: caused by :: Path collision at origdatablocks/, + ); }); }); }); diff --git a/test/ElasticSearch.js b/test/ElasticSearch.js deleted file mode 100644 index 3742493d1..000000000 --- a/test/ElasticSearch.js +++ /dev/null @@ -1,254 +0,0 @@ -"use strict"; -const { faker } = require("@faker-js/faker"); -const utils = require("./LoginUtils"); -const { TestData } = require("./TestData"); -require("dotenv").config(); - -let accessTokenAdminIngestor = null, - accessTokenArchiveManager = null, - - pid = null; - -const isESenabled = process.env.ELASTICSEARCH_ENABLED == "yes"; - -const Relation = { - GREATER_THAN: "GREATER_THAN", - LESS_THAN: "LESS_THAN", - EQUAL_TO_NUMERIC: "EQUAL_TO_NUMERIC", - EQUAL_TO_STRING: "EQUAL_TO_STRING", -}; - -const scientificMetadataFieldName = { - keyValue: "with_key_value", - unitAndValue: "with_unit_and_value_si", - number: "with_number", - string: "with_string", -}; - -const scientificMetadata = (values) => { - const scientificQuery = values.map((value) => { - return { - lhs: value.lhs, - relation: value.relation, - rhs: value.rhs, - unit: value.unit, - }; - }); - - return { - scientific: scientificQuery, - }; -}; - -(isESenabled ? describe : describe.skip)( - "ElastiSearch: CRUD, filtering and search test case", - () => { - before(async () => { - db.collection("Dataset").deleteMany({}); - - accessTokenAdminIngestor = await utils.getToken(appUrl, { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }); - - accessTokenArchiveManager = await utils.getToken(appUrl, { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }); - }); - - it("0010: adds a new raw dataset with scientificMetadata", async () => { - return request(appUrl) - .post("/api/v3/Datasets") - .send(TestData.ScientificMetadataForElasticSearch) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have - .property("scientificMetadata") - .which.is.an("object") - .that.has.all.keys( - scientificMetadataFieldName.keyValue, - scientificMetadataFieldName.unitAndValue, - scientificMetadataFieldName.number, - scientificMetadataFieldName.string, - ); - pid = encodeURIComponent(res.body["pid"]); - }); - }); - - it("0020: should fetch dataset with correct unitSI and ValueSI condition for scientific filter", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send( - scientificMetadata([ - { - lhs: scientificMetadataFieldName.unitAndValue, - relation: Relation.GREATER_THAN, - rhs: 99, - unit: "mbar l/s/cm^2", - }, - { - lhs: scientificMetadataFieldName.unitAndValue, - relation: Relation.EQUAL_TO_NUMERIC, - rhs: 100, - unit: "mbar l/s/cm^2", - }, - { - lhs: scientificMetadataFieldName.unitAndValue, - relation: Relation.LESS_THAN, - rhs: 101, - unit: "mbar l/s/cm^2", - }, - ]), - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.include(decodeURIComponent(pid)); - }); - }); - - it("0027: should fetch dataset with correct numeric value for scientific filter", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send( - scientificMetadata([ - { - lhs: scientificMetadataFieldName.number, - relation: Relation.EQUAL_TO_NUMERIC, - rhs: 111, - unit: "", - }, - ]), - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.include(decodeURIComponent(pid)); - }); - }); - - it("0028: should fetch dataset with correct string value for the scientific filter", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send( - scientificMetadata([ - { - lhs: scientificMetadataFieldName.string, - relation: Relation.EQUAL_TO_STRING, - rhs: "222", - unit: "", - }, - ]), - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.include(decodeURIComponent(pid)); - }); - }); - - it("0029: should fail when fetching dataset with incorrect relation type and value type for the scientific filter", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send( - scientificMetadata([ - { - lhs: scientificMetadataFieldName.number, - relation: Relation.EQUAL_TO_NUMERIC, - rhs: "111", - unit: "", - }, - ]), - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.be.length(0); - }); - }); - - it("0030: should fetching dataset with correct proposalIds and size", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send({ - proposalIds: TestData.ScientificMetadataForElasticSearch.proposalId, - size: TestData.ScientificMetadataForElasticSearch.size, - }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.include(decodeURIComponent(pid)); - }); - }); - - it("0031: should fail fetching dataset with correct proposalIds but wrong size", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send({ - proposalIds: [TestData.ScientificMetadataForElasticSearch.proposalId], - size: faker.number.int({ min: 100000001, max: 100400000 }), - }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.be.length(0); - }); - }); - it("0032: should fail fetching dataset with wrong proposalIds but correct size", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send({ - proposalIds: ["wrongProposalId"], - size: TestData.ScientificMetadataForElasticSearch.size, - }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.be.length(0); - }); - }); - - it("0033: should fail fetching dataset with incorrect proposalIds and size", async () => { - return request(appUrl) - .post("/api/v3/elastic-search/search") - .send({ - proposalIds: ["wrongProposalId"], - size: faker.number.int({ min: 100000001, max: 100400000 }), - }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPostStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.data.should.be.length(0); - }); - }); - - it("0034: should delete this raw dataset", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + pid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - }, -); diff --git a/test/OpenSearch.js b/test/OpenSearch.js new file mode 100644 index 000000000..d8e645dad --- /dev/null +++ b/test/OpenSearch.js @@ -0,0 +1,249 @@ +"use strict"; +const { faker } = require("@faker-js/faker"); +const utils = require("./LoginUtils"); +const { TestData } = require("./TestData"); +require("dotenv").config(); + +let accessTokenAdminIngestor = null, + accessTokenArchiveManager = null, + pid1 = null, + pid2 = null; + +const commonName = "common"; + +const datasetName1 = `XRD_Si02_Beam3_2024A_thetaScan_dSpacing3.14_run07 ${commonName}`; +const datasetName2 = `Neutron_CeO2_400K_P12bar_timeOfFlight_lambda1.8_seq42 ${commonName}`; + +const datasetName1Tokens = [ + "XRD", + "Si02", + "Beam3", + "2024A", + "thetaScan", + "dSpacing3.14", + "run07", +]; +const datasetName2Tokens = [ + "Neutron", + "CeO2", + "400K", + "P12bar", + "timeOfFlight", + "lambda1.8", + "seq42", +]; + +const randomToken1 = + datasetName1Tokens[Math.floor(Math.random() * datasetName1Tokens.length)]; +const randomToken2 = + datasetName2Tokens[Math.floor(Math.random() * datasetName2Tokens.length)]; + +const isOSenabled = process.env.OPENSEARCH_ENABLED == "yes"; + +(isOSenabled ? describe : describe.skip)( + "Opensearch: CRUD, filtering and search test case", + () => { + before(async () => { + db.collection("Dataset").deleteMany({}); + + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); + }); + + it("0010: adds a new raw dataset -1 ", async () => { + const dataset1 = { + ...TestData.DatasetWithScientificMetadata, + datasetName: datasetName1, + isPublished: true, + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(dataset1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + pid1 = encodeURIComponent(res.body["pid"]); + }); + }); + + it("0011: adds a new raw dataset -2 ", async () => { + const dataset2 = { + ...TestData.DatasetWithScientificMetadata, + datasetName: datasetName2, + isPublished: true, + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(dataset2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + pid2 = encodeURIComponent(res.body["pid"]); + }); + }); + + it("0020: finds the dataset1 by partial text search", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: randomToken1 }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .expect(200) + .then((res) => { + const found = res.body.some((d) => d.datasetName === datasetName1); + found.should.equal(true); + }); + }); + + it("0021: finds the dataset2 by partial text search", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: randomToken2 }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .expect(200) + .then((res) => { + const found = res.body.some((d) => d.datasetName === datasetName2); + found.should.equal(true); + }); + }); + + it("0022: finds the dataset1 by full text search", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: datasetName1 }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .expect(200) + .then((res) => { + const found = res.body.some((d) => d.datasetName === datasetName2); + found.should.equal(true); + }); + }); + + it("0023: finds the dataset2 by full text search", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: datasetName2 }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .expect(200) + .then((res) => { + const found = res.body.some((d) => d.datasetName === datasetName2); + found.should.equal(true); + }); + }); + + it("0024: finds both datasets by shared common text", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: commonName }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(200) + .then((res) => { + const foundDataset1 = res.body.some( + (d) => d.datasetName === datasetName1, + ); + const foundDataset2 = res.body.some( + (d) => d.datasetName === datasetName2, + ); + foundDataset1.should.equal(true); + foundDataset2.should.equal(true); + }); + }); + + it("0025: should finds both datasets by shared common text", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: commonName }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(200) + .then((res) => { + const foundDataset1 = res.body.some( + (d) => d.datasetName === datasetName1, + ); + const foundDataset2 = res.body.some( + (d) => d.datasetName === datasetName2, + ); + foundDataset1.should.equal(true); + foundDataset2.should.equal(true); + }); + }); + + it("0026: returns no datasets for irrelevant search text", async () => { + return request(appUrl) + .get("/api/v3/datasets/fullquery") + .query({ + fields: JSON.stringify({ text: "shouldnotmatchanything" }), + limits: JSON.stringify({ + skip: 0, + limit: 10, + }), + }) + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(200) + .then((res) => { + res.body.length.should.equal(0); + }); + }); + + it("0034: should delete dataset1", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + pid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0035: should delete dataset2", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + pid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + }, +); diff --git a/test/TestData.js b/test/TestData.js index 36280b8bd..aa6a59de9 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -1,6 +1,6 @@ "use strict"; const { faker } = require("@faker-js/faker"); -const _ = require("lodash") +const _ = require("lodash"); const RawTestAccounts = require("../test/config/functionalAccounts.json"); const TestAccounts = Object.fromEntries( @@ -335,15 +335,13 @@ const TestData = { publishedOn: "JEST_ANY", retrievable: false, retrieveIntegrityCheck: false, - retrieveStatusMessage: "" + retrieveStatusMessage: "", }, description: "None, The ultimate test", endTime: "JEST_ANY", inputDatasets: [], instrumentId: "1f016ec4-7a73-11ef-ae3e-439013069377", - instrumentIds: [ - "1f016ec4-7a73-11ef-ae3e-439013069377" - ], + instrumentIds: ["1f016ec4-7a73-11ef-ae3e-439013069377"], isPublished: false, keywords: ["sls", "protein"], license: "CC BY-SA 4.0", @@ -355,20 +353,14 @@ const TestData = { ownerGroup: "p13388", packedSize: 0, pid: "JEST_ANY", - principalInvestigators: [ - "scicatingestor@your.site" - ], + principalInvestigators: ["scicatingestor@your.site"], principalInvestigator: "scicatingestor@your.site", proposalId: "JEST_ANY", - proposalIds: [ - "JEST_ANY" - ], + proposalIds: ["JEST_ANY"], relationships: [], runNumber: "123456", sampleId: "20c32b4e-7a73-11ef-9aec-5b9688aa3791i", - sampleIds: [ - "20c32b4e-7a73-11ef-9aec-5b9688aa3791i" - ], + sampleIds: ["20c32b4e-7a73-11ef-9aec-5b9688aa3791i"], scientificMetadata: { File_Prefix: "817b_B2_", approx_distance_range: { @@ -376,43 +368,43 @@ const TestData = { unit: "cm", unitSI: "m", value: [1, 2], - valueSI: [0.01, 0.02] + valueSI: [0.01, 0.02], }, approx_file_size_mb: { unit: "", - value: 8500 + value: 8500, }, beamlineParameters: { "Beam energy": { u: "eV", v: 22595, unitSI: "(kg m^2) / s^2", - valueSI: 3.6201179486175005e-15 + valueSI: 3.6201179486175005e-15, }, Monostripe: "Ru/C", "Ring current": { u: "A", v: 0.402246, unitSI: "A", - valueSI: 0.402246 - } + valueSI: 0.402246, + }, }, detectorParameters: { "Exposure time": { u: "s", v: 0.4, unitSI: "s", - valueSI: 0.4 + valueSI: 0.4, }, Objective: 20, - Scintillator: "LAG 20um" + Scintillator: "LAG 20um", }, scanParameters: { "Angular step": { u: "deg", v: 0.1, unitSI: "rad", - valueSI: 0.0017453292519943296 + valueSI: 0.0017453292519943296, }, "File Prefix": "817b_B2_", "Flat frequency": 0, @@ -425,28 +417,28 @@ const TestData = { u: "deg", v: 180, unitSI: "rad", - valueSI: 3.141592653589793 + valueSI: 3.141592653589793, }, "Rot Y min position": { u: "deg", v: 0, unitSI: "rad", - valueSI: 0 + valueSI: 0, }, "Sample In": { u: "m", v: 0, unitSI: "m", - valueSI: 0 + valueSI: 0, }, "Sample Out": { u: "m", v: -0.005, unitSI: "m", - valueSI: -0.005 + valueSI: -0.005, }, - "Sample folder": "/ramjet/817b_B2_" - } + "Sample folder": "/ramjet/817b_B2_", + }, }, sharedWith: [], size: 0, @@ -1425,7 +1417,7 @@ const TestData = { dataQualityMetrics: "test", }, - ScientificMetadataForElasticSearch: { + DatasetWithScientificMetadata: { ownerGroup: faker.company.name(), creationLocation: faker.location.city(), principalInvestigator: faker.internet.username(), @@ -1456,7 +1448,7 @@ const TestData = { }, }, - ScientificMetadataForElasticSearchV4: { + DatasetWithScientificMetadataV4: { ownerGroup: faker.company.name(), creationLocation: faker.location.city(), type: "raw", @@ -1493,10 +1485,9 @@ const TestData = { }, }; -const isEqualWithAny = (actual, expected) => +const isEqualWithAny = (actual, expected) => _.isEqualWith(actual, expected, (actualValue, expectedValue) => { - if (expectedValue === "JEST_ANY") - return true; -}); + if (expectedValue === "JEST_ANY") return true; + }); module.exports = { TestData, isEqualWithAny }; diff --git a/test/config/.env b/test/config/.env index ae29b1da9..e7b09a5ca 100644 --- a/test/config/.env +++ b/test/config/.env @@ -28,14 +28,10 @@ DOI_PREFIX="10.17199/" REGISTER_DOI_URI="https://api.test.datacite.org/dois" REGISTER_DOI_URI_V3="https://mds.test.datacite.org/doi" -ES_HOST=https://localhost:9200 -ES_USERNAME=elastic -ES_PASSWORD=duo-password -MONGODB_COLLECTION=Dataset -ES_MAX_RESULT=10000 -ES_FIELDS_LIMIT=1000 -ES_INDEX=dataset -ES_REFRESH=wait_for + +OPENSEARCH_HOST=https://localhost:9200 +OPENSEARCH_PASSWORD=Scicat_default_password_2026 +OPENSEARCH_REFRESH="wait_for" #history TRACKABLE_STRATEGY=delta From 850ac9000bb977c99768ed359dd9c95a0f683074 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 07:43:47 +0000 Subject: [PATCH 094/120] build(deps): bump nodemailer from 8.0.3 to 8.0.4 Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 8.0.3 to 8.0.4. - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v8.0.3...v8.0.4) --- updated-dependencies: - dependency-name: nodemailer dependency-version: 8.0.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 207 ---------------------------------------------- 1 file changed, 207 deletions(-) diff --git a/package-lock.json b/package-lock.json index cba1b1aab..4a5eb64d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -226,40 +226,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics-cli/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -315,40 +281,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -2732,110 +2664,6 @@ } } }, - "node_modules/@nestjs-modules/mailer/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/nunjucks": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", - "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", - "license": "BSD-2-Clause", - "optional": true, - "dependencies": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - }, - "bin": { - "nunjucks-precompile": "bin/precompile" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "chokidar": "^3.3.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/@nestjs/axios": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", @@ -3417,40 +3245,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@nestjs/schematics/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nestjs/schematics/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@nestjs/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -3684,7 +3478,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" From 3e737994b70537e508d8402622be66d993482b4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 07:46:21 +0000 Subject: [PATCH 095/120] build(deps): bump handlebars from 4.7.8 to 4.7.9 Bumps [handlebars](https://github.com/handlebars-lang/handlebars.js) from 4.7.8 to 4.7.9. - [Release notes](https://github.com/handlebars-lang/handlebars.js/releases) - [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.9/release-notes.md) - [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9) --- updated-dependencies: - dependency-name: handlebars dependency-version: 4.7.9 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a5eb64d8..4d05f8b9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8745,9 +8745,9 @@ "license": "ISC" }, "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "license": "MIT", "dependencies": { "minimist": "^1.2.5", From ec5d4fec18d4e1e93b541e307eb0d69c6c903ff4 Mon Sep 17 00:00:00 2001 From: fpotier <58594145+fpotier@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:14:57 +0200 Subject: [PATCH 096/120] feat(publish): add support for ajv custom dynamicDefaults and keywords (#2569) --- README.md | 2 + ajvCustomDefinitions.example.js | 41 ++++ docs/developer-guide/ajv-extensions.md | 84 ++++++++ package-lock.json | 6 +- package.json | 4 +- publishedDataConfig.example.json | 1 + src/config/configuration.ts | 7 +- .../interfaces/published-data.interface.ts | 10 +- src/published-data/published-data.module.ts | 7 +- src/published-data/published-data.service.ts | 7 - .../published-data.v4.controller.spec.ts | 4 + .../published-data.v4.controller.ts | 59 +++--- src/published-data/validator.service.spec.ts | 190 ++++++++++++++++++ src/published-data/validator.service.ts | 158 +++++++++++++++ test/PublishedDataV4.js | 46 +++-- 15 files changed, 563 insertions(+), 63 deletions(-) create mode 100644 ajvCustomDefinitions.example.js create mode 100644 docs/developer-guide/ajv-extensions.md create mode 100644 src/published-data/validator.service.spec.ts create mode 100644 src/published-data/validator.service.ts diff --git a/README.md b/README.md index 98a0c3570..3ad25fd6c 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,8 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `DOI_SHORT_SUFFIX` | string | | By default `uuidv4` is used to generate the DOI suffix but if this flag is `true` the shorter version of 10 random characters is used as DOI suffix. | | | `DOI_USERNAME` | string | | The facility DOI DataCite username. | | | `DOI_PASSWORD` | string | | The facility DOI DataCite password. | | +| `PUBLISHED_DATA_CONFIG_FILE` | string | | Path to the file containing the metadata and UI schemas for PublishedData. | `"publishedDataConfig.json"` | +| `AJV_CUSTOM_DEFINITIONS_FILE` | string | | The path to a JavaScript module that defines custom AJV keywords or dynamic defaults functions. | | | `EXPRESS_SESSION_SECRET` | string | No | Secret used to set up express session. Required if using OIDC authentication | | | `EXPRESS_SESSION_STORE` | string | Yes | Where to store the express session. When "mongo" on mongo else in memory | | | `HTTP_MAX_REDIRECTS` | number | Yes | Max redirects for HTTP requests. | 5 | diff --git a/ajvCustomDefinitions.example.js b/ajvCustomDefinitions.example.js new file mode 100644 index 000000000..b97434bd6 --- /dev/null +++ b/ajvCustomDefinitions.example.js @@ -0,0 +1,41 @@ +keywords = [ + // Automatically sets the name property based on givenName and familyName + { + keyword: "setFullName", + schema: false, + modifying: true, + validate: function (data, dataCxt) { + data.name = + data.givenName && data.familyName + ? `${data.familyName}, ${data.givenName}` + : data.givenName || data.familyName || undefined; + return true; + }, + }, +]; + +// Computes the sum of all datasets size in DataCite format +async function computeTotalSize(ctx) { + const datasets = await ctx.datasetsService.findAll({ + where: { + $or: ctx.publishedData.datasetPids.map((p) => ({ + pid: p, + })), + }, + }); + + return () => { + if (!datasets) return; + + return [datasets.reduce((acc, ds) => acc + (ds.size ?? 0), 0).toString()]; + }; +} + +const dynamicDefaults = new Map([ + ["computeTotalSize", computeTotalSize], +]); + +module.exports = { + keywords, + dynamicDefaults, +}; diff --git a/docs/developer-guide/ajv-extensions.md b/docs/developer-guide/ajv-extensions.md new file mode 100644 index 000000000..e071649b0 --- /dev/null +++ b/docs/developer-guide/ajv-extensions.md @@ -0,0 +1,84 @@ +# Extending Ajv + +## Overview + +SciCat uses the [Ajv library](https://ajv.js.org/) to validate metadata for `PublishedData` objects against the configured JSON Schema. + +Ajv provides mechanisms to overcome some limitations of JSON Schema by allowing to register custom code to be run during the validation process. + +SciCat backend can load an external javascript module containing facility-specific code at runtime and execute it during validation. + +Supported features: +- registering new [keywords](https://ajv.js.org/keywords.html) +- registering new [dynamicDefaults functions](https://ajv.js.org/packages/ajv-keywords.html#dynamicdefaults) + +## Writing your own extensions + +Custom code will be loaded as a [Javascript Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) by the backend. + +To load a module, define the `AJV_CUSTOM_DEFINITIONS_FILE` environment variable with the path to your module. + +It should export two symbols: +- `keywords` an array of custom keyword definitions +- `dynamicDefaults` a map of function name / function + +see [the example file](../../ajvCustomDefinitions.example.js). + +⚠️ Ajv expects higher-order functions (i.e., a function that returns another function). + +### Synchronous functions + +If a function is synchronous, it will simply be registered in ajv and its execution is entirely delegated to the library. + +Example: +```js +export const dynamicDefaults = new Map([ + ["mySyncDynamicDefault", () => () => Math.random()] +]); +``` + +### Asynchronous functions + +If you need to execute asynchronous code, you should declare your function `async` (only supported for dynamicDefaults). +It should return a synchronous function as ajv will not resolve any `Promise` returned by custom code. + +Asynchronous functions have access to additional context via the `ctx` argument: +- The `PublishedData` instance being validated +- Read-only access to the following services: `ProposalsService`, `DatasetsService` and `AttachmentsService` + +Currently only the following methods are supported on read-only services: +- `findOne` +- `findAll` +- `count` + +Example: +```js +export const dynamicDefaults = new Map([ + [ + "mergeKeywords", + async (ctx) => { + // Make async DB access + // This will be executed by the ValidatorService + const datasets = await ctx.datasetsService.findAll({ + where: { + $or: ctx.publishedData.datasetPids.map((p) => ({ + pid: p, + })), + }, + }); + + // Return a synchronous function processing data fetched from the DB + // This will be executed by ajv + return () => { + if (!datasets) return; + + const uniqueKeywords = new Set(datasets.flatMap((ds) => ds.keywords || [])); + return Array.from(uniqueKeywords).map((k) => ({ + subject: k, + lang: "en", + })); + }; + }, + ], +]); +``` diff --git a/package-lock.json b/package-lock.json index 4d05f8b9c..37ab8b944 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,9 @@ "@types/jsonschema": "^1.1.1", "@user-office-software/duo-logger": "^2.1.1", "@user-office-software/duo-message-broker": "^1.4.0", - "ajv": "^8.12.0", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "ajv-keywords": "^5.1.0", "amqplib": "^0.10.5", "bcrypt": "^6.0.0", "class-transformer": "^0.5.1", @@ -5133,7 +5135,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -5151,7 +5152,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" diff --git a/package.json b/package.json index 68246c718..12c063e81 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,9 @@ "@types/jsonschema": "^1.1.1", "@user-office-software/duo-logger": "^2.1.1", "@user-office-software/duo-message-broker": "^1.4.0", - "ajv": "^8.12.0", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "ajv-keywords": "^5.1.0", "amqplib": "^0.10.5", "bcrypt": "^6.0.0", "class-transformer": "^0.5.1", diff --git a/publishedDataConfig.example.json b/publishedDataConfig.example.json index 6d09b4286..ab4458dad 100644 --- a/publishedDataConfig.example.json +++ b/publishedDataConfig.example.json @@ -1,6 +1,7 @@ { "metadataSchema": { "type": "object", + "dynamicDefaults": { "publicationYear": "currentYear" }, "properties": { "creators": { "type": "array", diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 3bb154bab..6d50a13e0 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -1,9 +1,9 @@ import * as fs from "fs"; import { merge } from "lodash"; -import localconfiguration from "./localconfiguration"; import { boolean } from "mathjs"; -import { DEFAULT_PROPOSAL_TYPE } from "src/proposals/schemas/proposal.schema"; import { DatasetType } from "src/datasets/types/dataset-type.enum"; +import { DEFAULT_PROPOSAL_TYPE } from "src/proposals/schemas/proposal.schema"; +import localconfiguration from "./localconfiguration"; const configuration = () => { const accessGroupsStaticValues = @@ -64,6 +64,8 @@ const configuration = () => { const jobConfigurationFile = process.env.JOB_CONFIGURATION_FILE || ""; + const ajvCustomDefinitions = process.env.AJV_CUSTOM_DEFINITIONS_FILE || ""; + const defaultLogger = { type: "DefaultLogger", modulePath: "./loggingProviders/defaultLogger", @@ -434,6 +436,7 @@ const configuration = () => { frontendConfig: jsonConfigMap.frontendConfig, frontendTheme: jsonConfigMap.frontendTheme, publishedDataConfig: jsonConfigMap.publishedDataConfig, + ajvCustomDefinitions: ajvCustomDefinitions, opensearchConfig: jsonConfigMap.opensearchConfig, }; return merge(config, localconfiguration); diff --git a/src/published-data/interfaces/published-data.interface.ts b/src/published-data/interfaces/published-data.interface.ts index 7eda17f50..c1e77ffdc 100644 --- a/src/published-data/interfaces/published-data.interface.ts +++ b/src/published-data/interfaces/published-data.interface.ts @@ -1,7 +1,7 @@ import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; import { FilterQuery } from "mongoose"; -import { PublishedDataDocument } from "../schemas/published-data.schema"; import { ILimitsFilter } from "src/common/interfaces/common.interface"; +import { PublishedDataDocument } from "../schemas/published-data.schema"; export interface IPublishedDataFilters { where?: FilterQuery; @@ -32,6 +32,9 @@ export class FormPopulateData { @ApiPropertyOptional() thumbnail?: string; + + @ApiPropertyOptional() + metadata?: object; } export interface IRegister { @@ -44,3 +47,8 @@ export enum PublishedDataStatus { REGISTERED = "registered", AMENDED = "amended", } + +export interface PublishedDataConfig { + metadataSchema: unknown; + uiSchema: unknown; +} diff --git a/src/published-data/published-data.module.ts b/src/published-data/published-data.module.ts index 3878ac7bd..657caf892 100644 --- a/src/published-data/published-data.module.ts +++ b/src/published-data/published-data.module.ts @@ -4,6 +4,7 @@ import { ConfigModule, ConfigService } from "@nestjs/config"; import { MongooseModule } from "@nestjs/mongoose"; import { AttachmentsModule } from "src/attachments/attachments.module"; import { CaslModule } from "src/casl/casl.module"; +import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; import { DatasetsModule } from "src/datasets/datasets.module"; import { ProposalsModule } from "src/proposals/proposals.module"; import { @@ -12,12 +13,12 @@ import { } from "../common/schemas/generic-history.schema"; import { PublishedDataController } from "./published-data.controller"; import { PublishedDataService } from "./published-data.service"; +import { PublishedDataV4Controller } from "./published-data.v4.controller"; import { PublishedData, PublishedDataSchema, } from "./schemas/published-data.schema"; -import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util"; -import { PublishedDataV4Controller } from "./published-data.v4.controller"; +import { ValidatorService } from "./validator.service"; @Module({ imports: [ @@ -65,6 +66,6 @@ import { PublishedDataV4Controller } from "./published-data.v4.controller"; ProposalsModule, ], controllers: [PublishedDataController, PublishedDataV4Controller], - providers: [PublishedDataService], + providers: [PublishedDataService, ValidatorService], }) export class PublishedDataModule {} diff --git a/src/published-data/published-data.service.ts b/src/published-data/published-data.service.ts index d3d929fbf..22fc4f3a8 100644 --- a/src/published-data/published-data.service.ts +++ b/src/published-data/published-data.service.ts @@ -67,13 +67,6 @@ export class PublishedDataService { ), ); - if ( - createdPublished.metadata && - !createdPublished.metadata.publicationYear - ) { - createdPublished.metadata.publicationYear = new Date().getFullYear(); - } - return createdPublished.save(); } diff --git a/src/published-data/published-data.v4.controller.spec.ts b/src/published-data/published-data.v4.controller.spec.ts index eb3fa3974..44cc1fa1e 100644 --- a/src/published-data/published-data.v4.controller.spec.ts +++ b/src/published-data/published-data.v4.controller.spec.ts @@ -9,6 +9,7 @@ import { ProposalsService } from "src/proposals/proposals.service"; import { PublishedDataService } from "./published-data.service"; import { PublishedDataV4Controller } from "./published-data.v4.controller"; import { PublishedData } from "./schemas/published-data.schema"; +import { ValidatorService } from "./validator.service"; class AttachmentsServiceMock {} @@ -23,6 +24,8 @@ class PublishedDataServiceMock {} class CaslAbilityFactoryMock {} +class ValidatorServiceMock {} + class ConfigServiceMock { get(key: string) { const config = { @@ -69,6 +72,7 @@ describe("PublishedDataController", () => { { provide: PublishedDataService, useClass: PublishedDataServiceMock }, { provide: CaslAbilityFactory, useClass: CaslAbilityFactoryMock }, { provide: ConfigService, useClass: ConfigServiceMock }, + { provide: ValidatorService, useClass: ValidatorServiceMock }, ], }).compile(); diff --git a/src/published-data/published-data.v4.controller.ts b/src/published-data/published-data.v4.controller.ts index 79346a164..6ed23c5c0 100644 --- a/src/published-data/published-data.v4.controller.ts +++ b/src/published-data/published-data.v4.controller.ts @@ -25,7 +25,7 @@ import { ApiTags, } from "@nestjs/swagger"; import { Request } from "express"; -import { Validator } from "jsonschema"; +import { cloneDeep } from "lodash"; import { FilterQuery, QueryOptions } from "mongoose"; import { firstValueFrom } from "rxjs"; import { AttachmentsService } from "src/attachments/attachments.service"; @@ -36,6 +36,7 @@ import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; import { AuthenticatedPoliciesGuard } from "src/casl/guards/auth-check.guard"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; +import { ILimitsFilter } from "src/common/interfaces/common.interface"; import { handleAxiosRequestError } from "src/common/utils"; import { DatasetsService } from "src/datasets/datasets.service"; import { DatasetsV4Controller } from "src/datasets/datasets.v4.controller"; @@ -50,15 +51,14 @@ import { IRegister, PublishedDataStatus, } from "./interfaces/published-data.interface"; +import { V4_FILTER_PIPE } from "./pipes/filter.pipe"; import { RegisteredFilterPipe } from "./pipes/registered.pipe"; import { PublishedDataService } from "./published-data.service"; import { PublishedData, PublishedDataDocument, } from "./schemas/published-data.schema"; -import { V4_FILTER_PIPE } from "./pipes/filter.pipe"; -import { ILimitsFilter } from "src/common/interfaces/common.interface"; -import { cloneDeep } from "lodash"; +import { ValidatorService } from "./validator.service"; @ApiBearerAuth() @ApiTags("published data v4") @@ -78,6 +78,7 @@ export class PublishedDataV4Controller { private readonly proposalsService: ProposalsService, private readonly publishedDataService: PublishedDataService, private caslAbilityFactory: CaslAbilityFactory, + private validatorService: ValidatorService, ) {} @AllowAny() @@ -223,6 +224,9 @@ export class PublishedDataV4Controller { name: "pid", description: "Dataset pid used to fetch form data.", required: true, + type: String, + isArray: true, + explode: true, }) @ApiResponse({ status: HttpStatus.OK, @@ -230,10 +234,11 @@ export class PublishedDataV4Controller { isArray: false, description: "Return form populate data", }) - async formPopulate(@Query("pid") pid: string) { + async formPopulate(@Query("pid") pid: string[] | string) { + pid = Array.isArray(pid) ? pid : [pid]; const formData: FormPopulateData = {}; const dataset = (await this.datasetsService.findOne({ - where: { pid }, + where: { pid: pid[0] }, })) as unknown as DatasetClass; let proposalId; @@ -263,6 +268,13 @@ export class PublishedDataV4Controller { formData.thumbnail = attachment.thumbnail; } + const dto: PartialUpdatePublishedDataV4Dto = { + datasetPids: pid, + metadata: {}, + }; + await this.validatorService.validate(dto); + formData.metadata = dto.metadata; + return formData; } @@ -409,7 +421,11 @@ export class PublishedDataV4Controller { ); } - await this.validateMetadata(publishedData.metadata); + const validationErrors = + await this.validatorService.validate(publishedData); + if (validationErrors) { + throw new HttpException(validationErrors, HttpStatus.BAD_REQUEST); + } // Make datasets in publishedData datasetPids array public const datasetPids = publishedData.datasetPids; @@ -477,29 +493,6 @@ export class PublishedDataV4Controller { ); } - async validateMetadata(metadata?: object) { - const validator = new Validator(); - const metadataConfig = await this.getConfig(); - if (!metadataConfig?.metadataSchema) { - throw new HttpException( - "Published data schema is not defined in the configuration.", - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - - const validationResult = validator.validate( - metadata, - metadataConfig.metadataSchema, - ); - - if (!validationResult.valid) { - throw new HttpException( - validationResult.errors.map((error) => error.stack), - HttpStatus.BAD_REQUEST, - ); - } - } - // DELETE /publisheddata/:id @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies("publisheddata", (ability: AppAbility) => @@ -568,7 +561,11 @@ export class PublishedDataV4Controller { publishedData.registeredTime = data.registeredTime; publishedData.status = data.status; - await this.validateMetadata(publishedData.metadata); + const validationErrors = + await this.validatorService.validate(publishedData); + if (validationErrors) { + throw new HttpException(validationErrors, HttpStatus.BAD_REQUEST); + } const mergePatchRequest = cloneDeep(request); mergePatchRequest.headers["content-type"] = "application/merge-patch+json"; diff --git a/src/published-data/validator.service.spec.ts b/src/published-data/validator.service.spec.ts new file mode 100644 index 000000000..7da657dbe --- /dev/null +++ b/src/published-data/validator.service.spec.ts @@ -0,0 +1,190 @@ +import { ConfigService } from "@nestjs/config"; +import { Test, TestingModule } from "@nestjs/testing"; +import { AttachmentsService } from "src/attachments/attachments.service"; +import { DatasetsService } from "src/datasets/datasets.service"; +import { ProposalsService } from "src/proposals/proposals.service"; +import { ReadOnlyDatasetsService, ValidatorService } from "./validator.service"; +import { ErrorObject } from "ajv"; + +describe("ValidatorService", () => { + let service: ValidatorService; + + const mockConfigService = { + get: jest.fn(), + }; + + const mockDataService = { + findOne: jest.fn(), + findAll: jest.fn(), + count: jest.fn(), + }; + + const createService = async (publishedDataConfig: unknown) => { + mockConfigService.get.mockImplementation((key: string) => { + if (key === "publishedDataConfig") return publishedDataConfig; + return null; + }); + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ValidatorService, + { provide: ConfigService, useValue: mockConfigService }, + { provide: ProposalsService, useValue: mockDataService }, + { provide: DatasetsService, useValue: mockDataService }, + { provide: AttachmentsService, useValue: mockDataService }, + ], + }).compile(); + + return module.get(ValidatorService); + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + it("should be defined", async () => { + service = await createService({ metadataSchema: {} }); + expect(service).toBeDefined(); + }); + + describe("validate", () => { + it("should be a no-op if metadataSchema is missing", async () => { + service = await createService({}); + const errors = await service.validate({}); + expect(errors).toBeNull(); + }); + + it("should return null when metadata is valid", async () => { + const schema = { + type: "object", + properties: { name: { type: "string" } }, + required: ["name"], + }; + + service = await createService({ metadataSchema: schema }); + + const mockData = { metadata: { name: "abc" } }; + const errors = await service.validate(mockData); + expect(errors).toBeNull(); + }); + + it("should return errors when metadata is invalid", async () => { + const schema = { + type: "object", + properties: { name: { type: "string" } }, + required: ["name"], + }; + + service = await createService({ metadataSchema: schema }); + + const mockData = { metadata: { invalidKey: 5 } }; + const errors = await service.validate(mockData); + + expect(errors).toBeDefined(); + expect(Array.isArray(errors)).toBe(true); + const errorList = errors! as ErrorObject< + string, + Record, + unknown + >[]; + expect(errorList.length).toBe(1); + expect(errorList[0].message).toBe("must have required property 'name'"); + }); + }); + + describe("Dynamic Defaults", () => { + it("should handle pre-defined dynamic default (currentYear)", async () => { + const schema = { + type: "object", + required: ["publicationYear"], + allOf: [ + { dynamicDefaults: { publicationYear: "currentYear" } }, + { properties: { publicationYear: { type: "number" } } }, + ], + }; + + service = await createService({ metadataSchema: schema }); + + const mockData = { metadata: {} }; + const errors = await service.validate(mockData); + expect(errors).toBeNull(); + + const metadata = mockData.metadata as Record; + expect(metadata.publicationYear).toBe(new Date().getFullYear()); + }); + + it("should handle user-defined dynamic default (sync)", async () => { + const schema = { + type: "object", + required: ["publicationYear"], + allOf: [ + { dynamicDefaults: { publicationYear: "userDefinedFunction" } }, + { properties: { publicationYear: { type: "number" } } }, + ], + }; + + service = await createService({ metadataSchema: schema }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (service as any).dynamicDefaults.set( + "userDefinedFunction", + () => () => 5, + ); + + const mockData = { metadata: {} }; + const errors = await service.validate(mockData); + expect(errors).toBeNull(); + + const metadata = mockData.metadata as Record; + expect(metadata.publicationYear).toBe(5); + }); + + it("should handle user-defined dynamic default (async)", async () => { + const schema = { + type: "object", + required: ["publicationYear"], + allOf: [ + { dynamicDefaults: { publicationYear: "userDefinedAsyncFunction" } }, + { properties: { publicationYear: { type: "number" } } }, + ], + }; + + service = await createService({ metadataSchema: schema }); + + mockDataService.count.mockImplementation(() => 6); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (service as any).dynamicDefaults.set( + "userDefinedAsyncFunction", + async function (ctx: { datasetsService: ReadOnlyDatasetsService }) { + const datasetsCount = await ctx.datasetsService.count({}); + return () => datasetsCount; + }, + ); + + const mockData = { metadata: {} }; + const errors = await service.validate(mockData); + expect(errors).toBeNull(); + + const metadata = mockData.metadata as Record; + expect(metadata.publicationYear).toBe(6); + }); + + it("should error on unknown dynamicDefaults functions", async () => { + const schema = { + type: "object", + required: ["publicationYear"], + allOf: [ + { dynamicDefaults: { publicationYear: "notImplemented" } }, + { properties: { publicationYear: { type: "number" } } }, + ], + }; + + service = await createService({ metadataSchema: schema }); + + const mockData = { metadata: {} }; + await expect(service.validate(mockData)).rejects.toThrow( + 'invalid "dynamicDefaults" keyword property value: notImplemented', + ); + }); + }); +}); diff --git a/src/published-data/validator.service.ts b/src/published-data/validator.service.ts new file mode 100644 index 000000000..8b884b039 --- /dev/null +++ b/src/published-data/validator.service.ts @@ -0,0 +1,158 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import addFormats from "ajv-formats"; +import addKeywords from "ajv-keywords"; +import def, { + DynamicDefaultFunc, +} from "ajv-keywords/dist/definitions/dynamicDefaults"; +import Ajv2019, { Schema } from "ajv/dist/2019"; +import { isArray, isEmpty, isMap, isNil } from "lodash"; +import { AttachmentsService } from "src/attachments/attachments.service"; +import { DatasetsService } from "src/datasets/datasets.service"; +import { ProposalsService } from "src/proposals/proposals.service"; +import { CreatePublishedDataV4Dto } from "./dto/create-published-data.v4.dto"; +import { + PartialUpdatePublishedDataV4Dto, + UpdatePublishedDataV4Dto, +} from "./dto/update-published-data.v4.dto"; +import { PublishedDataConfig } from "./interfaces/published-data.interface"; + +export type ReadOnlyProposalsService = Pick< + ProposalsService, + "findOne" | "findAll" | "count" +>; +export type ReadOnlyDatasetsService = Pick< + DatasetsService, + "findOne" | "findAll" | "count" +>; +export type ReadOnlyAttachmentsService = Pick< + AttachmentsService, + "findOne" | "findAll" | "count" +>; + +@Injectable() +export class ValidatorService { + private ajv: Ajv2019; + private config: PublishedDataConfig; + private dynamicDefaults: Map = new Map([ + ["currentYear", () => () => new Date().getFullYear()], + ]); + + constructor( + private readonly configService: ConfigService, + private readonly proposalsService: ProposalsService, + private readonly datasetsService: DatasetsService, + private readonly attachmentsService: AttachmentsService, + ) { + this.ajv = new Ajv2019({ + useDefaults: "empty", + allErrors: true, + strict: false, + }); + addFormats(this.ajv); + addKeywords(this.ajv); + + this.config = this.configService.get( + "publishedDataConfig", + { metadataSchema: null, uiSchema: null }, + ); + + if (isNil(this.config.metadataSchema)) { + return; + } + + const modulePath = this.configService.get("ajvCustomDefinitions"); + if (isEmpty(modulePath)) { + return; + } + + try { + const externalModule = this.loadExternalModule(modulePath!); + + if (isArray(externalModule.keywords)) { + for (const definition of externalModule.keywords) { + Logger.log(`Adding ajv keyword: '${definition.keyword}'`); + this.ajv.addKeyword(definition); + } + } + + if (isMap(externalModule.dynamicDefaults)) { + this.dynamicDefaults = new Map([ + ...this.dynamicDefaults, + ...externalModule.dynamicDefaults, + ]); + } + } catch (error) { + Logger.error(`Failed to load module at '${modulePath}'`, error); + throw error; + } + } + + async validate( + publishedData: + | CreatePublishedDataV4Dto + | UpdatePublishedDataV4Dto + | PartialUpdatePublishedDataV4Dto, + ) { + if (isNil(this.config.metadataSchema)) { + return null; + } + + await this.loadDynamicDefaultFunctions(publishedData); + + const validateFn = this.ajv.compile(this.config.metadataSchema as Schema); + validateFn(publishedData.metadata); + return validateFn.errors; + } + + private loadExternalModule(path: string) { + Logger.debug(`Loading custom ajv code at ${path}`); + // eslint-disable-next-line @typescript-eslint/no-require-imports + const externalModule = require(path); + + return externalModule; + } + + private async loadDynamicDefaultFunctions( + publishedData: + | CreatePublishedDataV4Dto + | UpdatePublishedDataV4Dto + | PartialUpdatePublishedDataV4Dto, + ) { + for (const [name, implementation] of this.dynamicDefaults.entries()) { + if (typeof implementation !== "function") { + Logger.error( + `Ignoring dynamic defaults function ${name} should be of type 'function' not '${typeof implementation}'.`, + ); + continue; + } + switch (implementation.constructor.name) { + case "Function": + def.DEFAULTS[name] = implementation; + break; + case "AsyncFunction": + /** + * Ajv cannot 'await' during validation. To get around this, we run the + * AsyncFunction now to perform any setup (like DB queries). + */ + try { + const syncFunc = await implementation({ + publishedData: publishedData, + proposalService: this + .proposalsService as ReadOnlyProposalsService, + datasetsService: this.datasetsService as ReadOnlyDatasetsService, + attachmentsService: this + .attachmentsService as ReadOnlyAttachmentsService, + }); + def.DEFAULTS[name] = () => syncFunc; + } catch (err) { + throw new Error( + `Executing dynamicDefaults function '${name}' failed with the following error:`, + { cause: err }, + ); + } + break; + } + } + } +} diff --git a/test/PublishedDataV4.js b/test/PublishedDataV4.js index 86b13aa68..131cb82db 100644 --- a/test/PublishedDataV4.js +++ b/test/PublishedDataV4.js @@ -5,7 +5,6 @@ const sandbox = require("sinon").createSandbox(); let accessTokenArchiveManager = null, accessTokenAdminIngestor = null, - idOrigDatablock = null, pid = null, pidnonpublic = null, @@ -77,6 +76,21 @@ describe("1600: PublishedDataV4: Test of access to published data v4 endpoints", }); }); + it("0011: formpopulate should return default values for metadata", async () => { + return request(appUrl) + .get(`/api/v4/PublishedData/formpopulate?pid=${encodeURIComponent(pid)}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryValidStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("metadata"); + res.body.metadata.should.have + .property("publicationYear") + .and.equal(new Date().getFullYear()); + }); + }); + it("0015: adds a published data", async () => { return request(appUrl) .post("/api/v4/PublishedData") @@ -103,9 +117,11 @@ describe("1600: PublishedDataV4: Test of access to published data v4 endpoints", it("0023: should fetch all published data as admin ingestor with fields", async () => { const limits = { skip: 0 }; - const fields = { createdBy: { $regex: "admin", $options: "i" } } + const fields = { createdBy: { $regex: "admin", $options: "i" } }; return request(appUrl) - .get(`/api/v4/PublishedData?fields=${encodeURIComponent(JSON.stringify(fields))}&limits=${encodeURIComponent(JSON.stringify(limits))}`) + .get( + `/api/v4/PublishedData?fields=${encodeURIComponent(JSON.stringify(fields))}&limits=${encodeURIComponent(JSON.stringify(limits))}`, + ) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -300,10 +316,10 @@ describe("1600: PublishedDataV4: Test of access to published data v4 endpoints", return request(appUrl) .get( "/api/v3/Datasets/fullquery" + - "?fields=" + - encodeURIComponent(JSON.stringify(fields)) + - "&limits=" + - encodeURIComponent(JSON.stringify(limits)), + "?fields=" + + encodeURIComponent(JSON.stringify(fields)) + + "&limits=" + + encodeURIComponent(JSON.stringify(limits)), ) .set("Accept", "application/json") .expect(TestData.SuccessfulGetStatusCode) @@ -324,10 +340,10 @@ describe("1600: PublishedDataV4: Test of access to published data v4 endpoints", return request(appUrl) .get( "/api/v3/Datasets/fullquery" + - "?fields=" + - encodeURIComponent(JSON.stringify(fields)) + - "&limits=" + - encodeURIComponent(JSON.stringify(limits)), + "?fields=" + + encodeURIComponent(JSON.stringify(fields)) + + "&limits=" + + encodeURIComponent(JSON.stringify(limits)), ) .set("Accept", "application/json") .expect(TestData.SuccessfulGetStatusCode) @@ -362,10 +378,10 @@ describe("1600: PublishedDataV4: Test of access to published data v4 endpoints", return request(appUrl) .get( "/api/v3/Datasets/findOne" + - "?filter=" + - encodeURIComponent(JSON.stringify(filter)) + - "&limits=" + - encodeURIComponent(JSON.stringify(limits)), + "?filter=" + + encodeURIComponent(JSON.stringify(filter)) + + "&limits=" + + encodeURIComponent(JSON.stringify(limits)), ) .set("Accept", "application/json") .expect(TestData.SuccessfulGetStatusCode) From 6e88e2a3819c65daaa3cc36abafa91a70c538e47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:16:44 +0000 Subject: [PATCH 097/120] build(deps-dev): bump brace-expansion from 1.1.12 to 1.1.13 Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.12 to 1.1.13. - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.13) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 1.1.13 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 66 +++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 37ab8b944..62ca85db3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1195,9 +1195,9 @@ } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2270,9 +2270,9 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -2778,9 +2778,9 @@ } }, "node_modules/@nestjs/cli/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4429,9 +4429,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5714,9 +5714,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -7663,9 +7663,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8686,9 +8686,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -9691,9 +9691,9 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -10162,9 +10162,9 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -11463,9 +11463,9 @@ } }, "node_modules/mjml-cli/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "optional": true, "dependencies": { @@ -11920,9 +11920,9 @@ } }, "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { From 5dd7757f721a90c40c72f2cbe76c4602c59eb894 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:36:42 +0000 Subject: [PATCH 098/120] build(deps): bump @nestjs-modules/mailer in the nestjs group Bumps the nestjs group with 1 update: [@nestjs-modules/mailer](https://github.com/nest-modules/mailer). Updates `@nestjs-modules/mailer` from 2.3.0 to 2.3.4 - [Release notes](https://github.com/nest-modules/mailer/releases) - [Commits](https://github.com/nest-modules/mailer/compare/@nestjs-modules/mailer@2.3.0...@nestjs-modules/mailer@2.3.4) --- updated-dependencies: - dependency-name: "@nestjs-modules/mailer" dependency-version: 2.3.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62ca85db3..23d8709c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2585,9 +2585,9 @@ } }, "node_modules/@nestjs-modules/mailer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.3.0.tgz", - "integrity": "sha512-C9FQOz+GKSIgJKWfUVJHuOCfbhhcQxitHcH1+Gl/nSVR/w+PhvrC/dk4h+pwB//5KYe4aPeE7Ia1slgIVjeAJQ==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.3.4.tgz", + "integrity": "sha512-0vPNAuXGFHERFphokC5RVDgRoqwUXvI3OTPNXonw74e4QQyntp25OKzS59EaXmQOCBiIuRglmWQaFPvEpP5tuw==", "license": "MIT", "dependencies": { "@css-inline/css-inline": "0.20.0", @@ -2600,7 +2600,7 @@ "@types/pug": "^2.0.10", "ejs": "^5.0.1", "handlebars": "^4.7.8", - "liquidjs": "^10.25.0", + "liquidjs": "^10.25.1", "mjml": "^5.0.0-alpha.4", "nunjucks": "^3.2.4", "preview-email": "^3.1.1", From 548c777a6fa4cc04624e28df4cb7f2496c72dac9 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 31 Mar 2026 09:31:46 +0200 Subject: [PATCH 099/120] build: update package-lock (#2643) --- package-lock.json | 103 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/package-lock.json b/package-lock.json index 23d8709c4..da78877ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -228,6 +228,40 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@angular-devkit/schematics-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/schematics-cli/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -283,6 +317,40 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -3247,6 +3315,40 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@nestjs/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nestjs/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nestjs/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -3480,6 +3582,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" From 111d55ccf3975831f16b0aa7f6ea9f3168b22a53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 07:33:04 +0000 Subject: [PATCH 100/120] build(deps): bump amqplib from 0.10.9 to 1.0.2 Bumps [amqplib](https://github.com/amqp-node/amqplib) from 0.10.9 to 1.0.2. - [Release notes](https://github.com/amqp-node/amqplib/releases) - [Changelog](https://github.com/amqp-node/amqplib/blob/main/CHANGELOG.md) - [Commits](https://github.com/amqp-node/amqplib/compare/v0.10.9...v1.0.2) --- updated-dependencies: - dependency-name: amqplib dependency-version: 1.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 129 +++++++--------------------------------------- package.json | 2 +- 2 files changed, 20 insertions(+), 111 deletions(-) diff --git a/package-lock.json b/package-lock.json index da78877ee..3b4537ee2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "ajv-keywords": "^5.1.0", - "amqplib": "^0.10.5", + "amqplib": "^1.0.2", "bcrypt": "^6.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.15.1", @@ -228,40 +228,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics-cli/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -317,40 +283,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -3315,40 +3247,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@nestjs/schematics/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nestjs/schematics/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@nestjs/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -3582,7 +3480,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -4956,6 +4853,19 @@ "npm": ">=8.5.0" } }, + "node_modules/@user-office-software/duo-message-broker/node_modules/amqplib": { + "version": "0.10.9", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.9.tgz", + "integrity": "sha512-jwSftI4QjS3mizvnSnOrPGYiUnm1vI2OP1iXeOUz5pb74Ua0nbf6nPyyTzuiCLEE3fMpaJORXh2K/TQ08H5xGA==", + "license": "MIT", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "url-parse": "~1.5.10" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -5300,16 +5210,15 @@ } }, "node_modules/amqplib": { - "version": "0.10.9", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.9.tgz", - "integrity": "sha512-jwSftI4QjS3mizvnSnOrPGYiUnm1vI2OP1iXeOUz5pb74Ua0nbf6nPyyTzuiCLEE3fMpaJORXh2K/TQ08H5xGA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-1.0.2.tgz", + "integrity": "sha512-QFzavIs3FxXA9/PWOiY/j5Arr7KFT0b1TYYsq9f5PyZ3Dv5H5hQXTK3fZTUUzzOo2BF1o/Vk5bHAKzlL40LfDA==", "license": "MIT", "dependencies": { - "buffer-more-ints": "~1.0.0", - "url-parse": "~1.5.10" + "buffer-more-ints": "~1.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/ansi-align": { diff --git a/package.json b/package.json index 12c063e81..f97256409 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "ajv-keywords": "^5.1.0", - "amqplib": "^0.10.5", + "amqplib": "^1.0.2", "bcrypt": "^6.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.15.1", From dcc56bba9e4517e0728b9e91f733fc5772c48e6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:17:00 +0000 Subject: [PATCH 101/120] build(deps): bump dependabot/fetch-metadata from 2.5.0 to 3.0.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.5.0 to 3.0.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.5.0...v3.0.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-version: 3.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge-dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge-dependabot.yml b/.github/workflows/auto-merge-dependabot.yml index 9af29eedd..4204ec651 100644 --- a/.github/workflows/auto-merge-dependabot.yml +++ b/.github/workflows/auto-merge-dependabot.yml @@ -15,7 +15,7 @@ jobs: ## Extract information about the dependencies being updated by a Dependabot-generated PR - name: Dependabot metadata id: dependabot-metadata - uses: dependabot/fetch-metadata@v2.5.0 + uses: dependabot/fetch-metadata@v3.0.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From fdb83e09ea1d8b1c492496f1e45dc38d7fc880ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:21:01 +0000 Subject: [PATCH 102/120] build(deps): bump geekyeggo/delete-artifact from 5 to 6 Bumps [geekyeggo/delete-artifact](https://github.com/geekyeggo/delete-artifact) from 5 to 6. - [Release notes](https://github.com/geekyeggo/delete-artifact/releases) - [Changelog](https://github.com/GeekyEggo/delete-artifact/blob/main/CHANGELOG.md) - [Commits](https://github.com/geekyeggo/delete-artifact/compare/v5...v6) --- updated-dependencies: - dependency-name: geekyeggo/delete-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/upload-sdk-artifact.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/upload-sdk-artifact.yml b/.github/workflows/upload-sdk-artifact.yml index b219dcbda..0feda6844 100644 --- a/.github/workflows/upload-sdk-artifact.yml +++ b/.github/workflows/upload-sdk-artifact.yml @@ -93,6 +93,6 @@ jobs: - generate-and-upload-sdk if: github.event_name != 'push' steps: - - uses: geekyeggo/delete-artifact@v5 + - uses: geekyeggo/delete-artifact@v6 with: name: swagger-* From d4aba513a8cb6676899243aad96582d011b8d802 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:23:43 +0000 Subject: [PATCH 103/120] build(deps): bump actions/create-github-app-token from 2 to 3 Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2 to 3. - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Commits](https://github.com/actions/create-github-app-token/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/create-github-app-token dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy.yml | 2 +- .github/workflows/release-and-publish-sdk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 64e99f5a0..6bd471f7d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -44,7 +44,7 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@v3 id: app-token with: app-id: ${{ secrets.WORKFLOW_DISPATCHER_APP_ID }} diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 1310ccd65..943584614 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -92,7 +92,7 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@v3 id: app-token with: app-id: ${{ secrets.WORKFLOW_DISPATCHER_APP_ID }} From 3dde3e848d521260ae78de3b1158cae019752d53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:03:41 +0000 Subject: [PATCH 104/120] build(deps): bump the nestjs group with 4 updates Bumps the nestjs group with 4 updates: [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express), [@nestjs/cli](https://github.com/nestjs/nest-cli), [@nestjs/schematics](https://github.com/nestjs/schematics) and [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing). Updates `@nestjs/platform-express` from 11.1.17 to 11.1.18 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.18/packages/platform-express) Updates `@nestjs/cli` from 11.0.16 to 11.0.17 - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Commits](https://github.com/nestjs/nest-cli/compare/11.0.16...11.0.17) Updates `@nestjs/schematics` from 11.0.9 to 11.0.10 - [Release notes](https://github.com/nestjs/schematics/releases) - [Commits](https://github.com/nestjs/schematics/compare/11.0.9...11.0.10) Updates `@nestjs/testing` from 11.1.17 to 11.1.18 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.18/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-version: 11.1.18 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/cli" dependency-version: 11.0.17 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/schematics" dependency-version: 11.0.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/testing" dependency-version: 11.1.18 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] --- package-lock.json | 393 +++++++++------------------------------------- 1 file changed, 71 insertions(+), 322 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3b4537ee2..48938fa64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -112,13 +112,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.19.tgz", - "integrity": "sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==", + "version": "19.2.22", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.22.tgz", + "integrity": "sha512-tvfu5jhem1o8qidVxvXe5KfCij65ioMLCOFA947DD+zb3yTl5pJyDm2dqzbOehuQw0fmH4XPQukRJsCUy+UwaA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", + "@angular-devkit/core": "19.2.22", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", @@ -131,14 +131,14 @@ } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.19.tgz", - "integrity": "sha512-7q9UY6HK6sccL9F3cqGRUwKhM7b/XfD2YcVaZ2WD7VMaRlRm85v6mRjSrfKIAwxcQU0UK27kMc79NIIqaHjzxA==", + "version": "19.2.22", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.22.tgz", + "integrity": "sha512-6BvkxDz4nV8B6Ha4n/pYZ503vXgLxMaEpcKsFDao1sl0iSwrIOphlIS1yWprlGdCThIM3aJref1JU13ZvEcBCA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", - "@angular-devkit/schematics": "19.2.19", + "@angular-devkit/core": "19.2.22", + "@angular-devkit/schematics": "19.2.22", "@inquirer/prompts": "7.3.2", "ansi-colors": "4.1.3", "symbol-observable": "4.0.0", @@ -154,13 +154,13 @@ } }, "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", - "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", + "version": "19.2.22", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.22.tgz", + "integrity": "sha512-OqN/Ded+ZKypPZN5+qUFwtnKGl7FKpxJXYO2Vts5vLBojY5goCZd9SGW1CyXeuPnisRUW+vjqBQbWYuEUh36Tw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "8.17.1", + "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", "picomatch": "4.0.2", @@ -211,23 +211,6 @@ } } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@angular-devkit/schematics-cli/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -239,13 +222,13 @@ } }, "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", - "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", + "version": "19.2.22", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.22.tgz", + "integrity": "sha512-OqN/Ded+ZKypPZN5+qUFwtnKGl7FKpxJXYO2Vts5vLBojY5goCZd9SGW1CyXeuPnisRUW+vjqBQbWYuEUh36Tw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "8.17.1", + "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", "picomatch": "4.0.2", @@ -266,23 +249,6 @@ } } }, - "node_modules/@angular-devkit/schematics/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -2678,15 +2644,15 @@ } }, "node_modules/@nestjs/cli": { - "version": "11.0.16", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.16.tgz", - "integrity": "sha512-P0H+Vcjki6P5160E5QnMt3Q0X5FTg4PZkP99Ig4lm/4JWqfw32j3EXv3YBTJ2DmxLwOQ/IS9F7dzKpMAgzKTGg==", + "version": "11.0.17", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.17.tgz", + "integrity": "sha512-tOMgoB9k+Zb2WdKYPhbhceROLcDR1BFQZWfkBOGMRgBTo8rnC125E65UvThEA77vp4w+zKjqiSIv0leT+wdpHg==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", - "@angular-devkit/schematics": "19.2.19", - "@angular-devkit/schematics-cli": "19.2.19", + "@angular-devkit/core": "19.2.22", + "@angular-devkit/schematics": "19.2.22", + "@angular-devkit/schematics-cli": "19.2.22", "@inquirer/prompts": "7.10.1", "@nestjs/schematics": "^11.0.1", "ansis": "4.2.0", @@ -2694,13 +2660,13 @@ "cli-table3": "0.6.5", "commander": "4.1.1", "fork-ts-checker-webpack-plugin": "9.1.0", - "glob": "13.0.0", + "glob": "13.0.6", "node-emoji": "1.11.0", "ora": "5.4.1", "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.2.0", "typescript": "5.9.3", - "webpack": "5.104.1", + "webpack": "5.105.4", "webpack-node-externals": "3.0.0" }, "bin": { @@ -2723,13 +2689,13 @@ } }, "node_modules/@nestjs/cli/node_modules/@angular-devkit/core": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", - "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", + "version": "19.2.22", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.22.tgz", + "integrity": "sha512-OqN/Ded+ZKypPZN5+qUFwtnKGl7FKpxJXYO2Vts5vLBojY5goCZd9SGW1CyXeuPnisRUW+vjqBQbWYuEUh36Tw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "8.17.1", + "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", "picomatch": "4.0.2", @@ -2750,46 +2716,6 @@ } } }, - "node_modules/@nestjs/cli/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@nestjs/cli/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/@nestjs/cli/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/@nestjs/cli/node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -2806,87 +2732,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@nestjs/cli/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@nestjs/cli/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@nestjs/cli/node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@nestjs/cli/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@nestjs/cli/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@nestjs/cli/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -2911,93 +2756,6 @@ "tslib": "^2.1.0" } }, - "node_modules/@nestjs/cli/node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@nestjs/cli/node_modules/schema-utils/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@nestjs/cli/node_modules/webpack": { - "version": "5.104.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", - "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.4", - "es-module-lexer": "^2.0.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", - "watchpack": "^2.4.4", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@nestjs/common": { "version": "11.1.17", "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.17.tgz", @@ -3146,15 +2904,15 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.17", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.17.tgz", - "integrity": "sha512-mAf4eOsSBsTOn/VbrUO1gsjW6dVh91qqXPMXun4dN8SnNjf7PTQagM9o8d6ab8ZBpNe6UdZftdrZoDetU+n4Qg==", + "version": "11.1.18", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.18.tgz", + "integrity": "sha512-s6GdHMTa3qx0fJewR74Xa30ysPHfBEqxIwZ7BGSTLoAEQ1vTP24urNl+b6+s49NFLEIOyeNho5fN/9/I17QlOw==", "license": "MIT", "dependencies": { "cors": "2.8.6", "express": "5.2.1", "multer": "2.1.1", - "path-to-regexp": "8.3.0", + "path-to-regexp": "8.4.2", "tslib": "2.8.1" }, "funding": { @@ -3166,16 +2924,26 @@ "@nestjs/core": "^11.0.0" } }, + "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/@nestjs/schematics": { - "version": "11.0.9", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.9.tgz", - "integrity": "sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==", + "version": "11.0.10", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.10.tgz", + "integrity": "sha512-q9lr0wGwgBHLarD4uno3XiW4JX60WPlg2VTgbqPHl/6bT4u1IEEzj+q9Tad3bVnqL5mlDF3vrZ2tj+x13CJpmw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.17", - "@angular-devkit/schematics": "19.2.17", - "comment-json": "4.4.1", + "@angular-devkit/core": "19.2.23", + "@angular-devkit/schematics": "19.2.23", + "comment-json": "4.6.2", "jsonc-parser": "3.3.1", "pluralize": "8.0.0" }, @@ -3184,16 +2952,16 @@ } }, "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.17.tgz", - "integrity": "sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==", + "version": "19.2.23", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.23.tgz", + "integrity": "sha512-RazHPQkUEsNU/OZ75w9UeHxGFMthRiuAW2B/uA7eXExBj/1meHrrBfoCA56ujW2GUxVjRtSrMjylKh4R4meiYA==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "8.17.1", + "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", + "picomatch": "4.0.4", "rxjs": "7.8.1", "source-map": "0.7.4" }, @@ -3212,13 +2980,13 @@ } }, "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.17.tgz", - "integrity": "sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==", + "version": "19.2.23", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.23.tgz", + "integrity": "sha512-Jzs7YM4X6azmHU7Mw5tQSPMuvaqYS8SLnZOJbtiXCy1JyuW9bm/WBBecNHMiuZ8LHXKhvQ6AVX1tKrzF6uiDmw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.17", + "@angular-devkit/core": "19.2.23", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", @@ -3230,21 +2998,17 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@nestjs/schematics/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "node_modules/@nestjs/schematics/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "engines": { + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@nestjs/schematics/node_modules/rxjs": { @@ -3381,9 +3145,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "11.1.17", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.17.tgz", - "integrity": "sha512-lNffw+z+2USewmw4W0tsK+Rq94A2N4PiHbcqoRUu5y8fnqxQeIWGHhjo5BFCqj7eivqJBhT7WdRydxVq4rAHzg==", + "version": "11.1.18", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.18.tgz", + "integrity": "sha512-frzwNlpBgtAzI3hp/qo57DZoRO4RMTH1wST3QUYEhRTHyfPkLpzkWz3jV/mhApXjD0yT56Ptlzn6zuYPLh87Lw==", "dev": true, "license": "MIT", "dependencies": { @@ -6436,14 +6200,13 @@ } }, "node_modules/comment-json": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz", - "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.6.2.tgz", + "integrity": "sha512-R2rze/hDX30uul4NZoIZ76ImSJLFxn/1/ZxtKC1L77y2X1k+yYu1joKbAtMA2Fg3hZrTOiw0I5mwVMo0cf250w==", "dev": true, "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", "esprima": "^4.0.1" }, "engines": { @@ -6640,13 +6403,6 @@ "dev": true, "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, "node_modules/cors": { "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", @@ -16405,7 +16161,6 @@ "integrity": "sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -16475,7 +16230,6 @@ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -16494,7 +16248,6 @@ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -16509,7 +16262,6 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -16520,7 +16272,6 @@ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -16531,7 +16282,6 @@ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -16545,7 +16295,6 @@ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", From 01d259a27e5962c4d2b5d0ebd45a67a1cc97fa08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:08:22 +0000 Subject: [PATCH 105/120] build(deps-dev): bump @typescript-eslint/parser from 8.57.2 to 8.58.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.57.2 to 8.58.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.58.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.58.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 185 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 48938fa64..ed91192dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4034,16 +4034,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", - "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.0.tgz", + "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", "debug": "^4.4.3" }, "engines": { @@ -4055,7 +4055,176 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz", + "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.58.0", + "@typescript-eslint/types": "^8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz", + "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz", + "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", + "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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", + "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", + "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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", + "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.58.0", + "@typescript-eslint/tsconfig-utils": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", + "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.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.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/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/project-service": { From 2aaaf75cee9108bcc646e01bd977d5bdeed8f9f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:14:07 +0000 Subject: [PATCH 106/120] build(deps): bump amqplib from 1.0.2 to 1.0.3 Bumps [amqplib](https://github.com/amqp-node/amqplib) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/amqp-node/amqplib/releases) - [Changelog](https://github.com/amqp-node/amqplib/blob/main/CHANGELOG.md) - [Commits](https://github.com/amqp-node/amqplib/compare/v1.0.2...v1.0.3) --- updated-dependencies: - dependency-name: amqplib dependency-version: 1.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed91192dd..07a5bef8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5143,9 +5143,9 @@ } }, "node_modules/amqplib": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-1.0.2.tgz", - "integrity": "sha512-QFzavIs3FxXA9/PWOiY/j5Arr7KFT0b1TYYsq9f5PyZ3Dv5H5hQXTK3fZTUUzzOo2BF1o/Vk5bHAKzlL40LfDA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-1.0.3.tgz", + "integrity": "sha512-nsrXa59tvX4HPjPPW8JJGuBb/Db0MOq3DOhGdSbIY7bTsQDMV2fmF9c3i74g/8Gt9+QWyrxfEPppOOoV9lK1uQ==", "license": "MIT", "dependencies": { "buffer-more-ints": "~1.0.0" From 4dbf8d60ecb062a5ddf7d82a6ef2f046b799b900 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:20:27 +0000 Subject: [PATCH 107/120] build(deps): bump dotenv from 17.3.1 to 17.4.1 Bumps [dotenv](https://github.com/motdotla/dotenv) from 17.3.1 to 17.4.1. - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](https://github.com/motdotla/dotenv/compare/v17.3.1...v17.4.1) --- updated-dependencies: - dependency-name: dotenv dependency-version: 17.4.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07a5bef8b..31f67085f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7099,9 +7099,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.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.1.tgz", + "integrity": "sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==", "license": "BSD-2-Clause", "engines": { "node": ">=12" From 68e0abc5831929700c60135900de1cebccf631e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:26:36 +0000 Subject: [PATCH 108/120] build(deps): bump lodash from 4.17.23 to 4.18.1 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.23...4.18.1) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.18.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 31f67085f..2791740cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2814,6 +2814,12 @@ "url": "https://dotenvx.com" } }, + "node_modules/@nestjs/config/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, "node_modules/@nestjs/core": { "version": "11.1.17", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.17.tgz", @@ -3074,6 +3080,12 @@ } } }, + "node_modules/@nestjs/swagger/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, "node_modules/@nestjs/terminus": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-11.1.1.tgz", @@ -8483,6 +8495,12 @@ "lodash": "~4.17.21" } }, + "node_modules/gelf-pro/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -10884,9 +10902,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.includes": { From 74d12a189b82f1a3a8b29ffe87f7984c5bdd1ed7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:33:34 +0000 Subject: [PATCH 109/120] build(deps-dev): bump @types/node from 25.5.0 to 25.5.2 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.5.0 to 25.5.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.5.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2791740cf..aed303ed9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3798,9 +3798,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", "license": "MIT", "dependencies": { "undici-types": "~7.18.0" From c67b76b6f3d6fa1cb2faf40be758efabfaa8ba24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:37:42 +0000 Subject: [PATCH 110/120] build(deps-dev): bump eslint from 10.1.0 to 10.2.0 Bumps [eslint](https://github.com/eslint/eslint) from 10.1.0 to 10.2.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.1.0...v10.2.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.2.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index aed303ed9..4e63a1ea5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1136,13 +1136,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.23.3", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz", - "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.4.tgz", + "integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^3.0.3", + "@eslint/object-schema": "^3.0.4", "debug": "^4.3.1", "minimatch": "^10.2.4" }, @@ -1174,13 +1174,13 @@ } }, "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -1190,22 +1190,22 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.3.tgz", - "integrity": "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.4.tgz", + "integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.1.1" + "@eslint/core": "^1.2.0" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", - "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.0.tgz", + "integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1290,9 +1290,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz", - "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.4.tgz", + "integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1300,13 +1300,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", - "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz", + "integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.1.1", + "@eslint/core": "^1.2.0", "levn": "^0.4.1" }, "engines": { @@ -7450,18 +7450,18 @@ } }, "node_modules/eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz", - "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", + "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.3", - "@eslint/config-helpers": "^0.5.3", - "@eslint/core": "^1.1.1", - "@eslint/plugin-kit": "^0.6.1", + "@eslint/config-array": "^0.23.4", + "@eslint/config-helpers": "^0.5.4", + "@eslint/core": "^1.2.0", + "@eslint/plugin-kit": "^0.7.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", From ce25109d9f1fb8518dc66f20a8244a855dbaa444 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:41:44 +0000 Subject: [PATCH 111/120] build(deps-dev): bump ts-loader from 9.5.4 to 9.5.7 Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 9.5.4 to 9.5.7. - [Release notes](https://github.com/TypeStrong/ts-loader/releases) - [Changelog](https://github.com/TypeStrong/ts-loader/blob/main/CHANGELOG.md) - [Commits](https://github.com/TypeStrong/ts-loader/compare/v9.5.4...v9.5.7) --- updated-dependencies: - dependency-name: ts-loader dependency-version: 9.5.7 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4e63a1ea5..940d3a964 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15737,9 +15737,9 @@ } }, "node_modules/ts-loader": { - "version": "9.5.4", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", - "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", + "version": "9.5.7", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.7.tgz", + "integrity": "sha512-/ZNrKgA3K3PtpMYOC71EeMWIloGw3IYEa5/t1cyz2r5/PyUwTXGzYJvcD3kfUvmhlfpz1rhV8B2O6IVTQ0avsg==", "dev": true, "license": "MIT", "dependencies": { From 42e109ae8cfce93237e1eb605acc46ae9641f52d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:45:51 +0000 Subject: [PATCH 112/120] build(deps-dev): bump ts-jest from 29.4.6 to 29.4.9 Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.4.6 to 29.4.9. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.4.6...v29.4.9) --- updated-dependencies: - dependency-name: ts-jest dependency-version: 29.4.9 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 940d3a964..f580165cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15671,19 +15671,19 @@ } }, "node_modules/ts-jest": { - "version": "29.4.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", - "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "version": "29.4.9", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.9.tgz", + "integrity": "sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==", "dev": true, "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", - "handlebars": "^4.7.8", + "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.3", + "semver": "^7.7.4", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -15700,7 +15700,7 @@ "babel-jest": "^29.0.0 || ^30.0.0", "jest": "^29.0.0 || ^30.0.0", "jest-util": "^29.0.0 || ^30.0.0", - "typescript": ">=4.3 <6" + "typescript": ">=4.3 <7" }, "peerDependenciesMeta": { "@babel/core": { From 519cf35ccd1b3a7ef23e90025811fb3ec231433b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:48:35 +0000 Subject: [PATCH 113/120] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.57.2 to 8.58.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.58.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.58.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 261 ++++++++-------------------------------------- 1 file changed, 46 insertions(+), 215 deletions(-) diff --git a/package-lock.json b/package-lock.json index f580165cf..24efc0419 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4007,20 +4007,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", - "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz", + "integrity": "sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/type-utils": "8.57.2", - "@typescript-eslint/utils": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/type-utils": "8.58.0", + "@typescript-eslint/utils": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4030,9 +4030,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/parser": "^8.58.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -4070,7 +4070,7 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "node_modules/@typescript-eslint/project-service": { "version": "8.58.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz", "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", @@ -4092,7 +4092,7 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "8.58.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz", "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", @@ -4110,7 +4110,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.58.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz", "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", @@ -4127,35 +4127,17 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", - "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", - "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": { + "node_modules/@typescript-eslint/type-utils": { "version": "8.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", - "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.0.tgz", + "integrity": "sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.58.0", - "@typescript-eslint/tsconfig-utils": "8.58.0", "@typescript-eslint/types": "8.58.0", - "@typescript-eslint/visitor-keys": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/utils": "8.58.0", "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "engines": { @@ -4165,166 +4147,15 @@ "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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", - "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.58.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.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/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/project-service": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", - "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.2", - "@typescript-eslint/types": "^8.57.2", - "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.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", - "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", - "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", - "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.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", - "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2", - "@typescript-eslint/utils": "8.57.2", - "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", - "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", + "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", "dev": true, "license": "MIT", "engines": { @@ -4336,21 +4167,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", - "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", + "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.2", - "@typescript-eslint/tsconfig-utils": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/project-service": "8.58.0", + "@typescript-eslint/tsconfig-utils": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4360,7 +4191,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { @@ -4387,13 +4218,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -4403,16 +4234,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", - "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.0.tgz", + "integrity": "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2" + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4423,17 +4254,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", - "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", + "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/types": "8.58.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { From 4a9d863a2dd2d2c1e12cc281c7e034eef061873e Mon Sep 17 00:00:00 2001 From: AB <71728199+abdellah257@users.noreply.github.com> Date: Tue, 7 Apr 2026 14:26:46 +0200 Subject: [PATCH 114/120] feat: rest api provider for access groups (#2558) * REST API Provider for Access Groups * Update logs to match the used standard * update the package lock json * typo fixe --- .env.example | 5 ++ ...s-group-from-rest-api-call.service.spec.ts | 46 +++++++++++++ ...access-group-from-rest-api-call.service.ts | 69 +++++++++++++++++++ .../access-group-service-factory.ts | 20 ++++++ src/config/configuration.ts | 8 +++ 5 files changed, 148 insertions(+) create mode 100644 src/auth/access-group-provider/access-group-from-rest-api-call.service.spec.ts create mode 100644 src/auth/access-group-provider/access-group-from-rest-api-call.service.ts diff --git a/.env.example b/.env.example index 8e71efa0b..e48ea3faa 100644 --- a/.env.example +++ b/.env.example @@ -19,6 +19,11 @@ ACCESS_GROUP_SERVICE_HANDLER="" ACCESS_GROUPS_STATIC_ENABLED=true ACCESS_GROUPS_STATIC_VALUES="" ACCESS_GROUPS_OIDCPAYLOAD_ENABLED=true +ACCESS_GROUPS_REST_ENABLED=true +ACCESS_GROUPS_SERVICE_REST_AUTH_KEY="Authorization" +ACCESS_GROUPS_SERVICE_REST_AUTH_VALUE="" +ACCESS_GROUPS_SERVICE_REST_API_URL="" +ACCESS_GROUPS_SERVICE_REST_USER_ID_FIELD="" #field to take as userID from user payload DOI_PREFIX="" EXPRESS_SESSION_SECRET="" EXPRESS_SESSION_STORE="" diff --git a/src/auth/access-group-provider/access-group-from-rest-api-call.service.spec.ts b/src/auth/access-group-provider/access-group-from-rest-api-call.service.spec.ts new file mode 100644 index 000000000..c38a0e8b5 --- /dev/null +++ b/src/auth/access-group-provider/access-group-from-rest-api-call.service.spec.ts @@ -0,0 +1,46 @@ +import { HttpService } from "@nestjs/axios"; +import { Test, TestingModule } from "@nestjs/testing"; +import { UserPayload } from "../interfaces/userPayload.interface"; +import { AccessGroupFromRestApiService } from "./access-group-from-rest-api-call.service"; + +describe("AccessGroupFromRestApiService", () => { + const mockResponse = ["AAA", "BBB"]; + + let service: AccessGroupFromRestApiService; + const mockAccessGroupService = new AccessGroupFromRestApiService( + "", + {}, + "payload.id", + new HttpService(), + ); + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AccessGroupFromRestApiService], + }) + .overrideProvider(AccessGroupFromRestApiService) + .useValue(mockAccessGroupService) + .compile(); + + service = module.get( + AccessGroupFromRestApiService, + ); + + jest.spyOn(service, "callRestApi").mockImplementation(async () => { + return mockResponse; + }); + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); + + it("Should resolve access groups", async () => { + const expected = ["AAA", "BBB"]; + const actual = await service.getAccessGroups({ + userId: "12378", + payload: { id: "123" }, + } as UserPayload); + expect(actual).toEqual(expected); + }); +}); diff --git a/src/auth/access-group-provider/access-group-from-rest-api-call.service.ts b/src/auth/access-group-provider/access-group-from-rest-api-call.service.ts new file mode 100644 index 000000000..c46a78f8a --- /dev/null +++ b/src/auth/access-group-provider/access-group-from-rest-api-call.service.ts @@ -0,0 +1,69 @@ +import { AccessGroupService as AccessGroupService } from "./access-group.service"; +import { Injectable, Logger } from "@nestjs/common"; +///import fetch from "node-fetch"; + +import { UserPayload } from "../interfaces/userPayload.interface"; +import { HttpService } from "@nestjs/axios"; +import { firstValueFrom } from "rxjs"; +import { get } from "lodash"; +import { AxiosError } from "axios"; +/** + * This service is used to fetch access groups from a REST API. + */ +@Injectable() +export class AccessGroupFromRestApiService extends AccessGroupService { + constructor( + private apiUrl: string, + private headers: Record, + private userIdfield: string, + private readonly httpService: HttpService, + ) { + super(); + } + + async getAccessGroups(userPayload: UserPayload): Promise { + const userId = get(userPayload, this.userIdfield) as string; + if (!userId) { + Logger.error(`User ID not found in payload: ${this.userIdfield}`); + return []; + } + const url = this.apiUrl.replace("{userId}", userId); + + const responseData = await this.callRestApi(url); + if (!responseData) { + Logger.warn("No access groups returned from REST API"); + return []; + } + return responseData; + } + + async callRestApi(url: string): Promise { + try { + const response = await firstValueFrom( + this.httpService.get(url, { + headers: { + ...this.headers, + }, + }), + ); + + if (!response || !response.data) { + Logger.warn("No access groups returned from REST API"); + return []; + } + + return response.data; + } catch (err: unknown) { + if (err instanceof AxiosError) { + Logger.warn( + `Status: ${err.response?.status}, Body: ${JSON.stringify(err.response?.data)}`, + ); + } else if (err instanceof Error) { + Logger.error(err.message); + } else { + Logger.error("Unknown error occurred"); + } + return []; + } + } +} diff --git a/src/auth/access-group-provider/access-group-service-factory.ts b/src/auth/access-group-provider/access-group-service-factory.ts index 6c9f7c689..91c48fe69 100644 --- a/src/auth/access-group-provider/access-group-service-factory.ts +++ b/src/auth/access-group-provider/access-group-service-factory.ts @@ -3,6 +3,7 @@ import { AccessGroupFromStaticValuesService } from "./access-group-from-static-v import { AccessGroupService } from "./access-group.service"; import { AccessGroupFromGraphQLApiService } from "./access-group-from-graphql-api-call.service"; import { AccessGroupFromPayloadService } from "./access-group-from-payload.service"; +import { AccessGroupFromRestApiService } from "./access-group-from-rest-api-call.service"; import { HttpService } from "@nestjs/axios"; import { AccessGroupFromMultipleProvidersService } from "./access-group-from-multiple-providers.service"; import { Logger } from "@nestjs/common"; @@ -23,6 +24,8 @@ export const accessGroupServiceFactory = { "accessGroupsOIDCPayloadConfig", ); + const accessGroupsRestConfig = configService.get("accessGroupsRestConfig"); + const accessGroupServices: AccessGroupService[] = []; if (accessGroupsStaticConfig?.enabled == true) { Logger.log( @@ -70,6 +73,23 @@ export const accessGroupServiceFactory = { }, ); } + if (accessGroupsRestConfig?.enabled == true) { + Logger.log( + JSON.stringify(accessGroupsRestConfig), + "loading REST API processor", + ); + accessGroupServices.push( + new AccessGroupFromRestApiService( + accessGroupsRestConfig.apiUrl, + { + [accessGroupsRestConfig.authKey]: + accessGroupsRestConfig.token.trim(), + }, + accessGroupsRestConfig.userIdField || "userId", + new HttpService(), + ), + ); + } return new AccessGroupFromMultipleProvidersService(accessGroupServices); }, diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 6d50a13e0..757736c68 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -298,6 +298,14 @@ const configuration = () => { enabled: boolean(process.env?.ACCESS_GROUPS_OIDCPAYLOAD_ENABLED || false), accessGroupProperty: process.env?.OIDC_ACCESS_GROUPS_PROPERTY, // Example: groups }, + accessGroupsRestConfig: { + enabled: boolean(process.env?.ACCESS_GROUPS_REST_ENABLED || false), + authKey: + process.env?.ACCESS_GROUPS_SERVICE_REST_AUTH_KEY || "Authorization", + token: process.env.ACCESS_GROUPS_SERVICE_REST_AUTH_VALUE, + apiUrl: process.env.ACCESS_GROUPS_SERVICE_REST_API_URL, + userIdField: process.env.ACCESS_GROUPS_SERVICE_REST_USER_ID_FIELD, + }, doiPrefix: process.env.DOI_PREFIX, expressSession: { secret: process.env.EXPRESS_SESSION_SECRET, From 290c17cd4751d32bbd9736cce8b28e61fa267357 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:23:47 +0000 Subject: [PATCH 115/120] build(deps): bump liquidjs from 10.25.1 to 10.25.5 Bumps [liquidjs](https://github.com/harttle/liquidjs) from 10.25.1 to 10.25.5. - [Release notes](https://github.com/harttle/liquidjs/releases) - [Changelog](https://github.com/harttle/liquidjs/blob/master/CHANGELOG.md) - [Commits](https://github.com/harttle/liquidjs/compare/v10.25.1...v10.25.5) --- updated-dependencies: - dependency-name: liquidjs dependency-version: 10.25.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24efc0419..48abf9a73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10653,9 +10653,9 @@ } }, "node_modules/liquidjs": { - "version": "10.25.1", - "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.1.tgz", - "integrity": "sha512-D+jsJvkGigFn8qNUgh8U6XNHhGFBp+p8Dk26ea/Hl+XrjFVSg9OXlN31hGAfS3MYQ3Kr8Xi9sEVBVQa/VTVSmg==", + "version": "10.25.5", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.5.tgz", + "integrity": "sha512-GKiKeZjJDdVoQAu+S9rzkYsYnYhcep5W3WwZXgb5f+yq484P/k9JqamBbGYu+LBEixcUAXZr2jogdAIjB3ki1w==", "license": "MIT", "optional": true, "dependencies": { From 6bb2748a3461fb393330a53e5f9e5bc4e2aeaf28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:32:21 +0000 Subject: [PATCH 116/120] build(deps): bump nodemailer and preview-email Bumps [nodemailer](https://github.com/nodemailer/nodemailer) and [preview-email](https://github.com/forwardemail/test-preview-emails-cross-browsers-ios-simulator-nodejs-javascript). These dependencies needed to be updated together. Updates `nodemailer` from 8.0.3 to 8.0.5 - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v8.0.3...v8.0.5) Updates `preview-email` from 3.1.1 to 3.1.3 - [Release notes](https://github.com/forwardemail/test-preview-emails-cross-browsers-ios-simulator-nodejs-javascript/releases) - [Commits](https://github.com/forwardemail/test-preview-emails-cross-browsers-ios-simulator-nodejs-javascript/compare/v3.1.1...v3.1.3) --- updated-dependencies: - dependency-name: nodemailer dependency-version: 8.0.5 dependency-type: indirect - dependency-name: preview-email dependency-version: 3.1.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 289 ++++++++++++---------------------------------- 1 file changed, 76 insertions(+), 213 deletions(-) diff --git a/package-lock.json b/package-lock.json index 48abf9a73..5d4a492f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4829,6 +4829,32 @@ "libqp": "2.1.1" } }, + "node_modules/@zone-eu/mailsplit/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@zone-eu/mailsplit/node_modules/libmime": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.7.tgz", + "integrity": "sha512-FlDb3Wtha8P01kTL3P9M+ZDNDWPKPmKHWaU/cG/lg5pfuAwdflVpZE+wm9m7pKmC5ww6s+zTxBKS1p6yl3KpSw==", + "license": "MIT", + "optional": true, + "dependencies": { + "encoding-japanese": "2.2.0", + "iconv-lite": "0.6.3", + "libbase64": "1.3.0", + "libqp": "2.1.1" + } + }, "node_modules/a-sync-waterfall": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", @@ -6862,17 +6888,20 @@ } }, "node_modules/display-notification": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/display-notification/-/display-notification-2.0.0.tgz", - "integrity": "sha512-TdmtlAcdqy1NU+j7zlkDdMnCL878zriLaBmoD9quOoq1ySSSGv03l0hXK5CvIFZlIfFI/hizqdQuW+Num7xuhw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/display-notification/-/display-notification-3.0.0.tgz", + "integrity": "sha512-/qAvqRy4zWP847zJc1GvXOc+AV1l9/ECKPA7APrLnqjur0o5liMM4bDJ/b1hnJo6Tyb5BfOHyyd4vn9lCh/NSg==", "license": "MIT", "optional": true, "dependencies": { - "escape-string-applescript": "^1.0.0", - "run-applescript": "^3.0.0" + "escape-string-applescript": "^3.0.0", + "run-applescript": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/doctypes": { @@ -7258,13 +7287,16 @@ "license": "MIT" }, "node_modules/escape-string-applescript": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", - "integrity": "sha512-4/hFwoYaC6TkpDn9A3pTC52zQPArFeXuIfhUtCGYdauTzXVP9H3BDr3oO/QzQehMpLDC7srvYgfwvImPFGfvBA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-3.0.0.tgz", + "integrity": "sha512-Wru0bY9XSICPNsy7KwbAZww9SLkoYjP9GtJkmnQOEqOy9U13KA0OJXoti7FaVMsiQ0mQfh916/xoByM6PqdW4g==", "license": "MIT", "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escape-string-regexp": { @@ -7616,7 +7648,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -7640,7 +7672,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/exit-x": { @@ -8416,7 +8448,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -8804,7 +8836,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -10584,31 +10616,18 @@ "optional": true }, "node_modules/libmime": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.7.tgz", - "integrity": "sha512-FlDb3Wtha8P01kTL3P9M+ZDNDWPKPmKHWaU/cG/lg5pfuAwdflVpZE+wm9m7pKmC5ww6s+zTxBKS1p6yl3KpSw==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.8.tgz", + "integrity": "sha512-ZrCY+Q66mPvasAfjsQ/IgahzoBvfE1VdtGRpo1hwRB1oK3wJKxhKA3GOcd2a6j7AH5eMFccxK9fBoCpRZTf8ng==", "license": "MIT", "optional": true, "dependencies": { "encoding-japanese": "2.2.0", - "iconv-lite": "0.6.3", + "iconv-lite": "0.7.2", "libbase64": "1.3.0", "libqp": "2.1.1" } }, - "node_modules/libmime/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/libphonenumber-js": { "version": "1.12.40", "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.40.tgz", @@ -10867,9 +10886,9 @@ } }, "node_modules/mailparser": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.9.5.tgz", - "integrity": "sha512-i5mXdEqDrh7I095uiQiebOrc00AOIJRLlpze1nBb82oZpI4GaCJIn9ypXR2bqb/Ayr7q+nmT6k11yYU5Age/Gg==", + "version": "3.9.8", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.9.8.tgz", + "integrity": "sha512-7jSlFGXiianVnhnb6wdutJFloD34488nrHY7r6FNqwXAhZ7YiJDYrKKTxZJ0oSrXcAPHm8YoYnh97xyGtrBQ3w==", "license": "MIT", "optional": true, "dependencies": { @@ -10878,9 +10897,9 @@ "he": "1.2.0", "html-to-text": "9.0.5", "iconv-lite": "0.7.2", - "libmime": "5.3.7", + "libmime": "5.3.8", "linkify-it": "5.0.0", - "nodemailer": "8.0.3", + "nodemailer": "8.0.5", "punycode.js": "2.3.1", "tlds": "1.261.0" } @@ -11008,7 +11027,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/methods": { @@ -11118,7 +11137,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -12057,13 +12076,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "license": "MIT" }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "license": "MIT", - "optional": true - }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -12154,9 +12166,9 @@ "license": "MIT" }, "node_modules/nodemailer": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.3.tgz", - "integrity": "sha512-JQNBqvK+bj3NMhUFR3wmCl3SYcOeMotDiwDBvIoCuQdF0PvlIY0BH+FJ2CG7u4cXKPChplE78oowlH/Otsc4ZQ==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.5.tgz", + "integrity": "sha512-0PF8Yb1yZuQfQbq+5/pZJrtF6WQcjTd5/S4JOHs9PGFxuTqoB/icwuB44pOdURHJbRKX1PPoJZtY7R4VUoCC8w==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -12176,7 +12188,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -12316,7 +12328,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -13590,18 +13602,18 @@ } }, "node_modules/preview-email": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.1.1.tgz", - "integrity": "sha512-nrdhnt+E9ClJ4khk9rNzqgsxubH7xSJSKoqXx/7aed2eghegNGNWkSGOelNgFgUtMz3LmKGks0waH2NuXWWmPg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.1.3.tgz", + "integrity": "sha512-M/R82S5iYDpNJIPcrtc3OToNbUATXmuV3b3bEcyOnTFzThjkChJqpoOwlm7AXvpEKZ9OFaglOsl/RxU5cnMC6g==", "license": "MIT", "optional": true, "dependencies": { "ci-info": "^3.8.0", - "display-notification": "2.0.0", + "display-notification": "^3.0.0", "fixpack": "^4.0.0", "get-port": "5.1.1", - "mailparser": "^3.9.1", - "nodemailer": "^7.0.12", + "mailparser": "^3.9.6", + "nodemailer": "^8.0.4", "open": "7", "p-event": "4.2.0", "p-wait-for": "3.2.0", @@ -13628,16 +13640,6 @@ "node": ">=8" } }, - "node_modules/preview-email/node_modules/nodemailer": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", - "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", - "license": "MIT-0", - "optional": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/preview-email/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -14138,148 +14140,19 @@ "license": "MIT" }, "node_modules/run-applescript": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz", - "integrity": "sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==", - "license": "MIT", - "optional": true, - "dependencies": { - "execa": "^0.10.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/run-applescript/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", - "license": "MIT", - "optional": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/run-applescript/node_modules/execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "license": "MIT", - "optional": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/run-applescript/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/run-applescript/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/run-applescript/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "license": "MIT", - "optional": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/run-applescript/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/run-applescript/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/run-applescript/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", "license": "MIT", "optional": true, "dependencies": { - "shebang-regex": "^1.0.0" + "execa": "^5.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/run-applescript/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/run-applescript/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC", - "optional": true - }, - "node_modules/run-applescript/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" + "node": ">=12" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/rxjs": { @@ -14857,21 +14730,11 @@ "node": ">=8" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" From fb15a66f89267153e5222f32c2fd6f8a85d343a4 Mon Sep 17 00:00:00 2001 From: Omkar Zade Date: Thu, 9 Apr 2026 18:19:37 +0200 Subject: [PATCH 117/120] feat: update relationship schema (#2661) --- src/datasets/dto/create-relationship.dto.ts | 50 ++++++++++++++--- .../dto/update-dataset-obsolete.dto.ts | 10 ++-- src/datasets/dto/update-dataset.dto.ts | 8 +-- src/datasets/schemas/dataset.schema.ts | 6 +- src/datasets/schemas/relationship.schema.ts | 40 ++++++++++++-- .../related-identifier-validator.util.spec.ts | 55 +++++++++++++++++++ .../related-identifier-validator.util.ts | 36 ++++++++++++ 7 files changed, 180 insertions(+), 25 deletions(-) create mode 100644 src/datasets/utils/related-identifier-validator.util.spec.ts create mode 100644 src/datasets/utils/related-identifier-validator.util.ts diff --git a/src/datasets/dto/create-relationship.dto.ts b/src/datasets/dto/create-relationship.dto.ts index 8054c330e..c1d24cee1 100644 --- a/src/datasets/dto/create-relationship.dto.ts +++ b/src/datasets/dto/create-relationship.dto.ts @@ -1,20 +1,54 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsString } from "class-validator"; +import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; +import { IsOptional, IsString, Validate } from "class-validator"; +import { RelatedIdentifierMatchesType } from "../utils/related-identifier-validator.util"; export class CreateRelationshipDto { @ApiProperty({ type: String, required: true, - description: "Persistent identifier of the related dataset.", + description: + "Identifier of the related entity (e.g. 'https://example.org/datasets/123', '10.1016/j.epsl.2011.11.037', 'arXiv:0706.0001').", }) + @Validate(RelatedIdentifierMatchesType) @IsString() - readonly pid: string; + readonly identifier: string; - @ApiProperty({ + @ApiPropertyOptional({ type: String, - required: true, - description: "Relationship between this dataset and the related one.", + description: + "Type of the related identifier (e.g., 'URL', 'DOI', 'arXiv', 'Other'). We may use 'Local' for SciCat identifiers", + default: "Other", + }) + @IsString() + @IsOptional() + readonly identifierType?: string; + + @ApiPropertyOptional({ + type: String, + description: + "Relationship between this dataset and the related entity (e.g., 'IsReferencedBy', 'IsSupplementTo', 'IsCitedBy').", + default: "IsReferencedBy", + }) + @IsString() + @IsOptional() + readonly relationship?: string; + + @ApiPropertyOptional({ + type: String, + description: + "Type of the related entity (e.g., 'Dataset', 'Logbook', 'Other').", + default: "Other", + }) + @IsString() + @IsOptional() + readonly entityType?: string; + + @ApiPropertyOptional({ + type: String, + description: + "Identifier of the related entity in the external system. Not used for SciCat-internal relationships.", }) @IsString() - relationship: string; + @IsOptional() + readonly externalId?: string; } diff --git a/src/datasets/dto/update-dataset-obsolete.dto.ts b/src/datasets/dto/update-dataset-obsolete.dto.ts index fe6ca09e8..00ddd66f9 100644 --- a/src/datasets/dto/update-dataset-obsolete.dto.ts +++ b/src/datasets/dto/update-dataset-obsolete.dto.ts @@ -23,7 +23,6 @@ import { import { TechniqueClass } from "../schemas/technique.schema"; import { Type, Transform } from "class-transformer"; import { CreateTechniqueDto } from "./create-technique.dto"; -import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; import { encodeScientificMetadataKeys } from "src/common/utils"; @@ -246,17 +245,18 @@ export class UpdateDatasetObsoleteDto extends OwnableDto { // it needs to be discussed if this fields is managed by the user or by the system @ApiProperty({ - type: "array", - items: { $ref: getSchemaPath(RelationshipClass) }, + type: CreateRelationshipDto, required: false, + isArray: true, default: [], - description: "Stores the relationships with other datasets.", + description: `Array of relationships with other entities (possibly external to the catalog). + Inspired by DataCite's relatedIdentifier schema: https://datacite-metadata-schema.readthedocs.io/en/4.7/properties/relatedidentifier/`, }) @IsArray() @IsOptional() @ValidateNested({ each: true }) @Type(() => CreateRelationshipDto) - readonly relationships?: RelationshipClass[]; + readonly relationships?: CreateRelationshipDto[]; @ApiProperty({ type: LifecycleClass, diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index 1fc2a098d..57848a7a0 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -23,7 +23,6 @@ import { import { TechniqueClass } from "../schemas/technique.schema"; import { Transform, Type } from "class-transformer"; import { CreateTechniqueDto } from "./create-technique.dto"; -import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; import { HistoryClass } from "../schemas/history.schema"; @@ -249,17 +248,18 @@ export class UpdateDatasetDto extends OwnableDto { // it needs to be discussed if this fields is managed by the user or by the system @ApiProperty({ - type: RelationshipClass, + type: CreateRelationshipDto, required: false, isArray: true, default: [], - description: "Stores the relationships with other datasets.", + description: `Array of relationships with other entities (possibly external to the catalog). + Inspired by DataCite's relatedIdentifier schema: https://datacite-metadata-schema.readthedocs.io/en/4.7/properties/relatedidentifier/`, }) @IsArray() @IsOptional() @ValidateNested({ each: true }) @Type(() => CreateRelationshipDto) - readonly relationships?: RelationshipClass[]; + readonly relationships?: CreateRelationshipDto[]; @ApiProperty({ type: LifecycleClass, diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 8f4f8a15e..9a8af6c39 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -290,8 +290,8 @@ export class DatasetClass extends OwnableClass { items: { $ref: getSchemaPath(RelationshipClass) }, required: false, default: [], - description: - "Array of relationships with other datasets. It contains relationship type and destination dataset", + description: `Array of relationships with other entities (possibly external to the catalog). + Inspired by DataCite's relatedIdentifier schema: https://datacite-metadata-schema.readthedocs.io/en/4.7/properties/relatedidentifier/`, }) @Prop({ type: [RelationshipSchema], required: false, default: [] }) relationships?: RelationshipClass[]; @@ -481,3 +481,5 @@ export class DatasetClass extends OwnableClass { export const DatasetSchema = SchemaFactory.createForClass(DatasetClass); DatasetSchema.index({ "$**": "text" }); +DatasetSchema.index({ "relationships.identifier": 1 }); +DatasetSchema.index({ "relationships.externalId": 1 }); diff --git a/src/datasets/schemas/relationship.schema.ts b/src/datasets/schemas/relationship.schema.ts index 200f0e5cb..63ff5b848 100644 --- a/src/datasets/schemas/relationship.schema.ts +++ b/src/datasets/schemas/relationship.schema.ts @@ -1,5 +1,5 @@ import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; -import { ApiProperty } from "@nestjs/swagger"; +import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; import { Document } from "mongoose"; export type RelationshipDocument = RelationshipClass & Document; @@ -9,18 +9,46 @@ export class RelationshipClass { @ApiProperty({ type: String, required: true, - description: "Persistent identifier of the related dataset.", + description: + "Identifier of the related entity (e.g. 'https://example.org/datasets/123', '10.1016/j.epsl.2011.11.037', 'arXiv:0706.0001')", }) @Prop({ type: String, required: true }) - pid: string; + identifier: string; @ApiProperty({ type: String, - required: true, - description: "Relationship between this dataset and the related one.", + description: + "Type of the related `identifier` (e.g., 'URL', 'DOI', 'arXiv', 'Other'). We may use 'Local' for SciCat identifiers", + default: "Other", }) - @Prop({ type: String, required: true }) + @Prop({ type: String, default: "Other" }) + identifierType: string; + + @ApiProperty({ + type: String, + description: + "Relationship between this dataset and the related entity (e.g., 'IsReferencedBy', 'IsSupplementTo', 'IsCitedBy').", + default: "IsReferencedBy", + }) + @Prop({ type: String, default: "IsReferencedBy" }) relationship: string; + + @ApiProperty({ + type: String, + description: + "Type of the related entity (e.g., 'Dataset', 'Logbook', 'Other').", + default: "Other", + }) + @Prop({ type: String, default: "Other" }) + entityType: string; + + @ApiPropertyOptional({ + type: String, + description: + "Identifier of the related entity in the external system. Not used for SciCat-internal relationships.", + }) + @Prop({ type: String, required: false }) + externalId?: string; } export const RelationshipSchema = diff --git a/src/datasets/utils/related-identifier-validator.util.spec.ts b/src/datasets/utils/related-identifier-validator.util.spec.ts new file mode 100644 index 000000000..b3fd04690 --- /dev/null +++ b/src/datasets/utils/related-identifier-validator.util.spec.ts @@ -0,0 +1,55 @@ +import { CreateRelationshipDto } from "../dto/create-relationship.dto"; +import { RelatedIdentifierMatchesType } from "./related-identifier-validator.util"; +import { ValidationArguments } from "class-validator"; + +describe("RelatedIdentifierMatchesType", () => { + const validator = new RelatedIdentifierMatchesType(); + + const makeArgs = ( + object: Partial, + ): ValidationArguments => + ({ + targetName: "CreateRelationshipDto", + object, + property: "identifier", + value: object.identifier, + constraints: [], + }) as ValidationArguments; + + it("validates URL when identifierType is URL", () => { + expect( + validator.validate( + "https://example.org/datasets/123", + makeArgs({ + identifier: "https://example.org/datasets/123", + identifierType: "URL", + }), + ), + ).toBe(true); + }); + + it("rejects invalid URL when identifierType is URL", () => { + expect( + validator.validate( + "noturl/datasets/123", + makeArgs({ + identifier: "noturl/datasets/123", + identifierType: "URL", + }), + ), + ).toBe(false); + }); + + it("accepts any string when identifierType is missing", () => { + expect( + validator.validate("anything123", makeArgs({ identifier: "Other" })), + ).toBe(true); + }); + + it("provides a descriptive default message", () => { + const message = validator.defaultMessage( + makeArgs({ identifier: "foo", identifierType: "URL" }), + ); + expect(message).toContain("URL"); + }); +}); diff --git a/src/datasets/utils/related-identifier-validator.util.ts b/src/datasets/utils/related-identifier-validator.util.ts new file mode 100644 index 000000000..3d16ae954 --- /dev/null +++ b/src/datasets/utils/related-identifier-validator.util.ts @@ -0,0 +1,36 @@ +import { Injectable } from "@nestjs/common"; +import { + ValidatorConstraint, + ValidatorConstraintInterface, + ValidationArguments, + isURL, +} from "class-validator"; +import { CreateRelationshipDto } from "../dto/create-relationship.dto"; + +@Injectable() +@ValidatorConstraint({ + name: "relatedIdentifierMatchesType", + async: false, +}) +export class RelatedIdentifierMatchesType implements ValidatorConstraintInterface { + validate(value: unknown, args: ValidationArguments) { + if (typeof value !== "string") { + return false; + } + + const dto = args.object as Partial; + + switch (dto.identifierType) { + case "URL": + return isURL(value); + default: + return true; + } + } + + defaultMessage(args: ValidationArguments) { + const dto = args.object as Partial; + const type = dto.identifierType ?? "the configured type"; + return `identifier must be a valid ${type} when identifierType is set to '${dto.identifierType}'.`; + } +} From 853518d114fe19b6588dbc13c18640085da93e12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 06:10:11 +0000 Subject: [PATCH 118/120] build(deps): bump axios from 1.13.6 to 1.15.0 Bumps [axios](https://github.com/axios/axios) from 1.13.6 to 1.15.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.13.6...v1.15.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.15.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d4a492f2..9c71c0e59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5231,14 +5231,14 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", - "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", + "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" } }, "node_modules/babel-jest": { @@ -13678,10 +13678,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/pug": { "version": "3.0.4", From e27ab9b13efa5329e53f03d04c694e4f439c23bc Mon Sep 17 00:00:00 2001 From: fpotier <58594145+fpotier@users.noreply.github.com> Date: Fri, 10 Apr 2026 15:48:46 +0200 Subject: [PATCH 119/120] docs: add description for `/publisheddata/config` endpoint (#2665) --- .../dto/published-data-config.dto.ts | 18 ++++++++++++++++++ .../interfaces/published-data.interface.ts | 5 ----- .../published-data.v4.controller.ts | 5 +++++ src/published-data/validator.service.ts | 8 ++++---- 4 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 src/published-data/dto/published-data-config.dto.ts diff --git a/src/published-data/dto/published-data-config.dto.ts b/src/published-data/dto/published-data-config.dto.ts new file mode 100644 index 000000000..d28aabbd5 --- /dev/null +++ b/src/published-data/dto/published-data-config.dto.ts @@ -0,0 +1,18 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsObject } from "class-validator"; + +export class PublishedDataConfigDto { + @IsObject() + @ApiProperty({ + description: + "[JSON schema](https://json-schema.org/docs) defining the structure for the metadata property of PublishedData objects.", + }) + metadataSchema: Record; + + @IsObject() + @ApiProperty({ + description: + "[UI schema](https://jsonforms.io/docs/uischema/) to use in the frontend for metadata edition", + }) + uiSchema: Record; +} diff --git a/src/published-data/interfaces/published-data.interface.ts b/src/published-data/interfaces/published-data.interface.ts index c1e77ffdc..b67ccd552 100644 --- a/src/published-data/interfaces/published-data.interface.ts +++ b/src/published-data/interfaces/published-data.interface.ts @@ -47,8 +47,3 @@ export enum PublishedDataStatus { REGISTERED = "registered", AMENDED = "amended", } - -export interface PublishedDataConfig { - metadataSchema: unknown; - uiSchema: unknown; -} diff --git a/src/published-data/published-data.v4.controller.ts b/src/published-data/published-data.v4.controller.ts index 6ed23c5c0..3101aa75f 100644 --- a/src/published-data/published-data.v4.controller.ts +++ b/src/published-data/published-data.v4.controller.ts @@ -59,6 +59,7 @@ import { PublishedDataDocument, } from "./schemas/published-data.schema"; import { ValidatorService } from "./validator.service"; +import { PublishedDataConfigDto } from "./dto/published-data-config.dto"; @ApiBearerAuth() @ApiTags("published data v4") @@ -83,6 +84,10 @@ export class PublishedDataV4Controller { @AllowAny() @Get("config") + @ApiResponse({ + status: HttpStatus.OK, + type: PublishedDataConfigDto, + }) async getConfig(): Promise | null> { return this.publishedDataService.getConfig(); } diff --git a/src/published-data/validator.service.ts b/src/published-data/validator.service.ts index 8b884b039..80550fc93 100644 --- a/src/published-data/validator.service.ts +++ b/src/published-data/validator.service.ts @@ -15,7 +15,7 @@ import { PartialUpdatePublishedDataV4Dto, UpdatePublishedDataV4Dto, } from "./dto/update-published-data.v4.dto"; -import { PublishedDataConfig } from "./interfaces/published-data.interface"; +import { PublishedDataConfigDto } from "./dto/published-data-config.dto"; export type ReadOnlyProposalsService = Pick< ProposalsService, @@ -33,7 +33,7 @@ export type ReadOnlyAttachmentsService = Pick< @Injectable() export class ValidatorService { private ajv: Ajv2019; - private config: PublishedDataConfig; + private config: PublishedDataConfigDto; private dynamicDefaults: Map = new Map([ ["currentYear", () => () => new Date().getFullYear()], ]); @@ -52,9 +52,9 @@ export class ValidatorService { addFormats(this.ajv); addKeywords(this.ajv); - this.config = this.configService.get( + this.config = this.configService.get( "publishedDataConfig", - { metadataSchema: null, uiSchema: null }, + { metadataSchema: {}, uiSchema: {} }, ); if (isNil(this.config.metadataSchema)) { From 5cc089c035efd3161bb55480639e9ce170c46651 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 22:54:15 +0000 Subject: [PATCH 120/120] build(deps): bump mathjs from 15.1.1 to 15.2.0 Bumps [mathjs](https://github.com/josdejong/mathjs) from 15.1.1 to 15.2.0. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v15.1.1...v15.2.0) --- updated-dependencies: - dependency-name: mathjs dependency-version: 15.2.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c71c0e59..78f73778c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10947,9 +10947,9 @@ } }, "node_modules/mathjs": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.1.1.tgz", - "integrity": "sha512-rM668DTtpSzMVoh/cKAllyQVEbBApM5g//IMGD8vD7YlrIz9ITRr3SrdhjaDxcBNTdyETWwPebj2unZyHD7ZdA==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.2.0.tgz", + "integrity": "sha512-UAQzSVob9rNLdGpqcFMYmSu9dkuLYy7Lr2hBEQS5SHQdknA9VppJz3cy2KkpMzTODunad6V6cNv+5kOLsePLow==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.26.10",