diff --git a/.github/workflows/publish-documentation.yml b/.github/workflows/publish-documentation.yml index 0be09c98..c1127f34 100644 --- a/.github/workflows/publish-documentation.yml +++ b/.github/workflows/publish-documentation.yml @@ -18,6 +18,10 @@ jobs: generate-api-data: if: "!contains(github.event.head_commit.message, 'Update autogenerated JSON files')" runs-on: ubuntu-latest + # Permissions needed to create PR and write content + permissions: + contents: write + pull-requests: write steps: - name: Checkout code @@ -39,28 +43,75 @@ jobs: run: | npm run generate-json-api - - name: Commit and push if there are any changes - working-directory: ./projects/composition - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git pull origin master - git add ./src/app/api-data - if [[ -n "$(git status --porcelain)" ]]; then - git commit -m "Update autogenerated JSON files" - git push origin HEAD:master - fi + # Instead of direct commit/push, create a PR + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + # More descriptive commit message + commit-message: 'chore: Update API documentation JSON files' + # Use bot account for better tracking + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + # Unique branch name using run number to avoid conflicts + branch: api-docs-update-${{ github.run_number }} + # Auto-delete branch after merge + delete-branch: true + title: 'chore: Update API documentation JSON files' + # Detailed PR description with context + body: | + ## Auto-generated API Documentation Update + + This PR contains automatically generated API documentation files. + + ### Changes + - Updated JSON API files based on latest component changes + + ### Workflow Run + - Triggered by commit: ${{ github.sha }} + - Run ID: ${{ github.run_id }} + + --- + + 🤖 This PR was automatically created by the documentation workflow. + # Labels for organization and to skip changelog + labels: | + documentation + automated + skip-changelog + + # Auto-merge the PR (requires repo settings to allow auto-merge) + - name: Enable Pull Request Automerge + if: steps.cpr.outputs.pull-request-operation == 'created' + uses: peter-evans/enable-pull-request-automerge@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} + merge-method: squash + + # Auto-approve the PR so it can be merged + - name: Auto approve PR + if: steps.cpr.outputs.pull-request-operation == 'created' + uses: hmarr/auto-approve-action@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} # Build job build: runs-on: ubuntu-latest needs: generate-api-data + # Only run if generate-api-data succeeded or was skipped (not failed) + if: always() && (needs.generate-api-data.result == 'success' || needs.generate-api-data.result == 'skipped') steps: - name: Checkout code uses: actions/checkout@v4 with: ssh-key: ${{ secrets.DEPLOY_KEY }} + # Explicitly checkout master to get latest changes after PR merge + ref: master - name: Fetch latest commits run: git pull origin master @@ -104,6 +155,8 @@ jobs: # Deploy job deploy: needs: build + # Only deploy if build succeeded + if: success() permissions: pages: write diff --git a/package-lock.json b/package-lock.json index 826d9661..d64719f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,15 +8,15 @@ "name": "cps-shared-ui", "version": "0.0.0", "dependencies": { - "@angular/animations": "^20.2.1", - "@angular/common": "^20.2.1", - "@angular/compiler": "^20.2.1", - "@angular/core": "^20.2.1", - "@angular/forms": "^20.2.1", - "@angular/platform-browser": "^20.2.1", - "@angular/platform-browser-dynamic": "^20.2.1", - "@angular/platform-server": "^20.2.1", - "@angular/router": "^20.2.1", + "@angular/animations": "^20.3.7", + "@angular/common": "^20.3.7", + "@angular/compiler": "^20.3.7", + "@angular/core": "^20.3.7", + "@angular/forms": "^20.3.7", + "@angular/platform-browser": "^20.3.7", + "@angular/platform-browser-dynamic": "^20.3.7", + "@angular/platform-server": "^20.3.7", + "@angular/router": "^20.3.7", "@e965/xlsx": "^0.20.3", "@primeuix/styled": "^0.7.2", "@primeuix/utils": "^0.6.1", @@ -31,9 +31,9 @@ }, "devDependencies": { "@angular-builders/jest": "^20.0.0", - "@angular-devkit/build-angular": "^20.2.0", - "@angular/cli": "~20.2.0", - "@angular/compiler-cli": "^20.2.1", + "@angular-devkit/build-angular": "^20.3.7", + "@angular/cli": "~20.3.7", + "@angular/compiler-cli": "^20.3.7", "@types/express": "^4.17.21", "@types/jest": "^29.5.14", "@types/node": "^22.10.10", @@ -320,13 +320,13 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.2002.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2002.0.tgz", - "integrity": "sha512-PaBXFP1kdUuNtMie0lWnitlYbq8o1gz/s0YIa8oY1X3swOJ7bP6kBfxTb9opV5uXAOkXg2zCdnZ4Eu1aVkgPGw==", + "version": "0.2003.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.7.tgz", + "integrity": "sha512-NGHLfrNQNjwWwvyQomMM1AqRaqH3UU0TwySJh9XlSc9dC/roB5zD2NjLf98K4LfAIfHvDBwkQ+dMo3F556/Xuw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.2.0", + "@angular-devkit/core": "20.3.7", "rxjs": "7.8.2" }, "engines": { @@ -336,17 +336,17 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.2.0.tgz", - "integrity": "sha512-B3dlR9AnANyT8yfESODFYEDEGV6pMwozsfjsH0NFxrdrfB1BYTBKpgYkQWg2I1j48hf7YmetZgA1sa3gYOt1QQ==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.7.tgz", + "integrity": "sha512-KVA6ztqrZz/DKSCk/iV9fz9Af+54YyZs25KwClBi+7/RJIBNml8CZQLW51VxIkbjD9aZdVZdUMkkbQJp5MgY5w==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2002.0", - "@angular-devkit/build-webpack": "0.2002.0", - "@angular-devkit/core": "20.2.0", - "@angular/build": "20.2.0", + "@angular-devkit/architect": "0.2003.7", + "@angular-devkit/build-webpack": "0.2003.7", + "@angular-devkit/core": "20.3.7", + "@angular/build": "20.3.7", "@babel/core": "7.28.3", "@babel/generator": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", @@ -357,7 +357,7 @@ "@babel/preset-env": "7.28.3", "@babel/runtime": "7.28.3", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "20.2.0", + "@ngtools/webpack": "20.3.7", "ansi-colors": "4.1.3", "autoprefixer": "10.4.21", "babel-loader": "10.0.0", @@ -412,7 +412,7 @@ "@angular/platform-browser": "^20.0.0", "@angular/platform-server": "^20.0.0", "@angular/service-worker": "^20.0.0", - "@angular/ssr": "^20.2.0", + "@angular/ssr": "^20.3.7", "@web/test-runner": "^0.20.0", "browser-sync": "^3.0.2", "jest": "^29.5.0", @@ -469,13 +469,13 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.2002.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2002.0.tgz", - "integrity": "sha512-sON0IFOaZW5/bLXlMuKXOV5viaa7SAGHhdM4PXM6Fa0PPqPI6zZp2iqYpwETKpN8DfnLNxefdysvCn9DbHuNhQ==", + "version": "0.2003.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.7.tgz", + "integrity": "sha512-9CVEUWOzf7sk6eudFEG3pfDT1AScUJ4+ekRFKyD5Q5sZivMjjVFqwQp7YUpHpZusZX6sgpT+Crj5Ydva+I/dvw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2002.0", + "@angular-devkit/architect": "0.2003.7", "rxjs": "7.8.2" }, "engines": { @@ -489,9 +489,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.2.0.tgz", - "integrity": "sha512-3CM6Zsr09Kf92ItFkxijlnC4+ZOgkxdCk0vFYvuw9UuvTDNwyIqJi6693PRPRbcXgpdY2vs6u99elSvQVmoEEw==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.7.tgz", + "integrity": "sha512-psmcjwYcXve4sLrcdnARc15/Wfd3RpydbtLo9+mViNzk5HQ6L2eEztKl/2QVYMgzZVIa1GfhjwUllVCyLAv3sg==", "dev": true, "license": "MIT", "dependencies": { @@ -517,13 +517,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.2.0.tgz", - "integrity": "sha512-TCPIN6Bd04oGuNocETmsd9hzGYrjrivisbMKb0WOuDi3OnCkmWqsPR+QA2kYwTOGqG3HXkz/z3CA0g04M2fgrQ==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.7.tgz", + "integrity": "sha512-DUxcQBPKO69p56ZgIdVfxWyLiSjdcUoD6BH9/nWHp0QiqRAR6GcXP4SFax76JPl2WsiCp4hHZ233Hf69AP1xew==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.2.0", + "@angular-devkit/core": "20.3.7", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "8.2.0", @@ -536,9 +536,9 @@ } }, "node_modules/@angular/animations": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.2.1.tgz", - "integrity": "sha512-g4yLXwXCF7OAahx1xI4FXRwG4dIXfBqHsvlpx2TappaMRpiPp7PfP2cW6l3ox+KRpTWhSvcRqbJyIOWad0f7Rw==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.7.tgz", + "integrity": "sha512-i655RaL0zmLE3OESUlDnRNBDRIMW/67nTQvMqP6V1cQ42l2+SMJtREsxmX6cWt55/qvvgeytAA6aBN4aerBl5A==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -547,19 +547,18 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.2.1", - "@angular/core": "20.2.1" + "@angular/core": "20.3.7" } }, "node_modules/@angular/build": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.2.0.tgz", - "integrity": "sha512-/Yhqhg01UvX0E+tx4WAeK3AnwpZLqcw+XKTmsPsH5rbqpLKNRR9XsC3PJ4qBFU1u9/Lh13mmmr1+pG2p8ixMug==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.7.tgz", + "integrity": "sha512-NHN5JNDqUc0Ux4IZPCe/fpFAnuRHujkxVfRHSqDFW5+jtj2JuW1XO6qlX+kDheFRlj/NvFgTpidKsE9IjpfMWQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2002.0", + "@angular-devkit/architect": "0.2003.7", "@babel/core": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", @@ -577,12 +576,12 @@ "parse5-html-rewriting-stream": "8.0.0", "picomatch": "4.0.3", "piscina": "5.1.3", - "rolldown": "1.0.0-beta.32", + "rollup": "4.52.3", "sass": "1.90.0", "semver": "7.7.2", "source-map-support": "0.5.21", "tinyglobby": "0.2.14", - "vite": "7.1.2", + "vite": "7.1.11", "watchpack": "2.4.4" }, "engines": { @@ -601,7 +600,7 @@ "@angular/platform-browser": "^20.0.0", "@angular/platform-server": "^20.0.0", "@angular/service-worker": "^20.0.0", - "@angular/ssr": "^20.2.0", + "@angular/ssr": "^20.3.7", "karma": "^6.4.0", "less": "^4.2.0", "ng-packagr": "^20.0.0", @@ -667,19 +666,19 @@ } }, "node_modules/@angular/cli": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.2.0.tgz", - "integrity": "sha512-p62hkuQOxf5kJsVq6AT7B1MHYo1uPGoZV4lf47qOrLjl0WANwfxEgLvyuVgL47ylnINbPnITeeUdoadVn4t1sw==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.7.tgz", + "integrity": "sha512-hNurF7g/e9cDHFBRCKLPSmQJs0n28jZsC3sTl/XuWE8PYtv5egh2EuqrxdruYB5GdANpIqSQNgDGQJrKrk/XnQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2002.0", - "@angular-devkit/core": "20.2.0", - "@angular-devkit/schematics": "20.2.0", + "@angular-devkit/architect": "0.2003.7", + "@angular-devkit/core": "20.3.7", + "@angular-devkit/schematics": "20.3.7", "@inquirer/prompts": "7.8.2", "@listr2/prompt-adapter-inquirer": "3.0.1", "@modelcontextprotocol/sdk": "1.17.3", - "@schematics/angular": "20.2.0", + "@schematics/angular": "20.3.7", "@yarnpkg/lockfile": "1.1.0", "algoliasearch": "5.35.0", "ini": "5.0.0", @@ -702,9 +701,9 @@ } }, "node_modules/@angular/common": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.2.1.tgz", - "integrity": "sha512-T6RYnDZA9TyYhj2hUz4set8p4RbBCg6IKUvy6qzdKTl4nn4xQ0XUV7aGBYN4LKiGrse9lzlVUAyXtkhmwuBbCQ==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.7.tgz", + "integrity": "sha512-uf8dXYTJbedk/wudkt2MfbtvN/T97aEZBtOTq8/IFQQZ3722rag6D+Cg76e5hBccROOn+ueGJX2gpxz02phTwA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -713,14 +712,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.2.1", + "@angular/core": "20.3.7", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.2.1.tgz", - "integrity": "sha512-ghVt1E8xmwjMwqyGRwXYJkr7fz40VEreUSX1q+gEzbGTftVrK1foxPT8jcueIn0ztArDf7+zSMtu314FiJZyYA==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.7.tgz", + "integrity": "sha512-EouHO15dUsgnFArj0M25R8cOPVoUfiFYSt6iXnMO8+S4dY1fDEmbFqkW5smlP66HL5Gys59Nwb5inejfIWHrLw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -730,9 +729,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.2.1.tgz", - "integrity": "sha512-VpbcRqNPJvy1L9RDtGGQsQiOrMzxodUWklphbtnh9MrrK6lLuy6Qj2ROiW7vKL9WfLTCXWA24gBAcMAR76dq3Q==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.7.tgz", + "integrity": "sha512-viZwWlwc1BAqryRJE0Wq2WgAxDaW9fuwtYHYrOWnIn9sy9KemKmR6RmU9VRydrwUROOlqK49R9+RC1wQ6sYwqA==", "dev": true, "license": "MIT", "dependencies": { @@ -753,7 +752,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.2.1", + "@angular/compiler": "20.3.7", "typescript": ">=5.8 <6.0" }, "peerDependenciesMeta": { @@ -763,9 +762,9 @@ } }, "node_modules/@angular/core": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.2.1.tgz", - "integrity": "sha512-/hl3AkmdQ62P9ttmfULEDg9GIz7BkzhGv9bSH2ssiU3Y4ax6eM8uQXEbMxBA8OUKOvg1Q4POcNHIiJQgO5t28Q==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.7.tgz", + "integrity": "sha512-2UuYzC2A5SUtu33tYTN411Wk0WilA+2Uld/GP3O6mragw1O7v/M8pMFmbe9TR5Ah/abRJIocWGlNqeztZmQmrw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -774,7 +773,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.2.1", + "@angular/compiler": "20.3.7", "rxjs": "^6.5.3 || ^7.4.0", "zone.js": "~0.15.0" }, @@ -788,9 +787,9 @@ } }, "node_modules/@angular/forms": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.2.1.tgz", - "integrity": "sha512-SfkiHEIFPLtTKeaXUTpRfYnpJDxaeKiTi0YqfvzEjKE68qH0t+pQ4rL0Poch2/l4snP6JS1XzO/nDve1dk3vZw==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.7.tgz", + "integrity": "sha512-uOCGCoqXeAWIlQMWiIeed/W8g8h2tk91YemMI+Ce1VQ/36Xfft40Bouz4eKcvJV6kLXGygdpWjzFGz32CE+3Og==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -799,16 +798,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.2.1", - "@angular/core": "20.2.1", - "@angular/platform-browser": "20.2.1", + "@angular/common": "20.3.7", + "@angular/core": "20.3.7", + "@angular/platform-browser": "20.3.7", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/platform-browser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.2.1.tgz", - "integrity": "sha512-oxDih/A8G7W+I6oAip+sev+kebioYmzhB/NMzF8C8zx/ieVDzatJ+YeEZQt7eDaJLH94S4sIC25SPq3OFIabxg==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.7.tgz", + "integrity": "sha512-AbLtyR7fVEGDYyrz95dP2pc69J5XIjLLsFNAuNQPzNX02WPoAxtrWrNY6UnTzGoSrCc5F52hiL2Uo6yPZTiJcg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -817,9 +816,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/animations": "20.2.1", - "@angular/common": "20.2.1", - "@angular/core": "20.2.1" + "@angular/animations": "20.3.7", + "@angular/common": "20.3.7", + "@angular/core": "20.3.7" }, "peerDependenciesMeta": { "@angular/animations": { @@ -828,9 +827,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.2.1.tgz", - "integrity": "sha512-bzBeDnRZFzlA5w5q5GskuKhLgAeJ3pU0B3Ch7V2fhfaAZDOTEczBFvL7I1pcXhDg8Y/8aoz4/OwqnilKLO3FUg==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.7.tgz", + "integrity": "sha512-4TEPA12183cMeVCzuU/Rmuk5RuIgsunTbjgx0o+ymxvYyULOxKDlhZ4hGDKzmRCOu6s3ZeEs4XbgaLP6pK+Kxg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -839,16 +838,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.2.1", - "@angular/compiler": "20.2.1", - "@angular/core": "20.2.1", - "@angular/platform-browser": "20.2.1" + "@angular/common": "20.3.7", + "@angular/compiler": "20.3.7", + "@angular/core": "20.3.7", + "@angular/platform-browser": "20.3.7" } }, "node_modules/@angular/platform-server": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.2.1.tgz", - "integrity": "sha512-yjos8jgHwcih9lF/CKjbKxzzc83NM+ZoIdm/XSVv9yg+QDnTsc6bLF3QZ+OChCoaCks/UtWUwyM7Ux2g/VvVFA==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.7.tgz", + "integrity": "sha512-ADqOwqeUpTkp97SUpNO4jZ0o9Du7oBpi0mqzLx/c1dQYgL5hKAZYpa7bpG/edn2nSMHXwQAaGw7t+MTmU7elxQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0", @@ -858,17 +857,17 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.2.1", - "@angular/compiler": "20.2.1", - "@angular/core": "20.2.1", - "@angular/platform-browser": "20.2.1", + "@angular/common": "20.3.7", + "@angular/compiler": "20.3.7", + "@angular/core": "20.3.7", + "@angular/platform-browser": "20.3.7", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/router": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.2.1.tgz", - "integrity": "sha512-f8KfG55EVnFDC9ud+MbxAP6voKi7hVQH4YaqPK0Lm6pyc1Xp0I5W25iRbg+Y1rO1csHKHauBPkUEESEuVGBGqg==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.7.tgz", + "integrity": "sha512-Lq7mCNcLP1npmNh2JlNEe02YS2jNnaLnCy/t//o+Qq0c6DGV78JRl7pHubiB2R6XXlgvOcZWg88v94Li+y85Iw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -877,9 +876,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.2.1", - "@angular/core": "20.2.1", - "@angular/platform-browser": "20.2.1", + "@angular/common": "20.3.7", + "@angular/core": "20.3.7", + "@angular/platform-browser": "20.3.7", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -4016,9 +4015,9 @@ } }, "node_modules/@jsonjoy.com/buffers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.0.0.tgz", - "integrity": "sha512-NDigYR3PHqCnQLXYyoLbnEdzMMvzeiCWo1KOut7Q0CoIqg9tUAPKJ1iq/2nFhc5kZtexzutNY0LFjdwWL3Dw3Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4050,19 +4049,20 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.11.0.tgz", - "integrity": "sha512-nLqSTAYwpk+5ZQIoVp7pfd/oSKNWlEdvTq2LzVA4r2wtWZg6v+5u0VgBOaDJuUfNOuw/4Ysq6glN5QKSrOCgrA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/base64": "^1.1.2", - "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/buffers": "^1.2.0", "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/json-pointer": "^1.0.1", + "@jsonjoy.com/json-pointer": "^1.0.2", "@jsonjoy.com/util": "^1.9.0", "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0" + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" }, "engines": { "node": ">=10.0" @@ -4076,13 +4076,14 @@ } }, "node_modules/@jsonjoy.com/json-pointer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.1.tgz", - "integrity": "sha512-tJpwQfuBuxqZlyoJOSZcqf7OUmiYQ6MiPNmOv4KbZdXE/DdvBSSAwhos0zIlJU/AXxC8XpuO8p08bh2fIl+RKA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/util": "^1.3.0" + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" }, "engines": { "node": ">=10.0" @@ -4140,6 +4141,90 @@ "listr2": "9.0.1" } }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.4.2.tgz", + "integrity": "sha512-NK80WwDoODyPaSazKbzd3NEJ3ygePrkERilZshxBViBARNz21rmediktGHExoj9n5t9+ChlgLlxecdFKLCuCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.4.2.tgz", + "integrity": "sha512-zevaowQNmrp3U7Fz1s9pls5aIgpKRsKb3dZWDINtLiozh3jZI9fBrI19lYYBxqdyiIyNdlyiidPnwPShj4aK+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.4.2.tgz", + "integrity": "sha512-OmHCULY17rkx/RoCoXlzU7LyR8xqrksgdYWwtYa14l/sseezZ8seKWXcogHcjulBddER5NnEFV4L/Jtr2nyxeg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.4.2.tgz", + "integrity": "sha512-ZBEfbNZdkneebvZs98Lq30jMY8V9IJzckVeigGivV7nTHJc+89Ctomp1kAIWKlwIG0ovCDrFI448GzFPORANYg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.4.2.tgz", + "integrity": "sha512-vL9nM17C77lohPYE4YaAQvfZCSVJSryE4fXdi8M7uWPBnU+9DJabgKVAeyDb84ZM2vcFseoBE4/AagVtJeRE7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.4.2.tgz", + "integrity": "sha512-SXWjdBfNDze4ZPeLtYIzsIeDJDJ/SdsA0pEXcUBayUIMO0FQBHfVZZyHXQjjHr4cvOAzANBgIiqaXRwfMhzmLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@lmdb/lmdb-win32-x64": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.4.2.tgz", @@ -4202,6 +4287,76 @@ "dev": true, "license": "MIT" }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", @@ -4268,9 +4423,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.2.0.tgz", - "integrity": "sha512-+oRNsB8RfmDd4Mnr8AyJwU3GUyXalQcI9r3Hoi4OSyFncWJeOnpTAWErx2JomqAYkm8WkE0PoRxKnD0RxKQ30Q==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.7.tgz", + "integrity": "sha512-AlFf28hylqopJYz4P5MOGEmasOGtXntN/xExOuurP4P9xuUrO99FvaVm0+RPgw8iKeojNW5Bi6qFS77gLof56w==", "dev": true, "license": "MIT", "engines": { @@ -4603,26 +4758,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@oxc-project/runtime": { - "version": "0.81.0", - "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.81.0.tgz", - "integrity": "sha512-zm/LDVOq9FEmHiuM8zO4DWirv0VP2Tv2VsgaiHby9nvpq+FVrcqNYgv+TysLKOITQXWZj/roluTxFvpkHP0Iuw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.81.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.81.0.tgz", - "integrity": "sha512-CnOqkybZK8z6Gx7Wb1qF7AEnSzbol1WwcIzxYOr8e91LytGOjo0wCpgoYWZo8sdbpqX+X+TJayIzo4Pv0R/KjA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, "node_modules/@parcel/watcher": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", @@ -4831,27 +4966,6 @@ "node": ">=12" } }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-beta.32", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.32.tgz", - "integrity": "sha512-Ej0i4PZk8ltblZtzVK8ouaGUacUtxRmTm5S9794mdyU/tYxXjAJNseOfxrnHpMWKjMDrOKbqkPqJ52T9NR4LQQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.32", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz", - "integrity": "sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==", - "dev": true, - "license": "MIT" - }, "node_modules/@rollup/plugin-json": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", @@ -4896,10 +5010,304 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz", + "integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz", + "integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz", + "integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz", + "integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz", + "integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz", + "integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz", + "integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz", + "integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz", + "integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz", + "integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz", + "integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz", + "integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz", + "integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz", + "integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz", + "integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz", + "integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz", + "integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz", + "integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz", + "integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz", + "integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz", + "integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.47.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.47.1.tgz", - "integrity": "sha512-CpKnYa8eHthJa3c+C38v/E+/KZyF1Jdh2Cz3DyKZqEWYgrM1IHFArXNWvBLPQCKUEsAqqKX27tTqVEFbDNUcOA==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz", + "integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==", "cpu": [ "x64" ], @@ -4938,14 +5346,14 @@ "license": "MIT" }, "node_modules/@schematics/angular": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.2.0.tgz", - "integrity": "sha512-7sZVj7hOcytQrPE17ixjzul9ih81IfXGcEZvr7fT77qy7Hm5rbMjxqSYxCTf3kAyBFRSLq/E8GTapPAjk2coOg==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.7.tgz", + "integrity": "sha512-jR2LPJVGK6yzPTNXkGJZYtdeLGkNdqJhVow2E+ILt3pk/LZuT/iSdr9V4nArU9yysifGuJFTyZapVOYkEYaykg==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.2.0", - "@angular-devkit/schematics": "20.2.0", + "@angular-devkit/core": "20.3.7", + "@angular-devkit/schematics": "20.3.7", "jsonc-parser": "3.3.1" }, "engines": { @@ -6341,16 +6749,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansis": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", - "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -9350,9 +9748,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -11753,6 +12151,21 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -11992,6 +12405,23 @@ "node": ">=10.13.0" } }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -13166,9 +13596,9 @@ } }, "node_modules/is-network-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", + "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", "dev": true, "license": "MIT", "engines": { @@ -15493,21 +15923,19 @@ } }, "node_modules/memfs": { - "version": "4.37.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.37.1.tgz", - "integrity": "sha512-10/gLuR1lnzU17BvXrpVplKs6lQmRtzH/67bar7fwRBEGLCSfK33M8lxN3gT1MdSUmGRRpN8LpIex9c39hAUyQ==", + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.49.0.tgz", + "integrity": "sha512-L9uC9vGuc4xFybbdOpRLoOAOq1YEBBsocCs5NVW32DfU+CZWWIn3OVF+lB8Gp4ttBVSMazwrTrjv8ussX/e3VQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" }, - "engines": { - "node": ">= 4.0.0" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" @@ -18817,42 +19245,10 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rolldown": { - "version": "1.0.0-beta.32", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.32.tgz", - "integrity": "sha512-vxI2sPN07MMaoYKlFrVva5qZ1Y7DAZkgp7MQwTnyHt4FUMz9Sh+YeCzNFV9JYHI6ZNwoGWLCfCViE3XVsRC1cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@oxc-project/runtime": "=0.81.0", - "@oxc-project/types": "=0.81.0", - "@rolldown/pluginutils": "1.0.0-beta.32", - "ansis": "^4.0.0" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-beta.32", - "@rolldown/binding-darwin-arm64": "1.0.0-beta.32", - "@rolldown/binding-darwin-x64": "1.0.0-beta.32", - "@rolldown/binding-freebsd-x64": "1.0.0-beta.32", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.32", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.32", - "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.32", - "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.32", - "@rolldown/binding-linux-x64-musl": "1.0.0-beta.32", - "@rolldown/binding-openharmony-arm64": "1.0.0-beta.32", - "@rolldown/binding-wasm32-wasi": "1.0.0-beta.32", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.32", - "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.32", - "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.32" - } - }, "node_modules/rollup": { - "version": "4.47.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.47.1.tgz", - "integrity": "sha512-iasGAQoZ5dWDzULEUX3jiW0oB1qyFOepSyDyoU6S/OhVlDIwj5knI5QBa5RRQ0sK7OE0v+8VIi2JuV+G+3tfNg==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz", + "integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==", "dev": true, "license": "MIT", "dependencies": { @@ -18866,26 +19262,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.47.1", - "@rollup/rollup-android-arm64": "4.47.1", - "@rollup/rollup-darwin-arm64": "4.47.1", - "@rollup/rollup-darwin-x64": "4.47.1", - "@rollup/rollup-freebsd-arm64": "4.47.1", - "@rollup/rollup-freebsd-x64": "4.47.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.47.1", - "@rollup/rollup-linux-arm-musleabihf": "4.47.1", - "@rollup/rollup-linux-arm64-gnu": "4.47.1", - "@rollup/rollup-linux-arm64-musl": "4.47.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.47.1", - "@rollup/rollup-linux-ppc64-gnu": "4.47.1", - "@rollup/rollup-linux-riscv64-gnu": "4.47.1", - "@rollup/rollup-linux-riscv64-musl": "4.47.1", - "@rollup/rollup-linux-s390x-gnu": "4.47.1", - "@rollup/rollup-linux-x64-gnu": "4.47.1", - "@rollup/rollup-linux-x64-musl": "4.47.1", - "@rollup/rollup-win32-arm64-msvc": "4.47.1", - "@rollup/rollup-win32-ia32-msvc": "4.47.1", - "@rollup/rollup-win32-x64-msvc": "4.47.1", + "@rollup/rollup-android-arm-eabi": "4.52.3", + "@rollup/rollup-android-arm64": "4.52.3", + "@rollup/rollup-darwin-arm64": "4.52.3", + "@rollup/rollup-darwin-x64": "4.52.3", + "@rollup/rollup-freebsd-arm64": "4.52.3", + "@rollup/rollup-freebsd-x64": "4.52.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.3", + "@rollup/rollup-linux-arm-musleabihf": "4.52.3", + "@rollup/rollup-linux-arm64-gnu": "4.52.3", + "@rollup/rollup-linux-arm64-musl": "4.52.3", + "@rollup/rollup-linux-loong64-gnu": "4.52.3", + "@rollup/rollup-linux-ppc64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-musl": "4.52.3", + "@rollup/rollup-linux-s390x-gnu": "4.52.3", + "@rollup/rollup-linux-x64-gnu": "4.52.3", + "@rollup/rollup-linux-x64-musl": "4.52.3", + "@rollup/rollup-openharmony-arm64": "4.52.3", + "@rollup/rollup-win32-arm64-msvc": "4.52.3", + "@rollup/rollup-win32-ia32-msvc": "4.52.3", + "@rollup/rollup-win32-x64-gnu": "4.52.3", + "@rollup/rollup-win32-x64-msvc": "4.52.3", "fsevents": "~2.3.2" } }, @@ -18930,9 +19328,9 @@ } }, "node_modules/run-applescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "dev": true, "license": "MIT", "engines": { @@ -20626,9 +21024,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -21014,9 +21412,9 @@ } }, "node_modules/tree-dump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", - "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -21061,9 +21459,9 @@ } }, "node_modules/ts-jest": { - "version": "29.4.1", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.1.tgz", - "integrity": "sha512-SaeUtjfpg9Uqu8IbeDKtdaS0g8lS6FT6OzM3ezrDfErPJPHNDo/Ey+VFGP1bQIDfagYDLyRpd7O15XpG1Es2Uw==", + "version": "29.4.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.5.tgz", + "integrity": "sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==", "dev": true, "license": "MIT", "dependencies": { @@ -21073,7 +21471,7 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.2", + "semver": "^7.7.3", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -21113,6 +21511,19 @@ } } }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ts-jest/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", @@ -21784,18 +22195,18 @@ } }, "node_modules/vite": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.2.tgz", - "integrity": "sha512-J0SQBPlQiEXAF7tajiH+rUooJPo0l8KQgyg4/aMunNtrOa7bwuZJsJbDWzeljqQpgftxuq5yNJxQ91O9ts29UQ==", + "version": "7.1.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", + "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.6", + "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", - "tinyglobby": "^0.2.14" + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" @@ -21858,6 +22269,23 @@ } } }, + "node_modules/vite/node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index 20246a65..f419ee92 100644 --- a/package.json +++ b/package.json @@ -18,15 +18,15 @@ }, "private": true, "dependencies": { - "@angular/animations": "^20.2.1", - "@angular/common": "^20.2.1", - "@angular/compiler": "^20.2.1", - "@angular/core": "^20.2.1", - "@angular/forms": "^20.2.1", - "@angular/platform-browser": "^20.2.1", - "@angular/platform-browser-dynamic": "^20.2.1", - "@angular/platform-server": "^20.2.1", - "@angular/router": "^20.2.1", + "@angular/animations": "^20.3.7", + "@angular/common": "^20.3.7", + "@angular/compiler": "^20.3.7", + "@angular/core": "^20.3.7", + "@angular/forms": "^20.3.7", + "@angular/platform-browser": "^20.3.7", + "@angular/platform-browser-dynamic": "^20.3.7", + "@angular/platform-server": "^20.3.7", + "@angular/router": "^20.3.7", "@e965/xlsx": "^0.20.3", "@primeuix/styled": "^0.7.2", "@primeuix/utils": "^0.6.1", @@ -41,9 +41,9 @@ }, "devDependencies": { "@angular-builders/jest": "^20.0.0", - "@angular-devkit/build-angular": "^20.2.0", - "@angular/cli": "~20.2.0", - "@angular/compiler-cli": "^20.2.1", + "@angular-devkit/build-angular": "^20.3.7", + "@angular/cli": "~20.3.7", + "@angular/compiler-cli": "^20.3.7", "@types/express": "^4.17.21", "@types/jest": "^29.5.14", "@types/node": "^22.10.10", diff --git a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.spec.ts b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.spec.ts new file mode 100644 index 00000000..179af7a5 --- /dev/null +++ b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.spec.ts @@ -0,0 +1,516 @@ +import { ElementRef } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { CpsInputComponent } from './cps-input.component'; + +describe('CpsInputComponent', () => { + let component: CpsInputComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CpsInputComponent, ReactiveFormsModule, NoopAnimationsModule] + }).compileComponents(); + + fixture = TestBed.createComponent(CpsInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + describe('Value Handling', () => { + it('should handle empty string', () => { + component.writeValue(''); + fixture.detectChanges(); + + expect(component.value).toBe(''); + }); + + it('should handle text values', () => { + component.writeValue('Hello'); + fixture.detectChanges(); + + expect(component.value).toBe('Hello'); + }); + + it('should handle numeric values', () => { + component.writeValue('123'); + fixture.detectChanges(); + + expect(component.value).toBe('123'); + }); + + it('should handle negative numbers', () => { + component.writeValue('-5'); + fixture.detectChanges(); + + expect(component.value).toBe('-5'); + }); + + it('should handle decimal numbers', () => { + component.writeValue('3.14'); + fixture.detectChanges(); + + expect(component.value).toBe('3.14'); + }); + }); + + describe('ControlValueAccessor Implementation', () => { + it('should register onChange callback', () => { + const fn = jest.fn(); + component.registerOnChange(fn); + + component.updateValueEvent({ target: { value: 'test' } } as any); + + expect(fn).toHaveBeenCalledWith('test'); + }); + + it('should call onChange when value updates', () => { + const onChange = jest.fn(); + component.registerOnChange(onChange); + + const inputElement = fixture.nativeElement.querySelector('input'); + inputElement.value = 'new value'; + inputElement.dispatchEvent(new Event('input')); + + expect(onChange).toHaveBeenCalledWith('new value'); + }); + + it('should write value through writeValue', () => { + component.writeValue('test value'); + fixture.detectChanges(); + + expect(component.value).toBe('test value'); + const inputElement = fixture.nativeElement.querySelector('input'); + expect(inputElement.value).toBe('test value'); + }); + }); + + describe('Input Properties', () => { + it('should apply label', () => { + component.label = 'Test Label'; + fixture.detectChanges(); + + const label = fixture.nativeElement.querySelector('label'); + expect(label?.textContent?.trim()).toBe('Test Label'); + }); + + it('should apply placeholder', () => { + component.placeholder = 'Enter text'; + fixture.detectChanges(); + + const input = fixture.nativeElement.querySelector('input'); + expect(input.placeholder).toBe('Enter text'); + }); + + it('should disable input when disabled is true', () => { + component.disabled = true; + fixture.detectChanges(); + + const input = fixture.nativeElement.querySelector('input'); + expect(input.disabled).toBe(true); + }); + + it('should make input readonly when readonly is true', () => { + component.readonly = true; + fixture.detectChanges(); + + const input = fixture.nativeElement.querySelector('input'); + expect(input.readOnly).toBe(true); + }); + + it('should apply hint text', () => { + component.hint = 'Helper text'; + fixture.detectChanges(); + + const hint = fixture.nativeElement.querySelector('.cps-input-hint'); + expect(hint?.textContent?.trim()).toBe('Helper text'); + }); + + it('should change input type', () => { + component.type = 'password'; + component.ngOnInit(); + fixture.detectChanges(); + + const input = fixture.nativeElement.querySelector('input'); + expect(input.type).toBe('password'); + }); + }); + + describe('Clear Functionality', () => { + it('should clear value when clear button is clicked', () => { + component.clearable = true; + component.writeValue('test'); + fixture.detectChanges(); + + component.onClear(); + + expect(component.value).toBe(''); + }); + + it('should emit cleared event', () => { + const emitSpy = jest.spyOn(component.cleared, 'emit'); + component.clearable = true; + component.writeValue('test'); + + component.onClear(); + + expect(emitSpy).toHaveBeenCalled(); + }); + + it('should emit valueChanged event when clearing', () => { + const emitSpy = jest.spyOn(component.valueChanged, 'emit'); + component.writeValue('test'); + + component.clear(); + + expect(emitSpy).toHaveBeenCalledWith(''); + }); + + it('should not clear if value is already empty', () => { + const emitSpy = jest.spyOn(component.valueChanged, 'emit'); + component.writeValue(''); + + component.clear(); + + expect(emitSpy).not.toHaveBeenCalled(); + }); + }); + + describe('Password Toggle', () => { + it('should toggle between password and text type', () => { + component.type = 'password'; + component.ngOnInit(); + expect(component.currentType).toBe('password'); + + component.togglePassword(); + expect(component.currentType).toBe('text'); + + component.togglePassword(); + expect(component.currentType).toBe('password'); + }); + }); + + describe('Event Emissions', () => { + it('should emit focused event on focus', () => { + const emitSpy = jest.spyOn(component.focused, 'emit'); + + component.onFocus(); + + expect(emitSpy).toHaveBeenCalled(); + }); + + it('should emit blurred event on blur', () => { + const emitSpy = jest.spyOn(component.blurred, 'emit'); + + component.onBlur(); + + expect(emitSpy).toHaveBeenCalled(); + }); + + it('should emit enterClicked event on enter key', () => { + const emitSpy = jest.spyOn(component.enterClicked, 'emit'); + + component.onInputEnterKeyDown(); + + expect(emitSpy).toHaveBeenCalled(); + }); + + it('should emit valueChanged on input', () => { + const emitSpy = jest.spyOn(component.valueChanged, 'emit'); + + const event = { target: { value: 'new value' } }; + component.updateValueEvent(event as any); + + expect(emitSpy).toHaveBeenCalledWith('new value'); + }); + + it('should emit prefixIconClicked when prefix icon is clicked', () => { + const emitSpy = jest.spyOn(component.prefixIconClicked, 'emit'); + component.prefixIconClickable = true; + + component.onClickPrefixIcon(); + + expect(emitSpy).toHaveBeenCalled(); + }); + + it('should not emit prefixIconClicked when not clickable', () => { + const emitSpy = jest.spyOn(component.prefixIconClicked, 'emit'); + component.prefixIconClickable = false; + + component.onClickPrefixIcon(); + + expect(emitSpy).not.toHaveBeenCalled(); + }); + + it('should not emit prefixIconClicked when disabled', () => { + const emitSpy = jest.spyOn(component.prefixIconClicked, 'emit'); + component.prefixIconClickable = true; + component.disabled = true; + + component.onClickPrefixIcon(); + + expect(emitSpy).not.toHaveBeenCalled(); + }); + + it('should not emit prefixIconClicked when readonly', () => { + const emitSpy = jest.spyOn(component.prefixIconClicked, 'emit'); + component.prefixIconClickable = true; + component.readonly = true; + + component.onClickPrefixIcon(); + + expect(emitSpy).not.toHaveBeenCalled(); + }); + }); + + describe('Validation Error Handling', () => { + it('should display required error message', () => { + // Mock NgControl with errors + (component as any)._control = { + errors: { required: true }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Field is required'); + }); + + it('should display pattern error message', () => { + (component as any)._control = { + errors: { pattern: true }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Value is invalid'); + }); + + it('should display email error message', () => { + (component as any)._control = { + errors: { email: true }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Email format is invalid'); + }); + + it('should display minlength error message', () => { + (component as any)._control = { + errors: { minlength: { requiredLength: 8 } }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Field must contain at least 8 characters'); + }); + + it('should display maxlength error message', () => { + (component as any)._control = { + errors: { maxlength: { requiredLength: 10 } }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Field must contain 10 characters maximum'); + }); + + it('should clear error when control is not touched', () => { + (component as any)._control = { + errors: { required: true }, + control: { touched: false } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe(''); + }); + + it('should clear error when no errors exist', () => { + (component as any)._control = { + errors: null, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe(''); + }); + + it('should handle custom error messages', () => { + (component as any)._control = { + errors: { customError: 'Custom error message' }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Custom error message'); + }); + + it('should display unknown error for unhandled errors', () => { + (component as any)._control = { + errors: { unknownError: { someProperty: 'value' } }, + control: { touched: true } + }; + + (component as any)._checkErrors(); + + expect(component.error).toBe('Unknown error'); + }); + }); + + describe('Focus Management', () => { + it('should focus input programmatically', () => { + const input = fixture.nativeElement.querySelector('input'); + const focusSpy = jest.spyOn(input, 'focus'); + + component.focus(); + + expect(focusSpy).toHaveBeenCalled(); + }); + + it('should blur input on enter key', () => { + const input = fixture.nativeElement.querySelector('input'); + const blurSpy = jest.spyOn(input, 'blur'); + + component.onInputEnterKeyDown(); + + expect(blurSpy).toHaveBeenCalled(); + }); + + it('should mark control as touched on focus', () => { + const markTouchedSpy = jest.fn(); + (component as any)._control = { + control: { markAsTouched: markTouchedSpy } + }; + + component.onFocus(); + + expect(markTouchedSpy).toHaveBeenCalled(); + }); + }); + + describe('Component Lifecycle', () => { + it('should initialize currentType from type input', () => { + component.type = 'password'; + component.ngOnInit(); + + expect(component.currentType).toBe('password'); + }); + + it('should subscribe to control status changes', () => { + const mockSubscription = { unsubscribe: jest.fn() }; + const mockStatusChanges = { + subscribe: jest.fn().mockReturnValue(mockSubscription) + }; + + (component as any)._control = { + statusChanges: mockStatusChanges + }; + + component.ngOnInit(); + + expect(mockStatusChanges.subscribe).toHaveBeenCalled(); + }); + + it('should unsubscribe on destroy', () => { + const unsubscribeSpy = jest.fn(); + (component as any)._statusChangesSubscription = { + unsubscribe: unsubscribeSpy + }; + + component.ngOnDestroy(); + + expect(unsubscribeSpy).toHaveBeenCalled(); + }); + + it('should calculate prefix width after view init', () => { + component.prefixText = 'USD'; + component.prefixIcon = 'search'; + + // Mock prefixTextSpan + component.prefixTextSpan = { + nativeElement: { offsetWidth: 50 } + } as ElementRef; + + component.ngAfterViewInit(); + + expect(component.prefixWidth).toBeTruthy(); + }); + }); + + describe('Edge Cases', () => { + it('should handle rapid value changes', () => { + const values = ['0', '1', '2', '3', '4', '5']; + + values.forEach((val) => { + component.writeValue(val); + fixture.detectChanges(); + expect(component.value).toBe(val); + }); + }); + + it('should handle very large numbers', () => { + const largeNumber = '999999999999'; + component.writeValue(largeNumber); + fixture.detectChanges(); + + expect(component.value).toBe(largeNumber); + }); + + it('should handle special characters in text', () => { + const specialText = '!@#$%^&*()'; + component.writeValue(specialText); + fixture.detectChanges(); + + expect(component.value).toBe(specialText); + }); + + it('should handle unicode characters', () => { + const unicode = '你好世界'; + component.writeValue(unicode); + fixture.detectChanges(); + + expect(component.value).toBe(unicode); + }); + + it('should handle whitespace', () => { + const whitespace = ' spaces '; + component.writeValue(whitespace); + fixture.detectChanges(); + + expect(component.value).toBe(whitespace); + }); + }); + + describe('Type Consistency', () => { + it('should maintain number type for numeric input', () => { + component.type = 'number'; + component.writeValue('42'); + fixture.detectChanges(); + + expect(typeof component.value).toBe('string'); + expect(component.value).toBe('42'); + }); + + it('should maintain string type for text input', () => { + component.type = 'text'; + component.writeValue('text'); + fixture.detectChanges(); + + expect(typeof component.value).toBe('string'); + expect(component.value).toBe('text'); + }); + }); +});