diff --git a/Dockerfile b/Dockerfile index 8800af7e3..9e9b964ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ ARG SQUIDEX__BUILD__ARGS RUN echo "ARGS IS $SQUIDEX__BUILD__ARGS" -WORKDIR /build +WORKDIR /source # Copy nuget project files. COPY backend/Directory.Build.props ./ @@ -57,7 +57,7 @@ RUN dotnet tool install --tool-path /tools dotnet-dump \ # FROM squidex/frontend-build:22.19 AS frontend -WORKDIR /build +WORKDIR /source ENV CONTINUOUS_INTEGRATION=1 diff --git a/README.md b/README.md index 6b4828e45..837147e28 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Squidex Logo](https://raw.githubusercontent.com/Squidex/squidex/master/media/logo-wide.png "Squidex") -# What is Squidex? +# What is Squidex?? Squidex is an open source headless CMS and content management hub. In contrast to a traditional CMS Squidex provides a rich API with OData filter and Swagger definitions. It is up to you to build your UI on top of it. It can be website, a native app or just another server. We build it with ASP.NET Core and CQRS and is tested for Windows and Linux on modern browsers. diff --git a/dev/frontend-build/Dockerfile b/dev/frontend-build/Dockerfile index b30742c67..3d34ff625 100644 --- a/dev/frontend-build/Dockerfile +++ b/dev/frontend-build/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22.19.0-slim +FROM node:24.13.0-slim ENV CHROME_BIN=/usr/bin/chromium diff --git a/frontend/angular.json b/frontend/angular.json index 7872244e6..317d9a84e 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -170,7 +170,12 @@ "defaultConfiguration": "development" }, "test": { - "builder": "@angular/build:unit-test" + "builder": "@angular/build:unit-test", + "options": { + "tsConfig": "./tsconfig.spec.json", + "runnerConfig": "vitest.config.js", + "setupFiles": ["./src/test-setup.ts"] + } }, "storybook": { "builder": "@storybook/angular:start-storybook", diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index 70be07204..9f736c3f1 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -4,7 +4,6 @@ const { const globals = require("globals"); const tsParser = require("@typescript-eslint/parser"); -const deprecation = require("eslint-plugin-deprecation"); const importPlugin = require("eslint-plugin-import"); const typescriptEslint = require("@typescript-eslint/eslint-plugin"); @@ -42,7 +41,6 @@ module.exports = defineConfig([{ ), plugins: { - deprecation, import: importPlugin, "@typescript-eslint": typescriptEslint, }, diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a9d5c7b69..0e7970371 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -90,8 +90,6 @@ "@typescript-eslint/parser": "^8.54.0", "copy-webpack-plugin": "^13.0.1", "eslint": "^9.39.2", - "eslint-config-airbnb-typescript": "18.0.0", - "eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-import": "2.32.0", "eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-storybook": "^10.2.7", @@ -105,7 +103,7 @@ "stylelint-scss": "7.0.0", "typescript": "5.9.3", "vite-tsconfig-paths": "^6.0.5", - "vitest": "^4.0.18" + "vitest": "^4.0.8" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -441,24 +439,6 @@ } } }, - "node_modules/@angular-devkit/architect/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/architect/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -479,7 +459,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -735,24 +714,6 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -831,7 +792,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -888,7 +848,6 @@ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.0.2.tgz", "integrity": "sha512-QXcEdfmODc0rKblBerk30yw70fypIkFm6gQBLJgsshpwc+TMA+fuMLcPQebOTzKLtD2tNUkk/7SrWPQIGqeXaA==", "dev": true, - "peer": true, "dependencies": { "ajv": "8.13.0", "ajv-formats": "3.0.1", @@ -916,7 +875,6 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, - "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -933,15 +891,13 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@angular-devkit/core/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, - "peer": true, "engines": { "node": ">=12" }, @@ -955,7 +911,6 @@ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -964,7 +919,6 @@ "version": "0.7.4", "dev": true, "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">= 8" } @@ -1051,24 +1005,6 @@ } } }, - "node_modules/@angular-devkit/schematics/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -1089,7 +1025,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -1187,24 +1122,6 @@ } } }, - "node_modules/@angular-eslint/builder/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-eslint/builder/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -1225,7 +1142,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -1380,24 +1296,6 @@ } } }, - "node_modules/@angular-eslint/schematics/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-eslint/schematics/node_modules/ignore": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", @@ -1428,7 +1326,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -1466,6 +1363,7 @@ "integrity": "sha512-TCb3qYOC/uXKZCo56cJ6N9sHeWdFhyVqrbbYfFjTi09081T6jllgHDZL5Ms7gOMNY8KywWGGbhxwvzeA0RwTgA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@angular-eslint/bundled-angular-compiler": "21.2.0", "eslint-scope": "^9.0.0" @@ -1519,23 +1417,6 @@ "typescript": "*" } }, - "node_modules/@angular/animations": { - "version": "21.1.3", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.1.3.tgz", - "integrity": "sha512-UADMncDd9lkmIT1NPVFcufyP5gJHMPzxNaQpojiGrxT1aT8Du30mao0KSrB4aTwcicv6/cdD5bZbIyg+FL6LkQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" - }, - "peerDependencies": { - "@angular/core": "21.1.3" - } - }, "node_modules/@angular/build": { "version": "21.1.3", "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.1.3.tgz", @@ -1732,6 +1613,7 @@ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.1.3.tgz", "integrity": "sha512-jMiEKCcZMIAnyx2jxrJHmw5c7JXAiN56ErZ4X+OuQ5yFvYRocRVEs25I0OMxntcXNdPTJQvpGwGlhWhS0yDorg==", "license": "MIT", + "peer": true, "dependencies": { "parse5": "^8.0.0", "tslib": "^2.3.0" @@ -1762,6 +1644,7 @@ "integrity": "sha512-UPtDcpKyrKZRPfym9gTovcibPzl2O/Woy7B8sm45sAnjDH+jDUCcCvuIak7GpH47shQkC2J4yvnHZbD4c6XxcQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@angular-devkit/architect": "0.2101.3", "@angular-devkit/core": "21.1.3", @@ -1855,24 +1738,6 @@ } } }, - "node_modules/@angular/cli/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular/cli/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -1893,7 +1758,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -1930,6 +1794,7 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.1.3.tgz", "integrity": "sha512-Wdbln/UqZM5oVnpfIydRdhhL8A9x3bKZ9Zy1/mM0q+qFSftPvmFZIXhEpFqbDwNYbGUhGzx7t8iULC4sVVp/zA==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1946,6 +1811,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.1.3.tgz", "integrity": "sha512-gDNLh7MEf7Qf88ktZzS4LJQXCA5U8aQTfK9ak+0mi2ruZ0x4XSjQCro4H6OPKrrbq94+6GcnlSX5+oVIajEY3w==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1958,6 +1824,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.1.3.tgz", "integrity": "sha512-nKxoQ89W2B1WdonNQ9kgRnvLNS6DAxDrRHBslsKTlV+kbdv7h59M9PjT4ZZ2sp1M/M8LiofnUfa/s2jd/xYj5w==", "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "7.28.5", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -2063,6 +1930,7 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-21.1.3.tgz", "integrity": "sha512-TbhQxRC7Lb/3WBdm1n8KRsktmVEuGBBp0WRF5mq0Ze4s1YewIM6cULrSw9ACtcL5jdcq7c74ms+uKQsaP/gdcQ==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2193,6 +2061,7 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.1.3.tgz", "integrity": "sha512-W+ZMXAioaP7CsACafBCHsIxiiKrRTPOlQ+hcC7XNBwy+bn5mjGONoCgLreQs76M8HNWLtr/OAUAr6h26OguOuA==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2215,6 +2084,7 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.1.3.tgz", "integrity": "sha512-wWEjrNtJfxzZmbDWdJSyRau7NWpQ6IFM9QAyn7xH3cQDGCj+Gy9lTU5sUIYQc+7sx3nKWztolc7h/M5meYCTAg==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2233,6 +2103,7 @@ "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-21.1.3.tgz", "integrity": "sha512-o6S9t52d00PKC9nAjN3DXkLiY41iQvpLLl2DnerNU23njA7lF3mwH2+IJxVPB0EkR/H9rAJr+7bo/S9LUoU7xw==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0", "xhr2": "^0.2.0" @@ -2253,6 +2124,7 @@ "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.1.3.tgz", "integrity": "sha512-uAw4LAMHXAPCe4SywhlUEWjMYVbbLHwTxLyduSp1b+9aVwep0juy5O/Xttlxd/oigVe0NMnOyJG9y1Br/ubnrg==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2358,6 +2230,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -2381,6 +2254,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -2434,6 +2308,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -4114,6 +3989,7 @@ "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } @@ -4159,7 +4035,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", "license": "MIT", - "peer": true, "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } @@ -4169,7 +4044,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.1.tgz", "integrity": "sha512-Qy4CAUwngy/VQkEz0XzMKVRcckQuqLYWKqVpDDDghBe5FSXSqfVrJn49nw3ePZHxRUz4nRmb05Lgi+9csWo4eg==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", @@ -4182,7 +4056,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=0.1.90" } @@ -4490,6 +4363,7 @@ "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "readdirp": "^5.0.0" }, @@ -4892,6 +4766,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" }, @@ -4932,6 +4807,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" } @@ -5019,6 +4895,7 @@ "node_modules/@egjs/hammerjs": { "version": "2.0.17", "license": "MIT", + "peer": true, "dependencies": { "@types/hammerjs": "^2.0.36" }, @@ -6193,6 +6070,7 @@ "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", @@ -6844,8 +6722,7 @@ "node_modules/@kurkle/color": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.1.tgz", - "integrity": "sha512-hW0GwZj06z/ZFUW2Espl7toVDjghJN+EKqyXzPSV8NV89d5BYp5rRMBJoc+aUN0x5OXDMeRQHazejr2Xmqj2tw==", - "peer": true + "integrity": "sha512-hW0GwZj06z/ZFUW2Espl7toVDjghJN+EKqyXzPSV8NV89d5BYp5rRMBJoc+aUN0x5OXDMeRQHazejr2Xmqj2tw==" }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", @@ -6858,15 +6735,13 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@lezer/highlight": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", "license": "MIT", - "peer": true, "dependencies": { "@lezer/common": "^1.0.0" } @@ -6876,7 +6751,6 @@ "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", "license": "MIT", - "peer": true, "dependencies": { "@lezer/common": "^1.0.0" } @@ -7014,8 +6888,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.26.0", @@ -9735,24 +9608,6 @@ } } }, - "node_modules/@schematics/angular/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@schematics/angular/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -9773,7 +9628,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 20.19.0" }, @@ -9918,8 +9772,7 @@ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "node_modules/@standard-schema/spec": { "version": "1.1.0", @@ -10148,6 +10001,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -10453,7 +10307,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -10590,6 +10443,7 @@ "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -10624,6 +10478,7 @@ "integrity": "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -10634,6 +10489,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -10760,6 +10616,7 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -10942,6 +10799,7 @@ "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -11048,6 +10906,7 @@ "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.54.0", @@ -11565,6 +11424,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -11649,6 +11509,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -11894,16 +11755,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/array.prototype.findlastindex": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", @@ -12188,7 +12039,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": "^4.5.0 || >= 5.9" } @@ -12539,6 +12389,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -13288,7 +13139,6 @@ "dev": true, "license": "ISC", "optional": true, - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -13330,7 +13180,8 @@ "version": "5.65.19", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.19.tgz", "integrity": "sha512-+aFkvqhaAVr1gferNMuN8vkTSrWIFvzlMV9I2KBLCWS2WpZ2+UAkZjlMZmEuT+gcXTi6RrGQCkWq1/bDtGqhIA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/codemirror-graphql": { "version": "2.2.2", @@ -13517,13 +13368,6 @@ "dev": true, "license": "MIT" }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true, - "license": "MIT" - }, "node_modules/connect": { "version": "3.7.0", "dev": true, @@ -13743,8 +13587,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cropperjs": { "version": "1.6.2", @@ -13912,8 +13755,7 @@ "version": "1.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -14013,7 +13855,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -14233,21 +14074,7 @@ "version": "0.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "optional": true }, "node_modules/dns-packet": { "version": "5.6.1", @@ -14285,7 +14112,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "custom-event": "~1.0.0", "ent": "~2.2.0", @@ -14488,7 +14314,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", @@ -14511,7 +14336,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=10.0.0" } @@ -14534,8 +14358,7 @@ "version": "2.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/entities": { "version": "2.2.0", @@ -14870,6 +14693,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -14924,50 +14748,6 @@ } } }, - "node_modules/eslint-config-airbnb-typescript": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", - "integrity": "sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==", - "dev": true, - "dependencies": { - "eslint-config-airbnb-base": "^15.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^7.0.0", - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - } - }, - "node_modules/eslint-config-airbnb-typescript/node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "license": "MIT", - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-typescript/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/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -15016,194 +14796,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-deprecation": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-3.0.0.tgz", - "integrity": "sha512-JuVLdNg/uf0Adjg2tpTyYoYaMbwQNn/c78P1HcccokvhtRphgnRjZDKmhlxbxYptppex03zO76f97DD/yQHv7A==", - "dev": true, - "license": "LGPL-3.0-or-later", - "dependencies": { - "@typescript-eslint/utils": "^7.0.0", - "ts-api-utils": "^1.3.0", - "tslib": "^2.3.1" - }, - "peerDependencies": { - "eslint": "^8.0.0", - "typescript": "^4.2.4 || ^5.0.0" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-deprecation/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/eslint-plugin-deprecation/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/ts-api-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, "node_modules/eslint-plugin-import": { "version": "2.32.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", @@ -15957,8 +15549,7 @@ "version": "3.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/fancy-log": { "version": "2.0.0", @@ -16220,6 +15811,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -16444,8 +16036,7 @@ "version": "1.0.0", "dev": true, "license": "ISC", - "optional": true, - "peer": true + "optional": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -16607,7 +16198,6 @@ "dev": true, "license": "ISC", "optional": true, - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -16809,6 +16399,7 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz", "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==", "license": "MIT", + "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -16835,6 +16426,7 @@ "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-6.0.7.tgz", "integrity": "sha512-yoLRW+KRlDmnnROdAu7sX77VNLC0bsFoZyGQJLy1cF+X/SkLg/fWkRGrEEYQK8o2cafJ2wmEaMqMEZB3U3DYDg==", "license": "MIT", + "peer": true, "engines": { "node": ">=20" }, @@ -16997,6 +16589,7 @@ "integrity": "sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=16.9.0" } @@ -17135,6 +16728,7 @@ "version": "5.5.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -17526,7 +17120,6 @@ "dev": true, "license": "ISC", "optional": true, - "peer": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -18208,7 +17801,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 8.0.0" }, @@ -18474,7 +18066,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -18521,7 +18112,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "minimist": "^1.2.6" }, @@ -18534,7 +18124,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -18553,7 +18142,6 @@ "dev": true, "license": "ISC", "optional": true, - "peer": true, "engines": { "node": ">=10" } @@ -18622,7 +18210,8 @@ "node_modules/leaflet": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "peer": true }, "node_modules/leaflet-control-geocoder": { "version": "3.3.1", @@ -18642,6 +18231,7 @@ "integrity": "sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -18800,6 +18390,7 @@ "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", @@ -19159,7 +18750,6 @@ "dev": true, "license": "Apache-2.0", "optional": true, - "peer": true, "dependencies": { "date-format": "^4.0.14", "debug": "^4.3.4", @@ -19505,7 +19095,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -20053,6 +19642,7 @@ "resolved": "https://registry.npmjs.org/ngx-scrollbar/-/ngx-scrollbar-19.1.4.tgz", "integrity": "sha512-VzmLli1Uq+tZ40s5BpBDVO5mxjeNL7L7JbVluuokKsrIfi1GmXmkx69iz0zruyVWmyzU5VeuiqhMobPYazGKOQ==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -20408,22 +19998,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.fromentries": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", @@ -21066,7 +20640,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -21253,6 +20826,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -21431,6 +21005,7 @@ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -21479,6 +21054,7 @@ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -21664,7 +21240,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=0.9" } @@ -21739,6 +21314,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -21759,6 +21335,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -22030,7 +21607,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -22176,7 +21752,6 @@ "dev": true, "license": "ISC", "optional": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -22356,6 +21931,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -23149,7 +22725,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", @@ -23170,7 +22745,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "debug": "~4.3.4", "ws": "~8.17.1" @@ -23182,7 +22756,6 @@ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" @@ -23452,6 +23025,7 @@ "integrity": "sha512-LFKSuZyF6EW2/Kkl5d7CvqgwhXXfuWv+aLBuoc616boLKJ3mxXuea+GxIgfk02NEyTKctJ0QsnSh5pAomf6Qkg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1", @@ -23595,7 +23169,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "date-format": "^4.0.14", "debug": "^4.3.4", @@ -23610,7 +23183,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -23625,7 +23197,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -23635,7 +23206,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 4.0.0" } @@ -23830,8 +23400,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/stylelint": { "version": "17.1.1", @@ -23849,6 +23418,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-syntax-patches-for-csstree": "^1.0.25", @@ -24458,6 +24028,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -24511,7 +24082,6 @@ "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=14.14" } @@ -24725,7 +24295,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/tuf-js": { "version": "4.1.0", @@ -24917,6 +24488,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -24946,7 +24518,6 @@ ], "license": "MIT", "optional": true, - "peer": true, "bin": { "ua-parser-js": "script/cli.js" }, @@ -25225,6 +24796,7 @@ "node_modules/uuid": { "version": "8.3.2", "license": "MIT", + "peer": true, "bin": { "uuid": "dist/bin/uuid" } @@ -25263,6 +24835,7 @@ "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.23.6.tgz", "integrity": "sha512-qjS3HTDo7iapedJuso62scA303i+6CaCUnwyRr8GYd/BYAp7XGb7InUMw2Eu6zrN6IWooPOb78NzyMyjRbIN+Q==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@babel/runtime": "^7.12.5", "@videojs/http-streaming": "^3.17.2", @@ -25312,6 +24885,7 @@ "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-8.0.3.tgz", "integrity": "sha512-jhnb6rJNqkKR1Qmlay0VuDXY9ZlvAnYN1udsrP4U+krgZEq7C0yNSKdZqmnCe13mdnf9AdVcdDGFOzy2mpPoqw==", "license": "(Apache-2.0 OR MIT)", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/visjs" @@ -25344,6 +24918,7 @@ "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-6.0.0.tgz", "integrity": "sha512-qtpts3HRma0zPe4bO7t9A2uejkRNj8Z2Tb6do6lN85iPNWExFkUiVhdAq5uLGIUqBFduyYeqWJKv/jMkxX0R5g==", "license": "(Apache-2.0 OR MIT)", + "peer": true, "engines": { "node": ">=8" }, @@ -25362,6 +24937,7 @@ "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -25470,6 +25046,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -25483,6 +25060,7 @@ "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", @@ -25648,7 +25226,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -25663,8 +25240,7 @@ "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", @@ -25727,6 +25303,7 @@ "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -25876,6 +25453,7 @@ "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -26700,7 +26278,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -26745,29 +26322,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/wsl-utils": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz", @@ -27066,6 +26620,7 @@ "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -27084,7 +26639,8 @@ "version": "0.16.0", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.16.0.tgz", "integrity": "sha512-LqLPpIQANebrlxY6jKcYKdgN5DTXyyHAKnnWWjE5pPfEQ4n7j5zn7mOEEpwNZVKGqx3kKKmvplEmoBrvpgROTA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/zustand": { "version": "5.0.5", diff --git a/frontend/package.json b/frontend/package.json index f51d655b1..dd3232693 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -98,8 +98,6 @@ "@typescript-eslint/parser": "^8.54.0", "copy-webpack-plugin": "^13.0.1", "eslint": "^9.39.2", - "eslint-config-airbnb-typescript": "18.0.0", - "eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-import": "2.32.0", "eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-storybook": "^10.2.7", @@ -113,7 +111,7 @@ "stylelint-scss": "7.0.0", "typescript": "5.9.3", "vite-tsconfig-paths": "^6.0.5", - "vitest": "^4.0.18" + "vitest": "^4.0.8" }, "overrides": { "ng2-charts": { diff --git a/frontend/src/app/framework/angular/forms/focus-on-init.directive.spec.ts b/frontend/src/app/framework/angular/forms/focus-on-init.directive.spec.ts index e05defec7..7e7afa265 100644 --- a/frontend/src/app/framework/angular/forms/focus-on-init.directive.spec.ts +++ b/frontend/src/app/framework/angular/forms/focus-on-init.directive.spec.ts @@ -30,27 +30,21 @@ describe('FocusOnInitDirective', () => { it('should call focus on element if init', async () => { const directive = new FocusOnInitDirective(element); + directive.scheduler = action => action(); directive.select = false; directive.ngAfterViewInit(); - setTimeout(() => { - expect(isFocusCalled).toBeTruthy(); - expect(isSelectCalled).toBeFalsy(); - - - }, 200); + expect(isFocusCalled).toBeTruthy(); + expect(isSelectCalled).toBeFalsy(); }); it('should call select on element if init', async () => { const directive = new FocusOnInitDirective(element); + directive.scheduler = action => action(); directive.select = true; directive.ngAfterViewInit(); - setTimeout(() => { - expect(isFocusCalled).toBeTruthy(); - expect(isSelectCalled).toBeTruthy(); - - - }, 200); + expect(isFocusCalled).toBeTruthy(); + expect(isSelectCalled).toBeTruthy(); }); }); diff --git a/frontend/src/app/framework/angular/forms/focus-on-init.directive.ts b/frontend/src/app/framework/angular/forms/focus-on-init.directive.ts index e22da24a0..7cc33a16e 100644 --- a/frontend/src/app/framework/angular/forms/focus-on-init.directive.ts +++ b/frontend/src/app/framework/angular/forms/focus-on-init.directive.ts @@ -18,6 +18,10 @@ export class FocusOnInitDirective implements AfterViewInit { @Input({ alias: 'sqxFocusOnInit', transform: booleanAttribute }) public enabled = true; + public scheduler: ((action: (() => void)) => void) = action => { + setTimeout(action, 200); + }; + constructor( private readonly element: ElementRef, ) { @@ -28,7 +32,7 @@ export class FocusOnInitDirective implements AfterViewInit { return; } - setTimeout(() => { + this.scheduler(() => { if (Types.isFunction(this.element.nativeElement.focus)) { this.element.nativeElement.focus(); } @@ -40,6 +44,6 @@ export class FocusOnInitDirective implements AfterViewInit { input.select(); } } - }, 100); + }); } } diff --git a/frontend/src/app/framework/services/loading.service.spec.ts b/frontend/src/app/framework/services/loading.service.spec.ts index ca8644a0b..ea201ef22 100644 --- a/frontend/src/app/framework/services/loading.service.spec.ts +++ b/frontend/src/app/framework/services/loading.service.spec.ts @@ -22,9 +22,9 @@ describe('LoadingService', () => { it('should set to loaded', () => { const loadingService = new LoadingService({ events }); + loadingService.scheduler = action => action(); let state = false; - loadingService.loading.subscribe(v => { state = v; }); @@ -35,9 +35,9 @@ describe('LoadingService', () => { it('should set to loaded on navigation start', () => { const loadingService = new LoadingService({ events }); + loadingService.scheduler = action => action(); let state = false; - loadingService.loading.subscribe(v => { state = v; }); @@ -51,7 +51,6 @@ describe('LoadingService', () => { const loadingService = new LoadingService({ events }); let state = false; - loadingService.loading.subscribe(v => { state = v; }); @@ -63,42 +62,35 @@ describe('LoadingService', () => { it('should not unset from loaded delayed', async () => { const loadingService = new LoadingService({ events }); + loadingService.scheduler = action => action(); let state = false; - loadingService.loading.subscribe(v => { state = v; }); loadingService.startLoading('1'); loadingService.completeLoading('1'); - setTimeout(() => { - expect(state).toBeFalsy(); - - - }, 400); + expect(state).toBeFalsy(); }); it('should not unset from loaded delayed on navigation event', async () => { const loadingService = new LoadingService({ events }); + loadingService.scheduler = action => action(); let state = false; - loadingService.loading.subscribe(v => { state = v; }); events.next(new NavigationStart(0, '')); events.next(new NavigationError(0, '', 0)); - setTimeout(() => { - expect(state).toBeFalsy(); - - - }, 400); + expect(state).toBeFalsy(); }); it('should set back to loaded after several completions', async () => { const loadingService = new LoadingService({ events }); + loadingService.scheduler = action => action(); let state = false; @@ -110,10 +102,6 @@ describe('LoadingService', () => { loadingService.completeLoading('1'); loadingService.startLoading('2'); - setTimeout(() => { - expect(state).toBeTruthy(); - - - }, 400); + expect(state).toBeTruthy(); }); }); diff --git a/frontend/src/app/framework/services/loading.service.ts b/frontend/src/app/framework/services/loading.service.ts index 528fe8212..84c4b7938 100644 --- a/frontend/src/app/framework/services/loading.service.ts +++ b/frontend/src/app/framework/services/loading.service.ts @@ -22,6 +22,10 @@ export class LoadingService implements OnDestroy { return this.loading$.pipe(map(x => x > 0)); } + public scheduler: ((action: (() => void)) => void) = action => { + setTimeout(action, 200); + }; + constructor(router: Router) { this.routerSubscription = router.events.subscribe(event => { @@ -54,13 +58,13 @@ export class LoadingService implements OnDestroy { if (this.loadingOperations[key]) { delete this.loadingOperations[key]; - setTimeout(() => { + this.scheduler(() => { const value = this.loading$.value; if (value > 0) { this.loading$.next(value - 1); } - }, 250); + }); } } } diff --git a/frontend/src/test-setup.ts b/frontend/src/test-setup.ts new file mode 100644 index 000000000..246e0bd68 --- /dev/null +++ b/frontend/src/test-setup.ts @@ -0,0 +1,18 @@ +import { getTestBed, TestBed } from "@angular/core/testing"; +import { BrowserTestingModule, platformBrowserTesting } from "@angular/platform-browser/testing"; +import { afterEach } from "vitest"; + +afterEach(() => { + TestBed.resetTestingModule(); +}); + +// Only initialize test environment if it hasn't been initialized yet +// This prevents errors when vitest runs tests in parallel (e.g., in CI) +try { + getTestBed().initTestEnvironment( + BrowserTestingModule, + platformBrowserTesting(), + ); +} catch { + // Test environment already initialized, ignore the error +} diff --git a/frontend/vitest.config.js b/frontend/vitest.config.js new file mode 100644 index 000000000..fd4252c4d --- /dev/null +++ b/frontend/vitest.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + passWithNoTests: true, + }, +});