├── .dockerignore ├── .env ├── .env.rp ├── .github └── workflows │ ├── docker-registry.yml │ ├── playwright-test.yml │ └── test-from-docker.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .prettierignore ├── .prettierrc.json ├── Dockerfile ├── Jenkinsfile ├── README.md ├── browsers.json ├── commitlint.config.mjs ├── custom_report ├── customreporter.ts └── influxdb.ts ├── docker-compose-reportportal.yml ├── docker-compose.yml ├── e2e ├── init │ ├── global-setup.ts │ └── global-teardown.ts └── tests │ ├── cart.spec.ts │ ├── home.spec.ts │ └── pip.spec.ts ├── eslint.config.mjs ├── k8s-manifests ├── job.yml ├── pv.yml └── pvc.yml ├── package-lock.json ├── package.json ├── page_objects ├── checkout.page.ts ├── login.page.ts ├── page.ts ├── product.info.ts └── product.list.cart.ts ├── playwright.config.ts ├── rpConfig.ts ├── test_data └── data.json ├── tsconfig.json └── utilities ├── fixture.ts ├── mongoclient.ts ├── read.yml.ts ├── stepdecorator.ts └── test.data.ts /.dockerignore: -------------------------------------------------------------------------------- 1 | ReadMe.md 2 | .github/ 3 | .vscode/ 4 | node_modules/ 5 | playwright-report/ 6 | test-results/ -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # .env file 2 | STAGING=0 3 | USER_NAME=me 4 | PASSWORD=secret 5 | URL=https://www.saucedemo.com 6 | 7 | # influx db details 8 | INFLUX_URL=https://8086-port-3b109de2e39a4833.labs.kodekloud.com/ 9 | INFLUX_TOKEN=Ppw5LspEuZu0zrdpf4ydDpNiAR0joF8Oiq2Jw8PJ7t3gX2DsG9OeLrEk1D_nK0jOp8sKPxnMgIsFLNTo3XdAXQ== 10 | INFLUX_ORG=qa-test 11 | INFLUX_BUCKET=QA 12 | 13 | #mongo DB details 14 | DB_CONN_STRING="mongodb+srv://:@solar-system.mkbz1n9.mongodb.net/" 15 | DB_NAME="student" 16 | COLLECTION_NAME="users" -------------------------------------------------------------------------------- /.env.rp: -------------------------------------------------------------------------------- 1 | RP_ENDPOINT=http://localhost:8080/api/v1 2 | RP_API_KEY= 3 | RP_LAUNCH=playwright-demo 4 | RP_PROJECT=playwright-saucelabs 5 | RP_ENV=staging 6 | RP_TAGS=playwright,saucelabs 7 | -------------------------------------------------------------------------------- /.github/workflows/docker-registry.yml: -------------------------------------------------------------------------------- 1 | name: Upload the image to docker hub 2 | on: 3 | push: 4 | tags: 5 | - 'v*' 6 | workflow_dispatch: 7 | inputs: 8 | name: 9 | type: string 10 | description: Enter the tag name 11 | required: true 12 | default: Enter value in format vx.x.x 13 | 14 | 15 | jobs: 16 | build-and-push-image: 17 | if: ${{ github.ref_type == 'tag' }} 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: checkout repo 21 | uses: actions/checkout@v4 22 | 23 | - name: Set up Docker Buildx 24 | uses: docker/setup-buildx-action@v3 25 | 26 | - name: Get version and repo name 27 | id: version-repo 28 | run: | 29 | export name=$(echo ${{ github.repository }} | cut -d '/' -f 2) 30 | echo "repo_name=$name" >> "$GITHUB_ENV" 31 | 32 | export version=$(echo ${{ github.ref_name }} | tr -d v) 33 | echo "version_no=$version" >> "$GITHUB_ENV" 34 | 35 | 36 | 37 | - name: Docker meta 38 | id: meta 39 | uses: docker/metadata-action@v5 40 | with: 41 | images: | 42 | ${{ vars.DOCKER_USER_NAME }}/${{ env.repo_name }} 43 | 44 | tags: | 45 | type=ref,event=branch 46 | type=ref,event=pr 47 | type=semver,pattern={{version}} 48 | type=semver,pattern={{major}}.{{minor}} 49 | type=sha 50 | 51 | - name: Login to Docker hub 52 | uses: docker/login-action@v3 53 | with: 54 | username: ${{ vars.DOCKER_USER_NAME }} 55 | password: ${{ secrets.DOCKER_PASSWORD }} 56 | 57 | - name: push Docker image 58 | uses: docker/build-push-action@v5 59 | with: 60 | context: . 61 | push: true 62 | tags: | 63 | ${{ steps.meta.outputs.tags }} 64 | labels: ${{ steps.meta.outputs.labels }} 65 | 66 | - name: Check the test image builds 67 | run: | 68 | docker images 69 | -------------------------------------------------------------------------------- /.github/workflows/playwright-test.yml: -------------------------------------------------------------------------------- 1 | name: Test execution on Github server 2 | on: 3 | pull_request: 4 | branches: [ test-run/**, main ] 5 | 6 | workflow_dispatch: 7 | 8 | jobs: 9 | test: 10 | permissions: 11 | contents: write 12 | pull-requests: write 13 | pages: write 14 | id-token: write 15 | 16 | timeout-minutes: 60 17 | runs-on: ubuntu-latest 18 | continue-on-error: true 19 | 20 | 21 | steps: 22 | - name: checkout repo 23 | uses: actions/checkout@v4 24 | 25 | - name: setup node 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: 20 29 | 30 | - name: Cache Node Modules 31 | id: cache-node-modules 32 | uses: actions/cache@v4 33 | with: 34 | path: | 35 | node_modules 36 | key: modules-${{ hashFiles('package-lock.json') }} 37 | 38 | - name: Cache Playwright Binaries 39 | id: cache-playwright 40 | uses: actions/cache@v4 41 | with: 42 | path: | 43 | ~/.cache/ms-playwright 44 | key: playwright-${{ hashFiles('package-lock.json') }} 45 | 46 | - name: Install dependencies 47 | id: install-dependencies 48 | if: steps.cache-node-modules.outputs.cache-hit != 'true' 49 | run: npm ci 50 | 51 | - name: Install Playwright Browsers 52 | id: install-playwright-browsers 53 | if: steps.cache-playwright.outputs.cache-hit != 'true' 54 | run: npx playwright install --with-deps 55 | 56 | - name: Run Playwright tests 57 | continue-on-error: true 58 | run: | 59 | npx playwright test 60 | 61 | - name: Get the failure count 62 | id: tests 63 | run: | 64 | export count=$(cat ./playwright-report/result.txt | grep Failed | cut -d ':' -f 2 | tr -d ' ') 65 | echo "fail_count=$count" >> "$GITHUB_OUTPUT" 66 | echo $count 67 | 68 | - uses: mshick/add-pr-comment@v2 69 | if: always() 70 | with: 71 | message-path: | 72 | ./playwright-report/result.txt 73 | message-failure: | 74 | Workflow failed 75 | 76 | 77 | - name: Setup Pages 78 | if: steps.tests.outputs.fail_count != '0' 79 | uses: actions/configure-pages@v5 80 | 81 | - name: Upload Artifact 82 | if: steps.tests.outputs.fail_count != '0' 83 | uses: actions/upload-pages-artifact@v3 84 | with: 85 | path: "./playwright-report" 86 | 87 | 88 | 89 | 90 | # - name: Fail the job if there any failed case 91 | # if: steps.tests.outputs.fail_count != '0' 92 | # run : | 93 | # exit 1 94 | 95 | outputs: 96 | fail_count: ${{ steps.tests.outputs.fail_count }} 97 | 98 | deploy: 99 | if: needs.test.outputs.fail_count != '0' 100 | 101 | needs: test 102 | 103 | permissions: 104 | pages: write 105 | id-token: write 106 | 107 | environment: 108 | name: github-pages 109 | url: ${{ steps.deployment.outputs.page_url }} 110 | 111 | runs-on: ubuntu-latest 112 | steps: 113 | 114 | 115 | - name: Deploy to GitHub Pages 116 | id: deployment 117 | uses: actions/deploy-pages@v4 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /.github/workflows/test-from-docker.yml: -------------------------------------------------------------------------------- 1 | name: Execute tests inside Docker container 2 | on: 3 | push: 4 | branches: [ main ] 5 | 6 | workflow_dispatch: 7 | 8 | jobs: 9 | container-test-job: 10 | permissions: 11 | contents: write 12 | pull-requests: write 13 | runs-on: ubuntu-latest 14 | name: execute a test from a image 15 | steps: 16 | - name: set up a docker environement 17 | uses: docker/setup-buildx-action@v3 18 | 19 | - name: Login to Docker hub 20 | uses: docker/login-action@v3 21 | with: 22 | username: ${{ vars.DOCKER_USER_NAME }} 23 | password: ${{ secrets.DOCKER_PASSWORD }} 24 | 25 | - name: pull and run the test from image 26 | id: tests 27 | run: | 28 | docker pull ${{ vars.DOCKER_USER_NAME }}/playwright-ui-typescript:latest 29 | docker run -v ./playwright-report:/app/playwright-report \ 30 | ${{ vars.DOCKER_USER_NAME }}/playwright-ui-typescript:latest \ 31 | -c "npx playwright test" 32 | export count=$(cat ./playwright-report/result.txt | grep Failed | cut -d ':' -f 2 | tr -d ' ') 33 | echo "fail_count=$count" >> "$GITHUB_OUTPUT" 34 | 35 | 36 | - name: Add the test summary status back to PR comment 37 | uses: mshick/add-pr-comment@v2 38 | if: (contains(fromJSON('["pull_request"]'), github.event_name)) 39 | with: 40 | message-path: | 41 | ./playwright-report/result.txt 42 | message-failure: | 43 | Workflow failed 44 | 45 | - name: Setup Pages 46 | uses: actions/configure-pages@v3 47 | 48 | - name: Upload Artifact for pages 49 | uses: actions/upload-pages-artifact@v1 50 | with: 51 | path: "./playwright-report" 52 | 53 | - name: Fail the job if there any failed case 54 | if: ${{ steps.tests.outputs.fail_count == '0' }} 55 | run : | 56 | exit 1 57 | 58 | outputs: 59 | fail_count: ${{ steps.tests.outputs.fail_count }} 60 | 61 | publish-reports: 62 | if: ${{ contains(github.ref,'main') && (contains(fromJSON('[ "push"]'), github.event_name)) && needs.test.outputs.fail_count != '0' }} 63 | needs: [ container-test-job ] 64 | runs-on: ubuntu-latest 65 | permissions: 66 | pages: write 67 | id-token: write 68 | environment: 69 | name: github-pages 70 | url: ${{ steps.deployment.outputs.page_url }} 71 | 72 | steps: 73 | - name: Deploy to GitHub Pages 74 | id: deployment 75 | uses: actions/deploy-pages@v2 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /test-results/ 3 | /playwright-report/ 4 | /blob-report/ 5 | /playwright/.cache/ 6 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx --no-install commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | # Format uncommitted files and add them to the commit 2 | npx lint-staged --concurrent false --verbose 3 | 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files to this list to exclude them from Prettier formatting: 2 | 3 | /.cloudbees 4 | /.github 5 | /.husky 6 | 7 | /allure-results 8 | /env 9 | /adr 10 | /docs 11 | /Logs 12 | /playwright-report 13 | /test-results 14 | /node_modules 15 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "jsxSingleQuote": false, 4 | "tabWidth": 2, 5 | "useTabs": false, 6 | "trailingComma": "all", 7 | "printWidth": 140, 8 | "semi": false, 9 | "arrowParens": "avoid", 10 | "bracketSpacing": true, 11 | "bracketSameLine": false, 12 | "proseWrap": "always", 13 | "quoteProps": "consistent", 14 | "endOfLine": "lf" 15 | } 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # use any base node image 2 | FROM node:22.9 3 | 4 | # copy the current working directories, please add .dockerignore to ommit unnecessay files 5 | WORKDIR /app 6 | COPY . /app 7 | 8 | RUN npm cache clean --force 9 | # install only the chromium based browser and dependencies 10 | RUN npm install 11 | RUN npx -y playwright install --with-deps msedge 12 | ENTRYPOINT ["/bin/sh"] -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { 3 | docker { 4 | image 'thanandock/playwright-ui-typescript:latest' 5 | args '--shm-size=1g --rm -v ${env.WORKSPACE}/playwright-report:/app/playwright-report' // assign some memory and remove container for every execution 6 | } 7 | } 8 | stages { 9 | stage('Run Tests') { 10 | steps { 11 | sh ''' 12 | echo 'Starting Playwright tests...' 13 | npx playwright test' 14 | ''' 15 | } 16 | } 17 | stage('Check Failures') { 18 | steps { 19 | script { 20 | // Extract 'count' from the result file using shell command 21 | def count = sh(script: "cat ./playwright-report/result.txt | grep Failed | cut -d ':' -f 2 | tr -d ' '", returnStdout: true).trim() 22 | env.FAIL_COUNT = count 23 | } 24 | } 25 | } 26 | } 27 | post { 28 | always { 29 | script { 30 | // Convert env.COUNT to an integer 31 | int count = env.FAIL_COUNT as Integer 32 | 33 | // Check if count is greater than 0 34 | if (count > 0) { 35 | echo "COUNT is greater than 0. Exiting pipeline." 36 | currentBuild.result = 'FAILURE' // Mark the build as failed 37 | error("Pipeline stopped because COUNT is greater than 0.") 38 | } else { 39 | echo "COUNT is not greater than 0. Proceeding with pipeline." 40 | } 41 | } 42 | } 43 | failure{ 44 | echo 'Archiving test report...' 45 | archiveArtifacts artifacts: "./playwright-report", allowEmptyArchive: false 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Playwright UI Test Automation with TypeScript 2 | 3 | A comprehensive suite of UI test cases built using Playwright for the [SauceDemo](https://saucedemo.com) website. This repository demonstrates how Playwright can seamlessly integrate with various tools and technologies for efficient test execution, reporting, and CI/CD automation. 4 | 5 | ## Table of Contents 6 | - [Getting Started](#getting-started) 7 | - [Database Integration](#database-integration) 8 | - [Test Trend Analysis with InfluxDB 2.0](#test-trend-analysis-with-influxdb-20) 9 | - [Docker Integration](#docker-integration) 10 | - [Jenkins Pipeline](#jenkins-pipeline) 11 | - [GitHub Actions Workflow](#github-actions-workflow) 12 | - [Kubernetes Deployment](#kubernetes-deployment) 13 | - [Live Test Execution with ReportPortal](#live-test-execution-with-reportportal) 14 | - [Code Quality with Husky](#code-quality-with-husky) 15 | - [Related Blogs & Resources](#related-blogs--resources) 16 | 17 | ## Getting Started 18 | 19 | ### Clone and Run Locally 20 | Clone the repository and install dependencies: 21 | ```sh 22 | git clone https://github.com/thananauto/playwright-ui-typescript.git 23 | cd playwright-ui-typescript 24 | npm install 25 | npx playwright test 26 | ``` 27 | Test reports will be generated with timestamps at: 28 | ```sh 29 | ./playwright-report// 30 | ``` 31 | 32 | ## Database Integration 33 | 34 | ### Test Trend Analysis with InfluxDB 2.0 35 | Playwright's custom reporter allows test summary results to be stored in a time-series database like InfluxDB 2.0. 36 | 37 | - Set up InfluxDB using Docker by referring to `docker-compose.yml`. 38 | - Configure the integration using files in `./custom_report`. 39 | 40 | ## Docker Integration 41 | 42 | To run tests inside a Docker container: 43 | 44 | 1. Build the Docker image: 45 | ```sh 46 | docker build -t playwright-tests . 47 | ``` 48 | 2. Run tests inside the container: 49 | ```sh 50 | docker run -it -v $(pwd)/report:/app/playwright-report playwright-tests -c "npx playwright test" 51 | ``` 52 | 53 | ## Jenkins Pipeline 54 | 55 | Execute tests inside a Docker container through a Jenkins pipeline. The pipeline archives test results for each build. 56 | 57 | ## GitHub Actions Workflow 58 | 59 | For continuous integration, GitHub Actions can execute Playwright tests seamlessly. 60 | 61 | 1. **Run tests in a GitHub-hosted Linux server**: [Workflow](https://github.com/thananauto/playwright-ui-typescript/blob/main/.github/workflows/playwright-test.yml) 62 | 2. **Build and push Docker image to Docker Hub**: [Workflow](https://github.com/thananauto/playwright-ui-typescript/blob/main/.github/workflows/docker-registry.yml) 63 | 3. **Pull Docker image and execute tests**: [Workflow](https://github.com/thananauto/playwright-ui-typescript/blob/main/.github/workflows/test-from-docker.yml) 64 | 65 | ## Kubernetes Deployment 66 | 67 | Execute Playwright tests within a Kubernetes environment using the provided manifest files: 68 | 69 | 1. **Persistent Volume for test results**: [pv.yml](https://github.com/thananauto/playwright-ui-typescript/blob/main/k8s-manifests/pv.yml) 70 | 2. **Persistent Volume Claim**: [pvc.yml](https://github.com/thananauto/playwright-ui-typescript/blob/main/k8s-manifests/pvc.yml) 71 | 3. **Deploy job for test execution**: [job.yml](https://github.com/thananauto/playwright-ui-typescript/blob/main/k8s-manifests/job.yml) 72 | 73 | ## Live Test Execution with ReportPortal 74 | 75 | To enable real-time test execution monitoring with ReportPortal: 76 | 77 | 1. Start ReportPortal using Docker: 78 | ```sh 79 | docker compose -f docker-compose-reportportal.yml up 80 | ``` 81 | 2. Configure `rpConfig.ts` and `.env.rp` with ReportPortal details. 82 | 3. Add the reporter type in `playwright.config.ts`: 83 | ```ts 84 | reporters: [['@reportportal/agent-js-playwright', rpConfig]] 85 | ``` 86 | 87 | ## Code Quality with Husky 88 | 89 | Husky enforces code quality by ensuring consistent commit messages and code formatting. 90 | 91 | - Prettier for code formatting 92 | - Lint-staged for staged file validation 93 | - Commit lint to enforce commit message conventions 94 | 95 | For structured commits, follow this format: 96 | ```sh 97 | [QA][Smoke] - Fixed Smoke test 98 | ``` 99 | This indicates that the commit is related to the QA environment and includes a smoke test fix. 100 | 101 | **For more details, check this blog:** 102 | [Custom Git Commit Rules with Husky](https://medium.com/@thananjayan1988/apply-custom-rules-for-git-commit-messages-husky-6743680366be) 103 | 104 | ## Related Blogs & Resources 105 | 106 | - [Executing Tests on Remote Browser and Browser in Servers](https://medium.com/@thananjayan1988/playwright-executing-tests-on-remote-browser-and-browser-in-servers-48c9979b5b4f) 107 | - [Reusing Browser Sessions for Debugging in Playwright](https://medium.com/@thananjayan1988/reusing-browser-sessions-for-debugging-in-playwright-bac94cd6d999) 108 | - [Optimizing Playwright Test Execution in Minimal Docker Images](https://medium.com/@thananjayan1988/optimize-the-docker-image-for-playwright-tests-3688c7d4be5f) 109 | - [Live Visualization of Test Results Using Playwright and InfluxDB 2.0](https://medium.com/@thananjayan1988/live-visualization-of-test-results-using-playwright-and-influxdb-2-0-2a193656dda2) 110 | - [CI/CD Pipeline: Running Playwright Tests in Jenkins with Docker](https://medium.com/@thananjayan1988/ci-cd-pipeline-running-playwright-tests-in-jenkins-with-docker-f9f08fda4bfc) 111 | - [Enhancing Playwright Test Reports with Decorators](https://medium.com/@thananjayan1988/how-to-enhance-the-playwright-html-report-using-test-step-with-typescript-decorator-4b45797a3031) 112 | 113 | For a complete list of related blogs, check out [Medium](https://medium.com/@thananjayan1988). 114 | -------------------------------------------------------------------------------- /browsers.json: -------------------------------------------------------------------------------- 1 | { 2 | "chromium": { 3 | "default": "1.14", 4 | "versions": { 5 | "1.14": { 6 | "image": "playwright/chromium:playwright-1.14.0", 7 | "port": "4444", 8 | "path": "/wd/hub", 9 | "tmpfs": { "/tmp": "size=512m" }, 10 | "additionalNetworks": ["selenoid-net"] 11 | } 12 | } 13 | }, 14 | "chrome": { 15 | "default": "112.0", 16 | "versions": { 17 | "111.0": { 18 | "image": "selenoid/chrome:111.0", 19 | "port": "4444", 20 | "path": "/", 21 | "tmpfs": { "/tmp": "size=512m" }, 22 | "additionalNetworks": ["selenoid-net"] 23 | }, 24 | "112.0": { 25 | "image": "selenoid/chrome:112.0", 26 | "port": "4444", 27 | "path": "/", 28 | "tmpfs": { "/tmp": "size=512m" }, 29 | "additionalNetworks": ["selenoid-net"] 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /commitlint.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | parserPreset: { 3 | parserOpts: { 4 | headerPattern: /^\[(QA|TEST|STAGE)\]\[([A-Za-z0-9_]+(\|[A-Za-z0-9_]+)*)\] - (.+)$/, 5 | headerCorrespondence: ['issue', 'title'], 6 | }, 7 | }, 8 | plugins: [ 9 | { 10 | rules: { 11 | 'title-pattern': ({ issue, title }) => 12 | issue === null || title === null 13 | ? [ 14 | false, 15 | "Commit message pattern should be in the form of [QA|TEST|STAGE][TEST_CASE_TAGS] - message \n for example: [STAGE][Smoke] - Fixed login cases \n For 'TEST_CASE_TAGS' refer the annotation name of testsl\n for example: [QA][Smoke|Home|Cart] - Fixed cases", 16 | ] 17 | : [true, ''], 18 | }, 19 | }, 20 | ], 21 | rules: { 22 | 'title-pattern': [2, 'always'], 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /custom_report/customreporter.ts: -------------------------------------------------------------------------------- 1 | import type { FullConfig, FullResult, Suite, TestCase, TestResult, Reporter } from '@playwright/test/reporter' 2 | import { influx, Point } from './influxdb' 3 | import { writeFileSync } from 'fs' 4 | 5 | class MyReporter implements Reporter { 6 | count = { total: 0, passed: 0, failed: 0, skipped: 0 } 7 | arr_err: any = [] 8 | async onBegin(config: FullConfig, suite: Suite) { 9 | console.log('My Reporter ------ set up DB client instance ......') 10 | //await setup(); 11 | console.log(`Starting the run with ${suite.allTests().length} tests`) 12 | this.count['total'] = suite.allTests().length 13 | } 14 | 15 | async onTestBegin(test: TestCase) { 16 | console.log(`Starting test ${test.title}`) 17 | } 18 | 19 | async onTestEnd(test: TestCase, result: TestResult) { 20 | console.log(`Finished test ${test.title}: ${result.status}`) 21 | await this.collectStatus(result) 22 | } 23 | 24 | async onEnd(result: FullResult) { 25 | //await teardown(); 26 | console.log('My Reporter ------ client instance done ......') 27 | console.log(`Finished the run: ${result.status}`) 28 | //overall summary status 29 | const resultMarkdownMessage = ` 30 | Test run results 31 | 32 | Summary: 33 | - ⌛ Total test cases ${this.count['total']} 34 | - 📦 Tests results: 35 | - Passed ✅: ${this.count['passed']} 36 | - Failed ❌: ${this.count['failed']} 37 | - Skipped ⏩: ${this.count['skipped']} 38 | 39 | To see the full report, please visit our github page for more details` 40 | 41 | console.log(resultMarkdownMessage) 42 | writeFileSync('./playwright-report/result.txt', resultMarkdownMessage, { 43 | flag: 'w', 44 | }) 45 | //time duration to execute 46 | console.log(`Total duration: ${result.duration}`) 47 | if (this.count['failed'] > 0) { 48 | this.arr_err.map(function (e: any) { 49 | console.log(e[0]['message']) 50 | }) 51 | } 52 | //add the point for influx db 53 | const status = new Point('QA') 54 | .tag('Status', 'UI Cases') 55 | .intField('Total', this.count['total']) 56 | .intField('Passed', this.count['passed']) 57 | .intField('Failed', this.count['failed']) 58 | .intField('Skipped', this.count['skipped']) 59 | await influx.writeMeasurement(status) 60 | 61 | //add the time duration 62 | const duration = new Point('QA').tag('Duration', 'time').floatField('Time', result.duration) 63 | await influx.writeMeasurement(duration) 64 | 65 | await influx.closeApi() 66 | } 67 | 68 | async collectStatus(status: TestResult) { 69 | switch (status.status) { 70 | case 'failed': 71 | case 'timedOut': 72 | this.count['failed'] += 1 73 | this.arr_err.push(status.errors) 74 | break 75 | case 'skipped': 76 | this.count['skipped'] += 1 77 | break 78 | case 'passed': 79 | this.count['passed'] += 1 80 | break 81 | } 82 | } 83 | } 84 | 85 | export default MyReporter 86 | -------------------------------------------------------------------------------- /custom_report/influxdb.ts: -------------------------------------------------------------------------------- 1 | import { InfluxDB, Point } from '@influxdata/influxdb-client' 2 | 3 | class InfluxDb { 4 | readonly writeApi 5 | 6 | constructor() { 7 | this.writeApi = new InfluxDB({ 8 | url: process.env.INFLUX_URL as string, 9 | token: process.env.INFLUX_TOKEN as string, 10 | }).getWriteApi(process.env.INFLUX_ORG as string, process.env.INFLUX_BUCKET as string) 11 | } 12 | 13 | async writeMeasurement(point: Point) { 14 | this.writeApi.writePoint(point) 15 | } 16 | 17 | async closeApi() { 18 | await this.writeApi.close().then(() => { 19 | console.log('WRITE FINISHED') 20 | }) 21 | } 22 | } 23 | 24 | const influx = new InfluxDb() 25 | export { influx, Point } 26 | -------------------------------------------------------------------------------- /docker-compose-reportportal.yml: -------------------------------------------------------------------------------- 1 | ## ReportPortal common variables 2 | x-logging: &logging 3 | driver: 'json-file' 4 | options: 5 | max-size: 100m 6 | max-file: '5' 7 | x-database: 8 | db_host: &db_host postgres 9 | db_port: &db_port 5432 10 | db_user: &db_user ${POSTGRES_USER-rpuser} 11 | db_password: &db_password ${POSTGRES_PASSWORD-rppass} 12 | db_name: &db_name ${POSTGRES_DB-reportportal} 13 | x-amqp: 14 | rabbitmq_host: &rabbitmq_host rabbitmq 15 | rabbitmq_port: &rabbitmq_port 5672 16 | rabbitmq_apiport: &rabbitmq_apiport 15672 17 | rabbitmq_user: &rabbitmq_user ${RABBITMQ_DEFAULT_USER-rabbitmq} 18 | rabbitmq_password: &rabbitmq_password ${RABBITMQ_DEFAULT_PASS-rabbitmq} 19 | x-environment: &common-environment 20 | RP_DB_HOST: *db_host 21 | RP_DB_PORT: *db_port 22 | RP_DB_USER: *db_user 23 | RP_DB_PASS: *db_password 24 | RP_DB_NAME: *db_name 25 | RP_AMQP_HOST: *rabbitmq_host 26 | RP_AMQP_PORT: *rabbitmq_port 27 | RP_AMQP_APIPORT: *rabbitmq_apiport 28 | RP_AMQP_USER: *rabbitmq_user 29 | RP_AMQP_PASS: *rabbitmq_password 30 | RP_AMQP_APIUSER: *rabbitmq_user 31 | RP_AMQP_APIPASS: *rabbitmq_password 32 | RP_AMQP_ANALYZER-VHOST: analyzer 33 | DATASTORE_TYPE: filesystem 34 | x-analyzer-environment: &common-analyzer-environment 35 | LOGGING_LEVEL: info 36 | AMQP_EXCHANGE_NAME: analyzer-default 37 | AMQP_VIRTUAL_HOST: analyzer 38 | AMQP_URL: amqp://${RABBITMQ_DEFAULT_USER-rabbitmq}:${RABBITMQ_DEFAULT_PASS-rabbitmq}@rabbitmq:5672 39 | ES_HOSTS: http://opensearch:9200 40 | ANALYZER_BINARYSTORE_TYPE: filesystem 41 | 42 | services: 43 | ## 44 | ## ReportPortal dependencies 45 | gateway: 46 | image: traefik:v2.11.15 47 | logging: 48 | <<: *logging 49 | ports: 50 | ## ReportPortal UI 51 | - '8080:8080' 52 | ## Traefik dashboard 53 | - '8081:8081' 54 | volumes: 55 | - /var/run/docker.sock:/var/run/docker.sock 56 | command: 57 | - --providers.docker=true 58 | - --providers.docker.constraints=Label(`traefik.expose`, `true`) 59 | - --entrypoints.web.address=:8080 60 | - --entrypoints.traefik.address=:8081 61 | - --api.dashboard=true 62 | - --api.insecure=true 63 | networks: 64 | - reportportal 65 | restart: always 66 | profiles: 67 | - core 68 | - '' 69 | 70 | postgres: 71 | image: bitnami/postgresql:16.6.0 72 | container_name: *db_host 73 | logging: 74 | <<: *logging 75 | shm_size: '512m' 76 | environment: 77 | POSTGRES_USER: *db_user 78 | POSTGRES_PASSWORD: *db_password 79 | POSTGRES_DB: *db_name 80 | volumes: 81 | - postgres:/bitnami/postgresql 82 | ## Uncomment to expose Database 83 | # ports: 84 | # - "5432:5432" 85 | healthcheck: 86 | test: ['CMD-SHELL', 'pg_isready -d $$POSTGRES_DB -U $$POSTGRES_USER'] 87 | interval: 10s 88 | timeout: 120s 89 | retries: 10 90 | networks: 91 | - reportportal 92 | restart: always 93 | profiles: 94 | - core 95 | - '' 96 | 97 | rabbitmq: 98 | image: bitnami/rabbitmq:3.13.7-debian-12-r5 99 | logging: 100 | <<: *logging 101 | ## Uncomment the following lines to expose RabbitMQ Management on port 5672 and API on 15672 102 | # ports: 103 | # - "5672:5672" 104 | # - "15672:15672" 105 | environment: 106 | RABBITMQ_DEFAULT_USER: *rabbitmq_user 107 | RABBITMQ_DEFAULT_PASS: *rabbitmq_password 108 | RABBITMQ_MANAGEMENT_ALLOW_WEB_ACCESS: 'true' 109 | ## Block all prcedures when free disk space is less than 50MB 110 | ## Ref: https://www.rabbitmq.com/docs/disk-alarms 111 | RABBITMQ_DISK_FREE_ABSOLUTE_LIMIT: 50MB 112 | RABBITMQ_PLUGINS: > 113 | rabbitmq_consistent_hash_exchange rabbitmq_management rabbitmq_auth_backend_ldap rabbitmq_shovel rabbitmq_shovel_management 114 | healthcheck: 115 | test: ['CMD', 'rabbitmqctl', 'status'] 116 | interval: 30s 117 | timeout: 30s 118 | retries: 5 119 | networks: 120 | - reportportal 121 | restart: always 122 | profiles: 123 | - core 124 | - '' 125 | 126 | opensearch: 127 | image: opensearchproject/opensearch:2.18.0 128 | logging: 129 | <<: *logging 130 | environment: 131 | discovery.type: single-node 132 | plugins.security.disabled: 'true' 133 | bootstrap.memory_lock: 'true' 134 | OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m 135 | DISABLE_INSTALL_DEMO_CONFIG: 'true' 136 | ulimits: 137 | memlock: 138 | soft: -1 139 | hard: -1 140 | ## Uncomment the following lines to expose OpenSearch on ports 9200 and 9600 141 | # ports: 142 | # - "9200:9200" # OpenSearch HTTP API 143 | # - "9600:9600" # OpenSearch Performance Analyzer 144 | volumes: 145 | - opensearch:/usr/share/opensearch/data 146 | healthcheck: 147 | test: ['CMD', 'curl', '-s', '-f', 'http://0.0.0.0:9200/_cat/health'] 148 | networks: 149 | - reportportal 150 | restart: always 151 | profiles: 152 | - '' 153 | 154 | ## 155 | ## ReportPortal Core services 156 | migrations: 157 | image: ${MIGRATIONS_IMAGE-reportportal/migrations:5.13.0} 158 | build: ./migrations 159 | logging: 160 | <<: *logging 161 | depends_on: 162 | postgres: 163 | condition: service_healthy 164 | environment: 165 | POSTGRES_SERVER: *db_host 166 | POSTGRES_PORT: *db_port 167 | POSTGRES_DB: *db_name 168 | POSTGRES_USER: *db_user 169 | POSTGRES_PASSWORD: *db_password 170 | networks: 171 | - reportportal 172 | restart: on-failure 173 | profiles: 174 | - core 175 | - '' 176 | 177 | index: 178 | image: ${INDEX_IMAGE-reportportal/service-index:5.13.0} 179 | build: ./service-index 180 | logging: 181 | <<: *logging 182 | depends_on: 183 | gateway: 184 | condition: service_started 185 | environment: 186 | LB_URL: http://gateway:8081 187 | TRAEFIK_V2_MODE: 'true' 188 | healthcheck: 189 | test: wget -q --spider http://0.0.0.0:8080/health 190 | interval: 30s 191 | timeout: 30s 192 | retries: 10 193 | start_period: 10s 194 | labels: 195 | - 'traefik.http.routers.index.rule=PathPrefix(`/`)' 196 | - 'traefik.http.routers.index.service=index' 197 | - 'traefik.http.services.index.loadbalancer.server.port=8080' 198 | - 'traefik.http.services.index.loadbalancer.server.scheme=http' 199 | - 'traefik.expose=true' 200 | networks: 201 | - reportportal 202 | restart: always 203 | profiles: 204 | - core 205 | - '' 206 | 207 | ui: 208 | image: ${UI_IMAGE-reportportal/service-ui:5.12.3} 209 | build: ./service-ui 210 | environment: 211 | RP_SERVER_PORT: '8080' 212 | healthcheck: 213 | test: wget -q --spider http://0.0.0.0:8080/health 214 | interval: 30s 215 | timeout: 30s 216 | retries: 10 217 | start_period: 10s 218 | labels: 219 | - 'traefik.http.middlewares.ui-strip-prefix.stripprefix.prefixes=/ui' 220 | - 'traefik.http.routers.ui.middlewares=ui-strip-prefix@docker' 221 | - 'traefik.http.routers.ui.rule=PathPrefix(`/ui`)' 222 | - 'traefik.http.routers.ui.service=ui' 223 | - 'traefik.http.services.ui.loadbalancer.server.port=8080' 224 | - 'traefik.http.services.ui.loadbalancer.server.scheme=http' 225 | - 'traefik.expose=true' 226 | networks: 227 | - reportportal 228 | restart: always 229 | profiles: 230 | - core 231 | - '' 232 | 233 | api: 234 | image: ${API_IMAGE-reportportal/service-api:5.13.3} 235 | build: ./service-api 236 | logging: 237 | <<: *logging 238 | depends_on: 239 | rabbitmq: 240 | condition: service_healthy 241 | gateway: 242 | condition: service_started 243 | postgres: 244 | condition: service_healthy 245 | environment: 246 | <<: *common-environment 247 | LOGGING_LEVEL_ORG_HIBERNATE_SQL: info 248 | RP_REQUESTLOGGING: 'false' 249 | AUDIT_LOGGER: 'OFF' 250 | MANAGEMENT_HEALTH_ELASTICSEARCH_ENABLED: 'false' 251 | RP_ENVIRONMENT_VARIABLE_ALLOW_DELETE_ACCOUNT: 'false' 252 | JAVA_OPTS: > 253 | -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp 254 | -Dcom.sun.management.jmxremote.rmi.port=12349 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false 255 | -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate=false 256 | -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=0.0.0.0 257 | RP_JOBS_BASEURL: http://jobs:8686 258 | COM_TA_REPORTPORTAL_JOB_INTERRUPT_BROKEN_LAUNCHES_CRON: PT1H 259 | RP_ENVIRONMENT_VARIABLE_PATTERN-ANALYSIS_BATCH-SIZE: 100 260 | RP_ENVIRONMENT_VARIABLE_PATTERN-ANALYSIS_PREFETCH-COUNT: 1 261 | RP_ENVIRONMENT_VARIABLE_PATTERN-ANALYSIS_CONSUMERS-COUNT: 1 262 | COM_TA_REPORTPORTAL_JOB_LOAD_PLUGINS_CRON: PT10S 263 | COM_TA_REPORTPORTAL_JOB_CLEAN_OUTDATED_PLUGINS_CRON: PT10S 264 | REPORTING_QUEUES_COUNT: 10 265 | REPORTING_CONSUMER_PREFETCHCOUNT: 10 266 | REPORTING_PARKINGLOT_TTL_DAYS: 7 267 | volumes: 268 | - storage:/data/storage 269 | healthcheck: 270 | test: curl -f http://0.0.0.0:8585/health 271 | interval: 60s 272 | timeout: 30s 273 | retries: 10 274 | start_period: 60s 275 | labels: 276 | - 'traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api' 277 | - 'traefik.http.routers.api.middlewares=api-strip-prefix@docker' 278 | - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' 279 | - 'traefik.http.routers.api.service=api' 280 | - 'traefik.http.services.api.loadbalancer.server.port=8585' 281 | - 'traefik.http.services.api.loadbalancer.server.scheme=http' 282 | - 'traefik.expose=true' 283 | networks: 284 | - reportportal 285 | restart: always 286 | profiles: 287 | - core 288 | - '' 289 | 290 | uat: 291 | image: ${UAT_IMAGE-reportportal/service-authorization:5.13.1} 292 | build: ./service-authorization 293 | logging: 294 | <<: *logging 295 | environment: 296 | <<: *common-environment 297 | ## Session lifetime in seconds for regular sessions 298 | RP_SESSION_LIVE: 86400 299 | ## Session lifetime in seconds for SAML sessions 300 | RP_SAML_SESSION-LIVE: 4320 301 | ## Initial password for the superadmin user on the first launch. This value won't change the password on redeployments. 302 | RP_INITIAL_ADMIN_PASSWORD: ${RP_INITIAL_ADMIN_PASSWORD:-erebus} 303 | JAVA_OPTS: > 304 | -Djava.security.egd=file:/dev/./urandom -XX:MinRAMPercentage=60.0 -XX:MaxRAMPercentage=90.0 305 | --add-opens=java.base/java.lang=ALL-UNNAMED 306 | volumes: 307 | - storage:/data/storage 308 | healthcheck: 309 | test: curl -f http://0.0.0.0:9999/health 310 | interval: 60s 311 | timeout: 30s 312 | retries: 10 313 | start_period: 60s 314 | labels: 315 | - 'traefik.http.middlewares.uat-strip-prefix.stripprefix.prefixes=/uat' 316 | - 'traefik.http.routers.uat.middlewares=uat-strip-prefix@docker' 317 | - 'traefik.http.routers.uat.rule=PathPrefix(`/uat`)' 318 | - 'traefik.http.routers.uat.service=uat' 319 | - 'traefik.http.services.uat.loadbalancer.server.port=9999' 320 | - 'traefik.http.services.uat.loadbalancer.server.scheme=http' 321 | - 'traefik.expose=true' 322 | depends_on: 323 | postgres: 324 | condition: service_healthy 325 | networks: 326 | - reportportal 327 | restart: always 328 | profiles: 329 | - core 330 | - '' 331 | 332 | jobs: 333 | image: ${JOBS_IMAGE-reportportal/service-jobs:5.13.1} 334 | build: ./service-jobs 335 | logging: 336 | <<: *logging 337 | depends_on: 338 | rabbitmq: 339 | condition: service_healthy 340 | gateway: 341 | condition: service_started 342 | postgres: 343 | condition: service_healthy 344 | environment: 345 | <<: *common-environment 346 | RP_ENVIRONMENT_VARIABLE_CLEAN_ATTACHMENT_CRON: 0 0 */24 * * * 347 | RP_ENVIRONMENT_VARIABLE_CLEAN_LOG_CRON: 0 0 */24 * * * 348 | RP_ENVIRONMENT_VARIABLE_CLEAN_LAUNCH_CRON: 0 0 */24 * * * 349 | RP_ENVIRONMENT_VARIABLE_CLEAN_STORAGE_CRON: 0 0 */24 * * * 350 | RP_ENVIRONMENT_VARIABLE_STORAGE_PROJECT_CRON: 0 */5 * * * * 351 | RP_ENVIRONMENT_VARIABLE_CLEAN_EXPIREDUSER_CRON: 0 0 */24 * * * 352 | RP_ENVIRONMENT_VARIABLE_CLEAN_EXPIREDUSER_RETENTIONPERIOD: 365 353 | RP_ENVIRONMENT_VARIABLE_NOTIFICATION_EXPIREDUSER_CRON: 0 0 */24 * * * 354 | RP_ENVIRONMENT_VARIABLE_CLEAN_EVENTS_RETENTIONPERIOD: 365 355 | RP_ENVIRONMENT_VARIABLE_CLEAN_EVENTS_CRON: 0 30 05 * * * 356 | RP_ENVIRONMENT_VARIABLE_CLEAN_STORAGE_CHUNKSIZE: 20000 357 | RP_PROCESSING_LOG_MAXBATCHSIZE: 2000 358 | RP_PROCESSING_LOG_MAXBATCHTIMEOUT: 6000 359 | RP_AMQP_MAXLOGCONSUMER: 1 360 | JAVA_OPTS: > 361 | -Djava.security.egd=file:/dev/./urandom -XX:+UseG1GC -XX:+UseStringDeduplication -XX:G1ReservePercent=20 362 | -XX:InitiatingHeapOccupancyPercent=60 -XX:MaxRAMPercentage=70.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp 363 | volumes: 364 | - storage:/data/storage 365 | healthcheck: 366 | test: curl -f http://0.0.0.0:8686/health || exit 1 367 | interval: 60s 368 | timeout: 30s 369 | retries: 10 370 | start_period: 60s 371 | labels: 372 | - traefik.http.middlewares.jobs-strip-prefix.stripprefix.prefixes=/jobs 373 | - traefik.http.routers.jobs.middlewares=jobs-strip-prefix@docker 374 | - traefik.http.routers.jobs.rule=PathPrefix(`/jobs`) 375 | - traefik.http.routers.jobs.service=jobs 376 | - traefik.http.services.jobs.loadbalancer.server.port=8686 377 | - traefik.http.services.jobs.loadbalancer.server.scheme=http 378 | - traefik.expose=true 379 | networks: 380 | - reportportal 381 | restart: always 382 | profiles: 383 | - core 384 | - '' 385 | 386 | ## 387 | ## Analyzer stack 388 | ## You can commit the following services if you don't need the Analyzer stack 389 | analyzer: 390 | image: &analyzer_image ${ANALYZER_IMAGE-reportportal/service-auto-analyzer:5.13.1} 391 | build: &analyzer_build ./service-auto-analyzer 392 | logging: 393 | <<: *logging 394 | environment: 395 | <<: *common-analyzer-environment 396 | volumes: 397 | - storage:/backend/storage 398 | depends_on: 399 | opensearch: 400 | condition: service_started 401 | rabbitmq: 402 | condition: service_healthy 403 | networks: 404 | - reportportal 405 | restart: always 406 | profiles: 407 | - '' 408 | 409 | analyzer-train: 410 | image: *analyzer_image 411 | build: *analyzer_build 412 | logging: 413 | <<: *logging 414 | environment: 415 | <<: *common-analyzer-environment 416 | INSTANCE_TASK_TYPE: train 417 | UWSGI_WORKERS: 1 418 | volumes: 419 | - storage:/backend/storage 420 | depends_on: 421 | opensearch: 422 | condition: service_started 423 | rabbitmq: 424 | condition: service_healthy 425 | networks: 426 | - reportportal 427 | restart: always 428 | profiles: 429 | - '' 430 | 431 | metrics-gatherer: 432 | image: ${METRICS_GATHERER_IMAGE-reportportal/service-metrics-gatherer:5.13.0} 433 | build: ./service-metrics-gatherer 434 | logging: 435 | <<: *logging 436 | environment: 437 | <<: *common-analyzer-environment 438 | ES_HOST: http://opensearch:9200 439 | POSTGRES_USER: *db_user 440 | POSTGRES_PASSWORD: *db_password 441 | POSTGRES_DB: *db_name 442 | POSTGRES_HOST: *db_host 443 | POSTGRES_PORT: *db_port 444 | ALLOWED_START_TIME: '22:00' 445 | ALLOWED_END_TIME: '08:00' 446 | depends_on: 447 | opensearch: 448 | condition: service_started 449 | networks: 450 | - reportportal 451 | restart: always 452 | profiles: 453 | - '' 454 | 455 | ## Define named volumes for persistent storage 456 | volumes: 457 | opensearch: 458 | storage: 459 | postgres: 460 | 461 | ## Define custom network for ReportPortal services 462 | networks: 463 | reportportal: 464 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | networks: 4 | qa: 5 | 6 | services: 7 | # InfluxDB is a fast time-series database 8 | influxdb2: 9 | image: influxdb:2 10 | networks: 11 | - qa 12 | ports: 13 | - '8086:8086' 14 | environment: 15 | - DOCKER_INFLUXDB_INIT_MODE=setup 16 | - DOCKER_INFLUXDB_INIT_USERNAME=admin 17 | - DOCKER_INFLUXDB_INIT_PASSWORD=password 18 | - DOCKER_INFLUXDB_INIT_ORG=qa-test 19 | - DOCKER_INFLUXDB_INIT_BUCKET=QA 20 | volumes: 21 | - ./data:/var/lib/influxdb2 22 | - ./config:/etc/influxdb2 23 | -------------------------------------------------------------------------------- /e2e/init/global-setup.ts: -------------------------------------------------------------------------------- 1 | import { dbSingleton } from '@utilities/mongoclient' 2 | 3 | async function setup() { 4 | console.log('set up DB client instance ......') 5 | await dbSingleton.getClient() 6 | } 7 | export default setup 8 | -------------------------------------------------------------------------------- /e2e/init/global-teardown.ts: -------------------------------------------------------------------------------- 1 | import { dbSingleton } from '@utilities/mongoclient' 2 | 3 | async function teardown() { 4 | console.log('clean up ') 5 | await dbSingleton.closeConnection() 6 | } 7 | 8 | export default teardown 9 | -------------------------------------------------------------------------------- /e2e/tests/cart.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@utilities/fixture' 2 | 3 | test.describe('Cart item page validation', () => { 4 | let data: any 5 | test.beforeEach(async ({ readData, homePage }) => { 6 | data = readData.getFile() 7 | await homePage.launchApp(process.env.URL) 8 | await homePage.login(data['credentials']['username'], data['credentials']['password']) 9 | }) 10 | 11 | test('Add item and remove from cart', { tag: ['@cart'] }, async ({ prodInfo, prodCart }) => { 12 | await prodInfo.clickAnItem(data['product']) 13 | await prodCart.clickCart() 14 | await prodCart.removeItemCart() 15 | await prodCart.emptyCart() 16 | }) 17 | 18 | test('Place an order', { tag: ['@e2e'] }, async ({ prodInfo, prodCart, checkoutPage }) => { 19 | await prodInfo.clickAnItem(data['product']) 20 | await prodCart.clickCart() 21 | await checkoutPage.clickCheckout() 22 | await checkoutPage.enterAddress(data['address']['firstname'], data['address']['lastname'], data['address']['zipcode']) 23 | await checkoutPage.checkoutOverview() 24 | await checkoutPage.finishCheckout() 25 | await checkoutPage.orderCompletion() 26 | }) 27 | 28 | test('Check github hover link', { tag: '@git' }, async ({ page }) => { 29 | await page.goto('https://mrjohn5on.github.io/') 30 | const home = page.locator('.nav_menu_list').getByRole('link', { name: 'Home', exact: true }) 31 | await expect(home).toHaveCSS('color', 'rgb(255, 4, 4)') 32 | await home.hover({ force: true }) 33 | await expect(home).toHaveCSS('color', 'rgb(0, 0, 0)') 34 | }) 35 | 36 | const students: string[] = ['Vijay', 'Noel', 'Prakash'] 37 | students.forEach(stu => { 38 | test(`DB validation for ${stu}`, { tag: '@db' }, async ({ mongoclient }) => { 39 | //rest of your tests 40 | const json = await mongoclient.readStudent(stu) 41 | expect(json.first_name).toEqual(stu) 42 | expect(json.age).toBeGreaterThan(18) 43 | expect(json.last_name).not.toBeNull() 44 | }) 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /e2e/tests/home.spec.ts: -------------------------------------------------------------------------------- 1 | import { test } from '@utilities/fixture' 2 | 3 | test.describe('Application Basic Tests', () => { 4 | let data: any 5 | test.beforeAll(async ({ readData }, testInfo) => { 6 | const _testName: string = testInfo.title.split('_')[0] 7 | data = readData.getFile()['credentials'] 8 | }) 9 | 10 | test.beforeEach(async ({ homePage }) => { 11 | await homePage.launchApp(process.env.URL) 12 | await homePage.login(data['username'], data['password']) 13 | }) 14 | 15 | test( 16 | 'TC01_veirfy Jacket link clicked', 17 | { 18 | tag: ['@home'], 19 | }, 20 | async ({ homePage }) => { 21 | await homePage.clickJacket() 22 | }, 23 | ) 24 | 25 | test( 26 | 'TC02_Verify all items have cart or remove button', 27 | { 28 | tag: ['@home'], 29 | }, 30 | async ({ prodInfo }) => { 31 | await prodInfo.validateRemoveOrAddToCart() 32 | }, 33 | ) 34 | }) 35 | -------------------------------------------------------------------------------- /e2e/tests/pip.spec.ts: -------------------------------------------------------------------------------- 1 | import { test } from '@utilities/fixture' 2 | 3 | test.describe('Validate the app behaviour in Product information page', () => { 4 | let data: any 5 | test.beforeAll(async ({ readData }, testInfo) => { 6 | const _testName: string = testInfo.title.split('_')[0] 7 | data = readData.getFile()['credentials'] 8 | }) 9 | 10 | test.beforeEach(async ({ homePage }) => { 11 | await homePage.launchApp(process.env.URL) 12 | await homePage.login(data['username'], data['password']) 13 | }) 14 | 15 | test('validate all image have valid url', { tag: ['@plp'] }, async ({ prodInfo }) => { 16 | await prodInfo.validateAllHaveValidImages() 17 | }) 18 | 19 | test('validate all items have price', { tag: ['@plp'] }, async ({ prodInfo }) => { 20 | await prodInfo.validateAllItemsHavePrice() 21 | }) 22 | 23 | test('validate sorting fucntionality of PIP', { tag: ['@plp'] }, async ({ prodInfo }) => { 24 | await prodInfo.validateLowToHighPrice() 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslint from '@eslint/js' 2 | import tseslint from 'typescript-eslint' 3 | import ascii from 'eslint-plugin-ascii' 4 | import eslintPluginJsonc from 'eslint-plugin-jsonc' 5 | import unusedImports from 'eslint-plugin-unused-imports' 6 | import simpleImportSort from 'eslint-plugin-simple-import-sort' 7 | import tsParser from '@typescript-eslint/parser' 8 | import parser from 'jsonc-eslint-parser' 9 | 10 | export default tseslint.config( 11 | eslint.configs.recommended, 12 | ...eslintPluginJsonc.configs['flat/recommended-with-jsonc'], 13 | ...tseslint.configs.recommended, 14 | { 15 | ignores: [ 16 | '.vscode/', 17 | '.idea/', 18 | '.cloudbees/', 19 | '.github/', 20 | '.husky/', 21 | 'dist/', 22 | 'node_modules/', 23 | 'allure-results/', 24 | 'test-results/', 25 | '.prettierrc.json', 26 | 'eslint.config.mjs', 27 | 'tsconfig.json', 28 | 'package.json', 29 | 'package-lock.json', 30 | '.commitlintrc.cjs', 31 | ], 32 | }, 33 | { 34 | files: ['**/*.ts'], 35 | languageOptions: { 36 | parser: tsParser, 37 | ecmaVersion: 2020, 38 | sourceType: 'module', 39 | parserOptions: { 40 | project: './tsconfig.json', 41 | }, 42 | }, 43 | plugins: { 44 | ascii, 45 | 'unused-imports': unusedImports, 46 | 'simple-import-sort': simpleImportSort, 47 | }, 48 | 49 | rules: { 50 | 'ascii/valid-name': 'error', 51 | '@typescript-eslint/await-thenable': 'error', 52 | '@typescript-eslint/consistent-type-imports': [ 53 | 'error', 54 | { 55 | prefer: 'type-imports', 56 | fixStyle: 'inline-type-imports', 57 | disallowTypeAnnotations: false, 58 | }, 59 | ], 60 | '@typescript-eslint/no-import-type-side-effects': 'error', 61 | '@typescript-eslint/no-explicit-any': 'warn', 62 | '@typescript-eslint/no-this-alias': 'off', 63 | '@typescript-eslint/no-unused-vars': [ 64 | 'error', 65 | { 66 | argsIgnorePattern: '^_', 67 | varsIgnorePattern: '^_', 68 | caughtErrorsIgnorePattern: '^_', 69 | }, 70 | ], 71 | '@typescript-eslint/no-unnecessary-type-assertion': [ 72 | 'warn', 73 | { 74 | typesToIgnore: ['HTMLElement'], 75 | }, 76 | ], 77 | }, 78 | }, 79 | { 80 | files: ['**/*.json', '**/*.json5', '**/*.jsonc'], 81 | rules: { 82 | 'jsonc/auto': 'error', 83 | }, 84 | languageOptions: { 85 | parser, 86 | }, 87 | }, 88 | ) 89 | -------------------------------------------------------------------------------- /k8s-manifests/job.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | namespace: ui-test-job 5 | name: ui-test 6 | labels: 7 | app: playwright 8 | name: ui-jobs 9 | spec: 10 | ttlSecondsAfterFinished: 100 11 | # set backofflimit as 0, otherwise this job will keep on execute till the status as completed 12 | backoffLimit: 0 13 | template: 14 | metadata: 15 | name: ui-test-job 16 | spec: 17 | restartPolicy: Never 18 | containers: 19 | - name: sample-ui-test 20 | image: thanandock/playwright-ui-typescript:latest 21 | args: ['-c', 'npx playwright test'] 22 | volumeMounts: 23 | - name: storage 24 | mountPath: /app/playwright-report 25 | 26 | volumes: 27 | - name: storage 28 | persistentVolumeClaim: 29 | claimName: logs-persistent-vol-claim 30 | -------------------------------------------------------------------------------- /k8s-manifests/pv.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: logs-persistent-vol 5 | labels: 6 | type: local 7 | spec: 8 | storageClassName: manual 9 | capacity: 10 | storage: 256Mi 11 | volumeMode: Filesystem 12 | accessModes: 13 | - ReadWriteMany 14 | persistentVolumeReclaimPolicy: Retain 15 | hostPath: 16 | path: '/test/output/result' 17 | -------------------------------------------------------------------------------- /k8s-manifests/pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | namespace: ui-test-job 5 | name: logs-persistent-vol-claim 6 | spec: 7 | storageClassName: manual 8 | resources: 9 | requests: 10 | storage: 256Mi 11 | volumeMode: Filesystem 12 | accessModes: 13 | - ReadWriteMany 14 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "saucelab-playwright", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "saucelab-playwright", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@influxdata/influxdb-client": "^1.33.2", 13 | "bson": "^6.8.0", 14 | "dotenv": "^16.4.5", 15 | "js-yaml": "^4.1.0", 16 | "mongodb": "^6.8.0", 17 | "tsx": "^4.19.0" 18 | }, 19 | "devDependencies": { 20 | "@commitlint/cli": "^19.7.1", 21 | "@commitlint/config-conventional": "^19.7.1", 22 | "@eslint/js": "^9.1.1", 23 | "@playwright/test": "^1.43.1", 24 | "@types/js-yaml": "^4.0.9", 25 | "@types/node": "^20.12.7", 26 | "eslint": "^8.57.1", 27 | "eslint-plugin-ascii": "^2.0.0", 28 | "eslint-plugin-jsonc": "^2.19.1", 29 | "eslint-plugin-simple-import-sort": "^12.1.1", 30 | "eslint-plugin-unused-imports": "^4.1.4", 31 | "globals": "^15.1.0", 32 | "husky": "^9.1.7", 33 | "prettier": "^3.5.2", 34 | "typescript": "^5.4.5", 35 | "typescript-eslint": "^7.8.0" 36 | } 37 | }, 38 | "node_modules/@babel/code-frame": { 39 | "version": "7.26.2", 40 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", 41 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", 42 | "dev": true, 43 | "license": "MIT", 44 | "dependencies": { 45 | "@babel/helper-validator-identifier": "^7.25.9", 46 | "js-tokens": "^4.0.0", 47 | "picocolors": "^1.0.0" 48 | }, 49 | "engines": { 50 | "node": ">=6.9.0" 51 | } 52 | }, 53 | "node_modules/@babel/helper-validator-identifier": { 54 | "version": "7.25.9", 55 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 56 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 57 | "dev": true, 58 | "license": "MIT", 59 | "engines": { 60 | "node": ">=6.9.0" 61 | } 62 | }, 63 | "node_modules/@commitlint/cli": { 64 | "version": "19.7.1", 65 | "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.7.1.tgz", 66 | "integrity": "sha512-iObGjR1tE/PfDtDTEfd+tnRkB3/HJzpQqRTyofS2MPPkDn1mp3DBC8SoPDayokfAy+xKhF8+bwRCJO25Nea0YQ==", 67 | "dev": true, 68 | "license": "MIT", 69 | "dependencies": { 70 | "@commitlint/format": "^19.5.0", 71 | "@commitlint/lint": "^19.7.1", 72 | "@commitlint/load": "^19.6.1", 73 | "@commitlint/read": "^19.5.0", 74 | "@commitlint/types": "^19.5.0", 75 | "tinyexec": "^0.3.0", 76 | "yargs": "^17.0.0" 77 | }, 78 | "bin": { 79 | "commitlint": "cli.js" 80 | }, 81 | "engines": { 82 | "node": ">=v18" 83 | } 84 | }, 85 | "node_modules/@commitlint/config-conventional": { 86 | "version": "19.7.1", 87 | "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.7.1.tgz", 88 | "integrity": "sha512-fsEIF8zgiI/FIWSnykdQNj/0JE4av08MudLTyYHm4FlLWemKoQvPNUYU2M/3tktWcCEyq7aOkDDgtjrmgWFbvg==", 89 | "dev": true, 90 | "license": "MIT", 91 | "dependencies": { 92 | "@commitlint/types": "^19.5.0", 93 | "conventional-changelog-conventionalcommits": "^7.0.2" 94 | }, 95 | "engines": { 96 | "node": ">=v18" 97 | } 98 | }, 99 | "node_modules/@commitlint/config-validator": { 100 | "version": "19.5.0", 101 | "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.5.0.tgz", 102 | "integrity": "sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==", 103 | "dev": true, 104 | "license": "MIT", 105 | "dependencies": { 106 | "@commitlint/types": "^19.5.0", 107 | "ajv": "^8.11.0" 108 | }, 109 | "engines": { 110 | "node": ">=v18" 111 | } 112 | }, 113 | "node_modules/@commitlint/config-validator/node_modules/ajv": { 114 | "version": "8.17.1", 115 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", 116 | "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", 117 | "dev": true, 118 | "license": "MIT", 119 | "dependencies": { 120 | "fast-deep-equal": "^3.1.3", 121 | "fast-uri": "^3.0.1", 122 | "json-schema-traverse": "^1.0.0", 123 | "require-from-string": "^2.0.2" 124 | }, 125 | "funding": { 126 | "type": "github", 127 | "url": "https://github.com/sponsors/epoberezkin" 128 | } 129 | }, 130 | "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { 131 | "version": "1.0.0", 132 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 133 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 134 | "dev": true, 135 | "license": "MIT" 136 | }, 137 | "node_modules/@commitlint/ensure": { 138 | "version": "19.5.0", 139 | "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.5.0.tgz", 140 | "integrity": "sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==", 141 | "dev": true, 142 | "license": "MIT", 143 | "dependencies": { 144 | "@commitlint/types": "^19.5.0", 145 | "lodash.camelcase": "^4.3.0", 146 | "lodash.kebabcase": "^4.1.1", 147 | "lodash.snakecase": "^4.1.1", 148 | "lodash.startcase": "^4.4.0", 149 | "lodash.upperfirst": "^4.3.1" 150 | }, 151 | "engines": { 152 | "node": ">=v18" 153 | } 154 | }, 155 | "node_modules/@commitlint/execute-rule": { 156 | "version": "19.5.0", 157 | "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.5.0.tgz", 158 | "integrity": "sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==", 159 | "dev": true, 160 | "license": "MIT", 161 | "engines": { 162 | "node": ">=v18" 163 | } 164 | }, 165 | "node_modules/@commitlint/format": { 166 | "version": "19.5.0", 167 | "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.5.0.tgz", 168 | "integrity": "sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==", 169 | "dev": true, 170 | "license": "MIT", 171 | "dependencies": { 172 | "@commitlint/types": "^19.5.0", 173 | "chalk": "^5.3.0" 174 | }, 175 | "engines": { 176 | "node": ">=v18" 177 | } 178 | }, 179 | "node_modules/@commitlint/format/node_modules/chalk": { 180 | "version": "5.4.1", 181 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", 182 | "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", 183 | "dev": true, 184 | "license": "MIT", 185 | "engines": { 186 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 187 | }, 188 | "funding": { 189 | "url": "https://github.com/chalk/chalk?sponsor=1" 190 | } 191 | }, 192 | "node_modules/@commitlint/is-ignored": { 193 | "version": "19.7.1", 194 | "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.7.1.tgz", 195 | "integrity": "sha512-3IaOc6HVg2hAoGleRK3r9vL9zZ3XY0rf1RsUf6jdQLuaD46ZHnXBiOPTyQ004C4IvYjSWqJwlh0/u2P73aIE3g==", 196 | "dev": true, 197 | "license": "MIT", 198 | "dependencies": { 199 | "@commitlint/types": "^19.5.0", 200 | "semver": "^7.6.0" 201 | }, 202 | "engines": { 203 | "node": ">=v18" 204 | } 205 | }, 206 | "node_modules/@commitlint/lint": { 207 | "version": "19.7.1", 208 | "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.7.1.tgz", 209 | "integrity": "sha512-LhcPfVjcOcOZA7LEuBBeO00o3MeZa+tWrX9Xyl1r9PMd5FWsEoZI9IgnGqTKZ0lZt5pO3ZlstgnRyY1CJJc9Xg==", 210 | "dev": true, 211 | "license": "MIT", 212 | "dependencies": { 213 | "@commitlint/is-ignored": "^19.7.1", 214 | "@commitlint/parse": "^19.5.0", 215 | "@commitlint/rules": "^19.6.0", 216 | "@commitlint/types": "^19.5.0" 217 | }, 218 | "engines": { 219 | "node": ">=v18" 220 | } 221 | }, 222 | "node_modules/@commitlint/load": { 223 | "version": "19.6.1", 224 | "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.6.1.tgz", 225 | "integrity": "sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==", 226 | "dev": true, 227 | "license": "MIT", 228 | "dependencies": { 229 | "@commitlint/config-validator": "^19.5.0", 230 | "@commitlint/execute-rule": "^19.5.0", 231 | "@commitlint/resolve-extends": "^19.5.0", 232 | "@commitlint/types": "^19.5.0", 233 | "chalk": "^5.3.0", 234 | "cosmiconfig": "^9.0.0", 235 | "cosmiconfig-typescript-loader": "^6.1.0", 236 | "lodash.isplainobject": "^4.0.6", 237 | "lodash.merge": "^4.6.2", 238 | "lodash.uniq": "^4.5.0" 239 | }, 240 | "engines": { 241 | "node": ">=v18" 242 | } 243 | }, 244 | "node_modules/@commitlint/load/node_modules/chalk": { 245 | "version": "5.4.1", 246 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", 247 | "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", 248 | "dev": true, 249 | "license": "MIT", 250 | "engines": { 251 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 252 | }, 253 | "funding": { 254 | "url": "https://github.com/chalk/chalk?sponsor=1" 255 | } 256 | }, 257 | "node_modules/@commitlint/message": { 258 | "version": "19.5.0", 259 | "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.5.0.tgz", 260 | "integrity": "sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==", 261 | "dev": true, 262 | "license": "MIT", 263 | "engines": { 264 | "node": ">=v18" 265 | } 266 | }, 267 | "node_modules/@commitlint/parse": { 268 | "version": "19.5.0", 269 | "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.5.0.tgz", 270 | "integrity": "sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==", 271 | "dev": true, 272 | "license": "MIT", 273 | "dependencies": { 274 | "@commitlint/types": "^19.5.0", 275 | "conventional-changelog-angular": "^7.0.0", 276 | "conventional-commits-parser": "^5.0.0" 277 | }, 278 | "engines": { 279 | "node": ">=v18" 280 | } 281 | }, 282 | "node_modules/@commitlint/read": { 283 | "version": "19.5.0", 284 | "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.5.0.tgz", 285 | "integrity": "sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==", 286 | "dev": true, 287 | "license": "MIT", 288 | "dependencies": { 289 | "@commitlint/top-level": "^19.5.0", 290 | "@commitlint/types": "^19.5.0", 291 | "git-raw-commits": "^4.0.0", 292 | "minimist": "^1.2.8", 293 | "tinyexec": "^0.3.0" 294 | }, 295 | "engines": { 296 | "node": ">=v18" 297 | } 298 | }, 299 | "node_modules/@commitlint/resolve-extends": { 300 | "version": "19.5.0", 301 | "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.5.0.tgz", 302 | "integrity": "sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==", 303 | "dev": true, 304 | "license": "MIT", 305 | "dependencies": { 306 | "@commitlint/config-validator": "^19.5.0", 307 | "@commitlint/types": "^19.5.0", 308 | "global-directory": "^4.0.1", 309 | "import-meta-resolve": "^4.0.0", 310 | "lodash.mergewith": "^4.6.2", 311 | "resolve-from": "^5.0.0" 312 | }, 313 | "engines": { 314 | "node": ">=v18" 315 | } 316 | }, 317 | "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { 318 | "version": "5.0.0", 319 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 320 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 321 | "dev": true, 322 | "license": "MIT", 323 | "engines": { 324 | "node": ">=8" 325 | } 326 | }, 327 | "node_modules/@commitlint/rules": { 328 | "version": "19.6.0", 329 | "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.6.0.tgz", 330 | "integrity": "sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==", 331 | "dev": true, 332 | "license": "MIT", 333 | "dependencies": { 334 | "@commitlint/ensure": "^19.5.0", 335 | "@commitlint/message": "^19.5.0", 336 | "@commitlint/to-lines": "^19.5.0", 337 | "@commitlint/types": "^19.5.0" 338 | }, 339 | "engines": { 340 | "node": ">=v18" 341 | } 342 | }, 343 | "node_modules/@commitlint/to-lines": { 344 | "version": "19.5.0", 345 | "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.5.0.tgz", 346 | "integrity": "sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==", 347 | "dev": true, 348 | "license": "MIT", 349 | "engines": { 350 | "node": ">=v18" 351 | } 352 | }, 353 | "node_modules/@commitlint/top-level": { 354 | "version": "19.5.0", 355 | "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.5.0.tgz", 356 | "integrity": "sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==", 357 | "dev": true, 358 | "license": "MIT", 359 | "dependencies": { 360 | "find-up": "^7.0.0" 361 | }, 362 | "engines": { 363 | "node": ">=v18" 364 | } 365 | }, 366 | "node_modules/@commitlint/top-level/node_modules/find-up": { 367 | "version": "7.0.0", 368 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", 369 | "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", 370 | "dev": true, 371 | "license": "MIT", 372 | "dependencies": { 373 | "locate-path": "^7.2.0", 374 | "path-exists": "^5.0.0", 375 | "unicorn-magic": "^0.1.0" 376 | }, 377 | "engines": { 378 | "node": ">=18" 379 | }, 380 | "funding": { 381 | "url": "https://github.com/sponsors/sindresorhus" 382 | } 383 | }, 384 | "node_modules/@commitlint/top-level/node_modules/locate-path": { 385 | "version": "7.2.0", 386 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", 387 | "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", 388 | "dev": true, 389 | "license": "MIT", 390 | "dependencies": { 391 | "p-locate": "^6.0.0" 392 | }, 393 | "engines": { 394 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 395 | }, 396 | "funding": { 397 | "url": "https://github.com/sponsors/sindresorhus" 398 | } 399 | }, 400 | "node_modules/@commitlint/top-level/node_modules/p-limit": { 401 | "version": "4.0.0", 402 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", 403 | "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", 404 | "dev": true, 405 | "license": "MIT", 406 | "dependencies": { 407 | "yocto-queue": "^1.0.0" 408 | }, 409 | "engines": { 410 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 411 | }, 412 | "funding": { 413 | "url": "https://github.com/sponsors/sindresorhus" 414 | } 415 | }, 416 | "node_modules/@commitlint/top-level/node_modules/p-locate": { 417 | "version": "6.0.0", 418 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", 419 | "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", 420 | "dev": true, 421 | "license": "MIT", 422 | "dependencies": { 423 | "p-limit": "^4.0.0" 424 | }, 425 | "engines": { 426 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 427 | }, 428 | "funding": { 429 | "url": "https://github.com/sponsors/sindresorhus" 430 | } 431 | }, 432 | "node_modules/@commitlint/top-level/node_modules/path-exists": { 433 | "version": "5.0.0", 434 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", 435 | "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", 436 | "dev": true, 437 | "license": "MIT", 438 | "engines": { 439 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 440 | } 441 | }, 442 | "node_modules/@commitlint/top-level/node_modules/yocto-queue": { 443 | "version": "1.1.1", 444 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", 445 | "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", 446 | "dev": true, 447 | "license": "MIT", 448 | "engines": { 449 | "node": ">=12.20" 450 | }, 451 | "funding": { 452 | "url": "https://github.com/sponsors/sindresorhus" 453 | } 454 | }, 455 | "node_modules/@commitlint/types": { 456 | "version": "19.5.0", 457 | "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.5.0.tgz", 458 | "integrity": "sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==", 459 | "dev": true, 460 | "license": "MIT", 461 | "dependencies": { 462 | "@types/conventional-commits-parser": "^5.0.0", 463 | "chalk": "^5.3.0" 464 | }, 465 | "engines": { 466 | "node": ">=v18" 467 | } 468 | }, 469 | "node_modules/@commitlint/types/node_modules/chalk": { 470 | "version": "5.4.1", 471 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", 472 | "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", 473 | "dev": true, 474 | "license": "MIT", 475 | "engines": { 476 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 477 | }, 478 | "funding": { 479 | "url": "https://github.com/chalk/chalk?sponsor=1" 480 | } 481 | }, 482 | "node_modules/@esbuild/aix-ppc64": { 483 | "version": "0.23.1", 484 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", 485 | "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", 486 | "cpu": [ 487 | "ppc64" 488 | ], 489 | "license": "MIT", 490 | "optional": true, 491 | "os": [ 492 | "aix" 493 | ], 494 | "engines": { 495 | "node": ">=18" 496 | } 497 | }, 498 | "node_modules/@esbuild/android-arm": { 499 | "version": "0.23.1", 500 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", 501 | "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", 502 | "cpu": [ 503 | "arm" 504 | ], 505 | "license": "MIT", 506 | "optional": true, 507 | "os": [ 508 | "android" 509 | ], 510 | "engines": { 511 | "node": ">=18" 512 | } 513 | }, 514 | "node_modules/@esbuild/android-arm64": { 515 | "version": "0.23.1", 516 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", 517 | "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", 518 | "cpu": [ 519 | "arm64" 520 | ], 521 | "license": "MIT", 522 | "optional": true, 523 | "os": [ 524 | "android" 525 | ], 526 | "engines": { 527 | "node": ">=18" 528 | } 529 | }, 530 | "node_modules/@esbuild/android-x64": { 531 | "version": "0.23.1", 532 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", 533 | "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", 534 | "cpu": [ 535 | "x64" 536 | ], 537 | "license": "MIT", 538 | "optional": true, 539 | "os": [ 540 | "android" 541 | ], 542 | "engines": { 543 | "node": ">=18" 544 | } 545 | }, 546 | "node_modules/@esbuild/darwin-arm64": { 547 | "version": "0.23.1", 548 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", 549 | "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", 550 | "cpu": [ 551 | "arm64" 552 | ], 553 | "license": "MIT", 554 | "optional": true, 555 | "os": [ 556 | "darwin" 557 | ], 558 | "engines": { 559 | "node": ">=18" 560 | } 561 | }, 562 | "node_modules/@esbuild/darwin-x64": { 563 | "version": "0.23.1", 564 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", 565 | "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", 566 | "cpu": [ 567 | "x64" 568 | ], 569 | "license": "MIT", 570 | "optional": true, 571 | "os": [ 572 | "darwin" 573 | ], 574 | "engines": { 575 | "node": ">=18" 576 | } 577 | }, 578 | "node_modules/@esbuild/freebsd-arm64": { 579 | "version": "0.23.1", 580 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", 581 | "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", 582 | "cpu": [ 583 | "arm64" 584 | ], 585 | "license": "MIT", 586 | "optional": true, 587 | "os": [ 588 | "freebsd" 589 | ], 590 | "engines": { 591 | "node": ">=18" 592 | } 593 | }, 594 | "node_modules/@esbuild/freebsd-x64": { 595 | "version": "0.23.1", 596 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", 597 | "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", 598 | "cpu": [ 599 | "x64" 600 | ], 601 | "license": "MIT", 602 | "optional": true, 603 | "os": [ 604 | "freebsd" 605 | ], 606 | "engines": { 607 | "node": ">=18" 608 | } 609 | }, 610 | "node_modules/@esbuild/linux-arm": { 611 | "version": "0.23.1", 612 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", 613 | "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", 614 | "cpu": [ 615 | "arm" 616 | ], 617 | "license": "MIT", 618 | "optional": true, 619 | "os": [ 620 | "linux" 621 | ], 622 | "engines": { 623 | "node": ">=18" 624 | } 625 | }, 626 | "node_modules/@esbuild/linux-arm64": { 627 | "version": "0.23.1", 628 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", 629 | "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", 630 | "cpu": [ 631 | "arm64" 632 | ], 633 | "license": "MIT", 634 | "optional": true, 635 | "os": [ 636 | "linux" 637 | ], 638 | "engines": { 639 | "node": ">=18" 640 | } 641 | }, 642 | "node_modules/@esbuild/linux-ia32": { 643 | "version": "0.23.1", 644 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", 645 | "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", 646 | "cpu": [ 647 | "ia32" 648 | ], 649 | "license": "MIT", 650 | "optional": true, 651 | "os": [ 652 | "linux" 653 | ], 654 | "engines": { 655 | "node": ">=18" 656 | } 657 | }, 658 | "node_modules/@esbuild/linux-loong64": { 659 | "version": "0.23.1", 660 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", 661 | "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", 662 | "cpu": [ 663 | "loong64" 664 | ], 665 | "license": "MIT", 666 | "optional": true, 667 | "os": [ 668 | "linux" 669 | ], 670 | "engines": { 671 | "node": ">=18" 672 | } 673 | }, 674 | "node_modules/@esbuild/linux-mips64el": { 675 | "version": "0.23.1", 676 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", 677 | "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", 678 | "cpu": [ 679 | "mips64el" 680 | ], 681 | "license": "MIT", 682 | "optional": true, 683 | "os": [ 684 | "linux" 685 | ], 686 | "engines": { 687 | "node": ">=18" 688 | } 689 | }, 690 | "node_modules/@esbuild/linux-ppc64": { 691 | "version": "0.23.1", 692 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", 693 | "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", 694 | "cpu": [ 695 | "ppc64" 696 | ], 697 | "license": "MIT", 698 | "optional": true, 699 | "os": [ 700 | "linux" 701 | ], 702 | "engines": { 703 | "node": ">=18" 704 | } 705 | }, 706 | "node_modules/@esbuild/linux-riscv64": { 707 | "version": "0.23.1", 708 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", 709 | "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", 710 | "cpu": [ 711 | "riscv64" 712 | ], 713 | "license": "MIT", 714 | "optional": true, 715 | "os": [ 716 | "linux" 717 | ], 718 | "engines": { 719 | "node": ">=18" 720 | } 721 | }, 722 | "node_modules/@esbuild/linux-s390x": { 723 | "version": "0.23.1", 724 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", 725 | "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", 726 | "cpu": [ 727 | "s390x" 728 | ], 729 | "license": "MIT", 730 | "optional": true, 731 | "os": [ 732 | "linux" 733 | ], 734 | "engines": { 735 | "node": ">=18" 736 | } 737 | }, 738 | "node_modules/@esbuild/linux-x64": { 739 | "version": "0.23.1", 740 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", 741 | "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", 742 | "cpu": [ 743 | "x64" 744 | ], 745 | "license": "MIT", 746 | "optional": true, 747 | "os": [ 748 | "linux" 749 | ], 750 | "engines": { 751 | "node": ">=18" 752 | } 753 | }, 754 | "node_modules/@esbuild/netbsd-x64": { 755 | "version": "0.23.1", 756 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", 757 | "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", 758 | "cpu": [ 759 | "x64" 760 | ], 761 | "license": "MIT", 762 | "optional": true, 763 | "os": [ 764 | "netbsd" 765 | ], 766 | "engines": { 767 | "node": ">=18" 768 | } 769 | }, 770 | "node_modules/@esbuild/openbsd-arm64": { 771 | "version": "0.23.1", 772 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", 773 | "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", 774 | "cpu": [ 775 | "arm64" 776 | ], 777 | "license": "MIT", 778 | "optional": true, 779 | "os": [ 780 | "openbsd" 781 | ], 782 | "engines": { 783 | "node": ">=18" 784 | } 785 | }, 786 | "node_modules/@esbuild/openbsd-x64": { 787 | "version": "0.23.1", 788 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", 789 | "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", 790 | "cpu": [ 791 | "x64" 792 | ], 793 | "license": "MIT", 794 | "optional": true, 795 | "os": [ 796 | "openbsd" 797 | ], 798 | "engines": { 799 | "node": ">=18" 800 | } 801 | }, 802 | "node_modules/@esbuild/sunos-x64": { 803 | "version": "0.23.1", 804 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", 805 | "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", 806 | "cpu": [ 807 | "x64" 808 | ], 809 | "license": "MIT", 810 | "optional": true, 811 | "os": [ 812 | "sunos" 813 | ], 814 | "engines": { 815 | "node": ">=18" 816 | } 817 | }, 818 | "node_modules/@esbuild/win32-arm64": { 819 | "version": "0.23.1", 820 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", 821 | "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", 822 | "cpu": [ 823 | "arm64" 824 | ], 825 | "license": "MIT", 826 | "optional": true, 827 | "os": [ 828 | "win32" 829 | ], 830 | "engines": { 831 | "node": ">=18" 832 | } 833 | }, 834 | "node_modules/@esbuild/win32-ia32": { 835 | "version": "0.23.1", 836 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", 837 | "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", 838 | "cpu": [ 839 | "ia32" 840 | ], 841 | "license": "MIT", 842 | "optional": true, 843 | "os": [ 844 | "win32" 845 | ], 846 | "engines": { 847 | "node": ">=18" 848 | } 849 | }, 850 | "node_modules/@esbuild/win32-x64": { 851 | "version": "0.23.1", 852 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", 853 | "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", 854 | "cpu": [ 855 | "x64" 856 | ], 857 | "license": "MIT", 858 | "optional": true, 859 | "os": [ 860 | "win32" 861 | ], 862 | "engines": { 863 | "node": ">=18" 864 | } 865 | }, 866 | "node_modules/@eslint-community/eslint-utils": { 867 | "version": "4.4.0", 868 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 869 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 870 | "dev": true, 871 | "license": "MIT", 872 | "dependencies": { 873 | "eslint-visitor-keys": "^3.3.0" 874 | }, 875 | "engines": { 876 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 877 | }, 878 | "peerDependencies": { 879 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 880 | } 881 | }, 882 | "node_modules/@eslint-community/regexpp": { 883 | "version": "4.12.1", 884 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 885 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 886 | "dev": true, 887 | "license": "MIT", 888 | "engines": { 889 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 890 | } 891 | }, 892 | "node_modules/@eslint/eslintrc": { 893 | "version": "2.1.4", 894 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", 895 | "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", 896 | "dev": true, 897 | "license": "MIT", 898 | "dependencies": { 899 | "ajv": "^6.12.4", 900 | "debug": "^4.3.2", 901 | "espree": "^9.6.0", 902 | "globals": "^13.19.0", 903 | "ignore": "^5.2.0", 904 | "import-fresh": "^3.2.1", 905 | "js-yaml": "^4.1.0", 906 | "minimatch": "^3.1.2", 907 | "strip-json-comments": "^3.1.1" 908 | }, 909 | "engines": { 910 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 911 | }, 912 | "funding": { 913 | "url": "https://opencollective.com/eslint" 914 | } 915 | }, 916 | "node_modules/@eslint/eslintrc/node_modules/globals": { 917 | "version": "13.24.0", 918 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", 919 | "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", 920 | "dev": true, 921 | "license": "MIT", 922 | "dependencies": { 923 | "type-fest": "^0.20.2" 924 | }, 925 | "engines": { 926 | "node": ">=8" 927 | }, 928 | "funding": { 929 | "url": "https://github.com/sponsors/sindresorhus" 930 | } 931 | }, 932 | "node_modules/@eslint/js": { 933 | "version": "9.21.0", 934 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", 935 | "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", 936 | "dev": true, 937 | "license": "MIT", 938 | "engines": { 939 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 940 | } 941 | }, 942 | "node_modules/@humanwhocodes/config-array": { 943 | "version": "0.13.0", 944 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", 945 | "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", 946 | "deprecated": "Use @eslint/config-array instead", 947 | "dev": true, 948 | "license": "Apache-2.0", 949 | "dependencies": { 950 | "@humanwhocodes/object-schema": "^2.0.3", 951 | "debug": "^4.3.1", 952 | "minimatch": "^3.0.5" 953 | }, 954 | "engines": { 955 | "node": ">=10.10.0" 956 | } 957 | }, 958 | "node_modules/@humanwhocodes/module-importer": { 959 | "version": "1.0.1", 960 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 961 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 962 | "dev": true, 963 | "license": "Apache-2.0", 964 | "engines": { 965 | "node": ">=12.22" 966 | }, 967 | "funding": { 968 | "type": "github", 969 | "url": "https://github.com/sponsors/nzakas" 970 | } 971 | }, 972 | "node_modules/@humanwhocodes/object-schema": { 973 | "version": "2.0.3", 974 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", 975 | "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", 976 | "deprecated": "Use @eslint/object-schema instead", 977 | "dev": true, 978 | "license": "BSD-3-Clause" 979 | }, 980 | "node_modules/@influxdata/influxdb-client": { 981 | "version": "1.33.2", 982 | "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.33.2.tgz", 983 | "integrity": "sha512-RT5SxH+grHAazo/YK3UTuWK/frPWRM0N7vkrCUyqVprDgQzlLP+bSK4ak2Jv3QVF/pazTnsxWjvtKZdwskV5Xw==", 984 | "license": "MIT" 985 | }, 986 | "node_modules/@mongodb-js/saslprep": { 987 | "version": "1.1.8", 988 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", 989 | "integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==", 990 | "license": "MIT", 991 | "dependencies": { 992 | "sparse-bitfield": "^3.0.3" 993 | } 994 | }, 995 | "node_modules/@nodelib/fs.scandir": { 996 | "version": "2.1.5", 997 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 998 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 999 | "dev": true, 1000 | "license": "MIT", 1001 | "dependencies": { 1002 | "@nodelib/fs.stat": "2.0.5", 1003 | "run-parallel": "^1.1.9" 1004 | }, 1005 | "engines": { 1006 | "node": ">= 8" 1007 | } 1008 | }, 1009 | "node_modules/@nodelib/fs.stat": { 1010 | "version": "2.0.5", 1011 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 1012 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 1013 | "dev": true, 1014 | "license": "MIT", 1015 | "engines": { 1016 | "node": ">= 8" 1017 | } 1018 | }, 1019 | "node_modules/@nodelib/fs.walk": { 1020 | "version": "1.2.8", 1021 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 1022 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 1023 | "dev": true, 1024 | "license": "MIT", 1025 | "dependencies": { 1026 | "@nodelib/fs.scandir": "2.1.5", 1027 | "fastq": "^1.6.0" 1028 | }, 1029 | "engines": { 1030 | "node": ">= 8" 1031 | } 1032 | }, 1033 | "node_modules/@playwright/test": { 1034 | "version": "1.45.2", 1035 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz", 1036 | "integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==", 1037 | "dev": true, 1038 | "license": "Apache-2.0", 1039 | "dependencies": { 1040 | "playwright": "1.45.2" 1041 | }, 1042 | "bin": { 1043 | "playwright": "cli.js" 1044 | }, 1045 | "engines": { 1046 | "node": ">=18" 1047 | } 1048 | }, 1049 | "node_modules/@types/conventional-commits-parser": { 1050 | "version": "5.0.1", 1051 | "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz", 1052 | "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==", 1053 | "dev": true, 1054 | "license": "MIT", 1055 | "dependencies": { 1056 | "@types/node": "*" 1057 | } 1058 | }, 1059 | "node_modules/@types/js-yaml": { 1060 | "version": "4.0.9", 1061 | "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", 1062 | "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", 1063 | "dev": true, 1064 | "license": "MIT" 1065 | }, 1066 | "node_modules/@types/node": { 1067 | "version": "20.14.11", 1068 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", 1069 | "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", 1070 | "dev": true, 1071 | "license": "MIT", 1072 | "dependencies": { 1073 | "undici-types": "~5.26.4" 1074 | } 1075 | }, 1076 | "node_modules/@types/webidl-conversions": { 1077 | "version": "7.0.3", 1078 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 1079 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", 1080 | "license": "MIT" 1081 | }, 1082 | "node_modules/@types/whatwg-url": { 1083 | "version": "11.0.5", 1084 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", 1085 | "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", 1086 | "license": "MIT", 1087 | "dependencies": { 1088 | "@types/webidl-conversions": "*" 1089 | } 1090 | }, 1091 | "node_modules/@typescript-eslint/eslint-plugin": { 1092 | "version": "7.16.1", 1093 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", 1094 | "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", 1095 | "dev": true, 1096 | "license": "MIT", 1097 | "dependencies": { 1098 | "@eslint-community/regexpp": "^4.10.0", 1099 | "@typescript-eslint/scope-manager": "7.16.1", 1100 | "@typescript-eslint/type-utils": "7.16.1", 1101 | "@typescript-eslint/utils": "7.16.1", 1102 | "@typescript-eslint/visitor-keys": "7.16.1", 1103 | "graphemer": "^1.4.0", 1104 | "ignore": "^5.3.1", 1105 | "natural-compare": "^1.4.0", 1106 | "ts-api-utils": "^1.3.0" 1107 | }, 1108 | "engines": { 1109 | "node": "^18.18.0 || >=20.0.0" 1110 | }, 1111 | "funding": { 1112 | "type": "opencollective", 1113 | "url": "https://opencollective.com/typescript-eslint" 1114 | }, 1115 | "peerDependencies": { 1116 | "@typescript-eslint/parser": "^7.0.0", 1117 | "eslint": "^8.56.0" 1118 | }, 1119 | "peerDependenciesMeta": { 1120 | "typescript": { 1121 | "optional": true 1122 | } 1123 | } 1124 | }, 1125 | "node_modules/@typescript-eslint/parser": { 1126 | "version": "7.16.1", 1127 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", 1128 | "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", 1129 | "dev": true, 1130 | "license": "BSD-2-Clause", 1131 | "dependencies": { 1132 | "@typescript-eslint/scope-manager": "7.16.1", 1133 | "@typescript-eslint/types": "7.16.1", 1134 | "@typescript-eslint/typescript-estree": "7.16.1", 1135 | "@typescript-eslint/visitor-keys": "7.16.1", 1136 | "debug": "^4.3.4" 1137 | }, 1138 | "engines": { 1139 | "node": "^18.18.0 || >=20.0.0" 1140 | }, 1141 | "funding": { 1142 | "type": "opencollective", 1143 | "url": "https://opencollective.com/typescript-eslint" 1144 | }, 1145 | "peerDependencies": { 1146 | "eslint": "^8.56.0" 1147 | }, 1148 | "peerDependenciesMeta": { 1149 | "typescript": { 1150 | "optional": true 1151 | } 1152 | } 1153 | }, 1154 | "node_modules/@typescript-eslint/scope-manager": { 1155 | "version": "7.16.1", 1156 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", 1157 | "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", 1158 | "dev": true, 1159 | "license": "MIT", 1160 | "dependencies": { 1161 | "@typescript-eslint/types": "7.16.1", 1162 | "@typescript-eslint/visitor-keys": "7.16.1" 1163 | }, 1164 | "engines": { 1165 | "node": "^18.18.0 || >=20.0.0" 1166 | }, 1167 | "funding": { 1168 | "type": "opencollective", 1169 | "url": "https://opencollective.com/typescript-eslint" 1170 | } 1171 | }, 1172 | "node_modules/@typescript-eslint/type-utils": { 1173 | "version": "7.16.1", 1174 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", 1175 | "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", 1176 | "dev": true, 1177 | "license": "MIT", 1178 | "dependencies": { 1179 | "@typescript-eslint/typescript-estree": "7.16.1", 1180 | "@typescript-eslint/utils": "7.16.1", 1181 | "debug": "^4.3.4", 1182 | "ts-api-utils": "^1.3.0" 1183 | }, 1184 | "engines": { 1185 | "node": "^18.18.0 || >=20.0.0" 1186 | }, 1187 | "funding": { 1188 | "type": "opencollective", 1189 | "url": "https://opencollective.com/typescript-eslint" 1190 | }, 1191 | "peerDependencies": { 1192 | "eslint": "^8.56.0" 1193 | }, 1194 | "peerDependenciesMeta": { 1195 | "typescript": { 1196 | "optional": true 1197 | } 1198 | } 1199 | }, 1200 | "node_modules/@typescript-eslint/types": { 1201 | "version": "7.16.1", 1202 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", 1203 | "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", 1204 | "dev": true, 1205 | "license": "MIT", 1206 | "engines": { 1207 | "node": "^18.18.0 || >=20.0.0" 1208 | }, 1209 | "funding": { 1210 | "type": "opencollective", 1211 | "url": "https://opencollective.com/typescript-eslint" 1212 | } 1213 | }, 1214 | "node_modules/@typescript-eslint/typescript-estree": { 1215 | "version": "7.16.1", 1216 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", 1217 | "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", 1218 | "dev": true, 1219 | "license": "BSD-2-Clause", 1220 | "dependencies": { 1221 | "@typescript-eslint/types": "7.16.1", 1222 | "@typescript-eslint/visitor-keys": "7.16.1", 1223 | "debug": "^4.3.4", 1224 | "globby": "^11.1.0", 1225 | "is-glob": "^4.0.3", 1226 | "minimatch": "^9.0.4", 1227 | "semver": "^7.6.0", 1228 | "ts-api-utils": "^1.3.0" 1229 | }, 1230 | "engines": { 1231 | "node": "^18.18.0 || >=20.0.0" 1232 | }, 1233 | "funding": { 1234 | "type": "opencollective", 1235 | "url": "https://opencollective.com/typescript-eslint" 1236 | }, 1237 | "peerDependenciesMeta": { 1238 | "typescript": { 1239 | "optional": true 1240 | } 1241 | } 1242 | }, 1243 | "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 1244 | "version": "2.0.1", 1245 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1246 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1247 | "dev": true, 1248 | "license": "MIT", 1249 | "dependencies": { 1250 | "balanced-match": "^1.0.0" 1251 | } 1252 | }, 1253 | "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 1254 | "version": "9.0.5", 1255 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1256 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1257 | "dev": true, 1258 | "license": "ISC", 1259 | "dependencies": { 1260 | "brace-expansion": "^2.0.1" 1261 | }, 1262 | "engines": { 1263 | "node": ">=16 || 14 >=14.17" 1264 | }, 1265 | "funding": { 1266 | "url": "https://github.com/sponsors/isaacs" 1267 | } 1268 | }, 1269 | "node_modules/@typescript-eslint/utils": { 1270 | "version": "7.16.1", 1271 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", 1272 | "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", 1273 | "dev": true, 1274 | "license": "MIT", 1275 | "dependencies": { 1276 | "@eslint-community/eslint-utils": "^4.4.0", 1277 | "@typescript-eslint/scope-manager": "7.16.1", 1278 | "@typescript-eslint/types": "7.16.1", 1279 | "@typescript-eslint/typescript-estree": "7.16.1" 1280 | }, 1281 | "engines": { 1282 | "node": "^18.18.0 || >=20.0.0" 1283 | }, 1284 | "funding": { 1285 | "type": "opencollective", 1286 | "url": "https://opencollective.com/typescript-eslint" 1287 | }, 1288 | "peerDependencies": { 1289 | "eslint": "^8.56.0" 1290 | } 1291 | }, 1292 | "node_modules/@typescript-eslint/visitor-keys": { 1293 | "version": "7.16.1", 1294 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", 1295 | "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", 1296 | "dev": true, 1297 | "license": "MIT", 1298 | "dependencies": { 1299 | "@typescript-eslint/types": "7.16.1", 1300 | "eslint-visitor-keys": "^3.4.3" 1301 | }, 1302 | "engines": { 1303 | "node": "^18.18.0 || >=20.0.0" 1304 | }, 1305 | "funding": { 1306 | "type": "opencollective", 1307 | "url": "https://opencollective.com/typescript-eslint" 1308 | } 1309 | }, 1310 | "node_modules/@ungap/structured-clone": { 1311 | "version": "1.3.0", 1312 | "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", 1313 | "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", 1314 | "dev": true, 1315 | "license": "ISC" 1316 | }, 1317 | "node_modules/acorn": { 1318 | "version": "8.14.0", 1319 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 1320 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 1321 | "dev": true, 1322 | "license": "MIT", 1323 | "bin": { 1324 | "acorn": "bin/acorn" 1325 | }, 1326 | "engines": { 1327 | "node": ">=0.4.0" 1328 | } 1329 | }, 1330 | "node_modules/acorn-jsx": { 1331 | "version": "5.3.2", 1332 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 1333 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 1334 | "dev": true, 1335 | "license": "MIT", 1336 | "peerDependencies": { 1337 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 1338 | } 1339 | }, 1340 | "node_modules/ajv": { 1341 | "version": "6.12.6", 1342 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1343 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1344 | "dev": true, 1345 | "license": "MIT", 1346 | "dependencies": { 1347 | "fast-deep-equal": "^3.1.1", 1348 | "fast-json-stable-stringify": "^2.0.0", 1349 | "json-schema-traverse": "^0.4.1", 1350 | "uri-js": "^4.2.2" 1351 | }, 1352 | "funding": { 1353 | "type": "github", 1354 | "url": "https://github.com/sponsors/epoberezkin" 1355 | } 1356 | }, 1357 | "node_modules/ansi-regex": { 1358 | "version": "5.0.1", 1359 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1360 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1361 | "dev": true, 1362 | "license": "MIT", 1363 | "engines": { 1364 | "node": ">=8" 1365 | } 1366 | }, 1367 | "node_modules/ansi-styles": { 1368 | "version": "4.3.0", 1369 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1370 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1371 | "dev": true, 1372 | "license": "MIT", 1373 | "dependencies": { 1374 | "color-convert": "^2.0.1" 1375 | }, 1376 | "engines": { 1377 | "node": ">=8" 1378 | }, 1379 | "funding": { 1380 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1381 | } 1382 | }, 1383 | "node_modules/argparse": { 1384 | "version": "2.0.1", 1385 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1386 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1387 | "license": "Python-2.0" 1388 | }, 1389 | "node_modules/array-ify": { 1390 | "version": "1.0.0", 1391 | "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", 1392 | "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", 1393 | "dev": true, 1394 | "license": "MIT" 1395 | }, 1396 | "node_modules/array-union": { 1397 | "version": "2.1.0", 1398 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 1399 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 1400 | "dev": true, 1401 | "license": "MIT", 1402 | "engines": { 1403 | "node": ">=8" 1404 | } 1405 | }, 1406 | "node_modules/balanced-match": { 1407 | "version": "1.0.2", 1408 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1409 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1410 | "dev": true, 1411 | "license": "MIT" 1412 | }, 1413 | "node_modules/brace-expansion": { 1414 | "version": "1.1.11", 1415 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1416 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1417 | "dev": true, 1418 | "license": "MIT", 1419 | "dependencies": { 1420 | "balanced-match": "^1.0.0", 1421 | "concat-map": "0.0.1" 1422 | } 1423 | }, 1424 | "node_modules/braces": { 1425 | "version": "3.0.3", 1426 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 1427 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 1428 | "dev": true, 1429 | "license": "MIT", 1430 | "dependencies": { 1431 | "fill-range": "^7.1.1" 1432 | }, 1433 | "engines": { 1434 | "node": ">=8" 1435 | } 1436 | }, 1437 | "node_modules/bson": { 1438 | "version": "6.8.0", 1439 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", 1440 | "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", 1441 | "license": "Apache-2.0", 1442 | "engines": { 1443 | "node": ">=16.20.1" 1444 | } 1445 | }, 1446 | "node_modules/callsites": { 1447 | "version": "3.1.0", 1448 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 1449 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1450 | "dev": true, 1451 | "license": "MIT", 1452 | "engines": { 1453 | "node": ">=6" 1454 | } 1455 | }, 1456 | "node_modules/chalk": { 1457 | "version": "4.1.2", 1458 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1459 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1460 | "dev": true, 1461 | "license": "MIT", 1462 | "dependencies": { 1463 | "ansi-styles": "^4.1.0", 1464 | "supports-color": "^7.1.0" 1465 | }, 1466 | "engines": { 1467 | "node": ">=10" 1468 | }, 1469 | "funding": { 1470 | "url": "https://github.com/chalk/chalk?sponsor=1" 1471 | } 1472 | }, 1473 | "node_modules/cliui": { 1474 | "version": "8.0.1", 1475 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 1476 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 1477 | "dev": true, 1478 | "license": "ISC", 1479 | "dependencies": { 1480 | "string-width": "^4.2.0", 1481 | "strip-ansi": "^6.0.1", 1482 | "wrap-ansi": "^7.0.0" 1483 | }, 1484 | "engines": { 1485 | "node": ">=12" 1486 | } 1487 | }, 1488 | "node_modules/color-convert": { 1489 | "version": "2.0.1", 1490 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1491 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1492 | "dev": true, 1493 | "license": "MIT", 1494 | "dependencies": { 1495 | "color-name": "~1.1.4" 1496 | }, 1497 | "engines": { 1498 | "node": ">=7.0.0" 1499 | } 1500 | }, 1501 | "node_modules/color-name": { 1502 | "version": "1.1.4", 1503 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1504 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1505 | "dev": true, 1506 | "license": "MIT" 1507 | }, 1508 | "node_modules/compare-func": { 1509 | "version": "2.0.0", 1510 | "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", 1511 | "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", 1512 | "dev": true, 1513 | "license": "MIT", 1514 | "dependencies": { 1515 | "array-ify": "^1.0.0", 1516 | "dot-prop": "^5.1.0" 1517 | } 1518 | }, 1519 | "node_modules/concat-map": { 1520 | "version": "0.0.1", 1521 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1522 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1523 | "dev": true, 1524 | "license": "MIT" 1525 | }, 1526 | "node_modules/conventional-changelog-angular": { 1527 | "version": "7.0.0", 1528 | "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", 1529 | "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", 1530 | "dev": true, 1531 | "license": "ISC", 1532 | "dependencies": { 1533 | "compare-func": "^2.0.0" 1534 | }, 1535 | "engines": { 1536 | "node": ">=16" 1537 | } 1538 | }, 1539 | "node_modules/conventional-changelog-conventionalcommits": { 1540 | "version": "7.0.2", 1541 | "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", 1542 | "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", 1543 | "dev": true, 1544 | "license": "ISC", 1545 | "dependencies": { 1546 | "compare-func": "^2.0.0" 1547 | }, 1548 | "engines": { 1549 | "node": ">=16" 1550 | } 1551 | }, 1552 | "node_modules/conventional-commits-parser": { 1553 | "version": "5.0.0", 1554 | "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", 1555 | "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", 1556 | "dev": true, 1557 | "license": "MIT", 1558 | "dependencies": { 1559 | "is-text-path": "^2.0.0", 1560 | "JSONStream": "^1.3.5", 1561 | "meow": "^12.0.1", 1562 | "split2": "^4.0.0" 1563 | }, 1564 | "bin": { 1565 | "conventional-commits-parser": "cli.mjs" 1566 | }, 1567 | "engines": { 1568 | "node": ">=16" 1569 | } 1570 | }, 1571 | "node_modules/cosmiconfig": { 1572 | "version": "9.0.0", 1573 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", 1574 | "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", 1575 | "dev": true, 1576 | "license": "MIT", 1577 | "dependencies": { 1578 | "env-paths": "^2.2.1", 1579 | "import-fresh": "^3.3.0", 1580 | "js-yaml": "^4.1.0", 1581 | "parse-json": "^5.2.0" 1582 | }, 1583 | "engines": { 1584 | "node": ">=14" 1585 | }, 1586 | "funding": { 1587 | "url": "https://github.com/sponsors/d-fischer" 1588 | }, 1589 | "peerDependencies": { 1590 | "typescript": ">=4.9.5" 1591 | }, 1592 | "peerDependenciesMeta": { 1593 | "typescript": { 1594 | "optional": true 1595 | } 1596 | } 1597 | }, 1598 | "node_modules/cosmiconfig-typescript-loader": { 1599 | "version": "6.1.0", 1600 | "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz", 1601 | "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==", 1602 | "dev": true, 1603 | "license": "MIT", 1604 | "dependencies": { 1605 | "jiti": "^2.4.1" 1606 | }, 1607 | "engines": { 1608 | "node": ">=v18" 1609 | }, 1610 | "peerDependencies": { 1611 | "@types/node": "*", 1612 | "cosmiconfig": ">=9", 1613 | "typescript": ">=5" 1614 | } 1615 | }, 1616 | "node_modules/cross-spawn": { 1617 | "version": "7.0.6", 1618 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 1619 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 1620 | "dev": true, 1621 | "license": "MIT", 1622 | "dependencies": { 1623 | "path-key": "^3.1.0", 1624 | "shebang-command": "^2.0.0", 1625 | "which": "^2.0.1" 1626 | }, 1627 | "engines": { 1628 | "node": ">= 8" 1629 | } 1630 | }, 1631 | "node_modules/dargs": { 1632 | "version": "8.1.0", 1633 | "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", 1634 | "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", 1635 | "dev": true, 1636 | "license": "MIT", 1637 | "engines": { 1638 | "node": ">=12" 1639 | }, 1640 | "funding": { 1641 | "url": "https://github.com/sponsors/sindresorhus" 1642 | } 1643 | }, 1644 | "node_modules/debug": { 1645 | "version": "4.3.5", 1646 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 1647 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 1648 | "dev": true, 1649 | "license": "MIT", 1650 | "dependencies": { 1651 | "ms": "2.1.2" 1652 | }, 1653 | "engines": { 1654 | "node": ">=6.0" 1655 | }, 1656 | "peerDependenciesMeta": { 1657 | "supports-color": { 1658 | "optional": true 1659 | } 1660 | } 1661 | }, 1662 | "node_modules/deep-is": { 1663 | "version": "0.1.4", 1664 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 1665 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 1666 | "dev": true, 1667 | "license": "MIT" 1668 | }, 1669 | "node_modules/dir-glob": { 1670 | "version": "3.0.1", 1671 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 1672 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 1673 | "dev": true, 1674 | "license": "MIT", 1675 | "dependencies": { 1676 | "path-type": "^4.0.0" 1677 | }, 1678 | "engines": { 1679 | "node": ">=8" 1680 | } 1681 | }, 1682 | "node_modules/doctrine": { 1683 | "version": "3.0.0", 1684 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 1685 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 1686 | "dev": true, 1687 | "license": "Apache-2.0", 1688 | "dependencies": { 1689 | "esutils": "^2.0.2" 1690 | }, 1691 | "engines": { 1692 | "node": ">=6.0.0" 1693 | } 1694 | }, 1695 | "node_modules/dot-prop": { 1696 | "version": "5.3.0", 1697 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", 1698 | "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", 1699 | "dev": true, 1700 | "license": "MIT", 1701 | "dependencies": { 1702 | "is-obj": "^2.0.0" 1703 | }, 1704 | "engines": { 1705 | "node": ">=8" 1706 | } 1707 | }, 1708 | "node_modules/dotenv": { 1709 | "version": "16.4.5", 1710 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", 1711 | "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", 1712 | "license": "BSD-2-Clause", 1713 | "engines": { 1714 | "node": ">=12" 1715 | }, 1716 | "funding": { 1717 | "url": "https://dotenvx.com" 1718 | } 1719 | }, 1720 | "node_modules/emoji-regex": { 1721 | "version": "8.0.0", 1722 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1723 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1724 | "dev": true, 1725 | "license": "MIT" 1726 | }, 1727 | "node_modules/env-paths": { 1728 | "version": "2.2.1", 1729 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", 1730 | "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", 1731 | "dev": true, 1732 | "license": "MIT", 1733 | "engines": { 1734 | "node": ">=6" 1735 | } 1736 | }, 1737 | "node_modules/error-ex": { 1738 | "version": "1.3.2", 1739 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 1740 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 1741 | "dev": true, 1742 | "license": "MIT", 1743 | "dependencies": { 1744 | "is-arrayish": "^0.2.1" 1745 | } 1746 | }, 1747 | "node_modules/esbuild": { 1748 | "version": "0.23.1", 1749 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", 1750 | "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", 1751 | "hasInstallScript": true, 1752 | "license": "MIT", 1753 | "bin": { 1754 | "esbuild": "bin/esbuild" 1755 | }, 1756 | "engines": { 1757 | "node": ">=18" 1758 | }, 1759 | "optionalDependencies": { 1760 | "@esbuild/aix-ppc64": "0.23.1", 1761 | "@esbuild/android-arm": "0.23.1", 1762 | "@esbuild/android-arm64": "0.23.1", 1763 | "@esbuild/android-x64": "0.23.1", 1764 | "@esbuild/darwin-arm64": "0.23.1", 1765 | "@esbuild/darwin-x64": "0.23.1", 1766 | "@esbuild/freebsd-arm64": "0.23.1", 1767 | "@esbuild/freebsd-x64": "0.23.1", 1768 | "@esbuild/linux-arm": "0.23.1", 1769 | "@esbuild/linux-arm64": "0.23.1", 1770 | "@esbuild/linux-ia32": "0.23.1", 1771 | "@esbuild/linux-loong64": "0.23.1", 1772 | "@esbuild/linux-mips64el": "0.23.1", 1773 | "@esbuild/linux-ppc64": "0.23.1", 1774 | "@esbuild/linux-riscv64": "0.23.1", 1775 | "@esbuild/linux-s390x": "0.23.1", 1776 | "@esbuild/linux-x64": "0.23.1", 1777 | "@esbuild/netbsd-x64": "0.23.1", 1778 | "@esbuild/openbsd-arm64": "0.23.1", 1779 | "@esbuild/openbsd-x64": "0.23.1", 1780 | "@esbuild/sunos-x64": "0.23.1", 1781 | "@esbuild/win32-arm64": "0.23.1", 1782 | "@esbuild/win32-ia32": "0.23.1", 1783 | "@esbuild/win32-x64": "0.23.1" 1784 | } 1785 | }, 1786 | "node_modules/escalade": { 1787 | "version": "3.2.0", 1788 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 1789 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1790 | "dev": true, 1791 | "license": "MIT", 1792 | "engines": { 1793 | "node": ">=6" 1794 | } 1795 | }, 1796 | "node_modules/escape-string-regexp": { 1797 | "version": "4.0.0", 1798 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1799 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1800 | "dev": true, 1801 | "license": "MIT", 1802 | "engines": { 1803 | "node": ">=10" 1804 | }, 1805 | "funding": { 1806 | "url": "https://github.com/sponsors/sindresorhus" 1807 | } 1808 | }, 1809 | "node_modules/eslint": { 1810 | "version": "8.57.1", 1811 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", 1812 | "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", 1813 | "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", 1814 | "dev": true, 1815 | "license": "MIT", 1816 | "dependencies": { 1817 | "@eslint-community/eslint-utils": "^4.2.0", 1818 | "@eslint-community/regexpp": "^4.6.1", 1819 | "@eslint/eslintrc": "^2.1.4", 1820 | "@eslint/js": "8.57.1", 1821 | "@humanwhocodes/config-array": "^0.13.0", 1822 | "@humanwhocodes/module-importer": "^1.0.1", 1823 | "@nodelib/fs.walk": "^1.2.8", 1824 | "@ungap/structured-clone": "^1.2.0", 1825 | "ajv": "^6.12.4", 1826 | "chalk": "^4.0.0", 1827 | "cross-spawn": "^7.0.2", 1828 | "debug": "^4.3.2", 1829 | "doctrine": "^3.0.0", 1830 | "escape-string-regexp": "^4.0.0", 1831 | "eslint-scope": "^7.2.2", 1832 | "eslint-visitor-keys": "^3.4.3", 1833 | "espree": "^9.6.1", 1834 | "esquery": "^1.4.2", 1835 | "esutils": "^2.0.2", 1836 | "fast-deep-equal": "^3.1.3", 1837 | "file-entry-cache": "^6.0.1", 1838 | "find-up": "^5.0.0", 1839 | "glob-parent": "^6.0.2", 1840 | "globals": "^13.19.0", 1841 | "graphemer": "^1.4.0", 1842 | "ignore": "^5.2.0", 1843 | "imurmurhash": "^0.1.4", 1844 | "is-glob": "^4.0.0", 1845 | "is-path-inside": "^3.0.3", 1846 | "js-yaml": "^4.1.0", 1847 | "json-stable-stringify-without-jsonify": "^1.0.1", 1848 | "levn": "^0.4.1", 1849 | "lodash.merge": "^4.6.2", 1850 | "minimatch": "^3.1.2", 1851 | "natural-compare": "^1.4.0", 1852 | "optionator": "^0.9.3", 1853 | "strip-ansi": "^6.0.1", 1854 | "text-table": "^0.2.0" 1855 | }, 1856 | "bin": { 1857 | "eslint": "bin/eslint.js" 1858 | }, 1859 | "engines": { 1860 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1861 | }, 1862 | "funding": { 1863 | "url": "https://opencollective.com/eslint" 1864 | } 1865 | }, 1866 | "node_modules/eslint-compat-utils": { 1867 | "version": "0.6.4", 1868 | "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.4.tgz", 1869 | "integrity": "sha512-/u+GQt8NMfXO8w17QendT4gvO5acfxQsAKirAt0LVxDnr2N8YLCVbregaNc/Yhp7NM128DwCaRvr8PLDfeNkQw==", 1870 | "dev": true, 1871 | "license": "MIT", 1872 | "dependencies": { 1873 | "semver": "^7.5.4" 1874 | }, 1875 | "engines": { 1876 | "node": ">=12" 1877 | }, 1878 | "peerDependencies": { 1879 | "eslint": ">=6.0.0" 1880 | } 1881 | }, 1882 | "node_modules/eslint-json-compat-utils": { 1883 | "version": "0.2.1", 1884 | "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", 1885 | "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", 1886 | "dev": true, 1887 | "license": "MIT", 1888 | "dependencies": { 1889 | "esquery": "^1.6.0" 1890 | }, 1891 | "engines": { 1892 | "node": ">=12" 1893 | }, 1894 | "peerDependencies": { 1895 | "eslint": "*", 1896 | "jsonc-eslint-parser": "^2.4.0" 1897 | }, 1898 | "peerDependenciesMeta": { 1899 | "@eslint/json": { 1900 | "optional": true 1901 | } 1902 | } 1903 | }, 1904 | "node_modules/eslint-plugin-ascii": { 1905 | "version": "2.0.0", 1906 | "resolved": "https://registry.npmjs.org/eslint-plugin-ascii/-/eslint-plugin-ascii-2.0.0.tgz", 1907 | "integrity": "sha512-hITZHSGWjot8R7iRuEBFRr7atPf2Rre31Kgwr2KryXGq1ah/KwpwtnhoX3uCo+xEE5SWDz2o85WfJ9fRdMCb/A==", 1908 | "dev": true, 1909 | "license": "MIT" 1910 | }, 1911 | "node_modules/eslint-plugin-jsonc": { 1912 | "version": "2.19.1", 1913 | "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.19.1.tgz", 1914 | "integrity": "sha512-MmlAOaZK1+Lg7YoCZPGRjb88ZjT+ct/KTsvcsbZdBm+w8WMzGx+XEmexk0m40P1WV9G2rFV7X3klyRGRpFXEjA==", 1915 | "dev": true, 1916 | "license": "MIT", 1917 | "dependencies": { 1918 | "@eslint-community/eslint-utils": "^4.2.0", 1919 | "eslint-compat-utils": "^0.6.0", 1920 | "eslint-json-compat-utils": "^0.2.1", 1921 | "espree": "^9.6.1", 1922 | "graphemer": "^1.4.0", 1923 | "jsonc-eslint-parser": "^2.0.4", 1924 | "natural-compare": "^1.4.0", 1925 | "synckit": "^0.6.0" 1926 | }, 1927 | "engines": { 1928 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1929 | }, 1930 | "funding": { 1931 | "url": "https://github.com/sponsors/ota-meshi" 1932 | }, 1933 | "peerDependencies": { 1934 | "eslint": ">=6.0.0" 1935 | } 1936 | }, 1937 | "node_modules/eslint-plugin-simple-import-sort": { 1938 | "version": "12.1.1", 1939 | "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", 1940 | "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", 1941 | "dev": true, 1942 | "license": "MIT", 1943 | "peerDependencies": { 1944 | "eslint": ">=5.0.0" 1945 | } 1946 | }, 1947 | "node_modules/eslint-plugin-unused-imports": { 1948 | "version": "4.1.4", 1949 | "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", 1950 | "integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==", 1951 | "dev": true, 1952 | "license": "MIT", 1953 | "peerDependencies": { 1954 | "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", 1955 | "eslint": "^9.0.0 || ^8.0.0" 1956 | }, 1957 | "peerDependenciesMeta": { 1958 | "@typescript-eslint/eslint-plugin": { 1959 | "optional": true 1960 | } 1961 | } 1962 | }, 1963 | "node_modules/eslint-scope": { 1964 | "version": "7.2.2", 1965 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", 1966 | "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", 1967 | "dev": true, 1968 | "license": "BSD-2-Clause", 1969 | "dependencies": { 1970 | "esrecurse": "^4.3.0", 1971 | "estraverse": "^5.2.0" 1972 | }, 1973 | "engines": { 1974 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1975 | }, 1976 | "funding": { 1977 | "url": "https://opencollective.com/eslint" 1978 | } 1979 | }, 1980 | "node_modules/eslint-visitor-keys": { 1981 | "version": "3.4.3", 1982 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 1983 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 1984 | "dev": true, 1985 | "license": "Apache-2.0", 1986 | "engines": { 1987 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1988 | }, 1989 | "funding": { 1990 | "url": "https://opencollective.com/eslint" 1991 | } 1992 | }, 1993 | "node_modules/eslint/node_modules/@eslint/js": { 1994 | "version": "8.57.1", 1995 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", 1996 | "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", 1997 | "dev": true, 1998 | "license": "MIT", 1999 | "engines": { 2000 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 2001 | } 2002 | }, 2003 | "node_modules/eslint/node_modules/globals": { 2004 | "version": "13.24.0", 2005 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", 2006 | "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", 2007 | "dev": true, 2008 | "license": "MIT", 2009 | "dependencies": { 2010 | "type-fest": "^0.20.2" 2011 | }, 2012 | "engines": { 2013 | "node": ">=8" 2014 | }, 2015 | "funding": { 2016 | "url": "https://github.com/sponsors/sindresorhus" 2017 | } 2018 | }, 2019 | "node_modules/espree": { 2020 | "version": "9.6.1", 2021 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", 2022 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", 2023 | "dev": true, 2024 | "license": "BSD-2-Clause", 2025 | "dependencies": { 2026 | "acorn": "^8.9.0", 2027 | "acorn-jsx": "^5.3.2", 2028 | "eslint-visitor-keys": "^3.4.1" 2029 | }, 2030 | "engines": { 2031 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 2032 | }, 2033 | "funding": { 2034 | "url": "https://opencollective.com/eslint" 2035 | } 2036 | }, 2037 | "node_modules/esquery": { 2038 | "version": "1.6.0", 2039 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 2040 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 2041 | "dev": true, 2042 | "license": "BSD-3-Clause", 2043 | "dependencies": { 2044 | "estraverse": "^5.1.0" 2045 | }, 2046 | "engines": { 2047 | "node": ">=0.10" 2048 | } 2049 | }, 2050 | "node_modules/esrecurse": { 2051 | "version": "4.3.0", 2052 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 2053 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 2054 | "dev": true, 2055 | "license": "BSD-2-Clause", 2056 | "dependencies": { 2057 | "estraverse": "^5.2.0" 2058 | }, 2059 | "engines": { 2060 | "node": ">=4.0" 2061 | } 2062 | }, 2063 | "node_modules/estraverse": { 2064 | "version": "5.3.0", 2065 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 2066 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 2067 | "dev": true, 2068 | "license": "BSD-2-Clause", 2069 | "engines": { 2070 | "node": ">=4.0" 2071 | } 2072 | }, 2073 | "node_modules/esutils": { 2074 | "version": "2.0.3", 2075 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 2076 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 2077 | "dev": true, 2078 | "license": "BSD-2-Clause", 2079 | "engines": { 2080 | "node": ">=0.10.0" 2081 | } 2082 | }, 2083 | "node_modules/fast-deep-equal": { 2084 | "version": "3.1.3", 2085 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 2086 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 2087 | "dev": true, 2088 | "license": "MIT" 2089 | }, 2090 | "node_modules/fast-glob": { 2091 | "version": "3.3.2", 2092 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 2093 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 2094 | "dev": true, 2095 | "license": "MIT", 2096 | "dependencies": { 2097 | "@nodelib/fs.stat": "^2.0.2", 2098 | "@nodelib/fs.walk": "^1.2.3", 2099 | "glob-parent": "^5.1.2", 2100 | "merge2": "^1.3.0", 2101 | "micromatch": "^4.0.4" 2102 | }, 2103 | "engines": { 2104 | "node": ">=8.6.0" 2105 | } 2106 | }, 2107 | "node_modules/fast-glob/node_modules/glob-parent": { 2108 | "version": "5.1.2", 2109 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 2110 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 2111 | "dev": true, 2112 | "license": "ISC", 2113 | "dependencies": { 2114 | "is-glob": "^4.0.1" 2115 | }, 2116 | "engines": { 2117 | "node": ">= 6" 2118 | } 2119 | }, 2120 | "node_modules/fast-json-stable-stringify": { 2121 | "version": "2.1.0", 2122 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 2123 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 2124 | "dev": true, 2125 | "license": "MIT" 2126 | }, 2127 | "node_modules/fast-levenshtein": { 2128 | "version": "2.0.6", 2129 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 2130 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 2131 | "dev": true, 2132 | "license": "MIT" 2133 | }, 2134 | "node_modules/fast-uri": { 2135 | "version": "3.0.6", 2136 | "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", 2137 | "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", 2138 | "dev": true, 2139 | "funding": [ 2140 | { 2141 | "type": "github", 2142 | "url": "https://github.com/sponsors/fastify" 2143 | }, 2144 | { 2145 | "type": "opencollective", 2146 | "url": "https://opencollective.com/fastify" 2147 | } 2148 | ], 2149 | "license": "BSD-3-Clause" 2150 | }, 2151 | "node_modules/fastq": { 2152 | "version": "1.17.1", 2153 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 2154 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 2155 | "dev": true, 2156 | "license": "ISC", 2157 | "dependencies": { 2158 | "reusify": "^1.0.4" 2159 | } 2160 | }, 2161 | "node_modules/file-entry-cache": { 2162 | "version": "6.0.1", 2163 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 2164 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 2165 | "dev": true, 2166 | "license": "MIT", 2167 | "dependencies": { 2168 | "flat-cache": "^3.0.4" 2169 | }, 2170 | "engines": { 2171 | "node": "^10.12.0 || >=12.0.0" 2172 | } 2173 | }, 2174 | "node_modules/fill-range": { 2175 | "version": "7.1.1", 2176 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 2177 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 2178 | "dev": true, 2179 | "license": "MIT", 2180 | "dependencies": { 2181 | "to-regex-range": "^5.0.1" 2182 | }, 2183 | "engines": { 2184 | "node": ">=8" 2185 | } 2186 | }, 2187 | "node_modules/find-up": { 2188 | "version": "5.0.0", 2189 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 2190 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 2191 | "dev": true, 2192 | "license": "MIT", 2193 | "dependencies": { 2194 | "locate-path": "^6.0.0", 2195 | "path-exists": "^4.0.0" 2196 | }, 2197 | "engines": { 2198 | "node": ">=10" 2199 | }, 2200 | "funding": { 2201 | "url": "https://github.com/sponsors/sindresorhus" 2202 | } 2203 | }, 2204 | "node_modules/flat-cache": { 2205 | "version": "3.2.0", 2206 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", 2207 | "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", 2208 | "dev": true, 2209 | "license": "MIT", 2210 | "dependencies": { 2211 | "flatted": "^3.2.9", 2212 | "keyv": "^4.5.3", 2213 | "rimraf": "^3.0.2" 2214 | }, 2215 | "engines": { 2216 | "node": "^10.12.0 || >=12.0.0" 2217 | } 2218 | }, 2219 | "node_modules/flatted": { 2220 | "version": "3.3.3", 2221 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 2222 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 2223 | "dev": true, 2224 | "license": "ISC" 2225 | }, 2226 | "node_modules/fs.realpath": { 2227 | "version": "1.0.0", 2228 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 2229 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 2230 | "dev": true, 2231 | "license": "ISC" 2232 | }, 2233 | "node_modules/fsevents": { 2234 | "version": "2.3.2", 2235 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 2236 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 2237 | "dev": true, 2238 | "hasInstallScript": true, 2239 | "license": "MIT", 2240 | "optional": true, 2241 | "os": [ 2242 | "darwin" 2243 | ], 2244 | "engines": { 2245 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 2246 | } 2247 | }, 2248 | "node_modules/get-caller-file": { 2249 | "version": "2.0.5", 2250 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 2251 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 2252 | "dev": true, 2253 | "license": "ISC", 2254 | "engines": { 2255 | "node": "6.* || 8.* || >= 10.*" 2256 | } 2257 | }, 2258 | "node_modules/get-tsconfig": { 2259 | "version": "4.8.0", 2260 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz", 2261 | "integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==", 2262 | "license": "MIT", 2263 | "dependencies": { 2264 | "resolve-pkg-maps": "^1.0.0" 2265 | }, 2266 | "funding": { 2267 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" 2268 | } 2269 | }, 2270 | "node_modules/git-raw-commits": { 2271 | "version": "4.0.0", 2272 | "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", 2273 | "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", 2274 | "dev": true, 2275 | "license": "MIT", 2276 | "dependencies": { 2277 | "dargs": "^8.0.0", 2278 | "meow": "^12.0.1", 2279 | "split2": "^4.0.0" 2280 | }, 2281 | "bin": { 2282 | "git-raw-commits": "cli.mjs" 2283 | }, 2284 | "engines": { 2285 | "node": ">=16" 2286 | } 2287 | }, 2288 | "node_modules/glob": { 2289 | "version": "7.2.3", 2290 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 2291 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 2292 | "deprecated": "Glob versions prior to v9 are no longer supported", 2293 | "dev": true, 2294 | "license": "ISC", 2295 | "dependencies": { 2296 | "fs.realpath": "^1.0.0", 2297 | "inflight": "^1.0.4", 2298 | "inherits": "2", 2299 | "minimatch": "^3.1.1", 2300 | "once": "^1.3.0", 2301 | "path-is-absolute": "^1.0.0" 2302 | }, 2303 | "engines": { 2304 | "node": "*" 2305 | }, 2306 | "funding": { 2307 | "url": "https://github.com/sponsors/isaacs" 2308 | } 2309 | }, 2310 | "node_modules/glob-parent": { 2311 | "version": "6.0.2", 2312 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 2313 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2314 | "dev": true, 2315 | "license": "ISC", 2316 | "dependencies": { 2317 | "is-glob": "^4.0.3" 2318 | }, 2319 | "engines": { 2320 | "node": ">=10.13.0" 2321 | } 2322 | }, 2323 | "node_modules/global-directory": { 2324 | "version": "4.0.1", 2325 | "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", 2326 | "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", 2327 | "dev": true, 2328 | "license": "MIT", 2329 | "dependencies": { 2330 | "ini": "4.1.1" 2331 | }, 2332 | "engines": { 2333 | "node": ">=18" 2334 | }, 2335 | "funding": { 2336 | "url": "https://github.com/sponsors/sindresorhus" 2337 | } 2338 | }, 2339 | "node_modules/globals": { 2340 | "version": "15.8.0", 2341 | "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", 2342 | "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", 2343 | "dev": true, 2344 | "license": "MIT", 2345 | "engines": { 2346 | "node": ">=18" 2347 | }, 2348 | "funding": { 2349 | "url": "https://github.com/sponsors/sindresorhus" 2350 | } 2351 | }, 2352 | "node_modules/globby": { 2353 | "version": "11.1.0", 2354 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 2355 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 2356 | "dev": true, 2357 | "license": "MIT", 2358 | "dependencies": { 2359 | "array-union": "^2.1.0", 2360 | "dir-glob": "^3.0.1", 2361 | "fast-glob": "^3.2.9", 2362 | "ignore": "^5.2.0", 2363 | "merge2": "^1.4.1", 2364 | "slash": "^3.0.0" 2365 | }, 2366 | "engines": { 2367 | "node": ">=10" 2368 | }, 2369 | "funding": { 2370 | "url": "https://github.com/sponsors/sindresorhus" 2371 | } 2372 | }, 2373 | "node_modules/graphemer": { 2374 | "version": "1.4.0", 2375 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 2376 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 2377 | "dev": true, 2378 | "license": "MIT" 2379 | }, 2380 | "node_modules/has-flag": { 2381 | "version": "4.0.0", 2382 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2383 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2384 | "dev": true, 2385 | "license": "MIT", 2386 | "engines": { 2387 | "node": ">=8" 2388 | } 2389 | }, 2390 | "node_modules/husky": { 2391 | "version": "9.1.7", 2392 | "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", 2393 | "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", 2394 | "dev": true, 2395 | "license": "MIT", 2396 | "bin": { 2397 | "husky": "bin.js" 2398 | }, 2399 | "engines": { 2400 | "node": ">=18" 2401 | }, 2402 | "funding": { 2403 | "url": "https://github.com/sponsors/typicode" 2404 | } 2405 | }, 2406 | "node_modules/ignore": { 2407 | "version": "5.3.1", 2408 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", 2409 | "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", 2410 | "dev": true, 2411 | "license": "MIT", 2412 | "engines": { 2413 | "node": ">= 4" 2414 | } 2415 | }, 2416 | "node_modules/import-fresh": { 2417 | "version": "3.3.1", 2418 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 2419 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 2420 | "dev": true, 2421 | "license": "MIT", 2422 | "dependencies": { 2423 | "parent-module": "^1.0.0", 2424 | "resolve-from": "^4.0.0" 2425 | }, 2426 | "engines": { 2427 | "node": ">=6" 2428 | }, 2429 | "funding": { 2430 | "url": "https://github.com/sponsors/sindresorhus" 2431 | } 2432 | }, 2433 | "node_modules/import-meta-resolve": { 2434 | "version": "4.1.0", 2435 | "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", 2436 | "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", 2437 | "dev": true, 2438 | "license": "MIT", 2439 | "funding": { 2440 | "type": "github", 2441 | "url": "https://github.com/sponsors/wooorm" 2442 | } 2443 | }, 2444 | "node_modules/imurmurhash": { 2445 | "version": "0.1.4", 2446 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 2447 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 2448 | "dev": true, 2449 | "license": "MIT", 2450 | "engines": { 2451 | "node": ">=0.8.19" 2452 | } 2453 | }, 2454 | "node_modules/inflight": { 2455 | "version": "1.0.6", 2456 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 2457 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 2458 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 2459 | "dev": true, 2460 | "license": "ISC", 2461 | "dependencies": { 2462 | "once": "^1.3.0", 2463 | "wrappy": "1" 2464 | } 2465 | }, 2466 | "node_modules/inherits": { 2467 | "version": "2.0.4", 2468 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 2469 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 2470 | "dev": true, 2471 | "license": "ISC" 2472 | }, 2473 | "node_modules/ini": { 2474 | "version": "4.1.1", 2475 | "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", 2476 | "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", 2477 | "dev": true, 2478 | "license": "ISC", 2479 | "engines": { 2480 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0" 2481 | } 2482 | }, 2483 | "node_modules/is-arrayish": { 2484 | "version": "0.2.1", 2485 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 2486 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", 2487 | "dev": true, 2488 | "license": "MIT" 2489 | }, 2490 | "node_modules/is-extglob": { 2491 | "version": "2.1.1", 2492 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 2493 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 2494 | "dev": true, 2495 | "license": "MIT", 2496 | "engines": { 2497 | "node": ">=0.10.0" 2498 | } 2499 | }, 2500 | "node_modules/is-fullwidth-code-point": { 2501 | "version": "3.0.0", 2502 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2503 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2504 | "dev": true, 2505 | "license": "MIT", 2506 | "engines": { 2507 | "node": ">=8" 2508 | } 2509 | }, 2510 | "node_modules/is-glob": { 2511 | "version": "4.0.3", 2512 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 2513 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2514 | "dev": true, 2515 | "license": "MIT", 2516 | "dependencies": { 2517 | "is-extglob": "^2.1.1" 2518 | }, 2519 | "engines": { 2520 | "node": ">=0.10.0" 2521 | } 2522 | }, 2523 | "node_modules/is-number": { 2524 | "version": "7.0.0", 2525 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 2526 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 2527 | "dev": true, 2528 | "license": "MIT", 2529 | "engines": { 2530 | "node": ">=0.12.0" 2531 | } 2532 | }, 2533 | "node_modules/is-obj": { 2534 | "version": "2.0.0", 2535 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", 2536 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", 2537 | "dev": true, 2538 | "license": "MIT", 2539 | "engines": { 2540 | "node": ">=8" 2541 | } 2542 | }, 2543 | "node_modules/is-path-inside": { 2544 | "version": "3.0.3", 2545 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 2546 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 2547 | "dev": true, 2548 | "license": "MIT", 2549 | "engines": { 2550 | "node": ">=8" 2551 | } 2552 | }, 2553 | "node_modules/is-text-path": { 2554 | "version": "2.0.0", 2555 | "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", 2556 | "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", 2557 | "dev": true, 2558 | "license": "MIT", 2559 | "dependencies": { 2560 | "text-extensions": "^2.0.0" 2561 | }, 2562 | "engines": { 2563 | "node": ">=8" 2564 | } 2565 | }, 2566 | "node_modules/isexe": { 2567 | "version": "2.0.0", 2568 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 2569 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 2570 | "dev": true, 2571 | "license": "ISC" 2572 | }, 2573 | "node_modules/jiti": { 2574 | "version": "2.4.2", 2575 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", 2576 | "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", 2577 | "dev": true, 2578 | "license": "MIT", 2579 | "bin": { 2580 | "jiti": "lib/jiti-cli.mjs" 2581 | } 2582 | }, 2583 | "node_modules/js-tokens": { 2584 | "version": "4.0.0", 2585 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 2586 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 2587 | "dev": true, 2588 | "license": "MIT" 2589 | }, 2590 | "node_modules/js-yaml": { 2591 | "version": "4.1.0", 2592 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2593 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2594 | "license": "MIT", 2595 | "dependencies": { 2596 | "argparse": "^2.0.1" 2597 | }, 2598 | "bin": { 2599 | "js-yaml": "bin/js-yaml.js" 2600 | } 2601 | }, 2602 | "node_modules/json-buffer": { 2603 | "version": "3.0.1", 2604 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 2605 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 2606 | "dev": true, 2607 | "license": "MIT" 2608 | }, 2609 | "node_modules/json-parse-even-better-errors": { 2610 | "version": "2.3.1", 2611 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", 2612 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", 2613 | "dev": true, 2614 | "license": "MIT" 2615 | }, 2616 | "node_modules/json-schema-traverse": { 2617 | "version": "0.4.1", 2618 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 2619 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 2620 | "dev": true, 2621 | "license": "MIT" 2622 | }, 2623 | "node_modules/json-stable-stringify-without-jsonify": { 2624 | "version": "1.0.1", 2625 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 2626 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 2627 | "dev": true, 2628 | "license": "MIT" 2629 | }, 2630 | "node_modules/jsonc-eslint-parser": { 2631 | "version": "2.4.0", 2632 | "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", 2633 | "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", 2634 | "dev": true, 2635 | "license": "MIT", 2636 | "dependencies": { 2637 | "acorn": "^8.5.0", 2638 | "eslint-visitor-keys": "^3.0.0", 2639 | "espree": "^9.0.0", 2640 | "semver": "^7.3.5" 2641 | }, 2642 | "engines": { 2643 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 2644 | }, 2645 | "funding": { 2646 | "url": "https://github.com/sponsors/ota-meshi" 2647 | } 2648 | }, 2649 | "node_modules/jsonparse": { 2650 | "version": "1.3.1", 2651 | "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", 2652 | "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", 2653 | "dev": true, 2654 | "engines": [ 2655 | "node >= 0.2.0" 2656 | ], 2657 | "license": "MIT" 2658 | }, 2659 | "node_modules/JSONStream": { 2660 | "version": "1.3.5", 2661 | "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", 2662 | "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", 2663 | "dev": true, 2664 | "license": "(MIT OR Apache-2.0)", 2665 | "dependencies": { 2666 | "jsonparse": "^1.2.0", 2667 | "through": ">=2.2.7 <3" 2668 | }, 2669 | "bin": { 2670 | "JSONStream": "bin.js" 2671 | }, 2672 | "engines": { 2673 | "node": "*" 2674 | } 2675 | }, 2676 | "node_modules/keyv": { 2677 | "version": "4.5.4", 2678 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 2679 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 2680 | "dev": true, 2681 | "license": "MIT", 2682 | "dependencies": { 2683 | "json-buffer": "3.0.1" 2684 | } 2685 | }, 2686 | "node_modules/levn": { 2687 | "version": "0.4.1", 2688 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 2689 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 2690 | "dev": true, 2691 | "license": "MIT", 2692 | "dependencies": { 2693 | "prelude-ls": "^1.2.1", 2694 | "type-check": "~0.4.0" 2695 | }, 2696 | "engines": { 2697 | "node": ">= 0.8.0" 2698 | } 2699 | }, 2700 | "node_modules/lines-and-columns": { 2701 | "version": "1.2.4", 2702 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 2703 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 2704 | "dev": true, 2705 | "license": "MIT" 2706 | }, 2707 | "node_modules/locate-path": { 2708 | "version": "6.0.0", 2709 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 2710 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 2711 | "dev": true, 2712 | "license": "MIT", 2713 | "dependencies": { 2714 | "p-locate": "^5.0.0" 2715 | }, 2716 | "engines": { 2717 | "node": ">=10" 2718 | }, 2719 | "funding": { 2720 | "url": "https://github.com/sponsors/sindresorhus" 2721 | } 2722 | }, 2723 | "node_modules/lodash.camelcase": { 2724 | "version": "4.3.0", 2725 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 2726 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", 2727 | "dev": true, 2728 | "license": "MIT" 2729 | }, 2730 | "node_modules/lodash.isplainobject": { 2731 | "version": "4.0.6", 2732 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 2733 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", 2734 | "dev": true, 2735 | "license": "MIT" 2736 | }, 2737 | "node_modules/lodash.kebabcase": { 2738 | "version": "4.1.1", 2739 | "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", 2740 | "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", 2741 | "dev": true, 2742 | "license": "MIT" 2743 | }, 2744 | "node_modules/lodash.merge": { 2745 | "version": "4.6.2", 2746 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 2747 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 2748 | "dev": true, 2749 | "license": "MIT" 2750 | }, 2751 | "node_modules/lodash.mergewith": { 2752 | "version": "4.6.2", 2753 | "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", 2754 | "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", 2755 | "dev": true, 2756 | "license": "MIT" 2757 | }, 2758 | "node_modules/lodash.snakecase": { 2759 | "version": "4.1.1", 2760 | "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", 2761 | "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", 2762 | "dev": true, 2763 | "license": "MIT" 2764 | }, 2765 | "node_modules/lodash.startcase": { 2766 | "version": "4.4.0", 2767 | "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", 2768 | "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", 2769 | "dev": true, 2770 | "license": "MIT" 2771 | }, 2772 | "node_modules/lodash.uniq": { 2773 | "version": "4.5.0", 2774 | "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", 2775 | "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", 2776 | "dev": true, 2777 | "license": "MIT" 2778 | }, 2779 | "node_modules/lodash.upperfirst": { 2780 | "version": "4.3.1", 2781 | "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", 2782 | "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", 2783 | "dev": true, 2784 | "license": "MIT" 2785 | }, 2786 | "node_modules/memory-pager": { 2787 | "version": "1.5.0", 2788 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 2789 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 2790 | "license": "MIT" 2791 | }, 2792 | "node_modules/meow": { 2793 | "version": "12.1.1", 2794 | "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", 2795 | "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", 2796 | "dev": true, 2797 | "license": "MIT", 2798 | "engines": { 2799 | "node": ">=16.10" 2800 | }, 2801 | "funding": { 2802 | "url": "https://github.com/sponsors/sindresorhus" 2803 | } 2804 | }, 2805 | "node_modules/merge2": { 2806 | "version": "1.4.1", 2807 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 2808 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 2809 | "dev": true, 2810 | "license": "MIT", 2811 | "engines": { 2812 | "node": ">= 8" 2813 | } 2814 | }, 2815 | "node_modules/micromatch": { 2816 | "version": "4.0.7", 2817 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", 2818 | "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", 2819 | "dev": true, 2820 | "license": "MIT", 2821 | "dependencies": { 2822 | "braces": "^3.0.3", 2823 | "picomatch": "^2.3.1" 2824 | }, 2825 | "engines": { 2826 | "node": ">=8.6" 2827 | } 2828 | }, 2829 | "node_modules/minimatch": { 2830 | "version": "3.1.2", 2831 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2832 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2833 | "dev": true, 2834 | "license": "ISC", 2835 | "dependencies": { 2836 | "brace-expansion": "^1.1.7" 2837 | }, 2838 | "engines": { 2839 | "node": "*" 2840 | } 2841 | }, 2842 | "node_modules/minimist": { 2843 | "version": "1.2.8", 2844 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 2845 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 2846 | "dev": true, 2847 | "license": "MIT", 2848 | "funding": { 2849 | "url": "https://github.com/sponsors/ljharb" 2850 | } 2851 | }, 2852 | "node_modules/mongodb": { 2853 | "version": "6.8.0", 2854 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz", 2855 | "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==", 2856 | "license": "Apache-2.0", 2857 | "dependencies": { 2858 | "@mongodb-js/saslprep": "^1.1.5", 2859 | "bson": "^6.7.0", 2860 | "mongodb-connection-string-url": "^3.0.0" 2861 | }, 2862 | "engines": { 2863 | "node": ">=16.20.1" 2864 | }, 2865 | "peerDependencies": { 2866 | "@aws-sdk/credential-providers": "^3.188.0", 2867 | "@mongodb-js/zstd": "^1.1.0", 2868 | "gcp-metadata": "^5.2.0", 2869 | "kerberos": "^2.0.1", 2870 | "mongodb-client-encryption": ">=6.0.0 <7", 2871 | "snappy": "^7.2.2", 2872 | "socks": "^2.7.1" 2873 | }, 2874 | "peerDependenciesMeta": { 2875 | "@aws-sdk/credential-providers": { 2876 | "optional": true 2877 | }, 2878 | "@mongodb-js/zstd": { 2879 | "optional": true 2880 | }, 2881 | "gcp-metadata": { 2882 | "optional": true 2883 | }, 2884 | "kerberos": { 2885 | "optional": true 2886 | }, 2887 | "mongodb-client-encryption": { 2888 | "optional": true 2889 | }, 2890 | "snappy": { 2891 | "optional": true 2892 | }, 2893 | "socks": { 2894 | "optional": true 2895 | } 2896 | } 2897 | }, 2898 | "node_modules/mongodb-connection-string-url": { 2899 | "version": "3.0.1", 2900 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", 2901 | "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", 2902 | "license": "Apache-2.0", 2903 | "dependencies": { 2904 | "@types/whatwg-url": "^11.0.2", 2905 | "whatwg-url": "^13.0.0" 2906 | } 2907 | }, 2908 | "node_modules/ms": { 2909 | "version": "2.1.2", 2910 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2911 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2912 | "dev": true, 2913 | "license": "MIT" 2914 | }, 2915 | "node_modules/natural-compare": { 2916 | "version": "1.4.0", 2917 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2918 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 2919 | "dev": true, 2920 | "license": "MIT" 2921 | }, 2922 | "node_modules/once": { 2923 | "version": "1.4.0", 2924 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2925 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 2926 | "dev": true, 2927 | "license": "ISC", 2928 | "dependencies": { 2929 | "wrappy": "1" 2930 | } 2931 | }, 2932 | "node_modules/optionator": { 2933 | "version": "0.9.4", 2934 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 2935 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 2936 | "dev": true, 2937 | "license": "MIT", 2938 | "dependencies": { 2939 | "deep-is": "^0.1.3", 2940 | "fast-levenshtein": "^2.0.6", 2941 | "levn": "^0.4.1", 2942 | "prelude-ls": "^1.2.1", 2943 | "type-check": "^0.4.0", 2944 | "word-wrap": "^1.2.5" 2945 | }, 2946 | "engines": { 2947 | "node": ">= 0.8.0" 2948 | } 2949 | }, 2950 | "node_modules/p-limit": { 2951 | "version": "3.1.0", 2952 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 2953 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 2954 | "dev": true, 2955 | "license": "MIT", 2956 | "dependencies": { 2957 | "yocto-queue": "^0.1.0" 2958 | }, 2959 | "engines": { 2960 | "node": ">=10" 2961 | }, 2962 | "funding": { 2963 | "url": "https://github.com/sponsors/sindresorhus" 2964 | } 2965 | }, 2966 | "node_modules/p-locate": { 2967 | "version": "5.0.0", 2968 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 2969 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 2970 | "dev": true, 2971 | "license": "MIT", 2972 | "dependencies": { 2973 | "p-limit": "^3.0.2" 2974 | }, 2975 | "engines": { 2976 | "node": ">=10" 2977 | }, 2978 | "funding": { 2979 | "url": "https://github.com/sponsors/sindresorhus" 2980 | } 2981 | }, 2982 | "node_modules/parent-module": { 2983 | "version": "1.0.1", 2984 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2985 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2986 | "dev": true, 2987 | "license": "MIT", 2988 | "dependencies": { 2989 | "callsites": "^3.0.0" 2990 | }, 2991 | "engines": { 2992 | "node": ">=6" 2993 | } 2994 | }, 2995 | "node_modules/parse-json": { 2996 | "version": "5.2.0", 2997 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", 2998 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", 2999 | "dev": true, 3000 | "license": "MIT", 3001 | "dependencies": { 3002 | "@babel/code-frame": "^7.0.0", 3003 | "error-ex": "^1.3.1", 3004 | "json-parse-even-better-errors": "^2.3.0", 3005 | "lines-and-columns": "^1.1.6" 3006 | }, 3007 | "engines": { 3008 | "node": ">=8" 3009 | }, 3010 | "funding": { 3011 | "url": "https://github.com/sponsors/sindresorhus" 3012 | } 3013 | }, 3014 | "node_modules/path-exists": { 3015 | "version": "4.0.0", 3016 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 3017 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 3018 | "dev": true, 3019 | "license": "MIT", 3020 | "engines": { 3021 | "node": ">=8" 3022 | } 3023 | }, 3024 | "node_modules/path-is-absolute": { 3025 | "version": "1.0.1", 3026 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 3027 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 3028 | "dev": true, 3029 | "license": "MIT", 3030 | "engines": { 3031 | "node": ">=0.10.0" 3032 | } 3033 | }, 3034 | "node_modules/path-key": { 3035 | "version": "3.1.1", 3036 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 3037 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 3038 | "dev": true, 3039 | "license": "MIT", 3040 | "engines": { 3041 | "node": ">=8" 3042 | } 3043 | }, 3044 | "node_modules/path-type": { 3045 | "version": "4.0.0", 3046 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 3047 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 3048 | "dev": true, 3049 | "license": "MIT", 3050 | "engines": { 3051 | "node": ">=8" 3052 | } 3053 | }, 3054 | "node_modules/picocolors": { 3055 | "version": "1.1.1", 3056 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 3057 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 3058 | "dev": true, 3059 | "license": "ISC" 3060 | }, 3061 | "node_modules/picomatch": { 3062 | "version": "2.3.1", 3063 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 3064 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 3065 | "dev": true, 3066 | "license": "MIT", 3067 | "engines": { 3068 | "node": ">=8.6" 3069 | }, 3070 | "funding": { 3071 | "url": "https://github.com/sponsors/jonschlinkert" 3072 | } 3073 | }, 3074 | "node_modules/playwright": { 3075 | "version": "1.45.2", 3076 | "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz", 3077 | "integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==", 3078 | "dev": true, 3079 | "license": "Apache-2.0", 3080 | "dependencies": { 3081 | "playwright-core": "1.45.2" 3082 | }, 3083 | "bin": { 3084 | "playwright": "cli.js" 3085 | }, 3086 | "engines": { 3087 | "node": ">=18" 3088 | }, 3089 | "optionalDependencies": { 3090 | "fsevents": "2.3.2" 3091 | } 3092 | }, 3093 | "node_modules/playwright-core": { 3094 | "version": "1.45.2", 3095 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz", 3096 | "integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==", 3097 | "dev": true, 3098 | "license": "Apache-2.0", 3099 | "bin": { 3100 | "playwright-core": "cli.js" 3101 | }, 3102 | "engines": { 3103 | "node": ">=18" 3104 | } 3105 | }, 3106 | "node_modules/prelude-ls": { 3107 | "version": "1.2.1", 3108 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 3109 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 3110 | "dev": true, 3111 | "license": "MIT", 3112 | "engines": { 3113 | "node": ">= 0.8.0" 3114 | } 3115 | }, 3116 | "node_modules/prettier": { 3117 | "version": "3.5.2", 3118 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", 3119 | "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", 3120 | "dev": true, 3121 | "license": "MIT", 3122 | "bin": { 3123 | "prettier": "bin/prettier.cjs" 3124 | }, 3125 | "engines": { 3126 | "node": ">=14" 3127 | }, 3128 | "funding": { 3129 | "url": "https://github.com/prettier/prettier?sponsor=1" 3130 | } 3131 | }, 3132 | "node_modules/punycode": { 3133 | "version": "2.3.1", 3134 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 3135 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 3136 | "license": "MIT", 3137 | "engines": { 3138 | "node": ">=6" 3139 | } 3140 | }, 3141 | "node_modules/queue-microtask": { 3142 | "version": "1.2.3", 3143 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 3144 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 3145 | "dev": true, 3146 | "funding": [ 3147 | { 3148 | "type": "github", 3149 | "url": "https://github.com/sponsors/feross" 3150 | }, 3151 | { 3152 | "type": "patreon", 3153 | "url": "https://www.patreon.com/feross" 3154 | }, 3155 | { 3156 | "type": "consulting", 3157 | "url": "https://feross.org/support" 3158 | } 3159 | ], 3160 | "license": "MIT" 3161 | }, 3162 | "node_modules/require-directory": { 3163 | "version": "2.1.1", 3164 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 3165 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 3166 | "dev": true, 3167 | "license": "MIT", 3168 | "engines": { 3169 | "node": ">=0.10.0" 3170 | } 3171 | }, 3172 | "node_modules/require-from-string": { 3173 | "version": "2.0.2", 3174 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 3175 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 3176 | "dev": true, 3177 | "license": "MIT", 3178 | "engines": { 3179 | "node": ">=0.10.0" 3180 | } 3181 | }, 3182 | "node_modules/resolve-from": { 3183 | "version": "4.0.0", 3184 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 3185 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 3186 | "dev": true, 3187 | "license": "MIT", 3188 | "engines": { 3189 | "node": ">=4" 3190 | } 3191 | }, 3192 | "node_modules/resolve-pkg-maps": { 3193 | "version": "1.0.0", 3194 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 3195 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 3196 | "license": "MIT", 3197 | "funding": { 3198 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 3199 | } 3200 | }, 3201 | "node_modules/reusify": { 3202 | "version": "1.0.4", 3203 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 3204 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 3205 | "dev": true, 3206 | "license": "MIT", 3207 | "engines": { 3208 | "iojs": ">=1.0.0", 3209 | "node": ">=0.10.0" 3210 | } 3211 | }, 3212 | "node_modules/rimraf": { 3213 | "version": "3.0.2", 3214 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 3215 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 3216 | "deprecated": "Rimraf versions prior to v4 are no longer supported", 3217 | "dev": true, 3218 | "license": "ISC", 3219 | "dependencies": { 3220 | "glob": "^7.1.3" 3221 | }, 3222 | "bin": { 3223 | "rimraf": "bin.js" 3224 | }, 3225 | "funding": { 3226 | "url": "https://github.com/sponsors/isaacs" 3227 | } 3228 | }, 3229 | "node_modules/run-parallel": { 3230 | "version": "1.2.0", 3231 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 3232 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 3233 | "dev": true, 3234 | "funding": [ 3235 | { 3236 | "type": "github", 3237 | "url": "https://github.com/sponsors/feross" 3238 | }, 3239 | { 3240 | "type": "patreon", 3241 | "url": "https://www.patreon.com/feross" 3242 | }, 3243 | { 3244 | "type": "consulting", 3245 | "url": "https://feross.org/support" 3246 | } 3247 | ], 3248 | "license": "MIT", 3249 | "dependencies": { 3250 | "queue-microtask": "^1.2.2" 3251 | } 3252 | }, 3253 | "node_modules/semver": { 3254 | "version": "7.6.3", 3255 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 3256 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 3257 | "dev": true, 3258 | "license": "ISC", 3259 | "bin": { 3260 | "semver": "bin/semver.js" 3261 | }, 3262 | "engines": { 3263 | "node": ">=10" 3264 | } 3265 | }, 3266 | "node_modules/shebang-command": { 3267 | "version": "2.0.0", 3268 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 3269 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 3270 | "dev": true, 3271 | "license": "MIT", 3272 | "dependencies": { 3273 | "shebang-regex": "^3.0.0" 3274 | }, 3275 | "engines": { 3276 | "node": ">=8" 3277 | } 3278 | }, 3279 | "node_modules/shebang-regex": { 3280 | "version": "3.0.0", 3281 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 3282 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 3283 | "dev": true, 3284 | "license": "MIT", 3285 | "engines": { 3286 | "node": ">=8" 3287 | } 3288 | }, 3289 | "node_modules/slash": { 3290 | "version": "3.0.0", 3291 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 3292 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 3293 | "dev": true, 3294 | "license": "MIT", 3295 | "engines": { 3296 | "node": ">=8" 3297 | } 3298 | }, 3299 | "node_modules/sparse-bitfield": { 3300 | "version": "3.0.3", 3301 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 3302 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 3303 | "license": "MIT", 3304 | "dependencies": { 3305 | "memory-pager": "^1.0.2" 3306 | } 3307 | }, 3308 | "node_modules/split2": { 3309 | "version": "4.2.0", 3310 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", 3311 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", 3312 | "dev": true, 3313 | "license": "ISC", 3314 | "engines": { 3315 | "node": ">= 10.x" 3316 | } 3317 | }, 3318 | "node_modules/string-width": { 3319 | "version": "4.2.3", 3320 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 3321 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 3322 | "dev": true, 3323 | "license": "MIT", 3324 | "dependencies": { 3325 | "emoji-regex": "^8.0.0", 3326 | "is-fullwidth-code-point": "^3.0.0", 3327 | "strip-ansi": "^6.0.1" 3328 | }, 3329 | "engines": { 3330 | "node": ">=8" 3331 | } 3332 | }, 3333 | "node_modules/strip-ansi": { 3334 | "version": "6.0.1", 3335 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 3336 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 3337 | "dev": true, 3338 | "license": "MIT", 3339 | "dependencies": { 3340 | "ansi-regex": "^5.0.1" 3341 | }, 3342 | "engines": { 3343 | "node": ">=8" 3344 | } 3345 | }, 3346 | "node_modules/strip-json-comments": { 3347 | "version": "3.1.1", 3348 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 3349 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 3350 | "dev": true, 3351 | "license": "MIT", 3352 | "engines": { 3353 | "node": ">=8" 3354 | }, 3355 | "funding": { 3356 | "url": "https://github.com/sponsors/sindresorhus" 3357 | } 3358 | }, 3359 | "node_modules/supports-color": { 3360 | "version": "7.2.0", 3361 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 3362 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 3363 | "dev": true, 3364 | "license": "MIT", 3365 | "dependencies": { 3366 | "has-flag": "^4.0.0" 3367 | }, 3368 | "engines": { 3369 | "node": ">=8" 3370 | } 3371 | }, 3372 | "node_modules/synckit": { 3373 | "version": "0.6.2", 3374 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", 3375 | "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", 3376 | "dev": true, 3377 | "license": "MIT", 3378 | "dependencies": { 3379 | "tslib": "^2.3.1" 3380 | }, 3381 | "engines": { 3382 | "node": ">=12.20" 3383 | } 3384 | }, 3385 | "node_modules/text-extensions": { 3386 | "version": "2.4.0", 3387 | "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", 3388 | "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", 3389 | "dev": true, 3390 | "license": "MIT", 3391 | "engines": { 3392 | "node": ">=8" 3393 | }, 3394 | "funding": { 3395 | "url": "https://github.com/sponsors/sindresorhus" 3396 | } 3397 | }, 3398 | "node_modules/text-table": { 3399 | "version": "0.2.0", 3400 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 3401 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 3402 | "dev": true, 3403 | "license": "MIT" 3404 | }, 3405 | "node_modules/through": { 3406 | "version": "2.3.8", 3407 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 3408 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", 3409 | "dev": true, 3410 | "license": "MIT" 3411 | }, 3412 | "node_modules/tinyexec": { 3413 | "version": "0.3.2", 3414 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", 3415 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", 3416 | "dev": true, 3417 | "license": "MIT" 3418 | }, 3419 | "node_modules/to-regex-range": { 3420 | "version": "5.0.1", 3421 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 3422 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 3423 | "dev": true, 3424 | "license": "MIT", 3425 | "dependencies": { 3426 | "is-number": "^7.0.0" 3427 | }, 3428 | "engines": { 3429 | "node": ">=8.0" 3430 | } 3431 | }, 3432 | "node_modules/tr46": { 3433 | "version": "4.1.1", 3434 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 3435 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 3436 | "license": "MIT", 3437 | "dependencies": { 3438 | "punycode": "^2.3.0" 3439 | }, 3440 | "engines": { 3441 | "node": ">=14" 3442 | } 3443 | }, 3444 | "node_modules/ts-api-utils": { 3445 | "version": "1.3.0", 3446 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", 3447 | "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", 3448 | "dev": true, 3449 | "license": "MIT", 3450 | "engines": { 3451 | "node": ">=16" 3452 | }, 3453 | "peerDependencies": { 3454 | "typescript": ">=4.2.0" 3455 | } 3456 | }, 3457 | "node_modules/tslib": { 3458 | "version": "2.8.1", 3459 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 3460 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 3461 | "dev": true, 3462 | "license": "0BSD" 3463 | }, 3464 | "node_modules/tsx": { 3465 | "version": "4.19.0", 3466 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", 3467 | "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", 3468 | "license": "MIT", 3469 | "dependencies": { 3470 | "esbuild": "~0.23.0", 3471 | "get-tsconfig": "^4.7.5" 3472 | }, 3473 | "bin": { 3474 | "tsx": "dist/cli.mjs" 3475 | }, 3476 | "engines": { 3477 | "node": ">=18.0.0" 3478 | }, 3479 | "optionalDependencies": { 3480 | "fsevents": "~2.3.3" 3481 | } 3482 | }, 3483 | "node_modules/tsx/node_modules/fsevents": { 3484 | "version": "2.3.3", 3485 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 3486 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 3487 | "hasInstallScript": true, 3488 | "license": "MIT", 3489 | "optional": true, 3490 | "os": [ 3491 | "darwin" 3492 | ], 3493 | "engines": { 3494 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 3495 | } 3496 | }, 3497 | "node_modules/type-check": { 3498 | "version": "0.4.0", 3499 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 3500 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 3501 | "dev": true, 3502 | "license": "MIT", 3503 | "dependencies": { 3504 | "prelude-ls": "^1.2.1" 3505 | }, 3506 | "engines": { 3507 | "node": ">= 0.8.0" 3508 | } 3509 | }, 3510 | "node_modules/type-fest": { 3511 | "version": "0.20.2", 3512 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 3513 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 3514 | "dev": true, 3515 | "license": "(MIT OR CC0-1.0)", 3516 | "engines": { 3517 | "node": ">=10" 3518 | }, 3519 | "funding": { 3520 | "url": "https://github.com/sponsors/sindresorhus" 3521 | } 3522 | }, 3523 | "node_modules/typescript": { 3524 | "version": "5.5.3", 3525 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", 3526 | "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", 3527 | "dev": true, 3528 | "license": "Apache-2.0", 3529 | "bin": { 3530 | "tsc": "bin/tsc", 3531 | "tsserver": "bin/tsserver" 3532 | }, 3533 | "engines": { 3534 | "node": ">=14.17" 3535 | } 3536 | }, 3537 | "node_modules/typescript-eslint": { 3538 | "version": "7.16.1", 3539 | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", 3540 | "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", 3541 | "dev": true, 3542 | "license": "MIT", 3543 | "dependencies": { 3544 | "@typescript-eslint/eslint-plugin": "7.16.1", 3545 | "@typescript-eslint/parser": "7.16.1", 3546 | "@typescript-eslint/utils": "7.16.1" 3547 | }, 3548 | "engines": { 3549 | "node": "^18.18.0 || >=20.0.0" 3550 | }, 3551 | "funding": { 3552 | "type": "opencollective", 3553 | "url": "https://opencollective.com/typescript-eslint" 3554 | }, 3555 | "peerDependencies": { 3556 | "eslint": "^8.56.0" 3557 | }, 3558 | "peerDependenciesMeta": { 3559 | "typescript": { 3560 | "optional": true 3561 | } 3562 | } 3563 | }, 3564 | "node_modules/undici-types": { 3565 | "version": "5.26.5", 3566 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 3567 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 3568 | "dev": true, 3569 | "license": "MIT" 3570 | }, 3571 | "node_modules/unicorn-magic": { 3572 | "version": "0.1.0", 3573 | "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", 3574 | "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", 3575 | "dev": true, 3576 | "license": "MIT", 3577 | "engines": { 3578 | "node": ">=18" 3579 | }, 3580 | "funding": { 3581 | "url": "https://github.com/sponsors/sindresorhus" 3582 | } 3583 | }, 3584 | "node_modules/uri-js": { 3585 | "version": "4.4.1", 3586 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 3587 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 3588 | "dev": true, 3589 | "license": "BSD-2-Clause", 3590 | "dependencies": { 3591 | "punycode": "^2.1.0" 3592 | } 3593 | }, 3594 | "node_modules/webidl-conversions": { 3595 | "version": "7.0.0", 3596 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 3597 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 3598 | "license": "BSD-2-Clause", 3599 | "engines": { 3600 | "node": ">=12" 3601 | } 3602 | }, 3603 | "node_modules/whatwg-url": { 3604 | "version": "13.0.0", 3605 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 3606 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 3607 | "license": "MIT", 3608 | "dependencies": { 3609 | "tr46": "^4.1.1", 3610 | "webidl-conversions": "^7.0.0" 3611 | }, 3612 | "engines": { 3613 | "node": ">=16" 3614 | } 3615 | }, 3616 | "node_modules/which": { 3617 | "version": "2.0.2", 3618 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 3619 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 3620 | "dev": true, 3621 | "license": "ISC", 3622 | "dependencies": { 3623 | "isexe": "^2.0.0" 3624 | }, 3625 | "bin": { 3626 | "node-which": "bin/node-which" 3627 | }, 3628 | "engines": { 3629 | "node": ">= 8" 3630 | } 3631 | }, 3632 | "node_modules/word-wrap": { 3633 | "version": "1.2.5", 3634 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 3635 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 3636 | "dev": true, 3637 | "license": "MIT", 3638 | "engines": { 3639 | "node": ">=0.10.0" 3640 | } 3641 | }, 3642 | "node_modules/wrap-ansi": { 3643 | "version": "7.0.0", 3644 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 3645 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 3646 | "dev": true, 3647 | "license": "MIT", 3648 | "dependencies": { 3649 | "ansi-styles": "^4.0.0", 3650 | "string-width": "^4.1.0", 3651 | "strip-ansi": "^6.0.0" 3652 | }, 3653 | "engines": { 3654 | "node": ">=10" 3655 | }, 3656 | "funding": { 3657 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 3658 | } 3659 | }, 3660 | "node_modules/wrappy": { 3661 | "version": "1.0.2", 3662 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3663 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 3664 | "dev": true, 3665 | "license": "ISC" 3666 | }, 3667 | "node_modules/y18n": { 3668 | "version": "5.0.8", 3669 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 3670 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 3671 | "dev": true, 3672 | "license": "ISC", 3673 | "engines": { 3674 | "node": ">=10" 3675 | } 3676 | }, 3677 | "node_modules/yargs": { 3678 | "version": "17.7.2", 3679 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 3680 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 3681 | "dev": true, 3682 | "license": "MIT", 3683 | "dependencies": { 3684 | "cliui": "^8.0.1", 3685 | "escalade": "^3.1.1", 3686 | "get-caller-file": "^2.0.5", 3687 | "require-directory": "^2.1.1", 3688 | "string-width": "^4.2.3", 3689 | "y18n": "^5.0.5", 3690 | "yargs-parser": "^21.1.1" 3691 | }, 3692 | "engines": { 3693 | "node": ">=12" 3694 | } 3695 | }, 3696 | "node_modules/yargs-parser": { 3697 | "version": "21.1.1", 3698 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 3699 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 3700 | "dev": true, 3701 | "license": "ISC", 3702 | "engines": { 3703 | "node": ">=12" 3704 | } 3705 | }, 3706 | "node_modules/yocto-queue": { 3707 | "version": "0.1.0", 3708 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 3709 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 3710 | "dev": true, 3711 | "license": "MIT", 3712 | "engines": { 3713 | "node": ">=10" 3714 | }, 3715 | "funding": { 3716 | "url": "https://github.com/sponsors/sindresorhus" 3717 | } 3718 | } 3719 | } 3720 | } 3721 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "saucelab-playwright", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test:htmlreport": "npx playwright test & npx playwright show-report", 8 | "test:full": "npx playwright test", 9 | "test:debug": "npx playwright test --ui", 10 | "test:e2e": "npx playwright test --grep @e2e", 11 | "type:check": "tsc --noEmit", 12 | "prettier:format": "npx prettier --write --ignore-unknown **/*", 13 | "prettier:check": "prettier --check --ignore-unknown **/*", 14 | "lint:fix": "eslint --fix */**/*.{js,ts}", 15 | "lint:check": "eslint */**/*.{js,ts}", 16 | "prepare": "husky" 17 | }, 18 | "lint-staged": { 19 | "*/**/*.{js,ts}": "npx eslint --fix", 20 | "**/*": "prettier --write --ignore-unknown", 21 | "*/**/*.ts": "bash -c 'tsc --noEmit'" 22 | }, 23 | "keywords": [], 24 | "author": "", 25 | "license": "ISC", 26 | "devDependencies": { 27 | "@commitlint/cli": "^19.7.1", 28 | "@commitlint/config-conventional": "^19.7.1", 29 | "@eslint/js": "^9.1.1", 30 | "@playwright/test": "^1.43.1", 31 | "@types/js-yaml": "^4.0.9", 32 | "@types/node": "^20.12.7", 33 | "eslint": "^8.57.1", 34 | "eslint-plugin-ascii": "^2.0.0", 35 | "eslint-plugin-jsonc": "^2.19.1", 36 | "eslint-plugin-simple-import-sort": "^12.1.1", 37 | "eslint-plugin-unused-imports": "^4.1.4", 38 | "globals": "^15.1.0", 39 | "husky": "^9.1.7", 40 | "prettier": "^3.5.2", 41 | "typescript": "^5.4.5", 42 | "typescript-eslint": "^7.8.0" 43 | }, 44 | "dependencies": { 45 | "@influxdata/influxdb-client": "^1.33.2", 46 | "bson": "^6.8.0", 47 | "dotenv": "^16.4.5", 48 | "js-yaml": "^4.1.0", 49 | "mongodb": "^6.8.0", 50 | "tsx": "^4.19.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /page_objects/checkout.page.ts: -------------------------------------------------------------------------------- 1 | import { type Page, expect } from '@playwright/test' 2 | import { Steps } from '@/utilities/stepdecorator' 3 | 4 | export default class Checkout { 5 | readonly page: Page 6 | 7 | constructor(page: Page) { 8 | this.page = page 9 | } 10 | 11 | @Steps('Click the checkout button') 12 | async clickCheckout() { 13 | await this.page.getByTestId('checkout').click() 14 | } 15 | @Steps('Enter the address with {firstname}, {lastname} and {postcode}') 16 | async enterAddress(firstname: string, lastname: string, postcode: string) { 17 | await this.page.getByTestId('firstName').fill(firstname) 18 | await this.page.getByTestId('lastName').fill(lastname) 19 | await this.page.getByTestId('postalCode').fill(postcode) 20 | await this.page.getByRole('button', { name: 'Continue' }).click() 21 | } 22 | 23 | @Steps('Checkout overview') 24 | async checkoutOverview() { 25 | await expect(this.page.getByTestId('payment-info-label')).toBeVisible() 26 | await expect(this.page.getByTestId('shipping-info-label')).toBeVisible() 27 | await expect(this.page.getByTestId('total-info-label')).toBeVisible() 28 | } 29 | 30 | @Steps('Finish the checkout') 31 | async finishCheckout() { 32 | await this.page.getByRole('button', { name: 'Finish' }).click() 33 | } 34 | 35 | @Steps('Order completion') 36 | async orderCompletion() { 37 | await expect(this.page.getByTestId('complete-header')).toHaveText('Thank you for your order!', { ignoreCase: true }) 38 | await expect(this.page.getByTestId('title')).toHaveText('Checkout: Complete!', { ignoreCase: true }) 39 | await expect(this.page.getByRole('button', { name: /Back Home/ })).toBeVisible() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /page_objects/login.page.ts: -------------------------------------------------------------------------------- 1 | import { expect, type Page } from '@playwright/test' 2 | import { Steps } from '@/utilities/stepdecorator' 3 | 4 | export default class HomePage { 5 | readonly page: Page 6 | constructor(page: Page) { 7 | this.page = page 8 | } 9 | 10 | @Steps('Launch the app with {args}') 11 | async launchApp(url: any) { 12 | await this.page.goto(url) 13 | await expect(this.page.getByText('Swag Labs')).toBeVisible() 14 | } 15 | 16 | @Steps('Login with {username} and {password}') 17 | async login(username: string, password: string) { 18 | await this.page.locator('[data-test="username"]').fill(username) 19 | await this.page.locator('[data-test="password"]').fill(password) 20 | await this.page.getByRole('button', { name: 'Login', exact: true }).click() 21 | await expect(this.page.getByText('Swag Labs')).toBeVisible() 22 | } 23 | 24 | @Steps('Click on the Jacket') 25 | async clickJacket() { 26 | await this.page.getByTestId('inventory-item-name').filter({ hasText: 'Jacket' }).click() 27 | await expect(this.page.getByRole('button', { name: 'Back to products' })).toBeVisible() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /page_objects/page.ts: -------------------------------------------------------------------------------- 1 | import HomePage from './login.page' 2 | import Checkout from './checkout.page' 3 | import ProductInfo from './product.info' 4 | import ProductCartPage from './product.list.cart' 5 | 6 | export { HomePage, Checkout, ProductCartPage, ProductInfo } 7 | -------------------------------------------------------------------------------- /page_objects/product.info.ts: -------------------------------------------------------------------------------- 1 | import { expect, type Page, request } from '@playwright/test' 2 | import { Steps } from '@/utilities/stepdecorator' 3 | 4 | export default class ProductInfo { 5 | readonly page: Page 6 | 7 | constructor(page: Page) { 8 | this.page = page 9 | } 10 | 11 | @Steps('Validate remove or add to cart button') 12 | async validateRemoveOrAddToCart() { 13 | const addToCart = this.page.getByRole('button', { name: 'Add to cart' }) 14 | const removeButton = this.page.getByRole('button', { name: 'Add to cart' }) 15 | //check either 'Add to cart' or 'Remove' button present on each item 16 | const buttons = await addToCart.or(removeButton).all() 17 | buttons.forEach(async ele => await expect.soft(ele).toBeVisible()) 18 | } 19 | 20 | @Steps('Validate all items have price') 21 | async validateAllItemsHavePrice() { 22 | //all products have the $ price symbol 23 | for (const li of await this.page.locator('.inventory_item').getByTestId('inventory-item-price').all()) 24 | await expect.soft(li).toHaveText(/\$\d{1,3}\.\d{0,2}/) 25 | } 26 | 27 | @Steps('Validate all items have valid images') 28 | async validateAllHaveValidImages() { 29 | //get all images 30 | const images = await this.page.locator('img.inventory_item_img').all() 31 | 32 | const imgUrl = await Promise.all( 33 | images.map(async eacItem => { 34 | const url: string | any = await eacItem.getAttribute('src') 35 | return process.env.URL + url 36 | }), 37 | ) 38 | //validate each url response code 39 | const context = await request.newContext() 40 | await Promise.all( 41 | imgUrl.map(async eachUrl => { 42 | const eachUrlStatus = await context.get(eachUrl) 43 | expect(eachUrlStatus.ok()).toBeTruthy() 44 | }), 45 | ) 46 | } 47 | 48 | @Steps('Validate all items have description') 49 | async validateLowToHighPrice() { 50 | await this.page.locator('[data-test="product-sort-container"]').selectOption('Price (low to high)') 51 | await expect(this.page.getByTestId('active-option')).toHaveText('Price (low to high)', { ignoreCase: true }) 52 | } 53 | 54 | @Steps('Click an item') 55 | async clickAnItem(item: string) { 56 | const product = this.page.locator('.inventory_item', { hasText: item }).getByRole('button', { name: 'Add to cart' }) 57 | await product.click() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /page_objects/product.list.cart.ts: -------------------------------------------------------------------------------- 1 | import { type Page, expect } from '@playwright/test' 2 | import { Steps } from '@/utilities/stepdecorator' 3 | 4 | export default class ProductCartPage { 5 | readonly page: Page 6 | 7 | constructor(page: Page) { 8 | this.page = page 9 | } 10 | 11 | @Steps('Validate the Product Info Page') 12 | async validateProductInfoPage() { 13 | await expect(this.page.getByTestId('inventory-item-name')).toBeVisible() 14 | await expect(this.page.getByTestId('inventory-item-desc')).toBeVisible() 15 | await expect(this.page.getByTestId('item-sauce-labs-backpack-img')).toBeVisible() 16 | await expect(this.page.getByTestId('inventory-item-price')).toBeVisible() 17 | await expect(this.page.getByTestId('add-to-cart')).toBeVisible() 18 | await expect(this.page.getByTestId('back-to-products')).toBeVisible() 19 | } 20 | 21 | @Steps('Click the Cart') 22 | async clickCart() { 23 | await this.page.getByTestId('shopping-cart-link').click() 24 | await expect(this.page.getByTestId('title')).toHaveText('Your Cart', { 25 | ignoreCase: false, 26 | }) 27 | } 28 | 29 | @Steps('Remove item from Cart') 30 | async removeItemCart() { 31 | await this.page.getByRole('button', { name: 'Remove' }).click() 32 | } 33 | 34 | @Steps('Empty Cart') 35 | async emptyCart() { 36 | await expect(this.page.getByTestId('inventory-item')).not.toBeVisible() 37 | await expect(this.page.locator('.shopping_cart_badge')).not.toBeVisible() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from '@playwright/test' 2 | import dotenv from 'dotenv' 3 | //import { rpConfig } from "./rpConfig"; 4 | 5 | /** 6 | * Read environment variables from file. 7 | * https://github.com/motdotla/dotenv 8 | */ 9 | // require('dotenv').config(); 10 | 11 | dotenv.config() 12 | const timestamp = new Date(Date.now()).toUTCString().replace(/ /gi, '_').replace(/:/gi, '').replace(/,/gi, '') 13 | /** 14 | * See https://playwright.dev/docs/test-configuration. 15 | */ 16 | export default defineConfig({ 17 | testDir: './e2e' /* Run tests in files in parallel */, 18 | fullyParallel: true, 19 | /* Fail the build on CI if you accidentally left test.only in the source code. */ 20 | forbidOnly: !!process.env.CI, 21 | /* Retry on CI only */ 22 | retries: process.env.CI ? 2 : 0, 23 | /* Opt out of parallel tests on CI. */ 24 | workers: process.env.CI ? 1 : undefined, //,['.\\custom_report\\customreporter.ts'] 25 | /* Reporter to use. See https://playwright.dev/docs/test-reporters */ 26 | reporter: [ 27 | ['html', { outputFolder: `./playwright-report/${timestamp}` }], 28 | ['list'], 29 | ['./custom_report/customreporter.ts'], 30 | //['@reportportal/agent-js-playwright', rpConfig], 31 | ], 32 | /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ 33 | use: { 34 | /* Base URL to use in actions like `await page.goto('/')`. */ 35 | baseURL: 'https://www.saucedemo.com', 36 | 37 | /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ 38 | trace: 'on', 39 | screenshot: 'only-on-failure', 40 | }, 41 | //globalSetup: require.resolve('./e2e/init/global-setup'), 42 | //globalTeardown: require.resolve('./e2e/init/global-teardown'), 43 | 44 | /* Configure projects for major browsers */ 45 | projects: [ 46 | { 47 | name: 'Sauce Demo - Chrome', 48 | use: { 49 | ...devices['Desktop Chrome'], 50 | channel: 'chrome', 51 | testIdAttribute: 'data-test', 52 | launchOptions: { 53 | args: ['--start-maximized'], 54 | }, 55 | }, 56 | }, 57 | // { 58 | // name: "chromium", 59 | // dependencies: ["init DB Connection"], 60 | // use: { 61 | // ...devices["Desktop Chrome"], 62 | // channel: 'chrome', 63 | // testIdAttribute: "data-test" 64 | // launchOptions: { 65 | // 66 | // headless: false 67 | // }, 68 | 69 | //connectOptions: { 70 | // wsEndpoint: "ws://playwright-ui-typescript-pw-server-1:3000/" 71 | //} 72 | //// }, 73 | // }, 74 | { 75 | name: 'init DB Connection', 76 | testMatch: '**/setup.ts', 77 | teardown: 'close DB', 78 | }, 79 | { 80 | name: 'close DB', 81 | testMatch: '**/teardown.ts', 82 | }, 83 | 84 | /* Test against mobile viewports. */ 85 | // { 86 | // name: 'Mobile Chrome', 87 | // use: { ...devices['Pixel 5'] }, 88 | // }, 89 | // { 90 | // name: 'Mobile Safari', 91 | // use: { ...devices['iPhone 12'] }, 92 | // }, 93 | 94 | /* Test against branded browsers. */ 95 | //{ 96 | // name: 'Microsoft Edge', 97 | // dependencies: ["init DB Connection"], 98 | 99 | // use: { ...devices['Desktop Edge'], channel: 'msedge', headless: false, testIdAttribute: "data-test" }, 100 | // }, 101 | // { 102 | // name: 'Google Chrome', 103 | // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, 104 | // }, 105 | ], 106 | 107 | /* Run your local dev server before starting the tests */ 108 | // webServer: { 109 | // command: 'npm run start', 110 | // url: 'http://127.0.0.1:3000', 111 | // reuseExistingServer: !process.env.CI, 112 | // }, 113 | }) 114 | -------------------------------------------------------------------------------- /rpConfig.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv' 2 | dotenv.config({ path: '.env.rp' }) 3 | export const rpConfig = { 4 | endpoint: process.env.RP_ENDPOINT, 5 | apiKey: process.env.RP_API_KEY, 6 | launch: process.env.RP_LAUNCH || 'Custom regression', 7 | project: process.env.RP_PROJECT, 8 | attributes: [ 9 | { 10 | key: 'agent', 11 | value: 'playwright', 12 | }, 13 | { 14 | value: 'example', 15 | }, 16 | ], 17 | description: 'This is an example launch with playwright tests', 18 | //launchId: process.env.RP_LAUNCH_ID, 19 | includeTestSteps: true, 20 | skippedIssue: false, 21 | restClientConfig: { 22 | timeout: 0, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /test_data/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "credentials": { 3 | "username": "standard_user", 4 | "password": "secret_sauce" 5 | }, 6 | "TC01": {}, 7 | 8 | "TC02": {}, 9 | "product": "Sauce Labs Onesie", 10 | "address": { 11 | "firstname": "hello", 12 | "lastname": "world", 13 | "zipcode": "609 313" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "ES2015" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "ES2015" /* Specify what module code is generated. */, 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | "moduleResolution": "Node" /* Specify how TypeScript looks up a file from a given module specifier. */, 31 | "baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */, 32 | "paths": { 33 | "@/*": ["*"], 34 | "@utilities/*": ["utilities/*"], 35 | "@pageobjects/*": ["page_objects/*"], 36 | "@reporter/*": ["custom_report/*"], 37 | "@tests/*": ["e2e/*"] 38 | } /* Specify a set of entries that re-map imports to additional lookup locations. */, 39 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 40 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 41 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 42 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 43 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 44 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 45 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 46 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 47 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 48 | // "resolveJsonModule": true, /* Enable importing .json files. */ 49 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 50 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 51 | 52 | /* JavaScript Support */ 53 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 54 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 55 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 56 | 57 | /* Emit */ 58 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 59 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 60 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 61 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 62 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 63 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 64 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 65 | // "removeComments": true, /* Disable emitting comments. */ 66 | // "noEmit": true, /* Disable emitting files from a compilation. */ 67 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 68 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 69 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 70 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 71 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 72 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 73 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 74 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 75 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 76 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 77 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 78 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 79 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 80 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 81 | 82 | /* Interop Constraints */ 83 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 84 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 85 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 86 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 87 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 88 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 89 | 90 | /* Type Checking */ 91 | "strict": true /* Enable all strict type-checking options. */, 92 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 93 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 94 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 95 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 96 | "strictPropertyInitialization": false /* Check for class properties that are declared but not set in the constructor. */, 97 | "noImplicitThis": false /* Enable error reporting when 'this' is given the type 'any'. */, 98 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 99 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 100 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 101 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 102 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 103 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 104 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 105 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 106 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 107 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 108 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 109 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 110 | 111 | /* Completeness */ 112 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 113 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /utilities/fixture.ts: -------------------------------------------------------------------------------- 1 | import { test as base, expect } from '@playwright/test' 2 | import { dbSingleton, type MongoClientSingelton } from '@utilities/mongoclient' 3 | import { HomePage, Checkout, ProductCartPage, ProductInfo } from '@pageobjects/page' 4 | import { ReadData } from '@utilities/test.data' 5 | 6 | type pageObject = { 7 | homePage: HomePage 8 | checkoutPage: Checkout 9 | prodInfo: ProductInfo 10 | prodCart: ProductCartPage 11 | readData: ReadData 12 | mongoclient: Readonly 13 | } 14 | type pageObject1 = { 15 | homePage: HomePage 16 | } 17 | 18 | const test2 = base.extend({ 19 | homePage: async ({ baseURL, page, context }, use) => { 20 | await context.newPage() 21 | const homePage = new HomePage(page) 22 | await page.goto(baseURL as string) 23 | await use(homePage) 24 | }, 25 | }) 26 | const test = base.extend({ 27 | readData: new ReadData(), 28 | homePage: async ({ baseURL, page }, use) => { 29 | const homePage = new HomePage(page) 30 | await page.goto(baseURL as string) 31 | await use(homePage) 32 | }, 33 | checkoutPage: async ({ page }, use) => { 34 | const checkout = new Checkout(page) 35 | await use(checkout) 36 | }, 37 | 38 | prodInfo: async ({ page }, use) => { 39 | const prodInfo = new ProductInfo(page) 40 | await use(prodInfo) 41 | }, 42 | prodCart: async ({ page }, use) => { 43 | const prodCart = new ProductCartPage(page) 44 | await use(prodCart) 45 | }, 46 | 47 | mongoclient: async ({ page }, use) => { 48 | const _page = page 49 | const client = await dbSingleton.getClient() 50 | if (!client) throw Error('DB Client Instance is not initiated') 51 | await use(dbSingleton) 52 | }, 53 | }) 54 | 55 | export { test, test2, expect } 56 | -------------------------------------------------------------------------------- /utilities/mongoclient.ts: -------------------------------------------------------------------------------- 1 | import { MongoClient, ServerApiVersion } from 'mongodb' 2 | import { EJSON, type ObjectId } from 'bson' 3 | import dotenv from 'dotenv' 4 | dotenv.config() 5 | 6 | interface Student { 7 | _id?: ObjectId 8 | first_name: string 9 | last_name: string 10 | major: string 11 | age: number 12 | } 13 | 14 | class MongoClientSingelton { 15 | private client: MongoClient 16 | public static instance: MongoClientSingelton 17 | 18 | constructor() { 19 | if (MongoClientSingelton.instance) { 20 | throw new Error('You can only create one instance!') 21 | } 22 | console.log(`constructor called! `) 23 | this.client = new MongoClient(process.env.DB_CONN_STRING as string, { 24 | serverApi: { 25 | version: ServerApiVersion.v1, 26 | strict: true, 27 | deprecationErrors: true, 28 | }, 29 | }) 30 | console.log('successfully created') 31 | MongoClientSingelton.instance = this 32 | } 33 | async initClient() { 34 | this.client.connect() 35 | } 36 | 37 | async getClient() { 38 | return this.client 39 | } 40 | 41 | async closeConnection() { 42 | if (this.client) { 43 | console.log('successfully closed') 44 | await this.client.close() 45 | } 46 | } 47 | 48 | async readStudent(studentname: string) { 49 | const result = await this.client 50 | .db(process.env.DB_NAME as string) 51 | .collection(process.env.COLLECTION_NAME as string) 52 | .findOne({ first_name: studentname }) 53 | if (result) { 54 | const student = EJSON.stringify(result) 55 | const stu: Student = JSON.parse(student) 56 | delete stu._id 57 | return stu 58 | } else { 59 | throw Error(`No result returned for Student ${studentname}`) 60 | } 61 | } 62 | } 63 | 64 | const dbSingleton = Object.freeze(new MongoClientSingelton()) 65 | export { dbSingleton, MongoClientSingelton } 66 | -------------------------------------------------------------------------------- /utilities/read.yml.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | import * as yaml from 'js-yaml' 3 | 4 | interface ReadType { 5 | overideFileName(fileName: string): void 6 | getFile(): string 7 | sizeOfFile(fileName: string): number 8 | } 9 | class _ReadYaml implements ReadType { 10 | private fileName 11 | sizeOfFile(fileName: string) { 12 | return fileName.length 13 | } 14 | constructor(filename: string, _size: number) { 15 | this.fileName = filename 16 | } 17 | 18 | overideFileName(fileName = 'check') { 19 | this.fileName = fileName 20 | } 21 | 22 | getFile(): string { 23 | const content = fs.readFileSync(`test_data/${this.fileName}`, { 24 | encoding: 'utf-8', 25 | }) 26 | const y = yaml.load(content) 27 | return y as string 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /utilities/stepdecorator.ts: -------------------------------------------------------------------------------- 1 | import { test } from '@playwright/test' 2 | 3 | function _replacePlaceholders(template: string, values: any[]): string { 4 | values.forEach(value => { 5 | if (typeof value === 'string' || typeof value === 'number') { 6 | // add support for other data types if needed 7 | template = template.replace(/{(.*?)}/, value as any) 8 | } 9 | }) 10 | return template 11 | } 12 | 13 | export function Steps(_stepName?: string) { 14 | return function (target: any, context: ClassMethodDecoratorContext) { 15 | return function (...args: any) { 16 | const methodDetails = this.constructor.name + '.' + (context.name as string) 17 | const name = _stepName ? `${_replacePlaceholders(_stepName, args)} - ${methodDetails} ` : methodDetails 18 | return test.step(name, async () => { 19 | return await target.call(this, ...args) 20 | }) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /utilities/test.data.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | 3 | export class ReadData { 4 | private file: string 5 | constructor() { 6 | this.file = 'data.json' 7 | } 8 | 9 | setFile(fileName: string) { 10 | this.file = fileName 11 | } 12 | 13 | getFile() { 14 | const loadedConfig = fs.readFileSync(`test_data/${this.file}`, 'utf-8') 15 | const config = JSON.parse(loadedConfig) 16 | return config 17 | } 18 | } 19 | 20 | export default class NewFile {} 21 | --------------------------------------------------------------------------------