├── .github └── workflows │ ├── ci.yaml │ └── npm-publish.yaml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.OLD.md ├── README.md ├── compose.yaml ├── composer.json ├── composer.lock ├── phpstan.neon ├── phpunit.xml ├── playwright ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── playwright.config.ts ├── src │ └── index.ts ├── tsconfig.json └── vite.config.ts ├── src ├── Controller.php ├── ServiceProvider.php ├── Services │ ├── Config.php │ ├── DynamicConfig.php │ └── Truncate.php └── routes │ └── e2e.php └── tests ├── Feature ├── ArtisanTest.php ├── DynamicConfigTest.php ├── FactoryTest.php ├── FunctionTest.php ├── QueryTest.php ├── RegisterBootFunctionTest.php ├── RouteEnvTest.php ├── SelectTest.php ├── TeadDownTest.php ├── TravelTest.php ├── TruncateTest.php └── functions.php ├── Helpers ├── Migrations.php ├── TestableStaticMethod.php ├── UserFactory.php └── UserModel.php └── TestCase.php /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | tests: 11 | name: "Tests on PHP ${{ matrix.php }}${{ matrix.name_suffix }}" 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | php: [ '8.2', '8.3', '8.4' ] 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | 22 | - name: Setup PHP 23 | uses: shivammathur/setup-php@v2 24 | with: 25 | coverage: "none" 26 | php-version: "${{ matrix.php }}" 27 | ini-file: development 28 | tools: composer:v2 29 | 30 | - name: Docker compose 31 | run: docker compose up -d 32 | 33 | - name: Install dependencies 34 | run: composer update --ansi --no-progress 35 | 36 | - name: Run tests 37 | run: vendor/bin/phpunit 38 | 39 | static_analysis: 40 | name: Static analysis 41 | runs-on: ubuntu-latest 42 | 43 | steps: 44 | - name: Checkout 45 | uses: actions/checkout@v2 46 | 47 | - name: Setup PHP 48 | uses: shivammathur/setup-php@v2 49 | with: 50 | coverage: "none" 51 | php-version: "8.3" 52 | ini-file: development 53 | 54 | - name: Install dependencies 55 | run: composer update --ansi --no-progress 56 | 57 | - name: Run phpstan 58 | run: vendor/bin/phpstan analyse --ansi --no-progress 59 | 60 | playwright_test: 61 | name: "Playwright TypeScript" 62 | runs-on: ubuntu-latest 63 | 64 | steps: 65 | - name: Checkout 66 | uses: actions/checkout@v2 67 | 68 | - name: Setup Node.js 69 | uses: actions/setup-node@v4 70 | with: 71 | node-version: '20.x' 72 | 73 | - name: Install dependencies 74 | working-directory: playwright 75 | run: npm install 76 | 77 | - name: Run TypeScript 78 | working-directory: playwright 79 | # build to check for errors 80 | run: npm run build -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yaml: -------------------------------------------------------------------------------- 1 | name: Publish to NPM 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | package_version: 6 | description: 'Custom package version to publish' 7 | required: true 8 | release: 9 | types: [published] 10 | 11 | jobs: 12 | publish: 13 | name: 'Publish to NPM' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v3 18 | 19 | - name: Setup Node 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: '20.x' 23 | registry-url: 'https://registry.npmjs.org' 24 | 25 | - name: Determine Version 26 | id: version 27 | run: | 28 | if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ inputs.package_version }}" != "" ]; then 29 | echo "::set-output name=version::${{ inputs.package_version }}" 30 | else 31 | echo "::set-output name=version::${{ github.ref_name }}" 32 | fi 33 | 34 | - name: Publish to NPM 35 | working-directory: playwright 36 | env: 37 | NODE_AUTH_TOKEN: ${{ secrets.HYVOR_ORG_NPM_TOKEN }} 38 | run: | 39 | npm ci 40 | npm run build 41 | npm version ${{ steps.version.outputs.version }} --no-git-tag-version 42 | npm publish --access public -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .idea 3 | .env 4 | .phpunit.result.cache -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2.0.0 2 | - Renamed PHP package from `hyvor/laravel-e2e` to `hyvor/laravel-playwright` 3 | - Introduces a new NPM package `@hyvor/laravel-playwright` for the frontend 4 | - Adds new methods for dynamic configuration 5 | 6 | # 1.0.0 7 | - Requires Laravel 11 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 HYVOR (hyvor.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.OLD.md: -------------------------------------------------------------------------------- 1 | # Laravel Playwright 2 | 3 | This repository contains a Laravel library and a Typescript library to help you write E2E tests for your Laravel application using [Playwright](https://playwright.dev/). It provides a set of endpoints to interact with your Laravel application from your Playwright tests. For example, you can run artisan commands, create models using factories, run database queries, and call PHP functions from your Playwright tests. 4 | 5 | ## Laravel 6 | 7 | ### Installation 8 | 9 | You can install the Laravel package via composer: 10 | 11 | ```bash 12 | composer require --dev hyvor/laravel-playwright 13 | ``` 14 | 15 | ### Configuration 16 | 17 | You can configure the package by adding an `e2e` key to your `config/app.php` file. The following options are available (default values are shown): 18 | 19 | ```php 20 | return [ 21 | // ... 22 | 23 | 'e2e' => [ 24 | /** 25 | * The prefix for the testing endpoints that are used to interact with Playwright 26 | * Make sure to change `use.laravelBaseUrl` in playwright.config.ts if you change this 27 | */ 28 | 'prefix' => 'playwright', 29 | 30 | /** 31 | * The environments in which the testing endpoints are enabled 32 | */ 33 | 'environments' => ['local', 'testing'], 34 | ], 35 | ]; 36 | ``` 37 | 38 | ## Playwright 39 | 40 | ## Usage 41 | 42 | ### Example Usage with Javascript 43 | 44 | ```js 45 | fetch('/playwright/artisan', { 46 | method: 'POST', 47 | headers: { 48 | 'Content-Type': 'application/json', 49 | }, 50 | body: JSON.stringify(INPUT_DATA), 51 | }) 52 | ``` 53 | 54 | ### Run artisan commands 55 | 56 | `POST playwright/artisan` endpoint allows you to run artisan commands from your tests. For example, you can run `php artisan migrate:fresh` before each test. It accepts two parameters: 57 | 58 | - `command` - The artisan command to run 59 | - `parameters` - The parameters to pass to the command (array/object, optional) 60 | 61 | ```json 62 | { 63 | "command": "migrate:fresh", 64 | "parameters": ["--seed"] 65 | } 66 | ``` 67 | 68 | This endpoint returns the exit code and the output of the command in JSON format: 69 | 70 | ```json 71 | { 72 | "code": 0, 73 | "output": "" 74 | } 75 | ``` 76 | 77 | ### Truncate all tables 78 | 79 | Truncating tables is faster than running `migrate:fresh` command in small sized databases. You can use `POST /playwright/truncate` endpoint to truncate all tables. It accepts an optional `connections` parameter to truncate tables in specific connections. If the `connections` parameter is not set, it truncates tables in the default connection. 80 | 81 | ```jsonc 82 | { 83 | "connections": [] // optional 84 | } 85 | ``` 86 | 87 | ### Create a model using factories 88 | 89 | You can use `POST /playwright/factory` endpoint to create a model using factories. It accepts the following parameters: 90 | 91 | - `model` - The model class name (if the model class name starts with `App\Models\`, you can omit it) 92 | - `count` - The number of models to create (optional, default: 1). If count is set (even if it's 1), it returns an array of models. Otherwise, it returns a single model. 93 | - `attributes` - The attributes to set (optional) 94 | 95 | The following example creates a single `App\Models\User` model with the `name` attribute set to `John Doe`, and returns it in JSON format: 96 | 97 | ```json 98 | { 99 | "model": "User", 100 | "attributes": { 101 | "name": "John Doe" 102 | } 103 | } 104 | ``` 105 | 106 | The following example creates 5 `App\Database\Models\User` models and returns them as an array in JSON format: 107 | 108 | ```json 109 | { 110 | "model": "App\\Database\\Models\\User", 111 | "count": 5 112 | } 113 | ``` 114 | 115 | ### Run a database query 116 | 117 | You can use `POST /playwright/query` endpoint to run a database query. It accepts the following parameters: 118 | 119 | - `query` - The query to run 120 | - `connection` - The database connection to use (optional) 121 | 122 | ```json 123 | { 124 | "query": "UPDATE users SET name = 'John Doe' WHERE id = 1", 125 | "connection": "mysql" 126 | } 127 | ``` 128 | 129 | ### Run a database select query 130 | 131 | You can use `POST /playwright/select` endpoint to run a database select query. It accepts the following parameters: 132 | 133 | - `query` - The query to run 134 | - `connection` - The database connection to use (optional) 135 | 136 | It returns the result as an array of objects in JSON format. 137 | 138 | ```json 139 | { 140 | "query": "SELECT * FROM users WHERE id = 1", 141 | "connection": "mysql" 142 | } 143 | ``` 144 | 145 | ### Call a PHP function or static class method 146 | 147 | Use the `POST /playwright/function` endpoint to call a PHP function or a static class method. It accepts the following parameters: 148 | 149 | - `function` - Function name to call 150 | - `args` - Array of arguments to send to the function 151 | 152 | Function's return value will be returned (JSON-encoded) from this endpoint. 153 | 154 | Examples: 155 | 156 | Arguments as an array: 157 | 158 | ```json 159 | { 160 | "function": "fullName", 161 | "args": ["Supun", "Wimalasena"] 162 | } 163 | ``` 164 | 165 | This calls a function named `fullName` with two arguments. 166 | 167 | Named arguments: 168 | 169 | ```json 170 | { 171 | "function": "fullName", 172 | "args": { 173 | "first": "Supun", 174 | "last": "Wimalasena" 175 | } 176 | } 177 | ``` 178 | 179 | Static methods: 180 | 181 | ```json 182 | { 183 | "function": "namespace\\class::method", 184 | "args": [] 185 | } 186 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Playwright 2 | 3 | This repository contains a Laravel and a Playwright library to help you write E2E tests for your Laravel application using [Playwright](https://playwright.dev/). It adds a set of endpoints to your Laravel application to allow Playwright to interact with it. You can do the following from your Playwright tests: 4 | 5 | - Run artisan commands 6 | - Create models using factories 7 | - Run database queries 8 | - Run PHP functions 9 | - Update Laravel config while a test is running (until the test ends and calls `tearDown`). 10 | - Registering a boot function to run on each Laravel request. You can use this feature to mock a service dependency, for example. 11 | - Traveling to a specific time in the application during the test 12 | 13 | ## Installation 14 | 15 | On Laravel side, install the package via composer: 16 | 17 | ```bash 18 | composer require --dev hyvor/laravel-playwright 19 | ``` 20 | 21 | On Playwright side, install the package via npm: 22 | 23 | ```bash 24 | npm install @hyvor/laravel-playwright 25 | ``` 26 | 27 | ## Laravel Config 28 | 29 | You can configure the routes by adding an `e2e` key to your `config/app.php` file. The following options are available (default values are shown): 30 | 31 | ```php 32 | return [ 33 | // ... 34 | 35 | 'e2e' => [ 36 | /** 37 | * The prefix for the testing endpoints that are used to interact with Playwright 38 | * Make sure to change `use.laravelBaseUrl` in playwright.config.ts if you change this 39 | */ 40 | 'prefix' => 'playwright', 41 | 42 | /** 43 | * The environments in which the testing endpoints are enabled 44 | * CAUTION: Enabling the testing endpoints in production can be a critical security issue 45 | */ 46 | 'environments' => ['local', 'testing'], 47 | ], 48 | ]; 49 | ``` 50 | 51 | ## Playwright Config 52 | 53 | Set `use.laravelBaseUrl` in your `playwright.config.ts` file to the base URL of your testing endpoints. This is the URL of your application + the `prefix` you set in Laravel config. 54 | 55 | ```ts 56 | export default defineConfig({ 57 | // ...other 58 | use: { 59 | laravelBaseUrl: 'http://localhost/playwright', 60 | }, 61 | }); 62 | ``` 63 | 64 | If you use Typescript, include the `LaravelOptions` type in the `defineConfig` function. 65 | 66 | ```ts 67 | import type { LaravelOptions } from '@hyvor/laravel-playwright'; 68 | 69 | export default defineConfig({ 70 | use: { 71 | laravelBaseUrl: 'http://localhost/playwright', 72 | }, 73 | }); 74 | ``` 75 | 76 | ## Setting up tests 77 | 78 | In your Playwright tests, swap the `test` import from `@playwright/test` to `@hyvor/laravel-playwright`. 79 | 80 | ```diff 81 | - import { test } from '@playwright/test'; 82 | + import { test } from '@hyvor/laravel-playwright'; 83 | 84 | test('example', async ({ laravel }) => { 85 | laravel.artisan('migrate:fresh'); 86 | }); 87 | ``` 88 | 89 | > **Note**: In practise, it is not recommended to import from `@hyvor/laravel-playwright` directly on every test file, if you have many. Instead, create your own [test fixture](https://playwright.dev/docs/test-fixtures) extending `test` from `@hyvor/laravel-playwright` and import that fixture in your tests. 90 | 91 | ## Basic Usage 92 | 93 | ```ts 94 | import { test } from '@hyvor/laravel-playwright'; 95 | 96 | test('example', async ({ laravel }) => { 97 | 98 | // RUN ARTISAN COMMANDS 99 | // ==================== 100 | const output = await laravel.artisan('migrate:fresh'); 101 | // output.code: number - The exit code of the command 102 | // output.output: string - The output of the command 103 | // with parameters 104 | await laravel.artisan('db:seed', ['--class', 'DatabaseSeeder']); 105 | 106 | 107 | // TRUNCATE TABLES 108 | // =============== 109 | await laravel.truncate(); 110 | // in specific DB connections 111 | await laravel.truncate(['connection1', 'connection2']); 112 | 113 | 114 | // CREATE MODELS FROM FACTORIES 115 | // ============================ 116 | // Create a App\Models\User model 117 | // user will be an object of the model 118 | const user = await laravel.factory('User'); 119 | // Create a App\Models\User model with attributes 120 | await laravel.factory('User', { name: 'John Doe' }); 121 | // Create 5 App\Models\User models 122 | // users will be an array of the models 123 | const users = await laravel.factory('User', {}, 5); 124 | // Create a CustomModel model 125 | await laravel.factory('CustomModel'); 126 | 127 | 128 | // RUN A DATABASE QUERY 129 | // ==================== 130 | // Run a query 131 | await laravel.query('DELETE FROM users'); 132 | // Run a query with bindings 133 | await laravel.query('DELETE FROM users WHERE id = ?', [1]); 134 | // Run a query on a specific connection 135 | await laravel.query('DELETE FROM users', [], { connection: 'connection1' }); 136 | // Run a unprepared statement 137 | await laravel.query(` 138 | DROP SCHEMA public CASCADE; 139 | CREATE SCHEMA public; 140 | GRANT ALL ON SCHEMA public TO public; 141 | `, [], { unprepared: true }); 142 | 143 | 144 | // RUN A SELECT QUERY 145 | // ================== 146 | // Run a select query 147 | // Returns an array of objects 148 | const blogs = await laravel.select('SELECT * FROM blogs'); 149 | // Run a select query with bindings 150 | await laravel.select('SELECT * FROM blogs WHERE id = ?', [1]); 151 | // Run a select query on a specific connection 152 | await laravel.select('SELECT * FROM blogs', [], { connection: 'connection1' }); 153 | 154 | 155 | // RUN A PHP FUNCTION 156 | // ================== 157 | // Run a PHP function 158 | // Returns the output of the function 159 | // Output is JSON encoded in Laravel and decoded in Playwright 160 | // The following examples call this function: 161 | // function sayHello($name) { return "Hello, $name!"; } 162 | const funcOutput = await laravel.callFunction('sayHello'); 163 | // Run a PHP function with parameters 164 | await laravel.callFunction('sayHello', ['John']); 165 | // Run a PHP function with named parameters 166 | await laravel.callFunction('sayHello', { name: 'John' }); 167 | // Run a static class method 168 | await laravel.callFunction("App\\MyAwesomeClass::method"); 169 | 170 | }); 171 | 172 | 173 | ``` 174 | 175 | ## Dynamic Configuration 176 | 177 | You can update Laravel config for **ALL** subsequent requests until the test ends. 178 | 179 | ```ts 180 | import { test } from '@hyvor/laravel-playwright'; 181 | 182 | test('example', async ({ laravel }) => { 183 | 184 | // SET DYNAMIC CONFIG 185 | // ================== 186 | // Update a config value 187 | // This value will be used in all subsequent requests sent to Laravel 188 | // until the test ends and calls `tearDown` (which is done automatically) 189 | await laravel.config('app.timezone', 'Europe/Paris'); 190 | 191 | // TRAVEL TO A TIME 192 | // ================= 193 | // Travel to a specific time in the application 194 | // This is similar to Laravel's `travelTo` method 195 | await laravel.travel('2022-01-01 12:00:00'); 196 | 197 | // REGISTER A BOOT FUNCTION 198 | // ======================== 199 | // Register a function to run while Laravel is booting 200 | // This is useful to mock a service dependency, for example 201 | await laravel.registerBootFunction('App\\E2EHelper::swapPaymentService'); 202 | 203 | }); 204 | ``` -------------------------------------------------------------------------------- /compose.yaml: -------------------------------------------------------------------------------- 1 | # Use postgres/example user/password credentials 2 | version: '3.9' 3 | 4 | services: 5 | 6 | db: 7 | image: postgres 8 | restart: always 9 | environment: 10 | POSTGRES_DB: postgres 11 | POSTGRES_USER: postgres 12 | POSTGRES_PASSWORD: postgres 13 | ports: 14 | - "8989:5432" 15 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hyvor/laravel-playwright", 3 | "description": "Laravel and Playwright E2E Testing", 4 | "keywords": ["laravel", "playwright", "testing", "e2e"], 5 | "type": "library", 6 | "license": "MIT", 7 | "autoload": { 8 | "psr-4": { 9 | "Hyvor\\LaravelPlaywright\\": "src/" 10 | } 11 | }, 12 | "autoload-dev": { 13 | "psr-4": { 14 | "Hyvor\\LaravelPlaywright\\Tests\\": "tests/" 15 | } 16 | }, 17 | "authors": [ 18 | { 19 | "name": "Supun", 20 | "email": "supun@hyvor.com" 21 | } 22 | ], 23 | "require": { 24 | "php": ">=8.2" 25 | }, 26 | "require-dev": { 27 | "orchestra/testbench": "^9.0", 28 | "phpstan/phpstan": "^2.0", 29 | "larastan/larastan": "^3.0", 30 | "phpunit/phpunit": "^10.5" 31 | }, 32 | "extra": { 33 | "laravel": { 34 | "providers": [ 35 | "Hyvor\\LaravelPlaywright\\ServiceProvider" 36 | ] 37 | } 38 | }, 39 | "config": { 40 | "allow-plugins": { 41 | "pestphp/pest-plugin": true 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/larastan/larastan/extension.neon 3 | 4 | parameters: 5 | level: max 6 | paths: 7 | - src 8 | - tests -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests 6 | 7 | 8 | 9 | 10 | 11 | ./app 12 | ./src 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /playwright/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | /test-results/ 26 | /playwright-report/ 27 | /blob-report/ 28 | /playwright/.cache/ 29 | -------------------------------------------------------------------------------- /playwright/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /playwright/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@hyvor/laravel-playwright", 3 | "version": "2.0.0-dev2", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@hyvor/laravel-playwright", 9 | "version": "2.0.0-dev2", 10 | "dependencies": { 11 | "vite-plugin-dts": "^4.5.0" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^22.10.5", 15 | "typescript": "~5.6.2", 16 | "vite": "^6.0.5" 17 | }, 18 | "peerDependencies": { 19 | "@playwright/test": "^1.49.1" 20 | } 21 | }, 22 | "node_modules/@babel/helper-string-parser": { 23 | "version": "7.25.9", 24 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", 25 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", 26 | "license": "MIT", 27 | "engines": { 28 | "node": ">=6.9.0" 29 | } 30 | }, 31 | "node_modules/@babel/helper-validator-identifier": { 32 | "version": "7.25.9", 33 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 34 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 35 | "license": "MIT", 36 | "engines": { 37 | "node": ">=6.9.0" 38 | } 39 | }, 40 | "node_modules/@babel/parser": { 41 | "version": "7.26.5", 42 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", 43 | "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", 44 | "license": "MIT", 45 | "dependencies": { 46 | "@babel/types": "^7.26.5" 47 | }, 48 | "bin": { 49 | "parser": "bin/babel-parser.js" 50 | }, 51 | "engines": { 52 | "node": ">=6.0.0" 53 | } 54 | }, 55 | "node_modules/@babel/types": { 56 | "version": "7.26.5", 57 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", 58 | "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", 59 | "license": "MIT", 60 | "dependencies": { 61 | "@babel/helper-string-parser": "^7.25.9", 62 | "@babel/helper-validator-identifier": "^7.25.9" 63 | }, 64 | "engines": { 65 | "node": ">=6.9.0" 66 | } 67 | }, 68 | "node_modules/@esbuild/aix-ppc64": { 69 | "version": "0.24.2", 70 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", 71 | "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", 72 | "cpu": [ 73 | "ppc64" 74 | ], 75 | "dev": true, 76 | "license": "MIT", 77 | "optional": true, 78 | "os": [ 79 | "aix" 80 | ], 81 | "engines": { 82 | "node": ">=18" 83 | } 84 | }, 85 | "node_modules/@esbuild/android-arm": { 86 | "version": "0.24.2", 87 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", 88 | "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", 89 | "cpu": [ 90 | "arm" 91 | ], 92 | "dev": true, 93 | "license": "MIT", 94 | "optional": true, 95 | "os": [ 96 | "android" 97 | ], 98 | "engines": { 99 | "node": ">=18" 100 | } 101 | }, 102 | "node_modules/@esbuild/android-arm64": { 103 | "version": "0.24.2", 104 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", 105 | "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", 106 | "cpu": [ 107 | "arm64" 108 | ], 109 | "dev": true, 110 | "license": "MIT", 111 | "optional": true, 112 | "os": [ 113 | "android" 114 | ], 115 | "engines": { 116 | "node": ">=18" 117 | } 118 | }, 119 | "node_modules/@esbuild/android-x64": { 120 | "version": "0.24.2", 121 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", 122 | "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", 123 | "cpu": [ 124 | "x64" 125 | ], 126 | "dev": true, 127 | "license": "MIT", 128 | "optional": true, 129 | "os": [ 130 | "android" 131 | ], 132 | "engines": { 133 | "node": ">=18" 134 | } 135 | }, 136 | "node_modules/@esbuild/darwin-arm64": { 137 | "version": "0.24.2", 138 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", 139 | "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", 140 | "cpu": [ 141 | "arm64" 142 | ], 143 | "dev": true, 144 | "license": "MIT", 145 | "optional": true, 146 | "os": [ 147 | "darwin" 148 | ], 149 | "engines": { 150 | "node": ">=18" 151 | } 152 | }, 153 | "node_modules/@esbuild/darwin-x64": { 154 | "version": "0.24.2", 155 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", 156 | "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", 157 | "cpu": [ 158 | "x64" 159 | ], 160 | "dev": true, 161 | "license": "MIT", 162 | "optional": true, 163 | "os": [ 164 | "darwin" 165 | ], 166 | "engines": { 167 | "node": ">=18" 168 | } 169 | }, 170 | "node_modules/@esbuild/freebsd-arm64": { 171 | "version": "0.24.2", 172 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", 173 | "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", 174 | "cpu": [ 175 | "arm64" 176 | ], 177 | "dev": true, 178 | "license": "MIT", 179 | "optional": true, 180 | "os": [ 181 | "freebsd" 182 | ], 183 | "engines": { 184 | "node": ">=18" 185 | } 186 | }, 187 | "node_modules/@esbuild/freebsd-x64": { 188 | "version": "0.24.2", 189 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", 190 | "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", 191 | "cpu": [ 192 | "x64" 193 | ], 194 | "dev": true, 195 | "license": "MIT", 196 | "optional": true, 197 | "os": [ 198 | "freebsd" 199 | ], 200 | "engines": { 201 | "node": ">=18" 202 | } 203 | }, 204 | "node_modules/@esbuild/linux-arm": { 205 | "version": "0.24.2", 206 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", 207 | "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", 208 | "cpu": [ 209 | "arm" 210 | ], 211 | "dev": true, 212 | "license": "MIT", 213 | "optional": true, 214 | "os": [ 215 | "linux" 216 | ], 217 | "engines": { 218 | "node": ">=18" 219 | } 220 | }, 221 | "node_modules/@esbuild/linux-arm64": { 222 | "version": "0.24.2", 223 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", 224 | "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", 225 | "cpu": [ 226 | "arm64" 227 | ], 228 | "dev": true, 229 | "license": "MIT", 230 | "optional": true, 231 | "os": [ 232 | "linux" 233 | ], 234 | "engines": { 235 | "node": ">=18" 236 | } 237 | }, 238 | "node_modules/@esbuild/linux-ia32": { 239 | "version": "0.24.2", 240 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", 241 | "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", 242 | "cpu": [ 243 | "ia32" 244 | ], 245 | "dev": true, 246 | "license": "MIT", 247 | "optional": true, 248 | "os": [ 249 | "linux" 250 | ], 251 | "engines": { 252 | "node": ">=18" 253 | } 254 | }, 255 | "node_modules/@esbuild/linux-loong64": { 256 | "version": "0.24.2", 257 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", 258 | "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", 259 | "cpu": [ 260 | "loong64" 261 | ], 262 | "dev": true, 263 | "license": "MIT", 264 | "optional": true, 265 | "os": [ 266 | "linux" 267 | ], 268 | "engines": { 269 | "node": ">=18" 270 | } 271 | }, 272 | "node_modules/@esbuild/linux-mips64el": { 273 | "version": "0.24.2", 274 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", 275 | "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", 276 | "cpu": [ 277 | "mips64el" 278 | ], 279 | "dev": true, 280 | "license": "MIT", 281 | "optional": true, 282 | "os": [ 283 | "linux" 284 | ], 285 | "engines": { 286 | "node": ">=18" 287 | } 288 | }, 289 | "node_modules/@esbuild/linux-ppc64": { 290 | "version": "0.24.2", 291 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", 292 | "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", 293 | "cpu": [ 294 | "ppc64" 295 | ], 296 | "dev": true, 297 | "license": "MIT", 298 | "optional": true, 299 | "os": [ 300 | "linux" 301 | ], 302 | "engines": { 303 | "node": ">=18" 304 | } 305 | }, 306 | "node_modules/@esbuild/linux-riscv64": { 307 | "version": "0.24.2", 308 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", 309 | "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", 310 | "cpu": [ 311 | "riscv64" 312 | ], 313 | "dev": true, 314 | "license": "MIT", 315 | "optional": true, 316 | "os": [ 317 | "linux" 318 | ], 319 | "engines": { 320 | "node": ">=18" 321 | } 322 | }, 323 | "node_modules/@esbuild/linux-s390x": { 324 | "version": "0.24.2", 325 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", 326 | "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", 327 | "cpu": [ 328 | "s390x" 329 | ], 330 | "dev": true, 331 | "license": "MIT", 332 | "optional": true, 333 | "os": [ 334 | "linux" 335 | ], 336 | "engines": { 337 | "node": ">=18" 338 | } 339 | }, 340 | "node_modules/@esbuild/linux-x64": { 341 | "version": "0.24.2", 342 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", 343 | "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", 344 | "cpu": [ 345 | "x64" 346 | ], 347 | "dev": true, 348 | "license": "MIT", 349 | "optional": true, 350 | "os": [ 351 | "linux" 352 | ], 353 | "engines": { 354 | "node": ">=18" 355 | } 356 | }, 357 | "node_modules/@esbuild/netbsd-arm64": { 358 | "version": "0.24.2", 359 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", 360 | "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", 361 | "cpu": [ 362 | "arm64" 363 | ], 364 | "dev": true, 365 | "license": "MIT", 366 | "optional": true, 367 | "os": [ 368 | "netbsd" 369 | ], 370 | "engines": { 371 | "node": ">=18" 372 | } 373 | }, 374 | "node_modules/@esbuild/netbsd-x64": { 375 | "version": "0.24.2", 376 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", 377 | "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", 378 | "cpu": [ 379 | "x64" 380 | ], 381 | "dev": true, 382 | "license": "MIT", 383 | "optional": true, 384 | "os": [ 385 | "netbsd" 386 | ], 387 | "engines": { 388 | "node": ">=18" 389 | } 390 | }, 391 | "node_modules/@esbuild/openbsd-arm64": { 392 | "version": "0.24.2", 393 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", 394 | "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", 395 | "cpu": [ 396 | "arm64" 397 | ], 398 | "dev": true, 399 | "license": "MIT", 400 | "optional": true, 401 | "os": [ 402 | "openbsd" 403 | ], 404 | "engines": { 405 | "node": ">=18" 406 | } 407 | }, 408 | "node_modules/@esbuild/openbsd-x64": { 409 | "version": "0.24.2", 410 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", 411 | "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", 412 | "cpu": [ 413 | "x64" 414 | ], 415 | "dev": true, 416 | "license": "MIT", 417 | "optional": true, 418 | "os": [ 419 | "openbsd" 420 | ], 421 | "engines": { 422 | "node": ">=18" 423 | } 424 | }, 425 | "node_modules/@esbuild/sunos-x64": { 426 | "version": "0.24.2", 427 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", 428 | "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", 429 | "cpu": [ 430 | "x64" 431 | ], 432 | "dev": true, 433 | "license": "MIT", 434 | "optional": true, 435 | "os": [ 436 | "sunos" 437 | ], 438 | "engines": { 439 | "node": ">=18" 440 | } 441 | }, 442 | "node_modules/@esbuild/win32-arm64": { 443 | "version": "0.24.2", 444 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", 445 | "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", 446 | "cpu": [ 447 | "arm64" 448 | ], 449 | "dev": true, 450 | "license": "MIT", 451 | "optional": true, 452 | "os": [ 453 | "win32" 454 | ], 455 | "engines": { 456 | "node": ">=18" 457 | } 458 | }, 459 | "node_modules/@esbuild/win32-ia32": { 460 | "version": "0.24.2", 461 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", 462 | "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", 463 | "cpu": [ 464 | "ia32" 465 | ], 466 | "dev": true, 467 | "license": "MIT", 468 | "optional": true, 469 | "os": [ 470 | "win32" 471 | ], 472 | "engines": { 473 | "node": ">=18" 474 | } 475 | }, 476 | "node_modules/@esbuild/win32-x64": { 477 | "version": "0.24.2", 478 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", 479 | "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", 480 | "cpu": [ 481 | "x64" 482 | ], 483 | "dev": true, 484 | "license": "MIT", 485 | "optional": true, 486 | "os": [ 487 | "win32" 488 | ], 489 | "engines": { 490 | "node": ">=18" 491 | } 492 | }, 493 | "node_modules/@jridgewell/sourcemap-codec": { 494 | "version": "1.5.0", 495 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 496 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 497 | "license": "MIT" 498 | }, 499 | "node_modules/@microsoft/api-extractor": { 500 | "version": "7.49.1", 501 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.49.1.tgz", 502 | "integrity": "sha512-jRTR/XbQF2kb+dYn8hfYSicOGA99+Fo00GrsdMwdfE3eIgLtKdH6Qa2M3wZV9S2XmbgCaGX1OdPtYctbfu5jQg==", 503 | "license": "MIT", 504 | "dependencies": { 505 | "@microsoft/api-extractor-model": "7.30.2", 506 | "@microsoft/tsdoc": "~0.15.1", 507 | "@microsoft/tsdoc-config": "~0.17.1", 508 | "@rushstack/node-core-library": "5.10.2", 509 | "@rushstack/rig-package": "0.5.3", 510 | "@rushstack/terminal": "0.14.5", 511 | "@rushstack/ts-command-line": "4.23.3", 512 | "lodash": "~4.17.15", 513 | "minimatch": "~3.0.3", 514 | "resolve": "~1.22.1", 515 | "semver": "~7.5.4", 516 | "source-map": "~0.6.1", 517 | "typescript": "5.7.2" 518 | }, 519 | "bin": { 520 | "api-extractor": "bin/api-extractor" 521 | } 522 | }, 523 | "node_modules/@microsoft/api-extractor-model": { 524 | "version": "7.30.2", 525 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.2.tgz", 526 | "integrity": "sha512-3/t2F+WhkJgBzSNwlkTIL0tBgUoBqDqL66pT+nh2mPbM0NIDGVGtpqbGWPgHIzn/mn7kGS/Ep8D8po58e8UUIw==", 527 | "license": "MIT", 528 | "dependencies": { 529 | "@microsoft/tsdoc": "~0.15.1", 530 | "@microsoft/tsdoc-config": "~0.17.1", 531 | "@rushstack/node-core-library": "5.10.2" 532 | } 533 | }, 534 | "node_modules/@microsoft/api-extractor/node_modules/typescript": { 535 | "version": "5.7.2", 536 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", 537 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 538 | "license": "Apache-2.0", 539 | "bin": { 540 | "tsc": "bin/tsc", 541 | "tsserver": "bin/tsserver" 542 | }, 543 | "engines": { 544 | "node": ">=14.17" 545 | } 546 | }, 547 | "node_modules/@microsoft/tsdoc": { 548 | "version": "0.15.1", 549 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", 550 | "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", 551 | "license": "MIT" 552 | }, 553 | "node_modules/@microsoft/tsdoc-config": { 554 | "version": "0.17.1", 555 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", 556 | "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", 557 | "license": "MIT", 558 | "dependencies": { 559 | "@microsoft/tsdoc": "0.15.1", 560 | "ajv": "~8.12.0", 561 | "jju": "~1.4.0", 562 | "resolve": "~1.22.2" 563 | } 564 | }, 565 | "node_modules/@playwright/test": { 566 | "version": "1.49.1", 567 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", 568 | "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", 569 | "license": "Apache-2.0", 570 | "peer": true, 571 | "dependencies": { 572 | "playwright": "1.49.1" 573 | }, 574 | "bin": { 575 | "playwright": "cli.js" 576 | }, 577 | "engines": { 578 | "node": ">=18" 579 | } 580 | }, 581 | "node_modules/@rollup/pluginutils": { 582 | "version": "5.1.4", 583 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", 584 | "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", 585 | "license": "MIT", 586 | "dependencies": { 587 | "@types/estree": "^1.0.0", 588 | "estree-walker": "^2.0.2", 589 | "picomatch": "^4.0.2" 590 | }, 591 | "engines": { 592 | "node": ">=14.0.0" 593 | }, 594 | "peerDependencies": { 595 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" 596 | }, 597 | "peerDependenciesMeta": { 598 | "rollup": { 599 | "optional": true 600 | } 601 | } 602 | }, 603 | "node_modules/@rollup/rollup-android-arm-eabi": { 604 | "version": "4.30.1", 605 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", 606 | "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", 607 | "cpu": [ 608 | "arm" 609 | ], 610 | "dev": true, 611 | "license": "MIT", 612 | "optional": true, 613 | "os": [ 614 | "android" 615 | ] 616 | }, 617 | "node_modules/@rollup/rollup-android-arm64": { 618 | "version": "4.30.1", 619 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", 620 | "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", 621 | "cpu": [ 622 | "arm64" 623 | ], 624 | "dev": true, 625 | "license": "MIT", 626 | "optional": true, 627 | "os": [ 628 | "android" 629 | ] 630 | }, 631 | "node_modules/@rollup/rollup-darwin-arm64": { 632 | "version": "4.30.1", 633 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", 634 | "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", 635 | "cpu": [ 636 | "arm64" 637 | ], 638 | "dev": true, 639 | "license": "MIT", 640 | "optional": true, 641 | "os": [ 642 | "darwin" 643 | ] 644 | }, 645 | "node_modules/@rollup/rollup-darwin-x64": { 646 | "version": "4.30.1", 647 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", 648 | "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", 649 | "cpu": [ 650 | "x64" 651 | ], 652 | "dev": true, 653 | "license": "MIT", 654 | "optional": true, 655 | "os": [ 656 | "darwin" 657 | ] 658 | }, 659 | "node_modules/@rollup/rollup-freebsd-arm64": { 660 | "version": "4.30.1", 661 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", 662 | "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", 663 | "cpu": [ 664 | "arm64" 665 | ], 666 | "dev": true, 667 | "license": "MIT", 668 | "optional": true, 669 | "os": [ 670 | "freebsd" 671 | ] 672 | }, 673 | "node_modules/@rollup/rollup-freebsd-x64": { 674 | "version": "4.30.1", 675 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", 676 | "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", 677 | "cpu": [ 678 | "x64" 679 | ], 680 | "dev": true, 681 | "license": "MIT", 682 | "optional": true, 683 | "os": [ 684 | "freebsd" 685 | ] 686 | }, 687 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 688 | "version": "4.30.1", 689 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", 690 | "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", 691 | "cpu": [ 692 | "arm" 693 | ], 694 | "dev": true, 695 | "license": "MIT", 696 | "optional": true, 697 | "os": [ 698 | "linux" 699 | ] 700 | }, 701 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 702 | "version": "4.30.1", 703 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", 704 | "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", 705 | "cpu": [ 706 | "arm" 707 | ], 708 | "dev": true, 709 | "license": "MIT", 710 | "optional": true, 711 | "os": [ 712 | "linux" 713 | ] 714 | }, 715 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 716 | "version": "4.30.1", 717 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", 718 | "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", 719 | "cpu": [ 720 | "arm64" 721 | ], 722 | "dev": true, 723 | "license": "MIT", 724 | "optional": true, 725 | "os": [ 726 | "linux" 727 | ] 728 | }, 729 | "node_modules/@rollup/rollup-linux-arm64-musl": { 730 | "version": "4.30.1", 731 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", 732 | "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", 733 | "cpu": [ 734 | "arm64" 735 | ], 736 | "dev": true, 737 | "license": "MIT", 738 | "optional": true, 739 | "os": [ 740 | "linux" 741 | ] 742 | }, 743 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 744 | "version": "4.30.1", 745 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", 746 | "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", 747 | "cpu": [ 748 | "loong64" 749 | ], 750 | "dev": true, 751 | "license": "MIT", 752 | "optional": true, 753 | "os": [ 754 | "linux" 755 | ] 756 | }, 757 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 758 | "version": "4.30.1", 759 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", 760 | "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", 761 | "cpu": [ 762 | "ppc64" 763 | ], 764 | "dev": true, 765 | "license": "MIT", 766 | "optional": true, 767 | "os": [ 768 | "linux" 769 | ] 770 | }, 771 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 772 | "version": "4.30.1", 773 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", 774 | "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", 775 | "cpu": [ 776 | "riscv64" 777 | ], 778 | "dev": true, 779 | "license": "MIT", 780 | "optional": true, 781 | "os": [ 782 | "linux" 783 | ] 784 | }, 785 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 786 | "version": "4.30.1", 787 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", 788 | "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", 789 | "cpu": [ 790 | "s390x" 791 | ], 792 | "dev": true, 793 | "license": "MIT", 794 | "optional": true, 795 | "os": [ 796 | "linux" 797 | ] 798 | }, 799 | "node_modules/@rollup/rollup-linux-x64-gnu": { 800 | "version": "4.30.1", 801 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", 802 | "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", 803 | "cpu": [ 804 | "x64" 805 | ], 806 | "dev": true, 807 | "license": "MIT", 808 | "optional": true, 809 | "os": [ 810 | "linux" 811 | ] 812 | }, 813 | "node_modules/@rollup/rollup-linux-x64-musl": { 814 | "version": "4.30.1", 815 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", 816 | "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", 817 | "cpu": [ 818 | "x64" 819 | ], 820 | "dev": true, 821 | "license": "MIT", 822 | "optional": true, 823 | "os": [ 824 | "linux" 825 | ] 826 | }, 827 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 828 | "version": "4.30.1", 829 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", 830 | "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", 831 | "cpu": [ 832 | "arm64" 833 | ], 834 | "dev": true, 835 | "license": "MIT", 836 | "optional": true, 837 | "os": [ 838 | "win32" 839 | ] 840 | }, 841 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 842 | "version": "4.30.1", 843 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", 844 | "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", 845 | "cpu": [ 846 | "ia32" 847 | ], 848 | "dev": true, 849 | "license": "MIT", 850 | "optional": true, 851 | "os": [ 852 | "win32" 853 | ] 854 | }, 855 | "node_modules/@rollup/rollup-win32-x64-msvc": { 856 | "version": "4.30.1", 857 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", 858 | "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", 859 | "cpu": [ 860 | "x64" 861 | ], 862 | "dev": true, 863 | "license": "MIT", 864 | "optional": true, 865 | "os": [ 866 | "win32" 867 | ] 868 | }, 869 | "node_modules/@rushstack/node-core-library": { 870 | "version": "5.10.2", 871 | "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.2.tgz", 872 | "integrity": "sha512-xOF/2gVJZTfjTxbo4BDj9RtQq/HFnrrKdtem4JkyRLnwsRz2UDTg8gA1/et10fBx5RxmZD9bYVGST69W8ME5OQ==", 873 | "license": "MIT", 874 | "dependencies": { 875 | "ajv": "~8.13.0", 876 | "ajv-draft-04": "~1.0.0", 877 | "ajv-formats": "~3.0.1", 878 | "fs-extra": "~7.0.1", 879 | "import-lazy": "~4.0.0", 880 | "jju": "~1.4.0", 881 | "resolve": "~1.22.1", 882 | "semver": "~7.5.4" 883 | }, 884 | "peerDependencies": { 885 | "@types/node": "*" 886 | }, 887 | "peerDependenciesMeta": { 888 | "@types/node": { 889 | "optional": true 890 | } 891 | } 892 | }, 893 | "node_modules/@rushstack/node-core-library/node_modules/ajv": { 894 | "version": "8.13.0", 895 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", 896 | "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", 897 | "license": "MIT", 898 | "dependencies": { 899 | "fast-deep-equal": "^3.1.3", 900 | "json-schema-traverse": "^1.0.0", 901 | "require-from-string": "^2.0.2", 902 | "uri-js": "^4.4.1" 903 | }, 904 | "funding": { 905 | "type": "github", 906 | "url": "https://github.com/sponsors/epoberezkin" 907 | } 908 | }, 909 | "node_modules/@rushstack/rig-package": { 910 | "version": "0.5.3", 911 | "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", 912 | "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", 913 | "license": "MIT", 914 | "dependencies": { 915 | "resolve": "~1.22.1", 916 | "strip-json-comments": "~3.1.1" 917 | } 918 | }, 919 | "node_modules/@rushstack/terminal": { 920 | "version": "0.14.5", 921 | "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.5.tgz", 922 | "integrity": "sha512-TEOpNwwmsZVrkp0omnuTUTGZRJKTr6n6m4OITiNjkqzLAkcazVpwR1SOtBg6uzpkIBLgrcNHETqI8rbw3uiUfw==", 923 | "license": "MIT", 924 | "dependencies": { 925 | "@rushstack/node-core-library": "5.10.2", 926 | "supports-color": "~8.1.1" 927 | }, 928 | "peerDependencies": { 929 | "@types/node": "*" 930 | }, 931 | "peerDependenciesMeta": { 932 | "@types/node": { 933 | "optional": true 934 | } 935 | } 936 | }, 937 | "node_modules/@rushstack/ts-command-line": { 938 | "version": "4.23.3", 939 | "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.3.tgz", 940 | "integrity": "sha512-HazKL8fv4HMQMzrKJCrOrhyBPPdzk7iajUXgsASwjQ8ROo1cmgyqxt/k9+SdmrNLGE1zATgRqMUH3s/6smbRMA==", 941 | "license": "MIT", 942 | "dependencies": { 943 | "@rushstack/terminal": "0.14.5", 944 | "@types/argparse": "1.0.38", 945 | "argparse": "~1.0.9", 946 | "string-argv": "~0.3.1" 947 | } 948 | }, 949 | "node_modules/@types/argparse": { 950 | "version": "1.0.38", 951 | "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", 952 | "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", 953 | "license": "MIT" 954 | }, 955 | "node_modules/@types/estree": { 956 | "version": "1.0.6", 957 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 958 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 959 | "license": "MIT" 960 | }, 961 | "node_modules/@types/node": { 962 | "version": "22.10.5", 963 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", 964 | "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", 965 | "devOptional": true, 966 | "license": "MIT", 967 | "dependencies": { 968 | "undici-types": "~6.20.0" 969 | } 970 | }, 971 | "node_modules/@volar/language-core": { 972 | "version": "2.4.11", 973 | "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.11.tgz", 974 | "integrity": "sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==", 975 | "license": "MIT", 976 | "dependencies": { 977 | "@volar/source-map": "2.4.11" 978 | } 979 | }, 980 | "node_modules/@volar/source-map": { 981 | "version": "2.4.11", 982 | "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.11.tgz", 983 | "integrity": "sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==", 984 | "license": "MIT" 985 | }, 986 | "node_modules/@volar/typescript": { 987 | "version": "2.4.11", 988 | "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.11.tgz", 989 | "integrity": "sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==", 990 | "license": "MIT", 991 | "dependencies": { 992 | "@volar/language-core": "2.4.11", 993 | "path-browserify": "^1.0.1", 994 | "vscode-uri": "^3.0.8" 995 | } 996 | }, 997 | "node_modules/@vue/compiler-core": { 998 | "version": "3.5.13", 999 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", 1000 | "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", 1001 | "license": "MIT", 1002 | "dependencies": { 1003 | "@babel/parser": "^7.25.3", 1004 | "@vue/shared": "3.5.13", 1005 | "entities": "^4.5.0", 1006 | "estree-walker": "^2.0.2", 1007 | "source-map-js": "^1.2.0" 1008 | } 1009 | }, 1010 | "node_modules/@vue/compiler-dom": { 1011 | "version": "3.5.13", 1012 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", 1013 | "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", 1014 | "license": "MIT", 1015 | "dependencies": { 1016 | "@vue/compiler-core": "3.5.13", 1017 | "@vue/shared": "3.5.13" 1018 | } 1019 | }, 1020 | "node_modules/@vue/compiler-vue2": { 1021 | "version": "2.7.16", 1022 | "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", 1023 | "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", 1024 | "license": "MIT", 1025 | "dependencies": { 1026 | "de-indent": "^1.0.2", 1027 | "he": "^1.2.0" 1028 | } 1029 | }, 1030 | "node_modules/@vue/language-core": { 1031 | "version": "2.2.0", 1032 | "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.0.tgz", 1033 | "integrity": "sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==", 1034 | "license": "MIT", 1035 | "dependencies": { 1036 | "@volar/language-core": "~2.4.11", 1037 | "@vue/compiler-dom": "^3.5.0", 1038 | "@vue/compiler-vue2": "^2.7.16", 1039 | "@vue/shared": "^3.5.0", 1040 | "alien-signals": "^0.4.9", 1041 | "minimatch": "^9.0.3", 1042 | "muggle-string": "^0.4.1", 1043 | "path-browserify": "^1.0.1" 1044 | }, 1045 | "peerDependencies": { 1046 | "typescript": "*" 1047 | }, 1048 | "peerDependenciesMeta": { 1049 | "typescript": { 1050 | "optional": true 1051 | } 1052 | } 1053 | }, 1054 | "node_modules/@vue/language-core/node_modules/brace-expansion": { 1055 | "version": "2.0.1", 1056 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1057 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1058 | "license": "MIT", 1059 | "dependencies": { 1060 | "balanced-match": "^1.0.0" 1061 | } 1062 | }, 1063 | "node_modules/@vue/language-core/node_modules/minimatch": { 1064 | "version": "9.0.5", 1065 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1066 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1067 | "license": "ISC", 1068 | "dependencies": { 1069 | "brace-expansion": "^2.0.1" 1070 | }, 1071 | "engines": { 1072 | "node": ">=16 || 14 >=14.17" 1073 | }, 1074 | "funding": { 1075 | "url": "https://github.com/sponsors/isaacs" 1076 | } 1077 | }, 1078 | "node_modules/@vue/shared": { 1079 | "version": "3.5.13", 1080 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", 1081 | "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", 1082 | "license": "MIT" 1083 | }, 1084 | "node_modules/acorn": { 1085 | "version": "8.14.0", 1086 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 1087 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 1088 | "license": "MIT", 1089 | "bin": { 1090 | "acorn": "bin/acorn" 1091 | }, 1092 | "engines": { 1093 | "node": ">=0.4.0" 1094 | } 1095 | }, 1096 | "node_modules/ajv": { 1097 | "version": "8.12.0", 1098 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", 1099 | "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", 1100 | "license": "MIT", 1101 | "dependencies": { 1102 | "fast-deep-equal": "^3.1.1", 1103 | "json-schema-traverse": "^1.0.0", 1104 | "require-from-string": "^2.0.2", 1105 | "uri-js": "^4.2.2" 1106 | }, 1107 | "funding": { 1108 | "type": "github", 1109 | "url": "https://github.com/sponsors/epoberezkin" 1110 | } 1111 | }, 1112 | "node_modules/ajv-draft-04": { 1113 | "version": "1.0.0", 1114 | "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", 1115 | "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", 1116 | "license": "MIT", 1117 | "peerDependencies": { 1118 | "ajv": "^8.5.0" 1119 | }, 1120 | "peerDependenciesMeta": { 1121 | "ajv": { 1122 | "optional": true 1123 | } 1124 | } 1125 | }, 1126 | "node_modules/ajv-formats": { 1127 | "version": "3.0.1", 1128 | "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", 1129 | "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", 1130 | "license": "MIT", 1131 | "dependencies": { 1132 | "ajv": "^8.0.0" 1133 | }, 1134 | "peerDependencies": { 1135 | "ajv": "^8.0.0" 1136 | }, 1137 | "peerDependenciesMeta": { 1138 | "ajv": { 1139 | "optional": true 1140 | } 1141 | } 1142 | }, 1143 | "node_modules/alien-signals": { 1144 | "version": "0.4.14", 1145 | "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.4.14.tgz", 1146 | "integrity": "sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==", 1147 | "license": "MIT" 1148 | }, 1149 | "node_modules/argparse": { 1150 | "version": "1.0.10", 1151 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 1152 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 1153 | "license": "MIT", 1154 | "dependencies": { 1155 | "sprintf-js": "~1.0.2" 1156 | } 1157 | }, 1158 | "node_modules/balanced-match": { 1159 | "version": "1.0.2", 1160 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1161 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1162 | "license": "MIT" 1163 | }, 1164 | "node_modules/brace-expansion": { 1165 | "version": "1.1.11", 1166 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1167 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1168 | "license": "MIT", 1169 | "dependencies": { 1170 | "balanced-match": "^1.0.0", 1171 | "concat-map": "0.0.1" 1172 | } 1173 | }, 1174 | "node_modules/compare-versions": { 1175 | "version": "6.1.1", 1176 | "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", 1177 | "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", 1178 | "license": "MIT" 1179 | }, 1180 | "node_modules/concat-map": { 1181 | "version": "0.0.1", 1182 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1183 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1184 | "license": "MIT" 1185 | }, 1186 | "node_modules/confbox": { 1187 | "version": "0.1.8", 1188 | "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", 1189 | "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", 1190 | "license": "MIT" 1191 | }, 1192 | "node_modules/de-indent": { 1193 | "version": "1.0.2", 1194 | "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", 1195 | "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", 1196 | "license": "MIT" 1197 | }, 1198 | "node_modules/debug": { 1199 | "version": "4.4.0", 1200 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1201 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1202 | "license": "MIT", 1203 | "dependencies": { 1204 | "ms": "^2.1.3" 1205 | }, 1206 | "engines": { 1207 | "node": ">=6.0" 1208 | }, 1209 | "peerDependenciesMeta": { 1210 | "supports-color": { 1211 | "optional": true 1212 | } 1213 | } 1214 | }, 1215 | "node_modules/entities": { 1216 | "version": "4.5.0", 1217 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 1218 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1219 | "license": "BSD-2-Clause", 1220 | "engines": { 1221 | "node": ">=0.12" 1222 | }, 1223 | "funding": { 1224 | "url": "https://github.com/fb55/entities?sponsor=1" 1225 | } 1226 | }, 1227 | "node_modules/esbuild": { 1228 | "version": "0.24.2", 1229 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", 1230 | "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", 1231 | "devOptional": true, 1232 | "hasInstallScript": true, 1233 | "license": "MIT", 1234 | "bin": { 1235 | "esbuild": "bin/esbuild" 1236 | }, 1237 | "engines": { 1238 | "node": ">=18" 1239 | }, 1240 | "optionalDependencies": { 1241 | "@esbuild/aix-ppc64": "0.24.2", 1242 | "@esbuild/android-arm": "0.24.2", 1243 | "@esbuild/android-arm64": "0.24.2", 1244 | "@esbuild/android-x64": "0.24.2", 1245 | "@esbuild/darwin-arm64": "0.24.2", 1246 | "@esbuild/darwin-x64": "0.24.2", 1247 | "@esbuild/freebsd-arm64": "0.24.2", 1248 | "@esbuild/freebsd-x64": "0.24.2", 1249 | "@esbuild/linux-arm": "0.24.2", 1250 | "@esbuild/linux-arm64": "0.24.2", 1251 | "@esbuild/linux-ia32": "0.24.2", 1252 | "@esbuild/linux-loong64": "0.24.2", 1253 | "@esbuild/linux-mips64el": "0.24.2", 1254 | "@esbuild/linux-ppc64": "0.24.2", 1255 | "@esbuild/linux-riscv64": "0.24.2", 1256 | "@esbuild/linux-s390x": "0.24.2", 1257 | "@esbuild/linux-x64": "0.24.2", 1258 | "@esbuild/netbsd-arm64": "0.24.2", 1259 | "@esbuild/netbsd-x64": "0.24.2", 1260 | "@esbuild/openbsd-arm64": "0.24.2", 1261 | "@esbuild/openbsd-x64": "0.24.2", 1262 | "@esbuild/sunos-x64": "0.24.2", 1263 | "@esbuild/win32-arm64": "0.24.2", 1264 | "@esbuild/win32-ia32": "0.24.2", 1265 | "@esbuild/win32-x64": "0.24.2" 1266 | } 1267 | }, 1268 | "node_modules/estree-walker": { 1269 | "version": "2.0.2", 1270 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1271 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1272 | "license": "MIT" 1273 | }, 1274 | "node_modules/fast-deep-equal": { 1275 | "version": "3.1.3", 1276 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1277 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1278 | "license": "MIT" 1279 | }, 1280 | "node_modules/fs-extra": { 1281 | "version": "7.0.1", 1282 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", 1283 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", 1284 | "license": "MIT", 1285 | "dependencies": { 1286 | "graceful-fs": "^4.1.2", 1287 | "jsonfile": "^4.0.0", 1288 | "universalify": "^0.1.0" 1289 | }, 1290 | "engines": { 1291 | "node": ">=6 <7 || >=8" 1292 | } 1293 | }, 1294 | "node_modules/fsevents": { 1295 | "version": "2.3.3", 1296 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1297 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1298 | "dev": true, 1299 | "hasInstallScript": true, 1300 | "license": "MIT", 1301 | "optional": true, 1302 | "os": [ 1303 | "darwin" 1304 | ], 1305 | "engines": { 1306 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1307 | } 1308 | }, 1309 | "node_modules/function-bind": { 1310 | "version": "1.1.2", 1311 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1312 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1313 | "license": "MIT", 1314 | "funding": { 1315 | "url": "https://github.com/sponsors/ljharb" 1316 | } 1317 | }, 1318 | "node_modules/graceful-fs": { 1319 | "version": "4.2.11", 1320 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1321 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1322 | "license": "ISC" 1323 | }, 1324 | "node_modules/has-flag": { 1325 | "version": "4.0.0", 1326 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1327 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1328 | "license": "MIT", 1329 | "engines": { 1330 | "node": ">=8" 1331 | } 1332 | }, 1333 | "node_modules/hasown": { 1334 | "version": "2.0.2", 1335 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1336 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1337 | "license": "MIT", 1338 | "dependencies": { 1339 | "function-bind": "^1.1.2" 1340 | }, 1341 | "engines": { 1342 | "node": ">= 0.4" 1343 | } 1344 | }, 1345 | "node_modules/he": { 1346 | "version": "1.2.0", 1347 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1348 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1349 | "license": "MIT", 1350 | "bin": { 1351 | "he": "bin/he" 1352 | } 1353 | }, 1354 | "node_modules/import-lazy": { 1355 | "version": "4.0.0", 1356 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", 1357 | "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", 1358 | "license": "MIT", 1359 | "engines": { 1360 | "node": ">=8" 1361 | } 1362 | }, 1363 | "node_modules/is-core-module": { 1364 | "version": "2.16.1", 1365 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 1366 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 1367 | "license": "MIT", 1368 | "dependencies": { 1369 | "hasown": "^2.0.2" 1370 | }, 1371 | "engines": { 1372 | "node": ">= 0.4" 1373 | }, 1374 | "funding": { 1375 | "url": "https://github.com/sponsors/ljharb" 1376 | } 1377 | }, 1378 | "node_modules/jju": { 1379 | "version": "1.4.0", 1380 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 1381 | "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", 1382 | "license": "MIT" 1383 | }, 1384 | "node_modules/json-schema-traverse": { 1385 | "version": "1.0.0", 1386 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 1387 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 1388 | "license": "MIT" 1389 | }, 1390 | "node_modules/jsonfile": { 1391 | "version": "4.0.0", 1392 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1393 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 1394 | "license": "MIT", 1395 | "optionalDependencies": { 1396 | "graceful-fs": "^4.1.6" 1397 | } 1398 | }, 1399 | "node_modules/kolorist": { 1400 | "version": "1.8.0", 1401 | "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", 1402 | "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", 1403 | "license": "MIT" 1404 | }, 1405 | "node_modules/local-pkg": { 1406 | "version": "0.5.1", 1407 | "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", 1408 | "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", 1409 | "license": "MIT", 1410 | "dependencies": { 1411 | "mlly": "^1.7.3", 1412 | "pkg-types": "^1.2.1" 1413 | }, 1414 | "engines": { 1415 | "node": ">=14" 1416 | }, 1417 | "funding": { 1418 | "url": "https://github.com/sponsors/antfu" 1419 | } 1420 | }, 1421 | "node_modules/lodash": { 1422 | "version": "4.17.21", 1423 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1424 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1425 | "license": "MIT" 1426 | }, 1427 | "node_modules/lru-cache": { 1428 | "version": "6.0.0", 1429 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1430 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1431 | "license": "ISC", 1432 | "dependencies": { 1433 | "yallist": "^4.0.0" 1434 | }, 1435 | "engines": { 1436 | "node": ">=10" 1437 | } 1438 | }, 1439 | "node_modules/magic-string": { 1440 | "version": "0.30.17", 1441 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", 1442 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 1443 | "license": "MIT", 1444 | "dependencies": { 1445 | "@jridgewell/sourcemap-codec": "^1.5.0" 1446 | } 1447 | }, 1448 | "node_modules/minimatch": { 1449 | "version": "3.0.8", 1450 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", 1451 | "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", 1452 | "license": "ISC", 1453 | "dependencies": { 1454 | "brace-expansion": "^1.1.7" 1455 | }, 1456 | "engines": { 1457 | "node": "*" 1458 | } 1459 | }, 1460 | "node_modules/mlly": { 1461 | "version": "1.7.3", 1462 | "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz", 1463 | "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==", 1464 | "license": "MIT", 1465 | "dependencies": { 1466 | "acorn": "^8.14.0", 1467 | "pathe": "^1.1.2", 1468 | "pkg-types": "^1.2.1", 1469 | "ufo": "^1.5.4" 1470 | } 1471 | }, 1472 | "node_modules/ms": { 1473 | "version": "2.1.3", 1474 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1475 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1476 | "license": "MIT" 1477 | }, 1478 | "node_modules/muggle-string": { 1479 | "version": "0.4.1", 1480 | "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", 1481 | "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", 1482 | "license": "MIT" 1483 | }, 1484 | "node_modules/nanoid": { 1485 | "version": "3.3.8", 1486 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 1487 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 1488 | "devOptional": true, 1489 | "funding": [ 1490 | { 1491 | "type": "github", 1492 | "url": "https://github.com/sponsors/ai" 1493 | } 1494 | ], 1495 | "license": "MIT", 1496 | "bin": { 1497 | "nanoid": "bin/nanoid.cjs" 1498 | }, 1499 | "engines": { 1500 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1501 | } 1502 | }, 1503 | "node_modules/path-browserify": { 1504 | "version": "1.0.1", 1505 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", 1506 | "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 1507 | "license": "MIT" 1508 | }, 1509 | "node_modules/path-parse": { 1510 | "version": "1.0.7", 1511 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1512 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1513 | "license": "MIT" 1514 | }, 1515 | "node_modules/pathe": { 1516 | "version": "1.1.2", 1517 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", 1518 | "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", 1519 | "license": "MIT" 1520 | }, 1521 | "node_modules/picocolors": { 1522 | "version": "1.1.1", 1523 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1524 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1525 | "devOptional": true, 1526 | "license": "ISC" 1527 | }, 1528 | "node_modules/picomatch": { 1529 | "version": "4.0.2", 1530 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", 1531 | "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", 1532 | "license": "MIT", 1533 | "engines": { 1534 | "node": ">=12" 1535 | }, 1536 | "funding": { 1537 | "url": "https://github.com/sponsors/jonschlinkert" 1538 | } 1539 | }, 1540 | "node_modules/pkg-types": { 1541 | "version": "1.3.0", 1542 | "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.0.tgz", 1543 | "integrity": "sha512-kS7yWjVFCkIw9hqdJBoMxDdzEngmkr5FXeWZZfQ6GoYacjVnsW6l2CcYW/0ThD0vF4LPJgVYnrg4d0uuhwYQbg==", 1544 | "license": "MIT", 1545 | "dependencies": { 1546 | "confbox": "^0.1.8", 1547 | "mlly": "^1.7.3", 1548 | "pathe": "^1.1.2" 1549 | } 1550 | }, 1551 | "node_modules/playwright": { 1552 | "version": "1.49.1", 1553 | "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", 1554 | "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", 1555 | "license": "Apache-2.0", 1556 | "peer": true, 1557 | "dependencies": { 1558 | "playwright-core": "1.49.1" 1559 | }, 1560 | "bin": { 1561 | "playwright": "cli.js" 1562 | }, 1563 | "engines": { 1564 | "node": ">=18" 1565 | }, 1566 | "optionalDependencies": { 1567 | "fsevents": "2.3.2" 1568 | } 1569 | }, 1570 | "node_modules/playwright-core": { 1571 | "version": "1.49.1", 1572 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", 1573 | "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", 1574 | "license": "Apache-2.0", 1575 | "peer": true, 1576 | "bin": { 1577 | "playwright-core": "cli.js" 1578 | }, 1579 | "engines": { 1580 | "node": ">=18" 1581 | } 1582 | }, 1583 | "node_modules/playwright/node_modules/fsevents": { 1584 | "version": "2.3.2", 1585 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1586 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1587 | "hasInstallScript": true, 1588 | "license": "MIT", 1589 | "optional": true, 1590 | "os": [ 1591 | "darwin" 1592 | ], 1593 | "peer": true, 1594 | "engines": { 1595 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1596 | } 1597 | }, 1598 | "node_modules/postcss": { 1599 | "version": "8.4.49", 1600 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", 1601 | "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", 1602 | "devOptional": true, 1603 | "funding": [ 1604 | { 1605 | "type": "opencollective", 1606 | "url": "https://opencollective.com/postcss/" 1607 | }, 1608 | { 1609 | "type": "tidelift", 1610 | "url": "https://tidelift.com/funding/github/npm/postcss" 1611 | }, 1612 | { 1613 | "type": "github", 1614 | "url": "https://github.com/sponsors/ai" 1615 | } 1616 | ], 1617 | "license": "MIT", 1618 | "dependencies": { 1619 | "nanoid": "^3.3.7", 1620 | "picocolors": "^1.1.1", 1621 | "source-map-js": "^1.2.1" 1622 | }, 1623 | "engines": { 1624 | "node": "^10 || ^12 || >=14" 1625 | } 1626 | }, 1627 | "node_modules/punycode": { 1628 | "version": "2.3.1", 1629 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1630 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1631 | "license": "MIT", 1632 | "engines": { 1633 | "node": ">=6" 1634 | } 1635 | }, 1636 | "node_modules/require-from-string": { 1637 | "version": "2.0.2", 1638 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 1639 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 1640 | "license": "MIT", 1641 | "engines": { 1642 | "node": ">=0.10.0" 1643 | } 1644 | }, 1645 | "node_modules/resolve": { 1646 | "version": "1.22.10", 1647 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 1648 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 1649 | "license": "MIT", 1650 | "dependencies": { 1651 | "is-core-module": "^2.16.0", 1652 | "path-parse": "^1.0.7", 1653 | "supports-preserve-symlinks-flag": "^1.0.0" 1654 | }, 1655 | "bin": { 1656 | "resolve": "bin/resolve" 1657 | }, 1658 | "engines": { 1659 | "node": ">= 0.4" 1660 | }, 1661 | "funding": { 1662 | "url": "https://github.com/sponsors/ljharb" 1663 | } 1664 | }, 1665 | "node_modules/rollup": { 1666 | "version": "4.30.1", 1667 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", 1668 | "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", 1669 | "devOptional": true, 1670 | "license": "MIT", 1671 | "dependencies": { 1672 | "@types/estree": "1.0.6" 1673 | }, 1674 | "bin": { 1675 | "rollup": "dist/bin/rollup" 1676 | }, 1677 | "engines": { 1678 | "node": ">=18.0.0", 1679 | "npm": ">=8.0.0" 1680 | }, 1681 | "optionalDependencies": { 1682 | "@rollup/rollup-android-arm-eabi": "4.30.1", 1683 | "@rollup/rollup-android-arm64": "4.30.1", 1684 | "@rollup/rollup-darwin-arm64": "4.30.1", 1685 | "@rollup/rollup-darwin-x64": "4.30.1", 1686 | "@rollup/rollup-freebsd-arm64": "4.30.1", 1687 | "@rollup/rollup-freebsd-x64": "4.30.1", 1688 | "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", 1689 | "@rollup/rollup-linux-arm-musleabihf": "4.30.1", 1690 | "@rollup/rollup-linux-arm64-gnu": "4.30.1", 1691 | "@rollup/rollup-linux-arm64-musl": "4.30.1", 1692 | "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", 1693 | "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", 1694 | "@rollup/rollup-linux-riscv64-gnu": "4.30.1", 1695 | "@rollup/rollup-linux-s390x-gnu": "4.30.1", 1696 | "@rollup/rollup-linux-x64-gnu": "4.30.1", 1697 | "@rollup/rollup-linux-x64-musl": "4.30.1", 1698 | "@rollup/rollup-win32-arm64-msvc": "4.30.1", 1699 | "@rollup/rollup-win32-ia32-msvc": "4.30.1", 1700 | "@rollup/rollup-win32-x64-msvc": "4.30.1", 1701 | "fsevents": "~2.3.2" 1702 | } 1703 | }, 1704 | "node_modules/semver": { 1705 | "version": "7.5.4", 1706 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1707 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1708 | "license": "ISC", 1709 | "dependencies": { 1710 | "lru-cache": "^6.0.0" 1711 | }, 1712 | "bin": { 1713 | "semver": "bin/semver.js" 1714 | }, 1715 | "engines": { 1716 | "node": ">=10" 1717 | } 1718 | }, 1719 | "node_modules/source-map": { 1720 | "version": "0.6.1", 1721 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1722 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1723 | "license": "BSD-3-Clause", 1724 | "engines": { 1725 | "node": ">=0.10.0" 1726 | } 1727 | }, 1728 | "node_modules/source-map-js": { 1729 | "version": "1.2.1", 1730 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 1731 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1732 | "license": "BSD-3-Clause", 1733 | "engines": { 1734 | "node": ">=0.10.0" 1735 | } 1736 | }, 1737 | "node_modules/sprintf-js": { 1738 | "version": "1.0.3", 1739 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1740 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", 1741 | "license": "BSD-3-Clause" 1742 | }, 1743 | "node_modules/string-argv": { 1744 | "version": "0.3.2", 1745 | "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", 1746 | "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", 1747 | "license": "MIT", 1748 | "engines": { 1749 | "node": ">=0.6.19" 1750 | } 1751 | }, 1752 | "node_modules/strip-json-comments": { 1753 | "version": "3.1.1", 1754 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1755 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1756 | "license": "MIT", 1757 | "engines": { 1758 | "node": ">=8" 1759 | }, 1760 | "funding": { 1761 | "url": "https://github.com/sponsors/sindresorhus" 1762 | } 1763 | }, 1764 | "node_modules/supports-color": { 1765 | "version": "8.1.1", 1766 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1767 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1768 | "license": "MIT", 1769 | "dependencies": { 1770 | "has-flag": "^4.0.0" 1771 | }, 1772 | "engines": { 1773 | "node": ">=10" 1774 | }, 1775 | "funding": { 1776 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1777 | } 1778 | }, 1779 | "node_modules/supports-preserve-symlinks-flag": { 1780 | "version": "1.0.0", 1781 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1782 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1783 | "license": "MIT", 1784 | "engines": { 1785 | "node": ">= 0.4" 1786 | }, 1787 | "funding": { 1788 | "url": "https://github.com/sponsors/ljharb" 1789 | } 1790 | }, 1791 | "node_modules/typescript": { 1792 | "version": "5.6.3", 1793 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", 1794 | "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", 1795 | "license": "Apache-2.0", 1796 | "bin": { 1797 | "tsc": "bin/tsc", 1798 | "tsserver": "bin/tsserver" 1799 | }, 1800 | "engines": { 1801 | "node": ">=14.17" 1802 | } 1803 | }, 1804 | "node_modules/ufo": { 1805 | "version": "1.5.4", 1806 | "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", 1807 | "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", 1808 | "license": "MIT" 1809 | }, 1810 | "node_modules/undici-types": { 1811 | "version": "6.20.0", 1812 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 1813 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 1814 | "devOptional": true, 1815 | "license": "MIT" 1816 | }, 1817 | "node_modules/universalify": { 1818 | "version": "0.1.2", 1819 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1820 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1821 | "license": "MIT", 1822 | "engines": { 1823 | "node": ">= 4.0.0" 1824 | } 1825 | }, 1826 | "node_modules/uri-js": { 1827 | "version": "4.4.1", 1828 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1829 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1830 | "license": "BSD-2-Clause", 1831 | "dependencies": { 1832 | "punycode": "^2.1.0" 1833 | } 1834 | }, 1835 | "node_modules/vite": { 1836 | "version": "6.0.7", 1837 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", 1838 | "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", 1839 | "devOptional": true, 1840 | "license": "MIT", 1841 | "dependencies": { 1842 | "esbuild": "^0.24.2", 1843 | "postcss": "^8.4.49", 1844 | "rollup": "^4.23.0" 1845 | }, 1846 | "bin": { 1847 | "vite": "bin/vite.js" 1848 | }, 1849 | "engines": { 1850 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 1851 | }, 1852 | "funding": { 1853 | "url": "https://github.com/vitejs/vite?sponsor=1" 1854 | }, 1855 | "optionalDependencies": { 1856 | "fsevents": "~2.3.3" 1857 | }, 1858 | "peerDependencies": { 1859 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 1860 | "jiti": ">=1.21.0", 1861 | "less": "*", 1862 | "lightningcss": "^1.21.0", 1863 | "sass": "*", 1864 | "sass-embedded": "*", 1865 | "stylus": "*", 1866 | "sugarss": "*", 1867 | "terser": "^5.16.0", 1868 | "tsx": "^4.8.1", 1869 | "yaml": "^2.4.2" 1870 | }, 1871 | "peerDependenciesMeta": { 1872 | "@types/node": { 1873 | "optional": true 1874 | }, 1875 | "jiti": { 1876 | "optional": true 1877 | }, 1878 | "less": { 1879 | "optional": true 1880 | }, 1881 | "lightningcss": { 1882 | "optional": true 1883 | }, 1884 | "sass": { 1885 | "optional": true 1886 | }, 1887 | "sass-embedded": { 1888 | "optional": true 1889 | }, 1890 | "stylus": { 1891 | "optional": true 1892 | }, 1893 | "sugarss": { 1894 | "optional": true 1895 | }, 1896 | "terser": { 1897 | "optional": true 1898 | }, 1899 | "tsx": { 1900 | "optional": true 1901 | }, 1902 | "yaml": { 1903 | "optional": true 1904 | } 1905 | } 1906 | }, 1907 | "node_modules/vite-plugin-dts": { 1908 | "version": "4.5.0", 1909 | "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-4.5.0.tgz", 1910 | "integrity": "sha512-M1lrPTdi7gilLYRZoLmGYnl4fbPryVYsehPN9JgaxjJKTs8/f7tuAlvCCvOLB5gRDQTTKnptBcB0ACsaw2wNLw==", 1911 | "license": "MIT", 1912 | "dependencies": { 1913 | "@microsoft/api-extractor": "^7.49.1", 1914 | "@rollup/pluginutils": "^5.1.4", 1915 | "@volar/typescript": "^2.4.11", 1916 | "@vue/language-core": "2.2.0", 1917 | "compare-versions": "^6.1.1", 1918 | "debug": "^4.4.0", 1919 | "kolorist": "^1.8.0", 1920 | "local-pkg": "^0.5.1", 1921 | "magic-string": "^0.30.17" 1922 | }, 1923 | "peerDependencies": { 1924 | "typescript": "*", 1925 | "vite": "*" 1926 | }, 1927 | "peerDependenciesMeta": { 1928 | "vite": { 1929 | "optional": true 1930 | } 1931 | } 1932 | }, 1933 | "node_modules/vscode-uri": { 1934 | "version": "3.0.8", 1935 | "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", 1936 | "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", 1937 | "license": "MIT" 1938 | }, 1939 | "node_modules/yallist": { 1940 | "version": "4.0.0", 1941 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1942 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 1943 | "license": "ISC" 1944 | } 1945 | } 1946 | } 1947 | -------------------------------------------------------------------------------- /playwright/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@hyvor/laravel-playwright", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "devDependencies": { 11 | "@types/node": "^22.10.5", 12 | "typescript": "~5.6.2", 13 | "vite": "^6.0.5" 14 | }, 15 | "peerDependencies": { 16 | "@playwright/test": "^1.49.1" 17 | }, 18 | "exports": { 19 | ".": { 20 | "types": "./dist/index.d.ts", 21 | "import": "./dist/laravel-playwright.js", 22 | "require": "./dist/laravel-playwright.umd.cjs" 23 | } 24 | }, 25 | "files": [ 26 | "dist" 27 | ], 28 | "dependencies": { 29 | "vite-plugin-dts": "^4.5.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /playwright/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from '@playwright/test'; 2 | 3 | /** 4 | * Read environment variables from file. 5 | * https://github.com/motdotla/dotenv 6 | */ 7 | // import dotenv from 'dotenv'; 8 | // import path from 'path'; 9 | // dotenv.config({ path: path.resolve(__dirname, '.env') }); 10 | 11 | /** 12 | * See https://playwright.dev/docs/test-configuration. 13 | */ 14 | export default defineConfig({ 15 | testDir: './tests', 16 | /* Run tests in files in parallel */ 17 | fullyParallel: true, 18 | /* Fail the build on CI if you accidentally left test.only in the source code. */ 19 | forbidOnly: !!process.env.CI, 20 | /* Retry on CI only */ 21 | retries: process.env.CI ? 2 : 0, 22 | /* Opt out of parallel tests on CI. */ 23 | workers: process.env.CI ? 1 : undefined, 24 | /* Reporter to use. See https://playwright.dev/docs/test-reporters */ 25 | reporter: 'html', 26 | /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ 27 | use: { 28 | /* Base URL to use in actions like `await page.goto('/')`. */ 29 | // baseURL: 'http://127.0.0.1:3000', 30 | 31 | /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ 32 | trace: 'on-first-retry', 33 | 34 | }, 35 | 36 | /* Configure projects for major browsers */ 37 | projects: [ 38 | { 39 | name: 'chromium', 40 | use: { ...devices['Desktop Chrome'] }, 41 | }, 42 | 43 | { 44 | name: 'firefox', 45 | use: { ...devices['Desktop Firefox'] }, 46 | }, 47 | 48 | { 49 | name: 'webkit', 50 | use: { ...devices['Desktop Safari'] }, 51 | }, 52 | 53 | /* Test against mobile viewports. */ 54 | // { 55 | // name: 'Mobile Chrome', 56 | // use: { ...devices['Pixel 5'] }, 57 | // }, 58 | // { 59 | // name: 'Mobile Safari', 60 | // use: { ...devices['iPhone 12'] }, 61 | // }, 62 | 63 | /* Test against branded browsers. */ 64 | // { 65 | // name: 'Microsoft Edge', 66 | // use: { ...devices['Desktop Edge'], channel: 'msedge' }, 67 | // }, 68 | // { 69 | // name: 'Google Chrome', 70 | // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, 71 | // }, 72 | ], 73 | 74 | /* Run your local dev server before starting the tests */ 75 | // webServer: { 76 | // command: 'npm run start', 77 | // url: 'http://127.0.0.1:3000', 78 | // reuseExistingServer: !process.env.CI, 79 | // }, 80 | }); 81 | -------------------------------------------------------------------------------- /playwright/src/index.ts: -------------------------------------------------------------------------------- 1 | import {APIRequestContext, test as playwrightTest} from '@playwright/test'; 2 | 3 | export interface LaravelOptions { 4 | /** 5 | * The base URL to the endpoints 6 | * @default /playwright 7 | */ 8 | laravelBaseUrl: string | undefined; 9 | } 10 | 11 | interface LaravelFixtures { 12 | laravel: Laravel; 13 | } 14 | 15 | export const test = playwrightTest.extend({ 16 | 17 | laravelBaseUrl: [undefined, {option: true}], 18 | 19 | laravel: async ({ laravelBaseUrl, baseURL, request }, use) => { 20 | const baseUrl = laravelBaseUrl || baseURL + '/playwright' 21 | const laravel = new Laravel(baseUrl, request); 22 | await use(laravel); 23 | await laravel.tearDown(); 24 | } 25 | 26 | }) 27 | 28 | export class Laravel { 29 | 30 | constructor( 31 | private baseUrl: string, 32 | private request: APIRequestContext 33 | ) {} 34 | 35 | async call(endpoint: string, data: object = {}) : Promise { 36 | const url = this.baseUrl.replace(/\/$/, '') + endpoint; 37 | const response = await this.request.post(url, {data}); 38 | if (response.status() !== 200) { 39 | throw new Error(` 40 | Failed to call Laravel ${endpoint}. 41 | Status: ${response.status()} 42 | Response: ${await response.text()} 43 | `); 44 | } 45 | 46 | return await response.json(); 47 | } 48 | 49 | async artisan(command: string, parameters: string[] = []) { 50 | return await this.call<{code: number, output: string}>('/artisan', {command, parameters}); 51 | } 52 | 53 | async truncate(connections: (string|null)[] = []) { 54 | return await this.call('/truncate', {connections}); 55 | } 56 | 57 | async factory( 58 | model: string, 59 | attrs: any = {}, 60 | count: CountT = undefined as CountT 61 | ) { 62 | return await this.call : Record[]>('/factory', {model, count, attrs}); 63 | } 64 | 65 | async query( 66 | query: string, 67 | bindings: Array = [], 68 | options: { 69 | connection?: string | null, 70 | unprepared?: boolean 71 | } = {} 72 | ) { 73 | 74 | const { connection = null, unprepared = false } = options; 75 | 76 | if (unprepared && bindings.length > 0) { 77 | throw new Error('Cannot use unprepared with bindings'); 78 | } 79 | 80 | return await this.call<{ 81 | success: boolean 82 | }>('/query', { 83 | query, 84 | bindings, 85 | connection, 86 | unprepared 87 | }); 88 | 89 | } 90 | 91 | async select( 92 | query: string, 93 | bindings: Record = {}, 94 | options: { 95 | connection?: string | null, 96 | unprepared?: boolean 97 | } = {} 98 | ) { 99 | const { connection = null } = options; 100 | return await this.call[]>('/select', {query, bindings, connection}); 101 | } 102 | 103 | async callFunction(func: string, args: any[]|Record = []) { 104 | return await this.call('/function', {function: func, args}); 105 | } 106 | 107 | /** 108 | * Sets a laravel config value until tearDown is called (or the test ends) 109 | */ 110 | async config(key: string, value: any) { 111 | return await this.call('/dynamicConfig', {key, value}); 112 | } 113 | 114 | /** 115 | * Travel to a specific time 116 | * ex: travel('2021-01-01 00:00:00') 117 | */ 118 | async travel(to: string) { 119 | return await this.call('/travel', {to}); 120 | } 121 | 122 | async registerBootFunction(func: string) { 123 | return await this.call('/registerBootFunction', {function: func}); 124 | } 125 | 126 | async tearDown() { 127 | return await this.call('/tearDown'); 128 | } 129 | 130 | } -------------------------------------------------------------------------------- /playwright/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /playwright/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { defineConfig } from 'vite' 3 | import dts from 'vite-plugin-dts' 4 | 5 | export default defineConfig({ 6 | build: { 7 | lib: { 8 | entry: resolve(__dirname, 'src/index.ts'), 9 | name: 'laravel-playwright', 10 | // fileName: 'laravel-playwright', 11 | }, 12 | rollupOptions: { 13 | // make sure to externalize deps that shouldn't be bundled 14 | // into your library 15 | external: ['@playwright/test'], 16 | // output: { 17 | // // Provide global variables to use in the UMD build 18 | // // for externalized deps 19 | // globals: { 20 | // vue: 'Vue', 21 | // }, 22 | // }, 23 | }, 24 | }, 25 | plugins: [dts()] 26 | }) -------------------------------------------------------------------------------- /src/Controller.php: -------------------------------------------------------------------------------- 1 | string('command'); 22 | $parameters = (array) $request->input('parameters'); 23 | 24 | $exitCode = Artisan::call($command, $parameters); 25 | 26 | return Response::json([ 27 | 'code' => $exitCode, 28 | 'output' => Artisan::output(), 29 | ]); 30 | 31 | } 32 | 33 | public function truncate(Request $request) : JsonResponse 34 | { 35 | 36 | $request->validate([ 37 | 'connections' => 'nullable|array', 38 | 'connections.*' => 'nullable|string' 39 | ]); 40 | 41 | /** @var array $connections */ 42 | $connections = $request->input('connections') ?? [null]; 43 | 44 | $truncate = new Services\Truncate(); 45 | $truncate->truncate($connections); 46 | 47 | return Response::json(); 48 | 49 | } 50 | 51 | public function factory(Request $request) : JsonResponse 52 | { 53 | 54 | $request->validate([ 55 | 'model' => 'string|required', 56 | 'count' => 'nullable|integer', 57 | 'attrs' => 'array', 58 | ]); 59 | 60 | $modelClass = (string) $request->string('model'); 61 | $count = $request->has('count') ? $request->integer('count') : null; 62 | /** @var array $attrs */ 63 | $attrs = (array) $request->input('attrs'); 64 | 65 | if (!class_exists($modelClass)) { 66 | $modelClass = 'App\\Models\\' . $modelClass; 67 | } 68 | 69 | if (!class_exists($modelClass)) { 70 | abort(422, 'Model not found'); 71 | } 72 | 73 | $model = app($modelClass); 74 | 75 | if (!$model instanceof Model) { 76 | abort(422, 'Model not found'); 77 | } 78 | 79 | if (!method_exists($model, 'factory')) { 80 | abort(422, 'Model factory not found'); 81 | } 82 | 83 | /** @var Factory $modelFactory */ 84 | $modelFactory = $model->factory(); 85 | 86 | if ($count !== null) { 87 | $modelFactory = $modelFactory->count($count); 88 | } 89 | 90 | $models = $modelFactory->create($attrs); 91 | 92 | return Response::json($models); 93 | 94 | } 95 | 96 | public function query(Request $request) : JsonResponse 97 | { 98 | 99 | $request->validate([ 100 | 'connection' => 'nullable|string', 101 | 'query' => 'string|required', 102 | 'bindings' => 'array', 103 | 'unprepared' => 'boolean' 104 | ]); 105 | 106 | $connection = $request->has('connection') ? 107 | (string) $request->string('connection') : 108 | null; 109 | $query = (string) $request->string('query'); 110 | /** @var array $bindings */ 111 | $bindings = $request->input('bindings', []); 112 | $unprepared = $request->boolean('unprepared'); 113 | 114 | $connection = DB::connection($connection); 115 | $success = $unprepared ? 116 | $connection->unprepared($query) : 117 | $connection->statement($query, $bindings); 118 | 119 | return Response::json([ 120 | 'success' => $success 121 | ]); 122 | 123 | } 124 | 125 | public function select(Request $request) : JsonResponse 126 | { 127 | 128 | $request->validate([ 129 | 'connection' => 'nullable|string', 130 | 'query' => 'string|required', 131 | 'bindings' => 'array', 132 | ]); 133 | 134 | $connection = $request->has('connection') ? 135 | (string) $request->string('connection') : 136 | null; 137 | $query = (string) $request->string('query'); 138 | /** @var array $bindings */ 139 | $bindings = $request->input('bindings', []); 140 | 141 | $results = DB::connection($connection)->select($query, $bindings); 142 | 143 | return Response::json($results); 144 | 145 | } 146 | 147 | public function function(Request $request) : JsonResponse 148 | { 149 | 150 | $request->validate([ 151 | 'function' => 'string|required', 152 | 'args' => 'array' 153 | ]); 154 | 155 | $function = (string) $request->string('function'); 156 | /** @var array $args */ 157 | $args = $request->input('args', []); 158 | 159 | if (!is_callable($function)) 160 | abort(422, 'Function does not exist'); 161 | 162 | $response = call_user_func_array($function, $args); 163 | return Response::json($response); 164 | 165 | } 166 | 167 | public function dynamicConfig(Request $request) : JsonResponse 168 | { 169 | 170 | $request->validate([ 171 | 'key' => 'string|required', 172 | 'value' => 'required', 173 | ]); 174 | 175 | $key = (string) $request->string('key'); 176 | $value = $request->input('value'); 177 | 178 | DynamicConfig::set($key, $value); 179 | 180 | return Response::json(); 181 | } 182 | 183 | public function registerBootFunction(Request $request) : JsonResponse 184 | { 185 | 186 | $request->validate([ 187 | 'function' => 'string|required', 188 | ]); 189 | 190 | $function = (string) $request->string('function'); 191 | 192 | if (!is_callable($function)) 193 | abort(422, 'Function is not callable'); 194 | 195 | $currentBootFunctions = DynamicConfig::get(DynamicConfig::KEY_BOOT_FUNCTIONS, []); 196 | assert(is_array($currentBootFunctions)); 197 | $currentBootFunctions[] = $function; 198 | 199 | DynamicConfig::set(DynamicConfig::KEY_BOOT_FUNCTIONS, $currentBootFunctions); 200 | 201 | return Response::json(); 202 | 203 | } 204 | 205 | public function travel(Request $request, DynamicConfig $dynamicConfig) : JsonResponse 206 | { 207 | 208 | $request->validate([ 209 | 'to' => 'string|required', 210 | ]); 211 | 212 | $to = (string) $request->string('to'); 213 | 214 | try { 215 | Carbon::parse($to); 216 | } catch (\Exception $e) { 217 | abort(422, 'Invalid date'); 218 | } 219 | 220 | DynamicConfig::set(DynamicConfig::KEY_TRAVEL, $to); 221 | 222 | return Response::json(); 223 | 224 | } 225 | 226 | public function tearDown(DynamicConfig $dynamicConfig) : JsonResponse 227 | { 228 | $dynamicConfig->delete(); 229 | 230 | return Response::json(); 231 | } 232 | 233 | 234 | } -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadRoutesFrom(__DIR__ . '/routes/e2e.php'); 18 | 19 | /** @var DynamicConfig $dynamicConfig */ 20 | $dynamicConfig = app(DynamicConfig::class); 21 | $dynamicConfig->load(); 22 | } 23 | 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/Services/Config.php: -------------------------------------------------------------------------------- 1 | $value) { 40 | assert(is_string($key)); 41 | config([$key => $value]); 42 | } 43 | 44 | self::loadTime(); 45 | self::loadBootFunctions(); 46 | } 47 | 48 | } 49 | 50 | private static function loadTime(): void 51 | { 52 | $time = self::get(self::KEY_TRAVEL); 53 | if (!is_string($time)) { 54 | return; 55 | } 56 | $time = Carbon::parse($time); 57 | \Carbon\Carbon::setTestNow($time); 58 | \Carbon\CarbonImmutable::setTestNow($time); 59 | } 60 | 61 | private static function loadBootFunctions(): void 62 | { 63 | 64 | $functions = self::get(self::KEY_BOOT_FUNCTIONS); 65 | if (!is_array($functions)) { 66 | return; 67 | } 68 | 69 | foreach ($functions as $function) { 70 | if (is_callable($function)) { 71 | $function(); 72 | } 73 | } 74 | 75 | } 76 | 77 | public static function set(string $key, mixed $value): void 78 | { 79 | $file = self::getFilePath(); 80 | $data = self::getAll(); 81 | $data[$key] = $value; 82 | file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT)); 83 | } 84 | 85 | public static function get(string $key, mixed $default = null): mixed 86 | { 87 | $data = self::getAll(); 88 | return $data[$key] ?? $default; 89 | } 90 | 91 | /** 92 | * @return array 93 | */ 94 | public static function getAll(): array 95 | { 96 | $file = self::getFilePath(); 97 | if (!file_exists($file)) { 98 | return []; 99 | } 100 | /** @var array $json */ 101 | $json = json_decode((string) file_get_contents($file), true); 102 | return $json; 103 | } 104 | 105 | public static function delete(): void 106 | { 107 | $file = self::getFilePath(); 108 | if (file_exists($file)) { 109 | unlink($file); 110 | } 111 | } 112 | 113 | } -------------------------------------------------------------------------------- /src/Services/Truncate.php: -------------------------------------------------------------------------------- 1 | $connections 13 | */ 14 | public function truncate(array $connections = [null]) : void 15 | { 16 | 17 | foreach ($connections as $connection) { 18 | $this->truncateTablesOfConnection($connection); 19 | } 20 | 21 | } 22 | 23 | private function truncateTablesOfConnection(?string $connection) : void 24 | { 25 | 26 | /** @var string[] $tables */ 27 | $tables = Schema::connection($connection)->getTableListing(); 28 | Schema::disableForeignKeyConstraints(); 29 | 30 | foreach ($tables as $table) { 31 | DB::table($table)->truncate(); 32 | } 33 | 34 | Schema::enableForeignKeyConstraints(); 35 | 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/routes/e2e.php: -------------------------------------------------------------------------------- 1 | group(function () { 9 | 10 | Route::post('artisan', [Controller::class, 'artisan']); 11 | Route::post('truncate', [Controller::class, 'truncate']); 12 | Route::post('factory', [Controller::class, 'factory']); 13 | Route::post('query', [Controller::class, 'query']); 14 | Route::post('select', [Controller::class, 'select']); 15 | Route::post('function', [Controller::class, 'function']); 16 | Route::post('dynamicConfig', [Controller::class, 'dynamicConfig']); 17 | Route::post('travel', [Controller::class, 'travel']); 18 | Route::post('registerBootFunction', [Controller::class, 'registerBootFunction']); 19 | 20 | Route::post('tearDown', [Controller::class, 'tearDown']); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /tests/Feature/ArtisanTest.php: -------------------------------------------------------------------------------- 1 | $json */ 14 | $json = $this->post('playwright/artisan', [ 15 | 'command' => 'route:list' 16 | ]) 17 | ->assertOk() 18 | ->json(); 19 | 20 | $this->assertEquals(0, $json['code']); 21 | $this->assertStringContainsString('playwright/artisan', (string) $json['output']); 22 | 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /tests/Feature/DynamicConfigTest.php: -------------------------------------------------------------------------------- 1 | postJson('/playwright/dynamicConfig', [ 14 | 'key' => 'test_key', 15 | 'value' => 'test_value', 16 | ])->assertOk(); 17 | 18 | $file = storage_path('laravel-playwright-config.json'); 19 | $this->assertTrue(file_exists($file)); 20 | $content= (string) file_get_contents($file); 21 | 22 | $json = json_decode($content, true); 23 | 24 | $this->assertIsArray($json); 25 | $this->assertArrayHasKey('test_key', $json); 26 | $this->assertEquals('test_value', $json['test_key']); 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /tests/Feature/FactoryTest.php: -------------------------------------------------------------------------------- 1 | postJson('playwright/factory', [ 15 | 'model' => '\Hyvor\LaravelPlaywright\Tests\Helpers\UserModel', 16 | 'attrs' => [ 17 | 'name' => 'John Doe', 18 | ] 19 | ]) 20 | ->assertOk() 21 | ->assertJsonPath('name', 'John Doe'); 22 | 23 | $this->assertEquals(1, UserModel::count()); 24 | 25 | } 26 | 27 | public function testCreatesModelFromFactoryWithCount(): void 28 | { 29 | 30 | $this->postJson('playwright/factory', [ 31 | 'model' => '\Hyvor\LaravelPlaywright\Tests\Helpers\UserModel', 32 | 'count' => 3 33 | ]) 34 | ->assertOk() 35 | ->assertJsonCount(3); 36 | 37 | $this->assertEquals(3, UserModel::count()); 38 | 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /tests/Feature/FunctionTest.php: -------------------------------------------------------------------------------- 1 | postJson('/playwright/function', [ 19 | 'function' => 'testFunction1' 20 | ]) 21 | ->assertOk() 22 | ->assertSee('Hello'); 23 | } 24 | 25 | public function testCallsAFunctionWithArgs() : void 26 | { 27 | $this->postJson('/playwright/function', [ 28 | 'function' => 'testFunction2', 29 | 'args' => ['Supun'] 30 | ]) 31 | ->assertOk() 32 | ->assertSee('Hello Supun'); 33 | } 34 | 35 | public function testCallsAFunctionWithNamedArgs() : void 36 | { 37 | $this->postJson('/playwright/function', [ 38 | 'function' => 'testFunction3', 39 | 'args' => [ 40 | 'age' => 24, 41 | 'name' => 'Supun' 42 | ] 43 | ]) 44 | ->assertOk() 45 | ->assertSee('Hello Supun. You are 24'); 46 | } 47 | 48 | public function testCallsAStaticMethod() : void 49 | { 50 | $this->postJson('/playwright/function', [ 51 | 'function' => 'testStaticMethodClass1::sayHello', 52 | 'args' => ['me'] 53 | ]) 54 | ->assertOk() 55 | ->assertSee('Says Hello to me'); 56 | } 57 | 58 | public function testCallsAStaticMethodWithNamespace() : void 59 | { 60 | $this->postJson('/playwright/function', [ 61 | 'function' => 'Hyvor\LaravelPlaywright\Tests\Helpers\TestableStaticMethod::ping', 62 | ]) 63 | ->assertOk() 64 | ->assertSee('pong'); 65 | 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /tests/Feature/QueryTest.php: -------------------------------------------------------------------------------- 1 | count(3) 15 | ->create(); 16 | 17 | $this->postJson('/playwright/query', [ 18 | 'query' => "update users set name = 'John Doe' where id = " . $users[0]?->id 19 | ])->assertOk(); 20 | 21 | $this->assertEquals('John Doe', $users[0]?->refresh()->name); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /tests/Feature/RegisterBootFunctionTest.php: -------------------------------------------------------------------------------- 1 | postJson('/playwright/registerBootFunction', [ 14 | 'function' => 'Hyvor\LaravelPlaywright\Tests\Feature\RegisterBootFunctionTest::setGlobalVariable', 15 | ]) 16 | ->assertOk(); 17 | 18 | $this->reloadApplication(); 19 | $this->assertEquals('Yes', $GLOBALS['bootRunning']); 20 | 21 | } 22 | 23 | /** 24 | * This is called via the service container for testing purposes from the above test 25 | */ 26 | public static function setGlobalVariable(): void 27 | { 28 | $GLOBALS['bootRunning'] = 'Yes'; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /tests/Feature/RouteEnvTest.php: -------------------------------------------------------------------------------- 1 | post('playwright/truncate')->assertOk(); 16 | 17 | assert($this->app !== null); 18 | 19 | $this->app->detectEnvironment(fn() => 'production'); 20 | $this->app->register(ServiceProvider::class, true); 21 | $this->app['env'] = 'production'; // @phpstan-ignore-line 22 | 23 | Route::setRoutes(new RouteCollection()); 24 | (new ServiceProvider($this->app))->boot(); 25 | $this->post('playwright/artisan')->assertNotFound(); 26 | } 27 | 28 | public function testSupportsCustomPrefix(): void 29 | { 30 | config(['app.e2e.prefix' => 'api/e2e']); 31 | 32 | assert($this->app !== null); 33 | 34 | Route::setRoutes(new RouteCollection()); 35 | (new ServiceProvider($this->app))->boot(); 36 | 37 | $this->post('playwright/truncate')->assertNotFound(); 38 | $this->post('api/e2e/truncate')->assertOk(); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /tests/Feature/SelectTest.php: -------------------------------------------------------------------------------- 1 | create(); 13 | 14 | $response = $this->postJson('/playwright/select', [ 15 | 'query' => 'select * from users where id = ' . $user->id 16 | ]); 17 | 18 | $response->assertOk(); 19 | $response->assertJsonPath('0.id', $user->id); 20 | } 21 | } -------------------------------------------------------------------------------- /tests/Feature/TeadDownTest.php: -------------------------------------------------------------------------------- 1 | $data */ 18 | $data = @json_decode($content, true); 19 | $this->assertEquals(true, $data['myconfig']); 20 | 21 | $this->postJson('/playwright/tearDown')->assertOk(); 22 | 23 | $this->assertFileDoesNotExist(storage_path('laravel-playwright-config.json')); 24 | 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /tests/Feature/TravelTest.php: -------------------------------------------------------------------------------- 1 | postJson('/playwright/travel', [ 14 | 'to' => '2025-01-01', 15 | ])->assertOk(); 16 | 17 | $this->reloadApplication(); 18 | $this->assertEquals('2025-01-01', now()->format('Y-m-d')); 19 | 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /tests/Feature/TruncateTest.php: -------------------------------------------------------------------------------- 1 | count(3)->create(); 13 | $this->assertCount(3, UserModel::all()); 14 | 15 | $this->postJson('/playwright/truncate'); 16 | 17 | $this->assertCount(0, UserModel::all()); 18 | } 19 | } -------------------------------------------------------------------------------- /tests/Feature/functions.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class UserFactory extends Factory 11 | { 12 | 13 | protected $model = UserModel::class; 14 | 15 | public function definition() 16 | { 17 | return [ 18 | 'name' => $this->faker->name, 19 | ]; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /tests/Helpers/UserModel.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | use HasFactory; 21 | 22 | protected $table = 'users'; 23 | 24 | public static function newFactory(): UserFactory 25 | { 26 | return new UserFactory(); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 |