diff options
| author | Leitwolf11 | 2026-09-26 16:57:36 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-09-26 16:57:36 +0300 |
| commit | 07b91c2966ffe5daa9501f41436b3a45b3a2d774 (patch) | |
| tree | 4a8771a38cbd7bc61735c3ae59b8b440f03d0d42 | |
| parent | 1855533fa44547e568471303530c67e5d2fa69c5 (diff) | |
| download | progmaweb-07b91c2966ffe5daa9501f41436b3a45b3a2d774.tar.gz | |
Add Progmaweb frontend tests and full-stack security and coverage workflows
| -rw-r--r-- | .codacy.yml | 11 | ||||
| -rw-r--r-- | .github/codeql/codeql-config.yml | 10 | ||||
| -rw-r--r-- | .github/dependabot.yml | 20 | ||||
| -rw-r--r-- | .github/pull_request_template.md | 25 | ||||
| -rw-r--r-- | .github/workflows/backend.yml | 9 | ||||
| -rw-r--r-- | .github/workflows/codeql.yml | 50 | ||||
| -rw-r--r-- | .github/workflows/frontend.yml | 8 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | apps/api-tests/Progmaweb.Api.Tests.csproj | 1 | ||||
| -rw-r--r-- | apps/api-tests/packages.lock.json | 11 | ||||
| -rw-r--r-- | apps/api/packages.lock.json | 2 | ||||
| -rw-r--r-- | apps/web/package.json | 3 | ||||
| -rw-r--r-- | apps/web/tests/localization.test.mjs | 62 | ||||
| -rw-r--r-- | package.json | 2 | ||||
| -rw-r--r-- | pnpm-lock.yaml | 255 |
16 files changed, 475 insertions, 2 deletions
diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 0000000..52ecd91 --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,11 @@ +--- +# SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +# SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 + +exclude_paths: + - '**/node_modules/**' + - '**/.next/**' + - '**/bin/**' + - '**/obj/**' + - 'coverage/**' + diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000..e4b5b8d --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +# SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 + +name: Progmaweb owned sources +paths-ignore: + - apps/web/.next + - apps/web/node_modules + - '**/bin' + - '**/obj' + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..647cf0e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +# SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 + +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + - package-ecosystem: nuget + directories: + - /apps/api + - /apps/api-tests + schedule: + interval: weekly + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..f4d6812 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,25 @@ +<!-- +SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 +--> + +## User-facing change + +Describe the Progmasoft, account, or ViGet behavior changed. State whether a deployed route or persistent account data +is affected. + +## Verification + +- [ ] Next.js check, frontend tests, lint, and build were run where relevant. +- [ ] ASP.NET Core build and API tests were run where relevant. +- [ ] en-US/de-DE, light/dark, accessibility, and small-screen behavior were considered for UI changes. +- [ ] Auth, session, publisher identity, registry paths, and deployment compatibility were reviewed if affected. +- [ ] No credentials, generated output, or unrelated files are included. + +Commands and results (including anything not run): + +```text + +``` + +Screenshots or recordings for visual changes: diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index e534f44..0aa2c83 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -23,6 +23,7 @@ on: permissions: contents: read + id-token: write concurrency: group: backend-${{ github.ref }} @@ -41,4 +42,10 @@ jobs: cache-dependency-path: "**/*.csproj" - run: dotnet restore Progmaweb.slnx --locked-mode - run: dotnet build Progmaweb.slnx --configuration Release --no-restore - - run: dotnet test --project apps/api-tests/Progmaweb.Api.Tests.csproj --configuration Release --no-build + - run: dotnet test --project apps/api-tests/Progmaweb.Api.Tests.csproj --configuration Release --no-build --coverlet --coverlet-output-format cobertura + - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + use_oidc: true + files: TestResults/coverage.cobertura.xml + flags: progmaweb-backend + fail_ci_if_error: true diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..1f6db33 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +# SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 + +name: CodeQL +on: + push: + branches: [main] + pull_request: + schedule: + - cron: '37 4 * * 1' +permissions: + actions: read + contents: read + security-events: write +jobs: + analyze: + name: ${{ matrix.language }} + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + include: + - language: actions + build_mode: none + - language: javascript-typescript + build_mode: none + - language: csharp + build_mode: manual + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-dotnet@v5 + if: matrix.language == 'csharp' + with: + dotnet-version: 10.0.x + - uses: github/codeql-action/init@7999b86c43a865dc79d8923397f35af22de63401 # v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build_mode }} + config-file: ./.github/codeql/codeql-config.yml + queries: security-extended + - name: Build ASP.NET Core for extraction + if: matrix.language == 'csharp' + run: | + dotnet restore Progmaweb.slnx --locked-mode + dotnet build Progmaweb.slnx --configuration Release --no-restore + - uses: github/codeql-action/analyze@7999b86c43a865dc79d8923397f35af22de63401 # v4 + with: + category: /language:${{ matrix.language }} + diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index cdbdb0a..87e17da 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -23,6 +23,7 @@ on: permissions: contents: read + id-token: write concurrency: group: frontend-${{ github.ref }} @@ -44,5 +45,12 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm check + - run: pnpm test:coverage - run: pnpm lint - run: pnpm build + - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + use_oidc: true + files: apps/web/coverage/lcov.info + flags: progmaweb-frontend + fail_ci_if_error: true @@ -5,6 +5,7 @@ node_modules/ .next/ out/ coverage/ +TestResults/ dist/ bin/ obj/ @@ -71,11 +71,18 @@ downloaded Google client JSON. ```text pnpm check +pnpm test +pnpm test:coverage pnpm build dotnet build apps/api/Progmaweb.Api.csproj --configuration Release dotnet test --project apps/api-tests/Progmaweb.Api.Tests.csproj --configuration Release +dotnet test --project apps/api-tests/Progmaweb.Api.Tests.csproj --configuration Release --coverlet --coverlet-output-format cobertura ``` +Frontend tests exercise the published locale contract and account/ViGet metadata without starting a production service. +The frontend LCOV and API Cobertura reports are uploaded to Codecov as separate components in CI. CodeQL and Codacy +provide static analysis; Dependabot proposes dependency updates without merging them automatically. + ## License Progmaweb project-owned source code is licensed under `AGPL-3.0-or-later`, matching the Visual X# website, with the diff --git a/apps/api-tests/Progmaweb.Api.Tests.csproj b/apps/api-tests/Progmaweb.Api.Tests.csproj index 63b5f6c..efb6a2f 100644 --- a/apps/api-tests/Progmaweb.Api.Tests.csproj +++ b/apps/api-tests/Progmaweb.Api.Tests.csproj @@ -11,6 +11,7 @@ </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.11" /> + <PackageReference Include="coverlet.MTP" Version="8.0.0" /> <!-- xUnit's MTP-v2 package is the native .NET 10 test host. Keeping the VSTest adapter here would make the solution mix incompatible runners. --> <PackageReference Include="xunit.v3.mtp-v2" Version="4.0.0" /> diff --git a/apps/api-tests/packages.lock.json b/apps/api-tests/packages.lock.json index 38c06e7..ca4dbb9 100644 --- a/apps/api-tests/packages.lock.json +++ b/apps/api-tests/packages.lock.json @@ -2,6 +2,17 @@ "version": 1, "dependencies": { "net10.0": { + "coverlet.MTP": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "r3+GPhzJd8G/qlw8UFOYGECZSFvpg0j+yRTGbSr8ikk1ed4Hui+Y56ghPcBT43S3DWYKEzZLGmZ/KFS28k1zHg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.1", + "Microsoft.Extensions.DependencyInjection": "8.0.1", + "Microsoft.Testing.Platform": "2.0.2" + } + }, "Microsoft.AspNetCore.Mvc.Testing": { "type": "Direct", "requested": "[10.0.11, )", diff --git a/apps/api/packages.lock.json b/apps/api/packages.lock.json index d134eda..b7d7ff4 100644 --- a/apps/api/packages.lock.json +++ b/apps/api/packages.lock.json @@ -10,4 +10,4 @@ } } } -} +}
\ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index ba3bcf5..fef38d7 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -12,6 +12,8 @@ "build": "next build", "start": "next start", "check": "next typegen && tsc --noEmit", + "test": "node --experimental-strip-types --test tests/*.test.mjs", + "test:coverage": "c8 --reporter=lcov --reporter=text npm test", "lint": "eslint . --max-warnings=0", "format": "prettier --write ." }, @@ -21,6 +23,7 @@ "react-dom": "19.2.8" }, "devDependencies": { + "c8": "12.0.0", "@types/node": "24.10.1", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", diff --git a/apps/web/tests/localization.test.mjs b/apps/web/tests/localization.test.mjs new file mode 100644 index 0000000..3d499ed --- /dev/null +++ b/apps/web/tests/localization.test.mjs @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +// SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 + +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { + getMessages, + isLocale, + messages, + supportedLocales, +} from "../lib/localization.ts"; + +test("only the two published locales are accepted", () => { + assert.deepEqual(supportedLocales, ["en-US", "de-DE"]); + assert.equal(isLocale("en-US"), true); + assert.equal(isLocale("de-DE"), true); + for (const value of ["en", "de", "en-us", "tr-TR", "", undefined]) { + assert.equal(isLocale(value), false, `unexpected locale: ${value}`); + } +}); + +test("both locales give the account and ViGet routes distinct page metadata", () => { + const english = messages["en-US"].metadata; + const german = messages["de-DE"].metadata; + for (const key of [ + "homeTitle", + "accountTitle", + "loginTitle", + "registerTitle", + "vigetTitle", + "dslPluginsTitle", + ]) { + assert.equal(typeof english[key], "string"); + assert.equal(typeof german[key], "string"); + assert.notEqual(english[key].trim(), ""); + assert.notEqual(german[key].trim(), ""); + } + assert.notEqual(english.loginTitle, german.loginTitle); + assert.notEqual(english.registerTitle, german.registerTitle); + assert.match(english.vigetTitle, /ViGet/); + assert.match(german.vigetTitle, /ViGet/); +}); + +test("each supported locale resolves to its own complete message tree", () => { + for (const locale of supportedLocales) { + assert.strictEqual(getMessages(locale), messages[locale]); + } + + function shape(value) { + if (Array.isArray(value)) return value.map(shape); + if (value !== null && typeof value === "object") { + return Object.fromEntries( + Object.entries(value).map(([key, child]) => [key, shape(child)]), + ); + } + assert.equal(typeof value, "string"); + assert.notEqual(value.trim(), ""); + return "text"; + } + + assert.deepEqual(shape(messages["de-DE"]), shape(messages["en-US"])); +}); diff --git a/package.json b/package.json index 4c409f8..003afee 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "dev": "pnpm --filter @progmasoft/web dev", "build": "pnpm --filter @progmasoft/web build", "check": "pnpm --filter @progmasoft/web check", + "test": "pnpm --filter @progmasoft/web test", + "test:coverage": "pnpm --filter @progmasoft/web test:coverage", "lint": "pnpm --filter @progmasoft/web lint", "format": "pnpm --filter @progmasoft/web format" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06db313..9e6edee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: '@types/react-dom': specifier: 19.2.3 version: 19.2.3(@types/react@19.2.14) + c8: + specifier: 12.0.0 + version: 12.0.0 eslint: specifier: 9.39.2 version: 9.39.2(supports-color@7.2.0) @@ -111,6 +114,10 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} @@ -349,6 +356,10 @@ packages: cpu: [x64] os: [win32] + '@istanbuljs/schema@0.1.6': + resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} + engines: {node: '>=8'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -458,6 +469,9 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -667,10 +681,18 @@ packages: ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -757,6 +779,16 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + c8@12.0.0: + resolution: {integrity: sha512-4zpJvrd1nKWutnnKC2pXkFmb6iM1l+ffN//o1CzlTNwW7GSOs9a1xrLqkC48nU8oEkjmPZLPiwMsIaOvoF4Pqg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + hasBin: true + peerDependencies: + monocart-coverage-reports: ^2 + peerDependenciesMeta: + monocart-coverage-reports: + optional: true + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -783,6 +815,10 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -861,6 +897,9 @@ packages: electron-to-chromium@1.5.415: resolution: {integrity: sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==} + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -1077,6 +1116,10 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -1095,6 +1138,14 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -1118,6 +1169,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1167,6 +1222,9 @@ packages: hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1300,6 +1358,18 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} @@ -1363,9 +1433,17 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1388,6 +1466,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1496,6 +1578,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1642,6 +1728,10 @@ packages: resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} engines: {node: '>= 0.4'} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1653,6 +1743,14 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -1676,6 +1774,10 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -1705,6 +1807,10 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + test-exclude@8.0.0: + resolution: {integrity: sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==} + engines: {node: 20 || >=22} + tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} @@ -1776,6 +1882,10 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -1801,9 +1911,29 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -1919,6 +2049,8 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@bcoe/v8-coverage@1.0.2': {} + '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -2114,6 +2246,8 @@ snapshots: '@img/sharp-win32-x64@0.35.4': optional: true + '@istanbuljs/schema@0.1.6': {} + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -2200,6 +2334,8 @@ snapshots: '@types/estree@1.0.9': {} + '@types/istanbul-lib-coverage@2.0.6': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -2390,10 +2526,14 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@6.3.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + argparse@2.0.1: {} aria-query@5.3.2: {} @@ -2504,6 +2644,20 @@ snapshots: node-releases: 2.0.54 update-browserslist-db: 1.3.1(browserslist@4.28.8) + c8@12.0.0: + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@istanbuljs/schema': 0.1.6 + find-up: 5.0.0 + foreground-child: 3.3.1 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + test-exclude: 8.0.0 + v8-to-istanbul: 9.3.0 + yargs: 18.2.0 + yargs-parser: 21.1.1 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -2532,6 +2686,12 @@ snapshots: client-only@0.0.1: {} + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2611,6 +2771,8 @@ snapshots: electron-to-chromium@1.5.415: {} + emoji-regex@10.6.0: {} + emoji-regex@9.2.2: {} es-abstract-get@1.0.0: @@ -2977,6 +3139,11 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + function-bind@1.1.2: {} function.prototype.name@1.2.0: @@ -2997,6 +3164,10 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + + get-east-asian-width@1.7.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -3033,6 +3204,12 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@13.0.6: + dependencies: + minimatch: 10.2.6 + minipass: 7.1.3 + path-scurry: 2.0.2 + globals@14.0.0: {} globals@16.4.0: {} @@ -3072,6 +3249,8 @@ snapshots: dependencies: hermes-estree: 0.25.1 + html-escaper@2.0.2: {} + ignore@5.3.2: {} ignore@7.0.6: {} @@ -3209,6 +3388,19 @@ snapshots: isexe@2.0.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -3270,10 +3462,16 @@ snapshots: dependencies: js-tokens: 4.0.0 + lru-cache@11.5.3: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 + make-dir@4.0.0: + dependencies: + semver: 7.8.5 + math-intrinsics@1.1.0: {} merge2@1.4.1: {} |