diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index cdbb1dffd91..00000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,82 +0,0 @@
-const DOMGlobals = ['window', 'document']
-const NodeGlobals = ['module', 'require']
-
-module.exports = {
- parser: '@typescript-eslint/parser',
- parserOptions: {
- sourceType: 'module'
- },
- plugins: ["jest"],
- rules: {
- 'no-debugger': 'error',
- 'no-unused-vars': [
- 'error',
- // we are only using this rule to check for unused arguments since TS
- // catches unused variables but not args.
- { varsIgnorePattern: '.*', args: 'none' }
- ],
- // most of the codebase are expected to be env agnostic
- 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals],
- // since we target ES2015 for baseline support, we need to forbid object
- // rest spread usage in destructure as it compiles into a verbose helper.
- // TS now compiles assignment spread into Object.assign() calls so that
- // is allowed.
- 'no-restricted-syntax': [
- 'error',
- 'ObjectPattern > RestElement',
- 'AwaitExpression'
- ]
- },
- overrides: [
- // tests, no restrictions (runs in Node / jest with jsdom)
- {
- files: ['**/__tests__/**', 'test-dts/**'],
- rules: {
- 'no-restricted-globals': 'off',
- 'no-restricted-syntax': 'off',
- 'jest/no-disabled-tests': 'error',
- 'jest/no-focused-tests': 'error'
- }
- },
- // shared, may be used in any env
- {
- files: ['packages/shared/**'],
- rules: {
- 'no-restricted-globals': 'off'
- }
- },
- // Packages targeting DOM
- {
- files: ['packages/{vue,vue-compat,runtime-dom}/**'],
- rules: {
- 'no-restricted-globals': ['error', ...NodeGlobals]
- }
- },
- // Packages targeting Node
- {
- files: [
- 'packages/{compiler-sfc,compiler-ssr,server-renderer,reactivity-transform}/**'
- ],
- rules: {
- 'no-restricted-globals': ['error', ...DOMGlobals],
- 'no-restricted-syntax': 'off'
- }
- },
- // Private package, browser only + no syntax restrictions
- {
- files: ['packages/template-explorer/**', 'packages/sfc-playground/**'],
- rules: {
- 'no-restricted-globals': ['error', ...NodeGlobals],
- 'no-restricted-syntax': 'off'
- }
- },
- // Node scripts
- {
- files: ['scripts/**', './*.js', 'packages/**/index.js', 'packages/size-check/**'],
- rules: {
- 'no-restricted-globals': 'off',
- 'no-restricted-syntax': 'off'
- }
- }
- ]
-}
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 00000000000..d06b03a3f89
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,2 @@
+# update prettier & eslint config (#9162)
+bfe6b459d3a0ce6168611ee1ac7e6e789709df9d
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 11853cec30c..95e0ca79c07 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -28,7 +28,7 @@ body:
attributes:
label: Link to minimal reproduction
description: |
- The easiest way to provide a reproduction is by showing the bug in [The SFC Playground](https://sfc.vuejs.org/).
+ The easiest way to provide a reproduction is by showing the bug in [The SFC Playground](https://play.vuejs.org/).
If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue).
If neither of these are suitable, you can always provide a GitHub repository.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index af3782c8422..02f99c6bfbb 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
+ - name: Feature Request
+ url: https://github.com/vuejs/rfcs/discussions
+ about: Suggest new features for consideration
- name: Discord Chat
url: https://chat.vuejs.org
about: Ask questions and discuss with other Vue users in real time.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
deleted file mode 100644
index 9165eb4d291..00000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-name: "\U0001F680 New feature proposal"
-description: Suggest an idea for this project
-labels: [":sparkles: feature request"]
-body:
- - type: markdown
- attributes:
- value: |
- **Before You Start...**
-
- This form is only for submitting feature requests. If you have a usage question
- or are unsure if this is really a bug, make sure to:
-
- - Read the [docs](https://vuejs.org/)
- - Ask on [Discord Chat](https://chat.vuejs.org/)
- - Ask on [GitHub Discussions](https://github.com/vuejs/core/discussions)
- - Look for / ask questions on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=vue.js)
-
- Also try to search for your issue - another user may have already requested something similar!
-
- - type: textarea
- id: problem-description
- attributes:
- label: What problem does this feature solve?
- description: |
- Explain your use case, context, and rationale behind this feature request. More importantly, what is the **end user experience** you are trying to build that led to the need for this feature?
-
- An important design goal of Vue is keeping the API surface small and straightforward. In general, we only consider adding new features that solve a problem that cannot be easily dealt with using existing APIs (i.e. not just an alternative way of doing things that can already be done). The problem should also be common enough to justify the addition.
- placeholder: Problem description
- validations:
- required: true
- - type: textarea
- id: proposed-API
- attributes:
- label: What does the proposed API look like?
- description: |
- Describe how you propose to solve the problem and provide code samples of how the API would work once implemented. Note that you can use [Markdown](https://guides.github.com/features/mastering-markdown/) to format your code blocks.
- placeholder: Steps to reproduce
- validations:
- required: true
diff --git a/.github/bug-repro-guidelines.md b/.github/bug-repro-guidelines.md
index 19e9a7e2f26..90458b30741 100644
--- a/.github/bug-repro-guidelines.md
+++ b/.github/bug-repro-guidelines.md
@@ -22,7 +22,7 @@ A minimal reproduction means it demonstrates the bug, and the bug only. It shoul
### How to create a repro
-For Vue 3 core reproductions, try reproducing it in [The SFC Playground](https://sfc.vuejs.org/).
+For Vue 3 core reproductions, try reproducing it in [The SFC Playground](https://play.vuejs.org/).
If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue).
diff --git a/.github/commit-convention.md b/.github/commit-convention.md
index a8522fa210a..11a64576a24 100644
--- a/.github/commit-convention.md
+++ b/.github/commit-convention.md
@@ -6,7 +6,7 @@
Messages must be matched by the following regex:
-``` js
+```regexp
/^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip)(\(.+\))?: .{1,50}/
```
@@ -44,7 +44,7 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
### Full Message Format
-A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
+A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
```
():
@@ -74,9 +74,9 @@ The scope could be anything specifying the place of the commit change. For examp
The subject contains a succinct description of the change:
-* use the imperative, present tense: "change" not "changed" nor "changes"
-* don't capitalize the first letter
-* no dot (.) at the end
+- use the imperative, present tense: "change" not "changed" nor "changes"
+- don't capitalize the first letter
+- no dot (.) at the end
### Body
diff --git a/.github/contributing.md b/.github/contributing.md
index f7b20da2690..2554582b887 100644
--- a/.github/contributing.md
+++ b/.github/contributing.md
@@ -17,7 +17,31 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before
## Pull Request Guidelines
-- Checkout a topic branch from a base branch, e.g. `main`, and merge back against that branch.
+### What kinds of Pull Requests are accepted?
+
+- Bug fix that addresses a clearly identified bug. **"Clearly identified bug"** means the bug has a proper reproduction either from a related open issue, or is included in the PR itself. Avoid submitting PRs that claim to fix something but do not sufficiently explain what is being fixed.
+
+- New feature that addresses a clearly explained and widely applicable use case. **"Widely applicable"** means the new feature should provide non-trivial improvements to the majority of the user base. Vue already has a large API surface so we are quite cautious about adding new features - if the use case is niche and can be addressed via userland implementations, it likely isn't suitable to go into core.
+
+ The feature implementation should also consider the trade-off between the added complexity vs. the benefits gained. For example, if a small feature requires significant changes that spreads across the codebase, it is likely not worth it, or the approach should be reconsidered.
+
+ If the feature has a non-trivial API surface addition, or significantly affects the way a common use case is approached by the users, it should go through a discussion first in the [RFC repo](https://github.com/vuejs/rfcs/discussions). PRs of such features without prior discussion make it really difficult to steer / adjust the API design due to coupling with concrete implementations, and can lead to wasted work.
+
+- Chore: typos, comment improvements, build config, CI config, etc. For typos and comment changes, try to combine multiple of them into a single PR.
+
+- **It should be noted that we discourage contributors from submitting code refactors that are largely stylistic.** Code refactors are only accepted if it improves performance, or comes with sufficient explanations on why it objectively improves the code quality (e.g. makes a related feature implementation easier).
+
+ The reason is that code readability is subjective. The maintainers of this project have chosen to write the code in its current style based on our preferences, and we do not want to spend time explaining our stylistic preferences. Contributors should just respect the established conventions when contributing code.
+
+ Another aspect of it is that large scale stylistic changes result in massive diffs that touch multiple files, adding noise to the git history and makes tracing behavior changes across commits more cumbersome.
+
+### Pull Request Checklist
+
+- Vue core has two primary work branches: `main` and `minor`.
+
+ - If your pull request is a feature that adds new API surface, it should be submitted against the `minor` branch.
+
+ - Otherwise, it should be submitted against the `main` branch.
- [Make sure to tick the "Allow edits from maintainers" box](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork). This allows us to directly make minor edits / refactors and saves a lot of time.
@@ -30,7 +54,7 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before
- If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`.
- Provide a detailed description of the bug in the PR. Live demo preferred.
- - Add appropriate test coverage if applicable. You can check the coverage of your code addition by running `npm test -- --coverage`.
+ - Add appropriate test coverage if applicable. You can check the coverage of your code addition by running `nr test-coverage`.
- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging.
@@ -57,9 +81,9 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before
## Development Setup
-You will need [Node.js](https://nodejs.org) **version 16+**, and [PNPM](https://pnpm.io) **version 7+**.
+You will need [Node.js](https://nodejs.org) with minimum version as specified in the [`.node-version`](https://github.com/vuejs/core/blob/main/.node-version) file, and [PNPM](https://pnpm.io) with minimum version as specified in the [`"packageManager"` field in `package.json`](https://github.com/vuejs/core/blob/main/package.json#L4).
-We also recommend installing [ni](https://github.com/antfu/ni) to help switching between repos using different package managers. `ni` also provides the handy `nr` command which running npm scripts easier.
+We also recommend installing [@antfu/ni](https://github.com/antfu/ni) to help switching between repos using different package managers. `ni` also provides the handy `nr` command which running npm scripts easier.
After cloning the repo, run:
@@ -70,16 +94,36 @@ $ pnpm i # install the dependencies of the project
A high level overview of tools used:
- [TypeScript](https://www.typescriptlang.org/) as the development language
-- [Rollup](https://rollupjs.org) for bundling
-- [Jest](https://jestjs.io/) for unit testing
+- [Vite](https://vitejs.dev/) and [ESBuild](https://esbuild.github.io/) for development bundling
+- [Rollup](https://rollupjs.org) for production bundling
+- [Vitest](https://vitest.dev/) for unit testing
- [Prettier](https://prettier.io/) for code formatting
+- [ESLint](https://eslint.org/) for static error prevention (outside of types)
+
+## Git Hooks
+
+The project uses [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks) to enforce the following on each commit:
+
+- Type check the entire project
+- Automatically format changed files using Prettier
+- Verify commit message format (logic in `scripts/verify-commit.js`)
## Scripts
-**The examples below will be using the `nr` command from the [ni](https://github.com/antfu/ni) package.** You can also use plain `npm run`, but you will need to pass all additional arguments after the command after an extra `--`. For example, `nr build runtime --all` is equivalent to `npm run build -- runtime --all`.
+**The examples below will be using the `nr` command from the [@antfu/ni](https://github.com/antfu/ni) package.** You can also use plain `npm run`, but you will need to pass all additional arguments after the command after an extra `--`. For example, `nr build runtime --all` is equivalent to `npm run build -- runtime --all`.
The `run-s` and `run-p` commands found in some scripts are from [npm-run-all](https://github.com/mysticatea/npm-run-all) for orchestrating multiple scripts. `run-s` means "run in sequence" while `run-p` means "run in parallel".
+- [`nr build`](#nr-build)
+- [`nr build-dts`](#nr-build-dts)
+- [`nr check`](#nr-check)
+- [`nr dev`](#nr-dev)
+- [`nr dev-sfc`](#nr-dev-sfc)
+- [`nr dev-esm`](#nr-dev-esm)
+- [`nr dev-compiler`](#nr-dev-compiler)
+- [`nr test`](#nr-test)
+- [`nr test-dts`](#nr-test-dts)
+
### `nr build`
The `build` script builds all public packages (packages without `private: true` in their `package.json`).
@@ -94,6 +138,8 @@ nr build runtime-core
nr build runtime --all
```
+Note that `nr build` uses `rollup-plugin-esbuild` for transpiling typescript and **does not perform type checking**. To run type check on the entire codebase, run `nr check`. Type checks are also automatically run on each commit.
+
#### Build Formats
By default, each package will be built in multiple distribution formats as specified in the `buildOptions.formats` field in its `package.json`. These can be overwritten via the `-f` flag. The following formats are supported:
@@ -127,13 +173,11 @@ nr build runtime-core -f esm-browser,cjs
Use the `--sourcemap` or `-s` flag to build with source maps. Note this will make the build much slower.
-#### Build with Type Declarations
+### `nr build-dts`
-The `--types` or `-t` flag will generate type declarations during the build and in addition:
+This command builds the type declarations for all packages. It first generates the raw `.d.ts` files in the `temp` directory, then uses [rollup-plugin-dts](https://github.com/Swatinem/rollup-plugin-dts) to roll the types into a single `.d.ts` file for each package.
-- Roll the declarations into a single `.d.ts` file for each package;
-- Generate an API report in `/temp/.api.md`. This report contains potential warnings emitted by [api-extractor](https://api-extractor.com/).
-- Generate an API model json in `/temp/.api.json`. This file can be used to generate a Markdown version of the exported APIs.
+### `nr check`
### `nr dev`
@@ -142,7 +186,7 @@ The `dev` script bundles a target package (default: `vue`) in a specified format
```bash
$ nr dev
-> watching: packages/vue/dist/vue.global.js
+> built: packages/vue/dist/vue.global.js
```
- **Important:** output of the `dev` script is for development and debugging only. While it has the same runtime behavior, the generated code should never be published to npm.
@@ -161,31 +205,38 @@ Shortcut for starting the SFC Playground in local dev mode. This provides the fa
### `nr dev-esm`
-Builds and watches `vue/dist/vue-runtime.esm-bundler.js` with all deps inlined using esbuild. This is useful when debugging the ESM build in a reproductions that require real build setups: link `packages/vue` globally, then link it into the project being debugged.
+Builds and watches `vue/dist/vue-runtime.esm-bundler.js` with all deps inlined using esbuild. This is useful when debugging the ESM build in a reproduction that requires real build setups: link `packages/vue` globally, then link it into the project being debugged.
### `nr dev-compiler`
-The `dev-compiler` script builds, watches and serves the [Template Explorer](https://github.com/vuejs/core/tree/main/packages/template-explorer) at `http://localhost:5000`. This is useful when working on pure compiler issues.
+The `dev-compiler` script builds, watches and serves the [Template Explorer](https://github.com/vuejs/core/tree/main/packages/template-explorer) at `http://localhost:3000`. This is useful when working on pure compiler issues.
### `nr test`
-The `test` script simply calls the `jest` binary, so all [Jest CLI Options](https://jestjs.io/docs/en/cli) can be used. Some examples:
+The `test` script simply calls the `vitest` binary, so all [Vitest CLI Options](https://vitest.dev/guide/cli.html#options) can be used. Some examples:
```bash
-# run all tests
+# run all tests in watch mode
$ nr test
+# run once and exit (equivalent to `vitest run`)
+$ nr test run
+
# run all tests under the runtime-core package
$ nr test runtime-core
-# run tests in a specific file
-$ nr test fileName
+# run tests in files matching the pattern
+$ nr test
-# run a specific test in a specific file
-$ nr test fileName -t 'test name'
+# run a specific test in specific files
+$ nr test -t 'test name'
```
-The default `test` script includes the `--runInBand` jest flag to improve test stability, especially for the CSS transition related tests. When you are testing specific test specs, you can also run `npx jest` with flags directly to speed up tests (jest runs them in parallel by default).
+Tests that test against source code are grouped under `nr test-unit`, while tests that test against built files that run in real browsers are grouped under `nr test-e2e`.
+
+### `nr test-dts`
+
+Runs `nr build-dts` first, then verify the type tests in `packages-private/dts-test` are working correctly against the actual built type declarations.
## Project Structure
@@ -209,14 +260,18 @@ This repository employs a [monorepo](https://en.wikipedia.org/wiki/Monorepo) set
- `compiler-ssr`: Compiler that produces render functions optimized for server-side rendering.
-- `template-explorer`: A development tool for debugging compiler output. You can run `nr dev template-explorer` and open its `index.html` to get a repl of template compilation based on current source code.
-
- A [live version](https://vue-next-template-explorer.netlify.com) of the template explorer is also available, which can be used for providing reproductions for compiler bugs. You can also pick the deployment for a specific commit from the [deploy logs](https://app.netlify.com/sites/vue-next-template-explorer/deploys).
-
- `shared`: Internal utilities shared across multiple packages (especially environment-agnostic utils used by both runtime and compiler packages).
- `vue`: The public facing "full build" which includes both the runtime AND the compiler.
+- Private utility packages:
+
+ - `dts-test`: Contains type-only tests against generated dts files.
+
+ - `sfc-playground`: The playground continuously deployed at https://play.vuejs.org. To run the playground locally, use [`nr dev-sfc`](#nr-dev-sfc).
+
+ - `template-explorer`: A development tool for debugging compiler output, continuously deployed at https://template-explorer.vuejs.org/. To run it locally, run [`nr dev-compiler`](#nr-dev-compiler).
+
### Importing Packages
The packages can import each other directly using their package names. Note that when importing a package, the name listed in its `package.json` should be used. Most of the time the `@vue/` prefix is needed:
@@ -228,7 +283,7 @@ import { h } from '@vue/runtime-core'
This is made possible via several configurations:
- For TypeScript, `compilerOptions.paths` in `tsconfig.json`
-- For Jest, `moduleNameMapper` in `jest.config.js`
+- Vitest and Rollup share the same set of aliases from `scripts/aliases.js`
- For plain Node.js, they are linked using [PNPM Workspaces](https://pnpm.io/workspaces).
### Package Dependencies
@@ -268,7 +323,7 @@ There are some rules to follow when importing across package boundaries:
## Contributing Tests
-Unit tests are collocated with the code being tested in each package, inside directories named `__tests__`. Consult the [Jest docs](https://jestjs.io/docs/en/using-matchers) and existing test cases for how to write new test specs. Here are some additional guidelines:
+Unit tests are collocated with the code being tested in each package, inside directories named `__tests__`. Consult the [Vitest docs](https://vitest.dev/api/) and existing test cases for how to write new test specs. Here are some additional guidelines:
- Use the minimal API needed for a test case. For example, if a test can be written without involving the reactivity system or a component, it should be written so. This limits the test's exposure to changes in unrelated parts and makes it more stable.
@@ -276,11 +331,11 @@ Unit tests are collocated with the code being tested in each package, inside dir
- Only use platform-specific runtimes if the test is asserting platform-specific behavior.
-Test coverage is continuously deployed at https://vue-next-coverage.netlify.app/. PRs that improve test coverage are welcome, but in general the test coverage should be used as a guidance for finding API use cases that are not covered by tests. We don't recommend adding tests that only improve coverage but not actually test a meaning use case.
+Test coverage is continuously deployed at https://coverage.vuejs.org. PRs that improve test coverage are welcome, but in general the test coverage should be used as a guidance for finding API use cases that are not covered by tests. We don't recommend adding tests that only improve coverage but not actually test a meaning use case.
### Testing Type Definition Correctness
-Type tests are located in the `test-dts` directory. To run the dts tests, run `nr test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by simply running `nr test-dts`.
+Type tests are located in the `packages-private/dts-test` directory. To run the dts tests, run `nr test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by running `nr test-dts-only`.
## Financial Contribution
@@ -297,4 +352,4 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
Thank you to all the people who have already contributed to Vue.js!
-
+
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 206deefc560..00000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-version: 2
-updates:
-- package-ecosystem: npm
- directory: "/"
- schedule:
- interval: monthly
- open-pull-requests-limit: 10
- versioning-strategy: lockfile-only
- ignore:
- - dependency-name: "@types/node"
- versions:
- - 14.14.24
- - 14.14.37
- - dependency-name: "@babel/parser"
- versions:
- - 7.12.11
- - 7.12.13
- - 7.12.14
- - 7.12.15
- - 7.12.16
- - 7.12.17
- - 7.13.0
- - 7.13.10
- - 7.13.11
- - 7.13.13
- - 7.13.4
- - 7.13.9
- - dependency-name: eslint
- versions:
- - 7.23.0
- - dependency-name: postcss
- versions:
- - 8.2.4
- - 8.2.5
- - 8.2.7
- - 8.2.8
- - dependency-name: typescript
- versions:
- - 4.2.2
- - dependency-name: "@babel/types"
- versions:
- - 7.12.12
- - 7.12.13
- - 7.12.17
- - 7.13.0
- - dependency-name: pug-code-gen
- versions:
- - 2.0.3
- - dependency-name: estree-walker
- versions:
- - 2.0.2
- - dependency-name: "@typescript-eslint/parser"
- versions:
- - 4.14.2
- - 4.15.0
- - dependency-name: "@microsoft/api-extractor"
- versions:
- - 7.13.1
- - dependency-name: rollup
- versions:
- - 2.38.5
- - dependency-name: node-notifier
- versions:
- - 8.0.1
-- package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: monthly
- open-pull-requests-limit: 10
- versioning-strategy: lockfile-only
diff --git a/.github/git-branch-workflow.excalidraw b/.github/git-branch-workflow.excalidraw
new file mode 100644
index 00000000000..dd9127938da
--- /dev/null
+++ b/.github/git-branch-workflow.excalidraw
@@ -0,0 +1,1746 @@
+{
+ "type": "excalidraw",
+ "version": 2,
+ "source": "https://excalidraw.com",
+ "elements": [
+ {
+ "type": "arrow",
+ "version": 799,
+ "versionNonce": 529220601,
+ "isDeleted": false,
+ "id": "Gao2krnDddLMCj468JSWD",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 860.0129225738813,
+ "y": 663.9911710635109,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 133.75296854079784,
+ "height": 149.58016791936518,
+ "seed": 1415631543,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "hDC6an14QljktaZCUhcPF",
+ "focus": 0.09950793234484598,
+ "gap": 1.2432497743127229
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 25.209039386719837,
+ 85.96948921803892
+ ],
+ [
+ 133.75296854079784,
+ 149.58016791936518
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 563,
+ "versionNonce": 290881303,
+ "isDeleted": false,
+ "id": "N3wyyEU7TQ8BsOQgxCmlR",
+ "fillStyle": "hachure",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 292.88008929085873,
+ "y": 660.7027503334302,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 936.9972134376155,
+ "height": 1.3184243543457796,
+ "seed": 534235417,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 936.9972134376155,
+ -1.3184243543457796
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 302,
+ "versionNonce": 883286489,
+ "isDeleted": false,
+ "id": "nRDWQs5nQa37yzCWTBiXC",
+ "fillStyle": "hachure",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 293.1231624544633,
+ "y": 820.6017661012943,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 790.7091601354882,
+ "height": 0.35284814071621895,
+ "seed": 515907671,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "ggogfJT7E_bbfEog7Hjnp",
+ "focus": -0.14000162237652433,
+ "gap": 1
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 790.7091601354882,
+ -0.35284814071621895
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 36,
+ "versionNonce": 981763127,
+ "isDeleted": false,
+ "id": "ZPdMAnEUq5Jgj1W07Zqiw",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 292.0450153578305,
+ "y": 619.3959946602608,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "width": 46.875,
+ "height": 24,
+ "seed": 1311694519,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 20,
+ "fontFamily": 3,
+ "text": "main",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "main",
+ "lineHeight": 1.2,
+ "baseline": 20
+ },
+ {
+ "type": "text",
+ "version": 94,
+ "versionNonce": 18759353,
+ "isDeleted": false,
+ "id": "g9IkEIfu4vA8Qkwtw01Hi",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 290.88990199912035,
+ "y": 779.1760596323645,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "width": 58.59375,
+ "height": 24,
+ "seed": 329886135,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 20,
+ "fontFamily": 3,
+ "text": "minor",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "minor",
+ "lineHeight": 1.2,
+ "baseline": 20
+ },
+ {
+ "type": "ellipse",
+ "version": 50,
+ "versionNonce": 1442112855,
+ "isDeleted": false,
+ "id": "RrdEQ7hwgGGDPhzDnuZj1",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 361.55609907891005,
+ "y": 649.8742329483416,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 2077639991,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 79,
+ "versionNonce": 1547173785,
+ "isDeleted": false,
+ "id": "Zmp49FKWxGSzKnVKomjQc",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 427.3015090315691,
+ "y": 650.256485100784,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 372652121,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 76,
+ "versionNonce": 586949239,
+ "isDeleted": false,
+ "id": "UOl9nLBksM7RPdH9mzjJa",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 490.9435520120701,
+ "y": 651.2601420343765,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 508667545,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 120,
+ "versionNonce": 874947705,
+ "isDeleted": false,
+ "id": "oMC55V0VO_hOXoZ1se8Kl",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 555.4481126698772,
+ "y": 650.7975189165487,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1914963513,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 66,
+ "versionNonce": 39762839,
+ "isDeleted": false,
+ "id": "DZY5DC5uVP7-U5c3ngIZ4",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 622.5167031502219,
+ "y": 649.3743647489936,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 165914713,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 107,
+ "versionNonce": 1689103705,
+ "isDeleted": false,
+ "id": "Vsw6oIiTM3fQypkiCic3f",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 690.330195260967,
+ "y": 650.6681412649529,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 280044345,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 148,
+ "versionNonce": 1986194201,
+ "isDeleted": false,
+ "id": "D14w9erv_2l53mINe2nSt",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 361.004283792179,
+ "y": 810.2809579853473,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1203257975,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 179,
+ "versionNonce": 1172811511,
+ "isDeleted": false,
+ "id": "6WO8xOpG0rf673b_bT0m7",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 426.74969374483805,
+ "y": 810.6632101377896,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 2056706967,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "mE8Mu0qKfFaWPCC5vmF_f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 173,
+ "versionNonce": 820518905,
+ "isDeleted": false,
+ "id": "VB9U8oH-78hf530hIb_mG",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 490.391736725339,
+ "y": 811.6668670713822,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1149587639,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 218,
+ "versionNonce": 1227143191,
+ "isDeleted": false,
+ "id": "Bxv1hcS0VmxUwI0JLFH97",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 554.8962973831461,
+ "y": 811.2042439535543,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1864901079,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "M14Q0Uo1DBy2Ss2SOFSgW",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 167,
+ "versionNonce": 1387509977,
+ "isDeleted": false,
+ "id": "4v23gkfhy-hzk18YdkfLz",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 621.9648878634908,
+ "y": 809.7810897859994,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 462671607,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "vEF1cIIYYWKm84KLKqEz3",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 200,
+ "versionNonce": 774085943,
+ "isDeleted": false,
+ "id": "AtEf7o4WZQn4Zxq8EN5fH",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 689.7783799742359,
+ "y": 811.0748663019584,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1414322199,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "3heKY3vfe3-6ni4dX7Uqo",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 199,
+ "versionNonce": 1834563001,
+ "isDeleted": false,
+ "id": "ugDby5sBv4NKdNt8eC1sg",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 762.6179978227377,
+ "y": 810.2986003923828,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1598537015,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 211,
+ "versionNonce": 407428695,
+ "isDeleted": false,
+ "id": "Fwe4F2sB_0jptOZGYsusj",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 837.1081608628116,
+ "y": 810.859236882632,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1340669527,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "M14Q0Uo1DBy2Ss2SOFSgW",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "arrow",
+ "version": 57,
+ "versionNonce": 335287961,
+ "isDeleted": false,
+ "id": "mE8Mu0qKfFaWPCC5vmF_f",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 437.60867586595543,
+ "y": 830.4227236701945,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 0.5232394659406623,
+ "height": 33.25787987764363,
+ "seed": 482155929,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "6WO8xOpG0rf673b_bT0m7",
+ "focus": -0.1727591064041787,
+ "gap": 1.046152088903881
+ },
+ "endBinding": {
+ "elementId": "JALHBtowuh3_a86loej2x",
+ "focus": 0.015156451076917701,
+ "gap": 15.586906139714472
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.5232394659406623,
+ 33.25787987764363
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 59,
+ "versionNonce": 1248394103,
+ "isDeleted": false,
+ "id": "AI-_jSAuzesxTqwRvpk0s",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 501.2878833373983,
+ "y": 652.3088851192829,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#ffc9c9",
+ "width": 0,
+ "height": 40.40111211199792,
+ "seed": 1052632343,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -40.40111211199792
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 261,
+ "versionNonce": 693099385,
+ "isDeleted": false,
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 786.7392304423553,
+ "y": 649.6016935672433,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#ffc9c9",
+ "width": 0,
+ "height": 40.40111211199792,
+ "seed": 1233043511,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "s0PKxsWTJSDbQeEl_WI-C",
+ "focus": 0.016372633695398757,
+ "gap": 1
+ },
+ "endBinding": {
+ "elementId": "9ia1Uwc5X0fRw5iaahmcT",
+ "focus": 0.025318405829282714,
+ "gap": 14.862364635333904
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -40.40111211199792
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 121,
+ "versionNonce": 952661143,
+ "isDeleted": false,
+ "id": "qWW8uxDIcV3Bkj28uvRLr",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 454.32425448306674,
+ "y": 537.8854189061962,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 93.75,
+ "height": 57.599999999999994,
+ "seed": 809847769,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "patch\nrelease\ne.g. 3.3.8",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "patch\nrelease\ne.g. 3.3.8",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "text",
+ "version": 257,
+ "versionNonce": 1838679129,
+ "isDeleted": false,
+ "id": "9ia1Uwc5X0fRw5iaahmcT",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 741.0510307156029,
+ "y": 536.7382168199114,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 93.75,
+ "height": 57.599999999999994,
+ "seed": 213765431,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "patch\nrelease\ne.g. 3.3.9",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "patch\nrelease\ne.g. 3.3.9",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "text",
+ "version": 222,
+ "versionNonce": 1528547767,
+ "isDeleted": false,
+ "id": "JALHBtowuh3_a86loej2x",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 350.7264132088442,
+ "y": 879.2675096875524,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 168.75,
+ "height": 57.599999999999994,
+ "seed": 41180921,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "mE8Mu0qKfFaWPCC5vmF_f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "pre minor\nrelease\ne.g. 3.4.0-alpha.1",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "pre minor\nrelease\ne.g. 3.4.0-alpha.1",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "arrow",
+ "version": 345,
+ "versionNonce": 1286082873,
+ "isDeleted": false,
+ "id": "3heKY3vfe3-6ni4dX7Uqo",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 699.5281288163526,
+ "y": 831.0290882554708,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 0.5502191262773977,
+ "height": 33.25154356841597,
+ "seed": 627698359,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "AtEf7o4WZQn4Zxq8EN5fH",
+ "focus": -0.05612657009295625,
+ "gap": 1.1451322685712295
+ },
+ "endBinding": {
+ "elementId": "9t6qH-tAxVUexkHHi2pd2",
+ "focus": 0.015156451076917755,
+ "gap": 15.586906139714358
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.5502191262773977,
+ 33.25154356841597
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 365,
+ "versionNonce": 1049066199,
+ "isDeleted": false,
+ "id": "9t6qH-tAxVUexkHHi2pd2",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 617.3409291322284,
+ "y": 879.8675379636011,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 159.375,
+ "height": 57.599999999999994,
+ "seed": 1013545943,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "3heKY3vfe3-6ni4dX7Uqo",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "pre minor\nrelease\ne.g. 3.4.0-beta.1",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "pre minor\nrelease\ne.g. 3.4.0-beta.1",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "arrow",
+ "version": 788,
+ "versionNonce": 1810072089,
+ "isDeleted": false,
+ "id": "vEF1cIIYYWKm84KLKqEz3",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 630.3597332113623,
+ "y": 667.2735668205443,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 2.258228100583324,
+ "height": 140.75112333166828,
+ "seed": 2091697367,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "4v23gkfhy-hzk18YdkfLz",
+ "focus": 0.13930391883256707,
+ "gap": 1.8256906627890626
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.8426514015177418,
+ 69.09942755691065
+ ],
+ [
+ 2.258228100583324,
+ 140.75112333166828
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 687,
+ "versionNonce": 2017318649,
+ "isDeleted": false,
+ "id": "M14Q0Uo1DBy2Ss2SOFSgW",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 370.5976915356099,
+ "y": 667.5155013947814,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 1.5329291446666957,
+ "height": 145.39303664953377,
+ "seed": 361678233,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.34892760581925586,
+ 83.56228079137543
+ ],
+ [
+ 1.1840015388474399,
+ 145.39303664953377
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 537,
+ "versionNonce": 342487319,
+ "isDeleted": false,
+ "id": "CHAOOJMz7tNaG1VsG_uzT",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 384.81046417498214,
+ "y": 725.4677076298137,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 131.25,
+ "height": 57.599999999999994,
+ "seed": 1656007289,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "merge main\ninto minor\nbefore release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "merge main\ninto minor\nbefore release",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "ellipse",
+ "version": 202,
+ "versionNonce": 876253145,
+ "isDeleted": false,
+ "id": "hDC6an14QljktaZCUhcPF",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 993.0386151813434,
+ "y": 810.335845473903,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1433430105,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "Gao2krnDddLMCj468JSWD",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "arrow",
+ "version": 1525,
+ "versionNonce": 777631287,
+ "isDeleted": false,
+ "id": "ces8IwHCpQlTnELpjFDIn",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1092.5386800881793,
+ "y": 827.5114796878765,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 0.3315362017829102,
+ "height": 49.45191086419197,
+ "seed": 225867737,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "8rWUxp-jRNGrGRmhHHfm4",
+ "focus": -0.2047594653982401,
+ "gap": 10.392197401393389
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.3315362017829102,
+ 49.45191086419197
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 894,
+ "versionNonce": 1173171385,
+ "isDeleted": false,
+ "id": "8rWUxp-jRNGrGRmhHHfm4",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1047.251646167428,
+ "y": 887.3555879534618,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 112.5,
+ "height": 57.599999999999994,
+ "seed": 1600918713,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "ces8IwHCpQlTnELpjFDIn",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "stable minor\nrelease\ne.g. 3.4.0",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "stable minor\nrelease\ne.g. 3.4.0",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "ellipse",
+ "version": 201,
+ "versionNonce": 78435447,
+ "isDeleted": false,
+ "id": "3RHuRn_evSK0YUe02B4MY",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 909.9742423218671,
+ "y": 810.4142561718397,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1199705047,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 371,
+ "versionNonce": 2093872087,
+ "isDeleted": false,
+ "id": "9h2Cu__8owLUgUGjGcWDe",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 848.4414471158692,
+ "y": 650.826922928275,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 603147257,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 361,
+ "versionNonce": 1981618457,
+ "isDeleted": false,
+ "id": "s0PKxsWTJSDbQeEl_WI-C",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 777.1778842958995,
+ "y": 650.2466837635417,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 326722777,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 871,
+ "versionNonce": 1528156247,
+ "isDeleted": false,
+ "id": "3JAdSa7kqqSDSom5ZFDoE",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 904.3603861670398,
+ "y": 707.2413714353705,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 140.625,
+ "height": 57.599999999999994,
+ "seed": 1011049431,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "final merge\nmain into minor\nbefore release",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "final merge\nmain into minor\nbefore release",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "arrow",
+ "version": 591,
+ "versionNonce": 1714373785,
+ "isDeleted": false,
+ "id": "7kFBLq2Iczmj0lVnVk8Ad",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1100.7141458557703,
+ "y": 814.2034531496416,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#ffffff",
+ "width": 127.38209933342364,
+ "height": 144.5383600420214,
+ "seed": 25829591,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "Y7VXnuc9QEz2N2l9i0xrc",
+ "focus": 0.3932764551319699,
+ "gap": 5.928572790502042
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 88.94909573964219,
+ -43.721805169626464
+ ],
+ [
+ 127.38209933342364,
+ -144.5383600420214
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 1208,
+ "versionNonce": 1254600055,
+ "isDeleted": false,
+ "id": "gwFWlPLabuYhxCOweJjWz",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1223.0464288187204,
+ "y": 725.1565933898091,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 150,
+ "height": 38.4,
+ "seed": 51102743,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "main merge minor\n(fast forward)",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "main merge minor\n(fast forward)",
+ "lineHeight": 1.2,
+ "baseline": 34
+ },
+ {
+ "type": "ellipse",
+ "version": 597,
+ "versionNonce": 1760381305,
+ "isDeleted": false,
+ "id": "Y7VXnuc9QEz2N2l9i0xrc",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1227.4473966637659,
+ "y": 647.6689320688656,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 412038615,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "7kFBLq2Iczmj0lVnVk8Ad",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 547,
+ "versionNonce": 1585505943,
+ "isDeleted": false,
+ "id": "ggogfJT7E_bbfEog7Hjnp",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1083.7911569735343,
+ "y": 809.5203742153592,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 741463161,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "nRDWQs5nQa37yzCWTBiXC",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 229,
+ "versionNonce": 1935127129,
+ "isDeleted": false,
+ "id": "eU-EgpwDD42CLYUEIDLaD",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.8405004265049,
+ "y": 389.31989430571576,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 581.25,
+ "height": 19.2,
+ "seed": 1086231577,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- merge feature PRs into, and release minors from minor branch",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- merge feature PRs into, and release minors from minor branch",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 397,
+ "versionNonce": 116088535,
+ "isDeleted": false,
+ "id": "Kt6VBAVD4sLM4IexsRGoX",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.4136207977353,
+ "y": 358.61173442109686,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 618.75,
+ "height": 19.2,
+ "seed": 273353945,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927617946,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- merge fix / chore PRs into, and release patches from main branch",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- merge fix / chore PRs into, and release patches from main branch",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 459,
+ "versionNonce": 440532793,
+ "isDeleted": false,
+ "id": "JwKEdnU6H_Nu74WbEAX5M",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.6723761009271,
+ "y": 418.3724478537203,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 459.375,
+ "height": 19.2,
+ "seed": 1001222329,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- merge main into minor before each minor release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- merge main into minor before each minor release",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 602,
+ "versionNonce": 1108720119,
+ "isDeleted": false,
+ "id": "mb9ZoP803MiH7MTO8wH-2",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.0895924262568,
+ "y": 447.44321411383333,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 534.375,
+ "height": 19.2,
+ "seed": 264651479,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- fast forward main to minor after a stable minor release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- fast forward main to minor after a stable minor release",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 612,
+ "versionNonce": 1588872441,
+ "isDeleted": false,
+ "id": "IfJPOFiwrCibpaBQqc5g-",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 646.7131179044119,
+ "y": 724.4984335940012,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 131.25,
+ "height": 57.599999999999994,
+ "seed": 1301100087,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "merge main\ninto minor\nbefore release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "merge main\ninto minor\nbefore release",
+ "lineHeight": 1.2,
+ "baseline": 53
+ }
+ ],
+ "appState": {
+ "gridSize": null,
+ "viewBackgroundColor": "#ffffff"
+ },
+ "files": {}
+}
\ No newline at end of file
diff --git a/.github/git-branch-workflow.png b/.github/git-branch-workflow.png
new file mode 100644
index 00000000000..6c8ee07d484
Binary files /dev/null and b/.github/git-branch-workflow.png differ
diff --git a/.github/issue-workflow.png b/.github/issue-workflow.png
new file mode 100644
index 00000000000..92b1de0633c
Binary files /dev/null and b/.github/issue-workflow.png differ
diff --git a/.github/maintenance.md b/.github/maintenance.md
new file mode 100644
index 00000000000..b1fb550dd7a
--- /dev/null
+++ b/.github/maintenance.md
@@ -0,0 +1,123 @@
+# Vue Core Maintenance Handbook
+
+Unlike [contributing.md](./contributing.md), which targets external contributors, this document is mainly intended for team members responsible for maintaining the project. It provides guidelines on how to triage issues, review & merge PRs, and publish releases. However, it should also be valuable to external contributors even if you are not a maintainer, as it gives you a better idea of how the maintainers operate, and how you can better collaborate with them. And who knows - maybe one day you will join as a maintainer as well!
+
+- [Issue Triage Workflow](#issue-triage-workflow)
+- [Pull Request Review Guidelines](#pull-request-review-guidelines)
+ - [Reviewing a Fix](#reviewing-a-fix)
+ - [Reviewing a Refactor](#reviewing-a-refactor)
+ - [Reviewing a Feature](#reviewing-a-feature)
+ - [Common Considerations for All PRs](#common-considerations-for-all-prs)
+- [PR Merge Rules for Team Members](#pr-merge-rules-for-team-members)
+- [Git Branch and Release Workflow](#git-branch-and-release-workflow)
+
+## Issue Triage Workflow
+
+
+
+## Pull Request Review Guidelines
+
+The first step of reviewing a PR is to identify its purpose. We can usually put a PR in one of these categories:
+
+- **Fix**: fixes some wrong behavior. Usually associated with an issue that has a reproduction of the behavior being fixed.
+- **Refactor**: improves performance or code quality, but does not affect behavior.
+- **Feature**: implements something that increases the public API surface.
+
+Depending on the type of the PR, different considerations need to be taken into account.
+
+### Reviewing a Fix
+
+- Is the PR fixing a well defined issue / bug report?
+ - If not, ask to clarify context / provide reproduction or failing test case
+- In most cases, a fix PR should include a test case that fails without the fix.
+- Is it the right fix?
+ - If not, guide user to rework the PR.
+ - If the needed change is small and obvious, can directly push to the PR or add inline suggestions to reduce the back-and-forth.
+- Is the cost justified?
+ - Sometimes the fix for a rare edge case might be introducing disproportionately large overhead (perf or code size). We should try our best to reduce the overhead to make the fix a reasonable tradeoff.
+- If the reviewer is not sure about a fix, try to leave a comment explaining the concerns / reservations so the contributor at least gets some feedback.
+
+#### Verifying a Fix
+
+- **Always locally verify that the fix indeed fixes the original behavior, either through a reproduction or a failing test case.**
+- We will run [ecosystem-ci](https://github.com/vuejs/ecosystem-ci) before every release, but if you are concerned about the potential impact of a change, it never hurts to manually run ecosystem-ci by leaving a `/ecosystem-ci run` comment (only works for team members).
+- Take extra caution with snapshot tests! The CI can be "passing" even if the code generated in the snapshot contains bugs. It's best to always accompany a snapshot test with extra `expect(code).toMatch(...)` assertions.
+
+### Reviewing a Refactor
+
+- Performance: if a refactor PR claims to improve performance, there should be benchmarks showcasing said performance unless the improvement is self-explanatory.
+
+- Code quality / stylistic PRs: we should be conservative on merging this type PRs because (1) they can be subjective in many cases, and (2) they often come with large git diffs, causing merge conflicts with other pending PRs, and leading to unwanted noise when tracing changes through git history. Use your best judgement on this type of PRs on whether they are worth it.
+
+ - For PRs in this category that are approved, do not merge immediately. Group them before releasing a new minor, after all feature-oriented PRs are merged.
+
+### Reviewing a Feature
+
+- Feature PRs should always have clear context and explanation on why the feature should be added, ideally in the form of an RFC. If the PR doesn't explain what real-world problem it is solving, ask the contributor to clarify.
+
+- Decide if the feature should require an RFC process. The line isn't always clear, but a rough criteria is whether it is augmenting an existing API vs. adding a new API. Some examples:
+
+ - Adding a new built-in component or directive is "significant" and definitely requires an RFC.
+ - Template syntax additions like adding a new `v-on` modifier or a new `v-bind` syntax sugar are "substantial". It would be nice to have an RFC for it, but a detailed explanation on the use case and reasoning behind the design directly in the PR itself can be acceptable.
+ - Small, low-impact additions like exposing a new utility type or adding a new app config option can be self-explanatory, but should still provide enough context in the PR.
+
+- Always ask if the use case can be solved with existing APIs. Vue already has a pretty large API surface, so we want to make sure every new addition either solves something that wasn't possible before, or significantly improves the DX of a common task.
+
+### Common Considerations for All PRs
+
+- Scope: a PR should only contain changes directly related to the problem being addressed. It should not contain unnecessary code style changes.
+
+- Implementation: code style should be consistent with the rest of the codebase, follow common best practices. Prefer code that is boring but easy to understand over "clever" code.
+
+- Size: bundle size matters. We have a GitHub action that compares the size change for every PR. We should always aim to realize the desired changes with the smallest amount of code size increase.
+
+ - Sometimes we need to compare the size increase vs. perceived benefits to decide whether a change is justifiable. Also take extra care to make sure added code can be tree-shaken if not needed.
+
+ - Make sure to put dev-only code in `__DEV__` branches so they are tree-shakable.
+
+ - Runtime code is more sensitive to size increase than compiler code.
+
+ - Make sure it doesn't accidentally cause dev-only or compiler-only code branches to be included in the runtime build. Notable case is that some functions in @vue/shared are compiler-only and should not be used in runtime code, e.g. `isHTMLTag` and `isSVGTag`.
+
+- Performance
+
+ - Be careful about code changes in "hot paths", in particular the Virtual DOM renderer (`runtime-core/src/renderer.ts`) and component instantiation code.
+
+- Potential Breakage
+ - avoiding runtime behavior breakage is the highest priority
+ - if not sure, use `ecosystem-ci` to verify!
+ - some fix inevitably cause behavior change, these must be discussed case-by-case
+ - type level breakage (e.g upgrading TS) is possible between minors
+
+## PR Merge Rules for Team Members
+
+Given that the PR meets the review requirements:
+
+- Chore / dependencies bumps: can merge directly.
+- Fixes / refactors: can merge with two or more approvals from team members.
+ - If you believe a PR looks good but you are not 100% confident to merge, label with "ready for merge" and Evan will provide a final review before merging.
+- Features: if approved by two or more team members, label with "ready to merge". Evan will review periodically, or they can be raised and discussed at team meetings.
+
+## Git Branch and Release Workflow
+
+We use two primary work branches: `main` and `minor`.
+
+- The `main` branch is for stable releases. Changes that are bug fixes or refactors that do not affect the public API surface should land in this branch. We periodically release patch releases from the `main` branch.
+
+- The `minor` branch is the WIP branch for the next minor release. Changes that are new features or those that affect public API behavior should land in this branch. We will periodically release pre-releases (alpha / beta) for the next minor from this branch.
+
+Before each release, we merge latest `main` into `minor` so it would include the latest bug fixes.
+
+When the minor is ready, we do a final merge of `main` into `minor`, and then release a stable minor from this branch (e.g. `3.4.0`). After that, the `main` branch is fast-forwarded to the release commit, so the two branches are synced at each stable minor release.
+
+
+
+### Reasoning Behind the Workflow
+
+The reason behind this workflow is to allow merging and releasing of fixes and features in parallel. In the past, we used a linear trunk-based development model. While the linear model results in a clean git history, the downside is that we need to be careful about when to merge patches vs. features.
+
+Vue typically groups a number of features with the same scope in a minor release. We don't want to release a minor just because we happened to merge a feature PR along with a bunch of small bug fixes. So we usually "wait" until we feel we are ready to start working on a minor release before merging feature PRs.
+
+But in reality, there are always bugs to fix and patch release to work on - this caused the intervals between minors to drag on longer than we had hoped, and many feature PRs were left waiting for a long period of time.
+
+This is why we decided to separate bug fixes and feature PRs into separate branches. With this two-branch model, we are able to merge and release both types of changes in parallel.
diff --git a/.github/renovate.json5 b/.github/renovate.json5
new file mode 100644
index 00000000000..aad4afa132a
--- /dev/null
+++ b/.github/renovate.json5
@@ -0,0 +1,75 @@
+{
+ $schema: 'https://docs.renovatebot.com/renovate-schema.json',
+ extends: ['config:recommended', 'schedule:weekly', 'group:allNonMajor'],
+ labels: ['dependencies'],
+ ignorePaths: ['**/__tests__/**'],
+ rangeStrategy: 'bump',
+ packageRules: [
+ {
+ matchDepTypes: ['peerDependencies'],
+ enabled: false,
+ },
+ {
+ groupName: 'test',
+ matchPackageNames: ['vitest', 'jsdom', 'puppeteer', '@vitest{/,}**'],
+ },
+ {
+ groupName: 'playground',
+ matchFileNames: [
+ 'packages-private/sfc-playground/package.json',
+ 'packages-private/template-explorer/package.json',
+ ],
+ },
+ {
+ groupName: 'compiler',
+ matchPackageNames: ['magic-string', '@babel{/,}**', 'postcss{/,}**'],
+ },
+ {
+ groupName: 'build',
+ matchPackageNames: [
+ 'vite',
+ '@swc/core',
+ 'rollup{/,}**',
+ 'esbuild{/,}**',
+ '@rollup{/,}**',
+ '@vitejs{/,}**',
+ ],
+ },
+ {
+ groupName: 'lint',
+ matchPackageNames: [
+ 'simple-git-hooks',
+ 'lint-staged',
+ 'typescript-eslint{/,}**',
+ 'eslint{/,}**',
+ 'prettier{/,}**',
+ ],
+ },
+ ],
+ ignoreDeps: [
+ 'vue',
+
+ // manually bumping
+ 'node',
+ 'typescript',
+
+ // ESM only
+ 'estree-walker',
+
+ // pinned
+ // https://github.com/vuejs/core/issues/10300#issuecomment-1940855364
+ 'lru-cache',
+
+ // pinned
+ // https://github.com/vuejs/core/commit/a012e39b373f1b6918e5c89856e8f902e1bfa14d
+ '@rollup/plugin-replace',
+
+ // pinned
+ // only used in example for e2e tests
+ 'marked',
+
+ // pinned, 5.0+ has exports issues
+ // https://github.com/vuejs/core/issues/11603
+ 'entities',
+ ],
+}
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
new file mode 100644
index 00000000000..95bc65f357b
--- /dev/null
+++ b/.github/workflows/autofix.yml
@@ -0,0 +1,34 @@
+name: autofix.ci
+
+on:
+ pull_request:
+permissions:
+ contents: read
+
+jobs:
+ autofix:
+ runs-on: ubuntu-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run eslint
+ run: pnpm run lint --fix
+
+ - name: Run prettier
+ run: pnpm run format
+
+ - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27
diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml
new file mode 100644
index 00000000000..0b6401b8ce4
--- /dev/null
+++ b/.github/workflows/canary-minor.yml
@@ -0,0 +1,33 @@
+name: canary minor release
+on:
+ # Runs every Monday at 1 AM UTC (9:00 AM in Singapore)
+ schedule:
+ - cron: 0 1 * * MON
+ workflow_dispatch:
+
+jobs:
+ canary:
+ # prevents this action from running on forks
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ environment: Release
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: minor
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - run: pnpm release --canary --publish --tag minor
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
new file mode 100644
index 00000000000..71c794c7078
--- /dev/null
+++ b/.github/workflows/canary.yml
@@ -0,0 +1,31 @@
+name: canary release
+on:
+ # Runs every Monday at 1 AM UTC (9:00 AM in Singapore)
+ schedule:
+ - cron: 0 1 * * MON
+ workflow_dispatch:
+
+jobs:
+ canary:
+ # prevents this action from running on forks
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ environment: Release
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - run: pnpm release --canary --publish
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c811c0b8214..c8c217f62c4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,105 +3,40 @@ on:
push:
branches:
- '**'
+ tags:
+ - '!**'
pull_request:
branches:
- main
-
-permissions:
- contents: read # to fetch code (actions/checkout)
+ - minor
jobs:
- unit-test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
-
- - name: Install pnpm
- uses: pnpm/action-setup@v2
-
- - name: Set node version to 18
- uses: actions/setup-node@v3
- with:
- node-version: 18
- cache: 'pnpm'
-
- - run: PUPPETEER_SKIP_DOWNLOAD=1 pnpm install
+ test:
+ if: ${{ ! startsWith(github.event.head_commit.message, 'release:') && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) }}
+ uses: ./.github/workflows/test.yml
- - name: Run unit tests
- run: pnpm run test-unit
-
- e2e-test:
+ continuous-release:
+ if: github.repository == 'vuejs/core'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
-
- - name: Setup cache for Chromium binary
- uses: actions/cache@v3
- with:
- path: ~/.cache/puppeteer/chrome
- key: chromium-${{ hashFiles('pnpm-lock.yaml') }}
+ - name: Checkout
+ uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v4
- - name: Set node version to 18
- uses: actions/setup-node@v3
+ - name: Install Node.js
+ uses: actions/setup-node@v4
with:
- node-version: 18
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- - run: pnpm install
-
- - name: Run e2e tests
- run: pnpm run test-e2e
-
- lint-and-test-dts:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
-
- - name: Install pnpm
- uses: pnpm/action-setup@v2
-
- - name: Set node version to 18
- uses: actions/setup-node@v3
- with:
- node-version: 18
- cache: 'pnpm'
-
- - run: PUPPETEER_SKIP_DOWNLOAD=1 pnpm install
-
- - name: Run eslint
- run: pnpm run lint
-
- # - name: Run prettier
- # run: pnpm run format-check
-
- - name: Run type declaration tests
- run: pnpm run test-dts
-
- size:
- runs-on: ubuntu-latest
- env:
- CI_JOB_NUMBER: 1
- steps:
- - uses: actions/checkout@v3
-
- - name: Install pnpm
- uses: pnpm/action-setup@v2
-
- - name: Set node version to 18
- uses: actions/setup-node@v3
- with:
- node-version: 18
- cache: 'pnpm'
+ - name: Install deps
+ run: pnpm install
- - run: PUPPETEER_SKIP_DOWNLOAD=1 pnpm install
- - run: pnpm run size
+ - name: Build
+ run: pnpm build --withTypes
- # - name: Check build size
- # uses: posva/size-check-action@v1.1.2
- # with:
- # github_token: ${{ secrets.GITHUB_TOKEN }}
- # build_script: size
- # files: packages/vue/dist/vue.global.prod.js packages/runtime-dom/dist/runtime-dom.global.prod.js packages/size-check/dist/index.js
+ - name: Release
+ run: pnpx pkg-pr-new publish --compact --pnpm './packages/*'
diff --git a/.github/workflows/close-cant-reproduce-issues.yml b/.github/workflows/close-cant-reproduce-issues.yml
new file mode 100644
index 00000000000..8fb48f842d8
--- /dev/null
+++ b/.github/workflows/close-cant-reproduce-issues.yml
@@ -0,0 +1,21 @@
+name: Auto close issues with "can't reproduce" label
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+permissions:
+ issues: write
+
+jobs:
+ close-issues:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ steps:
+ - name: can't reproduce
+ uses: actions-cool/issues-helper@v3
+ with:
+ actions: 'close-issues'
+ token: ${{ secrets.GITHUB_TOKEN }}
+ labels: "can't reproduce"
+ inactive-day: 3
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
new file mode 100644
index 00000000000..b3e963ececa
--- /dev/null
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -0,0 +1,90 @@
+name: ecosystem-ci trigger
+
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ trigger:
+ runs-on: ubuntu-latest
+ if: github.repository == 'vuejs/core' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run')
+ steps:
+ - name: Check user permission
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const user = context.payload.sender.login
+ console.log(`Validate user: ${user}`)
+
+ let isVuejsMember = false
+ try {
+ const { status } = await github.rest.orgs.checkMembershipForUser({
+ org: 'vuejs',
+ username: user
+ });
+
+ isVuejsMember = (status === 204)
+ } catch (e) {}
+
+ if (isVuejsMember) {
+ console.log('Allowed')
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: '+1',
+ })
+ } else {
+ console.log('Not allowed')
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: '-1',
+ })
+ throw new Error('not allowed')
+ }
+ - name: Get PR info
+ uses: actions/github-script@v7
+ id: get-pr-data
+ with:
+ script: |
+ console.log(`Get PR info: ${context.repo.owner}/${context.repo.repo}#${context.issue.number}`)
+ const { data: pr } = await github.rest.pulls.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: context.issue.number
+ })
+ return {
+ num: context.issue.number,
+ branchName: pr.head.ref,
+ repo: pr.head.repo.full_name,
+ commit: pr.head.sha
+ }
+ - name: Trigger run
+ uses: actions/github-script@v7
+ id: trigger
+ env:
+ COMMENT: ${{ github.event.comment.body }}
+ with:
+ github-token: ${{ secrets.ECOSYSTEM_CI_ACCESS_TOKEN }}
+ result-encoding: string
+ script: |
+ const comment = process.env.COMMENT.trim()
+ const prData = ${{ steps.get-pr-data.outputs.result }}
+
+ const suite = comment.replace(/^\/ecosystem-ci run/, '').trim()
+
+ await github.rest.actions.createWorkflowDispatch({
+ owner: context.repo.owner,
+ repo: 'ecosystem-ci',
+ workflow_id: 'ecosystem-ci-from-pr.yml',
+ ref: 'main',
+ inputs: {
+ prNumber: '' + prData.num,
+ branchName: prData.branchName,
+ repo: prData.repo,
+ suite: suite === '' ? '-' : suite,
+ commit: prData.commit
+ }
+ })
diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml
new file mode 100644
index 00000000000..68a7d6c7a15
--- /dev/null
+++ b/.github/workflows/lock-closed-issues.yml
@@ -0,0 +1,20 @@
+name: Lock Closed Issues
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+permissions:
+ issues: write
+
+jobs:
+ action:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: dessant/lock-threads@v5
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-inactive-days: '14'
+ issue-lock-reason: ''
+ process-only: 'issues'
diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml
deleted file mode 100644
index 16c6c9c5c10..00000000000
--- a/.github/workflows/release-tag.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-on:
- push:
- tags:
- - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
-
-name: Create Release
-
-permissions: {}
-jobs:
- build:
- permissions:
- contents: write # to create release (yyx990803/release-tag)
-
- name: Create Release
- runs-on: ubuntu-latest
- steps:
- - name: Checkout code
- uses: actions/checkout@master
- - name: Create Release for Tag
- id: release_tag
- uses: yyx990803/release-tag@master
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- body: |
- Please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000000..c260a728e71
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,55 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
+
+jobs:
+ test:
+ uses: ./.github/workflows/test.yml
+
+ release:
+ # prevents this action from running on forks
+ if: github.repository == 'vuejs/core'
+ needs: [test]
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ id-token: write
+ # Use Release environment for deployment protection
+ environment: Release
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - name: Install deps
+ run: pnpm install
+
+ - name: Build and publish
+ id: publish
+ run: |
+ pnpm release --publishOnly
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+
+ - name: Create GitHub release
+ id: release_tag
+ uses: yyx990803/release-tag@master
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref }}
+ body: |
+ For stable releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details.
+ For pre-releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/minor/CHANGELOG.md) of the `minor` branch.
diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml
new file mode 100644
index 00000000000..5a370b8b92f
--- /dev/null
+++ b/.github/workflows/size-data.yml
@@ -0,0 +1,51 @@
+name: size data
+
+on:
+ push:
+ branches:
+ - main
+ - minor
+ pull_request:
+ branches:
+ - main
+ - minor
+
+permissions:
+ contents: read
+
+env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+
+jobs:
+ upload:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: pnpm
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - run: pnpm run size
+
+ - name: Save PR number & base branch
+ if: ${{github.event_name == 'pull_request'}}
+ run: |
+ echo ${{ github.event.number }} > ./temp/size/number.txt
+ echo ${{ github.base_ref }} > ./temp/size/base.txt
+
+ - name: Upload Size Data
+ uses: actions/upload-artifact@v4
+ with:
+ name: size-data
+ path: temp/size
diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml
new file mode 100644
index 00000000000..66b5ad0ef29
--- /dev/null
+++ b/.github/workflows/size-report.yml
@@ -0,0 +1,85 @@
+name: size report
+
+on:
+ workflow_run:
+ workflows: ['size data']
+ types:
+ - completed
+
+permissions:
+ contents: read
+ pull-requests: write
+ issues: write
+
+env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+
+jobs:
+ size-report:
+ runs-on: ubuntu-latest
+ if: >
+ github.repository == 'vuejs/core' &&
+ github.event.workflow_run.event == 'pull_request' &&
+ github.event.workflow_run.conclusion == 'success'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: pnpm
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Download Size Data
+ uses: dawidd6/action-download-artifact@v9
+ with:
+ name: size-data
+ run_id: ${{ github.event.workflow_run.id }}
+ path: temp/size
+
+ - name: Read PR Number
+ id: pr-number
+ uses: juliangruber/read-file-action@v1
+ with:
+ path: temp/size/number.txt
+
+ - name: Read base branch
+ id: pr-base
+ uses: juliangruber/read-file-action@v1
+ with:
+ path: temp/size/base.txt
+
+ - name: Download Previous Size Data
+ uses: dawidd6/action-download-artifact@v9
+ with:
+ branch: ${{ steps.pr-base.outputs.content }}
+ workflow: size-data.yml
+ event: push
+ name: size-data
+ path: temp/size-prev
+ if_no_artifact_found: warn
+
+ - name: Prepare report
+ run: node scripts/size-report.js > size-report.md
+
+ - name: Read Size Report
+ id: size-report
+ uses: juliangruber/read-file-action@v1
+ with:
+ path: ./size-report.md
+
+ - name: Create Comment
+ uses: actions-cool/maintain-one-comment@v3
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ number: ${{ steps.pr-number.outputs.content }}
+ body: |
+ ${{ steps.size-report.outputs.content }}
+
+ body-include: ''
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000000..1122eb35573
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,111 @@
+name: 'test'
+
+on: workflow_call
+
+permissions:
+ contents: read # to fetch code (actions/checkout)
+
+jobs:
+ unit-test:
+ runs-on: ubuntu-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run unit tests
+ run: pnpm run test-unit
+
+ unit-test-windows:
+ runs-on: windows-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run compiler unit tests
+ run: pnpm run test-unit compiler
+
+ - name: Run ssr unit tests
+ run: pnpm run test-unit server-renderer
+
+ e2e-test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup cache for Chromium binary
+ uses: actions/cache@v4
+ with:
+ path: ~/.cache/puppeteer
+ key: chromium-${{ hashFiles('pnpm-lock.yaml') }}
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+ - run: node node_modules/puppeteer/install.mjs
+
+ - name: Run e2e tests
+ run: pnpm run test-e2e
+
+ - name: verify treeshaking
+ run: node scripts/verify-treeshaking.js
+
+ lint-and-test-dts:
+ runs-on: ubuntu-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run eslint
+ run: pnpm run lint
+
+ - name: Run prettier
+ run: pnpm run format-check
+
+ - name: Run tsc
+ run: pnpm run check
+
+ - name: Run type declaration tests
+ run: pnpm run test-dts
diff --git a/.gitignore b/.gitignore
index 75c8139bd9b..9dd21f59bf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,6 @@ TODOs.md
*.log
.idea
.eslintcache
+dts-build/packages
+*.tsbuildinfo
+*.tgz
diff --git a/.node-version b/.node-version
new file mode 100644
index 00000000000..7d41c735d71
--- /dev/null
+++ b/.node-version
@@ -0,0 +1 @@
+22.14.0
diff --git a/.prettierignore b/.prettierignore
index 1521c8b7652..ca3c40849fd 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1 +1,3 @@
dist
+pnpm-lock.yaml
+CHANGELOG*.md
diff --git a/.prettierrc b/.prettierrc
index ef93d94821a..759232e7cf6 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,5 +1,5 @@
-semi: false
-singleQuote: true
-printWidth: 80
-trailingComma: 'none'
-arrowParens: 'avoid'
+{
+ "semi": false,
+ "singleQuote": true,
+ "arrowParens": "avoid"
+}
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000000..91ebd56925c
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["vitest.explorer"]
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index b63ffc79b80..9fc03aa9bc4 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -5,24 +5,15 @@
"version": "0.2.0",
"configurations": [
{
- "name": "Jest",
"type": "node",
"request": "launch",
- "program": "${workspaceFolder}/node_modules/.bin/jest",
- "stopOnEntry": false,
- "args": ["${fileBasename}", "--runInBand", "--detectOpenHandles"],
- "cwd": "${workspaceFolder}",
- "preLaunchTask": null,
- "runtimeExecutable": null,
- "runtimeArgs": ["--nolazy"],
- "env": {
- "NODE_ENV": "development"
- },
- "console": "integratedTerminal",
- "sourceMaps": true,
- "windows": {
- "program": "${workspaceFolder}/node_modules/jest/bin/jest",
- }
+ "name": "Vitest - Debug Current Test File",
+ "autoAttachChildProcesses": true,
+ "skipFiles": ["/**", "**/node_modules/**"],
+ "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
+ "args": ["run", "${relativeFile}"],
+ "smartStep": true,
+ "console": "integratedTerminal"
}
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 1dcc2819c28..302428290b9 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -13,5 +13,6 @@
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
- }
+ },
+ "editor.formatOnSave": true
}
diff --git a/.well-known/funding-manifest-urls b/.well-known/funding-manifest-urls
new file mode 100644
index 00000000000..f26079d4138
--- /dev/null
+++ b/.well-known/funding-manifest-urls
@@ -0,0 +1 @@
+https://vuejs.org/funding.json
diff --git a/BACKERS.md b/BACKERS.md
index fa66d206698..d8eb697f957 100644
--- a/BACKERS.md
+++ b/BACKERS.md
@@ -1,9 +1,9 @@
Sponsors & Backers
-Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of the awesome sponsors and backers listed in this file. If you'd like to join them, please consider [ sponsor Vue's development](https://vuejs.org/sponsor/).
+Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of the awesome sponsors and backers listed in this file. If you'd like to join them, please consider [ sponsoring Vue's development](https://vuejs.org/sponsor/).
-
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11a2a9dde78..2a0b96332b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,2961 +1,636 @@
-## [3.2.45](https://github.com/vuejs/core/compare/v3.2.44...v3.2.45) (2022-11-11)
+## [3.5.18](https://github.com/vuejs/core/compare/v3.5.17...v3.5.18) (2025-07-23)
### Bug Fixes
-* **compiler/v-model:** catch incorrect v-model usage on prop bindings ([001184e](https://github.com/vuejs/core/commit/001184e6bbbc85c4698f460b1f810beca3aed262)), closes [#5584](https://github.com/vuejs/core/issues/5584)
-* **custom-elements:** also dispatch hyphenated version of emitted events ([#5378](https://github.com/vuejs/core/issues/5378)) ([0b39e46](https://github.com/vuejs/core/commit/0b39e46192c6258d5bf9d3b6992b84edb0b641d3)), closes [#5373](https://github.com/vuejs/core/issues/5373)
-* **custom-elements:** custom element should re-instantiate when inserted again ([#6966](https://github.com/vuejs/core/issues/6966)) ([67890da](https://github.com/vuejs/core/commit/67890daad1a8474c5178565f32a4efa427db911a)), closes [#6934](https://github.com/vuejs/core/issues/6934)
-* **custom-elements:** define declared properties in constructor ([#5328](https://github.com/vuejs/core/issues/5328)) ([55382ae](https://github.com/vuejs/core/commit/55382aed58aa3d937f442ad9445b3fff83a07de1))
-* **custom-elements:** ensure custom elements can inherit provides from ancestors ([#5098](https://github.com/vuejs/core/issues/5098)) ([192dcb6](https://github.com/vuejs/core/commit/192dcb648c0630ac20d2009eed512e142a72654a)), closes [#5096](https://github.com/vuejs/core/issues/5096)
-* **custom-elements:** fix event emitting for async custom elements ([#5601](https://github.com/vuejs/core/issues/5601)) ([665f2ae](https://github.com/vuejs/core/commit/665f2ae121ec31d65cf22bd577f12fb1d9ffa4a2)), closes [#5599](https://github.com/vuejs/core/issues/5599)
-* **custom-elements:** fix number type props casting check ([89f37ce](https://github.com/vuejs/core/commit/89f37ceb62363c77697d177675790a9ab81ba34f)), closes [#5793](https://github.com/vuejs/core/issues/5793) [#5794](https://github.com/vuejs/core/issues/5794)
-* **custom-elements:** properties set pre-upgrade should not show up in $attrs ([afe8899](https://github.com/vuejs/core/commit/afe889999cbcaa11020c46c30b591a5ee6c3d4cf))
-* **custom-elements:** respect slot props in custom element mode ([ffef822](https://github.com/vuejs/core/commit/ffef8228694b39638f07c0fe5bc30d826262b672))
-* **custom-elements:** should not reflect non-decalred properties set before upgrade ([5e50909](https://github.com/vuejs/core/commit/5e509091000779acbfae4c85cc1cc3973b1b2e64))
-* **hmr/keep-alive:** fix error in reload component ([#7049](https://github.com/vuejs/core/issues/7049)) ([a54bff2](https://github.com/vuejs/core/commit/a54bff2c9c8e1d908b4a0f3826ac715c9a35e68c)), closes [#7042](https://github.com/vuejs/core/issues/7042)
-* **runtime-core:** fix move/removal of static fragments containing text nodes ([#6858](https://github.com/vuejs/core/issues/6858)) ([4049ffc](https://github.com/vuejs/core/commit/4049ffcf29dc12dca71f682edf0b422a5c502e23)), closes [#6852](https://github.com/vuejs/core/issues/6852)
-* **sfc:** also generate getter for import bindings during dev ([0594400](https://github.com/vuejs/core/commit/0594400980d3bdc394e92db63fc939a6609f7a94))
-* **sfc:** ensure `
+
+
+
+
+
+
+
diff --git a/packages/sfc-playground/src/Header.vue b/packages-private/sfc-playground/src/Header.vue
similarity index 51%
rename from packages/sfc-playground/src/Header.vue
rename to packages-private/sfc-playground/src/Header.vue
index 15f22ca66ff..bf1c9bad6eb 100644
--- a/packages/sfc-playground/src/Header.vue
+++ b/packages-private/sfc-playground/src/Header.vue
@@ -1,42 +1,56 @@
@@ -97,35 +73,35 @@ async function fetchVersions(): Promise {
Vue SFC Playground
-
-
- Version
- {{ activeVersion }}
-
-
-
+
+
+
+ This Commit ({{ currentCommit }})
+
+
+ Commits History
+
+
- {{ dev ? 'DEV' : 'PROD' }}
+ {{ prod ? 'PROD' : 'DEV' }}
{
>
{{ ssr ? 'SSR ON' : 'SSR OFF' }}
-
+
+ {{ autoSave ? 'AutoSave ON' : 'AutoSave OFF' }}
+
+
+
+
+
{
>
-
-
-
-
-
+
+
+
@@ -223,54 +214,30 @@ h1 img {
display: flex;
}
-.version {
- margin-right: 12px;
- position: relative;
-}
-
-.active-version {
- cursor: pointer;
- position: relative;
- display: inline-flex;
- place-items: center;
-}
-
-.active-version .number {
- color: var(--green);
- margin-left: 4px;
-}
-
-.active-version::after {
- content: '';
- width: 0;
- height: 0;
- border-left: 4px solid transparent;
- border-right: 4px solid transparent;
- border-top: 6px solid #aaa;
- margin-left: 8px;
-}
-
-.toggle-dev span,
-.toggle-ssr span {
+.toggle-prod span,
+.toggle-ssr span,
+.toggle-autosave span {
font-size: 12px;
border-radius: 4px;
padding: 4px 6px;
}
-.toggle-dev span {
- background: var(--purple);
+.toggle-prod span {
+ background: var(--green);
color: #fff;
}
-.toggle-dev.dev span {
- background: var(--green);
+.toggle-prod.prod span {
+ background: var(--purple);
}
-.toggle-ssr span {
+.toggle-ssr span,
+.toggle-autosave span {
background-color: var(--btn-bg);
}
-.toggle-ssr.enabled span {
+.toggle-ssr.enabled span,
+.toggle-autosave.enabled span {
color: #fff;
background-color: var(--green);
}
@@ -290,12 +257,13 @@ h1 img {
}
.links button,
-.links button a {
+.links .github {
+ padding: 1px 6px;
color: var(--btn);
}
.links button:hover,
-.links button:hover a {
+.links .github:hover {
color: var(--highlight);
}
diff --git a/packages-private/sfc-playground/src/VersionSelect.vue b/packages-private/sfc-playground/src/VersionSelect.vue
new file mode 100644
index 00000000000..3a30e497f97
--- /dev/null
+++ b/packages-private/sfc-playground/src/VersionSelect.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
+ {{ label }}
+ {{ version }}
+
+
+
+
+
+
+
diff --git a/packages/sfc-playground/src/download/download.ts b/packages-private/sfc-playground/src/download/download.ts
similarity index 67%
rename from packages/sfc-playground/src/download/download.ts
rename to packages-private/sfc-playground/src/download/download.ts
index dd7e3761d67..6b051abae19 100644
--- a/packages/sfc-playground/src/download/download.ts
+++ b/packages-private/sfc-playground/src/download/download.ts
@@ -5,8 +5,9 @@ import main from './template/main.js?raw'
import pkg from './template/package.json?raw'
import config from './template/vite.config.js?raw'
import readme from './template/README.md?raw'
+import type { ReplStore } from '@vue/repl'
-export async function downloadProject(store: any) {
+export async function downloadProject(store: ReplStore) {
if (!confirm('Download project files?')) {
return
}
@@ -16,7 +17,10 @@ export async function downloadProject(store: any) {
// basic structure
zip.file('index.html', index)
- zip.file('package.json', pkg)
+ zip.file(
+ 'package.json',
+ pkg.replace(`"vue": "latest"`, `"vue": "${store.vueVersion || 'latest'}"`),
+ )
zip.file('vite.config.js', config)
zip.file('README.md', readme)
@@ -26,7 +30,11 @@ export async function downloadProject(store: any) {
const files = store.getFiles()
for (const file in files) {
- src.file(file, files[file])
+ if (file !== 'import-map.json' && file !== 'tsconfig.json') {
+ src.file(file, files[file])
+ } else {
+ zip.file(file, files[file])
+ }
}
const blob = await zip.generateAsync({ type: 'blob' })
diff --git a/packages/sfc-playground/src/download/template/README.md b/packages-private/sfc-playground/src/download/template/README.md
similarity index 60%
rename from packages/sfc-playground/src/download/template/README.md
rename to packages-private/sfc-playground/src/download/template/README.md
index 39c47d255ae..91b21489fd5 100644
--- a/packages/sfc-playground/src/download/template/README.md
+++ b/packages-private/sfc-playground/src/download/template/README.md
@@ -1,6 +1,6 @@
# Vite Vue Starter
-This is a project template using [Vite](https://vitejs.dev/). It requires [Node.js](https://nodejs.org) v12+.
+This is a project template using [Vite](https://vitejs.dev/). It requires [Node.js](https://nodejs.org) version 18+ or 20+.
To start:
@@ -11,4 +11,8 @@ npm run dev
# if using yarn:
yarn
yarn dev
+
+# if using pnpm:
+pnpm install
+pnpm run dev
```
diff --git a/packages/sfc-playground/src/download/template/index.html b/packages-private/sfc-playground/src/download/template/index.html
similarity index 95%
rename from packages/sfc-playground/src/download/template/index.html
rename to packages-private/sfc-playground/src/download/template/index.html
index 030a6ff51bf..e631329c1b0 100644
--- a/packages/sfc-playground/src/download/template/index.html
+++ b/packages-private/sfc-playground/src/download/template/index.html
@@ -1,4 +1,4 @@
-
+
diff --git a/packages/sfc-playground/src/download/template/main.js b/packages-private/sfc-playground/src/download/template/main.js
similarity index 100%
rename from packages/sfc-playground/src/download/template/main.js
rename to packages-private/sfc-playground/src/download/template/main.js
diff --git a/packages/sfc-playground/src/download/template/package.json b/packages-private/sfc-playground/src/download/template/package.json
similarity index 63%
rename from packages/sfc-playground/src/download/template/package.json
rename to packages-private/sfc-playground/src/download/template/package.json
index 4f6bdd4a42c..b9bb278edf3 100644
--- a/packages/sfc-playground/src/download/template/package.json
+++ b/packages-private/sfc-playground/src/download/template/package.json
@@ -1,17 +1,17 @@
{
"name": "vite-vue-starter",
"version": "0.0.0",
+ "type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"dependencies": {
- "vue": "^3.2.0"
+ "vue": "latest"
},
"devDependencies": {
- "@vitejs/plugin-vue": "^1.4.0",
- "@vue/compiler-sfc": "^3.2.0",
- "vite": "^2.4.4"
+ "@vitejs/plugin-vue": "^5.2.4",
+ "vite": "^6.3.5"
}
-}
\ No newline at end of file
+}
diff --git a/packages/sfc-playground/src/download/template/vite.config.js b/packages-private/sfc-playground/src/download/template/vite.config.js
similarity index 87%
rename from packages/sfc-playground/src/download/template/vite.config.js
rename to packages-private/sfc-playground/src/download/template/vite.config.js
index 315212d69a7..05c17402a4a 100644
--- a/packages/sfc-playground/src/download/template/vite.config.js
+++ b/packages-private/sfc-playground/src/download/template/vite.config.js
@@ -3,5 +3,5 @@ import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [vue()]
+ plugins: [vue()],
})
diff --git a/packages-private/sfc-playground/src/icons/Copy.vue b/packages-private/sfc-playground/src/icons/Copy.vue
new file mode 100644
index 00000000000..f3851da63cc
--- /dev/null
+++ b/packages-private/sfc-playground/src/icons/Copy.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/packages/sfc-playground/src/icons/Download.vue b/packages-private/sfc-playground/src/icons/Download.vue
similarity index 100%
rename from packages/sfc-playground/src/icons/Download.vue
rename to packages-private/sfc-playground/src/icons/Download.vue
diff --git a/packages-private/sfc-playground/src/icons/GitHub.vue b/packages-private/sfc-playground/src/icons/GitHub.vue
new file mode 100644
index 00000000000..2a6aaf62dd2
--- /dev/null
+++ b/packages-private/sfc-playground/src/icons/GitHub.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/packages-private/sfc-playground/src/icons/Moon.vue b/packages-private/sfc-playground/src/icons/Moon.vue
new file mode 100644
index 00000000000..21f393d4d6e
--- /dev/null
+++ b/packages-private/sfc-playground/src/icons/Moon.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/packages-private/sfc-playground/src/icons/Reload.vue b/packages-private/sfc-playground/src/icons/Reload.vue
new file mode 100644
index 00000000000..5ec5be80889
--- /dev/null
+++ b/packages-private/sfc-playground/src/icons/Reload.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/packages/sfc-playground/src/icons/Share.vue b/packages-private/sfc-playground/src/icons/Share.vue
similarity index 100%
rename from packages/sfc-playground/src/icons/Share.vue
rename to packages-private/sfc-playground/src/icons/Share.vue
diff --git a/packages-private/sfc-playground/src/icons/Sun.vue b/packages-private/sfc-playground/src/icons/Sun.vue
new file mode 100644
index 00000000000..4b73922421a
--- /dev/null
+++ b/packages-private/sfc-playground/src/icons/Sun.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/sfc-playground/src/main.ts b/packages-private/sfc-playground/src/main.ts
similarity index 73%
rename from packages/sfc-playground/src/main.ts
rename to packages-private/sfc-playground/src/main.ts
index 713251fd81c..7be63408035 100644
--- a/packages/sfc-playground/src/main.ts
+++ b/packages-private/sfc-playground/src/main.ts
@@ -1,10 +1,9 @@
import { createApp } from 'vue'
import App from './App.vue'
-import '@vue/repl/style.css'
// @ts-expect-error Custom window property
window.VUE_DEVTOOLS_CONFIG = {
- defaultSelectedAppId: 'repl'
+ defaultSelectedAppId: 'repl',
}
createApp(App).mount('#app')
diff --git a/packages-private/sfc-playground/src/vue-dev-proxy-prod.ts b/packages-private/sfc-playground/src/vue-dev-proxy-prod.ts
new file mode 100644
index 00000000000..3b2faf19533
--- /dev/null
+++ b/packages-private/sfc-playground/src/vue-dev-proxy-prod.ts
@@ -0,0 +1,2 @@
+// serve vue to the iframe sandbox during dev.
+export * from 'vue/dist/vue.runtime.esm-browser.prod.js'
diff --git a/packages/sfc-playground/src/vue-dev-proxy.ts b/packages-private/sfc-playground/src/vue-dev-proxy.ts
similarity index 100%
rename from packages/sfc-playground/src/vue-dev-proxy.ts
rename to packages-private/sfc-playground/src/vue-dev-proxy.ts
diff --git a/packages/sfc-playground/src/vue-server-renderer-dev-proxy.ts b/packages-private/sfc-playground/src/vue-server-renderer-dev-proxy.ts
similarity index 100%
rename from packages/sfc-playground/src/vue-server-renderer-dev-proxy.ts
rename to packages-private/sfc-playground/src/vue-server-renderer-dev-proxy.ts
diff --git a/packages-private/sfc-playground/vercel.json b/packages-private/sfc-playground/vercel.json
new file mode 100644
index 00000000000..4511eb79d49
--- /dev/null
+++ b/packages-private/sfc-playground/vercel.json
@@ -0,0 +1,16 @@
+{
+ "github": {
+ "silent": true
+ },
+ "headers": [
+ {
+ "source": "/assets/(.*)",
+ "headers": [
+ {
+ "key": "Cache-Control",
+ "value": "max-age=31536000, immutable"
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages-private/sfc-playground/vite.config.ts b/packages-private/sfc-playground/vite.config.ts
new file mode 100644
index 00000000000..2e77f1970a7
--- /dev/null
+++ b/packages-private/sfc-playground/vite.config.ts
@@ -0,0 +1,59 @@
+import fs from 'node:fs'
+import path from 'node:path'
+import { type Plugin, defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import { spawnSync } from 'node:child_process'
+
+const commit = spawnSync('git', ['rev-parse', '--short=7', 'HEAD'])
+ .stdout.toString()
+ .trim()
+
+export default defineConfig({
+ plugins: [
+ vue({
+ script: {
+ fs: {
+ fileExists: fs.existsSync,
+ readFile: file => fs.readFileSync(file, 'utf-8'),
+ },
+ },
+ }),
+ copyVuePlugin(),
+ ],
+ define: {
+ __COMMIT__: JSON.stringify(commit),
+ __VUE_PROD_DEVTOOLS__: JSON.stringify(true),
+ },
+ optimizeDeps: {
+ exclude: ['@vue/repl'],
+ },
+})
+
+function copyVuePlugin(): Plugin {
+ return {
+ name: 'copy-vue',
+ generateBundle() {
+ const copyFile = (file: string) => {
+ const filePath = path.resolve(__dirname, '../../packages', file)
+ const basename = path.basename(file)
+ if (!fs.existsSync(filePath)) {
+ throw new Error(
+ `${basename} not built. ` +
+ `Run "nr build vue -f esm-browser" first.`,
+ )
+ }
+ this.emitFile({
+ type: 'asset',
+ fileName: basename,
+ source: fs.readFileSync(filePath, 'utf-8'),
+ })
+ }
+
+ copyFile(`vue/dist/vue.esm-browser.js`)
+ copyFile(`vue/dist/vue.esm-browser.prod.js`)
+ copyFile(`vue/dist/vue.runtime.esm-browser.js`)
+ copyFile(`vue/dist/vue.runtime.esm-browser.prod.js`)
+ copyFile(`server-renderer/dist/server-renderer.esm-browser.js`)
+ },
+ }
+}
diff --git a/packages/template-explorer/README.md b/packages-private/template-explorer/README.md
similarity index 100%
rename from packages/template-explorer/README.md
rename to packages-private/template-explorer/README.md
diff --git a/packages-private/template-explorer/_redirects b/packages-private/template-explorer/_redirects
new file mode 100644
index 00000000000..9d570fb8259
--- /dev/null
+++ b/packages-private/template-explorer/_redirects
@@ -0,0 +1,2 @@
+https://vue-next-template-explorer.netlify.app https://template-explorer.vuejs.org 301!
+https://vue-next-template-explorer.netlify.app/* https://template-explorer.vuejs.org/:splat 301!
diff --git a/packages-private/template-explorer/index.html b/packages-private/template-explorer/index.html
new file mode 100644
index 00000000000..d1db969f01b
--- /dev/null
+++ b/packages-private/template-explorer/index.html
@@ -0,0 +1,24 @@
+Vue Template Explorer
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages-private/template-explorer/local.html b/packages-private/template-explorer/local.html
new file mode 100644
index 00000000000..c86cdb6b34c
--- /dev/null
+++ b/packages-private/template-explorer/local.html
@@ -0,0 +1,24 @@
+Vue Template Explorer
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/template-explorer/package.json b/packages-private/template-explorer/package.json
similarity index 73%
rename from packages/template-explorer/package.json
rename to packages-private/template-explorer/package.json
index ec594cb3bd8..08da34b173e 100644
--- a/packages/template-explorer/package.json
+++ b/packages-private/template-explorer/package.json
@@ -1,7 +1,7 @@
{
"name": "@vue/template-explorer",
- "version": "3.2.45",
"private": true,
+ "version": "0.0.0",
"buildOptions": {
"formats": [
"global"
@@ -11,7 +11,7 @@
"enableNonBrowserBranches": true
},
"dependencies": {
- "monaco-editor": "^0.20.0",
- "source-map": "^0.6.1"
+ "monaco-editor": "^0.52.2",
+ "source-map-js": "^1.2.1"
}
}
diff --git a/packages/template-explorer/src/index.ts b/packages-private/template-explorer/src/index.ts
similarity index 88%
rename from packages/template-explorer/src/index.ts
rename to packages-private/template-explorer/src/index.ts
index 3cf9c6b52cf..988712d623c 100644
--- a/packages/template-explorer/src/index.ts
+++ b/packages-private/template-explorer/src/index.ts
@@ -1,14 +1,18 @@
-import * as m from 'monaco-editor'
-import { compile, CompilerError, CompilerOptions } from '@vue/compiler-dom'
+import type * as m from 'monaco-editor'
+import {
+ type CompilerError,
+ type CompilerOptions,
+ compile,
+} from '@vue/compiler-dom'
import { compile as ssrCompile } from '@vue/compiler-ssr'
import {
- defaultOptions,
compilerOptions,
+ defaultOptions,
initOptions,
- ssrMode
+ ssrMode,
} from './options'
import { toRaw, watchEffect } from '@vue/runtime-dom'
-import { SourceMapConsumer } from 'source-map'
+import { SourceMapConsumer } from 'source-map-js'
import theme from './theme'
declare global {
@@ -30,8 +34,8 @@ const sharedEditorOptions: m.editor.IStandaloneEditorConstructionOptions = {
scrollBeyondLastLine: false,
renderWhitespace: 'selection',
minimap: {
- enabled: false
- }
+ enabled: false,
+ },
}
window.init = () => {
@@ -48,13 +52,13 @@ window.init = () => {
hash = escape(atob(hash))
} catch (e) {}
persistedState = JSON.parse(
- decodeURIComponent(hash) || localStorage.getItem('state') || `{}`
+ decodeURIComponent(hash) || localStorage.getItem('state') || `{}`,
)
} catch (e: any) {
// bad stored state, clear it
console.warn(
'Persisted state in localStorage seems to be corrupted, please reload.\n' +
- e.message
+ e.message,
)
localStorage.clear()
}
@@ -76,18 +80,18 @@ window.init = () => {
const compileFn = ssrMode.value ? ssrCompile : compile
const start = performance.now()
const { code, ast, map } = compileFn(source, {
- filename: 'ExampleTemplate.vue',
...compilerOptions,
+ filename: 'ExampleTemplate.vue',
sourceMap: true,
onError: err => {
errors.push(err)
- }
+ },
})
console.log(`Compiled in ${(performance.now() - start).toFixed(2)}ms.`)
monaco.editor.setModelMarkers(
editor.getModel()!,
`@vue/compiler-dom`,
- errors.filter(e => e.loc).map(formatError)
+ errors.filter(e => e.loc).map(formatError),
)
console.log(`AST: `, ast)
console.log(`Options: `, toRaw(compilerOptions))
@@ -110,7 +114,7 @@ window.init = () => {
endLineNumber: loc.end.line,
endColumn: loc.end.column,
message: `Vue template compilation error: ${err.message}`,
- code: String(err.code)
+ code: String(err.code),
}
}
@@ -123,7 +127,7 @@ window.init = () => {
for (key in compilerOptions) {
const val = compilerOptions[key]
if (typeof val !== 'object' && val !== defaultOptions[key]) {
- // @ts-ignore
+ // @ts-expect-error
optionsToSave[key] = val
}
}
@@ -131,7 +135,7 @@ window.init = () => {
const state = JSON.stringify({
src,
ssr: ssrMode.value,
- options: optionsToSave
+ options: optionsToSave,
} as PersistedState)
localStorage.setItem('state', state)
window.location.hash = btoa(unescape(encodeURIComponent(state)))
@@ -145,21 +149,21 @@ window.init = () => {
value: persistedState?.src || `Hello World
`,
language: 'html',
...sharedEditorOptions,
- wordWrap: 'bounded'
+ wordWrap: 'bounded',
})
editor.getModel()!.updateOptions({
- tabSize: 2
+ tabSize: 2,
})
const output = monaco.editor.create(document.getElementById('output')!, {
value: '',
language: 'javascript',
readOnly: true,
- ...sharedEditorOptions
+ ...sharedEditorOptions,
})
output.getModel()!.updateOptions({
- tabSize: 2
+ tabSize: 2,
})
// handle resize
@@ -184,7 +188,7 @@ window.init = () => {
const pos = lastSuccessfulMap.generatedPositionFor({
source: 'ExampleTemplate.vue',
line: e.position.lineNumber,
- column: e.position.column - 1
+ column: e.position.column - 1,
})
if (pos.line != null && pos.column != null) {
prevOutputDecos = output.deltaDecorations(prevOutputDecos, [
@@ -193,22 +197,22 @@ window.init = () => {
pos.line,
pos.column + 1,
pos.line,
- pos.lastColumn ? pos.lastColumn + 2 : pos.column + 2
+ pos.lastColumn ? pos.lastColumn + 2 : pos.column + 2,
),
options: {
- inlineClassName: `highlight`
- }
- }
+ inlineClassName: `highlight`,
+ },
+ },
])
output.revealPositionInCenter({
lineNumber: pos.line,
- column: pos.column + 1
+ column: pos.column + 1,
})
} else {
clearOutputDecos()
}
}
- }, 100)
+ }, 100),
)
let previousEditorDecos: string[] = []
@@ -222,7 +226,7 @@ window.init = () => {
if (lastSuccessfulMap) {
const pos = lastSuccessfulMap.originalPositionFor({
line: e.position.lineNumber,
- column: e.position.column - 1
+ column: e.position.column - 1,
})
if (
pos.line != null &&
@@ -234,7 +238,7 @@ window.init = () => {
) {
const translatedPos = {
column: pos.column + 1,
- lineNumber: pos.line
+ lineNumber: pos.line,
}
previousEditorDecos = editor.deltaDecorations(previousEditorDecos, [
{
@@ -242,20 +246,20 @@ window.init = () => {
pos.line,
pos.column + 1,
pos.line,
- pos.column + 1
+ pos.column + 1,
),
options: {
isWholeLine: true,
- className: `highlight`
- }
- }
+ className: `highlight`,
+ },
+ },
])
editor.revealPositionInCenter(translatedPos)
} else {
clearEditorDecos()
}
}
- }, 100)
+ }, 100),
)
initOptions()
@@ -264,7 +268,7 @@ window.init = () => {
function debounce any>(
fn: T,
- delay: number = 300
+ delay: number = 300,
): T {
let prevTimer: number | null = null
return ((...args: any[]) => {
diff --git a/packages/template-explorer/src/options.ts b/packages-private/template-explorer/src/options.ts
similarity index 86%
rename from packages/template-explorer/src/options.ts
rename to packages-private/template-explorer/src/options.ts
index 73e0a959f79..e3cc6173a8a 100644
--- a/packages/template-explorer/src/options.ts
+++ b/packages-private/template-explorer/src/options.ts
@@ -1,5 +1,5 @@
-import { h, reactive, createApp, ref } from 'vue'
-import { CompilerOptions } from '@vue/compiler-dom'
+import { createApp, h, reactive, ref } from 'vue'
+import type { CompilerOptions } from '@vue/compiler-dom'
import { BindingTypes } from '@vue/compiler-core'
export const ssrMode = ref(false)
@@ -22,12 +22,12 @@ export const defaultOptions: CompilerOptions = {
setupLet: BindingTypes.SETUP_LET,
setupMaybeRef: BindingTypes.SETUP_MAYBE_REF,
setupProp: BindingTypes.PROPS,
- vMySetupDir: BindingTypes.SETUP_CONST
- }
+ vMySetupDir: BindingTypes.SETUP_CONST,
+ },
}
export const compilerOptions: CompilerOptions = reactive(
- Object.assign({}, defaultOptions)
+ Object.assign({}, defaultOptions),
)
const App = {
@@ -44,18 +44,18 @@ const App = {
'a',
{
href: `https://github.com/vuejs/core/tree/${__COMMIT__}`,
- target: `_blank`
+ target: `_blank`,
},
- `@${__COMMIT__}`
+ `@${__COMMIT__}`,
),
' | ',
h(
'a',
{
href: 'https://app.netlify.com/sites/vue-next-template-explorer/deploys',
- target: `_blank`
+ target: `_blank`,
},
- 'History'
+ 'History',
),
h('div', { id: 'options-wrapper' }, [
@@ -71,7 +71,7 @@ const App = {
checked: isModule,
onChange() {
compilerOptions.mode = 'module'
- }
+ },
}),
h('label', { for: 'mode-module' }, 'module'),
' ',
@@ -82,9 +82,9 @@ const App = {
checked: !isModule,
onChange() {
compilerOptions.mode = 'function'
- }
+ },
}),
- h('label', { for: 'mode-function' }, 'function')
+ h('label', { for: 'mode-function' }, 'function'),
]),
// whitespace handling
@@ -97,7 +97,7 @@ const App = {
checked: compilerOptions.whitespace === 'condense',
onChange() {
compilerOptions.whitespace = 'condense'
- }
+ },
}),
h('label', { for: 'whitespace-condense' }, 'condense'),
' ',
@@ -108,9 +108,9 @@ const App = {
checked: compilerOptions.whitespace === 'preserve',
onChange() {
compilerOptions.whitespace = 'preserve'
- }
+ },
}),
- h('label', { for: 'whitespace-preserve' }, 'preserve')
+ h('label', { for: 'whitespace-preserve' }, 'preserve'),
]),
// SSR
@@ -122,9 +122,9 @@ const App = {
checked: ssrMode.value,
onChange(e: Event) {
ssrMode.value = (e.target as HTMLInputElement).checked
- }
+ },
}),
- h('label', { for: 'ssr' }, 'SSR')
+ h('label', { for: 'ssr' }, 'SSR'),
]),
// toggle prefixIdentifiers
@@ -137,9 +137,9 @@ const App = {
onChange(e: Event) {
compilerOptions.prefixIdentifiers =
(e.target as HTMLInputElement).checked || isModule
- }
+ },
}),
- h('label', { for: 'prefix' }, 'prefixIdentifiers')
+ h('label', { for: 'prefix' }, 'prefixIdentifiers'),
]),
// toggle hoistStatic
@@ -153,9 +153,9 @@ const App = {
compilerOptions.hoistStatic = (
e.target as HTMLInputElement
).checked
- }
+ },
}),
- h('label', { for: 'hoist' }, 'hoistStatic')
+ h('label', { for: 'hoist' }, 'hoistStatic'),
]),
// toggle cacheHandlers
@@ -169,9 +169,9 @@ const App = {
compilerOptions.cacheHandlers = (
e.target as HTMLInputElement
).checked
- }
+ },
}),
- h('label', { for: 'cache' }, 'cacheHandlers')
+ h('label', { for: 'cache' }, 'cacheHandlers'),
]),
// toggle scopeId
@@ -186,9 +186,9 @@ const App = {
isModule && (e.target as HTMLInputElement).checked
? 'scope-id'
: null
- }
+ },
}),
- h('label', { for: 'scope-id' }, 'scopeId')
+ h('label', { for: 'scope-id' }, 'scopeId'),
]),
// inline mode
@@ -201,9 +201,9 @@ const App = {
compilerOptions.inline = (
e.target as HTMLInputElement
).checked
- }
+ },
}),
- h('label', { for: 'inline' }, 'inline')
+ h('label', { for: 'inline' }, 'inline'),
]),
// compat mode
@@ -218,15 +218,15 @@ const App = {
).checked
? 2
: 3
- }
+ },
}),
- h('label', { for: 'compat' }, 'v2 compat mode')
- ])
- ])
- ])
+ h('label', { for: 'compat' }, 'v2 compat mode'),
+ ]),
+ ]),
+ ]),
]
}
- }
+ },
}
export function initOptions() {
diff --git a/packages/template-explorer/src/theme.ts b/packages-private/template-explorer/src/theme.ts
similarity index 57%
rename from packages/template-explorer/src/theme.ts
rename to packages-private/template-explorer/src/theme.ts
index 99da1081ae9..9027cd0c011 100644
--- a/packages/template-explorer/src/theme.ts
+++ b/packages-private/template-explorer/src/theme.ts
@@ -4,234 +4,234 @@ export default {
rules: [
{
foreground: 'de935f',
- token: 'number'
+ token: 'number',
},
{
foreground: '969896',
- token: 'comment'
+ token: 'comment',
},
{
foreground: 'ced1cf',
- token: 'keyword.operator.class'
+ token: 'keyword.operator.class',
},
{
foreground: 'ced1cf',
- token: 'constant.other'
+ token: 'constant.other',
},
{
foreground: 'ced1cf',
- token: 'source.php.embedded.line'
+ token: 'source.php.embedded.line',
},
{
foreground: 'cc6666',
- token: 'variable'
+ token: 'variable',
},
{
foreground: 'cc6666',
- token: 'support.other.variable'
+ token: 'support.other.variable',
},
{
foreground: 'cc6666',
- token: 'string.other.link'
+ token: 'string.other.link',
},
{
foreground: 'cc6666',
- token: 'string.regexp'
+ token: 'string.regexp',
},
{
foreground: 'cc6666',
- token: 'entity.name.tag'
+ token: 'entity.name.tag',
},
{
foreground: 'cc6666',
- token: 'entity.other.attribute-name'
+ token: 'entity.other.attribute-name',
},
{
foreground: 'cc6666',
- token: 'meta.tag'
+ token: 'meta.tag',
},
{
foreground: 'cc6666',
- token: 'declaration.tag'
+ token: 'declaration.tag',
},
{
foreground: 'cc6666',
- token: 'markup.deleted.git_gutter'
+ token: 'markup.deleted.git_gutter',
},
{
foreground: 'de935f',
- token: 'constant.numeric'
+ token: 'constant.numeric',
},
{
foreground: 'de935f',
- token: 'constant.language'
+ token: 'constant.language',
},
{
foreground: 'de935f',
- token: 'support.constant'
+ token: 'support.constant',
},
{
foreground: 'de935f',
- token: 'constant.character'
+ token: 'constant.character',
},
{
foreground: 'de935f',
- token: 'variable.parameter'
+ token: 'variable.parameter',
},
{
foreground: 'de935f',
- token: 'punctuation.section.embedded'
+ token: 'punctuation.section.embedded',
},
{
foreground: 'de935f',
- token: 'keyword.other.unit'
+ token: 'keyword.other.unit',
},
{
foreground: 'f0c674',
- token: 'entity.name.class'
+ token: 'entity.name.class',
},
{
foreground: 'f0c674',
- token: 'entity.name.type.class'
+ token: 'entity.name.type.class',
},
{
foreground: 'f0c674',
- token: 'support.type'
+ token: 'support.type',
},
{
foreground: 'f0c674',
- token: 'support.class'
+ token: 'support.class',
},
{
foreground: 'b5bd68',
- token: 'string'
+ token: 'string',
},
{
foreground: 'b5bd68',
- token: 'constant.other.symbol'
+ token: 'constant.other.symbol',
},
{
foreground: 'b5bd68',
- token: 'entity.other.inherited-class'
+ token: 'entity.other.inherited-class',
},
{
foreground: 'b5bd68',
- token: 'markup.heading'
+ token: 'markup.heading',
},
{
foreground: 'b5bd68',
- token: 'markup.inserted.git_gutter'
+ token: 'markup.inserted.git_gutter',
},
{
foreground: '8abeb7',
- token: 'keyword.operator'
+ token: 'keyword.operator',
},
{
foreground: '8abeb7',
- token: 'constant.other.color'
+ token: 'constant.other.color',
},
{
foreground: '81a2be',
- token: 'entity.name.function'
+ token: 'entity.name.function',
},
{
foreground: '81a2be',
- token: 'meta.function-call'
+ token: 'meta.function-call',
},
{
foreground: '81a2be',
- token: 'support.function'
+ token: 'support.function',
},
{
foreground: '81a2be',
- token: 'keyword.other.special-method'
+ token: 'keyword.other.special-method',
},
{
foreground: '81a2be',
- token: 'meta.block-level'
+ token: 'meta.block-level',
},
{
foreground: '81a2be',
- token: 'markup.changed.git_gutter'
+ token: 'markup.changed.git_gutter',
},
{
foreground: 'b294bb',
- token: 'keyword'
+ token: 'keyword',
},
{
foreground: 'b294bb',
- token: 'storage'
+ token: 'storage',
},
{
foreground: 'b294bb',
- token: 'storage.type'
+ token: 'storage.type',
},
{
foreground: 'b294bb',
- token: 'entity.name.tag.css'
+ token: 'entity.name.tag.css',
},
{
foreground: 'ced2cf',
background: 'df5f5f',
- token: 'invalid'
+ token: 'invalid',
},
{
foreground: 'ced2cf',
background: '82a3bf',
- token: 'meta.separator'
+ token: 'meta.separator',
},
{
foreground: 'ced2cf',
background: 'b798bf',
- token: 'invalid.deprecated'
+ token: 'invalid.deprecated',
},
{
foreground: 'ffffff',
- token: 'markup.inserted.diff'
+ token: 'markup.inserted.diff',
},
{
foreground: 'ffffff',
- token: 'markup.deleted.diff'
+ token: 'markup.deleted.diff',
},
{
foreground: 'ffffff',
- token: 'meta.diff.header.to-file'
+ token: 'meta.diff.header.to-file',
},
{
foreground: 'ffffff',
- token: 'meta.diff.header.from-file'
+ token: 'meta.diff.header.from-file',
},
{
foreground: '718c00',
- token: 'markup.inserted.diff'
+ token: 'markup.inserted.diff',
},
{
foreground: '718c00',
- token: 'meta.diff.header.to-file'
+ token: 'meta.diff.header.to-file',
},
{
foreground: 'c82829',
- token: 'markup.deleted.diff'
+ token: 'markup.deleted.diff',
},
{
foreground: 'c82829',
- token: 'meta.diff.header.from-file'
+ token: 'meta.diff.header.from-file',
},
{
foreground: 'ffffff',
background: '4271ae',
- token: 'meta.diff.header.from-file'
+ token: 'meta.diff.header.from-file',
},
{
foreground: 'ffffff',
background: '4271ae',
- token: 'meta.diff.header.to-file'
+ token: 'meta.diff.header.to-file',
},
{
foreground: '3e999f',
fontStyle: 'italic',
- token: 'meta.diff.range'
- }
+ token: 'meta.diff.range',
+ },
],
colors: {
'editor.foreground': '#C5C8C6',
@@ -239,6 +239,6 @@ export default {
'editor.selectionBackground': '#373B41',
'editor.lineHighlightBackground': '#282A2E',
'editorCursor.foreground': '#AEAFAD',
- 'editorWhitespace.foreground': '#4B4E55'
- }
+ 'editorWhitespace.foreground': '#4B4E55',
+ },
}
diff --git a/packages/template-explorer/style.css b/packages-private/template-explorer/style.css
similarity index 86%
rename from packages/template-explorer/style.css
rename to packages-private/template-explorer/style.css
index 01a3e8b550b..eed9e18a009 100644
--- a/packages/template-explorer/style.css
+++ b/packages-private/template-explorer/style.css
@@ -1,7 +1,10 @@
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
- --bg: #1D1F21;
+ overflow: hidden;
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
+ Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ --bg: #1d1f21;
--border: #333;
}
diff --git a/packages-private/tsconfig.json b/packages-private/tsconfig.json
new file mode 100644
index 00000000000..1c287a7500c
--- /dev/null
+++ b/packages-private/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "isolatedDeclarations": false
+ },
+ "include": ["."]
+}
diff --git a/packages-private/vite-debug/App.vue b/packages-private/vite-debug/App.vue
new file mode 100644
index 00000000000..95b3be8eee5
--- /dev/null
+++ b/packages-private/vite-debug/App.vue
@@ -0,0 +1,15 @@
+
+
+
+ {{ count }}
+
+
+
diff --git a/packages-private/vite-debug/README.md b/packages-private/vite-debug/README.md
new file mode 100644
index 00000000000..4f035ae6f8d
--- /dev/null
+++ b/packages-private/vite-debug/README.md
@@ -0,0 +1 @@
+This package is used for debugging issues that are related to `@vitejs/plugin-vue`, or can only be reproduced in a Vite-based setup. It aims to be as close to production as possible so Vue packages are resolved to the dist files instead of source.
diff --git a/packages-private/vite-debug/index.html b/packages-private/vite-debug/index.html
new file mode 100644
index 00000000000..79052a023ba
--- /dev/null
+++ b/packages-private/vite-debug/index.html
@@ -0,0 +1,2 @@
+
+
diff --git a/packages-private/vite-debug/main.ts b/packages-private/vite-debug/main.ts
new file mode 100644
index 00000000000..52668a0a545
--- /dev/null
+++ b/packages-private/vite-debug/main.ts
@@ -0,0 +1,6 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.mount('#app')
diff --git a/packages-private/vite-debug/package.json b/packages-private/vite-debug/package.json
new file mode 100644
index 00000000000..b0f2bad2b2d
--- /dev/null
+++ b/packages-private/vite-debug/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "vite-debug",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "serve": "vite preview"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "catalog:",
+ "vite": "catalog:",
+ "vue": "workspace:*"
+ }
+}
diff --git a/packages-private/vite-debug/tsconfig.json b/packages-private/vite-debug/tsconfig.json
new file mode 100644
index 00000000000..ceecb1cde14
--- /dev/null
+++ b/packages-private/vite-debug/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "module": "esnext",
+ "moduleResolution": "bundler"
+ },
+ "include": ["./*"]
+}
diff --git a/packages-private/vite-debug/vite.config.ts b/packages-private/vite-debug/vite.config.ts
new file mode 100644
index 00000000000..c40aa3c361b
--- /dev/null
+++ b/packages-private/vite-debug/vite.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+export default defineConfig({
+ plugins: [vue()],
+})
diff --git a/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
index 036b7c8f953..db268af4f9b 100644
--- a/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: codegen ArrayExpression 1`] = `
+exports[`compiler: codegen > ArrayExpression 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -12,26 +12,26 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen CacheExpression 1`] = `
+exports[`compiler: codegen > CacheExpression 1`] = `
"
export function render(_ctx, _cache) {
return _cache[1] || (_cache[1] = foo)
}"
`;
-exports[`compiler: codegen CacheExpression w/ isVNode: true 1`] = `
+exports[`compiler: codegen > CacheExpression w/ isVOnce: true 1`] = `
"
export function render(_ctx, _cache) {
return _cache[1] || (
_setBlockTracking(-1),
- _cache[1] = foo,
+ (_cache[1] = foo).cacheIndex = 1,
_setBlockTracking(1),
_cache[1]
)
}"
`;
-exports[`compiler: codegen ConditionalExpression 1`] = `
+exports[`compiler: codegen > ConditionalExpression 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -44,7 +44,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen Element (callExpression + objectExpression + TemplateChildNode[]) 1`] = `
+exports[`compiler: codegen > Element (callExpression + objectExpression + TemplateChildNode[]) 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -54,12 +54,12 @@ return function render(_ctx, _cache) {
[foo + bar]: bar
}, [
_createElementVNode("p", { "some-key": "foo" })
- ], 16)
+ ], 16 /* FULL_PROPS */)
}
}"
`;
-exports[`compiler: codegen assets + temps 1`] = `
+exports[`compiler: codegen > assets + temps 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -76,7 +76,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen comment 1`] = `
+exports[`compiler: codegen > comment 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -85,7 +85,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen compound expression 1`] = `
+exports[`compiler: codegen > compound expression 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -94,16 +94,16 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen forNode 1`] = `
+exports[`compiler: codegen > forNode 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
- return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1))
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1 /* TEXT */))
}
}"
`;
-exports[`compiler: codegen forNode with constant expression 1`] = `
+exports[`compiler: codegen > forNode with constant expression 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -112,7 +112,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen function mode preamble 1`] = `
+exports[`compiler: codegen > function mode preamble 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -124,7 +124,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen function mode preamble w/ prefixIdentifiers: true 1`] = `
+exports[`compiler: codegen > function mode preamble w/ prefixIdentifiers: true 1`] = `
"const { createVNode: _createVNode, resolveDirective: _resolveDirective } = Vue
return function render(_ctx, _cache) {
@@ -132,7 +132,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen hoists 1`] = `
+exports[`compiler: codegen > hoists 1`] = `
"
const _hoisted_1 = hello
const _hoisted_2 = { id: "foo" }
@@ -144,7 +144,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen ifNode 1`] = `
+exports[`compiler: codegen > ifNode 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -155,7 +155,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen interpolation 1`] = `
+exports[`compiler: codegen > interpolation 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -164,7 +164,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen module mode preamble 1`] = `
+exports[`compiler: codegen > module mode preamble 1`] = `
"import { createVNode as _createVNode, resolveDirective as _resolveDirective } from "vue"
export function render(_ctx, _cache) {
@@ -172,7 +172,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen module mode preamble w/ optimizeImports: true 1`] = `
+exports[`compiler: codegen > module mode preamble w/ optimizeImports: true 1`] = `
"import { createVNode, resolveDirective } from "vue"
// Binding optimization for webpack code-split
@@ -183,7 +183,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen static text 1`] = `
+exports[`compiler: codegen > static text 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
@@ -192,7 +192,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: codegen temps 1`] = `
+exports[`compiler: codegen > temps 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
diff --git a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap
index 02c995fe97f..625485719cb 100644
--- a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: integration tests function mode 1`] = `
+exports[`compiler: integration tests > function mode 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -27,7 +27,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`] = `
+exports[`compiler: integration tests > function mode w/ prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createElementVNode: _createElementVNode, normalizeClass: _normalizeClass } = Vue
return function render(_ctx, _cache) {
@@ -50,7 +50,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: integration tests module mode 1`] = `
+exports[`compiler: integration tests > module mode 1`] = `
"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, Fragment as _Fragment, renderList as _renderList, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass } from "vue"
export function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
index 8a12c8c399f..942eed4c4dc 100644
--- a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
@@ -1,38 +1,45 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT 1`] = `
+exports[`compiler: parse > Edge Cases > invalid html 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 16,
- "line": 1,
- "offset": 15,
+ "column": 1,
+ "line": 3,
+ "offset": 13,
},
- "source": "",
+ "source": "
+",
"start": {
- "column": 11,
- "line": 1,
- "offset": 10,
+ "column": 1,
+ "line": 2,
+ "offset": 6,
},
},
- "type": 3,
+ "ns": 0,
+ "props": [],
+ "tag": "span",
+ "tagType": 0,
+ "type": 1,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 27,
- "line": 1,
- "offset": 26,
+ "column": 7,
+ "line": 3,
+ "offset": 19,
},
- "source": " ",
+ "source": "
+
+
",
"start": {
"column": 1,
"line": 1,
@@ -41,7 +48,7 @@ exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT <
},
"ns": 0,
"props": [],
- "tag": "template",
+ "tag": "div",
"tagType": 0,
"type": 1,
},
@@ -54,55 +61,44 @@ exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT <
"imports": [],
"loc": {
"end": {
- "column": 27,
- "line": 1,
- "offset": 26,
+ "column": 8,
+ "line": 4,
+ "offset": 27,
},
- "source": " ",
+ "source": "
+
+
+ ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
+
+
+",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT 1`] = `
+exports[`compiler: parse > Edge Cases > self closing multiple tag 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "content": "",
- "loc": {
- "end": {
- "column": 17,
- "line": 1,
- "offset": 16,
- },
- "source": "",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 3,
- },
- ],
+ "children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
+ "isSelfClosing": true,
"loc": {
"end": {
- "column": 28,
+ "column": 37,
"line": 1,
- "offset": 27,
+ "offset": 36,
},
- "source": " ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -110,78 +106,147 @@ exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT
},
},
"ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 28,
- "line": 1,
- "offset": 27,
- },
- "source": " ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
+ "props": [
{
- "content": "",
+ "arg": {
+ "constType": 3,
+ "content": "class",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "{ some: condition }",
+ "start": {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ },
+ "type": 4,
+ },
"loc": {
"end": {
- "column": 18,
+ "column": 34,
"line": 1,
- "offset": 17,
+ "offset": 33,
},
- "source": "",
+ "source": ":class="{ some: condition }"",
"start": {
- "column": 11,
+ "column": 6,
"line": 1,
- "offset": 10,
+ "offset": 5,
},
},
- "type": 3,
+ "modifiers": [],
+ "name": "bind",
+ "rawName": ":class",
+ "type": 7,
},
],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ {
+ "children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
+ "isSelfClosing": true,
"loc": {
"end": {
- "column": 29,
- "line": 1,
- "offset": 28,
+ "column": 37,
+ "line": 2,
+ "offset": 73,
},
- "source": " ",
+ "source": "
",
"start": {
"column": 1,
- "line": 1,
- "offset": 0,
+ "line": 2,
+ "offset": 37,
},
},
"ns": 0,
- "props": [],
- "tag": "template",
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "style",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 16,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": {
+ "column": 11,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 2,
+ "offset": 70,
+ },
+ "source": "{ color: 'red' }",
+ "start": {
+ "column": 18,
+ "line": 2,
+ "offset": 54,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 35,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style="{ color: 'red' }"",
+ "start": {
+ "column": 4,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": "v-bind:style",
+ "type": 7,
+ },
+ ],
+ "tag": "p",
"tagType": 0,
"type": 1,
},
@@ -194,48 +259,250 @@ exports[`compiler: parse Errors ABRUPT_CLOSING_OF_EMPTY_COMMENT ",
+ "source": "
+
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
+
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors CDATA_IN_HTML_CONTENT 1`] = `
+exports[`compiler: parse > Edge Cases > valid html 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "[CDATA[cdata]]",
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
"loc": {
"end": {
- "column": 28,
- "line": 1,
- "offset": 27,
+ "column": 39,
+ "line": 2,
+ "offset": 73,
},
- "source": "",
+ "source": "
",
"start": {
- "column": 11,
- "line": 1,
- "offset": 10,
+ "column": 3,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "style",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 18,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": {
+ "column": 13,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 36,
+ "line": 2,
+ "offset": 70,
+ },
+ "source": "{ color: 'red' }",
+ "start": {
+ "column": 20,
+ "line": 2,
+ "offset": 54,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style="{ color: 'red' }"",
+ "start": {
+ "column": 6,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": "v-bind:style",
+ "type": 7,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 1,
+ },
+ {
+ "content": " a comment with inside it ",
+ "loc": {
+ "end": {
+ "column": 43,
+ "line": 3,
+ "offset": 116,
+ },
+ "source": "",
+ "start": {
+ "column": 3,
+ "line": 3,
+ "offset": 76,
},
},
"type": 3,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "class",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "{ some: condition }",
+ "start": {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class="{ some: condition }"",
+ "start": {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": ":class",
+ "type": 7,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
+exports[`compiler: parse > Errors > CDATA_IN_HTML_CONTENT > 1`] = `
+{
+ "cached": [],
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
"column": 39,
@@ -275,14 +542,15 @@ exports[`compiler: parse Errors CDATA_IN_HTML_CONTENT ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors CDATA_IN_HTML_CONTENT 1`] = `
+exports[`compiler: parse > Errors > CDATA_IN_HTML_CONTENT > 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
@@ -307,7 +575,6 @@ exports[`compiler: parse Errors CDATA_IN_HTML_CONTENT ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors DUPLICATE_ATTRIBUTE
1`] = `
+exports[`compiler: parse > Errors > DUPLICATE_ATTRIBUTE >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
"children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
"column": 34,
@@ -414,6 +680,19 @@ exports[`compiler: parse Errors DUPLICATE_ATTRIBUTE <
},
},
"name": "id",
+ "nameLoc": {
+ "end": {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "id",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
"type": 6,
"value": {
"content": "",
@@ -448,6 +727,19 @@ exports[`compiler: parse Errors DUPLICATE_ATTRIBUTE
<
},
},
"name": "id",
+ "nameLoc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id",
+ "start": {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ },
"type": 6,
"value": {
"content": "",
@@ -474,7 +766,6 @@ exports[`compiler: parse Errors DUPLICATE_ATTRIBUTE
<
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
"column": 45,
@@ -514,50 +805,44 @@ exports[`compiler: parse Errors DUPLICATE_ATTRIBUTE
<
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors END_TAG_WITH_ATTRIBUTES
1`] = `
+exports[`compiler: parse > Errors > EOF_BEFORE_TAG_NAME >
< 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "content": "<",
"loc": {
"end": {
- "column": 28,
+ "column": 12,
"line": 1,
- "offset": 27,
+ "offset": 11,
},
- "source": "
",
+ "source": "<",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
+ "type": 2,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 39,
+ "column": 12,
"line": 1,
- "offset": 38,
+ "offset": 11,
},
- "source": "
",
+ "source": "<",
"start": {
"column": 1,
"line": 1,
@@ -579,183 +864,38 @@ exports[`compiler: parse Errors END_TAG_WITH_ATTRIBUTES
",
+ "source": "<",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "<",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors END_TAG_WITH_TRAILING_SOLIDUS
1`] = `
+exports[`compiler: parse > Errors > EOF_BEFORE_TAG_NAME > 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "content": "",
"loc": {
"end": {
- "column": 23,
+ "column": 13,
"line": 1,
- "offset": 22,
+ "offset": 12,
},
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors EOF_BEFORE_TAG_NAME < 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "<",
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "<",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 2,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "<",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "<",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors EOF_BEFORE_TAG_NAME 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "",
- "loc": {
- "end": {
- "column": 13,
- "line": 1,
- "offset": 12,
- },
- "source": "",
+ "source": "",
"start": {
"column": 11,
"line": 1,
@@ -766,7 +906,6 @@ exports[`compiler: parse Errors EOF_BEFORE_TAG_NAME 1`] = `
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
"column": 13,
@@ -806,21 +945,21 @@ exports[`compiler: parse Errors EOF_BEFORE_TAG_NAME 1`] = `
"offset": 0,
},
},
+ "source": "",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors EOF_IN_CDATA Errors > EOF_IN_CDATA > Errors > EOF_IN_CDATA > Errors > EOF_IN_COMMENT > 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "comment",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 26,
+ "column": 30,
"line": 1,
- "offset": 25,
+ "offset": 29,
},
- "source": "",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": " ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": " ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "content": "DOCTYPE html",
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "",
- "loc": {
- "end": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- "source": "",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "a ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3018,55 +2796,108 @@ exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "-",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 15,
+ "column": 31,
"line": 1,
- "offset": 14,
+ "offset": 30,
},
- "source": "",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "foo=bar"",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "nameLoc": {
+ "end": {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "foo",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 6,
+ "value": {
+ "content": "bar"",
+ "loc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar"",
+ "start": {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 2,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 26,
+ "column": 42,
"line": 1,
- "offset": 25,
+ "offset": 41,
},
- "source": " ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3088,55 +2919,108 @@ exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "ELEMENT br EMPTY",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 30,
+ "column": 31,
"line": 1,
- "offset": 29,
+ "offset": 30,
},
- "source": "",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "foo=bar'",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "nameLoc": {
+ "end": {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "foo",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 6,
+ "value": {
+ "content": "bar'",
+ "loc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar'",
+ "start": {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 2,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 41,
+ "column": 42,
"line": 1,
- "offset": 40,
+ "offset": 41,
},
- "source": " ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3158,55 +3042,108 @@ exports[`compiler: parse Errors INCORRECTLY_OPENED_COMMENT ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME �> 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "�",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 15,
+ "column": 34,
"line": 1,
- "offset": 14,
+ "offset": 33,
},
- "source": "�>",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "foo=bar�>",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3228,55 +3165,108 @@ exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME
"imports": [],
"loc": {
"end": {
- "column": 26,
+ "column": 45,
"line": 1,
- "offset": 25,
+ "offset": 44,
},
- "source": "�> ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME <�> 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "<�>",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 14,
+ "column": 34,
"line": 1,
- "offset": 13,
+ "offset": 33,
},
- "source": "<�>",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 2,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "foo=bar=baz",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "nameLoc": {
+ "end": {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "foo",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 6,
+ "value": {
+ "content": "bar=baz",
+ "loc": {
+ "end": {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "bar=baz",
+ "start": {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 2,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 25,
+ "column": 45,
"line": 1,
- "offset": 24,
+ "offset": 44,
},
- "source": "<�> ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3298,73 +3288,108 @@ exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME <
"imports": [],
"loc": {
"end": {
- "column": 25,
+ "column": 45,
"line": 1,
- "offset": 24,
+ "offset": 44,
},
- "source": "<�> ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME {{a < b}} 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": {
- "constType": 0,
- "content": "a < b",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 18,
- "line": 1,
- "offset": 17,
- },
- "source": "a < b",
- "start": {
- "column": 13,
- "line": 1,
- "offset": 12,
- },
- },
- "type": 4,
- },
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 20,
+ "column": 31,
"line": 1,
- "offset": 19,
+ "offset": 30,
},
- "source": "{{a < b}}",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 5,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "foo=bar\`",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "nameLoc": {
+ "end": {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "foo",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 6,
+ "value": {
+ "content": "bar\`",
+ "loc": {
+ "end": {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar\`",
+ "start": {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 2,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 31,
+ "column": 42,
"line": 1,
- "offset": 30,
+ "offset": 41,
},
- "source": "{{a < b}} ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3386,142 +3411,92 @@ exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME {{
"imports": [],
"loc": {
"end": {
- "column": 31,
+ "column": 42,
"line": 1,
- "offset": 30,
+ "offset": 41,
},
- "source": "{{a < b}} ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME a < b 1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "a < b",
+ "children": [],
+ "codegenNode": undefined,
"loc": {
"end": {
- "column": 16,
+ "column": 24,
"line": 1,
- "offset": 15,
+ "offset": 23,
},
- "source": "a < b",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 2,
+ "ns": 0,
+ "props": [
+ {
+ "loc": {
+ "end": {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "=",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "=",
+ "nameLoc": {
+ "end": {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "=",
+ "start": {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 6,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 27,
+ "column": 35,
"line": 1,
- "offset": 26,
+ "offset": 34,
},
- "source": "a < b ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "a < b ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME a b 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "a ",
- "loc": {
- "end": {
- "column": 13,
- "line": 1,
- "offset": 12,
- },
- "source": "a ",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 2,
- },
- {
- "content": " b ",
- "start": {
- "column": 13,
- "line": 1,
- "offset": 12,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 28,
- "line": 1,
- "offset": 27,
- },
- "source": "a b ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3543,39 +3518,39 @@ exports[`compiler: parse Errors INVALID_FIRST_CHARACTER_OF_TAG_NAME a
"imports": [],
"loc": {
"end": {
- "column": 28,
+ "column": 35,
"line": 1,
- "offset": 27,
+ "offset": 34,
},
- "source": "a b ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
"children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 28,
+ "column": 31,
"line": 1,
- "offset": 27,
+ "offset": 30,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
@@ -3587,32 +3562,45 @@ exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3654,80 +3641,37 @@ exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 20,
- "line": 1,
- "offset": 19,
- },
- "source": "id= ",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "id",
- "type": 6,
- "value": undefined,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
+ "children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 38,
+ "column": 29,
"line": 1,
- "offset": 37,
+ "offset": 28,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3749,39 +3693,39 @@ exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
1`] = `
+exports[`compiler: parse > Errors > UNEXPECTED_SOLIDUS_IN_TAG >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
"children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
"column": 26,
"line": 1,
"offset": 25,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
@@ -3793,18 +3737,62 @@ exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -3848,42 +3835,60 @@ exports[`compiler: parse Errors MISSING_ATTRIBUTE_VALUE
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors MISSING_END_TAG_NAME
> 1`] = `
+exports[`compiler: parse > Errors > X_INVALID_END_TAG >
]]> 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 25,
- "line": 1,
- "offset": 24,
+ "children": [
+ {
+ "content": "
",
+ "loc": {
+ "end": {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": " ",
+ "start": {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ },
+ "type": 2,
},
- "source": "> ",
+ ],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "]]> ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
- "ns": 0,
+ "ns": 1,
"props": [],
- "tag": "template",
+ "tag": "svg",
"tagType": 0,
"type": 1,
},
@@ -3896,141 +3901,64 @@ exports[`compiler: parse Errors MISSING_END_TAG_NAME > 1`
"imports": [],
"loc": {
"end": {
- "column": 25,
+ "column": 30,
"line": 1,
- "offset": 24,
+ "offset": 29,
},
- "source": "> ",
+ "source": "]]> ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "]]> ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors MISSING_WHITESPACE_BETWEEN_ATTRIBUTES
1`] = `
+exports[`compiler: parse > Errors > X_INVALID_END_TAG > 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "content": "",
"loc": {
"end": {
"column": 19,
- "line": 2,
- "offset": 43,
+ "line": 1,
+ "offset": 18,
},
- "source": "
",
+ "source": "",
"start": {
- "column": 11,
+ "column": 6,
"line": 1,
- "offset": 10,
+ "offset": 5,
},
},
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "id="foo"",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "id",
- "type": 6,
- "value": {
- "content": "foo",
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": ""foo"",
- "start": {
- "column": 19,
- "line": 1,
- "offset": 18,
- },
- },
- "type": 2,
- },
- },
- {
- "loc": {
- "end": {
- "column": 12,
- "line": 2,
- "offset": 36,
- },
- "source": "class="bar"",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 25,
- },
- },
- "name": "class",
- "type": 6,
- "value": {
- "content": "bar",
- "loc": {
- "end": {
- "column": 12,
- "line": 2,
- "offset": 36,
- },
- "source": ""bar"",
- "start": {
- "column": 7,
- "line": 2,
- "offset": 31,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
+ "type": 3,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 30,
- "line": 2,
- "offset": 54,
+ "column": 25,
+ "line": 1,
+ "offset": 24,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
- "ns": 0,
+ "ns": 1,
"props": [],
- "tag": "template",
+ "tag": "svg",
"tagType": 0,
"type": 1,
},
@@ -4043,131 +3971,37 @@ class="bar">
",
"imports": [],
"loc": {
"end": {
- "column": 30,
- "line": 2,
- "offset": 54,
+ "column": 25,
+ "line": 1,
+ "offset": 24,
},
- "source": "
",
+ "source": " ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": " ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors MISSING_WHITESPACE_BETWEEN_ATTRIBUTES
1`] = `
+exports[`compiler: parse > Errors > X_INVALID_END_TAG > 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 42,
- "line": 1,
- "offset": 41,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "id="foo"",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "id",
- "type": 6,
- "value": {
- "content": "foo",
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": ""foo"",
- "start": {
- "column": 19,
- "line": 1,
- "offset": 18,
- },
- },
- "type": 2,
- },
- },
- {
- "loc": {
- "end": {
- "column": 35,
- "line": 1,
- "offset": 34,
- },
- "source": "class="bar"",
- "start": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- },
- "name": "class",
- "type": 6,
- "value": {
- "content": "bar",
- "loc": {
- "end": {
- "column": 35,
- "line": 1,
- "offset": 34,
- },
- "source": ""bar"",
- "start": {
- "column": 30,
- "line": 1,
- "offset": 29,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
+ "children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 53,
+ "column": 34,
"line": 1,
- "offset": 52,
+ "offset": 33,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -4189,55 +4023,37 @@ exports[`compiler: parse Errors MISSING_WHITESPACE_BETWEEN_ATTRIBUTES
"imports": [],
"loc": {
"end": {
- "column": 53,
+ "column": 34,
"line": 1,
- "offset": 52,
+ "offset": 33,
},
- "source": "
",
+ "source": " ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": " ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors NESTED_COMMENT 1`] = `
+exports[`compiler: parse > Errors > X_INVALID_END_TAG > {{''}} 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "a'",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "''",
+ "start": {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ },
+ "type": 4,
+ },
"loc": {
"end": {
- "column": 21,
+ "column": 23,
"line": 1,
- "offset": 20,
+ "offset": 22,
},
- "source": "",
+ "source": "{{''}}",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
+ "type": 5,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 32,
+ "column": 34,
"line": 1,
- "offset": 31,
+ "offset": 33,
},
- "source": " ",
+ "source": "{{''}} ",
"start": {
"column": 1,
"line": 1,
@@ -4329,55 +4163,55 @@ exports[`compiler: parse Errors NESTED_COMMENT 1
"imports": [],
"loc": {
"end": {
- "column": 32,
+ "column": 34,
"line": 1,
- "offset": 31,
+ "offset": 33,
},
- "source": " ",
+ "source": "{{''}} ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "{{''}} ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors NESTED_COMMENT 1`] = `
+exports[`compiler: parse > Errors > X_INVALID_END_TAG > a b 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "a",
+ "source": "a ",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
+ "type": 2,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 39,
+ "column": 28,
"line": 1,
- "offset": 38,
+ "offset": 27,
},
- "source": " ",
+ "source": "a b ",
"start": {
"column": 1,
"line": 1,
@@ -4399,55 +4233,55 @@ exports[`compiler: parse Errors NESTED_COMMENT ",
+ "source": "a b ",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "a b ",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors NESTED_COMMENT 1`] = `
+exports[`compiler: parse > Errors > X_INVALID_END_TAG > 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "content": "a",
+ "source": "",
"start": {
"column": 11,
"line": 1,
"offset": 10,
},
},
- "type": 3,
+ "type": 2,
},
],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 40,
+ "column": 28,
"line": 1,
- "offset": 39,
+ "offset": 27,
},
- "source": " ",
+ "source": "",
"start": {
"column": 1,
"line": 1,
@@ -4456,7 +4290,7 @@ exports[`compiler: parse Errors NESTED_COMMENT ",
+ "source": "",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors NESTED_COMMENT 1`] = `
+exports[`compiler: parse > Errors > X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "content": "a",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 3,
- },
- ],
+ "children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
+ "isSelfClosing": true,
"loc": {
"end": {
- "column": 35,
+ "column": 25,
"line": 1,
- "offset": 34,
+ "offset": 24,
},
- "source": " ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -4525,8 +4342,79 @@ exports[`compiler: parse Errors NESTED_COMMENT ",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
1`] = `
+exports[`compiler: parse > Errors > X_MISSING_END_TAG > 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
"children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 30,
+ "column": 16,
"line": 1,
- "offset": 29,
+ "offset": 15,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
@@ -4579,56 +4467,20 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -4650,39 +4502,39 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
1`] = `
+exports[`compiler: parse > Errors > X_MISSING_END_TAG >
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
"children": [],
"codegenNode": undefined,
- "isSelfClosing": false,
"loc": {
"end": {
- "column": 30,
+ "column": 16,
"line": 1,
- "offset": 29,
+ "offset": 15,
},
- "source": "
",
+ "source": "
",
"start": {
"column": 11,
"line": 1,
@@ -4690,56 +4542,20 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
@@ -4761,96 +4577,55 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
",
+ "source": "
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
1`] = `
+exports[`compiler: parse > Errors > X_MISSING_INTERPOLATION_END >
{{ foo
1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
"children": [
{
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "content": "{{ foo
",
"loc": {
"end": {
- "column": 30,
+ "column": 18,
"line": 1,
- "offset": 29,
+ "offset": 17,
},
- "source": "
",
+ "source": "{{ foo ",
"start": {
- "column": 11,
+ "column": 6,
"line": 1,
- "offset": 10,
+ "offset": 5,
},
},
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 23,
- "line": 1,
- "offset": 22,
- },
- "source": "a
",
+ "source": "
{{ foo
",
"start": {
"column": 1,
"line": 1,
@@ -4859,7 +4634,7 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME
",
+ "source": "
{{ foo
",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "
{{ foo
",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
1`] = `
+exports[`compiler: parse > Errors > X_MISSING_INTERPOLATION_END > {{ 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 31,
- "line": 1,
- "offset": 30,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "foo=bar"",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "foo",
- "type": 6,
- "value": {
- "content": "bar"",
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "bar"",
- "start": {
- "column": 20,
- "line": 1,
- "offset": 19,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "content": "{{",
"loc": {
"end": {
- "column": 42,
+ "column": 3,
"line": 1,
- "offset": 41,
+ "offset": 2,
},
- "source": "
",
+ "source": "{{",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
+ "type": 2,
},
],
"codegenNode": undefined,
@@ -4983,107 +4694,43 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
"imports": [],
"loc": {
"end": {
- "column": 42,
+ "column": 3,
"line": 1,
- "offset": 41,
+ "offset": 2,
},
- "source": "
",
+ "source": "{{",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "{{",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
1`] = `
+exports[`compiler: parse > Errors > X_MISSING_INTERPOLATION_END > {{ foo 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 31,
- "line": 1,
- "offset": 30,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "foo=bar'",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "foo",
- "type": 6,
- "value": {
- "content": "bar'",
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "bar'",
- "start": {
- "column": 20,
- "line": 1,
- "offset": 19,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "content": "{{ foo",
"loc": {
"end": {
- "column": 42,
+ "column": 7,
"line": 1,
- "offset": 41,
+ "offset": 6,
},
- "source": "
",
+ "source": "{{ foo",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
+ "type": 2,
},
],
"codegenNode": undefined,
@@ -5094,218 +4741,61 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
"imports": [],
"loc": {
"end": {
- "column": 42,
+ "column": 7,
"line": 1,
- "offset": 41,
+ "offset": 6,
},
- "source": "
",
+ "source": "{{ foo",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "{{ foo",
"temps": 0,
"type": 0,
}
`;
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
1`] = `
+exports[`compiler: parse > Errors > X_MISSING_INTERPOLATION_END > {{}} 1`] = `
{
- "cached": 0,
+ "cached": [],
"children": [
{
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
+ "content": {
+ "constType": 0,
+ "content": "",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 3,
+ "line": 1,
+ "offset": 2,
},
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "foo=bar
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 45,
- "line": 1,
- "offset": 44,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
+ "source": "",
+ "start": {
+ "column": 3,
+ "line": 1,
+ "offset": 2,
},
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "foo=bar=baz",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "foo",
- "type": 6,
- "value": {
- "content": "bar=baz",
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "bar=baz",
- "start": {
- "column": 20,
- "line": 1,
- "offset": 19,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
},
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
+ "type": 4,
+ },
"loc": {
"end": {
- "column": 45,
+ "column": 5,
"line": 1,
- "offset": 44,
+ "offset": 4,
},
- "source": "
",
+ "source": "{{}}",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
+ "type": 5,
},
],
"codegenNode": undefined,
@@ -5316,1821 +4806,18 @@ exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
"imports": [],
"loc": {
"end": {
- "column": 45,
- "line": 1,
- "offset": 44,
- },
- "source": "
",
- "start": {
- "column": 1,
+ "column": 5,
"line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 31,
- "line": 1,
- "offset": 30,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "foo=bar\`",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "foo",
- "type": 6,
- "value": {
- "content": "bar\`",
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "bar\`",
- "start": {
- "column": 20,
- "line": 1,
- "offset": 19,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 42,
- "line": 1,
- "offset": 41,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
+ "offset": 4,
},
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 42,
- "line": 1,
- "offset": 41,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 17,
- "line": 1,
- "offset": 16,
- },
- "source": "=",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "=",
- "type": 6,
- "value": undefined,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 35,
- "line": 1,
- "offset": 34,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 35,
- "line": 1,
- "offset": 34,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 31,
- "line": 1,
- "offset": 30,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "=foo=bar",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "=foo",
- "type": 6,
- "value": {
- "content": "bar",
- "loc": {
- "end": {
- "column": 24,
- "line": 1,
- "offset": 23,
- },
- "source": "bar",
- "start": {
- "column": 21,
- "line": 1,
- "offset": 20,
- },
- },
- "type": 2,
- },
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 42,
- "line": 1,
- "offset": 41,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 42,
- "line": 1,
- "offset": 41,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "?xml?",
- "loc": {
- "end": {
- "column": 18,
- "line": 1,
- "offset": 17,
- },
- "source": "",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 29,
- "line": 1,
- "offset": 28,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 29,
- "line": 1,
- "offset": 28,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors UNEXPECTED_SOLIDUS_IN_TAG
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 26,
- "line": 1,
- "offset": 25,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [
- {
- "loc": {
- "end": {
- "column": 17,
- "line": 1,
- "offset": 16,
- },
- "source": "a",
- "start": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- },
- "name": "a",
- "type": 6,
- "value": undefined,
- },
- {
- "loc": {
- "end": {
- "column": 19,
- "line": 1,
- "offset": 18,
- },
- "source": "b",
- "start": {
- "column": 18,
- "line": 1,
- "offset": 17,
- },
- },
- "name": "b",
- "type": 6,
- "value": undefined,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_INVALID_END_TAG
]]> 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "
",
- "loc": {
- "end": {
- "column": 21,
- "line": 1,
- "offset": 20,
- },
- "source": "
",
- "start": {
- "column": 15,
- "line": 1,
- "offset": 14,
- },
- },
- "type": 2,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 30,
- "line": 1,
- "offset": 29,
- },
- "source": "]]> ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 1,
- "props": [],
- "tag": "svg",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 30,
- "line": 1,
- "offset": 29,
- },
- "source": "]]> ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_INVALID_END_TAG 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "",
- "loc": {
- "end": {
- "column": 19,
- "line": 1,
- "offset": 18,
- },
- "source": "",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 25,
- "line": 1,
- "offset": 24,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 1,
- "props": [],
- "tag": "svg",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 25,
- "line": 1,
- "offset": 24,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_INVALID_END_TAG
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_INVALID_END_TAG 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 28,
- "line": 1,
- "offset": 27,
- },
- "source": " ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 28,
- "line": 1,
- "offset": 27,
- },
- "source": " ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_INVALID_END_TAG {{''}} 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": {
- "constType": 0,
- "content": "''",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 21,
- "line": 1,
- "offset": 20,
- },
- "source": "''",
- "start": {
- "column": 13,
- "line": 1,
- "offset": 12,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 23,
- "line": 1,
- "offset": 22,
- },
- "source": "{{''}}",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 5,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "{{''}} ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": "{{''}} ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_INVALID_END_TAG 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "content": "",
- "loc": {
- "end": {
- "column": 17,
- "line": 1,
- "offset": 16,
- },
- "source": "",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "type": 2,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 28,
- "line": 1,
- "offset": 27,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "textarea",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 28,
- "line": 1,
- "offset": 27,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 25,
- "line": 1,
- "offset": 24,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 0,
- "content": "sef",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "[sef",
- "start": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- },
- "type": 4,
- },
- "exp": undefined,
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "v-foo:[sef",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "foo",
- "type": 7,
- },
- {
- "loc": {
- "end": {
- "column": 22,
- "line": 1,
- "offset": 21,
- },
- "source": "fsef]",
- "start": {
- "column": 17,
- "line": 1,
- "offset": 16,
- },
- },
- "name": "fsef]",
- "type": 6,
- "value": undefined,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 25,
- "line": 1,
- "offset": 24,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_MISSING_END_TAG 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_MISSING_END_TAG
1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 16,
- "line": 1,
- "offset": 15,
- },
- "source": "
",
- "start": {
- "column": 11,
- "line": 1,
- "offset": 10,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "template",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 27,
- "line": 1,
- "offset": 26,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_MISSING_INTERPOLATION_END {{ 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "content": "{{",
- "loc": {
- "end": {
- "column": 3,
- "line": 1,
- "offset": 2,
- },
- "source": "{{",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "type": 2,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 3,
- "line": 1,
- "offset": 2,
- },
- "source": "{{",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_MISSING_INTERPOLATION_END {{ foo 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "content": "{{ foo",
- "loc": {
- "end": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- "source": "{{ foo",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "type": 2,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- "source": "{{ foo",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse Errors X_MISSING_INTERPOLATION_END {{}} 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "content": {
- "constType": 0,
- "content": "",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 3,
- "line": 1,
- "offset": 2,
- },
- "source": "",
- "start": {
- "column": 3,
- "line": 1,
- "offset": 2,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 5,
- "line": 1,
- "offset": 4,
- },
- "source": "{{}}",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "type": 5,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 5,
- "line": 1,
- "offset": 4,
- },
- "source": "{{}}",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse invalid html 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 1,
- "line": 3,
- "offset": 13,
- },
- "source": "
-",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 6,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "span",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 7,
- "line": 3,
- "offset": 19,
- },
- "source": "
-
-
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 8,
- "line": 4,
- "offset": 27,
- },
- "source": "
-
-
- ",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse self closing multiple tag 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "class",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "class",
- "start": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ some: condition }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 33,
- "line": 1,
- "offset": 32,
- },
- "source": "{ some: condition }",
- "start": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": ":class="{ some: condition }"",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "bind",
- "type": 7,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 73,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 37,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "style",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 16,
- "line": 2,
- "offset": 52,
- },
- "source": "style",
- "start": {
- "column": 11,
- "line": 2,
- "offset": 47,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ color: 'red' }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 2,
- "offset": 70,
- },
- "source": "{ color: 'red' }",
- "start": {
- "column": 18,
- "line": 2,
- "offset": 54,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 35,
- "line": 2,
- "offset": 71,
- },
- "source": "v-bind:style="{ color: 'red' }"",
- "start": {
- "column": 4,
- "line": 2,
- "offset": 40,
- },
- },
- "modifiers": [],
- "name": "bind",
- "type": 7,
- },
- ],
- "tag": "p",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 73,
- },
- "source": "
-
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse valid html 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 39,
- "line": 2,
- "offset": 73,
- },
- "source": "
",
- "start": {
- "column": 3,
- "line": 2,
- "offset": 37,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "style",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 18,
- "line": 2,
- "offset": 52,
- },
- "source": "style",
- "start": {
- "column": 13,
- "line": 2,
- "offset": 47,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ color: 'red' }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 36,
- "line": 2,
- "offset": 70,
- },
- "source": "{ color: 'red' }",
- "start": {
- "column": 20,
- "line": 2,
- "offset": 54,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 71,
- },
- "source": "v-bind:style="{ color: 'red' }"",
- "start": {
- "column": 6,
- "line": 2,
- "offset": 40,
- },
- },
- "modifiers": [],
- "name": "bind",
- "type": 7,
- },
- ],
- "tag": "p",
- "tagType": 0,
- "type": 1,
- },
- {
- "content": " a comment with inside it ",
- "loc": {
- "end": {
- "column": 43,
- "line": 3,
- "offset": 116,
- },
- "source": "",
- "start": {
- "column": 3,
- "line": 3,
- "offset": 76,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "isSelfClosing": false,
- "loc": {
- "end": {
- "column": 7,
- "line": 4,
- "offset": 123,
- },
- "source": "
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "class",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "class",
- "start": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ some: condition }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 33,
- "line": 1,
- "offset": 32,
- },
- "source": "{ some: condition }",
- "start": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": ":class="{ some: condition }"",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "bind",
- "type": 7,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 7,
- "line": 4,
- "offset": 123,
- },
- "source": "
",
+ "source": "{{}}",
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
+ "source": "{{}}",
"temps": 0,
"type": 0,
}
diff --git a/packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap
index 4f20eabbad5..97aff163ecb 100644
--- a/packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap
@@ -1,22 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
-"import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from "vue"
-
-const _withScopeId = n => (_pushScopeId("test"),n=n(),_popScopeId(),n)
-const _hoisted_1 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode("div", null, "hello", -1 /* HOISTED */))
-const _hoisted_2 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode("div", null, "world", -1 /* HOISTED */))
-
-export function render(_ctx, _cache) {
- return (_openBlock(), _createElementBlock("div", null, [
- _hoisted_1,
- _createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */),
- _hoisted_2
- ]))
-}"
-`;
-
-exports[`scopeId compiler support should wrap default slot 1`] = `
+exports[`scopeId compiler support > should wrap default slot 1`] = `
"import { createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from "vue"
export function render(_ctx, _cache) {
@@ -31,7 +15,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`scopeId compiler support should wrap dynamic slots 1`] = `
+exports[`scopeId compiler support > should wrap dynamic slots 1`] = `
"import { createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock } from "vue"
export function render(_ctx, _cache) {
@@ -59,7 +43,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`scopeId compiler support should wrap named slots 1`] = `
+exports[`scopeId compiler support > should wrap named slots 1`] = `
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from "vue"
export function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/codegen.spec.ts b/packages/compiler-core/__tests__/codegen.spec.ts
index 3f9120471bb..34386ce6930 100644
--- a/packages/compiler-core/__tests__/codegen.spec.ts
+++ b/packages/compiler-core/__tests__/codegen.spec.ts
@@ -1,38 +1,38 @@
import {
- locStub,
- generate,
+ ConstantTypes,
+ type DirectiveArguments,
+ type ForCodegenNode,
+ type IfConditionalExpression,
NodeTypes,
- RootNode,
- createSimpleExpression,
- createObjectExpression,
- createObjectProperty,
+ type RootNode,
+ type VNodeCall,
createArrayExpression,
- createCompoundExpression,
- createInterpolation,
+ createAssignmentExpression,
+ createBlockStatement,
+ createCacheExpression,
createCallExpression,
+ createCompoundExpression,
createConditionalExpression,
- ForCodegenNode,
- createCacheExpression,
- createTemplateLiteral,
- createBlockStatement,
createIfStatement,
- createAssignmentExpression,
- IfConditionalExpression,
+ createInterpolation,
+ createObjectExpression,
+ createObjectProperty,
+ createSimpleExpression,
+ createTemplateLiteral,
createVNodeCall,
- VNodeCall,
- DirectiveArguments,
- ConstantTypes
+ generate,
+ locStub,
} from '../src'
import {
- CREATE_VNODE,
- TO_DISPLAY_STRING,
- RESOLVE_DIRECTIVE,
- helperNameMap,
- RESOLVE_COMPONENT,
CREATE_COMMENT,
+ CREATE_ELEMENT_VNODE,
+ CREATE_VNODE,
FRAGMENT,
RENDER_LIST,
- CREATE_ELEMENT_VNODE
+ RESOLVE_COMPONENT,
+ RESOLVE_DIRECTIVE,
+ TO_DISPLAY_STRING,
+ helperNameMap,
} from '../src/runtimeHelpers'
import { createElementWithCodegen, genFlagText } from './testUtils'
import { PatchFlags } from '@vue/shared'
@@ -40,69 +40,70 @@ import { PatchFlags } from '@vue/shared'
function createRoot(options: Partial
= {}): RootNode {
return {
type: NodeTypes.ROOT,
+ source: '',
children: [],
helpers: new Set(),
components: [],
directives: [],
imports: [],
hoists: [],
- cached: 0,
+ cached: [],
temps: 0,
codegenNode: createSimpleExpression(`null`, false),
loc: locStub,
- ...options
+ ...options,
}
}
describe('compiler: codegen', () => {
test('module mode preamble', () => {
const root = createRoot({
- helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
+ helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE]),
})
const { code } = generate(root, { mode: 'module' })
expect(code).toMatch(
- `import { ${helperNameMap[CREATE_VNODE]} as _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]} as _${helperNameMap[RESOLVE_DIRECTIVE]} } from "vue"`
+ `import { ${helperNameMap[CREATE_VNODE]} as _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]} as _${helperNameMap[RESOLVE_DIRECTIVE]} } from "vue"`,
)
expect(code).toMatchSnapshot()
})
test('module mode preamble w/ optimizeImports: true', () => {
const root = createRoot({
- helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
+ helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE]),
})
const { code } = generate(root, { mode: 'module', optimizeImports: true })
expect(code).toMatch(
- `import { ${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]} } from "vue"`
+ `import { ${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]} } from "vue"`,
)
expect(code).toMatch(
- `const _${helperNameMap[CREATE_VNODE]} = ${helperNameMap[CREATE_VNODE]}, _${helperNameMap[RESOLVE_DIRECTIVE]} = ${helperNameMap[RESOLVE_DIRECTIVE]}`
+ `const _${helperNameMap[CREATE_VNODE]} = ${helperNameMap[CREATE_VNODE]}, _${helperNameMap[RESOLVE_DIRECTIVE]} = ${helperNameMap[RESOLVE_DIRECTIVE]}`,
)
expect(code).toMatchSnapshot()
})
test('function mode preamble', () => {
const root = createRoot({
- helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
+ helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE]),
})
const { code } = generate(root, { mode: 'function' })
expect(code).toMatch(`const _Vue = Vue`)
expect(code).toMatch(
- `const { ${helperNameMap[CREATE_VNODE]}: _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${helperNameMap[RESOLVE_DIRECTIVE]} } = _Vue`
+ `const { ${helperNameMap[CREATE_VNODE]}: _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${helperNameMap[RESOLVE_DIRECTIVE]} } = _Vue`,
)
expect(code).toMatchSnapshot()
})
test('function mode preamble w/ prefixIdentifiers: true', () => {
const root = createRoot({
- helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
+ helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE]),
})
const { code } = generate(root, {
mode: 'function',
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(code).not.toMatch(`const _Vue = Vue`)
expect(code).toMatch(
- `const { ${helperNameMap[CREATE_VNODE]}: _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${helperNameMap[RESOLVE_DIRECTIVE]} } = Vue`
+ `const { ${helperNameMap[CREATE_VNODE]}: _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${helperNameMap[RESOLVE_DIRECTIVE]} } = Vue`,
)
expect(code).toMatchSnapshot()
})
@@ -111,27 +112,27 @@ describe('compiler: codegen', () => {
const root = createRoot({
components: [`Foo`, `bar-baz`, `barbaz`, `Qux__self`],
directives: [`my_dir_0`, `my_dir_1`],
- temps: 3
+ temps: 3,
})
const { code } = generate(root, { mode: 'function' })
expect(code).toMatch(
- `const _component_Foo = _${helperNameMap[RESOLVE_COMPONENT]}("Foo")\n`
+ `const _component_Foo = _${helperNameMap[RESOLVE_COMPONENT]}("Foo")\n`,
)
expect(code).toMatch(
- `const _component_bar_baz = _${helperNameMap[RESOLVE_COMPONENT]}("bar-baz")\n`
+ `const _component_bar_baz = _${helperNameMap[RESOLVE_COMPONENT]}("bar-baz")\n`,
)
expect(code).toMatch(
- `const _component_barbaz = _${helperNameMap[RESOLVE_COMPONENT]}("barbaz")\n`
+ `const _component_barbaz = _${helperNameMap[RESOLVE_COMPONENT]}("barbaz")\n`,
)
// implicit self reference from SFC filename
expect(code).toMatch(
- `const _component_Qux = _${helperNameMap[RESOLVE_COMPONENT]}("Qux", true)\n`
+ `const _component_Qux = _${helperNameMap[RESOLVE_COMPONENT]}("Qux", true)\n`,
)
expect(code).toMatch(
- `const _directive_my_dir_0 = _${helperNameMap[RESOLVE_DIRECTIVE]}("my_dir_0")\n`
+ `const _directive_my_dir_0 = _${helperNameMap[RESOLVE_DIRECTIVE]}("my_dir_0")\n`,
)
expect(code).toMatch(
- `const _directive_my_dir_1 = _${helperNameMap[RESOLVE_DIRECTIVE]}("my_dir_1")\n`
+ `const _directive_my_dir_1 = _${helperNameMap[RESOLVE_DIRECTIVE]}("my_dir_1")\n`,
)
expect(code).toMatch(`let _temp0, _temp1, _temp2`)
expect(code).toMatchSnapshot()
@@ -145,12 +146,12 @@ describe('compiler: codegen', () => {
[
createObjectProperty(
createSimpleExpression(`id`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- )
+ createSimpleExpression(`foo`, true, locStub),
+ ),
],
- locStub
- )
- ]
+ locStub,
+ ),
+ ],
})
const { code } = generate(root)
expect(code).toMatch(`const _hoisted_1 = hello`)
@@ -160,7 +161,7 @@ describe('compiler: codegen', () => {
test('temps', () => {
const root = createRoot({
- temps: 3
+ temps: 3,
})
const { code } = generate(root)
expect(code).toMatch(`let _temp0, _temp1, _temp2`)
@@ -173,9 +174,9 @@ describe('compiler: codegen', () => {
codegenNode: {
type: NodeTypes.TEXT,
content: 'hello',
- loc: locStub
- }
- })
+ loc: locStub,
+ },
+ }),
)
expect(code).toMatch(`return "hello"`)
expect(code).toMatchSnapshot()
@@ -184,8 +185,8 @@ describe('compiler: codegen', () => {
test('interpolation', () => {
const { code } = generate(
createRoot({
- codegenNode: createInterpolation(`hello`, locStub)
- })
+ codegenNode: createInterpolation(`hello`, locStub),
+ }),
)
expect(code).toMatch(`return _${helperNameMap[TO_DISPLAY_STRING]}(hello)`)
expect(code).toMatchSnapshot()
@@ -197,9 +198,9 @@ describe('compiler: codegen', () => {
codegenNode: {
type: NodeTypes.COMMENT,
content: 'foo',
- loc: locStub
- }
- })
+ loc: locStub,
+ },
+ }),
)
expect(code).toMatch(`return _${helperNameMap[CREATE_COMMENT]}("foo")`)
expect(code).toMatchSnapshot()
@@ -215,15 +216,15 @@ describe('compiler: codegen', () => {
{
type: NodeTypes.INTERPOLATION,
loc: locStub,
- content: createSimpleExpression(`bar`, false, locStub)
+ content: createSimpleExpression(`bar`, false, locStub),
},
// nested compound
- createCompoundExpression([` + `, `nested`])
- ])
- })
+ createCompoundExpression([` + `, `nested`]),
+ ]),
+ }),
)
expect(code).toMatch(
- `return _ctx.foo + _${helperNameMap[TO_DISPLAY_STRING]}(bar) + nested`
+ `return _ctx.foo + _${helperNameMap[TO_DISPLAY_STRING]}(bar) + nested`,
)
expect(code).toMatchSnapshot()
})
@@ -238,10 +239,10 @@ describe('compiler: codegen', () => {
codegenNode: createConditionalExpression(
createSimpleExpression('foo', false),
createSimpleExpression('bar', false),
- createSimpleExpression('baz', false)
- ) as IfConditionalExpression
- }
- })
+ createSimpleExpression('baz', false),
+ ) as IfConditionalExpression,
+ },
+ }),
)
expect(code).toMatch(/return foo\s+\? bar\s+: baz/)
expect(code).toMatchSnapshot()
@@ -266,13 +267,13 @@ describe('compiler: codegen', () => {
disableTracking: true,
props: undefined,
children: createCallExpression(RENDER_LIST),
- patchFlag: '1',
+ patchFlag: PatchFlags.TEXT,
dynamicProps: undefined,
directives: undefined,
- loc: locStub
- } as ForCodegenNode
- }
- })
+ loc: locStub,
+ } as ForCodegenNode,
+ },
+ }),
)
expect(code).toMatch(`openBlock(true)`)
expect(code).toMatchSnapshot()
@@ -288,7 +289,7 @@ describe('compiler: codegen', () => {
'1 + 2',
false,
locStub,
- ConstantTypes.CAN_STRINGIFY
+ ConstantTypes.CAN_STRINGIFY,
),
valueAlias: undefined,
keyAlias: undefined,
@@ -302,13 +303,13 @@ describe('compiler: codegen', () => {
disableTracking: false,
props: undefined,
children: createCallExpression(RENDER_LIST),
- patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+ patchFlag: PatchFlags.STABLE_FRAGMENT,
dynamicProps: undefined,
directives: undefined,
- loc: locStub
- } as ForCodegenNode
- }
- })
+ loc: locStub,
+ } as ForCodegenNode,
+ },
+ }),
)
expect(code).toMatch(`openBlock()`)
expect(code).toMatchSnapshot()
@@ -325,11 +326,11 @@ describe('compiler: codegen', () => {
[
createObjectProperty(
createSimpleExpression(`id`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
+ createSimpleExpression(`foo`, true, locStub),
),
createObjectProperty(
createSimpleExpression(`prop`, false, locStub),
- createSimpleExpression(`bar`, false, locStub)
+ createSimpleExpression(`bar`, false, locStub),
),
// compound expression as computed key
createObjectProperty(
@@ -338,13 +339,13 @@ describe('compiler: codegen', () => {
loc: locStub,
children: [
`foo + `,
- createSimpleExpression(`bar`, false, locStub)
- ]
+ createSimpleExpression(`bar`, false, locStub),
+ ],
},
- createSimpleExpression(`bar`, false, locStub)
- )
+ createSimpleExpression(`bar`, false, locStub),
+ ),
],
- locStub
+ locStub,
),
// ChildNode[]
[
@@ -355,17 +356,17 @@ describe('compiler: codegen', () => {
createObjectProperty(
// should quote the key!
createSimpleExpression(`some-key`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- )
+ createSimpleExpression(`foo`, true, locStub),
+ ),
],
- locStub
- )
- )
+ locStub,
+ ),
+ ),
],
// flag
- PatchFlags.FULL_PROPS + ''
- )
- })
+ PatchFlags.FULL_PROPS,
+ ),
+ }),
)
expect(code).toMatch(`
return _${helperNameMap[CREATE_ELEMENT_VNODE]}("div", {
@@ -374,7 +375,7 @@ describe('compiler: codegen', () => {
[foo + bar]: bar
}, [
_${helperNameMap[CREATE_ELEMENT_VNODE]}("p", { "some-key": "foo" })
- ], ${PatchFlags.FULL_PROPS})`)
+ ], ${genFlagText(PatchFlags.FULL_PROPS)})`)
expect(code).toMatchSnapshot()
})
@@ -383,9 +384,9 @@ describe('compiler: codegen', () => {
createRoot({
codegenNode: createArrayExpression([
createSimpleExpression(`foo`, false),
- createCallExpression(`bar`, [`baz`])
- ])
- })
+ createCallExpression(`bar`, [`baz`]),
+ ]),
+ }),
)
expect(code).toMatch(`return [
foo,
@@ -403,17 +404,17 @@ describe('compiler: codegen', () => {
createConditionalExpression(
createSimpleExpression(`orNot`, false),
createCallExpression(`bar`),
- createCallExpression(`baz`)
- )
- )
- })
+ createCallExpression(`baz`),
+ ),
+ ),
+ }),
)
expect(code).toMatch(
`return ok
? foo()
: orNot
? bar()
- : baz()`
+ : baz()`,
)
expect(code).toMatchSnapshot()
})
@@ -421,45 +422,45 @@ describe('compiler: codegen', () => {
test('CacheExpression', () => {
const { code } = generate(
createRoot({
- cached: 1,
+ cached: [],
codegenNode: createCacheExpression(
1,
- createSimpleExpression(`foo`, false)
- )
+ createSimpleExpression(`foo`, false),
+ ),
}),
{
mode: 'module',
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
expect(code).toMatch(`_cache[1] || (_cache[1] = foo)`)
expect(code).toMatchSnapshot()
})
- test('CacheExpression w/ isVNode: true', () => {
+ test('CacheExpression w/ isVOnce: true', () => {
const { code } = generate(
createRoot({
- cached: 1,
+ cached: [],
codegenNode: createCacheExpression(
1,
createSimpleExpression(`foo`, false),
- true
- )
+ true,
+ ),
}),
{
mode: 'module',
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
expect(code).toMatch(
`
_cache[1] || (
_setBlockTracking(-1),
- _cache[1] = foo,
+ (_cache[1] = foo).cacheIndex = 1,
_setBlockTracking(1),
_cache[1]
)
- `.trim()
+ `.trim(),
)
expect(code).toMatchSnapshot()
})
@@ -471,11 +472,11 @@ describe('compiler: codegen', () => {
createTemplateLiteral([
`foo`,
createCallExpression(`_renderAttr`, ['id', 'foo']),
- `bar`
- ])
- ])
+ `bar`,
+ ]),
+ ]),
}),
- { ssr: true, mode: 'module' }
+ { ssr: true, mode: 'module' },
)
expect(code).toMatchInlineSnapshot(`
"
@@ -492,11 +493,11 @@ describe('compiler: codegen', () => {
codegenNode: createBlockStatement([
createIfStatement(
createSimpleExpression('foo', false),
- createBlockStatement([createCallExpression(`ok`)])
- )
- ])
+ createBlockStatement([createCallExpression(`ok`)]),
+ ),
+ ]),
}),
- { ssr: true, mode: 'module' }
+ { ssr: true, mode: 'module' },
)
expect(code).toMatchInlineSnapshot(`
"
@@ -515,11 +516,11 @@ describe('compiler: codegen', () => {
createIfStatement(
createSimpleExpression('foo', false),
createBlockStatement([createCallExpression(`foo`)]),
- createBlockStatement([createCallExpression('bar')])
- )
- ])
+ createBlockStatement([createCallExpression('bar')]),
+ ),
+ ]),
}),
- { ssr: true, mode: 'module' }
+ { ssr: true, mode: 'module' },
)
expect(code).toMatchInlineSnapshot(`
"
@@ -542,12 +543,12 @@ describe('compiler: codegen', () => {
createBlockStatement([createCallExpression(`foo`)]),
createIfStatement(
createSimpleExpression('bar', false),
- createBlockStatement([createCallExpression(`bar`)])
- )
- )
- ])
+ createBlockStatement([createCallExpression(`bar`)]),
+ ),
+ ),
+ ]),
}),
- { ssr: true, mode: 'module' }
+ { ssr: true, mode: 'module' },
)
expect(code).toMatchInlineSnapshot(`
"
@@ -571,12 +572,12 @@ describe('compiler: codegen', () => {
createIfStatement(
createSimpleExpression('bar', false),
createBlockStatement([createCallExpression(`bar`)]),
- createBlockStatement([createCallExpression('baz')])
- )
- )
- ])
+ createBlockStatement([createCallExpression('baz')]),
+ ),
+ ),
+ ]),
}),
- { ssr: true, mode: 'module' }
+ { ssr: true, mode: 'module' },
)
expect(code).toMatchInlineSnapshot(`
"
@@ -598,9 +599,9 @@ describe('compiler: codegen', () => {
createRoot({
codegenNode: createAssignmentExpression(
createSimpleExpression(`foo`, false),
- createSimpleExpression(`bar`, false)
- )
- })
+ createSimpleExpression(`bar`, false),
+ ),
+ }),
)
expect(code).toMatchInlineSnapshot(`
"
@@ -616,17 +617,17 @@ describe('compiler: codegen', () => {
function genCode(node: VNodeCall) {
return generate(
createRoot({
- codegenNode: node
- })
+ codegenNode: node,
+ }),
).code.match(/with \(_ctx\) \{\s+([^]+)\s+\}\s+\}$/)![1]
}
const mockProps = createObjectExpression([
- createObjectProperty(`foo`, createSimpleExpression(`bar`, true))
+ createObjectProperty(`foo`, createSimpleExpression(`bar`, true)),
])
const mockChildren = createCompoundExpression(['children'])
const mockDirs = createArrayExpression([
- createArrayExpression([`foo`, createSimpleExpression(`bar`, false)])
+ createArrayExpression([`foo`, createSimpleExpression(`bar`, false)]),
]) as DirectiveArguments
test('tag only', () => {
@@ -643,31 +644,34 @@ describe('compiler: codegen', () => {
test('with props', () => {
expect(genCode(createVNodeCall(null, `"div"`, mockProps)))
.toMatchInlineSnapshot(`
- "return _createElementVNode("div", { foo: "bar" })
- "
- `)
+ "return _createElementVNode("div", { foo: "bar" })
+ "
+ `)
})
test('with children, no props', () => {
expect(genCode(createVNodeCall(null, `"div"`, undefined, mockChildren)))
.toMatchInlineSnapshot(`
- "return _createElementVNode("div", null, children)
- "
- `)
+ "return _createElementVNode("div", null, children)
+ "
+ `)
})
test('with children + props', () => {
expect(genCode(createVNodeCall(null, `"div"`, mockProps, mockChildren)))
.toMatchInlineSnapshot(`
- "return _createElementVNode("div", { foo: "bar" }, children)
- "
- `)
+ "return _createElementVNode("div", { foo: "bar" }, children)
+ "
+ `)
})
test('with patchFlag and no children/props', () => {
- expect(genCode(createVNodeCall(null, `"div"`, undefined, undefined, '1')))
- .toMatchInlineSnapshot(`
- "return _createElementVNode("div", null, null, 1)
+ expect(
+ genCode(
+ createVNodeCall(null, `"div"`, undefined, undefined, PatchFlags.TEXT),
+ ),
+ ).toMatchInlineSnapshot(`
+ "return _createElementVNode("div", null, null, 1 /* TEXT */)
"
`)
})
@@ -683,9 +687,9 @@ describe('compiler: codegen', () => {
undefined,
undefined,
undefined,
- true
- )
- )
+ true,
+ ),
+ ),
).toMatchInlineSnapshot(`
"return (_openBlock(), _createElementBlock("div", { foo: "bar" }, children))
"
@@ -704,9 +708,9 @@ describe('compiler: codegen', () => {
undefined,
undefined,
true,
- true
- )
- )
+ true,
+ ),
+ ),
).toMatchInlineSnapshot(`
"return (_openBlock(true), _createElementBlock("div", { foo: "bar" }, children))
"
@@ -723,9 +727,9 @@ describe('compiler: codegen', () => {
mockChildren,
undefined,
undefined,
- mockDirs
- )
- )
+ mockDirs,
+ ),
+ ),
).toMatchInlineSnapshot(`
"return _withDirectives(_createElementVNode("div", { foo: "bar" }, children), [
[foo, bar]
@@ -745,9 +749,9 @@ describe('compiler: codegen', () => {
undefined,
undefined,
mockDirs,
- true
- )
- )
+ true,
+ ),
+ ),
).toMatchInlineSnapshot(`
"return _withDirectives((_openBlock(), _createElementBlock("div", { foo: "bar" }, children)), [
[foo, bar]
diff --git a/packages/compiler-core/__tests__/compile.spec.ts b/packages/compiler-core/__tests__/compile.spec.ts
index 33766f71b3b..995741091df 100644
--- a/packages/compiler-core/__tests__/compile.spec.ts
+++ b/packages/compiler-core/__tests__/compile.spec.ts
@@ -1,5 +1,5 @@
import { baseCompile as compile } from '../src'
-import { SourceMapConsumer, RawSourceMap } from 'source-map'
+import { type RawSourceMap, SourceMapConsumer } from 'source-map-js'
describe('compiler: integration tests', () => {
const source = `
@@ -20,7 +20,7 @@ describe('compiler: integration tests', () => {
function getPositionInCode(
code: string,
token: string,
- expectName: string | boolean = false
+ expectName: string | boolean = false,
): Pos {
const generatedOffset = code.indexOf(token)
let line = 1
@@ -36,7 +36,7 @@ describe('compiler: integration tests', () => {
column:
lastNewLinePos === -1
? generatedOffset
- : generatedOffset - lastNewLinePos - 1
+ : generatedOffset - lastNewLinePos - 1,
}
if (expectName) {
res.name = typeof expectName === 'string' ? expectName : token
@@ -47,7 +47,7 @@ describe('compiler: integration tests', () => {
test('function mode', () => {
const { code, map } = compile(source, {
sourceMap: true,
- filename: `foo.vue`
+ filename: `foo.vue`,
})
expect(code).toMatchSnapshot()
@@ -57,55 +57,55 @@ describe('compiler: integration tests', () => {
const consumer = new SourceMapConsumer(map as RawSourceMap)
expect(
- consumer.originalPositionFor(getPositionInCode(code, `id`))
+ consumer.originalPositionFor(getPositionInCode(code, `id`)),
).toMatchObject(getPositionInCode(source, `id`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `"foo"`))
+ consumer.originalPositionFor(getPositionInCode(code, `"foo"`)),
).toMatchObject(getPositionInCode(source, `"foo"`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `class:`))
+ consumer.originalPositionFor(getPositionInCode(code, `class:`)),
).toMatchObject(getPositionInCode(source, `class=`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `bar`))
+ consumer.originalPositionFor(getPositionInCode(code, `bar`)),
).toMatchObject(getPositionInCode(source, `bar`))
// without prefixIdentifiers: true, identifiers inside compound expressions
// are mapped to closest parent expression.
expect(
- consumer.originalPositionFor(getPositionInCode(code, `baz`))
+ consumer.originalPositionFor(getPositionInCode(code, `baz`)),
).toMatchObject(getPositionInCode(source, `bar`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `world`))
+ consumer.originalPositionFor(getPositionInCode(code, `world`)),
).toMatchObject(getPositionInCode(source, `world`))
// without prefixIdentifiers: true, identifiers inside compound expressions
// are mapped to closest parent expression.
expect(
- consumer.originalPositionFor(getPositionInCode(code, `burn()`))
+ consumer.originalPositionFor(getPositionInCode(code, `burn()`)),
).toMatchObject(getPositionInCode(source, `world`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `ok`))
+ consumer.originalPositionFor(getPositionInCode(code, `ok`)),
).toMatchObject(getPositionInCode(source, `ok`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `list`))
+ consumer.originalPositionFor(getPositionInCode(code, `list`)),
).toMatchObject(getPositionInCode(source, `list`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `value`))
+ consumer.originalPositionFor(getPositionInCode(code, `value`)),
).toMatchObject(getPositionInCode(source, `value`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `index`))
+ consumer.originalPositionFor(getPositionInCode(code, `index`)),
).toMatchObject(getPositionInCode(source, `index`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `value + index`))
+ consumer.originalPositionFor(getPositionInCode(code, `value + index`)),
).toMatchObject(getPositionInCode(source, `value + index`))
})
@@ -113,7 +113,7 @@ describe('compiler: integration tests', () => {
const { code, map } = compile(source, {
sourceMap: true,
filename: `foo.vue`,
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(code).toMatchSnapshot()
@@ -123,64 +123,66 @@ describe('compiler: integration tests', () => {
const consumer = new SourceMapConsumer(map as RawSourceMap)
expect(
- consumer.originalPositionFor(getPositionInCode(code, `id`))
+ consumer.originalPositionFor(getPositionInCode(code, `id`)),
).toMatchObject(getPositionInCode(source, `id`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `"foo"`))
+ consumer.originalPositionFor(getPositionInCode(code, `"foo"`)),
).toMatchObject(getPositionInCode(source, `"foo"`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `class:`))
+ consumer.originalPositionFor(getPositionInCode(code, `class:`)),
).toMatchObject(getPositionInCode(source, `class=`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `bar`))
+ consumer.originalPositionFor(getPositionInCode(code, `bar`)),
).toMatchObject(getPositionInCode(source, `bar`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`, `bar`))
+ consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`, `bar`)),
).toMatchObject(getPositionInCode(source, `bar`, true))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `baz`))
+ consumer.originalPositionFor(getPositionInCode(code, `baz`)),
).toMatchObject(getPositionInCode(source, `baz`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `world`, true))
+ consumer.originalPositionFor(getPositionInCode(code, `world`, true)),
).toMatchObject(getPositionInCode(source, `world`, `world`))
expect(
consumer.originalPositionFor(
- getPositionInCode(code, `_ctx.world`, `world`)
- )
+ getPositionInCode(code, `_ctx.world`, `world`),
+ ),
).toMatchObject(getPositionInCode(source, `world`, `world`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `burn()`))
+ consumer.originalPositionFor(getPositionInCode(code, `burn()`)),
).toMatchObject(getPositionInCode(source, `burn()`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `ok`))
+ consumer.originalPositionFor(getPositionInCode(code, `ok`)),
).toMatchObject(getPositionInCode(source, `ok`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`, `ok`))
+ consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`, `ok`)),
).toMatchObject(getPositionInCode(source, `ok`, true))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `list`))
+ consumer.originalPositionFor(getPositionInCode(code, `list`)),
).toMatchObject(getPositionInCode(source, `list`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`, `list`))
+ consumer.originalPositionFor(
+ getPositionInCode(code, `_ctx.list`, `list`),
+ ),
).toMatchObject(getPositionInCode(source, `list`, true))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `value`))
+ consumer.originalPositionFor(getPositionInCode(code, `value`)),
).toMatchObject(getPositionInCode(source, `value`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `index`))
+ consumer.originalPositionFor(getPositionInCode(code, `index`)),
).toMatchObject(getPositionInCode(source, `index`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `value + index`))
+ consumer.originalPositionFor(getPositionInCode(code, `value + index`)),
).toMatchObject(getPositionInCode(source, `value + index`))
})
@@ -188,7 +190,7 @@ describe('compiler: integration tests', () => {
const { code, map } = compile(source, {
mode: 'module',
sourceMap: true,
- filename: `foo.vue`
+ filename: `foo.vue`,
})
expect(code).toMatchSnapshot()
@@ -198,64 +200,66 @@ describe('compiler: integration tests', () => {
const consumer = new SourceMapConsumer(map as RawSourceMap)
expect(
- consumer.originalPositionFor(getPositionInCode(code, `id`))
+ consumer.originalPositionFor(getPositionInCode(code, `id`)),
).toMatchObject(getPositionInCode(source, `id`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `"foo"`))
+ consumer.originalPositionFor(getPositionInCode(code, `"foo"`)),
).toMatchObject(getPositionInCode(source, `"foo"`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `class:`))
+ consumer.originalPositionFor(getPositionInCode(code, `class:`)),
).toMatchObject(getPositionInCode(source, `class=`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `bar`))
+ consumer.originalPositionFor(getPositionInCode(code, `bar`)),
).toMatchObject(getPositionInCode(source, `bar`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`, `bar`))
+ consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`, `bar`)),
).toMatchObject(getPositionInCode(source, `bar`, true))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `baz`))
+ consumer.originalPositionFor(getPositionInCode(code, `baz`)),
).toMatchObject(getPositionInCode(source, `baz`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `world`, true))
+ consumer.originalPositionFor(getPositionInCode(code, `world`, true)),
).toMatchObject(getPositionInCode(source, `world`, `world`))
expect(
consumer.originalPositionFor(
- getPositionInCode(code, `_ctx.world`, `world`)
- )
+ getPositionInCode(code, `_ctx.world`, `world`),
+ ),
).toMatchObject(getPositionInCode(source, `world`, `world`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `burn()`))
+ consumer.originalPositionFor(getPositionInCode(code, `burn()`)),
).toMatchObject(getPositionInCode(source, `burn()`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `ok`))
+ consumer.originalPositionFor(getPositionInCode(code, `ok`)),
).toMatchObject(getPositionInCode(source, `ok`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`, `ok`))
+ consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`, `ok`)),
).toMatchObject(getPositionInCode(source, `ok`, true))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `list`))
+ consumer.originalPositionFor(getPositionInCode(code, `list`)),
).toMatchObject(getPositionInCode(source, `list`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`, `list`))
+ consumer.originalPositionFor(
+ getPositionInCode(code, `_ctx.list`, `list`),
+ ),
).toMatchObject(getPositionInCode(source, `list`, true))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `value`))
+ consumer.originalPositionFor(getPositionInCode(code, `value`)),
).toMatchObject(getPositionInCode(source, `value`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `index`))
+ consumer.originalPositionFor(getPositionInCode(code, `index`)),
).toMatchObject(getPositionInCode(source, `index`))
expect(
- consumer.originalPositionFor(getPositionInCode(code, `value + index`))
+ consumer.originalPositionFor(getPositionInCode(code, `value + index`)),
).toMatchObject(getPositionInCode(source, `value + index`))
})
})
diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts
index 8979e8fb0e1..cdc2b09fd48 100644
--- a/packages/compiler-core/__tests__/parse.spec.ts
+++ b/packages/compiler-core/__tests__/parse.spec.ts
@@ -1,18 +1,21 @@
-import { ParserOptions } from '../src/options'
-import { baseParse, TextModes } from '../src/parse'
+import type { ParserOptions } from '../src/options'
import { ErrorCodes } from '../src/errors'
import {
- CommentNode,
- ElementNode,
+ type CommentNode,
+ ConstantTypes,
+ type DirectiveNode,
+ type ElementNode,
ElementTypes,
+ type InterpolationNode,
Namespaces,
NodeTypes,
- Position,
- TextNode,
- InterpolationNode,
- ConstantTypes
+ type Position,
+ type TextNode,
} from '../src/ast'
+import { baseParse } from '../src/parser'
+import type { Program } from '@babel/types'
+
describe('compiler: parse', () => {
describe('Text', () => {
test('simple text', () => {
@@ -25,27 +28,36 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 9, line: 1, column: 10 },
- source: 'some text'
- }
+ source: 'some text',
+ },
})
})
test('simple text with invalid end tag', () => {
- const onError = jest.fn()
- const ast = baseParse('some text ', {
- onError
- })
+ const onError = vi.fn()
+ const ast = baseParse('some text ', { onError })
const text = ast.children[0] as TextNode
- expect(onError).toBeCalled()
+ expect(onError.mock.calls).toMatchObject([
+ [
+ {
+ code: ErrorCodes.X_INVALID_END_TAG,
+ loc: {
+ start: { column: 10, line: 1, offset: 9 },
+ end: { column: 10, line: 1, offset: 9 },
+ },
+ },
+ ],
+ ])
+
expect(text).toStrictEqual({
type: NodeTypes.TEXT,
content: 'some text',
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 9, line: 1, column: 10 },
- source: 'some text'
- }
+ source: 'some text',
+ },
})
})
@@ -60,8 +72,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 5, line: 1, column: 6 },
- source: 'some '
- }
+ source: 'some ',
+ },
})
expect(text2).toStrictEqual({
type: NodeTypes.TEXT,
@@ -69,8 +81,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 20, line: 1, column: 21 },
end: { offset: 25, line: 1, column: 26 },
- source: ' text'
- }
+ source: ' text',
+ },
})
})
@@ -85,8 +97,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 5, line: 1, column: 6 },
- source: 'some '
- }
+ source: 'some ',
+ },
})
expect(text2).toStrictEqual({
type: NodeTypes.TEXT,
@@ -94,8 +106,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 21, line: 1, column: 22 },
end: { offset: 26, line: 1, column: 27 },
- source: ' text'
- }
+ source: ' text',
+ },
})
})
@@ -110,8 +122,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 5, line: 1, column: 6 },
- source: 'some '
- }
+ source: 'some ',
+ },
})
expect(text2).toStrictEqual({
type: NodeTypes.TEXT,
@@ -119,8 +131,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 32, line: 1, column: 33 },
end: { offset: 37, line: 1, column: 38 },
- source: ' text'
- }
+ source: ' text',
+ },
})
})
@@ -130,7 +142,7 @@ describe('compiler: parse', () => {
if (err.code !== ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME) {
throw err
}
- }
+ },
})
const text = ast.children[0] as TextNode
@@ -140,8 +152,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 5, line: 1, column: 6 },
- source: 'a < b'
- }
+ source: 'a < b',
+ },
})
})
@@ -151,7 +163,7 @@ describe('compiler: parse', () => {
if (error.code !== ErrorCodes.X_MISSING_INTERPOLATION_END) {
throw error
}
- }
+ },
})
const text = ast.children[0] as TextNode
@@ -161,8 +173,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 6, line: 1, column: 7 },
- source: 'a {{ b'
- }
+ source: 'a {{ b',
+ },
})
})
})
@@ -182,14 +194,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 2, line: 1, column: 3 },
end: { offset: 9, line: 1, column: 10 },
- source: `message`
- }
+ source: 'message',
+ },
},
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 11, line: 1, column: 12 },
- source: '{{message}}'
- }
+ source: '{{message}}',
+ },
})
})
@@ -207,14 +219,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 3, line: 1, column: 4 },
end: { offset: 6, line: 1, column: 7 },
- source: 'a {
loc: {
start: { offset: 3, line: 1, column: 4 },
end: { offset: 6, line: 1, column: 7 },
- source: 'a {
loc: {
start: { offset: 12, line: 1, column: 13 },
end: { offset: 15, line: 1, column: 16 },
- source: 'c>d'
- }
+ source: 'c>d',
+ },
},
loc: {
start: { offset: 9, line: 1, column: 10 },
end: { offset: 18, line: 1, column: 19 },
- source: '{{ c>d }}'
- }
+ source: '{{ c>d }}',
+ },
})
})
@@ -280,20 +292,20 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 16, line: 1, column: 17 },
- source: '" "'
- }
+ source: '"
"',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 19, line: 1, column: 20 },
- source: '{{ " " }}'
- }
+ source: '{{ " " }}',
+ },
})
})
test('custom delimiters', () => {
const ast = baseParse('{msg}
', {
- delimiters: ['{', '}']
+ delimiters: ['{', '}'],
})
const element = ast.children[0] as ElementNode
const interpolation = element.children[0] as InterpolationNode
@@ -308,14 +320,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 4, line: 1, column: 5 },
end: { offset: 7, line: 1, column: 8 },
- source: 'msg'
- }
+ source: 'msg',
+ },
},
loc: {
start: { offset: 3, line: 1, column: 4 },
end: { offset: 8, line: 1, column: 9 },
- source: '{msg}'
- }
+ source: '{msg}',
+ },
})
})
})
@@ -331,8 +343,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 7, line: 1, column: 8 },
- source: ''
- }
+ source: '',
+ },
})
})
@@ -346,8 +358,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 10, line: 1, column: 11 },
- source: ''
- }
+ source: '',
+ },
})
})
@@ -362,8 +374,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 10, line: 1, column: 11 },
- source: ''
- }
+ source: '',
+ },
})
expect(comment2).toStrictEqual({
type: NodeTypes.COMMENT,
@@ -371,8 +383,8 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 10, line: 1, column: 11 },
end: { offset: 20, line: 1, column: 21 },
- source: ''
- }
+ source: '',
+ },
})
})
@@ -389,38 +401,38 @@ describe('compiler: parse', () => {
const rawText = `
`
const astWithComments = baseParse(`${rawText} `, {
- comments: true
+ comments: true,
})
expect(
- (astWithComments.children[0] as ElementNode).children
+ (astWithComments.children[0] as ElementNode).children,
).toMatchObject([
{
type: NodeTypes.ELEMENT,
- tag: 'p'
+ tag: 'p',
},
{
- type: NodeTypes.COMMENT
+ type: NodeTypes.COMMENT,
},
{
type: NodeTypes.ELEMENT,
- tag: 'p'
- }
+ tag: 'p',
+ },
])
const astWithoutComments = baseParse(`${rawText} `, {
- comments: false
+ comments: false,
})
expect(
- (astWithoutComments.children[0] as ElementNode).children
+ (astWithoutComments.children[0] as ElementNode).children,
).toMatchObject([
{
type: NodeTypes.ELEMENT,
- tag: 'p'
+ tag: 'p',
},
{
type: NodeTypes.ELEMENT,
- tag: 'p'
- }
+ tag: 'p',
+ },
])
})
})
@@ -437,7 +449,6 @@ describe('compiler: parse', () => {
tagType: ElementTypes.ELEMENT,
codegenNode: undefined,
props: [],
- isSelfClosing: false,
children: [
{
type: NodeTypes.TEXT,
@@ -445,15 +456,15 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 10, line: 1, column: 11 },
- source: 'hello'
- }
- }
+ source: 'hello',
+ },
+ },
],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 16, line: 1, column: 17 },
- source: 'hello
'
- }
+ source: 'hello
',
+ },
})
})
@@ -468,13 +479,12 @@ describe('compiler: parse', () => {
tagType: ElementTypes.ELEMENT,
codegenNode: undefined,
props: [],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 11, line: 1, column: 12 },
- source: '
'
- }
+ source: '
',
+ },
})
})
@@ -489,20 +499,19 @@ describe('compiler: parse', () => {
tagType: ElementTypes.ELEMENT,
codegenNode: undefined,
props: [],
-
- isSelfClosing: true,
children: [],
+ isSelfClosing: true,
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 6, line: 1, column: 7 },
- source: '
'
- }
+ source: '
',
+ },
})
})
test('void element', () => {
const ast = baseParse(' after', {
- isVoidTag: tag => tag === 'img'
+ isVoidTag: tag => tag === 'img',
})
const element = ast.children[0] as ElementNode
@@ -513,14 +522,35 @@ describe('compiler: parse', () => {
tagType: ElementTypes.ELEMENT,
codegenNode: undefined,
props: [],
-
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 5, line: 1, column: 6 },
- source: ' '
- }
+ source: ' ',
+ },
+ })
+ })
+
+ test('self-closing void element', () => {
+ const ast = baseParse(' after', {
+ isVoidTag: tag => tag === 'img',
+ })
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'img',
+ tagType: ElementTypes.ELEMENT,
+ codegenNode: undefined,
+ props: [],
+ children: [],
+ isSelfClosing: true,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 6, line: 1, column: 7 },
+ source: ' ',
+ },
})
})
@@ -529,7 +559,7 @@ describe('compiler: parse', () => {
const element = ast.children[0]
expect(element).toMatchObject({
type: NodeTypes.ELEMENT,
- tagType: ElementTypes.TEMPLATE
+ tagType: ElementTypes.TEMPLATE,
})
})
@@ -538,31 +568,31 @@ describe('compiler: parse', () => {
const element = ast.children[0]
expect(element).toMatchObject({
type: NodeTypes.ELEMENT,
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
})
test('native element with `isNativeTag`', () => {
const ast = baseParse('
', {
- isNativeTag: tag => tag === 'div'
+ isNativeTag: tag => tag === 'div',
})
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
expect(ast.children[2]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
})
@@ -572,105 +602,105 @@ describe('compiler: parse', () => {
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'comp',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[2]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
})
- test('v-is with `isNativeTag`', () => {
+ test('is casting with `isNativeTag`', () => {
const ast = baseParse(
- `
`,
+ `
`,
{
- isNativeTag: tag => tag === 'div'
- }
+ isNativeTag: tag => tag === 'div',
+ },
)
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
expect(ast.children[2]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
})
- test('v-is without `isNativeTag`', () => {
- const ast = baseParse(`
`)
+ test('is casting without `isNativeTag`', () => {
+ const ast = baseParse(`
`)
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
expect(ast.children[2]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
})
test('custom element', () => {
const ast = baseParse('
', {
isNativeTag: tag => tag === 'div',
- isCustomElement: tag => tag === 'comp'
+ isCustomElement: tag => tag === 'comp',
})
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'comp',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
})
test('built-in component', () => {
const ast = baseParse('
', {
- isBuiltInComponent: tag => (tag === 'comp' ? Symbol() : void 0)
+ isBuiltInComponent: tag => (tag === 'comp' ? Symbol() : void 0),
})
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
- tagType: ElementTypes.ELEMENT
+ tagType: ElementTypes.ELEMENT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
})
@@ -680,13 +710,13 @@ describe('compiler: parse', () => {
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'slot',
- tagType: ElementTypes.SLOT
+ tagType: ElementTypes.SLOT,
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
- tagType: ElementTypes.COMPONENT
+ tagType: ElementTypes.COMPONENT,
})
})
@@ -704,22 +734,26 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 7, line: 1, column: 8 },
- source: 'id'
- }
- }
+ source: 'id',
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 14, line: 1, column: 15 },
- source: '
'
- }
+ source: '
',
+ },
})
})
@@ -737,30 +771,34 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: {
type: NodeTypes.TEXT,
content: '',
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 10, line: 1, column: 11 },
- source: '""'
- }
+ source: '""',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 10, line: 1, column: 11 },
- source: 'id=""'
- }
- }
+ source: 'id=""',
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 17, line: 1, column: 18 },
- source: '
'
- }
+ source: '
',
+ },
})
})
@@ -778,30 +816,34 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: {
type: NodeTypes.TEXT,
content: '',
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 10, line: 1, column: 11 },
- source: "''"
- }
+ source: "''",
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 10, line: 1, column: 11 },
- source: "id=''"
- }
- }
+ source: "id=''",
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 17, line: 1, column: 18 },
- source: "
"
- }
+ source: "
",
+ },
})
})
@@ -819,30 +861,34 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: {
type: NodeTypes.TEXT,
content: ">'",
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 12, line: 1, column: 13 },
- source: '">\'"'
- }
+ source: '">\'"',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 12, line: 1, column: 13 },
- source: 'id=">\'"'
- }
- }
+ source: 'id=">\'"',
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 19, line: 1, column: 20 },
- source: '
'
- }
+ source: '
',
+ },
})
})
@@ -860,30 +906,34 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: {
type: NodeTypes.TEXT,
content: '>"',
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 12, line: 1, column: 13 },
- source: "'>\"'"
- }
+ source: "'>\"'",
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 12, line: 1, column: 13 },
- source: "id='>\"'"
- }
- }
+ source: "id='>\"'",
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 19, line: 1, column: 20 },
- source: "
"
- }
+ source: "
",
+ },
})
})
@@ -901,30 +951,117 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: {
type: NodeTypes.TEXT,
content: 'a/',
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 10, line: 1, column: 11 },
- source: 'a/'
- }
+ source: 'a/',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 10, line: 1, column: 11 },
- source: 'id=a/'
- }
- }
+ source: 'id=a/',
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 17, line: 1, column: 18 },
- source: '
'
- }
+ source: '
',
+ },
+ })
+ })
+
+ test('attribute value with >', () => {
+ const ast = baseParse(
+ '',
+ { parseMode: 'sfc' },
+ )
+ const element = ast.children[0] as ElementNode
+ expect(element).toMatchObject({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'script',
+ tagType: ElementTypes.ELEMENT,
+ codegenNode: undefined,
+ children: [],
+ innerLoc: {
+ start: { column: 67, line: 1, offset: 66 },
+ end: { column: 67, line: 1, offset: 66 },
+ },
+ props: [
+ {
+ loc: {
+ source: 'setup',
+ end: { column: 14, line: 1, offset: 13 },
+ start: { column: 9, line: 1, offset: 8 },
+ },
+ name: 'setup',
+ nameLoc: {
+ source: 'setup',
+ end: { column: 14, line: 1, offset: 13 },
+ start: { column: 9, line: 1, offset: 8 },
+ },
+ type: NodeTypes.ATTRIBUTE,
+ value: undefined,
+ },
+ {
+ loc: {
+ source: 'lang="ts"',
+ end: { column: 24, line: 1, offset: 23 },
+ start: { column: 15, line: 1, offset: 14 },
+ },
+ name: 'lang',
+ nameLoc: {
+ source: 'lang',
+ end: { column: 19, line: 1, offset: 18 },
+ start: { column: 15, line: 1, offset: 14 },
+ },
+ type: NodeTypes.ATTRIBUTE,
+ value: {
+ content: 'ts',
+ loc: {
+ source: '"ts"',
+ end: { column: 24, line: 1, offset: 23 },
+ start: { column: 20, line: 1, offset: 19 },
+ },
+ type: NodeTypes.TEXT,
+ },
+ },
+ {
+ loc: {
+ source: 'generic="T extends Record"',
+ end: { column: 66, line: 1, offset: 65 },
+ start: { column: 25, line: 1, offset: 24 },
+ },
+ name: 'generic',
+ nameLoc: {
+ source: 'generic',
+ end: { column: 32, line: 1, offset: 31 },
+ start: { column: 25, line: 1, offset: 24 },
+ },
+ type: NodeTypes.ATTRIBUTE,
+ value: {
+ content: 'T extends Record',
+ loc: {
+ source: '"T extends Record"',
+ end: { column: 66, line: 1, offset: 65 },
+ start: { column: 33, line: 1, offset: 32 },
+ },
+ type: NodeTypes.TEXT,
+ },
+ },
+ ],
})
})
@@ -942,76 +1079,95 @@ describe('compiler: parse', () => {
{
type: NodeTypes.ATTRIBUTE,
name: 'id',
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id',
+ },
value: {
type: NodeTypes.TEXT,
content: 'a',
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 9, line: 1, column: 10 },
- source: 'a'
- }
+ source: 'a',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 9, line: 1, column: 10 },
- source: 'id=a'
- }
+ source: 'id=a',
+ },
},
{
type: NodeTypes.ATTRIBUTE,
name: 'class',
+ nameLoc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 15, line: 1, column: 16 },
+ source: 'class',
+ },
value: {
type: NodeTypes.TEXT,
content: 'c',
loc: {
start: { offset: 16, line: 1, column: 17 },
end: { offset: 19, line: 1, column: 20 },
- source: '"c"'
- }
+ source: '"c"',
+ },
},
loc: {
start: { offset: 10, line: 1, column: 11 },
end: { offset: 19, line: 1, column: 20 },
- source: 'class="c"'
- }
+ source: 'class="c"',
+ },
},
{
type: NodeTypes.ATTRIBUTE,
name: 'inert',
+ nameLoc: {
+ start: { offset: 20, line: 1, column: 21 },
+ end: { offset: 25, line: 1, column: 26 },
+ source: 'inert',
+ },
value: undefined,
loc: {
start: { offset: 20, line: 1, column: 21 },
end: { offset: 25, line: 1, column: 26 },
- source: 'inert'
- }
+ source: 'inert',
+ },
},
{
type: NodeTypes.ATTRIBUTE,
name: 'style',
+ nameLoc: {
+ start: { offset: 26, line: 1, column: 27 },
+ end: { offset: 31, line: 1, column: 32 },
+ source: 'style',
+ },
value: {
type: NodeTypes.TEXT,
content: '',
loc: {
start: { offset: 32, line: 1, column: 33 },
end: { offset: 34, line: 1, column: 35 },
- source: "''"
- }
+ source: "''",
+ },
},
loc: {
start: { offset: 26, line: 1, column: 27 },
end: { offset: 34, line: 1, column: 35 },
- source: "style=''"
- }
- }
+ source: "style=''",
+ },
+ },
],
- isSelfClosing: false,
children: [],
loc: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 41, line: 1, column: 42 },
- source: '
'
- }
+ source: '
',
+ },
})
})
@@ -1023,60 +1179,40 @@ describe('compiler: parse', () => {
expect(element).toStrictEqual({
children: [],
codegenNode: undefined,
- isSelfClosing: false,
loc: {
- end: {
- column: 10,
- line: 3,
- offset: 29
- },
+ start: { column: 1, line: 1, offset: 0 },
+ end: { column: 10, line: 3, offset: 29 },
source: '
',
- start: {
- column: 1,
- line: 1,
- offset: 0
- }
},
ns: Namespaces.HTML,
props: [
{
- loc: {
- end: {
- column: 3,
- line: 3,
- offset: 22
- },
- source: 'class=" \n\t c \t\n "',
- start: {
- column: 6,
- line: 1,
- offset: 5
- }
- },
name: 'class',
+ nameLoc: {
+ start: { column: 6, line: 1, offset: 5 },
+ end: { column: 11, line: 1, offset: 10 },
+ source: 'class',
+ },
type: NodeTypes.ATTRIBUTE,
value: {
content: 'c',
loc: {
- end: {
- column: 3,
- line: 3,
- offset: 22
- },
+ start: { column: 12, line: 1, offset: 11 },
+ end: { column: 3, line: 3, offset: 22 },
source: '" \n\t c \t\n "',
- start: {
- column: 12,
- line: 1,
- offset: 11
- }
},
- type: NodeTypes.TEXT
- }
- }
- ],
- tag: 'div',
- tagType: ElementTypes.ELEMENT,
- type: NodeTypes.ELEMENT
+ type: NodeTypes.TEXT,
+ },
+ loc: {
+ start: { column: 6, line: 1, offset: 5 },
+ end: { column: 3, line: 3, offset: 22 },
+ source: 'class=" \n\t c \t\n "',
+ },
+ },
+ ],
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ type: NodeTypes.ELEMENT,
})
})
@@ -1087,14 +1223,15 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'if',
+ rawName: 'v-if',
arg: undefined,
modifiers: [],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 9, line: 1, column: 10 },
- source: 'v-if'
- }
+ source: 'v-if',
+ },
})
})
@@ -1105,6 +1242,7 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'if',
+ rawName: 'v-if',
arg: undefined,
modifiers: [],
exp: {
@@ -1115,14 +1253,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 11, line: 1, column: 12 },
end: { offset: 12, line: 1, column: 13 },
- source: 'a'
- }
+ source: 'a',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 13, line: 1, column: 14 },
- source: 'v-if="a"'
- }
+ source: 'v-if="a"',
+ },
})
})
@@ -1133,33 +1271,52 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: 'v-on:click',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'click',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 11, line: 1, offset: 10 },
+ end: { column: 16, line: 1, offset: 15 },
source: 'click',
- start: {
- column: 11,
- line: 1,
- offset: 10
- },
- end: {
- column: 16,
- line: 1,
- offset: 15
- }
- }
+ },
},
modifiers: [],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 15, line: 1, column: 16 },
- source: 'v-on:click'
- }
+ source: 'v-on:click',
+ },
+ })
+ })
+
+ // #3494
+ test('directive argument edge case', () => {
+ const ast = baseParse('
')
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+ expect(directive.arg).toMatchObject({
+ loc: {
+ start: { offset: 12, line: 1, column: 13 },
+ end: { offset: 16, line: 1, column: 17 },
+ },
+ })
+ })
+
+ // https://github.com/vuejs/language-tools/issues/2710
+ test('directive argument edge case (2)', () => {
+ const ast = baseParse('
')
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+ expect(directive.arg).toMatchObject({
+ content: 'item.item',
+ loc: {
+ start: { offset: 6, line: 1, column: 7 },
+ end: { offset: 15, line: 1, column: 16 },
+ },
})
})
@@ -1170,33 +1327,25 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: 'v-on:[event]',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'event',
isStatic: false,
constType: ConstantTypes.NOT_CONSTANT,
-
loc: {
+ start: { column: 11, line: 1, offset: 10 },
+ end: { column: 18, line: 1, offset: 17 },
source: '[event]',
- start: {
- column: 11,
- line: 1,
- offset: 10
- },
- end: {
- column: 18,
- line: 1,
- offset: 17
- }
- }
+ },
},
modifiers: [],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 17, line: 1, column: 18 },
- source: 'v-on:[event]'
- }
+ source: 'v-on:[event]',
+ },
})
})
@@ -1207,14 +1356,35 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: 'v-on.enter',
arg: undefined,
- modifiers: ['enter'],
+ modifiers: [
+ {
+ constType: 3,
+ content: 'enter',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 16,
+ line: 1,
+ offset: 15,
+ },
+ source: 'enter',
+ start: {
+ column: 11,
+ line: 1,
+ offset: 10,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 15, line: 1, column: 16 },
- source: 'v-on.enter'
- }
+ source: 'v-on.enter',
+ },
})
})
@@ -1225,14 +1395,54 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: 'v-on.enter.exact',
arg: undefined,
- modifiers: ['enter', 'exact'],
+ modifiers: [
+ {
+ constType: 3,
+ content: 'enter',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 16,
+ line: 1,
+ offset: 15,
+ },
+ source: 'enter',
+ start: {
+ column: 11,
+ line: 1,
+ offset: 10,
+ },
+ },
+ type: 4,
+ },
+ {
+ constType: 3,
+ content: 'exact',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 22,
+ line: 1,
+ offset: 21,
+ },
+ source: 'exact',
+ start: {
+ column: 17,
+ line: 1,
+ offset: 16,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 21, line: 1, column: 22 },
- source: 'v-on.enter.exact'
- }
+ source: 'v-on.enter.exact',
+ },
})
})
@@ -1243,33 +1453,64 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: 'v-on:click.enter.exact',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'click',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 11, line: 1, offset: 10 },
+ end: { column: 16, line: 1, offset: 15 },
source: 'click',
- start: {
- column: 11,
- line: 1,
- offset: 10
- },
- end: {
- column: 16,
- line: 1,
- offset: 15
- }
- }
+ },
},
- modifiers: ['enter', 'exact'],
+ modifiers: [
+ {
+ constType: 3,
+ content: 'enter',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 22,
+ line: 1,
+ offset: 21,
+ },
+ source: 'enter',
+ start: {
+ column: 17,
+ line: 1,
+ offset: 16,
+ },
+ },
+ type: 4,
+ },
+ {
+ constType: 3,
+ content: 'exact',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 28,
+ line: 1,
+ offset: 27,
+ },
+ source: 'exact',
+ start: {
+ column: 23,
+ line: 1,
+ offset: 22,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 27, line: 1, column: 28 },
- source: 'v-on:click.enter.exact'
- }
+ source: 'v-on:click.enter.exact',
+ },
})
})
@@ -1280,41 +1521,54 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: 'v-on:[a.b].camel',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a.b',
isStatic: false,
constType: ConstantTypes.NOT_CONSTANT,
-
loc: {
+ start: { column: 11, line: 1, offset: 10 },
+ end: { column: 16, line: 1, offset: 15 },
source: '[a.b]',
- start: {
- column: 11,
- line: 1,
- offset: 10
- },
- end: {
- column: 16,
- line: 1,
- offset: 15
- }
- }
+ },
},
- modifiers: ['camel'],
+ modifiers: [
+ {
+ constType: 3,
+ content: 'camel',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 22,
+ line: 1,
+ offset: 21,
+ },
+ source: 'camel',
+ start: {
+ column: 17,
+ line: 1,
+ offset: 16,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 21, line: 1, column: 22 },
- source: 'v-on:[a.b].camel'
- }
+ source: 'v-on:[a.b].camel',
+ },
})
})
+
test('directive with no name', () => {
let errorCode = -1
const ast = baseParse('
', {
onError: err => {
errorCode = err.code as number
- }
+ },
})
const directive = (ast.children[0] as ElementNode).props[0]
@@ -1326,8 +1580,13 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 7, line: 1, column: 8 },
- source: 'v-'
- }
+ source: 'v-',
+ },
+ nameLoc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'v-',
+ },
})
})
@@ -1338,25 +1597,17 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'bind',
+ rawName: ':a',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 7, line: 1, offset: 6 },
+ end: { column: 8, line: 1, offset: 7 },
source: 'a',
- start: {
- column: 7,
- line: 1,
- offset: 6
- },
- end: {
- column: 8,
- line: 1,
- offset: 7
- }
- }
+ },
},
modifiers: [],
exp: {
@@ -1364,18 +1615,17 @@ describe('compiler: parse', () => {
content: 'b',
isStatic: false,
constType: ConstantTypes.NOT_CONSTANT,
-
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 9, line: 1, column: 10 },
- source: 'b'
- }
+ source: 'b',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 9, line: 1, column: 10 },
- source: ':a=b'
- }
+ source: ':a=b',
+ },
})
})
@@ -1386,44 +1636,55 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'bind',
+ rawName: '.a',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 7, line: 1, offset: 6 },
+ end: { column: 8, line: 1, offset: 7 },
source: 'a',
- start: {
- column: 7,
- line: 1,
- offset: 6
- },
- end: {
- column: 8,
- line: 1,
- offset: 7
- }
- }
+ },
},
- modifiers: ['prop'],
+ modifiers: [
+ {
+ constType: 0,
+ content: 'prop',
+ isStatic: false,
+ loc: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ source: '',
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'b',
isStatic: false,
constType: ConstantTypes.NOT_CONSTANT,
-
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 9, line: 1, column: 10 },
- source: 'b'
- }
+ source: 'b',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 9, line: 1, column: 10 },
- source: '.a=b'
- }
+ source: '.a=b',
+ },
})
})
@@ -1434,27 +1695,39 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'bind',
+ rawName: ':a.sync',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 7, line: 1, offset: 6 },
+ end: { column: 8, line: 1, offset: 7 },
source: 'a',
- start: {
- column: 7,
- line: 1,
- offset: 6
- },
- end: {
- column: 8,
- line: 1,
- offset: 7
- }
- }
+ },
},
- modifiers: ['sync'],
+ modifiers: [
+ {
+ constType: 3,
+ content: 'sync',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 13,
+ line: 1,
+ offset: 12,
+ },
+ source: 'sync',
+ start: {
+ column: 9,
+ line: 1,
+ offset: 8,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'b',
@@ -1464,14 +1737,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 13, line: 1, column: 14 },
end: { offset: 14, line: 1, column: 15 },
- source: 'b'
- }
+ source: 'b',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 14, line: 1, column: 15 },
- source: ':a.sync=b'
- }
+ source: ':a.sync=b',
+ },
})
})
@@ -1482,25 +1755,17 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: '@a',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 7, line: 1, offset: 6 },
+ end: { column: 8, line: 1, offset: 7 },
source: 'a',
- start: {
- column: 7,
- line: 1,
- offset: 6
- },
- end: {
- column: 8,
- line: 1,
- offset: 7
- }
- }
+ },
},
modifiers: [],
exp: {
@@ -1512,14 +1777,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 9, line: 1, column: 10 },
- source: 'b'
- }
+ source: 'b',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 9, line: 1, column: 10 },
- source: '@a=b'
- }
+ source: '@a=b',
+ },
})
})
@@ -1530,27 +1795,39 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'on',
+ rawName: '@a.enter',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
-
loc: {
+ start: { column: 7, line: 1, offset: 6 },
+ end: { column: 8, line: 1, offset: 7 },
source: 'a',
- start: {
- column: 7,
- line: 1,
- offset: 6
- },
- end: {
- column: 8,
- line: 1,
- offset: 7
- }
- }
+ },
},
- modifiers: ['enter'],
+ modifiers: [
+ {
+ constType: 3,
+ content: 'enter',
+ isStatic: true,
+ loc: {
+ end: {
+ column: 14,
+ line: 1,
+ offset: 13,
+ },
+ source: 'enter',
+ start: {
+ column: 9,
+ line: 1,
+ offset: 8,
+ },
+ },
+ type: 4,
+ },
+ ],
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'b',
@@ -1560,14 +1837,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 14, line: 1, column: 15 },
end: { offset: 15, line: 1, column: 16 },
- source: 'b'
- }
+ source: 'b',
+ },
},
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 15, line: 1, column: 16 },
- source: '@a.enter=b'
- }
+ source: '@a.enter=b',
+ },
})
})
@@ -1578,24 +1855,17 @@ describe('compiler: parse', () => {
expect(directive).toStrictEqual({
type: NodeTypes.DIRECTIVE,
name: 'slot',
+ rawName: '#a',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'a',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
loc: {
+ start: { column: 8, line: 1, offset: 7 },
+ end: { column: 9, line: 1, offset: 8 },
source: 'a',
- start: {
- column: 8,
- line: 1,
- offset: 7
- },
- end: {
- column: 9,
- line: 1,
- offset: 8
- }
- }
+ },
},
modifiers: [],
exp: {
@@ -1607,14 +1877,14 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 10, line: 1, column: 11 },
end: { offset: 15, line: 1, column: 16 },
- source: '{ b }'
- }
+ source: '{ b }',
+ },
},
loc: {
start: { offset: 6, line: 1, column: 7 },
end: { offset: 16, line: 1, column: 17 },
- source: '#a="{ b }"'
- }
+ source: '#a="{ b }"',
+ },
})
})
@@ -1626,32 +1896,32 @@ describe('compiler: parse', () => {
expect(directive).toMatchObject({
type: NodeTypes.DIRECTIVE,
name: 'slot',
+ rawName: 'v-slot:foo.bar',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'foo.bar',
isStatic: true,
constType: ConstantTypes.CAN_STRINGIFY,
loc: {
- source: 'foo.bar',
start: {
column: 14,
line: 1,
- offset: 13
+ offset: 13,
},
end: {
column: 21,
line: 1,
- offset: 20
- }
- }
- }
+ offset: 20,
+ },
+ },
+ },
})
})
test('v-pre', () => {
const ast = baseParse(
` {{ bar }}
\n` +
- ` {{ bar }}
`
+ ` {{ bar }}
`,
)
const divWithPre = ast.children[0] as ElementNode
@@ -1661,29 +1931,22 @@ describe('compiler: parse', () => {
name: `:id`,
value: {
type: NodeTypes.TEXT,
- content: `foo`
+ content: `foo`,
},
loc: {
- source: `:id="foo"`,
- start: {
- line: 1,
- column: 12
- },
- end: {
- line: 1,
- column: 21
- }
- }
- }
+ start: { line: 1, column: 12 },
+ end: { line: 1, column: 21 },
+ },
+ },
])
expect(divWithPre.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tagType: ElementTypes.ELEMENT,
- tag: `Comp`
+ tag: `Comp`,
})
expect(divWithPre.children[1]).toMatchObject({
type: NodeTypes.TEXT,
- content: `{{ bar }}`
+ content: `{{ bar }}`,
})
// should not affect siblings after it
@@ -1695,44 +1958,87 @@ describe('compiler: parse', () => {
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: true,
- content: `id`
+ content: `id`,
},
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: false,
- content: `foo`
+ content: `foo`,
},
loc: {
- source: `:id="foo"`,
start: {
line: 2,
- column: 6
+ column: 6,
},
end: {
line: 2,
- column: 15
- }
- }
- }
+ column: 15,
+ },
+ },
+ },
])
expect(divWithoutPre.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tagType: ElementTypes.COMPONENT,
- tag: `Comp`
+ tag: `Comp`,
})
expect(divWithoutPre.children[1]).toMatchObject({
type: NodeTypes.INTERPOLATION,
content: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `bar`,
- isStatic: false
- }
+ isStatic: false,
+ },
})
})
+ // https://github.com/vuejs/docs/issues/2586
+ test('v-pre with half-open interpolation', () => {
+ const ast = baseParse(
+ `
+ {{ number
+ }}
+
+ `,
+ )
+ expect((ast.children[0] as ElementNode).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ children: [{ type: NodeTypes.TEXT, content: `{{ number ` }],
+ },
+ {
+ type: NodeTypes.ELEMENT,
+ children: [{ type: NodeTypes.TEXT, content: `}}` }],
+ },
+ ])
+
+ const ast2 = baseParse(`{{ number
`)
+ expect((ast2.children[0] as ElementNode).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ children: [{ type: NodeTypes.TEXT, content: `{{ number ` }],
+ },
+ ])
+
+ const ast3 = baseParse(`
`, {
+ parseMode: 'html',
+ })
+ expect((ast3.children[0] as ElementNode).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ children: [
+ {
+ type: NodeTypes.TEXT,
+ content: `{{ foo `,
+ },
+ ],
+ },
+ ])
+ })
+
test('self-closing v-pre', () => {
const ast = baseParse(
- `
\n {{ bar }}
`
+ `
\n {{ bar }}
`,
)
// should not affect siblings after it
const divWithoutPre = ast.children[1] as ElementNode
@@ -1743,38 +2049,37 @@ describe('compiler: parse', () => {
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: true,
- content: `id`
+ content: `id`,
},
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: false,
- content: `foo`
+ content: `foo`,
},
loc: {
- source: `:id="foo"`,
start: {
line: 2,
- column: 6
+ column: 6,
},
end: {
line: 2,
- column: 15
- }
- }
- }
+ column: 15,
+ },
+ },
+ },
])
expect(divWithoutPre.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tagType: ElementTypes.COMPONENT,
- tag: `Comp`
+ tag: `Comp`,
})
expect(divWithoutPre.children[1]).toMatchObject({
type: NodeTypes.INTERPOLATION,
content: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `bar`,
- isStatic: false
- }
+ isStatic: false,
+ },
})
})
@@ -1789,133 +2094,192 @@ describe('compiler: parse', () => {
loc: {
start: { offset: 5, line: 1, column: 6 },
end: { offset: 10, line: 1, column: 11 },
- source: 'hello'
- }
+ source: 'hello',
+ },
})
})
})
- test('self closing single tag', () => {
- const ast = baseParse('
')
+ describe('Edge Cases', () => {
+ test('self closing single tag', () => {
+ const ast = baseParse('
')
- expect(ast.children).toHaveLength(1)
- expect(ast.children[0]).toMatchObject({ tag: 'div' })
- })
+ expect(ast.children).toHaveLength(1)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
+ })
- test('self closing multiple tag', () => {
- const ast = baseParse(
- `
\n` +
- `
`
- )
+ test('self closing multiple tag', () => {
+ const ast = baseParse(
+ `
\n` +
+ `
`,
+ )
- expect(ast).toMatchSnapshot()
+ expect(ast).toMatchSnapshot()
- expect(ast.children).toHaveLength(2)
- expect(ast.children[0]).toMatchObject({ tag: 'div' })
- expect(ast.children[1]).toMatchObject({ tag: 'p' })
- })
+ expect(ast.children).toHaveLength(2)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
+ expect(ast.children[1]).toMatchObject({ tag: 'p' })
+ })
- test('valid html', () => {
- const ast = baseParse(
- `\n` +
- `
\n` +
- ` \n` +
- `
`
- )
+ test('valid html', () => {
+ const ast = baseParse(
+ `\n` +
+ `
\n` +
+ ` \n` +
+ `
`,
+ )
- expect(ast).toMatchSnapshot()
+ expect(ast).toMatchSnapshot()
- expect(ast.children).toHaveLength(1)
- const el = ast.children[0] as any
- expect(el).toMatchObject({
- tag: 'div'
- })
- expect(el.children).toHaveLength(2)
- expect(el.children[0]).toMatchObject({
- tag: 'p'
+ expect(ast.children).toHaveLength(1)
+ const el = ast.children[0] as any
+ expect(el).toMatchObject({
+ tag: 'div',
+ })
+ expect(el.children).toHaveLength(2)
+ expect(el.children[0]).toMatchObject({
+ tag: 'p',
+ })
+ expect(el.children[1]).toMatchObject({
+ type: NodeTypes.COMMENT,
+ })
})
- expect(el.children[1]).toMatchObject({
- type: NodeTypes.COMMENT
+
+ test('invalid html', () => {
+ expect(() => {
+ baseParse(`\n\n
\n`)
+ }).toThrow('Element is missing end tag.')
+
+ const spy = vi.fn()
+ const ast = baseParse(`\n\n
\n`, {
+ onError: spy,
+ })
+
+ expect(spy.mock.calls).toMatchObject([
+ [
+ {
+ code: ErrorCodes.X_MISSING_END_TAG,
+ loc: {
+ start: {
+ offset: 6,
+ line: 2,
+ column: 1,
+ },
+ },
+ },
+ ],
+ [
+ {
+ code: ErrorCodes.X_INVALID_END_TAG,
+ loc: {
+ start: {
+ offset: 20,
+ line: 4,
+ column: 1,
+ },
+ },
+ },
+ ],
+ ])
+
+ expect(ast).toMatchSnapshot()
+ })
+
+ test('parse with correct location info', () => {
+ const fooSrc = `foo\n is `
+ const barSrc = `{{ bar }}`
+ const butSrc = ` but `
+ const bazSrc = `{{ baz }}`
+ const [foo, bar, but, baz] = baseParse(
+ fooSrc + barSrc + butSrc + bazSrc,
+ ).children
+
+ let offset = 0
+ expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
+ offset += fooSrc.length
+ expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
+
+ expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
+ const barInner = (bar as InterpolationNode).content
+ offset += 3
+ expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
+ offset += 3
+ expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
+ offset += 3
+ expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
+
+ expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
+ offset += butSrc.length
+ expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
+
+ expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
+ const bazInner = (baz as InterpolationNode).content
+ offset += 3
+ expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
+ offset += 3
+ expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
+ offset += 3
+ expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
+ })
+
+ // With standard HTML parsing, the following input would ignore the slash
+ // and treat "<" and "template" as attributes on the open tag of "Hello",
+ // causing `` to fail to close, and ``,
+ {
+ onError: spy,
+ },
+ )
+ //
+ expect(ast.children.length).toBe(2)
+ expect(ast.children[1]).toMatchObject({
+ type: NodeTypes.ELEMENT,
+ tag: 'script',
+ })
})
- })
- test('invalid html', () => {
- expect(() => {
- baseParse(`\n\n
\n`)
- }).toThrow('Element is missing end tag.')
+ test('arg should be undefined on shorthand dirs with no arg', () => {
+ const ast = baseParse(` `)
+ const el = ast.children[0] as ElementNode
+ expect(el.props[0]).toMatchObject({
+ type: NodeTypes.DIRECTIVE,
+ name: 'slot',
+ exp: undefined,
+ arg: undefined,
+ })
+ })
- const spy = jest.fn()
- const ast = baseParse(`\n\n
\n`, {
- onError: spy
+ // edge case found in vue-macros where the input is TS or JSX
+ test('should reset inRCDATA state', () => {
+ baseParse(``, { parseMode: 'sfc', onError() {} })
+ expect(() => baseParse(`{ foo }`)).not.toThrow()
})
- expect(spy.mock.calls).toMatchObject([
- [
- {
- code: ErrorCodes.X_MISSING_END_TAG,
- loc: {
- start: {
- offset: 6,
- line: 2,
- column: 1
- }
- }
- }
- ],
- [
- {
- code: ErrorCodes.X_INVALID_END_TAG,
- loc: {
- start: {
- offset: 20,
- line: 4,
- column: 1
- }
- }
- }
- ]
- ])
+ test('correct loc when the closing > is foarmatted', () => {
+ const [span] = baseParse(` `).children
- expect(ast).toMatchSnapshot()
- })
+ expect(span.loc.source).toBe(' ')
+ expect(span.loc.start.offset).toBe(0)
+ expect(span.loc.end.offset).toBe(27)
+ })
- test('parse with correct location info', () => {
- const [foo, bar, but, baz] = baseParse(
- `
-foo
- is {{ bar }} but {{ baz }}`.trim()
- ).children
-
- let offset = 0
- expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
- offset += foo.loc.source.length
- expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
-
- expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
- const barInner = (bar as InterpolationNode).content
- offset += 3
- expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
- offset += barInner.loc.source.length
- expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
- offset += 3
- expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
-
- expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
- offset += but.loc.source.length
- expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
-
- expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
- const bazInner = (baz as InterpolationNode).content
- offset += 3
- expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
- offset += bazInner.loc.source.length
- expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
- offset += 3
- expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
+ test('correct loc when a line in attribute value ends with &', () => {
+ const [span] = baseParse(` `).children
+ expect(span.loc.end.line).toBe(2)
+ })
})
describe('decodeEntities option', () => {
- test('use default map', () => {
+ test('use decode by default', () => {
const ast: any = baseParse('><&'"&foo;')
expect(ast.children.length).toBe(1)
@@ -1923,15 +2287,14 @@ foo
expect(ast.children[0].content).toBe('><&\'"&foo;')
})
- test('use the given map', () => {
- const ast: any = baseParse('&∪︀', {
+ test('should warn in non-browser build', () => {
+ baseParse('&∪︀', {
decodeEntities: text => text.replace('∪︀', '\u222A\uFE00'),
- onError: () => {} // Ignore errors
+ onError: () => {}, // Ignore errors
})
-
- expect(ast.children.length).toBe(1)
- expect(ast.children[0].type).toBe(NodeTypes.TEXT)
- expect(ast.children[0].content).toBe('&\u222A\uFE00')
+ expect(
+ `decodeEntities option is passed but will be ignored`,
+ ).toHaveBeenWarned()
})
})
@@ -1939,21 +2302,21 @@ foo
const parse = (content: string, options?: ParserOptions) =>
baseParse(content, {
whitespace: 'condense',
- ...options
+ ...options,
})
- it('should remove whitespaces at start/end inside an element', () => {
+ test('should remove whitespaces at start/end inside an element', () => {
const ast = parse(`
`)
expect((ast.children[0] as ElementNode).children.length).toBe(1)
})
- it('should remove whitespaces w/ newline between elements', () => {
+ test('should remove whitespaces w/ newline between elements', () => {
const ast = parse(`
\n
\n
`)
expect(ast.children.length).toBe(3)
expect(ast.children.every(c => c.type === NodeTypes.ELEMENT)).toBe(true)
})
- it('should remove whitespaces adjacent to comments', () => {
+ test('should remove whitespaces adjacent to comments', () => {
const ast = parse(`
\n
`)
expect(ast.children.length).toBe(3)
expect(ast.children[0].type).toBe(NodeTypes.ELEMENT)
@@ -1961,7 +2324,7 @@ foo
expect(ast.children[2].type).toBe(NodeTypes.ELEMENT)
})
- it('should remove whitespaces w/ newline between comments and elements', () => {
+ test('should remove whitespaces w/ newline between comments and elements', () => {
const ast = parse(`
\n \n
`)
expect(ast.children.length).toBe(3)
expect(ast.children[0].type).toBe(NodeTypes.ELEMENT)
@@ -1969,29 +2332,29 @@ foo
expect(ast.children[2].type).toBe(NodeTypes.ELEMENT)
})
- it('should NOT remove whitespaces w/ newline between interpolations', () => {
+ test('should NOT remove whitespaces w/ newline between interpolations', () => {
const ast = parse(`{{ foo }} \n {{ bar }}`)
expect(ast.children.length).toBe(3)
expect(ast.children[0].type).toBe(NodeTypes.INTERPOLATION)
expect(ast.children[1]).toMatchObject({
type: NodeTypes.TEXT,
- content: ' '
+ content: ' ',
})
expect(ast.children[2].type).toBe(NodeTypes.INTERPOLATION)
})
- it('should NOT remove whitespaces w/ newline between interpolation and comment', () => {
+ test('should NOT remove whitespaces w/ newline between interpolation and comment', () => {
const ast = parse(` \n {{msg}}`)
expect(ast.children.length).toBe(3)
expect(ast.children[0].type).toBe(NodeTypes.COMMENT)
expect(ast.children[1]).toMatchObject({
type: NodeTypes.TEXT,
- content: ' '
+ content: ' ',
})
expect(ast.children[2].type).toBe(NodeTypes.INTERPOLATION)
})
-
- it('should NOT remove whitespaces w/o newline between elements', () => {
+
+ test('should NOT remove whitespaces w/o newline between elements', () => {
const ast = parse(`
`)
expect(ast.children.length).toBe(5)
expect(ast.children.map(c => c.type)).toMatchObject([
@@ -1999,18 +2362,19 @@ foo
NodeTypes.TEXT,
NodeTypes.ELEMENT,
NodeTypes.TEXT,
- NodeTypes.ELEMENT
+ NodeTypes.ELEMENT,
])
})
- it('should condense consecutive whitespaces in text', () => {
+ test('should condense consecutive whitespaces in text', () => {
const ast = parse(` foo \n bar baz `)
expect((ast.children[0] as TextNode).content).toBe(` foo bar baz `)
})
- it('should remove leading newline character immediately following the pre element start tag', () => {
- const ast = baseParse(`\n foo bar `, {
- isPreTag: tag => tag === 'pre'
+ test('should remove leading newline character immediately following the pre element start tag', () => {
+ const ast = parse(`\n foo bar `, {
+ isPreTag: tag => tag === 'pre',
+ isIgnoreNewlineTag: tag => tag === 'pre',
})
expect(ast.children).toHaveLength(1)
const preElement = ast.children[0] as ElementNode
@@ -2018,30 +2382,29 @@ foo
expect((preElement.children[0] as TextNode).content).toBe(` foo bar `)
})
- it('should NOT remove leading newline character immediately following child-tag of pre element', () => {
- const ast = baseParse(` \n foo bar `, {
- isPreTag: tag => tag === 'pre'
+ test('should NOT remove leading newline character immediately following child-tag of pre element', () => {
+ const ast = parse(` \n foo bar `, {
+ isPreTag: tag => tag === 'pre',
})
const preElement = ast.children[0] as ElementNode
expect(preElement.children).toHaveLength(2)
expect((preElement.children[1] as TextNode).content).toBe(
- `\n foo bar `
+ `\n foo bar `,
)
})
- it('self-closing pre tag', () => {
- const ast = baseParse(`\n foo bar `, {
- isPreTag: tag => tag === 'pre'
+ test('self-closing pre tag', () => {
+ const ast = parse(`\n foo bar `, {
+ isPreTag: tag => tag === 'pre',
})
const elementAfterPre = ast.children[1] as ElementNode
// should not affect the and condense its whitespace inside
expect((elementAfterPre.children[0] as TextNode).content).toBe(` foo bar`)
})
- it('should NOT condense whitespaces in RCDATA text mode', () => {
- const ast = baseParse(``, {
- getTextMode: ({ tag }) =>
- tag === 'textarea' ? TextModes.RCDATA : TextModes.DATA
+ test('should NOT condense whitespaces in RCDATA text mode', () => {
+ const ast = parse(``, {
+ parseMode: 'html',
})
const preElement = ast.children[0] as ElementNode
expect(preElement.children).toHaveLength(1)
@@ -2053,15 +2416,15 @@ foo
const parse = (content: string, options?: ParserOptions) =>
baseParse(content, {
whitespace: 'preserve',
- ...options
+ ...options,
})
- it('should still remove whitespaces at start/end inside an element', () => {
+ test('should still remove whitespaces at start/end inside an element', () => {
const ast = parse(`
`)
expect((ast.children[0] as ElementNode).children.length).toBe(1)
})
- it('should preserve whitespaces w/ newline between elements', () => {
+ test('should preserve whitespaces w/ newline between elements', () => {
const ast = parse(`
\n
\n
`)
expect(ast.children.length).toBe(5)
expect(ast.children.map(c => c.type)).toMatchObject([
@@ -2069,11 +2432,11 @@ foo
NodeTypes.TEXT,
NodeTypes.ELEMENT,
NodeTypes.TEXT,
- NodeTypes.ELEMENT
+ NodeTypes.ELEMENT,
])
})
- it('should preserve whitespaces adjacent to comments', () => {
+ test('should preserve whitespaces adjacent to comments', () => {
const ast = parse(`
\n
`)
expect(ast.children.length).toBe(5)
expect(ast.children.map(c => c.type)).toMatchObject([
@@ -2081,11 +2444,11 @@ foo
NodeTypes.TEXT,
NodeTypes.COMMENT,
NodeTypes.TEXT,
- NodeTypes.ELEMENT
+ NodeTypes.ELEMENT,
])
})
- it('should preserve whitespaces w/ newline between comments and elements', () => {
+ test('should preserve whitespaces w/ newline between comments and elements', () => {
const ast = parse(`
\n \n
`)
expect(ast.children.length).toBe(5)
expect(ast.children.map(c => c.type)).toMatchObject([
@@ -2093,22 +2456,22 @@ foo
NodeTypes.TEXT,
NodeTypes.COMMENT,
NodeTypes.TEXT,
- NodeTypes.ELEMENT
+ NodeTypes.ELEMENT,
])
})
- it('should preserve whitespaces w/ newline between interpolations', () => {
+ test('should preserve whitespaces w/ newline between interpolations', () => {
const ast = parse(`{{ foo }} \n {{ bar }}`)
expect(ast.children.length).toBe(3)
expect(ast.children[0].type).toBe(NodeTypes.INTERPOLATION)
expect(ast.children[1]).toMatchObject({
type: NodeTypes.TEXT,
- content: ' '
+ content: ' ',
})
expect(ast.children[2].type).toBe(NodeTypes.INTERPOLATION)
})
- it('should preserve whitespaces w/o newline between elements', () => {
+ test('should preserve whitespaces w/o newline between elements', () => {
const ast = parse(`
`)
expect(ast.children.length).toBe(5)
expect(ast.children.map(c => c.type)).toMatchObject([
@@ -2116,18 +2479,79 @@ foo
NodeTypes.TEXT,
NodeTypes.ELEMENT,
NodeTypes.TEXT,
- NodeTypes.ELEMENT
+ NodeTypes.ELEMENT,
])
})
- it('should preserve consecutive whitespaces in text', () => {
+ test('should preserve consecutive whitespaces in text', () => {
const content = ` foo \n bar baz `
const ast = parse(content)
expect((ast.children[0] as TextNode).content).toBe(content)
})
})
+ describe('expression parsing', () => {
+ test('interpolation', () => {
+ const ast = baseParse(`{{ a + b }}`, { prefixIdentifiers: true })
+ // @ts-expect-error
+ expect((ast.children[0] as InterpolationNode).content.ast?.type).toBe(
+ 'BinaryExpression',
+ )
+ })
+
+ test('v-bind', () => {
+ const ast = baseParse(`
`, {
+ prefixIdentifiers: true,
+ })
+ const dir = (ast.children[0] as ElementNode).props[0] as DirectiveNode
+ // @ts-expect-error
+ expect(dir.arg?.ast?.type).toBe('BinaryExpression')
+ // @ts-expect-error
+ expect(dir.exp?.ast?.type).toBe('CallExpression')
+ })
+
+ test('v-on multi statements', () => {
+ const ast = baseParse(`
`, {
+ prefixIdentifiers: true,
+ })
+ const dir = (ast.children[0] as ElementNode).props[0] as DirectiveNode
+ // @ts-expect-error
+ expect(dir.exp?.ast?.type).toBe('Program')
+ expect((dir.exp?.ast as Program).body).toMatchObject([
+ { type: 'ExpressionStatement' },
+ { type: 'ExpressionStatement' },
+ ])
+ })
+
+ test('v-slot', () => {
+ const ast = baseParse(` `, {
+ prefixIdentifiers: true,
+ })
+ const dir = (ast.children[0] as ElementNode).props[0] as DirectiveNode
+ // @ts-expect-error
+ expect(dir.exp?.ast?.type).toBe('ArrowFunctionExpression')
+ })
+
+ test('v-for', () => {
+ const ast = baseParse(`
`, {
+ prefixIdentifiers: true,
+ })
+ const dir = (ast.children[0] as ElementNode).props[0] as DirectiveNode
+ const { source, value, key, index } = dir.forParseResult!
+ // @ts-expect-error
+ expect(source.ast?.type).toBe('MemberExpression')
+ // @ts-expect-error
+ expect(value?.ast?.type).toBe('ArrowFunctionExpression')
+ expect(key?.ast).toBeNull() // simple ident
+ expect(index?.ast).toBeNull() // simple ident
+ })
+ })
+
describe('Errors', () => {
+ // HTML parsing errors as specified at
+ // https://html.spec.whatwg.org/multipage/parsing.html#parse-errors
+ // We ignore some errors that do NOT affect parse result in meaningful ways
+ // but have non-trivial implementation cost.
const patterns: {
[key: string]: Array<{
code: string
@@ -2135,44 +2559,44 @@ foo
options?: Partial
}>
} = {
- ABRUPT_CLOSING_OF_EMPTY_COMMENT: [
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
- },
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
- },
- {
- code: ' ',
- errors: []
- }
- ],
+ // ABRUPT_CLOSING_OF_EMPTY_COMMENT: [
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT,
+ // loc: { offset: 10, line: 1, column: 11 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT,
+ // loc: { offset: 10, line: 1, column: 11 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: []
+ // }
+ // ],
CDATA_IN_HTML_CONTENT: [
{
code: ' ',
errors: [
{
type: ErrorCodes.CDATA_IN_HTML_CONTENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
+ loc: { offset: 10, line: 1, column: 11 },
+ },
+ ],
},
{
code: ' ',
- errors: []
- }
+ errors: [],
+ },
],
DUPLICATE_ATTRIBUTE: [
{
@@ -2180,60 +2604,60 @@ foo
errors: [
{
type: ErrorCodes.DUPLICATE_ATTRIBUTE,
- loc: { offset: 21, line: 1, column: 22 }
- }
- ]
- }
- ],
- END_TAG_WITH_ATTRIBUTES: [
- {
- code: '
',
- errors: [
- {
- type: ErrorCodes.END_TAG_WITH_ATTRIBUTES,
- loc: { offset: 21, line: 1, column: 22 }
- }
- ]
- }
- ],
- END_TAG_WITH_TRAILING_SOLIDUS: [
- {
- code: '
',
- errors: [
- {
- type: ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS,
- loc: { offset: 20, line: 1, column: 21 }
- }
- ]
- }
+ loc: { offset: 21, line: 1, column: 22 },
+ },
+ ],
+ },
],
+ // END_TAG_WITH_ATTRIBUTES: [
+ // {
+ // code: '
',
+ // errors: [
+ // {
+ // type: ErrorCodes.END_TAG_WITH_ATTRIBUTES,
+ // loc: { offset: 21, line: 1, column: 22 }
+ // }
+ // ]
+ // }
+ // ],
+ // END_TAG_WITH_TRAILING_SOLIDUS: [
+ // {
+ // code: '
',
+ // errors: [
+ // {
+ // type: ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS,
+ // loc: { offset: 20, line: 1, column: 21 }
+ // }
+ // ]
+ // }
+ // ],
EOF_BEFORE_TAG_NAME: [
{
code: '<',
errors: [
{
type: ErrorCodes.EOF_BEFORE_TAG_NAME,
- loc: { offset: 11, line: 1, column: 12 }
+ loc: { offset: 11, line: 1, column: 12 },
},
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
},
{
code: '',
errors: [
{
type: ErrorCodes.EOF_BEFORE_TAG_NAME,
- loc: { offset: 12, line: 1, column: 13 }
+ loc: { offset: 12, line: 1, column: 13 },
},
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
- }
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
+ },
],
EOF_IN_CDATA: [
{
@@ -2241,35 +2665,35 @@ foo
errors: [
{
type: ErrorCodes.EOF_IN_CDATA,
- loc: { offset: 29, line: 1, column: 30 }
+ loc: { offset: 29, line: 1, column: 30 },
},
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 10, line: 1, column: 11 }
+ loc: { offset: 10, line: 1, column: 11 },
},
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
},
{
code: ' ',
- errors: [
- {
- type: ErrorCodes.INCORRECTLY_CLOSED_COMMENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
- }
- ],
- INCORRECTLY_OPENED_COMMENT: [
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.INCORRECTLY_OPENED_COMMENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
- },
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.INCORRECTLY_OPENED_COMMENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
- },
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.INCORRECTLY_OPENED_COMMENT,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
- },
- // Just ignore doctype.
- {
- code: '',
- errors: []
- }
- ],
- INVALID_FIRST_CHARACTER_OF_TAG_NAME: [
- {
- code: 'a < b ',
- errors: [
- {
- type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
- loc: { offset: 13, line: 1, column: 14 }
- }
- ]
- },
- {
- code: '<�> ',
- errors: [
- {
- type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
- loc: { offset: 11, line: 1, column: 12 }
- }
- ]
- },
- {
- code: 'a b ',
- errors: [
- {
- type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
- loc: { offset: 14, line: 1, column: 15 }
+ loc: { offset: 10, line: 1, column: 11 },
},
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
- },
- {
- code: '�> ',
- errors: [
- {
- type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
- loc: { offset: 12, line: 1, column: 13 }
- }
- ]
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
},
- // Don't throw invalid-first-character-of-tag-name in interpolation
- {
- code: '{{a < b}} ',
- errors: []
- }
],
+ // INCORRECTLY_CLOSED_COMMENT: [
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INCORRECTLY_CLOSED_COMMENT,
+ // loc: { offset: 10, line: 1, column: 11 }
+ // }
+ // ]
+ // }
+ // ],
+ // INCORRECTLY_OPENED_COMMENT: [
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INCORRECTLY_OPENED_COMMENT,
+ // loc: { offset: 10, line: 1, column: 11 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INCORRECTLY_OPENED_COMMENT,
+ // loc: { offset: 10, line: 1, column: 11 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INCORRECTLY_OPENED_COMMENT,
+ // loc: { offset: 10, line: 1, column: 11 }
+ // }
+ // ]
+ // },
+ // // Just ignore doctype.
+ // {
+ // code: '',
+ // errors: []
+ // }
+ // ],
+ // INVALID_FIRST_CHARACTER_OF_TAG_NAME: [
+ // {
+ // code: 'a < b ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ // loc: { offset: 13, line: 1, column: 14 }
+ // }
+ // ]
+ // },
+ // {
+ // code: '<�> ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ // loc: { offset: 11, line: 1, column: 12 }
+ // }
+ // ]
+ // },
+ // {
+ // code: 'a b ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ // loc: { offset: 14, line: 1, column: 15 }
+ // },
+ // {
+ // type: ErrorCodes.X_MISSING_END_TAG,
+ // loc: { offset: 0, line: 1, column: 1 }
+ // }
+ // ]
+ // },
+ // {
+ // code: '�> ',
+ // errors: [
+ // {
+ // type: ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ // loc: { offset: 12, line: 1, column: 13 }
+ // }
+ // ]
+ // },
+ // // Don't throw invalid-first-character-of-tag-name in interpolation
+ // {
+ // code: '{{a < b}} ',
+ // errors: []
+ // }
+ // ],
MISSING_ATTRIBUTE_VALUE: [
{
code: '
',
errors: [
{
type: ErrorCodes.MISSING_ATTRIBUTE_VALUE,
- loc: { offset: 18, line: 1, column: 19 }
- }
- ]
+ loc: { offset: 18, line: 1, column: 19 },
+ },
+ ],
},
{
code: '
',
errors: [
{
type: ErrorCodes.MISSING_ATTRIBUTE_VALUE,
- loc: { offset: 19, line: 1, column: 20 }
- }
- ]
+ loc: { offset: 19, line: 1, column: 20 },
+ },
+ ],
},
{
code: '
',
- errors: []
- }
+ errors: [],
+ },
],
MISSING_END_TAG_NAME: [
{
@@ -2734,106 +3110,106 @@ foo
errors: [
{
type: ErrorCodes.MISSING_END_TAG_NAME,
- loc: { offset: 12, line: 1, column: 13 }
- }
- ]
- }
- ],
- MISSING_WHITESPACE_BETWEEN_ATTRIBUTES: [
- {
- code: '
',
- errors: [
- {
- type: ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES,
- loc: { offset: 23, line: 1, column: 24 }
- }
- ]
- },
- // CR doesn't appear in tokenization phase, but all CR are removed in preprocessing.
- // https://html.spec.whatwg.org/multipage/parsing.html#preprocessing-the-input-stream
- {
- code: '
',
- errors: []
- }
- ],
- NESTED_COMMENT: [
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.NESTED_COMMENT,
- loc: { offset: 15, line: 1, column: 16 }
- }
- ]
- },
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.NESTED_COMMENT,
- loc: { offset: 15, line: 1, column: 16 }
+ loc: { offset: 12, line: 1, column: 13 },
},
- {
- type: ErrorCodes.NESTED_COMMENT,
- loc: { offset: 20, line: 1, column: 21 }
- }
- ]
+ ],
},
- {
- code: ' ',
- errors: [
- {
- type: ErrorCodes.NESTED_COMMENT,
- loc: { offset: 15, line: 1, column: 16 }
- }
- ]
- },
- {
- code: ' ',
- errors: []
- },
- {
- code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.NESTED_COMMENT,
+ // loc: { offset: 15, line: 1, column: 16 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.NESTED_COMMENT,
+ // loc: { offset: 15, line: 1, column: 16 }
+ // },
+ // {
+ // type: ErrorCodes.NESTED_COMMENT,
+ // loc: { offset: 20, line: 1, column: 21 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: [
+ // {
+ // type: ErrorCodes.NESTED_COMMENT,
+ // loc: { offset: 15, line: 1, column: 16 }
+ // }
+ // ]
+ // },
+ // {
+ // code: ' ',
+ // errors: []
+ // },
+ // {
+ // code: '',
- errors: []
- }
+ errors: [],
+ },
],
X_MISSING_END_TAG: [
{
@@ -2970,23 +3359,23 @@ foo
errors: [
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 10, line: 1, column: 11 }
- }
- ]
+ loc: { offset: 10, line: 1, column: 11 },
+ },
+ ],
},
{
code: '',
errors: [
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 10, line: 1, column: 11 }
+ loc: { offset: 10, line: 1, column: 11 },
},
{
type: ErrorCodes.X_MISSING_END_TAG,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
- }
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
+ },
],
X_MISSING_INTERPOLATION_END: [
{
@@ -2994,23 +3383,36 @@ foo
errors: [
{
type: ErrorCodes.X_MISSING_INTERPOLATION_END,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
},
{
code: '{{',
errors: [
{
type: ErrorCodes.X_MISSING_INTERPOLATION_END,
- loc: { offset: 0, line: 1, column: 1 }
- }
- ]
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
+ },
+ {
+ code: '
{{ foo
',
+ errors: [
+ {
+ type: ErrorCodes.X_MISSING_INTERPOLATION_END,
+ loc: { offset: 5, line: 1, column: 6 },
+ },
+ {
+ type: ErrorCodes.X_MISSING_END_TAG,
+ loc: { offset: 0, line: 1, column: 1 },
+ },
+ ],
},
{
code: '{{}}',
- errors: []
- }
+ errors: [],
+ },
],
X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END: [
{
@@ -3018,54 +3420,39 @@ foo
errors: [
{
type: ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END,
- loc: { offset: 15, line: 1, column: 16 }
- }
- ]
- }
- ]
+ loc: { offset: 15, line: 1, column: 16 },
+ },
+ ],
+ },
+ ],
}
- for (const key of Object.keys(patterns) as (keyof typeof patterns)[]) {
+ for (const key of Object.keys(patterns)) {
describe(key, () => {
for (const { code, errors, options } of patterns[key]) {
test(
code.replace(
/[\r\n]/g,
- c => `\\x0${c.codePointAt(0)!.toString(16)};`
+ c => `\\x0${c.codePointAt(0)!.toString(16)};`,
),
() => {
- const spy = jest.fn()
+ const spy = vi.fn()
const ast = baseParse(code, {
- getNamespace: (tag, parent) => {
- const ns = parent ? parent.ns : Namespaces.HTML
- if (ns === Namespaces.HTML) {
- if (tag === 'svg') {
- return (Namespaces.HTML + 1) as any
- }
- }
- return ns
- },
- getTextMode: ({ tag }) => {
- if (tag === 'textarea') {
- return TextModes.RCDATA
- }
- if (tag === 'script') {
- return TextModes.RAWTEXT
- }
- return TextModes.DATA
- },
+ parseMode: 'html',
+ getNamespace: tag =>
+ tag === 'svg' ? Namespaces.SVG : Namespaces.HTML,
...options,
- onError: spy
+ onError: spy,
})
expect(
spy.mock.calls.map(([err]) => ({
type: err.code,
- loc: err.loc.start
- }))
+ loc: err.loc.start,
+ })),
).toMatchObject(errors)
expect(ast).toMatchSnapshot()
- }
+ },
)
}
})
diff --git a/packages/compiler-core/__tests__/scopeId.spec.ts b/packages/compiler-core/__tests__/scopeId.spec.ts
index 5f7ea0d2e6a..7d1d27e115f 100644
--- a/packages/compiler-core/__tests__/scopeId.spec.ts
+++ b/packages/compiler-core/__tests__/scopeId.spec.ts
@@ -1,7 +1,4 @@
import { baseCompile } from '../src/compile'
-import { PUSH_SCOPE_ID, POP_SCOPE_ID } from '../src/runtimeHelpers'
-import { PatchFlags } from '@vue/shared'
-import { genFlagText } from './testUtils'
/**
* Ensure all slot functions are wrapped with _withCtx
@@ -18,7 +15,7 @@ describe('scopeId compiler support', () => {
test('should wrap default slot', () => {
const { code } = baseCompile(`
`, {
mode: 'module',
- scopeId: 'test'
+ scopeId: 'test',
})
expect(code).toMatch(`default: _withCtx(() => [`)
expect(code).toMatchSnapshot()
@@ -33,8 +30,8 @@ describe('scopeId compiler support', () => {
`,
{
mode: 'module',
- scopeId: 'test'
- }
+ scopeId: 'test',
+ },
)
expect(code).toMatch(`foo: _withCtx(({ msg }) => [`)
expect(code).toMatch(`bar: _withCtx(() => [`)
@@ -50,35 +47,11 @@ describe('scopeId compiler support', () => {
`,
{
mode: 'module',
- scopeId: 'test'
- }
+ scopeId: 'test',
+ },
)
expect(code).toMatch(/name: "foo",\s+fn: _withCtx\(/)
expect(code).toMatch(/name: i,\s+fn: _withCtx\(/)
expect(code).toMatchSnapshot()
})
-
- test('should push scopeId for hoisted nodes', () => {
- const { ast, code } = baseCompile(
- `
`,
- {
- mode: 'module',
- scopeId: 'test',
- hoistStatic: true
- }
- )
- expect(ast.helpers).toContain(PUSH_SCOPE_ID)
- expect(ast.helpers).toContain(POP_SCOPE_ID)
- expect(ast.hoists.length).toBe(2)
- ;[
- `const _withScopeId = n => (_pushScopeId("test"),n=n(),_popScopeId(),n)`,
- `const _hoisted_1 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode("div", null, "hello", ${genFlagText(
- PatchFlags.HOISTED
- )}))`,
- `const _hoisted_2 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode("div", null, "world", ${genFlagText(
- PatchFlags.HOISTED
- )}))`
- ].forEach(c => expect(code).toMatch(c))
- expect(code).toMatchSnapshot()
- })
})
diff --git a/packages/compiler-core/__tests__/testUtils.ts b/packages/compiler-core/__tests__/testUtils.ts
index 23a29a777e3..a2525e0cab9 100644
--- a/packages/compiler-core/__tests__/testUtils.ts
+++ b/packages/compiler-core/__tests__/testUtils.ts
@@ -1,17 +1,19 @@
import {
+ type ElementNode,
+ ElementTypes,
+ Namespaces,
NodeTypes,
- ElementNode,
+ type Property,
+ type SimpleExpressionNode,
+ type VNodeCall,
locStub,
- Namespaces,
- ElementTypes,
- VNodeCall
} from '../src'
import {
- isString,
- PatchFlags,
PatchFlagNames,
+ type PatchFlags,
+ type ShapeFlags,
isArray,
- ShapeFlags
+ isString,
} from '@vue/shared'
const leadingBracketRE = /^\[/
@@ -22,7 +24,10 @@ const bracketsRE = /^\[|\]$/g
// e.g.
// - createObjectMatcher({ 'foo': '[bar]' }) matches { foo: bar }
// - createObjectMatcher({ '[foo]': 'bar' }) matches { [foo]: "bar" }
-export function createObjectMatcher(obj: Record
) {
+export function createObjectMatcher(obj: Record): {
+ type: NodeTypes
+ properties: Partial[]
+} {
return {
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: Object.keys(obj).map(key => ({
@@ -30,16 +35,16 @@ export function createObjectMatcher(obj: Record) {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: key.replace(bracketsRE, ''),
- isStatic: !leadingBracketRE.test(key)
- },
+ isStatic: !leadingBracketRE.test(key),
+ } as SimpleExpressionNode,
value: isString(obj[key])
? {
type: NodeTypes.SIMPLE_EXPRESSION,
content: obj[key].replace(bracketsRE, ''),
- isStatic: !leadingBracketRE.test(obj[key])
+ isStatic: !leadingBracketRE.test(obj[key]),
}
- : obj[key]
- }))
+ : obj[key],
+ })),
}
}
@@ -48,7 +53,7 @@ export function createElementWithCodegen(
props?: VNodeCall['props'],
children?: VNodeCall['children'],
patchFlag?: VNodeCall['patchFlag'],
- dynamicProps?: VNodeCall['dynamicProps']
+ dynamicProps?: VNodeCall['dynamicProps'],
): ElementNode {
return {
type: NodeTypes.ELEMENT,
@@ -56,7 +61,6 @@ export function createElementWithCodegen(
ns: Namespaces.HTML,
tag: 'div',
tagType: ElementTypes.ELEMENT,
- isSelfClosing: false,
props: [],
children: [],
codegenNode: {
@@ -70,16 +74,16 @@ export function createElementWithCodegen(
isBlock: false,
disableTracking: false,
isComponent: false,
- loc: locStub
- }
+ loc: locStub,
+ },
}
}
type Flags = PatchFlags | ShapeFlags
export function genFlagText(
flag: Flags | Flags[],
- names: { [k: number]: string } = PatchFlagNames
-) {
+ names: { [k: number]: string } = PatchFlagNames,
+): string {
if (isArray(flag)) {
let f = 0
flag.forEach(ff => {
diff --git a/packages/compiler-core/__tests__/transform.spec.ts b/packages/compiler-core/__tests__/transform.spec.ts
index 89f0ecda56e..0946d364838 100644
--- a/packages/compiler-core/__tests__/transform.spec.ts
+++ b/packages/compiler-core/__tests__/transform.spec.ts
@@ -1,25 +1,24 @@
-import { baseParse } from '../src/parse'
-import { transform, NodeTransform } from '../src/transform'
+import { baseParse } from '../src/parser'
+import { type NodeTransform, transform } from '../src/transform'
import {
- ElementNode,
+ type DirectiveNode,
+ type ElementNode,
+ type ExpressionNode,
NodeTypes,
- DirectiveNode,
- ExpressionNode,
- VNodeCall
+ type VNodeCall,
} from '../src/ast'
import { ErrorCodes, createCompilerError } from '../src/errors'
import {
- TO_DISPLAY_STRING,
+ CREATE_COMMENT,
FRAGMENT,
RENDER_SLOT,
- CREATE_COMMENT
+ TO_DISPLAY_STRING,
} from '../src/runtimeHelpers'
import { transformIf } from '../src/transforms/vIf'
import { transformFor } from '../src/transforms/vFor'
import { transformElement } from '../src/transforms/transformElement'
import { transformSlotOutlet } from '../src/transforms/transformSlotOutlet'
import { transformText } from '../src/transforms/transformText'
-import { genFlagText } from './testUtils'
import { PatchFlags } from '@vue/shared'
describe('compiler: transform', () => {
@@ -34,7 +33,7 @@ describe('compiler: transform', () => {
}
transform(ast, {
- nodeTransforms: [plugin]
+ nodeTransforms: [plugin],
})
const div = ast.children[0] as ElementNode
@@ -43,29 +42,29 @@ describe('compiler: transform', () => {
ast,
{
parent: null,
- currentNode: ast
- }
+ currentNode: ast,
+ },
])
expect(calls[1]).toMatchObject([
div,
{
parent: ast,
- currentNode: div
- }
+ currentNode: div,
+ },
])
expect(calls[2]).toMatchObject([
div.children[0],
{
parent: div,
- currentNode: div.children[0]
- }
+ currentNode: div.children[0],
+ },
])
expect(calls[3]).toMatchObject([
div.children[1],
{
parent: div,
- currentNode: div.children[1]
- }
+ currentNode: div.children[1],
+ },
])
})
@@ -81,16 +80,16 @@ describe('compiler: transform', () => {
{
type: NodeTypes.TEXT,
content: 'hello',
- isEmpty: false
- }
- ]
- })
+ isEmpty: false,
+ },
+ ],
+ }),
)
}
}
- const spy = jest.fn(plugin)
+ const spy = vi.fn(plugin)
transform(ast, {
- nodeTransforms: [spy]
+ nodeTransforms: [spy],
})
expect(ast.children.length).toBe(2)
@@ -113,9 +112,9 @@ describe('compiler: transform', () => {
context.removeNode()
}
}
- const spy = jest.fn(plugin)
+ const spy = vi.fn(plugin)
transform(ast, {
- nodeTransforms: [spy]
+ nodeTransforms: [spy],
})
expect(ast.children.length).toBe(2)
@@ -141,9 +140,9 @@ describe('compiler: transform', () => {
context.removeNode(context.parent!.children[0])
}
}
- const spy = jest.fn(plugin)
+ const spy = vi.fn(plugin)
transform(ast, {
- nodeTransforms: [spy]
+ nodeTransforms: [spy],
})
expect(ast.children.length).toBe(1)
@@ -168,9 +167,9 @@ describe('compiler: transform', () => {
context.removeNode(context.parent!.children[1])
}
}
- const spy = jest.fn(plugin)
+ const spy = vi.fn(plugin)
transform(ast, {
- nodeTransforms: [spy]
+ nodeTransforms: [spy],
})
expect(ast.children.length).toBe(1)
@@ -194,31 +193,51 @@ describe('compiler: transform', () => {
}
}
transform(ast, {
- nodeTransforms: [mock]
+ nodeTransforms: [mock],
})
expect(ast.hoists).toMatchObject(hoisted)
expect((ast as any).children[0].props[0].exp.content).toBe(`_hoisted_1`)
expect((ast as any).children[1].props[0].exp.content).toBe(`_hoisted_2`)
})
+ test('context.filename and selfName', () => {
+ const ast = baseParse(`
`)
+
+ const calls: any[] = []
+ const plugin: NodeTransform = (node, context) => {
+ calls.push({ ...context })
+ }
+
+ transform(ast, {
+ filename: '/the/fileName.vue',
+ nodeTransforms: [plugin],
+ })
+
+ expect(calls.length).toBe(2)
+ expect(calls[1]).toMatchObject({
+ filename: '/the/fileName.vue',
+ selfName: 'FileName',
+ })
+ })
+
test('onError option', () => {
const ast = baseParse(`
`)
const loc = ast.children[0].loc
const plugin: NodeTransform = (node, context) => {
context.onError(
- createCompilerError(ErrorCodes.X_INVALID_END_TAG, node.loc)
+ createCompilerError(ErrorCodes.X_INVALID_END_TAG, node.loc),
)
}
- const spy = jest.fn()
+ const spy = vi.fn()
transform(ast, {
nodeTransforms: [plugin],
- onError: spy
+ onError: spy,
})
expect(spy.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_INVALID_END_TAG,
- loc
- }
+ loc,
+ },
])
})
@@ -243,8 +262,8 @@ describe('compiler: transform', () => {
transformFor,
transformText,
transformSlotOutlet,
- transformElement
- ]
+ transformElement,
+ ],
})
return ast
}
@@ -253,7 +272,7 @@ describe('compiler: transform', () => {
tag: VNodeCall['tag'],
props?: VNodeCall['props'],
children?: VNodeCall['children'],
- patchFlag?: VNodeCall['patchFlag']
+ patchFlag?: VNodeCall['patchFlag'],
) {
return {
type: NodeTypes.VNODE_CALL,
@@ -261,7 +280,7 @@ describe('compiler: transform', () => {
tag,
props,
children,
- patchFlag
+ patchFlag,
}
}
@@ -275,8 +294,8 @@ describe('compiler: transform', () => {
expect(ast.codegenNode).toMatchObject({
codegenNode: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: RENDER_SLOT
- }
+ callee: RENDER_SLOT,
+ },
})
})
@@ -288,14 +307,14 @@ describe('compiler: transform', () => {
test('root v-if', () => {
const ast = transformWithCodegen(`
`)
expect(ast.codegenNode).toMatchObject({
- type: NodeTypes.IF
+ type: NodeTypes.IF,
})
})
test('root v-for', () => {
const ast = transformWithCodegen(`
`)
expect(ast.codegenNode).toMatchObject({
- type: NodeTypes.FOR
+ type: NodeTypes.FOR,
})
})
@@ -303,28 +322,28 @@ describe('compiler: transform', () => {
const ast = transformWithCodegen(`
`)
expect(ast.codegenNode).toMatchObject({
type: NodeTypes.VNODE_CALL,
- directives: { type: NodeTypes.JS_ARRAY_EXPRESSION }
+ directives: { type: NodeTypes.JS_ARRAY_EXPRESSION },
})
})
test('single text', () => {
const ast = transformWithCodegen(`hello`)
expect(ast.codegenNode).toMatchObject({
- type: NodeTypes.TEXT
+ type: NodeTypes.TEXT,
})
})
test('single interpolation', () => {
const ast = transformWithCodegen(`{{ foo }}`)
expect(ast.codegenNode).toMatchObject({
- type: NodeTypes.INTERPOLATION
+ type: NodeTypes.INTERPOLATION,
})
})
test('single CompoundExpression', () => {
const ast = transformWithCodegen(`{{ foo }} bar baz`)
expect(ast.codegenNode).toMatchObject({
- type: NodeTypes.COMPOUND_EXPRESSION
+ type: NodeTypes.COMPOUND_EXPRESSION,
})
})
@@ -336,10 +355,10 @@ describe('compiler: transform', () => {
undefined,
[
{ type: NodeTypes.ELEMENT, tag: `div` },
- { type: NodeTypes.ELEMENT, tag: `div` }
+ { type: NodeTypes.ELEMENT, tag: `div` },
] as any,
- genFlagText(PatchFlags.STABLE_FRAGMENT)
- )
+ PatchFlags.STABLE_FRAGMENT,
+ ),
)
})
@@ -352,13 +371,10 @@ describe('compiler: transform', () => {
[
{ type: NodeTypes.COMMENT },
{ type: NodeTypes.ELEMENT, tag: `div` },
- { type: NodeTypes.COMMENT }
+ { type: NodeTypes.COMMENT },
] as any,
- genFlagText([
- PatchFlags.STABLE_FRAGMENT,
- PatchFlags.DEV_ROOT_FRAGMENT
- ])
- )
+ PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
+ ),
)
})
})
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap
similarity index 61%
rename from packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap
rename to packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap
index 2770335a5f3..91a82db5bba 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap
@@ -1,103 +1,87 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: hoistStatic transform hoist element with static key 1`] = `
+exports[`compiler: cacheStatic transform > cache element with static key 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", { key: "foo" }, null, -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
return function render(_ctx, _cache) {
with (_ctx) {
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("div", { key: "foo" }, null, -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform hoist nested static tree 1`] = `
+exports[`compiler: cacheStatic transform > cache nested children array 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("p", null, [
- /*#__PURE__*/_createElementVNode("span"),
- /*#__PURE__*/_createElementVNode("span")
-], -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
return function render(_ctx, _cache) {
with (_ctx) {
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("p", null, [
+ _createElementVNode("span"),
+ _createElementVNode("span")
+ ], -1 /* CACHED */),
+ _createElementVNode("p", null, [
+ _createElementVNode("span"),
+ _createElementVNode("span")
+ ], -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform hoist nested static tree with comments 1`] = `
+exports[`compiler: cacheStatic transform > cache nested static tree with comments 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, [
- /*#__PURE__*/_createCommentVNode("comment")
-], -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
return function render(_ctx, _cache) {
with (_ctx) {
const { createCommentVNode: _createCommentVNode, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("div", null, [
+ _createCommentVNode("comment")
+ ], -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform hoist siblings with common non-hoistable parent 1`] = `
+exports[`compiler: cacheStatic transform > cache siblings including text with common non-hoistable parent 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("span", null, null, -1 /* HOISTED */)
-const _hoisted_2 = /*#__PURE__*/_createElementVNode("div", null, null, -1 /* HOISTED */)
-const _hoisted_3 = [
- _hoisted_1,
- _hoisted_2
-]
return function render(_ctx, _cache) {
with (_ctx) {
- const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+ const { createElementVNode: _createElementVNode, createTextVNode: _createTextVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_3))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("span", null, null, -1 /* CACHED */),
+ _createTextVNode("foo", -1 /* CACHED */),
+ _createElementVNode("div", null, null, -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform hoist simple element 1`] = `
+exports[`compiler: cacheStatic transform > cache single children array 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("span", { class: "inline" }, "hello", -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
return function render(_ctx, _cache) {
with (_ctx) {
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("span", { class: "inline" }, "hello", -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform hoist static props for elements with directives 1`] = `
+exports[`compiler: cacheStatic transform > hoist static props for elements with directives 1`] = `
"const _Vue = Vue
const { createElementVNode: _createElementVNode } = _Vue
@@ -118,7 +102,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform hoist static props for elements with dynamic text children 1`] = `
+exports[`compiler: cacheStatic transform > hoist static props for elements with dynamic text children 1`] = `
"const _Vue = Vue
const { createElementVNode: _createElementVNode } = _Vue
@@ -135,7 +119,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform hoist static props for elements with unhoistable children 1`] = `
+exports[`compiler: cacheStatic transform > hoist static props for elements with unhoistable children 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode, createElementVNode: _createElementVNode } = _Vue
@@ -156,69 +140,73 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers hoist class with static object value 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > cache nested static tree with static interpolation 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = {
- class: /*#__PURE__*/_normalizeClass({ foo: true })
-}
return function render(_ctx, _cache) {
with (_ctx) {
- const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+ const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, [
- _createElementVNode("span", _hoisted_1, _toDisplayString(_ctx.bar), 1 /* TEXT */)
- ]))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("span", null, "foo " + _toDisplayString(1) + " " + _toDisplayString(true), -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static tree with static interpolation 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > cache nested static tree with static prop value 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("span", null, "foo " + /*#__PURE__*/_toDisplayString(1) + " " + /*#__PURE__*/_toDisplayString(true), -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("span", { foo: 0 }, _toDisplayString(1), -1 /* CACHED */)
+ ])))
}
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static tree with static prop value 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > clone hoisted array children in v-for + HMR mode 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
-
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("span", { foo: 0 }, /*#__PURE__*/_toDisplayString(1), -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
return function render(_ctx, _cache) {
with (_ctx) {
- const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, [
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(1, (i) => {
+ return (_openBlock(), _createElementBlock("div", null, [...(_cache[0] || (_cache[0] = [
+ _createElementVNode("span", { class: "hi" }, null, -1 /* CACHED */)
+ ]))]))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ ]))
}
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist SVG with directives 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > hoist class with static object value 1`] = `
"const _Vue = Vue
const { createElementVNode: _createElementVNode } = _Vue
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("path", { d: "M2,3H5.5L12" }, null, -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
+const _hoisted_1 = {
+ class: /*@__PURE__*/_normalizeClass({ foo: true })
+}
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(), _createElementBlock("div", null, [
+ _createElementVNode("span", _hoisted_1, _toDisplayString(_ctx.bar), 1 /* TEXT */)
+ ]))
+ }
+}"
+`;
+
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache SVG with directives 1`] = `
+"const _Vue = Vue
return function render(_ctx, _cache) {
with (_ctx) {
@@ -227,7 +215,9 @@ return function render(_ctx, _cache) {
const _directive_foo = _resolveDirective("foo")
return (_openBlock(), _createElementBlock("div", null, [
- _withDirectives((_openBlock(), _createElementBlock("svg", null, _hoisted_2)), [
+ _withDirectives((_openBlock(), _createElementBlock("svg", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("path", { d: "M2,3H5.5L12" }, null, -1 /* CACHED */)
+ ]))), [
[_directive_foo]
])
]))
@@ -235,7 +225,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers + other bindings 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache elements with cached handlers + other bindings 1`] = `
"import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
@@ -250,7 +240,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache elements with cached handlers 1`] = `
"import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
@@ -264,7 +254,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expressions that refer scope variables (2) 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache expressions that refer scope variables (2) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -282,7 +272,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expressions that refer scope variables (v-slot) 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache expressions that refer scope variables (v-slot) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -301,7 +291,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expressions that refer scope variables 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache expressions that refer scope variables 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -319,7 +309,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist keyed template v-for with plain element child 1`] = `
+exports[`compiler: cacheStatic transform > prefixIdentifiers > should NOT cache keyed template v-for with plain element child 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -335,7 +325,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform should NOT hoist components 1`] = `
+exports[`compiler: cacheStatic transform > should NOT cache components 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -351,7 +341,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform should NOT hoist element with dynamic key 1`] = `
+exports[`compiler: cacheStatic transform > should NOT cache element with dynamic key 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -365,7 +355,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform should NOT hoist element with dynamic props (but hoist the props list) 1`] = `
+exports[`compiler: cacheStatic transform > should NOT cache element with dynamic props (but hoist the props list) 1`] = `
"const _Vue = Vue
const { createElementVNode: _createElementVNode } = _Vue
@@ -382,7 +372,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform should NOT hoist element with dynamic ref 1`] = `
+exports[`compiler: cacheStatic transform > should NOT cache element with dynamic ref 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -396,62 +386,72 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: hoistStatic transform should NOT hoist root node 1`] = `
+exports[`compiler: cacheStatic transform > should cache v-if props/children if static 1`] = `
"const _Vue = Vue
+const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
+
+const _hoisted_1 = {
+ key: 0,
+ id: "foo"
+}
return function render(_ctx, _cache) {
with (_ctx) {
- const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+ const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
- return (_openBlock(), _createElementBlock("div"))
+ return (_openBlock(), _createElementBlock("div", null, [
+ ok
+ ? (_openBlock(), _createElementBlock("div", _hoisted_1, _cache[0] || (_cache[0] = [
+ _createElementVNode("span", null, null, -1 /* CACHED */)
+ ])))
+ : _createCommentVNode("v-if", true)
+ ]))
}
}"
`;
-exports[`compiler: hoistStatic transform should hoist v-for children if static 1`] = `
+exports[`compiler: cacheStatic transform > should hoist props for root with single element excluding comments 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode } = _Vue
+const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
-const _hoisted_1 = { id: "foo" }
-const _hoisted_2 = /*#__PURE__*/_createElementVNode("span", null, null, -1 /* HOISTED */)
-const _hoisted_3 = [
- _hoisted_2
-]
+const _hoisted_1 = { id: "a" }
return function render(_ctx, _cache) {
with (_ctx) {
- const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
-
- return (_openBlock(), _createElementBlock("div", null, [
- (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => {
- return (_openBlock(), _createElementBlock("div", _hoisted_1, _hoisted_3))
- }), 256 /* UNKEYED_FRAGMENT */))
- ]))
+ const { createCommentVNode: _createCommentVNode, createElementVNode: _createElementVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(), _createElementBlock(_Fragment, null, [
+ _createCommentVNode("comment"),
+ _createElementVNode("div", _hoisted_1, _cache[0] || (_cache[0] = [
+ _createElementVNode("div", { id: "b" }, [
+ _createElementVNode("div", { id: "c" }, [
+ _createElementVNode("div", { id: "d" }, [
+ _createElementVNode("div", { id: "e" }, "hello")
+ ])
+ ])
+ ], -1 /* CACHED */)
+ ]))
+ ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
}
}"
`;
-exports[`compiler: hoistStatic transform should hoist v-if props/children if static 1`] = `
+exports[`compiler: cacheStatic transform > should hoist v-for children if static 1`] = `
"const _Vue = Vue
-const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
+const { createElementVNode: _createElementVNode } = _Vue
-const _hoisted_1 = {
- key: 0,
- id: "foo"
-}
-const _hoisted_2 = /*#__PURE__*/_createElementVNode("span", null, null, -1 /* HOISTED */)
-const _hoisted_3 = [
- _hoisted_2
-]
+const _hoisted_1 = { id: "foo" }
return function render(_ctx, _cache) {
with (_ctx) {
- const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(), _createElementBlock("div", null, [
- ok
- ? (_openBlock(), _createElementBlock("div", _hoisted_1, _hoisted_3))
- : _createCommentVNode("v-if", true)
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => {
+ return (_openBlock(), _createElementBlock("div", _hoisted_1, _cache[0] || (_cache[0] = [
+ _createElementVNode("span", null, null, -1 /* CACHED */)
+ ])))
+ }), 256 /* UNKEYED_FRAGMENT */))
]))
}
}"
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
new file mode 100644
index 00000000000..3da778eb675
--- /dev/null
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
@@ -0,0 +1,228 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`compiler: v-for > codegen > basic v-for 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return (_openBlock(), _createElementBlock("span"))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > keyed template v-for 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return (_openBlock(), _createElementBlock(_Fragment, { key: item }, [
+ "hello",
+ _createElementVNode("span")
+ ], 64 /* STABLE_FRAGMENT */))
+ }), 128 /* KEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > keyed v-for 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return (_openBlock(), _createElementBlock("span", { key: item }))
+ }), 128 /* KEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > skipped key 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item, __, index) => {
+ return (_openBlock(), _createElementBlock("span"))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > skipped value & key 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (_, __, index) => {
+ return (_openBlock(), _createElementBlock("span"))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > skipped value 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (_, key, index) => {
+ return (_openBlock(), _createElementBlock("span"))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > template v-for 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return (_openBlock(), _createElementBlock(_Fragment, null, [
+ "hello",
+ _createElementVNode("span")
+ ], 64 /* STABLE_FRAGMENT */))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > template v-for key injection with single child 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return (_openBlock(), _createElementBlock("span", {
+ key: item.id,
+ id: item.id
+ }, null, 8 /* PROPS */, ["id"]))
+ }), 128 /* KEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > template v-for w/ 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, renderSlot: _renderSlot } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return _renderSlot($slots, "default")
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > v-for on 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, renderSlot: _renderSlot } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
+ return _renderSlot($slots, "default")
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > v-for on element with custom directive 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, resolveDirective: _resolveDirective, withDirectives: _withDirectives } = _Vue
+
+ const _directive_foo = _resolveDirective("foo")
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => {
+ return _withDirectives((_openBlock(), _createElementBlock("div", null, null, 512 /* NEED_PATCH */)), [
+ [_directive_foo]
+ ])
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > v-for with constant expression 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, toDisplayString: _toDisplayString, createElementVNode: _createElementVNode } = _Vue
+
+ return (_openBlock(), _createElementBlock(_Fragment, null, _renderList(10, (item) => {
+ return _createElementVNode("p", null, _toDisplayString(item), 1 /* TEXT */)
+ }), 64 /* STABLE_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > v-if + v-for 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
+
+ return ok
+ ? (_openBlock(true), _createElementBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
+ return (_openBlock(), _createElementBlock("div"))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ : _createCommentVNode("v-if", true)
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > v-if + v-for on 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
+
+ return ok
+ ? (_openBlock(true), _createElementBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
+ return (_openBlock(), _createElementBlock(_Fragment, null, [], 64 /* STABLE_FRAGMENT */))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ : _createCommentVNode("v-if", true)
+ }
+}"
+`;
+
+exports[`compiler: v-for > codegen > value + key + index 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
+
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item, key, index) => {
+ return (_openBlock(), _createElementBlock("span"))
+ }), 256 /* UNKEYED_FRAGMENT */))
+ }
+}"
+`;
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap
index aa8a6e2e20e..5a94de5a68b 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap
@@ -1,15 +1,105 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: expression transform bindingMetadata inline mode 1`] = `
+exports[`compiler: expression transform > bindingMetadata > inline mode 1`] = `
"(_ctx, _cache) => {
- return (_openBlock(), _createElementBlock("div", null, _toDisplayString(__props.props) + " " + _toDisplayString(_unref(setup)) + " " + _toDisplayString(setupConst) + " " + _toDisplayString(_ctx.data) + " " + _toDisplayString(_ctx.options), 1 /* TEXT */))
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(__props.props) + " " + _toDisplayString(_unref(setup)) + " " + _toDisplayString(setupConst) + " " + _toDisplayString(_ctx.data) + " " + _toDisplayString(_ctx.options) + " " + _toDisplayString(isNaN.value), 1 /* TEXT */))
}"
`;
-exports[`compiler: expression transform bindingMetadata non-inline mode 1`] = `
+exports[`compiler: expression transform > bindingMetadata > non-inline mode 1`] = `
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache, $props, $setup, $data, $options) {
- return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props.props) + " " + _toDisplayString($setup.setup) + " " + _toDisplayString($data.data) + " " + _toDisplayString($options.options), 1 /* TEXT */))
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props.props) + " " + _toDisplayString($setup.setup) + " " + _toDisplayString($data.data) + " " + _toDisplayString($options.options) + " " + _toDisplayString($setup.isNaN), 1 /* TEXT */))
+}"
+`;
+
+exports[`compiler: expression transform > should allow leak of var declarations in for loop 1`] = `
+"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: () => {
+ for (var i = 0; i < _ctx.list.length; i++) {
+ _ctx.log(i)
+ }
+ _ctx.error(i)
+ }
+ }, null, 8 /* PROPS */, ["onClick"]))
+}"
+`;
+
+exports[`compiler: expression transform > should not prefix catch block param 1`] = `
+"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: () => {
+ try {} catch (err) { console.error(err) }
+ console.log(_ctx.err)
+ }
+ }, null, 8 /* PROPS */, ["onClick"]))
+}"
+`;
+
+exports[`compiler: expression transform > should not prefix destructured catch block param 1`] = `
+"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: () => {
+ try {
+ throw new Error('sup?')
+ } catch ({ message: { length } }) {
+ console.error(length)
+ }
+ console.log(_ctx.length)
+ }
+ }, null, 8 /* PROPS */, ["onClick"]))
+}"
+`;
+
+exports[`compiler: expression transform > should not prefix temp variable of for loop 1`] = `
+"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: () => {
+ for (let i = 0; i < _ctx.list.length; i++) {
+ _ctx.log(i)
+ }
+ _ctx.error(_ctx.i)
+ }
+ }, null, 8 /* PROPS */, ["onClick"]))
+}"
+`;
+
+exports[`compiler: expression transform > should not prefix temp variable of for...in 1`] = `
+"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: () => {
+ for (const x in _ctx.list) {
+ _ctx.log(x)
+ }
+ _ctx.error(_ctx.x)
+ }
+ }, null, 8 /* PROPS */, ["onClick"]))
+}"
+`;
+
+exports[`compiler: expression transform > should not prefix temp variable of for...of 1`] = `
+"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: () => {
+ for (const x of _ctx.list) {
+ _ctx.log(x)
+ }
+ _ctx.error(_ctx.x)
+ }
+ }, null, 8 /* PROPS */, ["onClick"]))
}"
`;
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap
index 945d19609cb..7fb49ea7887 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: transform text 1`] = `
+exports[`compiler: transform text > 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -16,7 +16,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text consecutive text 1`] = `
+exports[`compiler: transform text > consecutive text 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -28,7 +28,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text consecutive text between elements 1`] = `
+exports[`compiler: transform text > consecutive text between elements 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -44,7 +44,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text consecutive text mixed with elements 1`] = `
+exports[`compiler: transform text > consecutive text mixed with elements 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -62,7 +62,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text element with custom directives and only one text child node 1`] = `
+exports[`compiler: transform text > element with custom directives and only one text child node 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -80,7 +80,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text no consecutive text 1`] = `
+exports[`compiler: transform text > no consecutive text 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -92,7 +92,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text text between elements (static) 1`] = `
+exports[`compiler: transform text > text between elements (static) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -108,7 +108,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform text with prefixIdentifiers: true 1`] = `
+exports[`compiler: transform text > with prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString } = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap
index 2d8498703e5..3da778eb675 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: v-for codegen basic v-for 1`] = `
+exports[`compiler: v-for > codegen > basic v-for 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -14,7 +14,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen keyed template v-for 1`] = `
+exports[`compiler: v-for > codegen > keyed template v-for 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -31,7 +31,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen keyed v-for 1`] = `
+exports[`compiler: v-for > codegen > keyed v-for 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -45,7 +45,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen skipped key 1`] = `
+exports[`compiler: v-for > codegen > skipped key 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -59,7 +59,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen skipped value & key 1`] = `
+exports[`compiler: v-for > codegen > skipped value & key 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -73,7 +73,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen skipped value 1`] = `
+exports[`compiler: v-for > codegen > skipped value 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -87,7 +87,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen template v-for 1`] = `
+exports[`compiler: v-for > codegen > template v-for 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -104,7 +104,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen template v-for key injection with single child 1`] = `
+exports[`compiler: v-for > codegen > template v-for key injection with single child 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -121,7 +121,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen template v-for w/ 1`] = `
+exports[`compiler: v-for > codegen > template v-for w/ 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -135,7 +135,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen v-for on 1`] = `
+exports[`compiler: v-for > codegen > v-for on 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -149,7 +149,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen v-for on element with custom directive 1`] = `
+exports[`compiler: v-for > codegen > v-for on element with custom directive 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -167,7 +167,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen v-for with constant expression 1`] = `
+exports[`compiler: v-for > codegen > v-for with constant expression 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -181,7 +181,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen v-if + v-for 1`] = `
+exports[`compiler: v-for > codegen > v-if + v-for 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -197,7 +197,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen v-if + v-for on 1`] = `
+exports[`compiler: v-for > codegen > v-if + v-for on 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -213,7 +213,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-for codegen value + key + index 1`] = `
+exports[`compiler: v-for > codegen > value + key + index 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap
index b36e21f7c37..65ee73c46f4 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: v-if codegen basic v-if 1`] = `
+exports[`compiler: v-if > codegen > basic v-if 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -14,7 +14,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen increasing key: v-if + v-else-if + v-else 1`] = `
+exports[`compiler: v-if > codegen > increasing key: v-if + v-else-if + v-else 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -35,7 +35,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen multiple v-if that are sibling nodes should have different keys 1`] = `
+exports[`compiler: v-if > codegen > multiple v-if that are sibling nodes should have different keys 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -54,7 +54,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen template v-if 1`] = `
+exports[`compiler: v-if > codegen > template v-if 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -72,7 +72,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen template v-if w/ single child 1`] = `
+exports[`compiler: v-if > codegen > template v-if w/ single child 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -86,7 +86,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen v-if + v-else 1`] = `
+exports[`compiler: v-if > codegen > v-if + v-else 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -100,7 +100,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen v-if + v-else-if + v-else 1`] = `
+exports[`compiler: v-if > codegen > v-if + v-else-if + v-else 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -116,7 +116,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen v-if + v-else-if 1`] = `
+exports[`compiler: v-if > codegen > v-if + v-else-if 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -132,7 +132,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-if codegen v-if on 1`] = `
+exports[`compiler: v-if > codegen > v-if on 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap
index 35e2aa66a72..86e0b3d2fd5 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap
@@ -1,6 +1,24 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: v-memo transform on component 1`] = `
+exports[`compiler: v-memo transform > element v-for key expression prefixing + v-memo 1`] = `
+"import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, isMemoSame as _isMemoSame, withMemo as _withMemo } from "vue"
+
+export function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, [
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.tableData, (data, __, ___, _cached) => {
+ const _memo = (_ctx.getLetter(data))
+ if (_cached && _cached.key === _ctx.getId(data) && _isMemoSame(_cached, _memo)) return _cached
+ const _item = (_openBlock(), _createElementBlock("span", {
+ key: _ctx.getId(data)
+ }))
+ _item.memo = _memo
+ return _item
+ }, _cache, 0), 128 /* KEYED_FRAGMENT */))
+ ]))
+}"
+`;
+
+exports[`compiler: v-memo transform > on component 1`] = `
"import { resolveComponent as _resolveComponent, createVNode as _createVNode, withMemo as _withMemo, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
@@ -12,7 +30,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-memo transform on normal element 1`] = `
+exports[`compiler: v-memo transform > on normal element 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock, withMemo as _withMemo } from "vue"
export function render(_ctx, _cache) {
@@ -22,7 +40,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-memo transform on root element 1`] = `
+exports[`compiler: v-memo transform > on root element 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock, withMemo as _withMemo } from "vue"
export function render(_ctx, _cache) {
@@ -30,7 +48,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-memo transform on template v-for 1`] = `
+exports[`compiler: v-memo transform > on template v-for 1`] = `
"import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, isMemoSame as _isMemoSame, withMemo as _withMemo } from "vue"
export function render(_ctx, _cache) {
@@ -46,7 +64,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-memo transform on v-for 1`] = `
+exports[`compiler: v-memo transform > on v-for 1`] = `
"import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, createElementVNode as _createElementVNode, isMemoSame as _isMemoSame, withMemo as _withMemo } from "vue"
export function render(_ctx, _cache) {
@@ -64,7 +82,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-memo transform on v-if 1`] = `
+exports[`compiler: v-memo transform > on v-if 1`] = `
"import { createElementVNode as _createElementVNode, createTextVNode as _createTextVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, withMemo as _withMemo, createCommentVNode as _createCommentVNode, resolveComponent as _resolveComponent, createBlock as _createBlock } from "vue"
export function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
index d4e9c6b2e16..17c4e80b160 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = `
+exports[`compiler: transform v-model > compound expression (with prefixIdentifiers) 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
@@ -11,7 +11,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model compound expression 1`] = `
+exports[`compiler: transform v-model > compound expression 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -26,7 +26,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression (with multilines) 1`] = `
+exports[`compiler: transform v-model > simple expression (with multilines) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -49,7 +49,7 @@ foo
}"
`;
-exports[`compiler: transform v-model simple expression (with prefixIdentifiers) 1`] = `
+exports[`compiler: transform v-model > simple expression (with prefixIdentifiers) 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
@@ -60,7 +60,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression 1`] = `
+exports[`compiler: transform v-model > simple expression 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -75,7 +75,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model with argument 1`] = `
+exports[`compiler: transform v-model > with argument 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -85,12 +85,12 @@ return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("input", {
"foo-value": model,
"onUpdate:fooValue": $event => ((model) = $event)
- }, null, 40 /* PROPS, HYDRATE_EVENTS */, ["foo-value", "onUpdate:fooValue"]))
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["foo-value", "onUpdate:fooValue"]))
}
}"
`;
-exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = `
+exports[`compiler: transform v-model > with dynamic argument (with prefixIdentifiers) 1`] = `
"import { normalizeProps as _normalizeProps, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
@@ -101,7 +101,7 @@ export function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model with dynamic argument 1`] = `
+exports[`compiler: transform v-model > with dynamic argument 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap
index 972acfb479a..6660865a523 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: v-once transform as root node 1`] = `
+exports[`compiler: v-once transform > as root node 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -8,8 +8,8 @@ return function render(_ctx, _cache) {
const { setBlockTracking: _setBlockTracking, createElementVNode: _createElementVNode } = _Vue
return _cache[0] || (
- _setBlockTracking(-1),
- _cache[0] = _createElementVNode("div", { id: foo }, null, 8 /* PROPS */, ["id"]),
+ _setBlockTracking(-1, true),
+ (_cache[0] = _createElementVNode("div", { id: foo }, null, 8 /* PROPS */, ["id"])).cacheIndex = 0,
_setBlockTracking(1),
_cache[0]
)
@@ -17,7 +17,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-once transform on component 1`] = `
+exports[`compiler: v-once transform > on component 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -28,8 +28,8 @@ return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, [
_cache[0] || (
- _setBlockTracking(-1),
- _cache[0] = _createVNode(_component_Comp, { id: foo }, null, 8 /* PROPS */, ["id"]),
+ _setBlockTracking(-1, true),
+ (_cache[0] = _createVNode(_component_Comp, { id: foo }, null, 8 /* PROPS */, ["id"])).cacheIndex = 0,
_setBlockTracking(1),
_cache[0]
)
@@ -38,7 +38,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-once transform on nested plain element 1`] = `
+exports[`compiler: v-once transform > on nested plain element 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -47,8 +47,8 @@ return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, [
_cache[0] || (
- _setBlockTracking(-1),
- _cache[0] = _createElementVNode("div", { id: foo }, null, 8 /* PROPS */, ["id"]),
+ _setBlockTracking(-1, true),
+ (_cache[0] = _createElementVNode("div", { id: foo }, null, 8 /* PROPS */, ["id"])).cacheIndex = 0,
_setBlockTracking(1),
_cache[0]
)
@@ -57,7 +57,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-once transform on slot outlet 1`] = `
+exports[`compiler: v-once transform > on slot outlet 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -66,8 +66,8 @@ return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, [
_cache[0] || (
- _setBlockTracking(-1),
- _cache[0] = _renderSlot($slots, "default"),
+ _setBlockTracking(-1, true),
+ (_cache[0] = _renderSlot($slots, "default")).cacheIndex = 0,
_setBlockTracking(1),
_cache[0]
)
@@ -76,7 +76,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: v-once transform with hoistStatic: true 1`] = `
+exports[`compiler: v-once transform > with hoistStatic: true 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -85,8 +85,8 @@ return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, [
_cache[0] || (
- _setBlockTracking(-1),
- _cache[0] = _createElementVNode("div"),
+ _setBlockTracking(-1, true),
+ (_cache[0] = _createElementVNode("div")).cacheIndex = 0,
_setBlockTracking(1),
_cache[0]
)
diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
index c17d1d0e52e..2cd13bab036 100644
--- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
+++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: transform component slots dynamically named slots 1`] = `
+exports[`compiler: transform component slots > dynamically named slots 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -14,7 +14,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots implicit default slot 1`] = `
+exports[`compiler: transform component slots > implicit default slot 1`] = `
"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -29,7 +29,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = `
+exports[`compiler: transform component slots > named slot with v-for w/ prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -46,7 +46,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = `
+exports[`compiler: transform component slots > named slot with v-if + prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -64,7 +64,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots named slot with v-if + v-else-if + v-else 1`] = `
+exports[`compiler: transform component slots > named slot with v-if + v-else-if + v-else 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -96,7 +96,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots named slot with v-if 1`] = `
+exports[`compiler: transform component slots > named slot with v-if 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -118,7 +118,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots named slots w/ implicit default slot 1`] = `
+exports[`compiler: transform component slots > named slots w/ implicit default slot 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -139,7 +139,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots nested slots scoping 1`] = `
+exports[`compiler: transform component slots > nested slots scoping 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -162,7 +162,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots on component dynamically named slot 1`] = `
+exports[`compiler: transform component slots > on component dynamically named slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -175,7 +175,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots on component named slot 1`] = `
+exports[`compiler: transform component slots > on component named slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -188,7 +188,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots on-component default slot 1`] = `
+exports[`compiler: transform component slots > on-component default slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -201,7 +201,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots template named slots 1`] = `
+exports[`compiler: transform component slots > template named slots 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -215,7 +215,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots with whitespace: 'preserve' implicit default slot 1`] = `
+exports[`compiler: transform component slots > with whitespace: 'preserve' > implicit default slot 1`] = `
"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -232,7 +232,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots with whitespace: 'preserve' named default slot + implicit whitespace content 1`] = `
+exports[`compiler: transform component slots > with whitespace: 'preserve' > named default slot + implicit whitespace content 1`] = `
"const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
@@ -246,7 +246,29 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform component slots with whitespace: 'preserve' should not generate whitespace only default slot 1`] = `
+exports[`compiler: transform component slots > with whitespace: 'preserve' > named slot with v-if + v-else 1`] = `
+"const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue
+
+return function render(_ctx, _cache) {
+ const _component_Comp = _resolveComponent("Comp")
+
+ return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [
+ ok
+ ? {
+ name: "one",
+ fn: _withCtx(() => ["foo"]),
+ key: "0"
+ }
+ : {
+ name: "two",
+ fn: _withCtx(() => ["baz"]),
+ key: "1"
+ }
+ ]), 1024 /* DYNAMIC_SLOTS */))
+}"
+`;
+
+exports[`compiler: transform component slots > with whitespace: 'preserve' > should not generate whitespace only default slot 1`] = `
"const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
new file mode 100644
index 00000000000..74f6caca328
--- /dev/null
+++ b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
@@ -0,0 +1,803 @@
+import {
+ type CompilerOptions,
+ ConstantTypes,
+ type ElementNode,
+ type ForNode,
+ type IfNode,
+ NodeTypes,
+ type VNodeCall,
+ generate,
+ baseParse as parse,
+ transform,
+} from '../../src'
+import {
+ FRAGMENT,
+ NORMALIZE_CLASS,
+ RENDER_LIST,
+} from '../../src/runtimeHelpers'
+import { transformElement } from '../../src/transforms/transformElement'
+import { transformExpression } from '../../src/transforms/transformExpression'
+import { transformIf } from '../../src/transforms/vIf'
+import { transformFor } from '../../src/transforms/vFor'
+import { transformBind } from '../../src/transforms/vBind'
+import { transformOn } from '../../src/transforms/vOn'
+import { createObjectMatcher } from '../testUtils'
+import { transformText } from '../../src/transforms/transformText'
+import { PatchFlags } from '@vue/shared'
+
+const cachedChildrenArrayMatcher = (
+ tags: string[],
+ needArraySpread = false,
+) => ({
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ needArraySpread,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: tags.map(tag => {
+ if (tag === '') {
+ return {
+ type: NodeTypes.TEXT_CALL,
+ }
+ } else {
+ return {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: JSON.stringify(tag),
+ },
+ }
+ }
+ }),
+ },
+})
+
+function transformWithCache(template: string, options: CompilerOptions = {}) {
+ const ast = parse(template)
+ transform(ast, {
+ hoistStatic: true,
+ nodeTransforms: [
+ transformIf,
+ transformFor,
+ ...(options.prefixIdentifiers ? [transformExpression] : []),
+ transformElement,
+ transformText,
+ ],
+ directiveTransforms: {
+ on: transformOn,
+ bind: transformBind,
+ },
+ ...options,
+ })
+ expect(ast.codegenNode).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ isBlock: true,
+ })
+ return ast
+}
+
+describe('compiler: cacheStatic transform', () => {
+ test('should NOT cache root node', () => {
+ // if the whole tree is static, the root still needs to be a block
+ // so that it's patched in optimized mode to skip children
+ const root = transformWithCache(`
`)
+ expect(root.codegenNode).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ })
+ expect(root.cached.length).toBe(0)
+ })
+
+ test('cache root node children', () => {
+ // we don't have access to the root codegenNode during the transform
+ // so we only cache each child individually
+ const root = transformWithCache(
+ `hello hello `,
+ )
+ expect(root.codegenNode).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ children: [
+ { codegenNode: { type: NodeTypes.JS_CACHE_EXPRESSION } },
+ { codegenNode: { type: NodeTypes.JS_CACHE_EXPRESSION } },
+ ],
+ })
+ expect(root.cached.length).toBe(2)
+ })
+
+ test('cache single children array', () => {
+ const root = transformWithCache(
+ `hello
`,
+ )
+ expect(root.codegenNode).toMatchObject({
+ tag: `"div"`,
+ props: undefined,
+ children: cachedChildrenArrayMatcher(['span']),
+ })
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('cache nested children array', () => {
+ const root = transformWithCache(
+ ``,
+ )
+ expect((root.codegenNode as VNodeCall).children).toMatchObject(
+ cachedChildrenArrayMatcher(['p', 'p']),
+ )
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('cache nested static tree with comments', () => {
+ const root = transformWithCache(``)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject(
+ cachedChildrenArrayMatcher(['div']),
+ )
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('cache siblings including text with common non-hoistable parent', () => {
+ const root = transformWithCache(``)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject(
+ cachedChildrenArrayMatcher(['span', '', 'div']),
+ )
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('cache inside default slot', () => {
+ const root = transformWithCache(`{{x}} `)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject({
+ properties: [
+ {
+ key: { content: 'default' },
+ value: {
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
+ returns: [
+ {
+ type: NodeTypes.TEXT_CALL,
+ },
+ // first slot child cached
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ },
+ },
+ ],
+ },
+ },
+ {
+ /* _ slot flag */
+ },
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: { content: '__' },
+ value: { content: '[0]' },
+ },
+ ],
+ })
+ })
+
+ test('cache default slot as a whole', () => {
+ const root = transformWithCache(` `)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject({
+ properties: [
+ {
+ key: { content: 'default' },
+ value: {
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
+ returns: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ { type: NodeTypes.ELEMENT },
+ { type: NodeTypes.ELEMENT },
+ ],
+ },
+ },
+ },
+ },
+ {
+ /* _ slot flag */
+ },
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: { content: '__' },
+ value: { content: '[0]' },
+ },
+ ],
+ })
+ })
+
+ test('cache inside named slot', () => {
+ const root = transformWithCache(
+ `{{x}} `,
+ )
+ expect((root.codegenNode as VNodeCall).children).toMatchObject({
+ properties: [
+ {
+ key: { content: 'foo' },
+ value: {
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
+ returns: [
+ {
+ type: NodeTypes.TEXT_CALL,
+ },
+ // first slot child cached
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ },
+ },
+ ],
+ },
+ },
+ {
+ /* _ slot flag */
+ },
+ ],
+ })
+ })
+
+ test('cache named slot as a whole', () => {
+ const root = transformWithCache(
+ ` `,
+ )
+ expect((root.codegenNode as VNodeCall).children).toMatchObject({
+ properties: [
+ {
+ key: { content: 'foo' },
+ value: {
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
+ returns: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ { type: NodeTypes.ELEMENT },
+ { type: NodeTypes.ELEMENT },
+ ],
+ },
+ },
+ },
+ },
+ {
+ /* _ slot flag */
+ },
+ ],
+ })
+ })
+
+ test('cache dynamically named slot as a whole', () => {
+ const root = transformWithCache(
+ ` `,
+ )
+ expect((root.codegenNode as VNodeCall).children).toMatchObject({
+ properties: [
+ {
+ key: { content: 'foo', isStatic: false },
+ value: {
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
+ returns: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ { type: NodeTypes.ELEMENT },
+ { type: NodeTypes.ELEMENT },
+ ],
+ },
+ },
+ },
+ },
+ {
+ /* _ slot flag */
+ },
+ ],
+ })
+ })
+
+ test('cache dynamically named (expression) slot as a whole', () => {
+ const root = transformWithCache(
+ ` `,
+ { prefixIdentifiers: true },
+ )
+ expect((root.codegenNode as VNodeCall).children).toMatchObject({
+ properties: [
+ {
+ key: { type: NodeTypes.COMPOUND_EXPRESSION },
+ value: {
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
+ returns: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ { type: NodeTypes.ELEMENT },
+ { type: NodeTypes.ELEMENT },
+ ],
+ },
+ },
+ },
+ },
+ {
+ /* _ slot flag */
+ },
+ ],
+ })
+ })
+
+ test('should NOT cache components', () => {
+ const root = transformWithCache(`
`)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `_component_Comp`,
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache element with dynamic props (but hoist the props list)', () => {
+ const root = transformWithCache(``)
+ expect(root.hoists.length).toBe(1)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: createObjectMatcher({
+ id: `[foo]`,
+ }),
+ children: undefined,
+ patchFlag: PatchFlags.PROPS,
+ dynamicProps: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `_hoisted_1`,
+ isStatic: false,
+ },
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('cache element with static key', () => {
+ const root = transformWithCache(``)
+ expect(root.codegenNode).toMatchObject({
+ tag: `"div"`,
+ props: undefined,
+ children: cachedChildrenArrayMatcher(['div']),
+ })
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache element with dynamic key', () => {
+ const root = transformWithCache(``)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: createObjectMatcher({
+ key: `[foo]`,
+ }),
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache element with dynamic ref', () => {
+ const root = transformWithCache(``)
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: createObjectMatcher({
+ ref: `[foo]`,
+ }),
+ children: undefined,
+ patchFlag: PatchFlags.NEED_PATCH,
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('hoist static props for elements with directives', () => {
+ const root = transformWithCache(``)
+ expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `_hoisted_1`,
+ },
+ children: undefined,
+ patchFlag: PatchFlags.NEED_PATCH,
+ directives: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ },
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('hoist static props for elements with dynamic text children', () => {
+ const root = transformWithCache(
+ ``,
+ )
+ expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: { content: `_hoisted_1` },
+ children: { type: NodeTypes.INTERPOLATION },
+ patchFlag: PatchFlags.TEXT,
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('hoist static props for elements with unhoistable children', () => {
+ const root = transformWithCache(``)
+ expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: { content: `_hoisted_1` },
+ children: [{ type: NodeTypes.ELEMENT, tag: `Comp` }],
+ },
+ },
+ ])
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should cache v-if props/children if static', () => {
+ const root = transformWithCache(
+ ``,
+ )
+ expect(root.hoists).toMatchObject([
+ createObjectMatcher({
+ key: `[0]`, // key injected by v-if branch
+ id: 'foo',
+ }),
+ ])
+ expect(
+ ((root.children[0] as ElementNode).children[0] as IfNode).codegenNode,
+ ).toMatchObject({
+ type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
+ consequent: {
+ // blocks should NOT be cached
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: { content: `_hoisted_1` },
+ children: cachedChildrenArrayMatcher(['span']),
+ },
+ })
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should hoist v-for children if static', () => {
+ const root = transformWithCache(
+ ``,
+ )
+ expect(root.hoists).toMatchObject([
+ createObjectMatcher({
+ id: 'foo',
+ }),
+ ])
+ const forBlockCodegen = (
+ (root.children[0] as ElementNode).children[0] as ForNode
+ ).codegenNode
+ expect(forBlockCodegen).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: FRAGMENT,
+ props: undefined,
+ children: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: RENDER_LIST,
+ },
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
+ })
+ const innerBlockCodegen = forBlockCodegen!.children.arguments[1]
+ expect(innerBlockCodegen.returns).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: { content: `_hoisted_1` },
+ children: cachedChildrenArrayMatcher(['span']),
+ })
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should hoist props for root with single element excluding comments', () => {
+ // deeply nested div to trigger stringification condition
+ const root = transformWithCache(
+ ``,
+ )
+ expect(root.cached.length).toBe(1)
+ expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'a' })])
+
+ expect((root.codegenNode as VNodeCall).children).toMatchObject([
+ {
+ type: NodeTypes.COMMENT,
+ content: 'comment',
+ },
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: { content: `_hoisted_1` },
+ children: { type: NodeTypes.JS_CACHE_EXPRESSION },
+ },
+ },
+ ])
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ describe('prefixIdentifiers', () => {
+ test('cache nested static tree with static interpolation', () => {
+ const root = transformWithCache(
+ `foo {{ 1 }} {{ true }}
`,
+ {
+ prefixIdentifiers: true,
+ },
+ )
+ expect(root.codegenNode).toMatchObject({
+ tag: `"div"`,
+ props: undefined,
+ children: cachedChildrenArrayMatcher(['span']),
+ })
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('cache nested static tree with static prop value', () => {
+ const root = transformWithCache(
+ `{{ 1 }}
`,
+ {
+ prefixIdentifiers: true,
+ },
+ )
+ expect(root.codegenNode).toMatchObject({
+ tag: `"div"`,
+ props: undefined,
+ children: cachedChildrenArrayMatcher(['span']),
+ })
+ expect(root.cached.length).toBe(1)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('hoist class with static object value', () => {
+ const root = transformWithCache(
+ `{{ bar }}
`,
+ {
+ prefixIdentifiers: true,
+ },
+ )
+
+ expect(root.hoists).toMatchObject([
+ {
+ type: NodeTypes.JS_OBJECT_EXPRESSION,
+ properties: [
+ {
+ key: {
+ content: `class`,
+ isStatic: true,
+ constType: ConstantTypes.CAN_STRINGIFY,
+ },
+ value: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: NORMALIZE_CLASS,
+ arguments: [
+ {
+ content: `{ foo: true }`,
+ isStatic: false,
+ constType: ConstantTypes.CAN_STRINGIFY,
+ },
+ ],
+ },
+ },
+ ],
+ },
+ ])
+ expect(root.codegenNode).toMatchObject({
+ tag: `"div"`,
+ props: undefined,
+ children: [
+ {
+ type: NodeTypes.ELEMENT,
+ codegenNode: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"span"`,
+ props: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `_hoisted_1`,
+ },
+ children: {
+ type: NodeTypes.INTERPOLATION,
+ content: {
+ content: `_ctx.bar`,
+ isStatic: false,
+ constType: ConstantTypes.NOT_CONSTANT,
+ },
+ },
+ patchFlag: PatchFlags.TEXT,
+ },
+ },
+ ],
+ })
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache expressions that refer scope variables', () => {
+ const root = transformWithCache(
+ ``,
+ {
+ prefixIdentifiers: true,
+ },
+ )
+
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache expressions that refer scope variables (2)', () => {
+ const root = transformWithCache(
+ ``,
+ {
+ prefixIdentifiers: true,
+ },
+ )
+
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache expressions that refer scope variables (v-slot)', () => {
+ const root = transformWithCache(
+ `{{ foo }} `,
+ {
+ prefixIdentifiers: true,
+ },
+ )
+
+ expect(root.cached.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache elements with cached handlers', () => {
+ const root = transformWithCache(
+ ``,
+ {
+ prefixIdentifiers: true,
+ cacheHandlers: true,
+ },
+ )
+
+ expect(root.cached.length).toBe(1)
+ expect(root.hoists.length).toBe(0)
+ expect(
+ generate(root, {
+ mode: 'module',
+ prefixIdentifiers: true,
+ }).code,
+ ).toMatchSnapshot()
+ })
+
+ test('should NOT cache elements with cached handlers + other bindings', () => {
+ const root = transformWithCache(
+ ``,
+ {
+ prefixIdentifiers: true,
+ cacheHandlers: true,
+ },
+ )
+
+ expect(root.cached.length).toBe(1)
+ expect(root.hoists.length).toBe(0)
+ expect(
+ generate(root, {
+ mode: 'module',
+ prefixIdentifiers: true,
+ }).code,
+ ).toMatchSnapshot()
+ })
+
+ test('should NOT cache keyed template v-for with plain element child', () => {
+ const root = transformWithCache(
+ `
`,
+ )
+ expect(root.hoists.length).toBe(0)
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('should NOT cache SVG with directives', () => {
+ const root = transformWithCache(
+ ``,
+ )
+ expect(root.cached.length).toBe(1)
+ expect(root.codegenNode).toMatchObject({
+ children: [
+ {
+ tag: 'svg',
+ // only cache the children, not the svg tag itself
+ codegenNode: {
+ children: {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ },
+ },
+ },
+ ],
+ })
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('clone hoisted array children in v-for + HMR mode', () => {
+ const root = transformWithCache(
+ ``,
+ {
+ hmr: true,
+ },
+ )
+ expect(root.cached.length).toBe(1)
+ const forBlockCodegen = (
+ (root.children[0] as ElementNode).children[0] as ForNode
+ ).codegenNode
+ expect(forBlockCodegen).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: FRAGMENT,
+ props: undefined,
+ children: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: RENDER_LIST,
+ },
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
+ })
+ const innerBlockCodegen = forBlockCodegen!.children.arguments[1]
+ expect(innerBlockCodegen.returns).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ children: cachedChildrenArrayMatcher(
+ ['span'],
+ true /* needArraySpread */,
+ ),
+ })
+ expect(generate(root).code).toMatchSnapshot()
+ })
+ })
+})
diff --git a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
deleted file mode 100644
index eec5a76d363..00000000000
--- a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
+++ /dev/null
@@ -1,597 +0,0 @@
-import {
- baseParse as parse,
- transform,
- NodeTypes,
- generate,
- CompilerOptions,
- VNodeCall,
- IfNode,
- ElementNode,
- ForNode,
- ConstantTypes
-} from '../../src'
-import {
- FRAGMENT,
- RENDER_LIST,
- NORMALIZE_CLASS
-} from '../../src/runtimeHelpers'
-import { transformElement } from '../../src/transforms/transformElement'
-import { transformExpression } from '../../src/transforms/transformExpression'
-import { transformIf } from '../../src/transforms/vIf'
-import { transformFor } from '../../src/transforms/vFor'
-import { transformBind } from '../../src/transforms/vBind'
-import { transformOn } from '../../src/transforms/vOn'
-import { createObjectMatcher, genFlagText } from '../testUtils'
-import { transformText } from '../../src/transforms/transformText'
-import { PatchFlags } from '@vue/shared'
-
-const hoistedChildrenArrayMatcher = (startIndex = 1, length = 1) => ({
- type: NodeTypes.JS_ARRAY_EXPRESSION,
- elements: new Array(length).fill(0).map((_, i) => ({
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_hoisted_${startIndex + i}`
- }
- }))
-})
-
-function transformWithHoist(template: string, options: CompilerOptions = {}) {
- const ast = parse(template)
- transform(ast, {
- hoistStatic: true,
- nodeTransforms: [
- transformIf,
- transformFor,
- ...(options.prefixIdentifiers ? [transformExpression] : []),
- transformElement,
- transformText
- ],
- directiveTransforms: {
- on: transformOn,
- bind: transformBind
- },
- ...options
- })
- expect(ast.codegenNode).toMatchObject({
- type: NodeTypes.VNODE_CALL,
- isBlock: true
- })
- return ast
-}
-
-describe('compiler: hoistStatic transform', () => {
- test('should NOT hoist root node', () => {
- // if the whole tree is static, the root still needs to be a block
- // so that it's patched in optimized mode to skip children
- const root = transformWithHoist(`
`)
- expect(root.hoists.length).toBe(0)
- expect(root.codegenNode).toMatchObject({
- tag: `"div"`
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist simple element', () => {
- const root = transformWithHoist(
- `hello
`
- )
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`,
- props: createObjectMatcher({ class: 'inline' }),
- children: {
- type: NodeTypes.TEXT,
- content: `hello`
- }
- },
- hoistedChildrenArrayMatcher()
- ])
- expect(root.codegenNode).toMatchObject({
- tag: `"div"`,
- props: undefined,
- children: { content: `_hoisted_2` }
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist nested static tree', () => {
- const root = transformWithHoist(``)
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"p"`,
- props: undefined,
- children: [
- { type: NodeTypes.ELEMENT, tag: `span` },
- { type: NodeTypes.ELEMENT, tag: `span` }
- ]
- },
- hoistedChildrenArrayMatcher()
- ])
- expect((root.codegenNode as VNodeCall).children).toMatchObject({
- content: '_hoisted_2'
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist nested static tree with comments', () => {
- const root = transformWithHoist(``)
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: undefined,
- children: [{ type: NodeTypes.COMMENT, content: `comment` }]
- },
- hoistedChildrenArrayMatcher()
- ])
- expect((root.codegenNode as VNodeCall).children).toMatchObject({
- content: `_hoisted_2`
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist siblings with common non-hoistable parent', () => {
- const root = transformWithHoist(``)
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`
- },
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`
- },
- hoistedChildrenArrayMatcher(1, 2)
- ])
- expect((root.codegenNode as VNodeCall).children).toMatchObject({
- content: '_hoisted_3'
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist components', () => {
- const root = transformWithHoist(`
`)
- expect(root.hoists.length).toBe(0)
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `_component_Comp`
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist element with dynamic props (but hoist the props list)', () => {
- const root = transformWithHoist(``)
- expect(root.hoists.length).toBe(1)
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: createObjectMatcher({
- id: `[foo]`
- }),
- children: undefined,
- patchFlag: genFlagText(PatchFlags.PROPS),
- dynamicProps: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_hoisted_1`,
- isStatic: false
- }
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist element with static key', () => {
- const root = transformWithHoist(``)
- expect(root.hoists.length).toBe(2)
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: createObjectMatcher({ key: 'foo' })
- },
- hoistedChildrenArrayMatcher()
- ])
- expect(root.codegenNode).toMatchObject({
- tag: `"div"`,
- props: undefined,
- children: { content: `_hoisted_2` }
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist element with dynamic key', () => {
- const root = transformWithHoist(``)
- expect(root.hoists.length).toBe(0)
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: createObjectMatcher({
- key: `[foo]`
- })
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist element with dynamic ref', () => {
- const root = transformWithHoist(``)
- expect(root.hoists.length).toBe(0)
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: createObjectMatcher({
- ref: `[foo]`
- }),
- children: undefined,
- patchFlag: genFlagText(PatchFlags.NEED_PATCH)
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist static props for elements with directives', () => {
- const root = transformWithHoist(``)
- expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_hoisted_1`
- },
- children: undefined,
- patchFlag: genFlagText(PatchFlags.NEED_PATCH),
- directives: {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist static props for elements with dynamic text children', () => {
- const root = transformWithHoist(
- ``
- )
- expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: { content: `_hoisted_1` },
- children: { type: NodeTypes.INTERPOLATION },
- patchFlag: genFlagText(PatchFlags.TEXT)
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist static props for elements with unhoistable children', () => {
- const root = transformWithHoist(``)
- expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
- expect((root.codegenNode as VNodeCall).children).toMatchObject([
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: { content: `_hoisted_1` },
- children: [{ type: NodeTypes.ELEMENT, tag: `Comp` }]
- }
- }
- ])
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should hoist v-if props/children if static', () => {
- const root = transformWithHoist(
- ``
- )
- expect(root.hoists).toMatchObject([
- createObjectMatcher({
- key: `[0]`, // key injected by v-if branch
- id: 'foo'
- }),
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`
- },
- hoistedChildrenArrayMatcher(2)
- ])
- expect(
- ((root.children[0] as ElementNode).children[0] as IfNode).codegenNode
- ).toMatchObject({
- type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
- consequent: {
- // blocks should NOT be hoisted
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: { content: `_hoisted_1` },
- children: { content: `_hoisted_3` }
- }
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should hoist v-for children if static', () => {
- const root = transformWithHoist(
- ``
- )
- expect(root.hoists).toMatchObject([
- createObjectMatcher({
- id: 'foo'
- }),
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`
- },
- hoistedChildrenArrayMatcher(2)
- ])
- const forBlockCodegen = (
- (root.children[0] as ElementNode).children[0] as ForNode
- ).codegenNode
- expect(forBlockCodegen).toMatchObject({
- type: NodeTypes.VNODE_CALL,
- tag: FRAGMENT,
- props: undefined,
- children: {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: RENDER_LIST
- },
- patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT)
- })
- const innerBlockCodegen = forBlockCodegen!.children.arguments[1]
- expect(innerBlockCodegen.returns).toMatchObject({
- type: NodeTypes.VNODE_CALL,
- tag: `"div"`,
- props: { content: `_hoisted_1` },
- children: { content: `_hoisted_3` }
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- describe('prefixIdentifiers', () => {
- test('hoist nested static tree with static interpolation', () => {
- const root = transformWithHoist(
- `foo {{ 1 }} {{ true }}
`,
- {
- prefixIdentifiers: true
- }
- )
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`,
- props: undefined,
- children: {
- type: NodeTypes.COMPOUND_EXPRESSION
- }
- },
- hoistedChildrenArrayMatcher()
- ])
- expect(root.codegenNode).toMatchObject({
- tag: `"div"`,
- props: undefined,
- children: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_hoisted_2`
- }
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist nested static tree with static prop value', () => {
- const root = transformWithHoist(
- `{{ 1 }}
`,
- {
- prefixIdentifiers: true
- }
- )
-
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`,
- props: createObjectMatcher({ foo: `[0]` }),
- children: {
- type: NodeTypes.INTERPOLATION,
- content: {
- content: `1`,
- isStatic: false,
- constType: ConstantTypes.CAN_STRINGIFY
- }
- }
- },
- hoistedChildrenArrayMatcher()
- ])
- expect(root.codegenNode).toMatchObject({
- tag: `"div"`,
- props: undefined,
- children: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_hoisted_2`
- }
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('hoist class with static object value', () => {
- const root = transformWithHoist(
- `{{ bar }}
`,
- {
- prefixIdentifiers: true
- }
- )
-
- expect(root.hoists).toMatchObject([
- {
- type: NodeTypes.JS_OBJECT_EXPRESSION,
- properties: [
- {
- key: {
- content: `class`,
- isStatic: true,
- constType: ConstantTypes.CAN_STRINGIFY
- },
- value: {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: NORMALIZE_CLASS,
- arguments: [
- {
- content: `{ foo: true }`,
- isStatic: false,
- constType: ConstantTypes.CAN_STRINGIFY
- }
- ]
- }
- }
- ]
- }
- ])
- expect(root.codegenNode).toMatchObject({
- tag: `"div"`,
- props: undefined,
- children: [
- {
- type: NodeTypes.ELEMENT,
- codegenNode: {
- type: NodeTypes.VNODE_CALL,
- tag: `"span"`,
- props: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_hoisted_1`
- },
- children: {
- type: NodeTypes.INTERPOLATION,
- content: {
- content: `_ctx.bar`,
- isStatic: false,
- constType: ConstantTypes.NOT_CONSTANT
- }
- },
- patchFlag: `1 /* TEXT */`
- }
- }
- ]
- })
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist expressions that refer scope variables', () => {
- const root = transformWithHoist(
- ``,
- {
- prefixIdentifiers: true
- }
- )
-
- expect(root.hoists.length).toBe(0)
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist expressions that refer scope variables (2)', () => {
- const root = transformWithHoist(
- ``,
- {
- prefixIdentifiers: true
- }
- )
-
- expect(root.hoists.length).toBe(0)
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist expressions that refer scope variables (v-slot)', () => {
- const root = transformWithHoist(
- `{{ foo }} `,
- {
- prefixIdentifiers: true
- }
- )
-
- expect(root.hoists.length).toBe(0)
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist elements with cached handlers', () => {
- const root = transformWithHoist(
- ``,
- {
- prefixIdentifiers: true,
- cacheHandlers: true
- }
- )
-
- expect(root.cached).toBe(1)
- expect(root.hoists.length).toBe(0)
- expect(
- generate(root, {
- mode: 'module',
- prefixIdentifiers: true
- }).code
- ).toMatchSnapshot()
- })
-
- test('should NOT hoist elements with cached handlers + other bindings', () => {
- const root = transformWithHoist(
- ``,
- {
- prefixIdentifiers: true,
- cacheHandlers: true
- }
- )
-
- expect(root.cached).toBe(1)
- expect(root.hoists.length).toBe(0)
- expect(
- generate(root, {
- mode: 'module',
- prefixIdentifiers: true
- }).code
- ).toMatchSnapshot()
- })
-
- test('should NOT hoist keyed template v-for with plain element child', () => {
- const root = transformWithHoist(
- `
`
- )
- expect(root.hoists.length).toBe(0)
- expect(generate(root).code).toMatchSnapshot()
- })
-
- test('should NOT hoist SVG with directives', () => {
- const root = transformWithHoist(
- ``
- )
- expect(root.hoists.length).toBe(2)
- expect(generate(root).code).toMatchSnapshot()
- })
- })
-})
diff --git a/packages/compiler-core/__tests__/transforms/noopDirectiveTransform.spec.ts b/packages/compiler-core/__tests__/transforms/noopDirectiveTransform.spec.ts
index 96a60bd1d42..fa711051c18 100644
--- a/packages/compiler-core/__tests__/transforms/noopDirectiveTransform.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/noopDirectiveTransform.spec.ts
@@ -1,9 +1,9 @@
import {
+ type ElementNode,
+ type VNodeCall,
+ noopDirectiveTransform,
baseParse as parse,
transform,
- ElementNode,
- noopDirectiveTransform,
- VNodeCall
} from '../../src'
import { transformElement } from '../../src/transforms/transformElement'
@@ -13,8 +13,8 @@ describe('compiler: noop directive transform', () => {
transform(ast, {
nodeTransforms: [transformElement],
directiveTransforms: {
- noop: noopDirectiveTransform
- }
+ noop: noopDirectiveTransform,
+ },
})
const node = ast.children[0] as ElementNode
// As v-noop adds no properties the codegen should be identical to
diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts
index 06fd2e12b19..bf3510a052d 100644
--- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts
@@ -1,48 +1,49 @@
import {
- CompilerOptions,
+ BindingTypes,
+ type CompilerOptions,
+ ErrorCodes,
+ type NodeTransform,
+ baseCompile,
baseParse as parse,
transform,
- ErrorCodes,
- BindingTypes,
- NodeTransform,
transformExpression,
- baseCompile
} from '../../src'
import {
- RESOLVE_COMPONENT,
+ BASE_TRANSITION,
CREATE_VNODE,
+ GUARD_REACTIVE_PROPS,
+ KEEP_ALIVE,
MERGE_PROPS,
+ NORMALIZE_CLASS,
+ NORMALIZE_PROPS,
+ NORMALIZE_STYLE,
+ RESOLVE_COMPONENT,
RESOLVE_DIRECTIVE,
- TO_HANDLERS,
- helperNameMap,
- TELEPORT,
RESOLVE_DYNAMIC_COMPONENT,
SUSPENSE,
- KEEP_ALIVE,
- BASE_TRANSITION,
- NORMALIZE_CLASS,
- NORMALIZE_STYLE,
- NORMALIZE_PROPS,
- GUARD_REACTIVE_PROPS
+ TELEPORT,
+ TO_HANDLERS,
+ helperNameMap,
} from '../../src/runtimeHelpers'
import {
+ type DirectiveNode,
NodeTypes,
+ type RootNode,
+ type VNodeCall,
createObjectProperty,
- DirectiveNode,
- RootNode,
- VNodeCall
} from '../../src/ast'
import { transformElement } from '../../src/transforms/transformElement'
import { transformStyle } from '../../../compiler-dom/src/transforms/transformStyle'
import { transformOn } from '../../src/transforms/vOn'
import { transformBind } from '../../src/transforms/vBind'
import { PatchFlags } from '@vue/shared'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
import { transformText } from '../../src/transforms/transformText'
+import { parseWithForTransform } from './vFor.spec'
function parseWithElementTransform(
template: string,
- options: CompilerOptions = {}
+ options: CompilerOptions = {},
): {
root: RootNode
node: VNodeCall
@@ -52,14 +53,14 @@ function parseWithElementTransform(
const ast = parse(`${template}
`, options)
transform(ast, {
nodeTransforms: [transformElement, transformText],
- ...options
+ ...options,
})
const codegenNode = (ast as any).children[0].children[0]
.codegenNode as VNodeCall
expect(codegenNode.type).toBe(NodeTypes.VNODE_CALL)
return {
root: ast,
- node: codegenNode
+ node: codegenNode,
}
}
@@ -68,8 +69,8 @@ function parseWithBind(template: string, options?: CompilerOptions) {
...options,
directiveTransforms: {
...options?.directiveTransforms,
- bind: transformBind
- }
+ bind: transformBind,
+ },
})
}
@@ -82,7 +83,7 @@ describe('compiler: element transform', () => {
test('resolve implicitly self-referencing component', () => {
const { root } = parseWithElementTransform(` `, {
- filename: `/foo/bar/Example.vue?vue&type=template`
+ filename: `/foo/bar/Example.vue?vue&type=template`,
})
expect(root.helpers).toContain(RESOLVE_COMPONENT)
expect(root.components).toContain(`Example__self`)
@@ -91,8 +92,8 @@ describe('compiler: element transform', () => {
test('resolve component from setup bindings', () => {
const { root, node } = parseWithElementTransform(` `, {
bindingMetadata: {
- Example: BindingTypes.SETUP_MAYBE_REF
- }
+ Example: BindingTypes.SETUP_MAYBE_REF,
+ },
})
expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
expect(node.tag).toBe(`$setup["Example"]`)
@@ -102,8 +103,8 @@ describe('compiler: element transform', () => {
const { root, node } = parseWithElementTransform(` `, {
inline: true,
bindingMetadata: {
- Example: BindingTypes.SETUP_MAYBE_REF
- }
+ Example: BindingTypes.SETUP_MAYBE_REF,
+ },
})
expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
expect(node.tag).toBe(`_unref(Example)`)
@@ -113,8 +114,8 @@ describe('compiler: element transform', () => {
const { root, node } = parseWithElementTransform(` `, {
inline: true,
bindingMetadata: {
- Example: BindingTypes.SETUP_CONST
- }
+ Example: BindingTypes.SETUP_CONST,
+ },
})
expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
expect(node.tag).toBe(`Example`)
@@ -123,8 +124,8 @@ describe('compiler: element transform', () => {
test('resolve namespaced component from setup bindings', () => {
const { root, node } = parseWithElementTransform(` `, {
bindingMetadata: {
- Foo: BindingTypes.SETUP_MAYBE_REF
- }
+ Foo: BindingTypes.SETUP_MAYBE_REF,
+ },
})
expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
expect(node.tag).toBe(`$setup["Foo"].Example`)
@@ -134,8 +135,8 @@ describe('compiler: element transform', () => {
const { root, node } = parseWithElementTransform(` `, {
inline: true,
bindingMetadata: {
- Foo: BindingTypes.SETUP_MAYBE_REF
- }
+ Foo: BindingTypes.SETUP_MAYBE_REF,
+ },
})
expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
expect(node.tag).toBe(`_unref(Foo).Example`)
@@ -145,20 +146,42 @@ describe('compiler: element transform', () => {
const { root, node } = parseWithElementTransform(` `, {
inline: true,
bindingMetadata: {
- Foo: BindingTypes.SETUP_CONST
- }
+ Foo: BindingTypes.SETUP_CONST,
+ },
})
expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
expect(node.tag).toBe(`Foo.Example`)
})
+ test('resolve namespaced component from props bindings (inline)', () => {
+ const { root, node } = parseWithElementTransform(` `, {
+ inline: true,
+ bindingMetadata: {
+ Foo: BindingTypes.PROPS,
+ },
+ })
+ expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
+ expect(node.tag).toBe(`_unref(__props["Foo"]).Example`)
+ })
+
+ test('resolve namespaced component from props bindings (non-inline)', () => {
+ const { root, node } = parseWithElementTransform(` `, {
+ inline: false,
+ bindingMetadata: {
+ Foo: BindingTypes.PROPS,
+ },
+ })
+ expect(root.helpers).not.toContain(RESOLVE_COMPONENT)
+ expect(node.tag).toBe('_unref($props["Foo"]).Example')
+ })
+
test('do not resolve component from non-script-setup bindings', () => {
const bindingMetadata = {
- Example: BindingTypes.SETUP_MAYBE_REF
+ Example: BindingTypes.SETUP_MAYBE_REF,
}
Object.defineProperty(bindingMetadata, '__isScriptSetup', { value: false })
const { root } = parseWithElementTransform(` `, {
- bindingMetadata
+ bindingMetadata,
})
expect(root.helpers).toContain(RESOLVE_COMPONENT)
expect(root.components).toContain(`Example`)
@@ -170,9 +193,9 @@ describe('compiler: element transform', () => {
tag: `"div"`,
props: createObjectMatcher({
id: 'foo',
- class: 'bar'
+ class: 'bar',
}),
- children: undefined
+ children: undefined,
})
})
@@ -182,7 +205,7 @@ describe('compiler: element transform', () => {
expect(node).toMatchObject({
tag: `"div"`,
props: createObjectMatcher({
- id: 'foo'
+ id: 'foo',
}),
children: [
{
@@ -190,10 +213,10 @@ describe('compiler: element transform', () => {
tag: 'span',
codegenNode: {
type: NodeTypes.VNODE_CALL,
- tag: `"span"`
- }
- }
- ]
+ tag: `"span"`,
+ },
+ },
+ ],
})
})
@@ -209,10 +232,10 @@ describe('compiler: element transform', () => {
tag: 'span',
codegenNode: {
type: NodeTypes.VNODE_CALL,
- tag: `"span"`
- }
- }
- ]
+ tag: `"span"`,
+ },
+ },
+ ],
})
})
@@ -234,17 +257,17 @@ describe('compiler: element transform', () => {
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
- }
- ]
- }
- ]
+ content: `obj`,
+ },
+ ],
+ },
+ ],
})
})
test('v-bind="obj" after static prop', () => {
const { root, node } = parseWithElementTransform(
- `
`
+ `
`,
)
expect(root.helpers).toContain(MERGE_PROPS)
@@ -253,19 +276,19 @@ describe('compiler: element transform', () => {
callee: MERGE_PROPS,
arguments: [
createObjectMatcher({
- id: 'foo'
+ id: 'foo',
}),
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
- }
- ]
+ content: `obj`,
+ },
+ ],
})
})
test('v-bind="obj" before static prop', () => {
const { root, node } = parseWithElementTransform(
- `
`
+ `
`,
)
expect(root.helpers).toContain(MERGE_PROPS)
@@ -275,18 +298,18 @@ describe('compiler: element transform', () => {
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
+ content: `obj`,
},
createObjectMatcher({
- id: 'foo'
- })
- ]
+ id: 'foo',
+ }),
+ ],
})
})
test('v-bind="obj" between static props', () => {
const { root, node } = parseWithElementTransform(
- `
`
+ `
`,
)
expect(root.helpers).toContain(MERGE_PROPS)
@@ -295,22 +318,22 @@ describe('compiler: element transform', () => {
callee: MERGE_PROPS,
arguments: [
createObjectMatcher({
- id: 'foo'
+ id: 'foo',
}),
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
+ content: `obj`,
},
createObjectMatcher({
- class: 'bar'
- })
- ]
+ class: 'bar',
+ }),
+ ],
})
})
test('v-on="obj"', () => {
const { root, node } = parseWithElementTransform(
- `
`
+ `
`,
)
expect(root.helpers).toContain(MERGE_PROPS)
@@ -319,7 +342,7 @@ describe('compiler: element transform', () => {
callee: MERGE_PROPS,
arguments: [
createObjectMatcher({
- id: 'foo'
+ id: 'foo',
}),
{
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -327,21 +350,21 @@ describe('compiler: element transform', () => {
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
+ content: `obj`,
},
- `true`
- ]
+ `true`,
+ ],
},
createObjectMatcher({
- class: 'bar'
- })
- ]
+ class: 'bar',
+ }),
+ ],
})
})
test('v-on="obj" on component', () => {
const { root, node } = parseWithElementTransform(
- ` `
+ ` `,
)
expect(root.helpers).toContain(MERGE_PROPS)
@@ -350,7 +373,7 @@ describe('compiler: element transform', () => {
callee: MERGE_PROPS,
arguments: [
createObjectMatcher({
- id: 'foo'
+ id: 'foo',
}),
{
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -358,20 +381,20 @@ describe('compiler: element transform', () => {
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
- }
- ]
+ content: `obj`,
+ },
+ ],
},
createObjectMatcher({
- class: 'bar'
- })
- ]
+ class: 'bar',
+ }),
+ ],
})
})
test('v-on="obj" + v-bind="obj"', () => {
const { root, node } = parseWithElementTransform(
- `
`
+ `
`,
)
expect(root.helpers).toContain(MERGE_PROPS)
@@ -380,7 +403,7 @@ describe('compiler: element transform', () => {
callee: MERGE_PROPS,
arguments: [
createObjectMatcher({
- id: 'foo'
+ id: 'foo',
}),
{
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -388,16 +411,16 @@ describe('compiler: element transform', () => {
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `handlers`
+ content: `handlers`,
},
- `true`
- ]
+ `true`,
+ ],
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `obj`
- }
- ]
+ content: `obj`,
+ },
+ ],
})
})
@@ -407,15 +430,15 @@ describe('compiler: element transform', () => {
expect(node).toMatchObject({
tag: `"template"`,
props: createObjectMatcher({
- id: 'foo'
- })
+ id: 'foo',
+ }),
})
})
test('should handle with normal children', () => {
function assert(tag: string) {
const { root, node } = parseWithElementTransform(
- `<${tag} target="#foo"> ${tag}>`
+ `<${tag} target="#foo"> ${tag}>`,
)
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(TELEPORT)
@@ -423,7 +446,7 @@ describe('compiler: element transform', () => {
expect(node).toMatchObject({
tag: TELEPORT,
props: createObjectMatcher({
- target: '#foo'
+ target: '#foo',
}),
children: [
{
@@ -431,10 +454,10 @@ describe('compiler: element transform', () => {
tag: 'span',
codegenNode: {
type: NodeTypes.VNODE_CALL,
- tag: `"span"`
- }
- }
- ]
+ tag: `"span"`,
+ },
+ },
+ ],
})
}
@@ -445,7 +468,7 @@ describe('compiler: element transform', () => {
test('should handle ', () => {
function assert(tag: string, content: string, hasFallback?: boolean) {
const { root, node } = parseWithElementTransform(
- `<${tag}>${content}${tag}>`
+ `<${tag}>${content}${tag}>`,
)
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(SUSPENSE)
@@ -456,19 +479,19 @@ describe('compiler: element transform', () => {
children: hasFallback
? createObjectMatcher({
default: {
- type: NodeTypes.JS_FUNCTION_EXPRESSION
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
},
fallback: {
- type: NodeTypes.JS_FUNCTION_EXPRESSION
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
},
- _: `[1 /* STABLE */]`
+ _: `[1 /* STABLE */]`,
})
: createObjectMatcher({
default: {
- type: NodeTypes.JS_FUNCTION_EXPRESSION
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
},
- _: `[1 /* STABLE */]`
- })
+ _: `[1 /* STABLE */]`,
+ }),
})
}
@@ -477,7 +500,7 @@ describe('compiler: element transform', () => {
assert(
`suspense`,
`foo fallback `,
- true
+ true,
)
})
@@ -485,7 +508,7 @@ describe('compiler: element transform', () => {
function assert(tag: string) {
const root = parse(`<${tag}> ${tag}>
`)
transform(root, {
- nodeTransforms: [transformElement, transformText]
+ nodeTransforms: [transformElement, transformText],
})
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(KEEP_ALIVE)
@@ -498,7 +521,7 @@ describe('compiler: element transform', () => {
// keep-alive should not compile content to slots
children: [{ type: NodeTypes.ELEMENT, tag: 'span' }],
// should get a dynamic slots flag to force updates
- patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS)
+ patchFlag: PatchFlags.DYNAMIC_SLOTS,
})
}
@@ -509,7 +532,7 @@ describe('compiler: element transform', () => {
test('should handle ', () => {
function assert(tag: string) {
const { root, node } = parseWithElementTransform(
- `<${tag}> ${tag}>`
+ `<${tag}> ${tag}>`,
)
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(BASE_TRANSITION)
@@ -519,10 +542,10 @@ describe('compiler: element transform', () => {
props: undefined,
children: createObjectMatcher({
default: {
- type: NodeTypes.JS_FUNCTION_EXPRESSION
+ type: NodeTypes.JS_FUNCTION_EXPRESSION,
},
- _: `[1 /* STABLE */]`
- })
+ _: `[1 /* STABLE */]`,
+ }),
})
}
@@ -531,12 +554,12 @@ describe('compiler: element transform', () => {
})
test('error on v-bind with no argument', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithElementTransform(`
`, { onError })
expect(onError.mock.calls[0]).toMatchObject([
{
- code: ErrorCodes.X_V_BIND_NO_EXPRESSION
- }
+ code: ErrorCodes.X_V_BIND_NO_EXPRESSION,
+ },
])
})
@@ -547,10 +570,10 @@ describe('compiler: element transform', () => {
foo(dir) {
_dir = dir
return {
- props: [createObjectProperty(dir.arg!, dir.exp!)]
+ props: [createObjectProperty(dir.arg!, dir.exp!)],
}
- }
- }
+ },
+ },
})
expect(node.props).toMatchObject({
@@ -559,13 +582,13 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.JS_PROPERTY,
key: _dir!.arg,
- value: _dir!.exp
- }
- ]
+ value: _dir!.exp,
+ },
+ ],
})
// should factor in props returned by custom directive transforms
// in patchFlag analysis
- expect(node.patchFlag).toMatch(PatchFlags.PROPS + '')
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
expect(node.dynamicProps).toMatch(`"bar"`)
})
@@ -577,11 +600,11 @@ describe('compiler: element transform', () => {
foo() {
return {
props: [],
- needRuntime: true
+ needRuntime: true,
}
- }
- }
- }
+ },
+ },
+ },
)
expect(root.helpers).toContain(RESOLVE_DIRECTIVE)
expect(root.directives).toContain(`foo`)
@@ -589,7 +612,7 @@ describe('compiler: element transform', () => {
tag: `"div"`,
props: undefined,
children: undefined,
- patchFlag: genFlagText(PatchFlags.NEED_PATCH), // should generate appropriate flag
+ patchFlag: PatchFlags.NEED_PATCH, // should generate appropriate flag
directives: {
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
@@ -601,18 +624,18 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `hello`,
- isStatic: false
+ isStatic: false,
},
// arg
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `bar`,
- isStatic: true
- }
- ]
- }
- ]
- }
+ isStatic: true,
+ },
+ ],
+ },
+ ],
+ },
})
})
@@ -624,24 +647,24 @@ describe('compiler: element transform', () => {
foo() {
return {
props: [],
- needRuntime: CREATE_VNODE
+ needRuntime: CREATE_VNODE,
}
- }
- }
- }
+ },
+ },
+ },
)
expect(root.helpers).toContain(CREATE_VNODE)
expect(root.helpers).not.toContain(RESOLVE_DIRECTIVE)
expect(root.directives.length).toBe(0)
expect(node.directives!.elements[0].elements[0]).toBe(
- `_${helperNameMap[CREATE_VNODE]}`
+ `_${helperNameMap[CREATE_VNODE]}`,
)
})
test('runtime directives', () => {
const { root, node } = parseWithElementTransform(
- `
`
+ `
`,
)
expect(root.helpers).toContain(RESOLVE_DIRECTIVE)
expect(root.directives).toContain(`foo`)
@@ -654,7 +677,7 @@ describe('compiler: element transform', () => {
elements: [
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
- elements: [`_directive_foo`]
+ elements: [`_directive_foo`],
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -663,9 +686,9 @@ describe('compiler: element transform', () => {
// exp
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `x`
- }
- ]
+ content: `x`,
+ },
+ ],
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -675,13 +698,13 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `y`,
- isStatic: false
+ isStatic: false,
},
// arg
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `arg`,
- isStatic: false
+ isStatic: false,
},
// modifiers
{
@@ -692,33 +715,33 @@ describe('compiler: element transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `mod`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `true`,
- isStatic: false
- }
+ isStatic: false,
+ },
},
{
type: NodeTypes.JS_PROPERTY,
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `mad`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `true`,
- isStatic: false
- }
- }
- ]
- }
- ]
- }
- ]
- }
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
})
})
@@ -727,9 +750,9 @@ describe('compiler: element transform', () => {
`
`,
{
directiveTransforms: {
- on: transformOn
- }
- }
+ on: transformOn,
+ },
+ },
)
expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
@@ -739,7 +762,7 @@ describe('compiler: element transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `onClick`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -747,17 +770,17 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `a`,
- isStatic: false
+ isStatic: false,
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `b`,
- isStatic: false
- }
- ]
- }
- }
- ]
+ isStatic: false,
+ },
+ ],
+ },
+ },
+ ],
})
})
@@ -767,9 +790,9 @@ describe('compiler: element transform', () => {
{
nodeTransforms: [transformStyle, transformElement],
directiveTransforms: {
- bind: transformBind
- }
- }
+ bind: transformBind,
+ },
+ },
)
expect(root.helpers).toContain(NORMALIZE_STYLE)
expect(node.props).toMatchObject({
@@ -780,7 +803,7 @@ describe('compiler: element transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `style`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -792,19 +815,19 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{"color":"green"}`,
- isStatic: false
+ isStatic: false,
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{ color: 'red' }`,
- isStatic: false
- }
- ]
- }
- ]
- }
- }
- ]
+ isStatic: false,
+ },
+ ],
+ },
+ ],
+ },
+ },
+ ],
})
})
@@ -814,10 +837,10 @@ describe('compiler: element transform', () => {
{
nodeTransforms: [transformExpression, transformStyle, transformElement],
directiveTransforms: {
- bind: transformBind
+ bind: transformBind,
},
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
expect(root.helpers).toContain(NORMALIZE_STYLE)
expect(node.props).toMatchObject({
@@ -828,14 +851,14 @@ describe('compiler: element transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `style`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: NORMALIZE_STYLE
- }
- }
- ]
+ callee: NORMALIZE_STYLE,
+ },
+ },
+ ],
})
})
@@ -845,10 +868,10 @@ describe('compiler: element transform', () => {
{
nodeTransforms: [transformExpression, transformStyle, transformElement],
directiveTransforms: {
- bind: transformBind
+ bind: transformBind,
},
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
expect(root.helpers).toContain(NORMALIZE_STYLE)
expect(node.props).toMatchObject({
@@ -859,14 +882,14 @@ describe('compiler: element transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `style`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: NORMALIZE_STYLE
- }
- }
- ]
+ callee: NORMALIZE_STYLE,
+ },
+ },
+ ],
})
})
@@ -875,9 +898,9 @@ describe('compiler: element transform', () => {
`
`,
{
directiveTransforms: {
- bind: transformBind
- }
- }
+ bind: transformBind,
+ },
+ },
)
expect(root.helpers).toContain(NORMALIZE_CLASS)
expect(node.props).toMatchObject({
@@ -888,7 +911,7 @@ describe('compiler: element transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `class`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -900,19 +923,19 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `foo`,
- isStatic: true
+ isStatic: true,
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{ bar: isBar }`,
- isStatic: false
- }
- ]
- }
- ]
- }
- }
- ]
+ isStatic: false,
+ },
+ ],
+ },
+ ],
+ },
+ },
+ ],
})
})
@@ -922,35 +945,35 @@ describe('compiler: element transform', () => {
expect(node.patchFlag).toBeUndefined()
const { node: node2 } = parseWithBind(`{{ foo }}
`)
- expect(node2.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
+ expect(node2.patchFlag).toBe(PatchFlags.TEXT)
// multiple nodes, merged with optimize text
const { node: node3 } = parseWithBind(`foo {{ bar }} baz
`)
- expect(node3.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
+ expect(node3.patchFlag).toBe(PatchFlags.TEXT)
})
test('CLASS', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.CLASS))
+ expect(node.patchFlag).toBe(PatchFlags.CLASS)
})
test('STYLE', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.STYLE))
+ expect(node.patchFlag).toBe(PatchFlags.STYLE)
})
test('PROPS', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
expect(node.dynamicProps).toBe(`["foo", "baz"]`)
})
test('CLASS + STYLE + PROPS', () => {
const { node } = parseWithBind(
- `
`
+ `
`,
)
expect(node.patchFlag).toBe(
- genFlagText([PatchFlags.CLASS, PatchFlags.STYLE, PatchFlags.PROPS])
+ PatchFlags.CLASS | PatchFlags.STYLE | PatchFlags.PROPS,
)
expect(node.dynamicProps).toBe(`["foo", "baz"]`)
})
@@ -958,59 +981,59 @@ describe('compiler: element transform', () => {
// should treat `class` and `style` as PROPS
test('PROPS on component', () => {
const { node } = parseWithBind(
- ` `
+ ` `,
)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
expect(node.dynamicProps).toBe(`["id", "class", "style"]`)
})
test('FULL_PROPS (v-bind)', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
})
test('FULL_PROPS (dynamic key)', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
})
test('FULL_PROPS (w/ others)', () => {
const { node } = parseWithBind(
- `
`
+ `
`,
)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
})
test('NEED_PATCH (static ref)', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('NEED_PATCH (dynamic ref)', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('NEED_PATCH (custom directives)', () => {
const { node } = parseWithBind(`
`)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('NEED_PATCH (vnode hooks)', () => {
- const root = baseCompile(`
`, {
+ const root = baseCompile(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
}).ast
const node = (root as any).children[0].codegenNode
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('script setup inline mode template ref (binding exists)', () => {
const { node } = parseWithElementTransform(` `, {
inline: true,
bindingMetadata: {
- input: BindingTypes.SETUP_REF
- }
+ input: BindingTypes.SETUP_REF,
+ },
})
expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
@@ -1019,31 +1042,31 @@ describe('compiler: element transform', () => {
type: NodeTypes.JS_PROPERTY,
key: {
content: 'ref_key',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'input',
- isStatic: true
- }
+ isStatic: true,
+ },
},
{
type: NodeTypes.JS_PROPERTY,
key: {
content: 'ref',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'input',
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
})
test('script setup inline mode template ref (binding does not exist)', () => {
const { node } = parseWithElementTransform(` `, {
- inline: true
+ inline: true,
})
expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
@@ -1052,14 +1075,14 @@ describe('compiler: element transform', () => {
type: NodeTypes.JS_PROPERTY,
key: {
content: 'ref',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'input',
- isStatic: true
- }
- }
- ]
+ isStatic: true,
+ },
+ },
+ ],
})
})
@@ -1068,8 +1091,8 @@ describe('compiler: element transform', () => {
inline: true,
bindingMetadata: {
msg: BindingTypes.PROPS,
- ref: BindingTypes.SETUP_CONST
- }
+ ref: BindingTypes.SETUP_CONST,
+ },
})
expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
@@ -1078,53 +1101,71 @@ describe('compiler: element transform', () => {
type: NodeTypes.JS_PROPERTY,
key: {
content: 'ref',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'msg',
- isStatic: true
- }
- }
- ]
+ isStatic: true,
+ },
+ },
+ ],
})
})
- test('HYDRATE_EVENTS', () => {
+ test('NEED_HYDRATION for v-on', () => {
// ignore click events (has dedicated fast path)
const { node } = parseWithElementTransform(`
`, {
directiveTransforms: {
- on: transformOn
- }
+ on: transformOn,
+ },
})
// should only have props flag
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
const { node: node2 } = parseWithElementTransform(
`
`,
{
directiveTransforms: {
- on: transformOn
- }
- }
- )
- expect(node2.patchFlag).toBe(
- genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
+ on: transformOn,
+ },
+ },
)
+ expect(node2.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
+ })
+
+ test('NEED_HYDRATION for v-bind.prop', () => {
+ const { node } = parseWithBind(`
`)
+ expect(node.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
+
+ const { node: node2 } = parseWithBind(`
`)
+ expect(node2.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
})
// #5870
- test('HYDRATE_EVENTS on dynamic component', () => {
+ test('NEED_HYDRATION on dynamic component', () => {
const { node } = parseWithElementTransform(
` `,
{
directiveTransforms: {
- on: transformOn
- }
- }
- )
- expect(node.patchFlag).toBe(
- genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
+ on: transformOn,
+ },
+ },
)
+ expect(node.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
+ })
+
+ test('should not have PROPS patchflag for constant v-on handlers', () => {
+ const { node } = parseWithElementTransform(`
`, {
+ prefixIdentifiers: true,
+ bindingMetadata: {
+ foo: BindingTypes.SETUP_CONST,
+ },
+ directiveTransforms: {
+ on: transformOn,
+ },
+ })
+ // should only have hydration flag
+ expect(node.patchFlag).toBe(PatchFlags.NEED_HYDRATION)
})
})
@@ -1140,10 +1181,10 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'foo',
- isStatic: true
- }
- ]
- }
+ isStatic: true,
+ },
+ ],
+ },
})
})
@@ -1158,10 +1199,10 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'foo',
- isStatic: true
- }
- ]
- }
+ isStatic: true,
+ },
+ ],
+ },
})
})
@@ -1176,41 +1217,49 @@ describe('compiler: element transform', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'foo',
- isStatic: false
- }
- ]
- }
+ isStatic: false,
+ },
+ ],
+ },
})
})
- test('v-is', () => {
- const { node, root } = parseWithBind(`
`)
+ test('dynamic binding shorthand', () => {
+ const { node, root } = parseWithBind(` `)
expect(root.helpers).toContain(RESOLVE_DYNAMIC_COMPONENT)
expect(node).toMatchObject({
+ isBlock: true,
tag: {
callee: RESOLVE_DYNAMIC_COMPONENT,
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `'foo'`,
- isStatic: false
- }
- ]
+ content: 'is',
+ isStatic: false,
+ },
+ ],
},
- // should skip v-is runtime check
- directives: undefined
+ })
+ })
+
+ test('is casting', () => {
+ const { node, root } = parseWithBind(`
`)
+ expect(root.helpers).toContain(RESOLVE_COMPONENT)
+ expect(node).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: '_component_foo',
})
})
// #3934
test('normal component with is prop', () => {
const { node, root } = parseWithBind(` `, {
- isNativeTag: () => false
+ isNativeTag: () => false,
})
expect(root.helpers).toContain(RESOLVE_COMPONENT)
expect(root.helpers).not.toContain(RESOLVE_DYNAMIC_COMPONENT)
expect(node).toMatchObject({
- tag: '_component_custom_input'
+ tag: '_component_custom_input',
})
})
})
@@ -1218,12 +1267,24 @@ describe('compiler: element transform', () => {
test(' should be forced into blocks', () => {
const ast = parse(`
`)
transform(ast, {
- nodeTransforms: [transformElement]
+ nodeTransforms: [transformElement],
})
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
type: NodeTypes.VNODE_CALL,
tag: `"svg"`,
- isBlock: true
+ isBlock: true,
+ })
+ })
+
+ test(' should be forced into blocks', () => {
+ const ast = parse(`
`)
+ transform(ast, {
+ nodeTransforms: [transformElement],
+ })
+ expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
+ type: NodeTypes.VNODE_CALL,
+ tag: `"math"`,
+ isBlock: true,
})
})
@@ -1235,7 +1296,7 @@ describe('compiler: element transform', () => {
test('force block for inline before-update handlers w/ children', () => {
expect(
parseWithElementTransform(`hello
`).node
- .isBlock
+ .isBlock,
).toBe(true)
})
@@ -1243,12 +1304,12 @@ describe('compiler: element transform', () => {
test('element with dynamic keys should be forced into blocks', () => {
const ast = parse(``)
transform(ast, {
- nodeTransforms: [transformElement]
+ nodeTransforms: [transformElement],
})
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
type: NodeTypes.VNODE_CALL,
tag: `"div"`,
- isBlock: true
+ isBlock: true,
})
})
@@ -1263,23 +1324,61 @@ describe('compiler: element transform', () => {
prop.type === NodeTypes.ATTRIBUTE &&
prop.name === 'id' &&
prop.value &&
- prop.value.content === 'foo'
+ prop.value.content === 'foo',
)
) {
context.replaceNode({
...node,
- tag: 'span'
+ tag: 'span',
})
}
}
const ast = parse(``)
transform(ast, {
- nodeTransforms: [transformElement, transformText, customNodeTransform]
+ nodeTransforms: [transformElement, transformText, customNodeTransform],
})
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
type: NodeTypes.VNODE_CALL,
tag: '"span"',
- isBlock: false
+ isBlock: false,
+ })
+ })
+
+ test('ref_for marker on static ref', () => {
+ const { node } = parseWithForTransform(`
`)
+ expect((node.children[0] as any).codegenNode.props).toMatchObject(
+ createObjectMatcher({
+ ref_for: `[true]`,
+ ref: 'x',
+ }),
+ )
+ })
+
+ test('ref_for marker on dynamic ref', () => {
+ const { node } = parseWithForTransform(`
`)
+ expect((node.children[0] as any).codegenNode.props).toMatchObject(
+ createObjectMatcher({
+ ref_for: `[true]`,
+ ref: '[x]',
+ }),
+ )
+ })
+
+ test('ref_for marker on v-bind', () => {
+ const { node } = parseWithForTransform(`
`)
+ expect((node.children[0] as any).codegenNode.props).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: MERGE_PROPS,
+ arguments: [
+ createObjectMatcher({
+ ref_for: `[true]`,
+ }),
+ {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'x',
+ isStatic: false,
+ },
+ ],
})
})
})
diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
index 4db7aa61903..c92814089ef 100644
--- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
@@ -1,37 +1,42 @@
import {
+ BindingTypes,
+ type CompilerOptions,
+ ConstantTypes,
+ type DirectiveNode,
+ type ElementNode,
+ type InterpolationNode,
+ NodeTypes,
+ baseCompile,
baseParse as parse,
transform,
- ElementNode,
- DirectiveNode,
- NodeTypes,
- CompilerOptions,
- InterpolationNode,
- ConstantTypes,
- BindingTypes,
- baseCompile
} from '../../src'
import { transformIf } from '../../src/transforms/vIf'
import { transformExpression } from '../../src/transforms/transformExpression'
+import { PatchFlagNames, PatchFlags } from '../../../shared/src'
function parseWithExpressionTransform(
template: string,
- options: CompilerOptions = {}
+ options: CompilerOptions = {},
) {
- const ast = parse(template)
+ const ast = parse(template, options)
transform(ast, {
prefixIdentifiers: true,
nodeTransforms: [transformIf, transformExpression],
- ...options
+ ...options,
})
return ast.children[0]
}
+function compile(template: string) {
+ return baseCompile(template, { prefixIdentifiers: true })
+}
+
describe('compiler: expression transform', () => {
test('interpolation (root)', () => {
const node = parseWithExpressionTransform(`{{ foo }}`) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.foo`
+ content: `_ctx.foo`,
})
})
@@ -39,34 +44,34 @@ describe('compiler: expression transform', () => {
const node = parseWithExpressionTransform(`{{}}`) as InterpolationNode
const node2 = parseWithExpressionTransform(`{{ }}`) as InterpolationNode
const node3 = parseWithExpressionTransform(
- `{{ }}
`
+ `{{ }}
`,
) as ElementNode
const objectToBeMatched = {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: ``
+ content: ``,
}
expect(node.content).toMatchObject(objectToBeMatched)
expect(node2.content).toMatchObject(objectToBeMatched)
expect((node3.children[0] as InterpolationNode).content).toMatchObject(
- objectToBeMatched
+ objectToBeMatched,
)
})
test('interpolation (children)', () => {
const el = parseWithExpressionTransform(
- `{{ foo }}
`
+ `{{ foo }}
`,
) as ElementNode
const node = el.children[0] as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.foo`
+ content: `_ctx.foo`,
})
})
test('interpolation (complex)', () => {
const el = parseWithExpressionTransform(
- `{{ foo + bar(baz.qux) }}
`
+ `{{ foo + bar(baz.qux) }}
`,
) as ElementNode
const node = el.children[0] as InterpolationNode
expect(node.content).toMatchObject({
@@ -79,46 +84,46 @@ describe('compiler: expression transform', () => {
{ content: `_ctx.baz` },
`.`,
{ content: `qux` },
- `)`
- ]
+ `)`,
+ ],
})
})
test('directive value', () => {
const node = parseWithExpressionTransform(
- `
`
+ `
`,
) as ElementNode
const arg = (node.props[0] as DirectiveNode).arg!
expect(arg).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `arg`
+ content: `arg`,
})
const exp = (node.props[0] as DirectiveNode).exp!
expect(exp).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.baz`
+ content: `_ctx.baz`,
})
})
test('dynamic directive arg', () => {
const node = parseWithExpressionTransform(
- `
`
+ `
`,
) as ElementNode
const arg = (node.props[0] as DirectiveNode).arg!
expect(arg).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.arg`
+ content: `_ctx.arg`,
})
const exp = (node.props[0] as DirectiveNode).exp!
expect(exp).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.baz`
+ content: `_ctx.baz`,
})
})
test('should prefix complex expressions', () => {
const node = parseWithExpressionTransform(
- `{{ foo(baz + 1, { key: kuz }) }}`
+ `{{ foo(baz + 1, { key: kuz }) }}`,
) as InterpolationNode
// should parse into compound expression
expect(node.content).toMatchObject({
@@ -127,76 +132,57 @@ describe('compiler: expression transform', () => {
{
content: `_ctx.foo`,
loc: {
- source: `foo`,
- start: {
- offset: 3,
- line: 1,
- column: 4
- },
- end: {
- offset: 6,
- line: 1,
- column: 7
- }
- }
+ start: { offset: 3, line: 1, column: 4 },
+ end: { offset: 6, line: 1, column: 7 },
+ },
},
`(`,
{
content: `_ctx.baz`,
loc: {
- source: `baz`,
- start: {
- offset: 7,
- line: 1,
- column: 8
- },
- end: {
- offset: 10,
- line: 1,
- column: 11
- }
- }
+ start: { offset: 7, line: 1, column: 8 },
+ end: { offset: 10, line: 1, column: 11 },
+ },
},
` + 1, { key: `,
{
content: `_ctx.kuz`,
loc: {
- source: `kuz`,
- start: {
- offset: 23,
- line: 1,
- column: 24
- },
- end: {
- offset: 26,
- line: 1,
- column: 27
- }
- }
+ start: { offset: 23, line: 1, column: 24 },
+ end: { offset: 26, line: 1, column: 27 },
+ },
},
- ` })`
- ]
+ ` })`,
+ ],
})
})
test('should not prefix whitelisted globals', () => {
const node = parseWithExpressionTransform(
- `{{ Math.max(1, 2) }}`
+ `{{ Math.max(1, 2) }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [{ content: `Math` }, `.`, { content: `max` }, `(1, 2)`]
+ children: [{ content: `Math` }, `.`, { content: `max` }, `(1, 2)`],
+ })
+
+ expect(
+ (parseWithExpressionTransform(`{{ new Error() }}`) as InterpolationNode)
+ .content,
+ ).toMatchObject({
+ type: NodeTypes.COMPOUND_EXPRESSION,
+ children: ['new ', { content: 'Error' }, '()'],
})
})
test('should not prefix reserved literals', () => {
function assert(exp: string) {
const node = parseWithExpressionTransform(
- `{{ ${exp} }}`
+ `{{ ${exp} }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: exp
+ content: exp,
})
}
assert(`true`)
@@ -207,7 +193,7 @@ describe('compiler: expression transform', () => {
test('should not prefix id of a function declaration', () => {
const node = parseWithExpressionTransform(
- `{{ function foo() { return bar } }}`
+ `{{ function foo() { return bar } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -216,14 +202,14 @@ describe('compiler: expression transform', () => {
{ content: `foo` },
`() { return `,
{ content: `_ctx.bar` },
- ` }`
- ]
+ ` }`,
+ ],
})
})
test('should not prefix params of a function expression', () => {
const node = parseWithExpressionTransform(
- `{{ foo => foo + bar }}`
+ `{{ foo => foo + bar }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -232,14 +218,14 @@ describe('compiler: expression transform', () => {
` => `,
{ content: `foo` },
` + `,
- { content: `_ctx.bar` }
- ]
+ { content: `_ctx.bar` },
+ ],
})
})
test('should prefix default value of a function expression param', () => {
const node = parseWithExpressionTransform(
- `{{ (foo = baz) => foo + bar }}`
+ `{{ (foo = baz) => foo + bar }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -251,14 +237,14 @@ describe('compiler: expression transform', () => {
`) => `,
{ content: `foo` },
` + `,
- { content: `_ctx.bar` }
- ]
+ { content: `_ctx.bar` },
+ ],
})
})
test('should not prefix function param destructuring', () => {
const node = parseWithExpressionTransform(
- `{{ ({ foo }) => foo + bar }}`
+ `{{ ({ foo }) => foo + bar }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -268,14 +254,14 @@ describe('compiler: expression transform', () => {
` }) => `,
{ content: `foo` },
` + `,
- { content: `_ctx.bar` }
- ]
+ { content: `_ctx.bar` },
+ ],
})
})
test('function params should not affect out of scope identifiers', () => {
const node = parseWithExpressionTransform(
- `{{ { a: foo => foo, b: foo } }}`
+ `{{ { a: foo => foo, b: foo } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -286,14 +272,14 @@ describe('compiler: expression transform', () => {
{ content: `foo` },
`, b: `,
{ content: `_ctx.foo` },
- ` }`
- ]
+ ` }`,
+ ],
})
})
test('should prefix default value of function param destructuring', () => {
const node = parseWithExpressionTransform(
- `{{ ({ foo = bar }) => foo + bar }}`
+ `{{ ({ foo = bar }) => foo + bar }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -305,13 +291,14 @@ describe('compiler: expression transform', () => {
` }) => `,
{ content: `foo` },
` + `,
- { content: `_ctx.bar` }
- ]
+ { content: `_ctx.bar` },
+ ],
})
})
+
test('should not prefix an object property key', () => {
const node = parseWithExpressionTransform(
- `{{ { foo() { baz() }, value: bar } }}`
+ `{{ { foo() { baz() }, value: bar } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -320,24 +307,24 @@ describe('compiler: expression transform', () => {
{ content: `_ctx.baz` },
`() }, value: `,
{ content: `_ctx.bar` },
- ` }`
- ]
+ ` }`,
+ ],
})
})
test('should not duplicate object key with same name as value', () => {
const node = parseWithExpressionTransform(
- `{{ { foo: foo } }}`
+ `{{ { foo: foo } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ foo: `, { content: `_ctx.foo` }, ` }`]
+ children: [`{ foo: `, { content: `_ctx.foo` }, ` }`],
})
})
test('should prefix a computed object property key', () => {
const node = parseWithExpressionTransform(
- `{{ { [foo]: bar } }}`
+ `{{ { [foo]: bar } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -346,24 +333,24 @@ describe('compiler: expression transform', () => {
{ content: `_ctx.foo` },
`]: `,
{ content: `_ctx.bar` },
- ` }`
- ]
+ ` }`,
+ ],
})
})
test('should prefix object property shorthand value', () => {
const node = parseWithExpressionTransform(
- `{{ { foo } }}`
+ `{{ { foo } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ foo: `, { content: `_ctx.foo` }, ` }`]
+ children: [`{ foo: `, { content: `_ctx.foo` }, ` }`],
})
})
test('should not prefix id in a member expression', () => {
const node = parseWithExpressionTransform(
- `{{ foo.bar.baz }}`
+ `{{ foo.bar.baz }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -372,14 +359,14 @@ describe('compiler: expression transform', () => {
`.`,
{ content: `bar` },
`.`,
- { content: `baz` }
- ]
+ { content: `baz` },
+ ],
})
})
test('should prefix computed id in a member expression', () => {
const node = parseWithExpressionTransform(
- `{{ foo[bar][baz] }}`
+ `{{ foo[bar][baz] }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -389,32 +376,43 @@ describe('compiler: expression transform', () => {
{ content: `_ctx.bar` },
`][`,
{ content: '_ctx.baz' },
- `]`
- ]
+ `]`,
+ ],
})
})
test('should handle parse error', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithExpressionTransform(`{{ a( }}`, { onError })
expect(onError.mock.calls[0][0].message).toMatch(
- `Error parsing JavaScript expression: Unexpected token`
+ `Error parsing JavaScript expression: Unexpected token`,
+ )
+ })
+
+ test('should not error', () => {
+ const onError = vi.fn()
+ parseWithExpressionTransform(
+ `
`,
+ {
+ onError,
+ },
)
+ expect(onError).not.toHaveBeenCalled()
})
test('should prefix in assignment', () => {
const node = parseWithExpressionTransform(
- `{{ x = 1 }}`
+ `{{ x = 1 }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [{ content: `_ctx.x` }, ` = 1`]
+ children: [{ content: `_ctx.x` }, ` = 1`],
})
})
test('should prefix in assignment pattern', () => {
const node = parseWithExpressionTransform(
- `{{ { x, y: [z] } = obj }}`
+ `{{ { x, y: [z] } = obj }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -424,37 +422,156 @@ describe('compiler: expression transform', () => {
`, y: [`,
{ content: `_ctx.z` },
`] } = `,
- { content: `_ctx.obj` }
- ]
+ { content: `_ctx.obj` },
+ ],
})
})
+ // #8295
+ test('should treat floating point number literals as constant', () => {
+ const node = parseWithExpressionTransform(
+ `{{ [1, 2.1] }}`,
+ ) as InterpolationNode
+ expect(node.content).toMatchObject({
+ constType: ConstantTypes.CAN_STRINGIFY,
+ })
+ })
+
+ // #10807
+ test('should not bail constant on strings w/ ()', () => {
+ const node = parseWithExpressionTransform(
+ `{{ { foo: 'ok()' } }}`,
+ ) as InterpolationNode
+ expect(node.content).toMatchObject({
+ constType: ConstantTypes.CAN_STRINGIFY,
+ })
+ })
+
+ test('should bail constant for global identifiers w/ new or call expressions', () => {
+ const node = parseWithExpressionTransform(
+ `{{ new Date().getFullYear() }}`,
+ ) as InterpolationNode
+ expect(node.content).toMatchObject({
+ children: [
+ 'new ',
+ { constType: ConstantTypes.NOT_CONSTANT },
+ '().',
+ { constType: ConstantTypes.NOT_CONSTANT },
+ '()',
+ ],
+ })
+ })
+
+ test('should not prefix temp variable of for...in', () => {
+ const { code } = compile(
+ ` {
+ for (const x in list) {
+ log(x)
+ }
+ error(x)
+ }"/>`,
+ )
+ expect(code).not.toMatch(`log(_ctx.x)`)
+ expect(code).toMatch(`error(_ctx.x)`)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should not prefix temp variable of for...of', () => {
+ const { code } = compile(
+ `
{
+ for (const x of list) {
+ log(x)
+ }
+ error(x)
+ }"/>`,
+ )
+ expect(code).not.toMatch(`log(_ctx.x)`)
+ expect(code).toMatch(`error(_ctx.x)`)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should not prefix temp variable of for loop', () => {
+ const { code } = compile(
+ `
{
+ for (let i = 0; i < list.length; i++) {
+ log(i)
+ }
+ error(i)
+ }"/>`,
+ )
+ expect(code).not.toMatch(`log(_ctx.i)`)
+ expect(code).toMatch(`error(_ctx.i)`)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should allow leak of var declarations in for loop', () => {
+ const { code } = compile(
+ `
{
+ for (var i = 0; i < list.length; i++) {
+ log(i)
+ }
+ error(i)
+ }"/>`,
+ )
+ expect(code).not.toMatch(`log(_ctx.i)`)
+ expect(code).not.toMatch(`error(_ctx.i)`)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should not prefix catch block param', () => {
+ const { code } = compile(
+ `
{
+ try {} catch (err) { console.error(err) }
+ console.log(err)
+ }"/>`,
+ )
+ expect(code).not.toMatch(`console.error(_ctx.err)`)
+ expect(code).toMatch(`console.log(_ctx.err)`)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should not prefix destructured catch block param', () => {
+ const { code } = compile(
+ `
{
+ try {
+ throw new Error('sup?')
+ } catch ({ message: { length } }) {
+ console.error(length)
+ }
+ console.log(length)
+ }"/>`,
+ )
+ expect(code).not.toMatch(`console.error(_ctx.length)`)
+ expect(code).toMatch(`console.log(_ctx.length)`)
+ expect(code).toMatchSnapshot()
+ })
+
describe('ES Proposals support', () => {
test('bigInt', () => {
const node = parseWithExpressionTransform(
- `{{ 13000n }}`
+ `{{ 13000n }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
content: `13000n`,
isStatic: false,
- constType: ConstantTypes.CAN_STRINGIFY
+ constType: ConstantTypes.CAN_STRINGIFY,
})
})
test('nullish coalescing', () => {
const node = parseWithExpressionTransform(
- `{{ a ?? b }}`
+ `{{ a ?? b }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [{ content: `_ctx.a` }, ` ?? `, { content: `_ctx.b` }]
+ children: [{ content: `_ctx.a` }, ` ?? `, { content: `_ctx.b` }],
})
})
test('optional chaining', () => {
const node = parseWithExpressionTransform(
- `{{ a?.b?.c }}`
+ `{{ a?.b?.c }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -463,8 +580,8 @@ describe('compiler: expression transform', () => {
`?.`,
{ content: `b` },
`?.`,
- { content: `c` }
- ]
+ { content: `c` },
+ ],
})
})
@@ -475,14 +592,18 @@ describe('compiler: expression transform', () => {
[
'pipelineOperator',
{
- proposal: 'minimal'
- }
- ]
- ]
+ proposal: 'minimal',
+ },
+ ],
+ ],
}) as InterpolationNode
expect(node.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [{ content: `_ctx.a` }, ` |> `, { content: `_ctx.uppercase` }]
+ children: [
+ { content: `_ctx.a` },
+ ` |> `,
+ { content: `_ctx.uppercase` },
+ ],
})
})
})
@@ -493,26 +614,30 @@ describe('compiler: expression transform', () => {
setup: BindingTypes.SETUP_MAYBE_REF,
setupConst: BindingTypes.SETUP_CONST,
data: BindingTypes.DATA,
- options: BindingTypes.OPTIONS
+ options: BindingTypes.OPTIONS,
+ reactive: BindingTypes.SETUP_REACTIVE_CONST,
+ literal: BindingTypes.LITERAL_CONST,
+ isNaN: BindingTypes.SETUP_REF,
}
function compileWithBindingMetadata(
template: string,
- options?: CompilerOptions
+ options?: CompilerOptions,
) {
return baseCompile(template, {
prefixIdentifiers: true,
bindingMetadata,
- ...options
+ ...options,
})
}
test('non-inline mode', () => {
const { code } = compileWithBindingMetadata(
- `
{{ props }} {{ setup }} {{ data }} {{ options }}
`
+ `
{{ props }} {{ setup }} {{ data }} {{ options }} {{ isNaN }}
`,
)
expect(code).toMatch(`$props.props`)
expect(code).toMatch(`$setup.setup`)
+ expect(code).toMatch(`$setup.isNaN`)
expect(code).toMatch(`$data.data`)
expect(code).toMatch(`$options.options`)
expect(code).toMatch(`_ctx, _cache, $props, $setup, $data, $options`)
@@ -521,15 +646,74 @@ describe('compiler: expression transform', () => {
test('inline mode', () => {
const { code } = compileWithBindingMetadata(
- `
{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }}
`,
- { inline: true }
+ `
{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }} {{ isNaN }}
`,
+ { inline: true },
)
expect(code).toMatch(`__props.props`)
expect(code).toMatch(`_unref(setup)`)
expect(code).toMatch(`_toDisplayString(setupConst)`)
expect(code).toMatch(`_ctx.data`)
expect(code).toMatch(`_ctx.options`)
+ expect(code).toMatch(`isNaN.value`)
expect(code).toMatchSnapshot()
})
+
+ test('literal const handling', () => {
+ const { code } = compileWithBindingMetadata(`
{{ literal }}
`, {
+ inline: true,
+ })
+ expect(code).toMatch(`toDisplayString(literal)`)
+ // #7973 should skip patch for literal const
+ expect(code).not.toMatch(
+ `${PatchFlags.TEXT} /* ${PatchFlagNames[PatchFlags.TEXT]} */`,
+ )
+ })
+
+ test('literal const handling, non-inline mode', () => {
+ const { code } = compileWithBindingMetadata(`
{{ literal }}
`)
+ expect(code).toMatch(`toDisplayString($setup.literal)`)
+ // #7973 should skip patch for literal const
+ expect(code).not.toMatch(
+ `${PatchFlags.TEXT} /* ${PatchFlagNames[PatchFlags.TEXT]} */`,
+ )
+ })
+
+ test('reactive const handling', () => {
+ const { code } = compileWithBindingMetadata(`
{{ reactive }}
`, {
+ inline: true,
+ })
+ // #7973 should not skip patch for reactive const
+ expect(code).toMatch(
+ `${PatchFlags.TEXT} /* ${PatchFlagNames[PatchFlags.TEXT]} */`,
+ )
+ })
+
+ // #10754
+ test('await expression in right hand of assignment, inline mode', () => {
+ const node = parseWithExpressionTransform(
+ `{{ (async () => { x = await bar })() }}`,
+ {
+ inline: true,
+ bindingMetadata: {
+ x: BindingTypes.SETUP_LET,
+ bar: BindingTypes.SETUP_CONST,
+ },
+ },
+ ) as InterpolationNode
+ expect(node.content).toMatchObject({
+ type: NodeTypes.COMPOUND_EXPRESSION,
+ children: [
+ `(async () => { `,
+ {
+ content: `_isRef(x) ? x.value = await bar : x`,
+ },
+ ` = await `,
+ {
+ content: `bar`,
+ },
+ ` })()`,
+ ],
+ })
+ })
})
})
diff --git a/packages/compiler-core/__tests__/transforms/transformSlotOutlet.spec.ts b/packages/compiler-core/__tests__/transforms/transformSlotOutlet.spec.ts
index fd5bd09c0f1..6420bdbbdac 100644
--- a/packages/compiler-core/__tests__/transforms/transformSlotOutlet.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformSlotOutlet.spec.ts
@@ -1,10 +1,10 @@
import {
- CompilerOptions,
+ type CompilerOptions,
+ type ElementNode,
+ ErrorCodes,
+ NodeTypes,
baseParse as parse,
transform,
- ElementNode,
- NodeTypes,
- ErrorCodes
} from '../../src'
import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn'
@@ -19,13 +19,13 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
nodeTransforms: [
...(options.prefixIdentifiers ? [transformExpression] : []),
transformSlotOutlet,
- transformElement
+ transformElement,
],
directiveTransforms: {
on: transformOn,
- bind: transformBind
+ bind: transformBind,
},
- ...options
+ ...options,
})
return ast
}
@@ -36,7 +36,7 @@ describe('compiler: transform
outlets', () => {
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
- arguments: [`$slots`, `"default"`]
+ arguments: [`$slots`, `"default"`],
})
})
@@ -45,7 +45,7 @@ describe('compiler: transform outlets', () => {
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
- arguments: [`$slots`, `"foo"`]
+ arguments: [`$slots`, `"foo"`],
})
})
@@ -59,15 +59,15 @@ describe('compiler: transform outlets', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `foo`,
- isStatic: false
- }
- ]
+ isStatic: false,
+ },
+ ],
})
})
test('dynamically named slot outlet w/ prefixIdentifiers: true', () => {
const ast = parseWithSlots(` `, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -80,23 +80,23 @@ describe('compiler: transform outlets', () => {
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_ctx.foo`,
- isStatic: false
+ isStatic: false,
},
` + `,
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_ctx.bar`,
- isStatic: false
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ ],
+ },
+ ],
})
})
test('default slot outlet with props', () => {
const ast = parseWithSlots(
- ` `
+ ` `,
)
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
@@ -110,36 +110,36 @@ describe('compiler: transform outlets', () => {
{
key: {
content: `foo`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `bar`,
- isStatic: true
- }
+ isStatic: true,
+ },
},
{
key: {
content: `baz`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `qux`,
- isStatic: false
- }
+ isStatic: false,
+ },
},
{
key: {
content: `fooBar`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `foo-bar`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
@@ -158,26 +158,26 @@ describe('compiler: transform outlets', () => {
{
key: {
content: `foo`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `bar`,
- isStatic: true
- }
+ isStatic: true,
+ },
},
{
key: {
content: `baz`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `qux`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
@@ -196,26 +196,26 @@ describe('compiler: transform outlets', () => {
{
key: {
content: `foo`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `bar`,
- isStatic: true
- }
+ isStatic: true,
+ },
},
{
key: {
content: `baz`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `qux`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
@@ -234,11 +234,11 @@ describe('compiler: transform outlets', () => {
returns: [
{
type: NodeTypes.ELEMENT,
- tag: `div`
- }
- ]
- }
- ]
+ tag: `div`,
+ },
+ ],
+ },
+ ],
})
})
@@ -257,11 +257,11 @@ describe('compiler: transform outlets', () => {
returns: [
{
type: NodeTypes.ELEMENT,
- tag: `div`
- }
- ]
- }
- ]
+ tag: `div`,
+ },
+ ],
+ },
+ ],
})
})
@@ -279,14 +279,14 @@ describe('compiler: transform outlets', () => {
{
key: {
content: `foo`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `bar`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
},
{
type: NodeTypes.JS_FUNCTION_EXPRESSION,
@@ -294,11 +294,11 @@ describe('compiler: transform outlets', () => {
returns: [
{
type: NodeTypes.ELEMENT,
- tag: `div`
- }
- ]
- }
- ]
+ tag: `div`,
+ },
+ ],
+ },
+ ],
})
})
@@ -316,14 +316,14 @@ describe('compiler: transform outlets', () => {
{
key: {
content: `foo`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `bar`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
},
{
type: NodeTypes.JS_FUNCTION_EXPRESSION,
@@ -331,11 +331,11 @@ describe('compiler: transform outlets', () => {
returns: [
{
type: NodeTypes.ELEMENT,
- tag: `div`
- }
- ]
- }
- ]
+ tag: `div`,
+ },
+ ],
+ },
+ ],
})
})
@@ -344,11 +344,11 @@ describe('compiler: transform outlets', () => {
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
- arguments: [`$slots`, `"default"`, `{}`, `undefined`, `true`]
+ arguments: [`$slots`, `"default"`, `{}`, `undefined`, `true`],
})
const fallback = parseWithSlots(`fallback `, {
slotted: false,
- scopeId: 'foo'
+ scopeId: 'foo',
})
const child = {
@@ -357,37 +357,52 @@ describe('compiler: transform outlets', () => {
returns: [
{
type: NodeTypes.TEXT,
- content: `fallback`
- }
- ]
+ content: `fallback`,
+ },
+ ],
}
expect((fallback.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
- arguments: [`$slots`, `"default"`, `{}`, child, `true`]
+ arguments: [`$slots`, `"default"`, `{}`, child, `true`],
})
})
test(`error on unexpected custom directive on `, () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const source = ` `
parseWithSlots(source, { onError })
const index = source.indexOf('v-foo')
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET,
loc: {
- source: `v-foo`,
start: {
offset: index,
line: 1,
- column: index + 1
+ column: index + 1,
},
end: {
offset: index + 5,
line: 1,
- column: index + 6
- }
- }
+ column: index + 6,
+ },
+ },
+ })
+ })
+
+ test('dynamically named slot outlet with v-bind shorthand', () => {
+ const ast = parseWithSlots(` `)
+ expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: RENDER_SLOT,
+ arguments: [
+ `$slots`,
+ {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `name`,
+ isStatic: false,
+ },
+ ],
})
})
})
diff --git a/packages/compiler-core/__tests__/transforms/transformText.spec.ts b/packages/compiler-core/__tests__/transforms/transformText.spec.ts
index 6e321d145e5..1a6d6916a73 100644
--- a/packages/compiler-core/__tests__/transforms/transformText.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformText.spec.ts
@@ -1,11 +1,11 @@
import {
- CompilerOptions,
- baseParse as parse,
- transform,
+ type CompilerOptions,
+ type ElementNode,
+ type ForNode,
NodeTypes,
generate,
- ForNode,
- ElementNode
+ baseParse as parse,
+ transform,
} from '../../src'
import { transformFor } from '../../src/transforms/vFor'
import { transformText } from '../../src/transforms/transformText'
@@ -22,9 +22,9 @@ function transformWithTextOpt(template: string, options: CompilerOptions = {}) {
transformFor,
...(options.prefixIdentifiers ? [transformExpression] : []),
transformElement,
- transformText
+ transformText,
],
- ...options
+ ...options,
})
return ast
}
@@ -35,8 +35,8 @@ describe('compiler: transform text', () => {
expect(root.children[0]).toMatchObject({
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -51,8 +51,8 @@ describe('compiler: transform text', () => {
` + `,
{ type: NodeTypes.TEXT, content: ` bar ` },
` + `,
- { type: NodeTypes.INTERPOLATION, content: { content: `baz` } }
- ]
+ { type: NodeTypes.INTERPOLATION, content: { content: `baz` } },
+ ],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -75,12 +75,12 @@ describe('compiler: transform text', () => {
` + `,
{ type: NodeTypes.TEXT, content: ` bar ` },
` + `,
- { type: NodeTypes.INTERPOLATION, content: { content: `baz` } }
- ]
+ { type: NodeTypes.INTERPOLATION, content: { content: `baz` } },
+ ],
},
- genFlagText(PatchFlags.TEXT)
- ]
- }
+ genFlagText(PatchFlags.TEXT),
+ ],
+ },
})
expect(root.children[2].type).toBe(NodeTypes.ELEMENT)
expect(generate(root).code).toMatchSnapshot()
@@ -99,11 +99,11 @@ describe('compiler: transform text', () => {
arguments: [
{
type: NodeTypes.TEXT,
- content: `hello`
- }
+ content: `hello`,
+ },
// should have no flag
- ]
- }
+ ],
+ },
})
expect(root.children[2].type).toBe(NodeTypes.ELEMENT)
expect(generate(root).code).toMatchSnapshot()
@@ -111,7 +111,7 @@ describe('compiler: transform text', () => {
test('consecutive text mixed with elements', () => {
const root = transformWithTextOpt(
- `
{{ foo }} bar {{ baz }}
hello
`
+ `
{{ foo }} bar {{ baz }}
hello
`,
)
expect(root.children.length).toBe(5)
expect(root.children[0].type).toBe(NodeTypes.ELEMENT)
@@ -128,12 +128,12 @@ describe('compiler: transform text', () => {
` + `,
{ type: NodeTypes.TEXT, content: ` bar ` },
` + `,
- { type: NodeTypes.INTERPOLATION, content: { content: `baz` } }
- ]
+ { type: NodeTypes.INTERPOLATION, content: { content: `baz` } },
+ ],
},
- genFlagText(PatchFlags.TEXT)
- ]
- }
+ genFlagText(PatchFlags.TEXT),
+ ],
+ },
})
expect(root.children[2].type).toBe(NodeTypes.ELEMENT)
expect(root.children[3]).toMatchObject({
@@ -144,10 +144,10 @@ describe('compiler: transform text', () => {
arguments: [
{
type: NodeTypes.TEXT,
- content: `hello`
- }
- ]
- }
+ content: `hello`,
+ },
+ ],
+ },
})
expect(root.children[4].type).toBe(NodeTypes.ELEMENT)
expect(generate(root).code).toMatchSnapshot()
@@ -155,21 +155,21 @@ describe('compiler: transform text', () => {
test('', () => {
const root = transformWithTextOpt(
- `foo `
+ `foo `,
)
expect(root.children[0].type).toBe(NodeTypes.FOR)
const forNode = root.children[0] as ForNode
// should convert template v-for text children because they are inside
// fragments
expect(forNode.children[0]).toMatchObject({
- type: NodeTypes.TEXT_CALL
+ type: NodeTypes.TEXT_CALL,
})
expect(generate(root).code).toMatchSnapshot()
})
test('with prefixIdentifiers: true', () => {
const root = transformWithTextOpt(`{{ foo }} bar {{ baz + qux }}`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(root.children.length).toBe(1)
expect(root.children[0]).toMatchObject({
@@ -183,15 +183,15 @@ describe('compiler: transform text', () => {
type: NodeTypes.INTERPOLATION,
content: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [{ content: `_ctx.baz` }, ` + `, { content: `_ctx.qux` }]
- }
- }
- ]
+ children: [{ content: `_ctx.baz` }, ` + `, { content: `_ctx.qux` }],
+ },
+ },
+ ],
})
expect(
generate(root, {
- prefixIdentifiers: true
- }).code
+ prefixIdentifiers: true,
+ }).code,
).toMatchSnapshot()
})
@@ -210,12 +210,12 @@ describe('compiler: transform text', () => {
type: NodeTypes.INTERPOLATION,
content: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'foo'
- }
+ content: 'foo',
+ },
},
- genFlagText(PatchFlags.TEXT)
- ]
- }
+ genFlagText(PatchFlags.TEXT),
+ ],
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
diff --git a/packages/compiler-core/__tests__/transforms/vBind.spec.ts b/packages/compiler-core/__tests__/transforms/vBind.spec.ts
index 27e0ae10c81..be063b8a9d5 100644
--- a/packages/compiler-core/__tests__/transforms/vBind.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vBind.spec.ts
@@ -1,37 +1,37 @@
import {
- baseParse as parse,
- transform,
- ElementNode,
- ObjectExpression,
- CompilerOptions,
+ type CallExpression,
+ type CompilerOptions,
+ type ElementNode,
ErrorCodes,
- VNodeCall,
NodeTypes,
- CallExpression
+ type ObjectExpression,
+ type VNodeCall,
+ baseParse as parse,
+ transform,
} from '../../src'
import { transformBind } from '../../src/transforms/vBind'
import { transformElement } from '../../src/transforms/transformElement'
import {
CAMELIZE,
+ NORMALIZE_PROPS,
helperNameMap,
- NORMALIZE_PROPS
} from '../../src/runtimeHelpers'
import { transformExpression } from '../../src/transforms/transformExpression'
function parseWithVBind(
template: string,
- options: CompilerOptions = {}
+ options: CompilerOptions = {},
): ElementNode {
const ast = parse(template)
transform(ast, {
nodeTransforms: [
...(options.prefixIdentifiers ? [transformExpression] : []),
- transformElement
+ transformElement,
],
directiveTransforms: {
- bind: transformBind
+ bind: transformBind,
},
- ...options
+ ...options,
})
return ast.children[0] as ElementNode
}
@@ -47,13 +47,13 @@ describe('compiler: transform v-bind', () => {
loc: {
start: {
line: 1,
- column: 13
+ column: 13,
},
end: {
line: 1,
- column: 15
- }
- }
+ column: 15,
+ },
+ },
},
value: {
content: `id`,
@@ -61,14 +61,52 @@ describe('compiler: transform v-bind', () => {
loc: {
start: {
line: 1,
- column: 17
+ column: 17,
},
end: {
line: 1,
- column: 19
- }
- }
- }
+ column: 19,
+ },
+ },
+ },
+ })
+ })
+
+ test('no expression', () => {
+ const node = parseWithVBind(`
`)
+ const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+ expect(props.properties[0]).toMatchObject({
+ key: {
+ content: `id`,
+ isStatic: true,
+ loc: {
+ start: { line: 1, column: 13, offset: 12 },
+ end: { line: 1, column: 15, offset: 14 },
+ },
+ },
+ value: {
+ content: `id`,
+ isStatic: false,
+ loc: {
+ start: { line: 1, column: 13, offset: 12 },
+ end: { line: 1, column: 15, offset: 14 },
+ },
+ },
+ })
+ })
+
+ test('no expression (shorthand)', () => {
+ const node = parseWithVBind(`
`)
+ const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+ expect(props.properties[0]).toMatchObject({
+ key: {
+ content: `id`,
+ isStatic: true,
+ },
+ value: {
+ content: `id`,
+ isStatic: false,
+ },
})
})
@@ -85,45 +123,45 @@ describe('compiler: transform v-bind', () => {
{
key: {
content: `id || ""`,
- isStatic: false
+ isStatic: false,
},
value: {
content: `id`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
- test('should error if no expression', () => {
- const onError = jest.fn()
- const node = parseWithVBind(`
`, { onError })
+ test('should error if empty expression', () => {
+ const onError = vi.fn()
+ const node = parseWithVBind(`
`, { onError })
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_BIND_NO_EXPRESSION,
loc: {
start: {
line: 1,
- column: 6
+ column: 6,
},
end: {
line: 1,
- column: 16
- }
- }
+ column: 19,
+ },
+ },
})
expect(props.properties[0]).toMatchObject({
key: {
content: `arg`,
- isStatic: true
+ isStatic: true,
},
value: {
content: ``,
- isStatic: true
- }
+ isStatic: true,
+ },
})
})
@@ -133,12 +171,27 @@ describe('compiler: transform v-bind', () => {
expect(props.properties[0]).toMatchObject({
key: {
content: `fooBar`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `id`,
- isStatic: false
- }
+ isStatic: false,
+ },
+ })
+ })
+
+ test('.camel modifier w/ no expression', () => {
+ const node = parseWithVBind(`
`)
+ const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+ expect(props.properties[0]).toMatchObject({
+ key: {
+ content: `fooBar`,
+ isStatic: true,
+ },
+ value: {
+ content: `fooBar`,
+ isStatic: false,
+ },
})
})
@@ -155,22 +208,22 @@ describe('compiler: transform v-bind', () => {
{
key: {
content: `_${helperNameMap[CAMELIZE]}(foo || "")`,
- isStatic: false
+ isStatic: false,
},
value: {
content: `id`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
test('.camel modifier w/ dynamic arg + prefixIdentifiers', () => {
const node = parseWithVBind(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
const props = (node.codegenNode as VNodeCall).props as CallExpression
expect(props).toMatchObject({
@@ -190,17 +243,17 @@ describe('compiler: transform v-bind', () => {
{ content: `_ctx.bar` },
`)`,
`) || ""`,
- `)`
- ]
+ `)`,
+ ],
},
value: {
content: `_ctx.id`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
@@ -210,12 +263,27 @@ describe('compiler: transform v-bind', () => {
expect(props.properties[0]).toMatchObject({
key: {
content: `.fooBar`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `id`,
- isStatic: false
- }
+ isStatic: false,
+ },
+ })
+ })
+
+ test('.prop modifier w/ no expression', () => {
+ const node = parseWithVBind(`
`)
+ const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+ expect(props.properties[0]).toMatchObject({
+ key: {
+ content: `.fooBar`,
+ isStatic: true,
+ },
+ value: {
+ content: `fooBar`,
+ isStatic: false,
+ },
})
})
@@ -232,22 +300,22 @@ describe('compiler: transform v-bind', () => {
{
key: {
content: '`.${fooBar || ""}`',
- isStatic: false
+ isStatic: false,
},
value: {
content: `id`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
test('.prop modifier w/ dynamic arg + prefixIdentifiers', () => {
const node = parseWithVBind(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
const props = (node.codegenNode as VNodeCall).props as CallExpression
expect(props).toMatchObject({
@@ -267,17 +335,17 @@ describe('compiler: transform v-bind', () => {
{ content: `_ctx.bar` },
`)`,
`) || ""`,
- `)`
- ]
+ `)`,
+ ],
},
value: {
content: `_ctx.id`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
})
@@ -287,12 +355,27 @@ describe('compiler: transform v-bind', () => {
expect(props.properties[0]).toMatchObject({
key: {
content: `.fooBar`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `id`,
- isStatic: false
- }
+ isStatic: false,
+ },
+ })
+ })
+
+ test('.prop modifier (shortband) w/ no expression', () => {
+ const node = parseWithVBind(`
`)
+ const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+ expect(props.properties[0]).toMatchObject({
+ key: {
+ content: `.fooBar`,
+ isStatic: true,
+ },
+ value: {
+ content: `fooBar`,
+ isStatic: false,
+ },
})
})
@@ -302,12 +385,45 @@ describe('compiler: transform v-bind', () => {
expect(props.properties[0]).toMatchObject({
key: {
content: `^foo-bar`,
- isStatic: true
+ isStatic: true,
},
value: {
content: `id`,
- isStatic: false
- }
+ isStatic: false,
+ },
+ })
+ })
+
+ test('.attr modifier w/ no expression', () => {
+ const node = parseWithVBind(`
`)
+ const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+ expect(props.properties[0]).toMatchObject({
+ key: {
+ content: `^foo-bar`,
+ isStatic: true,
+ },
+ value: {
+ content: `fooBar`,
+ isStatic: false,
+ },
+ })
+ })
+
+ test('error on invalid argument for same-name shorthand', () => {
+ const onError = vi.fn()
+ parseWithVBind(`
`, { onError })
+ expect(onError.mock.calls[0][0]).toMatchObject({
+ code: ErrorCodes.X_V_BIND_INVALID_SAME_NAME_ARGUMENT,
+ loc: {
+ start: {
+ line: 1,
+ column: 13,
+ },
+ end: {
+ line: 1,
+ column: 18,
+ },
+ },
})
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vFor.spec.ts b/packages/compiler-core/__tests__/transforms/vFor.spec.ts
index c22b364aa61..fead2476ac5 100644
--- a/packages/compiler-core/__tests__/transforms/vFor.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vFor.spec.ts
@@ -1,4 +1,4 @@
-import { baseParse as parse } from '../../src/parse'
+import { baseParse as parse } from '../../src/parser'
import { transform } from '../../src/transform'
import { transformIf } from '../../src/transforms/vIf'
import { transformFor } from '../../src/transforms/vFor'
@@ -7,24 +7,28 @@ import { transformElement } from '../../src/transforms/transformElement'
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
import { transformExpression } from '../../src/transforms/transformExpression'
import {
- ForNode,
+ ConstantTypes,
+ type ElementNode,
+ type ForCodegenNode,
+ type ForNode,
+ type InterpolationNode,
NodeTypes,
- SimpleExpressionNode,
- ElementNode,
- InterpolationNode,
- ForCodegenNode,
- ConstantTypes
+ type RootNode,
+ type SimpleExpressionNode,
} from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
-import { CompilerOptions, generate } from '../../src'
+import { type CompilerOptions, generate } from '../../src'
import { FRAGMENT, RENDER_LIST, RENDER_SLOT } from '../../src/runtimeHelpers'
import { PatchFlags } from '@vue/shared'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
-function parseWithForTransform(
+export function parseWithForTransform(
template: string,
- options: CompilerOptions = {}
-) {
+ options: CompilerOptions = {},
+): {
+ root: RootNode
+ node: ForNode & { codegenNode: ForCodegenNode }
+} {
const ast = parse(template, options)
transform(ast, {
nodeTransforms: [
@@ -32,16 +36,16 @@ function parseWithForTransform(
transformFor,
...(options.prefixIdentifiers ? [transformExpression] : []),
transformSlotOutlet,
- transformElement
+ transformElement,
],
directiveTransforms: {
- bind: transformBind
+ bind: transformBind,
},
- ...options
+ ...options,
})
return {
root: ast,
- node: ast.children[0] as ForNode & { codegenNode: ForCodegenNode }
+ node: ast.children[0] as ForNode & { codegenNode: ForCodegenNode },
}
}
@@ -49,7 +53,7 @@ describe('compiler: v-for', () => {
describe('transform', () => {
test('number expression', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
@@ -59,7 +63,7 @@ describe('compiler: v-for', () => {
test('value', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
@@ -69,31 +73,31 @@ describe('compiler: v-for', () => {
test('object de-structured value', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
expect((forNode.valueAlias as SimpleExpressionNode).content).toBe(
- '{ id, value }'
+ '{ id, value }',
)
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
})
test('array de-structured value', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
expect((forNode.valueAlias as SimpleExpressionNode).content).toBe(
- '[ id, value ]'
+ '[ id, value ]',
)
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
})
test('value and key', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).not.toBeUndefined()
expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
@@ -104,13 +108,13 @@ describe('compiler: v-for', () => {
test('value, key and index', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).not.toBeUndefined()
expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
- 'index'
+ 'index',
)
expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
@@ -118,12 +122,12 @@ describe('compiler: v-for', () => {
test('skipped key', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
- 'index'
+ 'index',
)
expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
@@ -131,12 +135,12 @@ describe('compiler: v-for', () => {
test('skipped value and key', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
- 'index'
+ 'index',
)
expect(forNode.valueAlias).toBeUndefined()
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
@@ -144,7 +148,7 @@ describe('compiler: v-for', () => {
test('unbracketed value', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
@@ -154,7 +158,7 @@ describe('compiler: v-for', () => {
test('unbracketed value and key', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).not.toBeUndefined()
expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
@@ -165,13 +169,13 @@ describe('compiler: v-for', () => {
test('unbracketed value, key and index', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).not.toBeUndefined()
expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
- 'index'
+ 'index',
)
expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
@@ -179,12 +183,12 @@ describe('compiler: v-for', () => {
test('unbracketed skipped key', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
- 'index'
+ 'index',
)
expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
@@ -192,94 +196,118 @@ describe('compiler: v-for', () => {
test('unbracketed skipped value and key', () => {
const { node: forNode } = parseWithForTransform(
- ' '
+ ' ',
)
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
- 'index'
+ 'index',
)
expect(forNode.valueAlias).toBeUndefined()
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
})
+
+ test('source containing string expression with spaces', () => {
+ const { node: forNode } = parseWithForTransform(
+ ` `,
+ )
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('item')
+ expect((forNode.source as SimpleExpressionNode).content).toBe(
+ "state ['my items']",
+ )
+ })
})
describe('errors', () => {
test('missing expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithForTransform(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_FOR_NO_EXPRESSION
- })
+ code: ErrorCodes.X_V_FOR_NO_EXPRESSION,
+ }),
)
})
test('empty expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithForTransform(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION
- })
+ code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION,
+ }),
)
})
test('invalid expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithForTransform(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION
- })
+ code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION,
+ }),
)
})
test('missing source', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithForTransform(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION
- })
+ code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION,
+ }),
+ )
+ })
+
+ test('missing source and have multiple spaces with', () => {
+ const onError = vi.fn()
+ parseWithForTransform(' ', { onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION,
+ }),
)
})
test('missing value', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithForTransform(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION
- })
+ code: ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION,
+ }),
)
})
test(' key placement', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithForTransform(
`
`,
- { onError }
+ { onError },
)
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT
- })
+ code: ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT,
+ }),
)
// should not warn on nested v-for keys
@@ -288,7 +316,7 @@ describe('compiler: v-for', () => {
`,
- { onError }
+ { onError },
)
expect(onError).toHaveBeenCalledTimes(1)
})
@@ -315,7 +343,7 @@ describe('compiler: v-for', () => {
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
expect(forNode.source.loc.end.line).toBe(1)
expect(forNode.source.loc.end.column).toBe(
- itemsOffset + 1 + `items`.length
+ itemsOffset + 1 + `items`.length,
)
})
@@ -339,7 +367,7 @@ describe('compiler: v-for', () => {
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
expect(forNode.source.loc.end.line).toBe(1)
expect(forNode.source.loc.end.column).toBe(
- itemsOffset + 1 + `items`.length
+ itemsOffset + 1 + `items`.length,
)
})
@@ -363,7 +391,7 @@ describe('compiler: v-for', () => {
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
expect(forNode.source.loc.end.line).toBe(1)
expect(forNode.source.loc.end.column).toBe(
- itemsOffset + 1 + `items`.length
+ itemsOffset + 1 + `items`.length,
)
})
@@ -405,7 +433,7 @@ describe('compiler: v-for', () => {
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
expect(forNode.source.loc.end.line).toBe(1)
expect(forNode.source.loc.end.column).toBe(
- itemsOffset + 1 + `items`.length
+ itemsOffset + 1 + `items`.length,
)
})
@@ -438,7 +466,7 @@ describe('compiler: v-for', () => {
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
expect(forNode.source.loc.end.line).toBe(1)
expect(forNode.source.loc.end.column).toBe(
- itemsOffset + 1 + `items`.length
+ itemsOffset + 1 + `items`.length,
)
})
})
@@ -446,18 +474,18 @@ describe('compiler: v-for', () => {
describe('prefixIdentifiers: true', () => {
test('should prefix v-for source', () => {
const { node } = parseWithForTransform(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(node.source).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.list`
+ content: `_ctx.list`,
})
})
test('should prefix v-for source w/ complex expression', () => {
const { node } = parseWithForTransform(
`
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(node.source).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -467,31 +495,31 @@ describe('compiler: v-for', () => {
{ content: `concat` },
`([`,
{ content: `_ctx.foo` },
- `])`
- ]
+ `])`,
+ ],
})
})
test('should not prefix v-for alias', () => {
const { node } = parseWithForTransform(
`{{ i }}{{ j }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
const div = node.children[0] as ElementNode
expect((div.children[0] as InterpolationNode).content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `i`
+ content: `i`,
})
expect((div.children[1] as InterpolationNode).content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.j`
+ content: `_ctx.j`,
})
})
test('should not prefix v-for aliases (multiple)', () => {
const { node } = parseWithForTransform(
`{{ i + j + k }}{{ l }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
const div = node.children[0] as ElementNode
expect((div.children[0] as InterpolationNode).content).toMatchObject({
@@ -501,23 +529,23 @@ describe('compiler: v-for', () => {
` + `,
{ content: `j` },
` + `,
- { content: `k` }
- ]
+ { content: `k` },
+ ],
})
expect((div.children[1] as InterpolationNode).content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.l`
+ content: `_ctx.l`,
})
})
test('should prefix id outside of v-for', () => {
const { node } = parseWithForTransform(
``,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect((node.children[1] as InterpolationNode).content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.i`
+ content: `_ctx.i`,
})
})
@@ -526,7 +554,7 @@ describe('compiler: v-for', () => {
``,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
const outerDiv = node.children[0] as ElementNode
const innerFor = outerDiv.children[0] as ForNode
@@ -534,7 +562,7 @@ describe('compiler: v-for', () => {
.children[0] as InterpolationNode
expect(innerExp.content).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [{ content: 'i' }, ` + `, { content: `_ctx.j` }]
+ children: [{ content: 'i' }, ` + `, { content: `_ctx.j` }],
})
// when an inner v-for shadows a variable of an outer v-for and exit,
@@ -542,7 +570,7 @@ describe('compiler: v-for', () => {
const outerExp = outerDiv.children[1] as InterpolationNode
expect(outerExp.content).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `i`
+ content: `i`,
})
})
@@ -551,7 +579,7 @@ describe('compiler: v-for', () => {
`
{{ foo + bar + baz + qux + quux }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(node.valueAlias!).toMatchObject({
type: NodeTypes.COMPOUND_EXPRESSION,
@@ -564,8 +592,8 @@ describe('compiler: v-for', () => {
{ content: `qux` },
` = `,
{ content: `_ctx.quux` },
- `] }`
- ]
+ `] }`,
+ ],
})
const div = node.children[0] as ElementNode
expect((div.children[0] as InterpolationNode).content).toMatchObject({
@@ -579,17 +607,17 @@ describe('compiler: v-for', () => {
` + `,
{ content: `qux` },
` + `,
- { content: `_ctx.quux` }
- ]
+ { content: `_ctx.quux` },
+ ],
})
})
test('element v-for key expression prefixing', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
'test
',
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
const innerBlock = codegenNode.children.arguments[1].returns
expect(innerBlock).toMatchObject({
@@ -604,20 +632,20 @@ describe('compiler: v-for', () => {
`(`,
// should NOT prefix in scope variables
{ content: `item` },
- `)`
- ]
- }
- })
+ `)`,
+ ],
+ },
+ }),
})
})
// #2085
test('template v-for key expression prefixing', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
'test ',
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
const innerBlock = codegenNode.children.arguments[1].returns
expect(innerBlock).toMatchObject({
@@ -632,19 +660,19 @@ describe('compiler: v-for', () => {
`(`,
// should NOT prefix in scope variables
{ content: `item` },
- `)`
- ]
- }
- })
+ `)`,
+ ],
+ },
+ }),
})
})
test('template v-for key no prefixing on attribute key', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
'test ',
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
const innerBlock = codegenNode.children.arguments[1].returns
expect(innerBlock).toMatchObject({
@@ -653,9 +681,9 @@ describe('compiler: v-for', () => {
props: createObjectMatcher({
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'key'
- }
- })
+ content: 'key',
+ },
+ }),
})
})
})
@@ -665,17 +693,17 @@ describe('compiler: v-for', () => {
node: ForCodegenNode,
keyed: boolean = false,
customReturn: boolean = false,
- disableTracking: boolean = true
+ disableTracking: boolean = true,
) {
expect(node).toMatchObject({
type: NodeTypes.VNODE_CALL,
tag: FRAGMENT,
disableTracking,
patchFlag: !disableTracking
- ? genFlagText(PatchFlags.STABLE_FRAGMENT)
+ ? PatchFlags.STABLE_FRAGMENT
: keyed
- ? genFlagText(PatchFlags.KEYED_FRAGMENT)
- : genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ ? PatchFlags.KEYED_FRAGMENT
+ : PatchFlags.UNKEYED_FRAGMENT,
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
@@ -687,32 +715,34 @@ describe('compiler: v-for', () => {
? {}
: {
type: NodeTypes.VNODE_CALL,
- isBlock: disableTracking
- }
- }
- ]
- }
+ isBlock: disableTracking,
+ },
+ },
+ ],
+ },
})
const renderListArgs = node.children.arguments
return {
source: renderListArgs[0] as SimpleExpressionNode,
params: (renderListArgs[1] as any).params,
returns: (renderListArgs[1] as any).returns,
- innerVNodeCall: customReturn ? null : (renderListArgs[1] as any).returns
+ innerVNodeCall: customReturn
+ ? null
+ : (renderListArgs[1] as any).returns,
}
}
test('basic v-for', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` },
params: [{ content: `item` }],
innerVNodeCall: {
- tag: `"span"`
- }
+ tag: `"span"`,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -720,11 +750,11 @@ describe('compiler: v-for', () => {
test('value + key + index', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` },
- params: [{ content: `item` }, { content: `key` }, { content: `index` }]
+ params: [{ content: `item` }, { content: `key` }, { content: `index` }],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -732,11 +762,11 @@ describe('compiler: v-for', () => {
test('skipped value', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` },
- params: [{ content: `_` }, { content: `key` }, { content: `index` }]
+ params: [{ content: `_` }, { content: `key` }, { content: `index` }],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -744,11 +774,11 @@ describe('compiler: v-for', () => {
test('skipped key', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` },
- params: [{ content: `item` }, { content: `__` }, { content: `index` }]
+ params: [{ content: `item` }, { content: `__` }, { content: `index` }],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -756,11 +786,11 @@ describe('compiler: v-for', () => {
test('skipped value & key', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` },
- params: [{ content: `_` }, { content: `__` }, { content: `index` }]
+ params: [{ content: `_` }, { content: `__` }, { content: `index` }],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -768,9 +798,9 @@ describe('compiler: v-for', () => {
test('v-for with constant expression', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform('{{item}}
', {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(
@@ -778,8 +808,8 @@ describe('compiler: v-for', () => {
codegenNode,
false /* keyed */,
false /* customReturn */,
- false /* disableTracking */
- )
+ false /* disableTracking */,
+ ),
).toMatchObject({
source: { content: `10`, constType: ConstantTypes.CAN_STRINGIFY },
params: [{ content: `item` }],
@@ -793,11 +823,11 @@ describe('compiler: v-for', () => {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'item',
isStatic: false,
- constType: ConstantTypes.NOT_CONSTANT
- }
+ constType: ConstantTypes.NOT_CONSTANT,
+ },
},
- patchFlag: genFlagText(PatchFlags.TEXT)
- }
+ patchFlag: PatchFlags.TEXT,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -805,9 +835,9 @@ describe('compiler: v-for', () => {
test('template v-for', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
- 'hello '
+ 'hello ',
)
expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` },
@@ -818,10 +848,10 @@ describe('compiler: v-for', () => {
isBlock: true,
children: [
{ type: NodeTypes.TEXT, content: `hello` },
- { type: NodeTypes.ELEMENT, tag: `span` }
+ { type: NodeTypes.ELEMENT, tag: `span` },
],
- patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT)
- }
+ patchFlag: PatchFlags.STABLE_FRAGMENT,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -829,19 +859,19 @@ describe('compiler: v-for', () => {
test('template v-for w/ ', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
- ' '
+ ' ',
)
expect(
- assertSharedCodegen(codegenNode, false, true /* custom return */)
+ assertSharedCodegen(codegenNode, false, true /* custom return */),
).toMatchObject({
source: { content: `items` },
params: [{ content: `item` }],
returns: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: RENDER_SLOT
- }
+ callee: RENDER_SLOT,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -850,9 +880,9 @@ describe('compiler: v-for', () => {
test('template v-for key injection with single child', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
- ' '
+ ' ',
)
expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
source: { content: `items` },
@@ -862,9 +892,9 @@ describe('compiler: v-for', () => {
tag: `"span"`,
props: createObjectMatcher({
key: '[item.id]',
- id: '[item.id]'
- })
- }
+ id: '[item.id]',
+ }),
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -872,17 +902,17 @@ describe('compiler: v-for', () => {
test('v-for on ', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(
- assertSharedCodegen(codegenNode, false, true /* custom return */)
+ assertSharedCodegen(codegenNode, false, true /* custom return */),
).toMatchObject({
source: { content: `items` },
params: [{ content: `item` }],
returns: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: RENDER_SLOT
- }
+ callee: RENDER_SLOT,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -890,7 +920,7 @@ describe('compiler: v-for', () => {
test('keyed v-for', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(' ')
expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
source: { content: `items` },
@@ -898,9 +928,9 @@ describe('compiler: v-for', () => {
innerVNodeCall: {
tag: `"span"`,
props: createObjectMatcher({
- key: `[item]`
- })
- }
+ key: `[item]`,
+ }),
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -908,9 +938,9 @@ describe('compiler: v-for', () => {
test('keyed template v-for', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(
- 'hello '
+ 'hello ',
)
expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
source: { content: `items` },
@@ -918,14 +948,14 @@ describe('compiler: v-for', () => {
innerVNodeCall: {
tag: FRAGMENT,
props: createObjectMatcher({
- key: `[item]`
+ key: `[item]`,
}),
children: [
{ type: NodeTypes.TEXT, content: `hello` },
- { type: NodeTypes.ELEMENT, tag: `span` }
+ { type: NodeTypes.ELEMENT, tag: `span` },
],
- patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT)
- }
+ patchFlag: PatchFlags.STABLE_FRAGMENT,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -933,7 +963,7 @@ describe('compiler: v-for', () => {
test('v-if + v-for', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(`
`)
expect(codegenNode).toMatchObject({
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
@@ -941,11 +971,11 @@ describe('compiler: v-for', () => {
consequent: {
type: NodeTypes.VNODE_CALL,
props: createObjectMatcher({
- key: `[0]`
+ key: `[0]`,
}),
isBlock: true,
disableTracking: true,
- patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
@@ -957,12 +987,12 @@ describe('compiler: v-for', () => {
returns: {
type: NodeTypes.VNODE_CALL,
tag: `"div"`,
- isBlock: true
- }
- }
- ]
- }
- }
+ isBlock: true,
+ },
+ },
+ ],
+ },
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -971,7 +1001,7 @@ describe('compiler: v-for', () => {
test('v-if + v-for on ', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform(` `)
expect(codegenNode).toMatchObject({
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
@@ -979,11 +1009,11 @@ describe('compiler: v-for', () => {
consequent: {
type: NodeTypes.VNODE_CALL,
props: createObjectMatcher({
- key: `[0]`
+ key: `[0]`,
}),
isBlock: true,
disableTracking: true,
- patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
@@ -995,12 +1025,12 @@ describe('compiler: v-for', () => {
returns: {
type: NodeTypes.VNODE_CALL,
tag: FRAGMENT,
- isBlock: true
- }
- }
- ]
- }
- }
+ isBlock: true,
+ },
+ },
+ ],
+ },
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -1008,14 +1038,40 @@ describe('compiler: v-for', () => {
test('v-for on element with custom directive', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithForTransform('
')
const { returns } = assertSharedCodegen(codegenNode, false, true)
expect(returns).toMatchObject({
type: NodeTypes.VNODE_CALL,
- directives: { type: NodeTypes.JS_ARRAY_EXPRESSION }
+ directives: { type: NodeTypes.JS_ARRAY_EXPRESSION },
})
expect(generate(root).code).toMatchSnapshot()
})
+
+ test('template v-for key w/ :key shorthand on div', () => {
+ const {
+ node: { codegenNode },
+ } = parseWithForTransform('test
')
+ expect(codegenNode.patchFlag).toBe(PatchFlags.KEYED_FRAGMENT)
+ })
+
+ test('template v-for key w/ :key shorthand on template injected to the child', () => {
+ const {
+ node: { codegenNode },
+ } = parseWithForTransform(
+ 'test
',
+ )
+ expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
+ source: { content: `keys` },
+ params: [{ content: `key` }],
+ innerVNodeCall: {
+ type: NodeTypes.VNODE_CALL,
+ tag: `"div"`,
+ props: createObjectMatcher({
+ key: '[key]',
+ }),
+ },
+ })
+ })
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vIf.spec.ts b/packages/compiler-core/__tests__/transforms/vIf.spec.ts
index 225f6d6082c..73b6e221554 100644
--- a/packages/compiler-core/__tests__/transforms/vIf.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vIf.spec.ts
@@ -1,29 +1,29 @@
-import { baseParse as parse } from '../../src/parse'
+import { baseParse as parse } from '../../src/parser'
import { transform } from '../../src/transform'
import { transformIf } from '../../src/transforms/vIf'
import { transformElement } from '../../src/transforms/transformElement'
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
import {
- CommentNode,
- ConditionalExpression,
- ElementNode,
+ type CommentNode,
+ type ConditionalExpression,
+ type ElementNode,
ElementTypes,
- IfBranchNode,
- IfConditionalExpression,
- IfNode,
+ type IfBranchNode,
+ type IfConditionalExpression,
+ type IfNode,
NodeTypes,
- SimpleExpressionNode,
- TextNode,
- VNodeCall
+ type SimpleExpressionNode,
+ type TextNode,
+ type VNodeCall,
} from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
-import { CompilerOptions, generate, TO_HANDLERS } from '../../src'
+import { type CompilerOptions, TO_HANDLERS, generate } from '../../src'
import {
CREATE_COMMENT,
FRAGMENT,
MERGE_PROPS,
NORMALIZE_PROPS,
- RENDER_SLOT
+ RENDER_SLOT,
} from '../../src/runtimeHelpers'
import { createObjectMatcher } from '../testUtils'
@@ -31,12 +31,12 @@ function parseWithIfTransform(
template: string,
options: CompilerOptions = {},
returnIndex: number = 0,
- childrenLen: number = 1
+ childrenLen: number = 1,
) {
const ast = parse(template, options)
transform(ast, {
nodeTransforms: [transformIf, transformSlotOutlet, transformElement],
- ...options
+ ...options,
})
if (!options.onError) {
expect(ast.children.length).toBe(childrenLen)
@@ -48,7 +48,7 @@ function parseWithIfTransform(
root: ast,
node: ast.children[returnIndex] as IfNode & {
codegenNode: IfConditionalExpression
- }
+ },
}
}
@@ -59,7 +59,7 @@ describe('compiler: v-if', () => {
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(1)
expect((node.branches[0].condition as SimpleExpressionNode).content).toBe(
- `ok`
+ `ok`,
)
expect(node.branches[0].children.length).toBe(1)
expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
@@ -68,12 +68,12 @@ describe('compiler: v-if', () => {
test('template v-if', () => {
const { node } = parseWithIfTransform(
- `
hello
`
+ `
hello
`,
)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(1)
expect((node.branches[0].condition as SimpleExpressionNode).content).toBe(
- `ok`
+ `ok`,
)
expect(node.branches[0].children.length).toBe(3)
expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
@@ -89,16 +89,16 @@ describe('compiler: v-if', () => {
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(1)
expect((node.branches[0].children[0] as ElementNode).tag).toBe(
- `Component`
+ `Component`,
)
expect((node.branches[0].children[0] as ElementNode).tagType).toBe(
- ElementTypes.COMPONENT
+ ElementTypes.COMPONENT,
)
// #2058 since a component may fail to resolve and fallback to a plain
// element, it still needs to be made a block
expect(
((node.branches[0].children[0] as ElementNode)!
- .codegenNode as VNodeCall)!.isBlock
+ .codegenNode as VNodeCall)!.isBlock,
).toBe(true)
})
@@ -122,7 +122,7 @@ describe('compiler: v-if', () => {
test('v-if + v-else-if', () => {
const { node } = parseWithIfTransform(
- `
`
+ `
`,
)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(2)
@@ -142,7 +142,7 @@ describe('compiler: v-if', () => {
test('v-if + v-else-if + v-else', () => {
const { node } = parseWithIfTransform(
- `
fine `
+ `
fine `,
)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(3)
@@ -202,125 +202,144 @@ describe('compiler: v-if', () => {
test('should prefix v-if condition', () => {
const { node } = parseWithIfTransform(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(node.branches[0].condition).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `_ctx.ok`
+ content: `_ctx.ok`,
})
})
})
describe('errors', () => {
test('error on v-else missing adjacent v-if', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const { node: node1 } = parseWithIfTransform(`
`, { onError })
expect(onError.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: node1.loc
- }
+ loc: node1.loc,
+ },
])
const { node: node2 } = parseWithIfTransform(
`
`,
{ onError },
- 1
+ 1,
)
expect(onError.mock.calls[1]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: node2.loc
- }
+ loc: node2.loc,
+ },
])
const { node: node3 } = parseWithIfTransform(
`
foo
`,
{ onError },
- 2
+ 2,
)
expect(onError.mock.calls[2]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: node3.loc
- }
+ loc: node3.loc,
+ },
])
})
test('error on v-else-if missing adjacent v-if or v-else-if', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const { node: node1 } = parseWithIfTransform(`
`, {
- onError
+ onError,
})
expect(onError.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: node1.loc
- }
+ loc: node1.loc,
+ },
])
const { node: node2 } = parseWithIfTransform(
`
`,
{ onError },
- 1
+ 1,
)
expect(onError.mock.calls[1]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: node2.loc
- }
+ loc: node2.loc,
+ },
])
const { node: node3 } = parseWithIfTransform(
`
foo
`,
{ onError },
- 2
+ 2,
)
expect(onError.mock.calls[2]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: node3.loc
- }
+ loc: node3.loc,
+ },
])
const {
- node: { branches }
+ node: { branches },
} = parseWithIfTransform(
`
`,
{ onError },
- 0
+ 0,
)
expect(onError.mock.calls[3]).toMatchObject([
{
code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
- loc: branches[branches.length - 1].loc
- }
+ loc: branches[branches.length - 1].loc,
+ },
+ ])
+ })
+
+ test('error on adjacent v-else', () => {
+ const onError = vi.fn()
+
+ const {
+ node: { branches },
+ } = parseWithIfTransform(
+ `
`,
+ { onError },
+ 0,
+ )
+
+ expect(onError.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
+ loc: branches[branches.length - 1].loc,
+ },
])
})
test('error on user key', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
// dynamic
parseWithIfTransform(
`
`,
- { onError }
+ { onError },
)
expect(onError.mock.calls[0]).toMatchObject([
{
- code: ErrorCodes.X_V_IF_SAME_KEY
- }
+ code: ErrorCodes.X_V_IF_SAME_KEY,
+ },
])
// static
parseWithIfTransform(`
`, {
- onError
+ onError,
})
expect(onError.mock.calls[1]).toMatchObject([
{
- code: ErrorCodes.X_V_IF_SAME_KEY
- }
+ code: ErrorCodes.X_V_IF_SAME_KEY,
+ },
])
})
})
@@ -329,63 +348,63 @@ describe('compiler: v-if', () => {
function assertSharedCodegen(
node: IfConditionalExpression,
depth: number = 0,
- hasElse: boolean = false
+ hasElse: boolean = false,
) {
expect(node).toMatchObject({
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
test: {
- content: `ok`
+ content: `ok`,
},
consequent: {
type: NodeTypes.VNODE_CALL,
- isBlock: true
+ isBlock: true,
},
alternate:
depth < 1
? hasElse
? {
type: NodeTypes.VNODE_CALL,
- isBlock: true
+ isBlock: true,
}
: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_COMMENT
+ callee: CREATE_COMMENT,
}
: {
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
test: {
- content: `orNot`
+ content: `orNot`,
},
consequent: {
type: NodeTypes.VNODE_CALL,
- isBlock: true
+ isBlock: true,
},
alternate: hasElse
? {
type: NodeTypes.VNODE_CALL,
- isBlock: true
+ isBlock: true,
}
: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_COMMENT
- }
- }
+ callee: CREATE_COMMENT,
+ },
+ },
})
}
test('basic v-if', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
assertSharedCodegen(codegenNode)
expect(codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
expect(codegenNode.alternate).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_COMMENT
+ callee: CREATE_COMMENT,
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -393,7 +412,7 @@ describe('compiler: v-if', () => {
test('template v-if', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
hello
`)
assertSharedCodegen(codegenNode)
expect(codegenNode.consequent).toMatchObject({
@@ -402,12 +421,12 @@ describe('compiler: v-if', () => {
children: [
{ type: NodeTypes.ELEMENT, tag: 'div' },
{ type: NodeTypes.TEXT, content: `hello` },
- { type: NodeTypes.ELEMENT, tag: 'p' }
- ]
+ { type: NodeTypes.ELEMENT, tag: 'p' },
+ ],
})
expect(codegenNode.alternate).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_COMMENT
+ callee: CREATE_COMMENT,
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -415,12 +434,12 @@ describe('compiler: v-if', () => {
test('template v-if w/ single child', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(` `)
expect(codegenNode.consequent).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
- arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })]
+ arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -428,12 +447,12 @@ describe('compiler: v-if', () => {
test('v-if on ', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(` `)
expect(codegenNode.consequent).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
- arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })]
+ arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -441,16 +460,16 @@ describe('compiler: v-if', () => {
test('v-if + v-else', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
assertSharedCodegen(codegenNode, 0, true)
expect(codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
expect(codegenNode.alternate).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[1]` })
+ props: createObjectMatcher({ key: `[1]` }),
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -458,17 +477,17 @@ describe('compiler: v-if', () => {
test('v-if + v-else-if', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
assertSharedCodegen(codegenNode, 1)
expect(codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
const branch2 = codegenNode.alternate as ConditionalExpression
expect(branch2.consequent).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[1]` })
+ props: createObjectMatcher({ key: `[1]` }),
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -476,19 +495,19 @@ describe('compiler: v-if', () => {
test('v-if + v-else-if + v-else', () => {
const {
root,
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(
- `
fine `
+ `
fine `,
)
assertSharedCodegen(codegenNode, 1, true)
expect(codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
const branch2 = codegenNode.alternate as ConditionalExpression
expect(branch2.consequent).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[1]` })
+ props: createObjectMatcher({ key: `[1]` }),
})
expect(branch2.alternate).toMatchObject({
tag: FRAGMENT,
@@ -496,9 +515,9 @@ describe('compiler: v-if', () => {
children: [
{
type: NodeTypes.TEXT,
- content: `fine`
- }
- ]
+ content: `fine`,
+ },
+ ],
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -508,7 +527,7 @@ describe('compiler: v-if', () => {
`
`,
{},
0 /* returnIndex, just give the default value */,
- 2 /* childrenLen */
+ 2 /* childrenLen */,
)
const ifNode = root.children[0] as IfNode & {
@@ -516,14 +535,14 @@ describe('compiler: v-if', () => {
}
expect(ifNode.codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
const ifNode2 = root.children[1] as IfNode & {
codegenNode: IfConditionalExpression
}
expect(ifNode2.codegenNode.consequent).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[1]` })
+ props: createObjectMatcher({ key: `[1]` }),
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -533,41 +552,41 @@ describe('compiler: v-if', () => {
`
`,
{},
0 /* returnIndex, just give the default value */,
- 2 /* childrenLen */
+ 2 /* childrenLen */,
)
const ifNode = root.children[0] as IfNode & {
codegenNode: IfConditionalExpression
}
expect(ifNode.codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
expect(ifNode.codegenNode.alternate).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[1]` })
+ props: createObjectMatcher({ key: `[1]` }),
})
const ifNode2 = root.children[1] as IfNode & {
codegenNode: IfConditionalExpression
}
expect(ifNode2.codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[2]` })
+ props: createObjectMatcher({ key: `[2]` }),
})
const branch = ifNode2.codegenNode.alternate as IfConditionalExpression
expect(branch.consequent).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[3]` })
+ props: createObjectMatcher({ key: `[3]` }),
})
expect(branch.alternate).toMatchObject({
tag: `"p"`,
- props: createObjectMatcher({ key: `[4]` })
+ props: createObjectMatcher({ key: `[4]` }),
})
expect(generate(root).code).toMatchSnapshot()
})
test('key injection (only v-bind)', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
const branch1 = codegenNode.consequent as VNodeCall
expect(branch1.props).toMatchObject({
@@ -577,15 +596,18 @@ describe('compiler: v-if', () => {
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS,
- arguments: [createObjectMatcher({ key: `[0]` }), { content: `obj` }]
- }
- ]
+ arguments: [
+ createObjectMatcher({ key: `[0]` }),
+ { content: `obj` },
+ ],
+ },
+ ],
})
})
test('key injection (before v-bind)', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
const branch1 = codegenNode.consequent as VNodeCall
expect(branch1.props).toMatchObject({
@@ -594,16 +616,16 @@ describe('compiler: v-if', () => {
arguments: [
createObjectMatcher({
key: '[0]',
- id: 'foo'
+ id: 'foo',
}),
- { content: `obj` }
- ]
+ { content: `obj` },
+ ],
})
})
test('key injection (after v-bind)', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
const branch1 = codegenNode.consequent as VNodeCall
expect(branch1.props).toMatchObject({
@@ -613,15 +635,15 @@ describe('compiler: v-if', () => {
createObjectMatcher({ key: `[0]` }),
{ content: `obj` },
createObjectMatcher({
- id: 'foo'
- })
- ]
+ id: 'foo',
+ }),
+ ],
})
})
test('key injection (w/ custom directive)', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
const branch1 = codegenNode.consequent as VNodeCall
expect(branch1.directives).not.toBeUndefined()
@@ -631,7 +653,7 @@ describe('compiler: v-if', () => {
// #6631
test('avoid duplicate keys', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(`
`)
const branch1 = codegenNode.consequent as VNodeCall
expect(branch1.props).toMatchObject({
@@ -639,31 +661,31 @@ describe('compiler: v-if', () => {
callee: MERGE_PROPS,
arguments: [
createObjectMatcher({
- key: 'custom_key'
+ key: 'custom_key',
}),
- { content: `obj` }
- ]
+ { content: `obj` },
+ ],
})
})
test('with spaces between branches', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(
- `
`
+ `
`,
)
expect(codegenNode.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[0]` })
+ props: createObjectMatcher({ key: `[0]` }),
})
const branch = codegenNode.alternate as ConditionalExpression
expect(branch.consequent).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[1]` })
+ props: createObjectMatcher({ key: `[1]` }),
})
expect(branch.alternate).toMatchObject({
tag: `"div"`,
- props: createObjectMatcher({ key: `[2]` })
+ props: createObjectMatcher({ key: `[2]` }),
})
})
@@ -729,7 +751,7 @@ describe('compiler: v-if', () => {
`,
- { comments: true }
+ { comments: true },
)
__DEV__ = true
})
@@ -737,21 +759,21 @@ describe('compiler: v-if', () => {
test('v-on with v-if', () => {
const {
- node: { codegenNode }
+ node: { codegenNode },
} = parseWithIfTransform(
- `w/ v-if `
+ `w/ v-if `,
)
expect((codegenNode.consequent as any).props.type).toBe(
- NodeTypes.JS_CALL_EXPRESSION
+ NodeTypes.JS_CALL_EXPRESSION,
)
expect((codegenNode.consequent as any).props.callee).toBe(MERGE_PROPS)
expect(
(codegenNode.consequent as any).props.arguments[0].properties[0].value
- .content
+ .content,
).toBe('0')
expect((codegenNode.consequent as any).props.arguments[1].callee).toBe(
- TO_HANDLERS
+ TO_HANDLERS,
)
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vMemo.spec.ts b/packages/compiler-core/__tests__/transforms/vMemo.spec.ts
index 1b259f7ca68..41e7d922ebe 100644
--- a/packages/compiler-core/__tests__/transforms/vMemo.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vMemo.spec.ts
@@ -4,7 +4,7 @@ describe('compiler: v-memo transform', () => {
function compile(content: string) {
return baseCompile(`${content}
`, {
mode: 'module',
- prefixIdentifiers: true
+ prefixIdentifiers: true,
}).code
}
@@ -12,8 +12,8 @@ describe('compiler: v-memo transform', () => {
expect(
baseCompile(`
`, {
mode: 'module',
- prefixIdentifiers: true
- }).code
+ prefixIdentifiers: true,
+ }).code,
).toMatchSnapshot()
})
@@ -29,8 +29,8 @@ describe('compiler: v-memo transform', () => {
expect(
compile(
`foo bar
- `
- )
+ `,
+ ),
).toMatchSnapshot()
})
@@ -39,8 +39,8 @@ describe('compiler: v-memo transform', () => {
compile(
`
foobar
-
`
- )
+ `,
+ ),
).toMatchSnapshot()
})
@@ -49,8 +49,16 @@ describe('compiler: v-memo transform', () => {
compile(
`
foobar
- `
- )
+ `,
+ ),
+ ).toMatchSnapshot()
+ })
+
+ test('element v-for key expression prefixing + v-memo', () => {
+ expect(
+ compile(
+ `
`,
+ ),
).toMatchSnapshot()
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vModel.spec.ts b/packages/compiler-core/__tests__/transforms/vModel.spec.ts
index 808fb94215e..82dd4909fd6 100644
--- a/packages/compiler-core/__tests__/transforms/vModel.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vModel.spec.ts
@@ -1,17 +1,17 @@
import {
+ BindingTypes,
+ type CompilerOptions,
+ type ComponentNode,
+ type ElementNode,
+ type ForNode,
+ NORMALIZE_PROPS,
+ NodeTypes,
+ type ObjectExpression,
+ type PlainElementNode,
+ type VNodeCall,
+ generate,
baseParse as parse,
transform,
- generate,
- ElementNode,
- ObjectExpression,
- CompilerOptions,
- ForNode,
- PlainElementNode,
- ComponentNode,
- NodeTypes,
- VNodeCall,
- NORMALIZE_PROPS,
- BindingTypes
} from '../../src'
import { ErrorCodes } from '../../src/errors'
import { transformModel } from '../../src/transforms/vModel'
@@ -19,7 +19,7 @@ import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
import { transformFor } from '../../src/transforms/vFor'
import { trackSlotScopes } from '../../src/transforms/vSlot'
-import { CallExpression } from '@babel/types'
+import type { CallExpression } from '@babel/types'
function parseWithVModel(template: string, options: CompilerOptions = {}) {
const ast = parse(template)
@@ -29,13 +29,13 @@ function parseWithVModel(template: string, options: CompilerOptions = {}) {
transformFor,
transformExpression,
transformElement,
- trackSlotScopes
+ trackSlotScopes,
],
directiveTransforms: {
...options.directiveTransforms,
- model: transformModel
+ model: transformModel,
},
- ...options
+ ...options,
})
return ast
@@ -51,29 +51,29 @@ describe('compiler: transform v-model', () => {
expect(props[0]).toMatchObject({
key: {
content: 'modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'model',
- isStatic: false
- }
+ isStatic: false,
+ },
})
expect(props[1]).toMatchObject({
key: {
content: 'onUpdate:modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
'$event => ((',
{
content: 'model',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
+ ') = $event)',
+ ],
+ },
})
expect(generate(root).code).toMatchSnapshot()
@@ -81,7 +81,7 @@ describe('compiler: transform v-model', () => {
test('simple expression (with prefixIdentifiers)', () => {
const root = parseWithVModel('
', {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
const node = root.children[0] as ElementNode
const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
@@ -90,29 +90,29 @@ describe('compiler: transform v-model', () => {
expect(props[0]).toMatchObject({
key: {
content: 'modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
content: '_ctx.model',
- isStatic: false
- }
+ isStatic: false,
+ },
})
expect(props[1]).toMatchObject({
key: {
content: 'onUpdate:modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
'$event => ((',
{
content: '_ctx.model',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
+ ') = $event)',
+ ],
+ },
})
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
@@ -128,29 +128,29 @@ describe('compiler: transform v-model', () => {
expect(props[0]).toMatchObject({
key: {
content: 'modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
content: '\n model\n.\nfoo \n',
- isStatic: false
- }
+ isStatic: false,
+ },
})
expect(props[1]).toMatchObject({
key: {
content: 'onUpdate:modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
'$event => ((',
{
content: '\n model\n.\nfoo \n',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
+ ') = $event)',
+ ],
+ },
})
expect(generate(root).code).toMatchSnapshot()
@@ -165,29 +165,29 @@ describe('compiler: transform v-model', () => {
expect(props[0]).toMatchObject({
key: {
content: 'modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'model[index]',
- isStatic: false
- }
+ isStatic: false,
+ },
})
expect(props[1]).toMatchObject({
key: {
content: 'onUpdate:modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
'$event => ((',
{
content: 'model[index]',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
+ ') = $event)',
+ ],
+ },
})
expect(generate(root).code).toMatchSnapshot()
@@ -195,7 +195,7 @@ describe('compiler: transform v-model', () => {
test('compound expression (with prefixIdentifiers)', () => {
const root = parseWithVModel('
', {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
const node = root.children[0] as ElementNode
const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
@@ -204,28 +204,28 @@ describe('compiler: transform v-model', () => {
expect(props[0]).toMatchObject({
key: {
content: 'modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
{
content: '_ctx.model',
- isStatic: false
+ isStatic: false,
},
'[',
{
content: '_ctx.index',
- isStatic: false
+ isStatic: false,
},
- ']'
- ]
- }
+ ']',
+ ],
+ },
})
expect(props[1]).toMatchObject({
key: {
content: 'onUpdate:modelValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
@@ -234,19 +234,19 @@ describe('compiler: transform v-model', () => {
children: [
{
content: '_ctx.model',
- isStatic: false
+ isStatic: false,
},
'[',
{
content: '_ctx.index',
- isStatic: false
+ isStatic: false,
},
- ']'
- ]
+ ']',
+ ],
},
- ') = $event)'
- ]
- }
+ ') = $event)',
+ ],
+ },
})
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
@@ -260,29 +260,29 @@ describe('compiler: transform v-model', () => {
expect(props[0]).toMatchObject({
key: {
content: 'foo-value',
- isStatic: true
+ isStatic: true,
},
value: {
content: 'model',
- isStatic: false
- }
+ isStatic: false,
+ },
})
expect(props[1]).toMatchObject({
key: {
content: 'onUpdate:fooValue',
- isStatic: true
+ isStatic: true,
},
value: {
children: [
'$event => ((',
{
content: 'model',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
+ ') = $event)',
+ ],
+ },
})
expect(generate(root).code).toMatchSnapshot()
@@ -304,12 +304,12 @@ describe('compiler: transform v-model', () => {
{
key: {
content: 'value',
- isStatic: false
+ isStatic: false,
},
value: {
content: 'model',
- isStatic: false
- }
+ isStatic: false,
+ },
},
{
key: {
@@ -317,24 +317,24 @@ describe('compiler: transform v-model', () => {
'"onUpdate:" + ',
{
content: 'value',
- isStatic: false
- }
- ]
+ isStatic: false,
+ },
+ ],
},
value: {
children: [
'$event => ((',
{
content: 'model',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
- }
- ]
- }
- ]
+ ') = $event)',
+ ],
+ },
+ },
+ ],
+ },
+ ],
})
expect(generate(root).code).toMatchSnapshot()
@@ -342,7 +342,7 @@ describe('compiler: transform v-model', () => {
test('with dynamic argument (with prefixIdentifiers)', () => {
const root = parseWithVModel('
', {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
const node = root.children[0] as ElementNode
const props = (node.codegenNode as VNodeCall)
@@ -358,12 +358,12 @@ describe('compiler: transform v-model', () => {
{
key: {
content: '_ctx.value',
- isStatic: false
+ isStatic: false,
},
value: {
content: '_ctx.model',
- isStatic: false
- }
+ isStatic: false,
+ },
},
{
key: {
@@ -371,24 +371,24 @@ describe('compiler: transform v-model', () => {
'"onUpdate:" + ',
{
content: '_ctx.value',
- isStatic: false
- }
- ]
+ isStatic: false,
+ },
+ ],
},
value: {
children: [
'$event => ((',
{
content: '_ctx.model',
- isStatic: false
+ isStatic: false,
},
- ') = $event)'
- ]
- }
- }
- ]
- }
- ]
+ ') = $event)',
+ ],
+ },
+ },
+ ],
+ },
+ ],
})
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
@@ -397,15 +397,15 @@ describe('compiler: transform v-model', () => {
test('should cache update handler w/ cacheHandlers: true', () => {
const root = parseWithVModel('
', {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const codegen = (root.children[0] as PlainElementNode)
.codegenNode as VNodeCall
// should not list cached prop in dynamicProps
expect(codegen.dynamicProps).toBe(`["modelValue"]`)
expect((codegen.props as ObjectExpression).properties[1].value.type).toBe(
- NodeTypes.JS_CACHE_EXPRESSION
+ NodeTypes.JS_CACHE_EXPRESSION,
)
})
@@ -414,34 +414,34 @@ describe('compiler: transform v-model', () => {
'
',
{
prefixIdentifiers: true,
- cacheHandlers: true
- }
+ cacheHandlers: true,
+ },
)
- expect(root.cached).toBe(0)
+ expect(root.cached.length).toBe(0)
const codegen = (
(root.children[0] as ForNode).children[0] as PlainElementNode
).codegenNode as VNodeCall
expect(codegen.dynamicProps).toBe(`["modelValue", "onUpdate:modelValue"]`)
expect(
- (codegen.props as ObjectExpression).properties[1].value.type
+ (codegen.props as ObjectExpression).properties[1].value.type,
).not.toBe(NodeTypes.JS_CACHE_EXPRESSION)
})
test('should not cache update handler if it inside v-once', () => {
const root = parseWithVModel('
', {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
expect(root.cached).not.toBe(2)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
})
test('should mark update handler dynamic if it refers slot scope variables', () => {
const root = parseWithVModel(
'
',
{
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
const codegen = (
(root.children[0] as ComponentNode).children[0] as PlainElementNode
@@ -451,7 +451,7 @@ describe('compiler: transform v-model', () => {
test('should generate modelModifiers for component v-model', () => {
const root = parseWithVModel('
', {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
const vnodeCall = (root.children[0] as ComponentNode)
.codegenNode as VNodeCall
@@ -462,9 +462,12 @@ describe('compiler: transform v-model', () => {
{ key: { content: `onUpdate:modelValue` } },
{
key: { content: 'modelModifiers' },
- value: { content: `{ trim: true, "bar-baz": true }`, isStatic: false }
- }
- ]
+ value: {
+ content: `{ trim: true, "bar-baz": true }`,
+ isStatic: false,
+ },
+ },
+ ],
})
// should NOT include modelModifiers in dynamicPropNames because it's never
// gonna change
@@ -475,8 +478,8 @@ describe('compiler: transform v-model', () => {
const root = parseWithVModel(
'
',
{
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
const vnodeCall = (root.children[0] as ComponentNode)
.codegenNode as VNodeCall
@@ -487,96 +490,96 @@ describe('compiler: transform v-model', () => {
{ key: { content: `onUpdate:foo` } },
{
key: { content: 'fooModifiers' },
- value: { content: `{ trim: true }`, isStatic: false }
+ value: { content: `{ trim: true }`, isStatic: false },
},
{ key: { content: `bar` } },
{ key: { content: `onUpdate:bar` } },
{
key: { content: 'barModifiers' },
- value: { content: `{ number: true }`, isStatic: false }
- }
- ]
+ value: { content: `{ number: true }`, isStatic: false },
+ },
+ ],
})
// should NOT include modelModifiers in dynamicPropNames because it's never
// gonna change
expect(vnodeCall.dynamicProps).toBe(
- `["foo", "onUpdate:foo", "bar", "onUpdate:bar"]`
+ `["foo", "onUpdate:foo", "bar", "onUpdate:bar"]`,
)
})
describe('errors', () => {
test('missing expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVModel('
', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_MODEL_NO_EXPRESSION
- })
+ code: ErrorCodes.X_V_MODEL_NO_EXPRESSION,
+ }),
)
})
test('empty expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVModel('
', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION
- })
+ code: ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION,
+ }),
)
})
test('mal-formed expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVModel('
', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION
- })
+ code: ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION,
+ }),
)
})
test('allow unicode', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVModel('
', { onError })
expect(onError).toHaveBeenCalledTimes(0)
})
test('used on scope variable', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVModel('
', {
onError,
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE
- })
+ code: ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE,
+ }),
)
})
test('used on props', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVModel('
', {
onError,
bindingMetadata: {
- p: BindingTypes.PROPS
- }
+ p: BindingTypes.PROPS,
+ },
})
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: ErrorCodes.X_V_MODEL_ON_PROPS
- })
+ code: ErrorCodes.X_V_MODEL_ON_PROPS,
+ }),
)
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
index 4ed9ea23a82..9fda0259585 100644
--- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
@@ -1,15 +1,16 @@
import {
- baseParse as parse,
- CompilerOptions,
- ElementNode,
+ type CompilerOptions,
+ type ElementNode,
ErrorCodes,
+ NodeTypes,
+ type ObjectExpression,
TO_HANDLER_KEY,
+ type VNodeCall,
helperNameMap,
- NodeTypes,
- ObjectExpression,
+ baseParse as parse,
transform,
- VNodeCall
} from '../../src'
+import { transformFor } from '../../src/transforms/vFor'
import { transformOn } from '../../src/transforms/vOn'
import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
@@ -17,15 +18,15 @@ import { transformExpression } from '../../src/transforms/transformExpression'
function parseWithVOn(template: string, options: CompilerOptions = {}) {
const ast = parse(template, options)
transform(ast, {
- nodeTransforms: [transformExpression, transformElement],
+ nodeTransforms: [transformExpression, transformElement, transformFor],
directiveTransforms: {
- on: transformOn
+ on: transformOn,
},
- ...options
+ ...options,
})
return {
root: ast,
- node: ast.children[0] as ElementNode
+ node: ast.children[0] as ElementNode,
}
}
@@ -41,13 +42,13 @@ describe('compiler: transform v-on', () => {
loc: {
start: {
line: 1,
- column: 11
+ column: 11,
},
end: {
line: 1,
- column: 16
- }
- }
+ column: 16,
+ },
+ },
},
value: {
content: `onClick`,
@@ -55,16 +56,16 @@ describe('compiler: transform v-on', () => {
loc: {
start: {
line: 1,
- column: 18
+ column: 18,
},
end: {
line: 1,
- column: 25
- }
- }
- }
- }
- ]
+ column: 25,
+ },
+ },
+ },
+ },
+ ],
})
})
@@ -78,22 +79,22 @@ describe('compiler: transform v-on', () => {
children: [
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: `event` },
- `)`
- ]
+ `)`,
+ ],
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `handler`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
})
test('dynamic arg with prefixing', () => {
const { node } = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -103,22 +104,22 @@ describe('compiler: transform v-on', () => {
children: [
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: `_ctx.event` },
- `)`
- ]
+ `)`,
+ ],
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_ctx.handler`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
})
test('dynamic arg with complex exp prefixing', () => {
const { node } = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -131,16 +132,16 @@ describe('compiler: transform v-on', () => {
`(`,
{ content: `_ctx.foo` },
`)`,
- `)`
- ]
+ `)`,
+ ],
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_ctx.handler`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
})
@@ -152,10 +153,10 @@ describe('compiler: transform v-on', () => {
key: { content: `onClick` },
value: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`$event => (`, { content: `i++` }, `)`]
- }
- }
- ]
+ children: [`$event => (`, { content: `i++` }, `)`],
+ },
+ },
+ ],
})
})
@@ -170,10 +171,10 @@ describe('compiler: transform v-on', () => {
// should wrap with `{` for multiple statements
// in this case the return value is discarded and the behavior is
// consistent with 2.x
- children: [`$event => {`, { content: `foo();bar()` }, `}`]
- }
- }
- ]
+ children: [`$event => {`, { content: `foo();bar()` }, `}`],
+ },
+ },
+ ],
})
})
@@ -188,16 +189,16 @@ describe('compiler: transform v-on', () => {
// should wrap with `{` for multiple statements
// in this case the return value is discarded and the behavior is
// consistent with 2.x
- children: [`$event => {`, { content: `\nfoo();\nbar()\n` }, `}`]
- }
- }
- ]
+ children: [`$event => {`, { content: `\nfoo();\nbar()\n` }, `}`],
+ },
+ },
+ ],
})
})
test('inline statement w/ prefixIdentifiers: true', () => {
const { node } = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -214,20 +215,20 @@ describe('compiler: transform v-on', () => {
`(`,
// should NOT prefix $event
{ content: `$event` },
- `)`
- ]
+ `)`,
+ ],
},
- `)`
- ]
- }
- }
- ]
+ `)`,
+ ],
+ },
+ },
+ ],
})
})
test('multiple inline statements w/ prefixIdentifiers: true', () => {
const { node } = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -245,14 +246,14 @@ describe('compiler: transform v-on', () => {
{ content: `$event` },
`);`,
{ content: `_ctx.bar` },
- `()`
- ]
+ `()`,
+ ],
},
- `}`
- ]
- }
- }
- ]
+ `}`,
+ ],
+ },
+ },
+ ],
})
})
@@ -264,14 +265,14 @@ describe('compiler: transform v-on', () => {
key: { content: `onClick` },
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `$event => foo($event)`
- }
- }
- ]
+ content: `$event => foo($event)`,
+ },
+ },
+ ],
})
})
- test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
+ test('should NOT wrap as function if expression is already function expression (with TypeScript)', () => {
const { node } = parseWithVOn(`
foo(e)"/>`)
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -279,10 +280,42 @@ describe('compiler: transform v-on', () => {
key: { content: `onClick` },
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `(e: any): any => foo(e)`
- }
- }
- ]
+ content: `(e: any): any => foo(e)`,
+ },
+ },
+ ],
+ })
+
+ const { node: node2 } = parseWithVOn(
+ `
foo(e)"/>`,
+ )
+ expect((node2.codegenNode as VNodeCall).props).toMatchObject({
+ properties: [
+ {
+ key: { content: `onClick` },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `(e: (number | string)[]) => foo(e)`,
+ },
+ },
+ ],
+ })
+ })
+
+ test('should NOT wrap as function if expression is already function expression (async)', () => {
+ const { node } = parseWithVOn(
+ `
await foo($event)"/>`,
+ )
+ expect((node.codegenNode as VNodeCall).props).toMatchObject({
+ properties: [
+ {
+ key: { content: `onClick` },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `async $event => await foo($event)`,
+ },
+ },
+ ],
})
})
@@ -292,7 +325,7 @@ describe('compiler: transform v-on', () => {
$event => {
foo($event)
}
- "/>`
+ "/>`,
)
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -304,10 +337,10 @@ describe('compiler: transform v-on', () => {
$event => {
foo($event)
}
- `
- }
- }
- ]
+ `,
+ },
+ },
+ ],
})
})
@@ -317,7 +350,7 @@ describe('compiler: transform v-on', () => {
function($event) {
foo($event)
}
- "/>`
+ "/>`,
)
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -329,10 +362,10 @@ describe('compiler: transform v-on', () => {
function($event) {
foo($event)
}
- `
- }
- }
- ]
+ `,
+ },
+ },
+ ],
})
})
@@ -344,16 +377,16 @@ describe('compiler: transform v-on', () => {
key: { content: `onClick` },
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `a['b' + c]`
- }
- }
- ]
+ content: `a['b' + c]`,
+ },
+ },
+ ],
})
})
test('complex member expression w/ prefixIdentifiers: true', () => {
const { node } = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -365,17 +398,17 @@ describe('compiler: transform v-on', () => {
{ content: `_ctx.a` },
`['b' + `,
{ content: `_ctx.c` },
- `]`
- ]
- }
- }
- ]
+ `]`,
+ ],
+ },
+ },
+ ],
})
})
test('function expression w/ prefixIdentifiers: true', () => {
const { node } = parseWithVOn(`
foo(e)"/>`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
@@ -389,34 +422,34 @@ describe('compiler: transform v-on', () => {
{ content: `_ctx.foo` },
`(`,
{ content: `e` },
- `)`
- ]
- }
- }
- ]
+ `)`,
+ ],
+ },
+ },
+ ],
})
})
test('should error if no expression AND no modifier', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVOn(`
`, { onError })
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_ON_NO_EXPRESSION,
loc: {
start: {
line: 1,
- column: 6
+ column: 6,
},
end: {
line: 1,
- column: 16
- }
- }
+ column: 16,
+ },
+ },
})
})
test('should NOT error if no expression but has modifier', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
parseWithVOn(`
`, { onError })
expect(onError).not.toHaveBeenCalled()
})
@@ -427,55 +460,57 @@ describe('compiler: transform v-on', () => {
properties: [
{
key: {
- content: `onFooBar`
+ content: `onFooBar`,
},
value: {
- content: `onMount`
- }
- }
- ]
+ content: `onMount`,
+ },
+ },
+ ],
})
})
- test('case conversion for vnode hooks', () => {
- const { node } = parseWithVOn(`
`)
- expect((node.codegenNode as VNodeCall).props).toMatchObject({
- properties: [
- {
- key: {
- content: `onVnodeMounted`
- },
- value: {
- content: `onMount`
- }
- }
- ]
+ test('error for vnode hooks', () => {
+ const onError = vi.fn()
+ parseWithVOn(`
`, { onError })
+ expect(onError.mock.calls[0][0]).toMatchObject({
+ code: ErrorCodes.X_VNODE_HOOKS,
+ loc: {
+ start: {
+ line: 1,
+ column: 11,
+ },
+ end: {
+ line: 1,
+ column: 24,
+ },
+ },
})
})
test('vue: prefixed events', () => {
const { node } = parseWithVOn(
- `
`
+ `
`,
)
expect((node.codegenNode as VNodeCall).props).toMatchObject({
properties: [
{
key: {
- content: `onVnodeMounted`
+ content: `onVnodeMounted`,
},
value: {
- content: `onMount`
- }
+ content: `onMount`,
+ },
},
{
key: {
- content: `onVnodeBeforeUpdate`
+ content: `onVnodeBeforeUpdate`,
},
value: {
- content: `onBeforeUpdate`
- }
- }
- ]
+ content: `onBeforeUpdate`,
+ },
+ },
+ ],
})
})
@@ -483,35 +518,35 @@ describe('compiler: transform v-on', () => {
test('empty handler', () => {
const { root, node } = parseWithVOn(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `() => {}`
- }
+ content: `() => {}`,
+ },
})
})
test('member expression handler', () => {
const { root, node } = parseWithVOn(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
@@ -520,23 +555,23 @@ describe('compiler: transform v-on', () => {
children: [
`(...args) => (`,
{ content: `_ctx.foo && _ctx.foo(...args)` },
- `)`
- ]
- }
+ `)`,
+ ],
+ },
})
})
test('compound member expression handler', () => {
const { root, node } = parseWithVOn(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
@@ -553,12 +588,12 @@ describe('compiler: transform v-on', () => {
{ content: `_ctx.foo` },
`.`,
{ content: `bar` },
- `(...args)`
- ]
+ `(...args)`,
+ ],
},
- `)`
- ]
- }
+ `)`,
+ ],
+ },
})
})
@@ -566,9 +601,9 @@ describe('compiler: transform v-on', () => {
const { root } = parseWithVOn(`
`, {
prefixIdentifiers: true,
cacheHandlers: true,
- isNativeTag: tag => tag === 'div'
+ isNativeTag: tag => tag === 'div',
})
- expect(root.cached).toBe(0)
+ expect(root.cached.length).toBe(0)
})
test('should not be cached inside v-once', () => {
@@ -576,31 +611,42 @@ describe('compiler: transform v-on', () => {
`
`,
{
prefixIdentifiers: true,
- cacheHandlers: true
- }
+ cacheHandlers: true,
+ },
)
- expect(root.cached).not.toBe(2)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).not.toBe(2)
+ expect(root.cached.length).toBe(1)
+ })
+
+ test('unicode identifier should not be cached (v-for)', () => {
+ const { root } = parseWithVOn(
+ `
`,
+ {
+ prefixIdentifiers: true,
+ cacheHandlers: true,
+ },
+ )
+ expect(root.cached.length).toBe(0)
})
test('inline function expression handler', () => {
const { root, node } = parseWithVOn(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`() => `, { content: `_ctx.foo` }, `()`]
- }
+ children: [`() => `, { content: `_ctx.foo` }, `()`],
+ },
})
})
@@ -609,22 +655,55 @@ describe('compiler: transform v-on', () => {
`
`,
{
prefixIdentifiers: true,
- cacheHandlers: true
- }
+ cacheHandlers: true,
+ },
)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`async () => await `, { content: `_ctx.foo` }, `()`]
- }
+ children: [`async () => await `, { content: `_ctx.foo` }, `()`],
+ },
+ })
+ })
+
+ test('inline async arrow function with no bracket expression handler', () => {
+ const { root, node } = parseWithVOn(
+ `
`,
+ {
+ prefixIdentifiers: true,
+ cacheHandlers: true,
+ },
+ )
+
+ expect(root.cached.length).toBe(1)
+ const vnodeCall = node.codegenNode as VNodeCall
+ // should not treat cached handler as dynamicProp, so no flags
+ expect(vnodeCall.patchFlag).toBeUndefined()
+ expect(
+ (vnodeCall.props as ObjectExpression).properties[0].value,
+ ).toMatchObject({
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ index: 0,
+ value: {
+ type: NodeTypes.COMPOUND_EXPRESSION,
+ children: [
+ `async `,
+ { content: `e` },
+ ` => await `,
+ { content: `_ctx.foo` },
+ `(`,
+ { content: `e` },
+ `)`,
+ ],
+ },
})
})
@@ -633,15 +712,15 @@ describe('compiler: transform v-on', () => {
`
`,
{
prefixIdentifiers: true,
- cacheHandlers: true
- }
+ cacheHandlers: true,
+ },
)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
@@ -650,24 +729,24 @@ describe('compiler: transform v-on', () => {
children: [
`async function () { await `,
{ content: `_ctx.foo` },
- `() } `
- ]
- }
+ `() } `,
+ ],
+ },
})
})
test('inline statement handler', () => {
const { root, node } = parseWithVOn(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
+ expect(root.cached.length).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags
expect(vnodeCall.patchFlag).toBeUndefined()
expect(
- (vnodeCall.props as ObjectExpression).properties[0].value
+ (vnodeCall.props as ObjectExpression).properties[0].value,
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
@@ -676,9 +755,9 @@ describe('compiler: transform v-on', () => {
children: [
`$event => (`,
{ children: [{ content: `_ctx.foo` }, `++`] },
- `)`
- ]
- }
+ `)`,
+ ],
+ },
})
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vOnce.spec.ts b/packages/compiler-core/__tests__/transforms/vOnce.spec.ts
index 553ac1dfac4..5f47a0fdbd9 100644
--- a/packages/compiler-core/__tests__/transforms/vOnce.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vOnce.spec.ts
@@ -1,10 +1,10 @@
import {
- baseParse as parse,
- transform,
+ type CompilerOptions,
NodeTypes,
generate,
- CompilerOptions,
- getBaseTransformPreset
+ getBaseTransformPreset,
+ baseParse as parse,
+ transform,
} from '../../src'
import { RENDER_SLOT, SET_BLOCK_TRACKING } from '../../src/runtimeHelpers'
@@ -14,7 +14,7 @@ function transformWithOnce(template: string, options: CompilerOptions = {}) {
transform(ast, {
nodeTransforms,
directiveTransforms,
- ...options
+ ...options,
})
return ast
}
@@ -22,60 +22,60 @@ function transformWithOnce(template: string, options: CompilerOptions = {}) {
describe('compiler: v-once transform', () => {
test('as root node', () => {
const root = transformWithOnce(`
`)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect(root.codegenNode).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.VNODE_CALL,
- tag: `"div"`
- }
+ tag: `"div"`,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
test('on nested plain element', () => {
const root = transformWithOnce(`
`)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect((root.children[0] as any).children[0].codegenNode).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.VNODE_CALL,
- tag: `"div"`
- }
+ tag: `"div"`,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
test('on component', () => {
const root = transformWithOnce(`
`)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect((root.children[0] as any).children[0].codegenNode).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.VNODE_CALL,
- tag: `_component_Comp`
- }
+ tag: `_component_Comp`,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
test('on slot outlet', () => {
const root = transformWithOnce(`
`)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect((root.children[0] as any).children[0].codegenNode).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: RENDER_SLOT
- }
+ callee: RENDER_SLOT,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
@@ -84,15 +84,15 @@ describe('compiler: v-once transform', () => {
test('inside v-once', () => {
const root = transformWithOnce(`
`)
expect(root.cached).not.toBe(2)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
})
// cached nodes should be ignored by hoistStatic transform
test('with hoistStatic: true', () => {
const root = transformWithOnce(`
`, {
- hoistStatic: true
+ hoistStatic: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect(root.hoists.length).toBe(0)
expect((root.children[0] as any).children[0].codegenNode).toMatchObject({
@@ -100,15 +100,15 @@ describe('compiler: v-once transform', () => {
index: 0,
value: {
type: NodeTypes.VNODE_CALL,
- tag: `"div"`
- }
+ tag: `"div"`,
+ },
})
expect(generate(root).code).toMatchSnapshot()
})
test('with v-if/else', () => {
const root = transformWithOnce(`
`)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect(root.children[0]).toMatchObject({
type: NodeTypes.IF,
@@ -119,27 +119,27 @@ describe('compiler: v-once transform', () => {
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
consequent: {
type: NodeTypes.VNODE_CALL,
- tag: `"div"`
+ tag: `"div"`,
},
alternate: {
type: NodeTypes.VNODE_CALL,
- tag: `"p"`
- }
- }
- }
+ tag: `"p"`,
+ },
+ },
+ },
})
})
test('with v-for', () => {
const root = transformWithOnce(`
`)
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
expect(root.helpers).toContain(SET_BLOCK_TRACKING)
expect(root.children[0]).toMatchObject({
type: NodeTypes.FOR,
// should cache the entire v-for expression, not just a single branch
codegenNode: {
- type: NodeTypes.JS_CACHE_EXPRESSION
- }
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ },
})
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
index c166f8d160a..e0f44a064fb 100644
--- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
@@ -1,18 +1,18 @@
import {
- CompilerOptions,
+ type CompilerOptions,
+ type ComponentNode,
+ type ElementNode,
+ ErrorCodes,
+ type ForNode,
+ NodeTypes,
+ type ObjectExpression,
+ type RenderSlotCall,
+ type SimpleExpressionNode,
+ type SlotsExpression,
+ type VNodeCall,
+ generate,
baseParse as parse,
transform,
- generate,
- ElementNode,
- NodeTypes,
- ErrorCodes,
- ForNode,
- ComponentNode,
- VNodeCall,
- SlotsExpression,
- ObjectExpression,
- SimpleExpressionNode,
- RenderSlotCall
} from '../../src'
import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn'
@@ -21,17 +21,17 @@ import { transformExpression } from '../../src/transforms/transformExpression'
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
import {
trackSlotScopes,
- trackVForSlotScopes
+ trackVForSlotScopes,
} from '../../src/transforms/vSlot'
import { CREATE_SLOTS, RENDER_LIST } from '../../src/runtimeHelpers'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
import { PatchFlags } from '@vue/shared'
import { transformFor } from '../../src/transforms/vFor'
import { transformIf } from '../../src/transforms/vIf'
function parseWithSlots(template: string, options: CompilerOptions = {}) {
const ast = parse(template, {
- whitespace: options.whitespace
+ whitespace: options.whitespace,
})
transform(ast, {
nodeTransforms: [
@@ -42,13 +42,13 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
: []),
transformSlotOutlet,
transformElement,
- trackSlotScopes
+ trackSlotScopes,
],
directiveTransforms: {
on: transformOn,
- bind: transformBind
+ bind: transformBind,
},
- ...options
+ ...options,
})
return {
root: ast,
@@ -56,7 +56,7 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
ast.children[0].type === NodeTypes.ELEMENT
? ((ast.children[0].codegenNode as VNodeCall)
.children as SlotsExpression)
- : null
+ : null,
}
}
@@ -70,25 +70,25 @@ function createSlotMatcher(obj: Record
, isDynamic = false) {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: !/^\[/.test(key),
- content: key.replace(/^\[|\]$/g, '')
+ content: key.replace(/^\[|\]$/g, ''),
},
- value: obj[key]
+ value: obj[key],
} as any
})
.concat({
key: { content: `_` },
value: {
content: isDynamic ? `2 /* DYNAMIC */` : `1 /* STABLE */`,
- isStatic: false
- }
- })
+ isStatic: false,
+ },
+ }),
}
}
describe('compiler: transform component slots', () => {
test('implicit default slot', () => {
const { root, slots } = parseWithSlots(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(slots).toMatchObject(
createSlotMatcher({
@@ -98,11 +98,11 @@ describe('compiler: transform component slots', () => {
returns: [
{
type: NodeTypes.ELEMENT,
- tag: `div`
- }
- ]
- }
- })
+ tag: `div`,
+ },
+ ],
+ },
+ }),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -110,7 +110,7 @@ describe('compiler: transform component slots', () => {
test('on-component default slot', () => {
const { root, slots } = parseWithSlots(
`{{ foo }}{{ bar }} `,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject(
createSlotMatcher({
@@ -118,24 +118,24 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `foo` }, ` }`]
+ children: [`{ `, { content: `foo` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.bar`
- }
- }
- ]
- }
- })
+ content: `_ctx.bar`,
+ },
+ },
+ ],
+ },
+ }),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -143,7 +143,7 @@ describe('compiler: transform component slots', () => {
test('on component named slot', () => {
const { root, slots } = parseWithSlots(
`{{ foo }}{{ bar }} `,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject(
createSlotMatcher({
@@ -151,24 +151,24 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `foo` }, ` }`]
+ children: [`{ `, { content: `foo` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.bar`
- }
- }
- ]
- }
- })
+ content: `_ctx.bar`,
+ },
+ },
+ ],
+ },
+ }),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -183,7 +183,7 @@ describe('compiler: transform component slots', () => {
{{ foo }}{{ bar }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject(
createSlotMatcher({
@@ -191,45 +191,45 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `foo` }, ` }`]
+ children: [`{ `, { content: `foo` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.bar`
- }
- }
- ]
+ content: `_ctx.bar`,
+ },
+ },
+ ],
},
two: {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `bar` }, ` }`]
+ children: [`{ `, { content: `bar` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.foo`
- }
+ content: `_ctx.foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `bar`
- }
- }
- ]
- }
- })
+ content: `bar`,
+ },
+ },
+ ],
+ },
+ }),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -237,7 +237,7 @@ describe('compiler: transform component slots', () => {
test('on component dynamically named slot', () => {
const { root, slots } = parseWithSlots(
`{{ foo }}{{ bar }} `,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject(
createSlotMatcher(
@@ -246,26 +246,26 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `foo` }, ` }`]
+ children: [`{ `, { content: `foo` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.bar`
- }
- }
- ]
- }
+ content: `_ctx.bar`,
+ },
+ },
+ ],
+ },
},
- true
- )
+ true,
+ ),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -274,7 +274,7 @@ describe('compiler: transform component slots', () => {
const { root, slots } = parseWithSlots(
`
foo bar
- `
+ `,
)
expect(slots).toMatchObject(
createSlotMatcher({
@@ -284,9 +284,9 @@ describe('compiler: transform component slots', () => {
returns: [
{
type: NodeTypes.TEXT,
- content: `foo`
- }
- ]
+ content: `foo`,
+ },
+ ],
},
default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
@@ -294,15 +294,15 @@ describe('compiler: transform component slots', () => {
returns: [
{
type: NodeTypes.TEXT,
- content: `bar`
+ content: `bar`,
},
{
type: NodeTypes.ELEMENT,
- tag: `span`
- }
- ]
- }
- })
+ tag: `span`,
+ },
+ ],
+ },
+ }),
)
expect(generate(root).code).toMatchSnapshot()
})
@@ -317,7 +317,7 @@ describe('compiler: transform component slots', () => {
{{ foo }}{{ bar }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject(
createSlotMatcher(
@@ -326,47 +326,47 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `foo` }, ` }`]
+ children: [`{ `, { content: `foo` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.bar`
- }
- }
- ]
+ content: `_ctx.bar`,
+ },
+ },
+ ],
},
'[_ctx.two]': {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `bar` }, ` }`]
+ children: [`{ `, { content: `bar` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.foo`
- }
+ content: `_ctx.foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `bar`
- }
- }
- ]
- }
+ content: `bar`,
+ },
+ },
+ ],
+ },
},
- true
- )
+ true,
+ ),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -381,7 +381,7 @@ describe('compiler: transform component slots', () => {
{{ foo }}{{ bar }}{{ baz }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject(
createSlotMatcher({
@@ -389,7 +389,7 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `foo` }, ` }`]
+ children: [`{ `, { content: `foo` }, ` }`],
},
returns: [
{
@@ -404,63 +404,63 @@ describe('compiler: transform component slots', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: {
type: NodeTypes.COMPOUND_EXPRESSION,
- children: [`{ `, { content: `bar` }, ` }`]
+ children: [`{ `, { content: `bar` }, ` }`],
},
returns: [
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `bar`
- }
+ content: `bar`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.baz`
- }
- }
- ]
- }
+ content: `_ctx.baz`,
+ },
+ },
+ ],
+ },
},
- true
+ true,
),
// nested slot should be forced dynamic, since scope variables
// are not tracked as dependencies of the slot.
- patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS)
- }
+ patchFlag: PatchFlags.DYNAMIC_SLOTS,
+ },
},
// test scope
{
type: NodeTypes.TEXT,
- content: ` `
+ content: ` `,
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `foo`
- }
+ content: `foo`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.bar`
- }
+ content: `_ctx.bar`,
+ },
},
{
type: NodeTypes.INTERPOLATION,
content: {
- content: `_ctx.baz`
- }
- }
- ]
- }
- })
+ content: `_ctx.baz`,
+ },
+ },
+ ],
+ },
+ }),
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -469,14 +469,12 @@ describe('compiler: transform component slots', () => {
const { root } = parseWithSlots(
`
foo
-
`
+ `,
)
const div = ((root.children[0] as ForNode).children[0] as ElementNode)
.codegenNode as any
const comp = div.children[0]
- expect(comp.codegenNode.patchFlag).toBe(
- genFlagText(PatchFlags.DYNAMIC_SLOTS)
- )
+ expect(comp.codegenNode.patchFlag).toBe(PatchFlags.DYNAMIC_SLOTS)
})
test('should only force dynamic slots when actually using scope vars w/ prefixIdentifiers: true', () => {
@@ -494,7 +492,7 @@ describe('compiler: transform component slots', () => {
flag = (innerComp.codegenNode as VNodeCall).patchFlag
}
if (shouldForce) {
- expect(flag).toBe(genFlagText(PatchFlags.DYNAMIC_SLOTS))
+ expect(flag).toBe(PatchFlags.DYNAMIC_SLOTS)
} else {
expect(flag).toBeUndefined()
}
@@ -504,14 +502,14 @@ describe('compiler: transform component slots', () => {
`
foo
`,
- false
+ false,
)
assertDynamicSlots(
`
{{ i }}
`,
- true
+ true,
)
// reference the component's own slot variable should not force dynamic slots
@@ -519,14 +517,14 @@ describe('compiler: transform component slots', () => {
`
{{ bar }}
`,
- false
+ false,
)
assertDynamicSlots(
`
{{ foo }}
`,
- true
+ true,
)
// #2564
@@ -534,14 +532,14 @@ describe('compiler: transform component slots', () => {
`
`,
- true
+ true,
)
assertDynamicSlots(
`
`,
- false
+ false,
)
})
@@ -549,14 +547,14 @@ describe('compiler: transform component slots', () => {
const { root, slots } = parseWithSlots(
`
hello
- `
+ `,
)
expect(slots).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_SLOTS,
arguments: [
createObjectMatcher({
- _: `[2 /* DYNAMIC */]`
+ _: `[2 /* DYNAMIC */]`,
}),
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -568,21 +566,21 @@ describe('compiler: transform component slots', () => {
name: `one`,
fn: {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
- returns: [{ type: NodeTypes.TEXT, content: `hello` }]
+ returns: [{ type: NodeTypes.TEXT, content: `hello` }],
},
- key: `0`
+ key: `0`,
}),
alternate: {
content: `undefined`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + ''
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect(generate(root).code).toMatchSnapshot()
})
@@ -592,14 +590,14 @@ describe('compiler: transform component slots', () => {
`
{{ props }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_SLOTS,
arguments: [
createObjectMatcher({
- _: `[2 /* DYNAMIC */]`
+ _: `[2 /* DYNAMIC */]`,
}),
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -615,23 +613,23 @@ describe('compiler: transform component slots', () => {
returns: [
{
type: NodeTypes.INTERPOLATION,
- content: { content: `props` }
- }
- ]
+ content: { content: `props` },
+ },
+ ],
},
- key: `0`
+ key: `0`,
}),
alternate: {
content: `undefined`,
- isStatic: false
- }
- }
- ]
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ ],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + ''
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -642,14 +640,14 @@ describe('compiler: transform component slots', () => {
foo
bar
baz
- `
+ `,
)
expect(slots).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_SLOTS,
arguments: [
createObjectMatcher({
- _: `[2 /* DYNAMIC */]`
+ _: `[2 /* DYNAMIC */]`,
}),
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -662,9 +660,9 @@ describe('compiler: transform component slots', () => {
fn: {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: undefined,
- returns: [{ type: NodeTypes.TEXT, content: `foo` }]
+ returns: [{ type: NodeTypes.TEXT, content: `foo` }],
},
- key: `0`
+ key: `0`,
}),
alternate: {
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
@@ -674,28 +672,29 @@ describe('compiler: transform component slots', () => {
fn: {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: { content: `props` },
- returns: [{ type: NodeTypes.TEXT, content: `bar` }]
+ returns: [{ type: NodeTypes.TEXT, content: `bar` }],
},
- key: `1`
+ key: `1`,
}),
alternate: createObjectMatcher({
name: `one`,
fn: {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: undefined,
- returns: [{ type: NodeTypes.TEXT, content: `baz` }]
+ returns: [{ type: NodeTypes.TEXT, content: `baz` }],
},
- key: `2`
- })
- }
- }
- ]
- }
- ]
+ key: `2`,
+ }),
+ },
+ },
+ ],
+ },
+ ],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + ''
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
+ expect((root as any).children[0].children.length).toBe(3)
expect(generate(root).code).toMatchSnapshot()
})
@@ -704,14 +703,14 @@ describe('compiler: transform component slots', () => {
`
{{ name }}
`,
- { prefixIdentifiers: true }
+ { prefixIdentifiers: true },
)
expect(slots).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_SLOTS,
arguments: [
createObjectMatcher({
- _: `[2 /* DYNAMIC */]`
+ _: `[2 /* DYNAMIC */]`,
}),
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
@@ -731,20 +730,20 @@ describe('compiler: transform component slots', () => {
returns: [
{
type: NodeTypes.INTERPOLATION,
- content: { content: `name`, isStatic: false }
- }
- ]
- }
- })
- }
- ]
- }
- ]
- }
- ]
+ content: { content: `name`, isStatic: false },
+ },
+ ],
+ },
+ }),
+ },
+ ],
+ },
+ ],
+ },
+ ],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + ''
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -755,13 +754,13 @@ describe('compiler: transform component slots', () => {
properties: [
{
key: { content: `default` },
- value: { type: NodeTypes.JS_FUNCTION_EXPRESSION }
+ value: { type: NodeTypes.JS_FUNCTION_EXPRESSION },
},
{
key: { content: `_` },
- value: { content: `3 /* FORWARDED */` }
- }
- ]
+ value: { content: `3 /* FORWARDED */` },
+ },
+ ],
}
test('
tag only', () => {
const { slots } = parseWithSlots(` `)
@@ -780,7 +779,7 @@ describe('compiler: transform component slots', () => {
test(' tag w/ template', () => {
const { slots } = parseWithSlots(
- ` `
+ ` `,
)
expect(slots).toMatchObject(toMatch)
})
@@ -793,7 +792,7 @@ describe('compiler: transform component slots', () => {
// # fix: #6900
test('consistent behavior of @xxx:modelValue and @xxx:model-value', () => {
const { root: rootUpper } = parseWithSlots(
- `
`
+ `
`,
)
const slotNodeUpper = (rootUpper.codegenNode! as VNodeCall)
.children as ElementNode[]
@@ -805,19 +804,19 @@ describe('compiler: transform component slots', () => {
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onFoo:modelValue'
+ content: 'onFoo:modelValue',
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `handler`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
const { root } = parseWithSlots(
- `
`
+ `
`,
)
const slotNode = (root.codegenNode! as VNodeCall)
.children as ElementNode[]
@@ -828,109 +827,105 @@ describe('compiler: transform component slots', () => {
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onFoo:modelValue'
+ content: 'onFoo:modelValue',
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `handler`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
})
})
describe('errors', () => {
test('error on extraneous children w/ named default slot', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const source = `foo bar `
parseWithSlots(source, { onError })
const index = source.indexOf('bar')
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN,
loc: {
- source: `bar`,
start: {
offset: index,
line: 1,
- column: index + 1
+ column: index + 1,
},
end: {
offset: index + 3,
line: 1,
- column: index + 4
- }
- }
+ column: index + 4,
+ },
+ },
})
})
test('error on duplicated slot names', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const source = ` `
parseWithSlots(source, { onError })
const index = source.lastIndexOf('#foo')
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES,
loc: {
- source: `#foo`,
start: {
offset: index,
line: 1,
- column: index + 1
+ column: index + 1,
},
end: {
offset: index + 4,
line: 1,
- column: index + 5
- }
- }
+ column: index + 5,
+ },
+ },
})
})
test('error on invalid mixed slot usage', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const source = ` `
parseWithSlots(source, { onError })
const index = source.lastIndexOf('#foo')
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE,
loc: {
- source: `#foo`,
start: {
offset: index,
line: 1,
- column: index + 1
+ column: index + 1,
},
end: {
offset: index + 4,
line: 1,
- column: index + 5
- }
- }
+ column: index + 5,
+ },
+ },
})
})
test('error on v-slot usage on plain elements', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const source = `
`
parseWithSlots(source, { onError })
const index = source.indexOf('v-slot')
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_SLOT_MISPLACED,
loc: {
- source: `v-slot`,
start: {
offset: index,
line: 1,
- column: index + 1
+ column: index + 1,
},
end: {
offset: index + 6,
line: 1,
- column: index + 7
- }
- }
+ column: index + 7,
+ },
+ },
})
})
})
@@ -944,11 +939,11 @@ describe('compiler: transform component slots', () => {
`
const { root } = parseWithSlots(source, {
- whitespace: 'preserve'
+ whitespace: 'preserve',
})
expect(
- `Extraneous children found when component already has explicitly named default slot.`
+ `Extraneous children found when component already has explicitly named default slot.`,
).not.toHaveBeenWarned()
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -961,11 +956,11 @@ describe('compiler: transform component slots', () => {
`
const { root } = parseWithSlots(source, {
- whitespace: 'preserve'
+ whitespace: 'preserve',
})
expect(
- `Extraneous children found when component already has explicitly named default slot.`
+ `Extraneous children found when component already has explicitly named default slot.`,
).not.toHaveBeenWarned()
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -978,7 +973,7 @@ describe('compiler: transform component slots', () => {
`
const { root } = parseWithSlots(source, {
- whitespace: 'preserve'
+ whitespace: 'preserve',
})
// slots is vnodeCall's children as an ObjectExpression
@@ -988,10 +983,24 @@ describe('compiler: transform component slots', () => {
// should be: header, footer, _ (no default)
expect(slots.length).toBe(3)
expect(
- slots.some(p => (p.key as SimpleExpressionNode).content === 'default')
+ slots.some(p => (p.key as SimpleExpressionNode).content === 'default'),
).toBe(false)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
+
+ test('named slot with v-if + v-else', () => {
+ const source = `
+
+ foo
+ baz
+
+ `
+ const { root } = parseWithSlots(source, {
+ whitespace: 'preserve',
+ })
+
+ expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
+ })
})
})
diff --git a/packages/compiler-core/__tests__/utils.spec.ts b/packages/compiler-core/__tests__/utils.spec.ts
index 45fa46fea7a..000b10e11bd 100644
--- a/packages/compiler-core/__tests__/utils.spec.ts
+++ b/packages/compiler-core/__tests__/utils.spec.ts
@@ -1,11 +1,15 @@
-import { TransformContext } from '../src'
-import { Position } from '../src/ast'
+import { babelParse, walkIdentifiers } from '@vue/compiler-sfc'
+import {
+ type ExpressionNode,
+ type TransformContext,
+ isReferencedIdentifier,
+} from '../src'
+import { type Position, createSimpleExpression } from '../src/ast'
import {
- getInnerRange,
advancePositionWithClone,
- isMemberExpressionNode,
isMemberExpressionBrowser,
- toValidAssetId
+ isMemberExpressionNode,
+ toValidAssetId,
} from '../src/utils'
function p(line: number, column: number, offset: number): Position {
@@ -41,34 +45,9 @@ describe('advancePositionWithClone', () => {
})
})
-describe('getInnerRange', () => {
- const loc1 = {
- source: 'foo\nbar\nbaz',
- start: p(1, 1, 0),
- end: p(3, 3, 11)
- }
-
- test('at start', () => {
- const loc2 = getInnerRange(loc1, 0, 4)
- expect(loc2.start).toEqual(loc1.start)
- expect(loc2.end.column).toBe(1)
- expect(loc2.end.line).toBe(2)
- expect(loc2.end.offset).toBe(4)
- })
-
- test('in between', () => {
- const loc2 = getInnerRange(loc1, 4, 3)
- expect(loc2.start.column).toBe(1)
- expect(loc2.start.line).toBe(2)
- expect(loc2.start.offset).toBe(4)
- expect(loc2.end.column).toBe(4)
- expect(loc2.end.line).toBe(2)
- expect(loc2.end.offset).toBe(7)
- })
-})
-
describe('isMemberExpression', () => {
- function commonAssertions(fn: (str: string) => boolean) {
+ function commonAssertions(raw: (exp: ExpressionNode) => boolean) {
+ const fn = (str: string) => raw(createSimpleExpression(str))
// should work
expect(fn('obj.foo')).toBe(true)
expect(fn('obj[foo]')).toBe(true)
@@ -105,13 +84,16 @@ describe('isMemberExpression', () => {
test('browser', () => {
commonAssertions(isMemberExpressionBrowser)
- expect(isMemberExpressionBrowser('123[a]')).toBe(false)
+ expect(isMemberExpressionBrowser(createSimpleExpression('123[a]'))).toBe(
+ false,
+ )
})
test('node', () => {
const ctx = { expressionPlugins: ['typescript'] } as any as TransformContext
- const fn = (str: string) => isMemberExpressionNode(str, ctx)
- commonAssertions(fn)
+ const fn = (str: string) =>
+ isMemberExpressionNode(createSimpleExpression(str), ctx)
+ commonAssertions(exp => isMemberExpressionNode(exp, ctx))
// TS-specific checks
expect(fn('foo as string')).toBe(true)
@@ -122,6 +104,10 @@ describe('isMemberExpression', () => {
expect(fn(`123[a]`)).toBe(true)
expect(fn(`foo() as string`)).toBe(false)
expect(fn(`a + b as string`)).toBe(false)
+ // #9865
+ expect(fn('""')).toBe(false)
+ expect(fn('undefined')).toBe(false)
+ expect(fn('null')).toBe(false)
})
})
@@ -131,6 +117,21 @@ test('toValidAssetId', () => {
expect(toValidAssetId('div', 'filter')).toBe('_filter_div')
expect(toValidAssetId('foo-bar', 'component')).toBe('_component_foo_bar')
expect(toValidAssetId('test-测试-1', 'component')).toBe(
- '_component_test_2797935797_1'
+ '_component_test_2797935797_1',
)
})
+
+describe('isReferencedIdentifier', () => {
+ test('identifiers in function parameters should not be inferred as references', () => {
+ expect.assertions(4)
+ const ast = babelParse(`(({ title }) => [])`)
+ walkIdentifiers(
+ ast.program.body[0],
+ (node, parent, parentStack, isReference) => {
+ expect(isReference).toBe(false)
+ expect(isReferencedIdentifier(node, parent, parentStack)).toBe(false)
+ },
+ true,
+ )
+ })
+})
diff --git a/packages/compiler-core/api-extractor.json b/packages/compiler-core/api-extractor.json
deleted file mode 100644
index b677d51cd8d..00000000000
--- a/packages/compiler-core/api-extractor.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "../../api-extractor.json",
- "mainEntryPointFilePath": "./dist/packages//src/index.d.ts",
- "dtsRollup": {
- "publicTrimmedFilePath": "./dist/.d.ts"
- }
-}
diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json
index 61ef0f8a616..a59342aeb93 100644
--- a/packages/compiler-core/package.json
+++ b/packages/compiler-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
- "version": "3.2.45",
+ "version": "3.5.18",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",
@@ -9,6 +9,20 @@
"index.js",
"dist"
],
+ "exports": {
+ ".": {
+ "types": "./dist/compiler-core.d.ts",
+ "node": {
+ "production": "./dist/compiler-core.cjs.prod.js",
+ "development": "./dist/compiler-core.cjs.js",
+ "default": "./index.js"
+ },
+ "module": "./dist/compiler-core.esm-bundler.js",
+ "import": "./dist/compiler-core.esm-bundler.js",
+ "require": "./index.js"
+ },
+ "./*": "./*"
+ },
"buildOptions": {
"name": "VueCompilerCore",
"compat": true,
@@ -32,12 +46,13 @@
},
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme",
"dependencies": {
- "@vue/shared": "3.2.45",
- "@babel/parser": "^7.16.4",
- "estree-walker": "^2.0.2",
- "source-map": "^0.6.1"
+ "@babel/parser": "catalog:",
+ "@vue/shared": "workspace:*",
+ "entities": "^4.5.0",
+ "estree-walker": "catalog:",
+ "source-map-js": "catalog:"
},
"devDependencies": {
- "@babel/types": "^7.16.0"
+ "@babel/types": "catalog:"
}
}
diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts
index 457a9057633..2d6df9d9010 100644
--- a/packages/compiler-core/src/ast.ts
+++ b/packages/compiler-core/src/ast.ts
@@ -1,28 +1,32 @@
-import { isString } from '@vue/shared'
-import { ForParseResult } from './transforms/vFor'
+import { type PatchFlags, isString } from '@vue/shared'
import {
- RENDER_SLOT,
- CREATE_SLOTS,
- RENDER_LIST,
+ CREATE_BLOCK,
+ CREATE_ELEMENT_BLOCK,
+ CREATE_ELEMENT_VNODE,
+ type CREATE_SLOTS,
+ CREATE_VNODE,
+ type FRAGMENT,
OPEN_BLOCK,
- FRAGMENT,
+ type RENDER_LIST,
+ type RENDER_SLOT,
WITH_DIRECTIVES,
- WITH_MEMO
+ type WITH_MEMO,
} from './runtimeHelpers'
-import { PropsExpression } from './transforms/transformElement'
-import { ImportItem, TransformContext } from './transform'
-import { getVNodeBlockHelper, getVNodeHelper } from './utils'
+import type { PropsExpression } from './transforms/transformElement'
+import type { ImportItem, TransformContext } from './transform'
+import type { Node as BabelNode } from '@babel/types'
// Vue template is a platform-agnostic superset of HTML (syntax only).
-// More namespaces like SVG and MathML are declared by platform specific
-// compilers.
+// More namespaces can be declared by platform specific compilers.
export type Namespace = number
-export const enum Namespaces {
- HTML
+export enum Namespaces {
+ HTML,
+ SVG,
+ MATH_ML,
}
-export const enum NodeTypes {
+export enum NodeTypes {
ROOT,
ELEMENT,
TEXT,
@@ -53,14 +57,14 @@ export const enum NodeTypes {
JS_IF_STATEMENT,
JS_ASSIGNMENT_EXPRESSION,
JS_SEQUENCE_EXPRESSION,
- JS_RETURN_STATEMENT
+ JS_RETURN_STATEMENT,
}
-export const enum ElementTypes {
+export enum ElementTypes {
ELEMENT,
COMPONENT,
SLOT,
- TEMPLATE
+ TEMPLATE,
}
export interface Node {
@@ -99,16 +103,18 @@ export type TemplateChildNode =
export interface RootNode extends Node {
type: NodeTypes.ROOT
+ source: string
children: TemplateChildNode[]
helpers: Set
components: string[]
directives: string[]
hoists: (JSChildNode | null)[]
imports: ImportItem[]
- cached: number
+ cached: (CacheExpression | null)[]
temps: number
ssrHelpers?: symbol[]
codegenNode?: TemplateChildNode | JSChildNode | BlockStatement
+ transformed?: boolean
// v2 compat only
filters?: string[]
@@ -125,9 +131,10 @@ export interface BaseElementNode extends Node {
ns: Namespace
tag: string
tagType: ElementTypes
- isSelfClosing: boolean
props: Array
children: TemplateChildNode[]
+ isSelfClosing?: boolean
+ innerLoc?: SourceLocation // only for SFC root level elements
}
export interface PlainElementNode extends BaseElementNode {
@@ -179,19 +186,28 @@ export interface CommentNode extends Node {
export interface AttributeNode extends Node {
type: NodeTypes.ATTRIBUTE
name: string
+ nameLoc: SourceLocation
value: TextNode | undefined
}
export interface DirectiveNode extends Node {
type: NodeTypes.DIRECTIVE
+ /**
+ * the normalized name without prefix or shorthands, e.g. "bind", "on"
+ */
name: string
+ /**
+ * the raw attribute name, preserving shorthand, and including arg & modifiers
+ * this is only used during parse.
+ */
+ rawName?: string
exp: ExpressionNode | undefined
arg: ExpressionNode | undefined
- modifiers: string[]
+ modifiers: SimpleExpressionNode[]
/**
* optional property to cache the expression parse result for v-for
*/
- parseResult?: ForParseResult
+ forParseResult?: ForParseResult
}
/**
@@ -199,11 +215,11 @@ export interface DirectiveNode extends Node {
* Higher levels implies lower levels. e.g. a node that can be stringified
* can always be hoisted and skipped for patch.
*/
-export const enum ConstantTypes {
+export enum ConstantTypes {
NOT_CONSTANT = 0,
CAN_SKIP_PATCH,
- CAN_HOIST,
- CAN_STRINGIFY
+ CAN_CACHE,
+ CAN_STRINGIFY,
}
export interface SimpleExpressionNode extends Node {
@@ -211,6 +227,12 @@ export interface SimpleExpressionNode extends Node {
content: string
isStatic: boolean
constType: ConstantTypes
+ /**
+ * - `null` means the expression is a simple identifier that doesn't need
+ * parsing
+ * - `false` means there was a parsing error
+ */
+ ast?: BabelNode | null | false
/**
* Indicates this is an identifier for a hoist vnode call and points to the
* hoisted node.
@@ -231,6 +253,12 @@ export interface InterpolationNode extends Node {
export interface CompoundExpressionNode extends Node {
type: NodeTypes.COMPOUND_EXPRESSION
+ /**
+ * - `null` means the expression is a simple identifier that doesn't need
+ * parsing
+ * - `false` means there was a parsing error
+ */
+ ast?: BabelNode | null | false
children: (
| SimpleExpressionNode
| CompoundExpressionNode
@@ -273,6 +301,14 @@ export interface ForNode extends Node {
codegenNode?: ForCodegenNode
}
+export interface ForParseResult {
+ source: ExpressionNode
+ value: ExpressionNode | undefined
+ key: ExpressionNode | undefined
+ index: ExpressionNode | undefined
+ finalized: boolean
+}
+
export interface TextCallNode extends Node {
type: NodeTypes.TEXT_CALL
content: TextNode | InterpolationNode | CompoundExpressionNode
@@ -294,8 +330,9 @@ export interface VNodeCall extends Node {
| SlotsExpression // component slots
| ForRenderListExpression // v-for fragment call
| SimpleExpressionNode // hoisted
+ | CacheExpression // cached
| undefined
- patchFlag: string | undefined
+ patchFlag: PatchFlags | undefined
dynamicProps: string | SimpleExpressionNode | undefined
directives: DirectiveArguments | undefined
isBlock: boolean
@@ -380,7 +417,9 @@ export interface CacheExpression extends Node {
type: NodeTypes.JS_CACHE_EXPRESSION
index: number
value: JSChildNode
- isVNode: boolean
+ needPauseTracking: boolean
+ inVOnce: boolean
+ needArraySpread: boolean
}
export interface MemoExpression extends CallExpression {
@@ -459,7 +498,7 @@ export interface RenderSlotCall extends CallExpression {
string,
string | ExpressionNode,
PropsExpression | '{}',
- TemplateChildNode[]
+ TemplateChildNode[],
]
}
@@ -475,7 +514,7 @@ export interface SlotsObjectProperty extends Property {
}
export interface SlotFunctionExpression extends FunctionExpression {
- returns: TemplateChildNode[]
+ returns: TemplateChildNode[] | CacheExpression
}
// createSlots({ ... }, [
@@ -525,7 +564,7 @@ export interface ForCodegenNode extends VNodeCall {
tag: typeof FRAGMENT
props: undefined
children: ForRenderListExpression
- patchFlag: string
+ patchFlag: PatchFlags
disableTracking: boolean
}
@@ -535,7 +574,7 @@ export interface ForRenderListExpression extends CallExpression {
}
export interface ForIteratorExpression extends FunctionExpression {
- returns: BlockCodegenNode
+ returns?: BlockCodegenNode
}
// AST Utilities ---------------------------------------------------------------
@@ -544,27 +583,28 @@ export interface ForIteratorExpression extends FunctionExpression {
// associated with template nodes, so their source locations are just a stub.
// Container types like CompoundExpression also don't need a real location.
export const locStub: SourceLocation = {
- source: '',
start: { line: 1, column: 1, offset: 0 },
- end: { line: 1, column: 1, offset: 0 }
+ end: { line: 1, column: 1, offset: 0 },
+ source: '',
}
export function createRoot(
children: TemplateChildNode[],
- loc = locStub
+ source = '',
): RootNode {
return {
type: NodeTypes.ROOT,
+ source,
children,
helpers: new Set(),
components: [],
directives: [],
hoists: [],
imports: [],
- cached: 0,
+ cached: [],
temps: 0,
codegenNode: undefined,
- loc
+ loc: locStub,
}
}
@@ -579,7 +619,7 @@ export function createVNodeCall(
isBlock: VNodeCall['isBlock'] = false,
disableTracking: VNodeCall['disableTracking'] = false,
isComponent: VNodeCall['isComponent'] = false,
- loc = locStub
+ loc: SourceLocation = locStub,
): VNodeCall {
if (context) {
if (isBlock) {
@@ -604,41 +644,41 @@ export function createVNodeCall(
isBlock,
disableTracking,
isComponent,
- loc
+ loc,
}
}
export function createArrayExpression(
elements: ArrayExpression['elements'],
- loc: SourceLocation = locStub
+ loc: SourceLocation = locStub,
): ArrayExpression {
return {
type: NodeTypes.JS_ARRAY_EXPRESSION,
loc,
- elements
+ elements,
}
}
export function createObjectExpression(
properties: ObjectExpression['properties'],
- loc: SourceLocation = locStub
+ loc: SourceLocation = locStub,
): ObjectExpression {
return {
type: NodeTypes.JS_OBJECT_EXPRESSION,
loc,
- properties
+ properties,
}
}
export function createObjectProperty(
key: Property['key'] | string,
- value: Property['value']
+ value: Property['value'],
): Property {
return {
type: NodeTypes.JS_PROPERTY,
loc: locStub,
key: isString(key) ? createSimpleExpression(key, true) : key,
- value
+ value,
}
}
@@ -646,38 +686,38 @@ export function createSimpleExpression(
content: SimpleExpressionNode['content'],
isStatic: SimpleExpressionNode['isStatic'] = false,
loc: SourceLocation = locStub,
- constType: ConstantTypes = ConstantTypes.NOT_CONSTANT
+ constType: ConstantTypes = ConstantTypes.NOT_CONSTANT,
): SimpleExpressionNode {
return {
type: NodeTypes.SIMPLE_EXPRESSION,
loc,
content,
isStatic,
- constType: isStatic ? ConstantTypes.CAN_STRINGIFY : constType
+ constType: isStatic ? ConstantTypes.CAN_STRINGIFY : constType,
}
}
export function createInterpolation(
content: InterpolationNode['content'] | string,
- loc: SourceLocation
+ loc: SourceLocation,
): InterpolationNode {
return {
type: NodeTypes.INTERPOLATION,
loc,
content: isString(content)
? createSimpleExpression(content, false, loc)
- : content
+ : content,
}
}
export function createCompoundExpression(
children: CompoundExpressionNode['children'],
- loc: SourceLocation = locStub
+ loc: SourceLocation = locStub,
): CompoundExpressionNode {
return {
type: NodeTypes.COMPOUND_EXPRESSION,
loc,
- children
+ children,
}
}
@@ -688,13 +728,13 @@ type InferCodegenNodeType = T extends typeof RENDER_SLOT
export function createCallExpression(
callee: T,
args: CallExpression['arguments'] = [],
- loc: SourceLocation = locStub
+ loc: SourceLocation = locStub,
): InferCodegenNodeType {
return {
type: NodeTypes.JS_CALL_EXPRESSION,
loc,
callee,
- arguments: args
+ arguments: args,
} as InferCodegenNodeType
}
@@ -703,7 +743,7 @@ export function createFunctionExpression(
returns: FunctionExpression['returns'] = undefined,
newline: boolean = false,
isSlot: boolean = false,
- loc: SourceLocation = locStub
+ loc: SourceLocation = locStub,
): FunctionExpression {
return {
type: NodeTypes.JS_FUNCTION_EXPRESSION,
@@ -711,7 +751,7 @@ export function createFunctionExpression(
returns,
newline,
isSlot,
- loc
+ loc,
}
}
@@ -719,7 +759,7 @@ export function createConditionalExpression(
test: ConditionalExpression['test'],
consequent: ConditionalExpression['consequent'],
alternate: ConditionalExpression['alternate'],
- newline = true
+ newline = true,
): ConditionalExpression {
return {
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
@@ -727,86 +767,115 @@ export function createConditionalExpression(
consequent,
alternate,
newline,
- loc: locStub
+ loc: locStub,
}
}
export function createCacheExpression(
index: number,
value: JSChildNode,
- isVNode: boolean = false
+ needPauseTracking: boolean = false,
+ inVOnce: boolean = false,
): CacheExpression {
return {
type: NodeTypes.JS_CACHE_EXPRESSION,
index,
value,
- isVNode,
- loc: locStub
+ needPauseTracking: needPauseTracking,
+ inVOnce,
+ needArraySpread: false,
+ loc: locStub,
}
}
export function createBlockStatement(
- body: BlockStatement['body']
+ body: BlockStatement['body'],
): BlockStatement {
return {
type: NodeTypes.JS_BLOCK_STATEMENT,
body,
- loc: locStub
+ loc: locStub,
}
}
export function createTemplateLiteral(
- elements: TemplateLiteral['elements']
+ elements: TemplateLiteral['elements'],
): TemplateLiteral {
return {
type: NodeTypes.JS_TEMPLATE_LITERAL,
elements,
- loc: locStub
+ loc: locStub,
}
}
export function createIfStatement(
test: IfStatement['test'],
consequent: IfStatement['consequent'],
- alternate?: IfStatement['alternate']
+ alternate?: IfStatement['alternate'],
): IfStatement {
return {
type: NodeTypes.JS_IF_STATEMENT,
test,
consequent,
alternate,
- loc: locStub
+ loc: locStub,
}
}
export function createAssignmentExpression(
left: AssignmentExpression['left'],
- right: AssignmentExpression['right']
+ right: AssignmentExpression['right'],
): AssignmentExpression {
return {
type: NodeTypes.JS_ASSIGNMENT_EXPRESSION,
left,
right,
- loc: locStub
+ loc: locStub,
}
}
export function createSequenceExpression(
- expressions: SequenceExpression['expressions']
+ expressions: SequenceExpression['expressions'],
): SequenceExpression {
return {
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions,
- loc: locStub
+ loc: locStub,
}
}
export function createReturnStatement(
- returns: ReturnStatement['returns']
+ returns: ReturnStatement['returns'],
): ReturnStatement {
return {
type: NodeTypes.JS_RETURN_STATEMENT,
returns,
- loc: locStub
+ loc: locStub,
+ }
+}
+
+export function getVNodeHelper(
+ ssr: boolean,
+ isComponent: boolean,
+): typeof CREATE_VNODE | typeof CREATE_ELEMENT_VNODE {
+ return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE
+}
+
+export function getVNodeBlockHelper(
+ ssr: boolean,
+ isComponent: boolean,
+): typeof CREATE_BLOCK | typeof CREATE_ELEMENT_BLOCK {
+ return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK
+}
+
+export function convertToBlock(
+ node: VNodeCall,
+ { helper, removeHelper, inSSR }: TransformContext,
+): void {
+ if (!node.isBlock) {
+ node.isBlock = true
+ removeHelper(getVNodeHelper(inSSR, node.isComponent))
+ helper(OPEN_BLOCK)
+ helper(getVNodeBlockHelper(inSSR, node.isComponent))
}
}
diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts
index e773015f90f..51614612b10 100644
--- a/packages/compiler-core/src/babelUtils.ts
+++ b/packages/compiler-core/src/babelUtils.ts
@@ -1,73 +1,96 @@
// should only use types from @babel/types
// do not import runtime methods
import type {
+ BlockStatement,
+ ForInStatement,
+ ForOfStatement,
+ ForStatement,
+ Function,
Identifier,
Node,
- Function,
ObjectProperty,
- BlockStatement,
- Program
+ Program,
} from '@babel/types'
import { walk } from 'estree-walker'
+/**
+ * Return value indicates whether the AST walked can be a constant
+ */
export function walkIdentifiers(
root: Node,
onIdentifier: (
node: Identifier,
- parent: Node,
+ parent: Node | null,
parentStack: Node[],
isReference: boolean,
- isLocal: boolean
+ isLocal: boolean,
) => void,
includeAll = false,
parentStack: Node[] = [],
- knownIds: Record = Object.create(null)
-) {
+ knownIds: Record = Object.create(null),
+): void {
if (__BROWSER__) {
return
}
const rootExp =
- root.type === 'Program' &&
- root.body[0].type === 'ExpressionStatement' &&
- root.body[0].expression
+ root.type === 'Program'
+ ? root.body[0].type === 'ExpressionStatement' && root.body[0].expression
+ : root
- ;(walk as any)(root, {
- enter(node: Node & { scopeIds?: Set }, parent: Node | undefined) {
+ walk(root, {
+ enter(node: Node & { scopeIds?: Set }, parent: Node | null) {
parent && parentStack.push(parent)
if (
parent &&
parent.type.startsWith('TS') &&
- parent.type !== 'TSAsExpression' &&
- parent.type !== 'TSNonNullExpression' &&
- parent.type !== 'TSTypeAssertion'
+ !TS_NODE_TYPES.includes(parent.type)
) {
return this.skip()
}
if (node.type === 'Identifier') {
const isLocal = !!knownIds[node.name]
- const isRefed = isReferencedIdentifier(node, parent!, parentStack)
+ const isRefed = isReferencedIdentifier(node, parent, parentStack)
if (includeAll || (isRefed && !isLocal)) {
- onIdentifier(node, parent!, parentStack, isRefed, isLocal)
+ onIdentifier(node, parent, parentStack, isRefed, isLocal)
}
} else if (
node.type === 'ObjectProperty' &&
- parent!.type === 'ObjectPattern'
+ // eslint-disable-next-line no-restricted-syntax
+ parent?.type === 'ObjectPattern'
) {
// mark property in destructure pattern
;(node as any).inPattern = true
} else if (isFunctionType(node)) {
- // walk function expressions and add its arguments to known identifiers
- // so that we don't prefix them
- walkFunctionParams(node, id => markScopeIdentifier(node, id, knownIds))
+ if (node.scopeIds) {
+ node.scopeIds.forEach(id => markKnownIds(id, knownIds))
+ } else {
+ // walk function expressions and add its arguments to known identifiers
+ // so that we don't prefix them
+ walkFunctionParams(node, id =>
+ markScopeIdentifier(node, id, knownIds),
+ )
+ }
} else if (node.type === 'BlockStatement') {
- // #3445 record block-level local variables
- walkBlockDeclarations(node, id =>
+ if (node.scopeIds) {
+ node.scopeIds.forEach(id => markKnownIds(id, knownIds))
+ } else {
+ // #3445 record block-level local variables
+ walkBlockDeclarations(node, id =>
+ markScopeIdentifier(node, id, knownIds),
+ )
+ }
+ } else if (node.type === 'CatchClause' && node.param) {
+ for (const id of extractIdentifiers(node.param)) {
markScopeIdentifier(node, id, knownIds)
+ }
+ } else if (isForStatement(node)) {
+ walkForStatement(node, false, id =>
+ markScopeIdentifier(node, id, knownIds),
)
}
},
- leave(node: Node & { scopeIds?: Set }, parent: Node | undefined) {
+ leave(node: Node & { scopeIds?: Set }, parent: Node | null) {
parent && parentStack.pop()
if (node !== rootExp && node.scopeIds) {
for (const id of node.scopeIds) {
@@ -77,15 +100,15 @@ export function walkIdentifiers(
}
}
}
- }
+ },
})
}
export function isReferencedIdentifier(
id: Identifier,
parent: Node | null,
- parentStack: Node[]
-) {
+ parentStack: Node[],
+): boolean {
if (__BROWSER__) {
return false
}
@@ -99,7 +122,7 @@ export function isReferencedIdentifier(
return false
}
- if (isReferenced(id, parent)) {
+ if (isReferenced(id, parent, parentStack[parentStack.length - 2])) {
return true
}
@@ -109,7 +132,8 @@ export function isReferencedIdentifier(
case 'AssignmentExpression':
case 'AssignmentPattern':
return true
- case 'ObjectPattern':
+ case 'ObjectProperty':
+ return parent.key !== id && isInDestructureAssignment(parent, parentStack)
case 'ArrayPattern':
return isInDestructureAssignment(parent, parentStack)
}
@@ -119,7 +143,7 @@ export function isReferencedIdentifier(
export function isInDestructureAssignment(
parent: Node,
- parentStack: Node[]
+ parentStack: Node[],
): boolean {
if (
parent &&
@@ -138,10 +162,23 @@ export function isInDestructureAssignment(
return false
}
+export function isInNewExpression(parentStack: Node[]): boolean {
+ let i = parentStack.length
+ while (i--) {
+ const p = parentStack[i]
+ if (p.type === 'NewExpression') {
+ return true
+ } else if (p.type !== 'MemberExpression') {
+ break
+ }
+ }
+ return false
+}
+
export function walkFunctionParams(
node: Function,
- onIdent: (id: Identifier) => void
-) {
+ onIdent: (id: Identifier) => void,
+): void {
for (const p of node.params) {
for (const id of extractIdentifiers(p)) {
onIdent(id)
@@ -151,8 +188,8 @@ export function walkFunctionParams(
export function walkBlockDeclarations(
block: BlockStatement | Program,
- onIdent: (node: Identifier) => void
-) {
+ onIdent: (node: Identifier) => void,
+): void {
for (const stmt of block.body) {
if (stmt.type === 'VariableDeclaration') {
if (stmt.declare) continue
@@ -167,13 +204,44 @@ export function walkBlockDeclarations(
) {
if (stmt.declare || !stmt.id) continue
onIdent(stmt.id)
+ } else if (isForStatement(stmt)) {
+ walkForStatement(stmt, true, onIdent)
+ }
+ }
+}
+
+function isForStatement(
+ stmt: Node,
+): stmt is ForStatement | ForOfStatement | ForInStatement {
+ return (
+ stmt.type === 'ForOfStatement' ||
+ stmt.type === 'ForInStatement' ||
+ stmt.type === 'ForStatement'
+ )
+}
+
+function walkForStatement(
+ stmt: ForStatement | ForOfStatement | ForInStatement,
+ isVar: boolean,
+ onIdent: (id: Identifier) => void,
+) {
+ const variable = stmt.type === 'ForStatement' ? stmt.init : stmt.left
+ if (
+ variable &&
+ variable.type === 'VariableDeclaration' &&
+ (variable.kind === 'var' ? isVar : !isVar)
+ ) {
+ for (const decl of variable.declarations) {
+ for (const id of extractIdentifiers(decl.id)) {
+ onIdent(id)
+ }
}
}
}
export function extractIdentifiers(
param: Node,
- nodes: Identifier[] = []
+ nodes: Identifier[] = [],
): Identifier[] {
switch (param.type) {
case 'Identifier':
@@ -216,20 +284,24 @@ export function extractIdentifiers(
return nodes
}
+function markKnownIds(name: string, knownIds: Record) {
+ if (name in knownIds) {
+ knownIds[name]++
+ } else {
+ knownIds[name] = 1
+ }
+}
+
function markScopeIdentifier(
node: Node & { scopeIds?: Set },
child: Identifier,
- knownIds: Record
+ knownIds: Record,
) {
const { name } = child
if (node.scopeIds && node.scopeIds.has(name)) {
return
}
- if (name in knownIds) {
- knownIds[name]++
- } else {
- knownIds[name] = 1
- }
+ markKnownIds(name, knownIds)
;(node.scopeIds || (node.scopeIds = new Set())).add(name)
}
@@ -242,7 +314,7 @@ export const isStaticProperty = (node: Node): node is ObjectProperty =>
(node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
!node.computed
-export const isStaticPropertyKey = (node: Node, parent: Node) =>
+export const isStaticPropertyKey = (node: Node, parent: Node): boolean =>
isStaticProperty(parent) && parent.key === node
/**
@@ -366,6 +438,7 @@ function isReferenced(node: Node, parent: Node, grandparent?: Node): boolean {
// no: export { NODE as foo } from "foo";
case 'ExportSpecifier':
// @ts-expect-error
+ // eslint-disable-next-line no-restricted-syntax
if (grandparent?.source) {
return false
}
@@ -422,3 +495,19 @@ function isReferenced(node: Node, parent: Node, grandparent?: Node): boolean {
return true
}
+
+export const TS_NODE_TYPES: string[] = [
+ 'TSAsExpression', // foo as number
+ 'TSTypeAssertion', // (foo)
+ 'TSNonNullExpression', // foo!
+ 'TSInstantiationExpression', // foo
+ 'TSSatisfiesExpression', // foo satisfies T
+]
+
+export function unwrapTSNode(node: Node): Node {
+ if (TS_NODE_TYPES.includes(node.type)) {
+ return unwrapTSNode((node as any).expression)
+ } else {
+ return node
+ }
+}
diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts
index dce58737735..6b4559fabb2 100644
--- a/packages/compiler-core/src/codegen.ts
+++ b/packages/compiler-core/src/codegen.ts
@@ -1,62 +1,105 @@
-import { CodegenOptions } from './options'
+import type { CodegenOptions } from './options'
import {
- RootNode,
- TemplateChildNode,
- TextNode,
- CommentNode,
- ExpressionNode,
+ type ArrayExpression,
+ type AssignmentExpression,
+ type CacheExpression,
+ type CallExpression,
+ type CommentNode,
+ type CompoundExpressionNode,
+ type ConditionalExpression,
+ type ExpressionNode,
+ type FunctionExpression,
+ type IfStatement,
+ type InterpolationNode,
+ type JSChildNode,
NodeTypes,
- JSChildNode,
- CallExpression,
- ArrayExpression,
- ObjectExpression,
- Position,
- InterpolationNode,
- CompoundExpressionNode,
- SimpleExpressionNode,
- FunctionExpression,
- ConditionalExpression,
- CacheExpression,
+ type ObjectExpression,
+ type Position,
+ type ReturnStatement,
+ type RootNode,
+ type SSRCodegenNode,
+ type SequenceExpression,
+ type SimpleExpressionNode,
+ type TemplateChildNode,
+ type TemplateLiteral,
+ type TextNode,
+ type VNodeCall,
+ getVNodeBlockHelper,
+ getVNodeHelper,
locStub,
- SSRCodegenNode,
- TemplateLiteral,
- IfStatement,
- AssignmentExpression,
- ReturnStatement,
- VNodeCall,
- SequenceExpression
} from './ast'
-import { SourceMapGenerator, RawSourceMap } from 'source-map'
+import { SourceMapGenerator } from 'source-map-js'
import {
advancePositionWithMutation,
assert,
- getVNodeBlockHelper,
- getVNodeHelper,
isSimpleIdentifier,
- toValidAssetId
+ toValidAssetId,
} from './utils'
-import { isString, isArray, isSymbol } from '@vue/shared'
import {
- helperNameMap,
- TO_DISPLAY_STRING,
+ PatchFlagNames,
+ type PatchFlags,
+ isArray,
+ isString,
+ isSymbol,
+} from '@vue/shared'
+import {
+ CREATE_COMMENT,
+ CREATE_ELEMENT_VNODE,
+ CREATE_STATIC,
+ CREATE_TEXT,
CREATE_VNODE,
+ OPEN_BLOCK,
RESOLVE_COMPONENT,
RESOLVE_DIRECTIVE,
+ RESOLVE_FILTER,
SET_BLOCK_TRACKING,
- CREATE_COMMENT,
- CREATE_TEXT,
- PUSH_SCOPE_ID,
- POP_SCOPE_ID,
- WITH_DIRECTIVES,
- CREATE_ELEMENT_VNODE,
- OPEN_BLOCK,
- CREATE_STATIC,
+ TO_DISPLAY_STRING,
WITH_CTX,
- RESOLVE_FILTER
+ WITH_DIRECTIVES,
+ helperNameMap,
} from './runtimeHelpers'
-import { ImportItem } from './transform'
+import type { ImportItem } from './transform'
+
+/**
+ * The `SourceMapGenerator` type from `source-map-js` is a bit incomplete as it
+ * misses `toJSON()`. We also need to add types for internal properties which we
+ * need to access for better performance.
+ *
+ * Since TS 5.3, dts generation starts to strangely include broken triple slash
+ * references for source-map-js, so we are inlining all source map related types
+ * here to to workaround that.
+ */
+export interface CodegenSourceMapGenerator {
+ setSourceContent(sourceFile: string, sourceContent: string): void
+ // SourceMapGenerator has this method but the types do not include it
+ toJSON(): RawSourceMap
+ _sources: Set
+ _names: Set
+ _mappings: {
+ add(mapping: MappingItem): void
+ }
+}
+
+export interface RawSourceMap {
+ file?: string
+ sourceRoot?: string
+ version: string
+ sources: string[]
+ names: string[]
+ sourcesContent?: string[]
+ mappings: string
+}
-const PURE_ANNOTATION = `/*#__PURE__*/`
+interface MappingItem {
+ source: string
+ generatedLine: number
+ generatedColumn: number
+ originalLine: number
+ originalColumn: number
+ name: string | null
+}
+
+const PURE_ANNOTATION = `/*@__PURE__*/`
const aliasHelper = (s: symbol) => `${helperNameMap[s]}: _${helperNameMap[s]}`
@@ -69,6 +112,13 @@ export interface CodegenResult {
map?: RawSourceMap
}
+enum NewlineType {
+ Start = 0,
+ End = -1,
+ None = -2,
+ Unknown = -3,
+}
+
export interface CodegenContext
extends Omit, 'bindingMetadata' | 'inline'> {
source: string
@@ -78,9 +128,9 @@ export interface CodegenContext
offset: number
indentLevel: number
pure: boolean
- map?: SourceMapGenerator
+ map?: CodegenSourceMapGenerator
helper(key: symbol): string
- push(code: string, node?: CodegenNode): void
+ push(code: string, newlineIndex?: number, node?: CodegenNode): void
indent(): void
deindent(withoutNewLine?: boolean): void
newline(): void
@@ -100,8 +150,8 @@ function createCodegenContext(
ssrRuntimeModuleName = 'vue/server-renderer',
ssr = false,
isTS = false,
- inSSR = false
- }: CodegenOptions
+ inSSR = false,
+ }: CodegenOptions,
): CodegenContext {
const context: CodegenContext = {
mode,
@@ -116,7 +166,7 @@ function createCodegenContext(
ssr,
isTS,
inSSR,
- source: ast.loc.source,
+ source: ast.source,
code: ``,
column: 1,
line: 1,
@@ -127,7 +177,7 @@ function createCodegenContext(
helper(key) {
return `_${helperNameMap[key]}`
},
- push(code, node) {
+ push(code, newlineIndex = NewlineType.None, node) {
context.code += code
if (!__BROWSER__ && context.map) {
if (node) {
@@ -138,10 +188,46 @@ function createCodegenContext(
name = content
}
}
- addMapping(node.loc.start, name)
+ if (node.loc.source) {
+ addMapping(node.loc.start, name)
+ }
+ }
+ if (newlineIndex === NewlineType.Unknown) {
+ // multiple newlines, full iteration
+ advancePositionWithMutation(context, code)
+ } else {
+ // fast paths
+ context.offset += code.length
+ if (newlineIndex === NewlineType.None) {
+ // no newlines; fast path to avoid newline detection
+ if (__TEST__ && code.includes('\n')) {
+ throw new Error(
+ `CodegenContext.push() called newlineIndex: none, but contains` +
+ `newlines: ${code.replace(/\n/g, '\\n')}`,
+ )
+ }
+ context.column += code.length
+ } else {
+ // single newline at known index
+ if (newlineIndex === NewlineType.End) {
+ newlineIndex = code.length - 1
+ }
+ if (
+ __TEST__ &&
+ (code.charAt(newlineIndex) !== '\n' ||
+ code.slice(0, newlineIndex).includes('\n') ||
+ code.slice(newlineIndex + 1).includes('\n'))
+ ) {
+ throw new Error(
+ `CodegenContext.push() called with newlineIndex: ${newlineIndex} ` +
+ `but does not conform: ${code.replace(/\n/g, '\\n')}`,
+ )
+ }
+ context.line++
+ context.column = code.length - newlineIndex
+ }
}
- advancePositionWithMutation(context, code)
- if (node && node.loc !== locStub) {
+ if (node && node.loc !== locStub && node.loc.source) {
addMapping(node.loc.end)
}
}
@@ -158,32 +244,35 @@ function createCodegenContext(
},
newline() {
newline(context.indentLevel)
- }
+ },
}
function newline(n: number) {
- context.push('\n' + ` `.repeat(n))
+ context.push('\n' + ` `.repeat(n), NewlineType.Start)
}
- function addMapping(loc: Position, name?: string) {
- context.map!.addMapping({
+ function addMapping(loc: Position, name: string | null = null) {
+ // we use the private property to directly add the mapping
+ // because the addMapping() implementation in source-map-js has a bunch of
+ // unnecessary arg and validation checks that are pure overhead in our case.
+ const { _names, _mappings } = context.map!
+ if (name !== null && !_names.has(name)) _names.add(name)
+ _mappings.add({
+ originalLine: loc.line,
+ originalColumn: loc.column - 1, // source-map column is 0 based
+ generatedLine: context.line,
+ generatedColumn: context.column - 1,
+ source: filename,
name,
- source: context.filename,
- original: {
- line: loc.line,
- column: loc.column - 1 // source-map column is 0 based
- },
- generated: {
- line: context.line,
- column: context.column - 1
- }
})
}
if (!__BROWSER__ && sourceMap) {
// lazy require source-map implementation, only in non-browser builds
- context.map = new SourceMapGenerator()
- context.map!.setSourceContent(filename, context.source)
+ context.map =
+ new SourceMapGenerator() as unknown as CodegenSourceMapGenerator
+ context.map.setSourceContent(filename, context.source)
+ context.map._sources.add(filename)
}
return context
@@ -193,7 +282,7 @@ export function generate(
ast: RootNode,
options: CodegenOptions & {
onContextCreated?: (context: CodegenContext) => void
- } = {}
+ } = {},
): CodegenResult {
const context = createCodegenContext(ast, options)
if (options.onContextCreated) options.onContextCreated(context)
@@ -205,7 +294,7 @@ export function generate(
deindent,
newline,
scopeId,
- ssr
+ ssr,
} = context
const helpers = Array.from(ast.helpers)
@@ -250,8 +339,10 @@ export function generate(
// function mode const declarations should be inside with block
// also they should be renamed to avoid collision with user properties
if (hasHelpers) {
- push(`const { ${helpers.map(aliasHelper).join(', ')} } = _Vue`)
- push(`\n`)
+ push(
+ `const { ${helpers.map(aliasHelper).join(', ')} } = _Vue\n`,
+ NewlineType.End,
+ )
newline()
}
}
@@ -282,7 +373,7 @@ export function generate(
}
}
if (ast.components.length || ast.directives.length || ast.temps) {
- push(`\n`)
+ push(`\n`, NewlineType.Start)
newline()
}
@@ -308,8 +399,7 @@ export function generate(
ast,
code: context.code,
preamble: isSetupInlined ? preambleContext.code : ``,
- // SourceMapGenerator does have toJSON() method but it's not in the types
- map: context.map ? (context.map as any).toJSON() : undefined
+ map: context.map ? context.map.toJSON() : undefined,
}
}
@@ -321,7 +411,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
newline,
runtimeModuleName,
runtimeGlobalName,
- ssrRuntimeModuleName
+ ssrRuntimeModuleName,
} = context
const VueBinding =
!__BROWSER__ && ssr
@@ -334,11 +424,14 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
const helpers = Array.from(ast.helpers)
if (helpers.length > 0) {
if (!__BROWSER__ && prefixIdentifiers) {
- push(`const { ${helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`)
+ push(
+ `const { ${helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`,
+ NewlineType.End,
+ )
} else {
// "with" mode.
// save Vue in a separate variable to avoid collision
- push(`const _Vue = ${VueBinding}\n`)
+ push(`const _Vue = ${VueBinding}\n`, NewlineType.End)
// in "with" mode, helpers are declared inside the with block to avoid
// has check cost, but hoists are lifted out of the function - we need
// to provide the helper here.
@@ -348,12 +441,12 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
CREATE_ELEMENT_VNODE,
CREATE_COMMENT,
CREATE_TEXT,
- CREATE_STATIC
+ CREATE_STATIC,
]
.filter(helper => helpers.includes(helper))
.map(aliasHelper)
.join(', ')
- push(`const { ${staticHelpers} } = _Vue\n`)
+ push(`const { ${staticHelpers} } = _Vue\n`, NewlineType.End)
}
}
}
@@ -363,7 +456,8 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
push(
`const { ${ast.ssrHelpers
.map(aliasHelper)
- .join(', ')} } = require("${ssrRuntimeModuleName}")\n`
+ .join(', ')} } = require("${ssrRuntimeModuleName}")\n`,
+ NewlineType.End,
)
}
genHoists(ast.hoists, context)
@@ -375,21 +469,16 @@ function genModulePreamble(
ast: RootNode,
context: CodegenContext,
genScopeId: boolean,
- inline?: boolean
+ inline?: boolean,
) {
const {
push,
newline,
optimizeImports,
runtimeModuleName,
- ssrRuntimeModuleName
+ ssrRuntimeModuleName,
} = context
- if (genScopeId && ast.hoists.length) {
- ast.helpers.add(PUSH_SCOPE_ID)
- ast.helpers.add(POP_SCOPE_ID)
- }
-
// generate import statements for helpers
if (ast.helpers.size) {
const helpers = Array.from(ast.helpers)
@@ -402,18 +491,21 @@ function genModulePreamble(
push(
`import { ${helpers
.map(s => helperNameMap[s])
- .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
+ .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`,
+ NewlineType.End,
)
push(
`\n// Binding optimization for webpack code-split\nconst ${helpers
.map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)
- .join(', ')}\n`
+ .join(', ')}\n`,
+ NewlineType.End,
)
} else {
push(
`import { ${helpers
.map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
- .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
+ .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`,
+ NewlineType.End,
)
}
}
@@ -422,7 +514,8 @@ function genModulePreamble(
push(
`import { ${ast.ssrHelpers
.map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
- .join(', ')} } from "${ssrRuntimeModuleName}"\n`
+ .join(', ')} } from "${ssrRuntimeModuleName}"\n`,
+ NewlineType.End,
)
}
@@ -442,14 +535,14 @@ function genModulePreamble(
function genAssets(
assets: string[],
type: 'component' | 'directive' | 'filter',
- { helper, push, newline, isTS }: CodegenContext
+ { helper, push, newline, isTS }: CodegenContext,
) {
const resolver = helper(
__COMPAT__ && type === 'filter'
? RESOLVE_FILTER
: type === 'component'
- ? RESOLVE_COMPONENT
- : RESOLVE_DIRECTIVE
+ ? RESOLVE_COMPONENT
+ : RESOLVE_DIRECTIVE,
)
for (let i = 0; i < assets.length; i++) {
let id = assets[i]
@@ -461,7 +554,7 @@ function genAssets(
push(
`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${
maybeSelfReference ? `, true` : ``
- })${isTS ? `!` : ``}`
+ })${isTS ? `!` : ``}`,
)
if (i < assets.length - 1) {
newline()
@@ -474,33 +567,14 @@ function genHoists(hoists: (JSChildNode | null)[], context: CodegenContext) {
return
}
context.pure = true
- const { push, newline, helper, scopeId, mode } = context
- const genScopeId = !__BROWSER__ && scopeId != null && mode !== 'function'
+ const { push, newline } = context
newline()
- // generate inlined withScopeId helper
- if (genScopeId) {
- push(
- `const _withScopeId = n => (${helper(
- PUSH_SCOPE_ID
- )}("${scopeId}"),n=n(),${helper(POP_SCOPE_ID)}(),n)`
- )
- newline()
- }
-
for (let i = 0; i < hoists.length; i++) {
const exp = hoists[i]
if (exp) {
- const needScopeIdWrapper = genScopeId && exp.type === NodeTypes.VNODE_CALL
- push(
- `const _hoisted_${i + 1} = ${
- needScopeIdWrapper ? `${PURE_ANNOTATION} _withScopeId(() => ` : ``
- }`
- )
+ push(`const _hoisted_${i + 1} = `)
genNode(exp, context)
- if (needScopeIdWrapper) {
- push(`)`)
- }
newline()
}
}
@@ -532,7 +606,7 @@ function isText(n: string | CodegenNode) {
function genNodeListAsArray(
nodes: (string | CodegenNode | TemplateChildNode[])[],
- context: CodegenContext
+ context: CodegenContext,
) {
const multilines =
nodes.length > 3 ||
@@ -548,13 +622,13 @@ function genNodeList(
nodes: (string | symbol | CodegenNode | TemplateChildNode[])[],
context: CodegenContext,
multilines: boolean = false,
- comma: boolean = true
+ comma: boolean = true,
) {
const { push, newline } = context
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]
if (isString(node)) {
- push(node)
+ push(node, NewlineType.Unknown)
} else if (isArray(node)) {
genNodeListAsArray(node, context)
} else {
@@ -573,7 +647,7 @@ function genNodeList(
function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
if (isString(node)) {
- context.push(node)
+ context.push(node, NewlineType.Unknown)
return
}
if (isSymbol(node)) {
@@ -588,7 +662,7 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
assert(
node.codegenNode != null,
`Codegen node is missing for element/if/for node. ` +
- `Apply appropriate transforms first.`
+ `Apply appropriate transforms first.`,
)
genNode(node.codegenNode!, context)
break
@@ -653,7 +727,7 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
!__BROWSER__ && genReturnStatement(node, context)
break
- /* istanbul ignore next */
+ /* v8 ignore start */
case NodeTypes.IF_BRANCH:
// noop
break
@@ -664,19 +738,24 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
const exhaustiveCheck: never = node
return exhaustiveCheck
}
+ /* v8 ignore stop */
}
}
function genText(
node: TextNode | SimpleExpressionNode,
- context: CodegenContext
+ context: CodegenContext,
) {
- context.push(JSON.stringify(node.content), node)
+ context.push(JSON.stringify(node.content), NewlineType.Unknown, node)
}
function genExpression(node: SimpleExpressionNode, context: CodegenContext) {
const { content, isStatic } = node
- context.push(isStatic ? JSON.stringify(content) : content, node)
+ context.push(
+ isStatic ? JSON.stringify(content) : content,
+ NewlineType.Unknown,
+ node,
+ )
}
function genInterpolation(node: InterpolationNode, context: CodegenContext) {
@@ -689,12 +768,12 @@ function genInterpolation(node: InterpolationNode, context: CodegenContext) {
function genCompoundExpression(
node: CompoundExpressionNode,
- context: CodegenContext
+ context: CodegenContext,
) {
for (let i = 0; i < node.children!.length; i++) {
const child = node.children![i]
if (isString(child)) {
- context.push(child)
+ context.push(child, NewlineType.Unknown)
} else {
genNode(child, context)
}
@@ -703,7 +782,7 @@ function genCompoundExpression(
function genExpressionAsPropertyKey(
node: ExpressionNode,
- context: CodegenContext
+ context: CodegenContext,
) {
const { push } = context
if (node.type === NodeTypes.COMPOUND_EXPRESSION) {
@@ -715,9 +794,9 @@ function genExpressionAsPropertyKey(
const text = isSimpleIdentifier(node.content)
? node.content
: JSON.stringify(node.content)
- push(text, node)
+ push(text, NewlineType.None, node)
} else {
- push(`[${node.content}]`, node)
+ push(`[${node.content}]`, NewlineType.Unknown, node)
}
}
@@ -726,7 +805,11 @@ function genComment(node: CommentNode, context: CodegenContext) {
if (pure) {
push(PURE_ANNOTATION)
}
- push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node)
+ push(
+ `${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`,
+ NewlineType.Unknown,
+ node,
+ )
}
function genVNodeCall(node: VNodeCall, context: CodegenContext) {
@@ -740,8 +823,30 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
directives,
isBlock,
disableTracking,
- isComponent
+ isComponent,
} = node
+
+ // add dev annotations to patch flags
+ let patchFlagString
+ if (patchFlag) {
+ if (__DEV__) {
+ if (patchFlag < 0) {
+ // special flags (negative and mutually exclusive)
+ patchFlagString = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`
+ } else {
+ // bitwise flags
+ const flagNames = Object.keys(PatchFlagNames)
+ .map(Number)
+ .filter(n => n > 0 && patchFlag & n)
+ .map(n => PatchFlagNames[n as PatchFlags])
+ .join(`, `)
+ patchFlagString = patchFlag + ` /* ${flagNames} */`
+ }
+ } else {
+ patchFlagString = String(patchFlag)
+ }
+ }
+
if (directives) {
push(helper(WITH_DIRECTIVES) + `(`)
}
@@ -754,10 +859,10 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
const callHelper: symbol = isBlock
? getVNodeBlockHelper(context.inSSR, isComponent)
: getVNodeHelper(context.inSSR, isComponent)
- push(helper(callHelper) + `(`, node)
+ push(helper(callHelper) + `(`, NewlineType.None, node)
genNodeList(
- genNullableArgs([tag, props, children, patchFlag, dynamicProps]),
- context
+ genNullableArgs([tag, props, children, patchFlagString, dynamicProps]),
+ context,
)
push(`)`)
if (isBlock) {
@@ -785,7 +890,7 @@ function genCallExpression(node: CallExpression, context: CodegenContext) {
if (pure) {
push(PURE_ANNOTATION)
}
- push(callee + `(`, node)
+ push(callee + `(`, NewlineType.None, node)
genNodeList(node.arguments, context)
push(`)`)
}
@@ -794,7 +899,7 @@ function genObjectExpression(node: ObjectExpression, context: CodegenContext) {
const { push, indent, deindent, newline } = context
const { properties } = node
if (!properties.length) {
- push(`{}`, node)
+ push(`{}`, NewlineType.None, node)
return
}
const multilines =
@@ -826,7 +931,7 @@ function genArrayExpression(node: ArrayExpression, context: CodegenContext) {
function genFunctionExpression(
node: FunctionExpression,
- context: CodegenContext
+ context: CodegenContext,
) {
const { push, indent, deindent } = context
const { params, returns, body, newline, isSlot } = node
@@ -834,7 +939,7 @@ function genFunctionExpression(
// wrap slot functions with owner context
push(`_${helperNameMap[WITH_CTX]}(`)
}
- push(`(`, node)
+ push(`(`, NewlineType.None, node)
if (isArray(params)) {
genNodeList(params, context)
} else if (params) {
@@ -871,7 +976,7 @@ function genFunctionExpression(
function genConditionalExpression(
node: ConditionalExpression,
- context: CodegenContext
+ context: CodegenContext,
) {
const { test, consequent, alternate, newline: needNewline } = node
const { push, indent, deindent, newline } = context
@@ -907,16 +1012,23 @@ function genConditionalExpression(
function genCacheExpression(node: CacheExpression, context: CodegenContext) {
const { push, helper, indent, deindent, newline } = context
+ const { needPauseTracking, needArraySpread } = node
+ if (needArraySpread) {
+ push(`[...(`)
+ }
push(`_cache[${node.index}] || (`)
- if (node.isVNode) {
+ if (needPauseTracking) {
indent()
- push(`${helper(SET_BLOCK_TRACKING)}(-1),`)
+ push(`${helper(SET_BLOCK_TRACKING)}(-1`)
+ if (node.inVOnce) push(`, true`)
+ push(`),`)
newline()
+ push(`(`)
}
push(`_cache[${node.index}] = `)
genNode(node.value, context)
- if (node.isVNode) {
- push(`,`)
+ if (needPauseTracking) {
+ push(`).cacheIndex = ${node.index},`)
newline()
push(`${helper(SET_BLOCK_TRACKING)}(1),`)
newline()
@@ -924,6 +1036,9 @@ function genCacheExpression(node: CacheExpression, context: CodegenContext) {
deindent()
}
push(`)`)
+ if (needArraySpread) {
+ push(`)]`)
+ }
}
function genTemplateLiteral(node: TemplateLiteral, context: CodegenContext) {
@@ -934,7 +1049,7 @@ function genTemplateLiteral(node: TemplateLiteral, context: CodegenContext) {
for (let i = 0; i < l; i++) {
const e = node.elements[i]
if (isString(e)) {
- push(e.replace(/(`|\$|\\)/g, '\\$1'))
+ push(e.replace(/(`|\$|\\)/g, '\\$1'), NewlineType.Unknown)
} else {
push('${')
if (multilines) indent()
@@ -972,7 +1087,7 @@ function genIfStatement(node: IfStatement, context: CodegenContext) {
function genAssignmentExpression(
node: AssignmentExpression,
- context: CodegenContext
+ context: CodegenContext,
) {
genNode(node.left, context)
context.push(` = `)
@@ -981,7 +1096,7 @@ function genAssignmentExpression(
function genSequenceExpression(
node: SequenceExpression,
- context: CodegenContext
+ context: CodegenContext,
) {
context.push(`(`)
genNodeList(node.expressions, context)
@@ -990,7 +1105,7 @@ function genSequenceExpression(
function genReturnStatement(
{ returns }: ReturnStatement,
- context: CodegenContext
+ context: CodegenContext,
) {
context.push(`return `)
if (isArray(returns)) {
diff --git a/packages/compiler-core/src/compat/compatConfig.ts b/packages/compiler-core/src/compat/compatConfig.ts
index dcb304263b4..58c5d9611f2 100644
--- a/packages/compiler-core/src/compat/compatConfig.ts
+++ b/packages/compiler-core/src/compat/compatConfig.ts
@@ -1,7 +1,7 @@
-import { SourceLocation } from '../ast'
-import { CompilerError } from '../errors'
-import { ParserContext } from '../parse'
-import { TransformContext } from '../transform'
+import type { SourceLocation } from '../ast'
+import type { CompilerError } from '../errors'
+import type { MergedParserOptions } from '../parser'
+import type { TransformContext } from '../transform'
export type CompilerCompatConfig = Partial<
Record
@@ -13,16 +13,15 @@ export interface CompilerCompatOptions {
compatConfig?: CompilerCompatConfig
}
-export const enum CompilerDeprecationTypes {
+export enum CompilerDeprecationTypes {
COMPILER_IS_ON_ELEMENT = 'COMPILER_IS_ON_ELEMENT',
COMPILER_V_BIND_SYNC = 'COMPILER_V_BIND_SYNC',
- COMPILER_V_BIND_PROP = 'COMPILER_V_BIND_PROP',
COMPILER_V_BIND_OBJECT_ORDER = 'COMPILER_V_BIND_OBJECT_ORDER',
COMPILER_V_ON_NATIVE = 'COMPILER_V_ON_NATIVE',
COMPILER_V_IF_V_FOR_PRECEDENCE = 'COMPILER_V_IF_V_FOR_PRECEDENCE',
COMPILER_NATIVE_TEMPLATE = 'COMPILER_NATIVE_TEMPLATE',
COMPILER_INLINE_TEMPLATE = 'COMPILER_INLINE_TEMPLATE',
- COMPILER_FILTERS = 'COMPILER_FILTER'
+ COMPILER_FILTERS = 'COMPILER_FILTERS',
}
type DeprecationData = {
@@ -36,7 +35,7 @@ const deprecationData: Record = {
`Platform-native elements with "is" prop will no longer be ` +
`treated as components in Vue 3 unless the "is" value is explicitly ` +
`prefixed with "vue:".`,
- link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
+ link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`,
},
[CompilerDeprecationTypes.COMPILER_V_BIND_SYNC]: {
@@ -44,13 +43,7 @@ const deprecationData: Record = {
`.sync modifier for v-bind has been removed. Use v-model with ` +
`argument instead. \`v-bind:${key}.sync\` should be changed to ` +
`\`v-model:${key}\`.`,
- link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
- },
-
- [CompilerDeprecationTypes.COMPILER_V_BIND_PROP]: {
- message:
- `.prop modifier for v-bind has been removed and no longer necessary. ` +
- `Vue 3 will automatically set a binding as DOM property when appropriate.`
+ link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`,
},
[CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER]: {
@@ -60,12 +53,12 @@ const deprecationData: Record = {
`that appears before v-bind in the case of conflict. ` +
`To retain 2.x behavior, move v-bind to make it the first attribute. ` +
`You can also suppress this warning if the usage is intended.`,
- link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
+ link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`,
},
[CompilerDeprecationTypes.COMPILER_V_ON_NATIVE]: {
message: `.native modifier for v-on has been removed as is no longer necessary.`,
- link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
+ link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`,
},
[CompilerDeprecationTypes.COMPILER_V_IF_V_FOR_PRECEDENCE]: {
@@ -75,18 +68,18 @@ const deprecationData: Record = {
`access to v-for scope variables. It is best to avoid the ambiguity ` +
`with tags or use a computed property that filters v-for ` +
`data source.`,
- link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
+ link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`,
},
[CompilerDeprecationTypes.COMPILER_NATIVE_TEMPLATE]: {
message:
` with no special directives will render as a native template ` +
- `element instead of its inner content in Vue 3.`
+ `element instead of its inner content in Vue 3.`,
},
[CompilerDeprecationTypes.COMPILER_INLINE_TEMPLATE]: {
message: `"inline-template" has been removed in Vue 3.`,
- link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
+ link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`,
},
[CompilerDeprecationTypes.COMPILER_FILTERS]: {
@@ -94,18 +87,15 @@ const deprecationData: Record = {
`filters have been removed in Vue 3. ` +
`The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
`Use method calls or computed properties instead.`,
- link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
- }
+ link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`,
+ },
}
function getCompatValue(
key: CompilerDeprecationTypes | 'MODE',
- context: ParserContext | TransformContext
+ { compatConfig }: MergedParserOptions | TransformContext,
) {
- const config = (context as ParserContext).options
- ? (context as ParserContext).options.compatConfig
- : (context as TransformContext).compatConfig
- const value = config && config[key]
+ const value = compatConfig && compatConfig[key]
if (key === 'MODE') {
return value || 3 // compiler defaults to v3 behavior
} else {
@@ -115,8 +105,8 @@ function getCompatValue(
export function isCompatEnabled(
key: CompilerDeprecationTypes,
- context: ParserContext | TransformContext
-) {
+ context: MergedParserOptions | TransformContext,
+): boolean {
const mode = getCompatValue('MODE', context)
const value = getCompatValue(key, context)
// in v3 mode, only enable if explicitly set to true
@@ -126,7 +116,7 @@ export function isCompatEnabled(
export function checkCompatEnabled(
key: CompilerDeprecationTypes,
- context: ParserContext | TransformContext,
+ context: MergedParserOptions | TransformContext,
loc: SourceLocation | null,
...args: any[]
): boolean {
@@ -139,10 +129,10 @@ export function checkCompatEnabled(
export function warnDeprecation(
key: CompilerDeprecationTypes,
- context: ParserContext | TransformContext,
+ context: MergedParserOptions | TransformContext,
loc: SourceLocation | null,
...args: any[]
-) {
+): void {
const val = getCompatValue(key, context)
if (val === 'suppress-warning') {
return
diff --git a/packages/compiler-core/src/compat/transformFilter.ts b/packages/compiler-core/src/compat/transformFilter.ts
index 8eaa81eb3f1..4791e67543e 100644
--- a/packages/compiler-core/src/compat/transformFilter.ts
+++ b/packages/compiler-core/src/compat/transformFilter.ts
@@ -1,19 +1,18 @@
import { RESOLVE_FILTER } from '../runtimeHelpers'
import {
- AttributeNode,
- DirectiveNode,
- NodeTransform,
+ type AttributeNode,
+ type DirectiveNode,
+ type ExpressionNode,
NodeTypes,
- SimpleExpressionNode,
- toValidAssetId,
- TransformContext
-} from '@vue/compiler-core'
+ type SimpleExpressionNode,
+} from '../ast'
import {
CompilerDeprecationTypes,
isCompatEnabled,
- warnDeprecation
+ warnDeprecation,
} from './compatConfig'
-import { ExpressionNode } from '../ast'
+import type { NodeTransform, TransformContext } from '../transform'
+import { toValidAssetId } from '../utils'
const validDivisionCharRE = /[\w).+\-_$\]]/
@@ -26,9 +25,7 @@ export const transformFilter: NodeTransform = (node, context) => {
// filter rewrite is applied before expression transform so only
// simple expressions are possible at this stage
rewriteFilter(node.content, context)
- }
-
- if (node.type === NodeTypes.ELEMENT) {
+ } else if (node.type === NodeTypes.ELEMENT) {
node.props.forEach((prop: AttributeNode | DirectiveNode) => {
if (
prop.type === NodeTypes.DIRECTIVE &&
@@ -163,19 +160,21 @@ function parseFilter(node: SimpleExpressionNode, context: TransformContext) {
warnDeprecation(
CompilerDeprecationTypes.COMPILER_FILTERS,
context,
- node.loc
+ node.loc,
)
for (i = 0; i < filters.length; i++) {
expression = wrapFilter(expression, filters[i], context)
}
node.content = expression
+ // reset ast since the content is replaced
+ node.ast = undefined
}
}
function wrapFilter(
exp: string,
filter: string,
- context: TransformContext
+ context: TransformContext,
): string {
context.helper(RESOLVE_FILTER)
const i = filter.indexOf('(')
diff --git a/packages/compiler-core/src/compile.ts b/packages/compiler-core/src/compile.ts
index 95e3718964a..a697c9d22e6 100644
--- a/packages/compiler-core/src/compile.ts
+++ b/packages/compiler-core/src/compile.ts
@@ -1,9 +1,13 @@
-import { CompilerOptions } from './options'
-import { baseParse } from './parse'
-import { transform, NodeTransform, DirectiveTransform } from './transform'
-import { generate, CodegenResult } from './codegen'
-import { RootNode } from './ast'
-import { isString, extend } from '@vue/shared'
+import type { CompilerOptions } from './options'
+import { baseParse } from './parser'
+import {
+ type DirectiveTransform,
+ type NodeTransform,
+ transform,
+} from './transform'
+import { type CodegenResult, generate } from './codegen'
+import type { RootNode } from './ast'
+import { extend, isString } from '@vue/shared'
import { transformIf } from './transforms/vIf'
import { transformFor } from './transforms/vFor'
import { transformExpression } from './transforms/transformExpression'
@@ -16,16 +20,16 @@ import { transformText } from './transforms/transformText'
import { transformOnce } from './transforms/vOnce'
import { transformModel } from './transforms/vModel'
import { transformFilter } from './compat/transformFilter'
-import { defaultOnError, createCompilerError, ErrorCodes } from './errors'
+import { ErrorCodes, createCompilerError, defaultOnError } from './errors'
import { transformMemo } from './transforms/vMemo'
export type TransformPreset = [
NodeTransform[],
- Record
+ Record,
]
export function getBaseTransformPreset(
- prefixIdentifiers?: boolean
+ prefixIdentifiers?: boolean,
): TransformPreset {
return [
[
@@ -38,33 +42,33 @@ export function getBaseTransformPreset(
? [
// order is important
trackVForSlotScopes,
- transformExpression
+ transformExpression,
]
: __BROWSER__ && __DEV__
- ? [transformExpression]
- : []),
+ ? [transformExpression]
+ : []),
transformSlotOutlet,
transformElement,
trackSlotScopes,
- transformText
+ transformText,
],
{
on: transformOn,
bind: transformBind,
- model: transformModel
- }
+ model: transformModel,
+ },
]
}
// we name it `baseCompile` so that higher order compilers like
// @vue/compiler-dom can export `compile` while re-exporting everything else.
export function baseCompile(
- template: string | RootNode,
- options: CompilerOptions = {}
+ source: string | RootNode,
+ options: CompilerOptions = {},
): CodegenResult {
const onError = options.onError || defaultOnError
const isModuleMode = options.mode === 'module'
- /* istanbul ignore if */
+ /* v8 ignore start */
if (__BROWSER__) {
if (options.prefixIdentifiers === true) {
onError(createCompilerError(ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED))
@@ -72,6 +76,7 @@ export function baseCompile(
onError(createCompilerError(ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED))
}
}
+ /* v8 ignore stop */
const prefixIdentifiers =
!__BROWSER__ && (options.prefixIdentifiers === true || isModuleMode)
@@ -82,7 +87,10 @@ export function baseCompile(
onError(createCompilerError(ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED))
}
- const ast = isString(template) ? baseParse(template, options) : template
+ const resolvedOptions = extend({}, options, {
+ prefixIdentifiers,
+ })
+ const ast = isString(source) ? baseParse(source, resolvedOptions) : source
const [nodeTransforms, directiveTransforms] =
getBaseTransformPreset(prefixIdentifiers)
@@ -95,24 +103,18 @@ export function baseCompile(
transform(
ast,
- extend({}, options, {
- prefixIdentifiers,
+ extend({}, resolvedOptions, {
nodeTransforms: [
...nodeTransforms,
- ...(options.nodeTransforms || []) // user transforms
+ ...(options.nodeTransforms || []), // user transforms
],
directiveTransforms: extend(
{},
directiveTransforms,
- options.directiveTransforms || {} // user transforms
- )
- })
+ options.directiveTransforms || {}, // user transforms
+ ),
+ }),
)
- return generate(
- ast,
- extend({}, options, {
- prefixIdentifiers
- })
- )
+ return generate(ast, resolvedOptions)
}
diff --git a/packages/compiler-core/src/errors.ts b/packages/compiler-core/src/errors.ts
index db7d0eb393d..58e113ab19e 100644
--- a/packages/compiler-core/src/errors.ts
+++ b/packages/compiler-core/src/errors.ts
@@ -1,4 +1,4 @@
-import { SourceLocation } from './ast'
+import type { SourceLocation } from './ast'
export interface CompilerError extends SyntaxError {
code: number | string
@@ -9,11 +9,11 @@ export interface CoreCompilerError extends CompilerError {
code: ErrorCodes
}
-export function defaultOnError(error: CompilerError) {
+export function defaultOnError(error: CompilerError): never {
throw error
}
-export function defaultOnWarn(msg: CompilerError) {
+export function defaultOnWarn(msg: CompilerError): void {
__DEV__ && console.warn(`[Vue warn] ${msg.message}`)
}
@@ -25,19 +25,19 @@ export function createCompilerError(
code: T,
loc?: SourceLocation,
messages?: { [code: number]: string },
- additionalMessage?: string
+ additionalMessage?: string,
): InferCompilerError {
const msg =
__DEV__ || !__BROWSER__
? (messages || errorMessages)[code] + (additionalMessage || ``)
- : code
+ : `https://vuejs.org/error-reference/#compiler-${code}`
const error = new SyntaxError(String(msg)) as InferCompilerError
error.code = code
error.loc = loc
return error
}
-export const enum ErrorCodes {
+export enum ErrorCodes {
// parse errors
ABRUPT_CLOSING_OF_EMPTY_COMMENT,
CDATA_IN_HTML_CONTENT,
@@ -96,11 +96,16 @@ export const enum ErrorCodes {
X_MODULE_MODE_NOT_SUPPORTED,
X_CACHE_HANDLER_NOT_SUPPORTED,
X_SCOPE_ID_NOT_SUPPORTED,
+ X_VNODE_HOOKS,
+
+ // placed here to preserve order for the current minor
+ // TODO adjust order in 3.5
+ X_V_BIND_INVALID_SAME_NAME_ARGUMENT,
// Special value for higher-order compilers to pick up the last code
// to avoid collision of error codes. This should always be kept as the last
// item.
- __EXTEND_POINT__
+ __EXTEND_POINT__,
}
export const errorMessages: Record = {
@@ -155,6 +160,7 @@ export const errorMessages: Record = {
[ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
[ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT]: ` key should be placed on the tag.`,
[ErrorCodes.X_V_BIND_NO_EXPRESSION]: `v-bind is missing expression.`,
+ [ErrorCodes.X_V_BIND_INVALID_SAME_NAME_ARGUMENT]: `v-bind with same-name shorthand only allows static argument.`,
[ErrorCodes.X_V_ON_NO_EXPRESSION]: `v-on is missing expression.`,
[ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET]: `Unexpected custom directive on outlet.`,
[ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE]:
@@ -172,6 +178,7 @@ export const errorMessages: Record = {
[ErrorCodes.X_V_MODEL_ON_PROPS]: `v-model cannot be used on a prop, because local prop bindings are not writable.\nUse a v-bind binding combined with a v-on listener that emits update:x event instead.`,
[ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: ` expects exactly one child component.`,
+ [ErrorCodes.X_VNODE_HOOKS]: `@vnode-* hooks in templates are no longer supported. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support has been removed in 3.4.`,
// generic errors
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
@@ -180,5 +187,5 @@ export const errorMessages: Record = {
[ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED]: `"scopeId" option is only supported in module mode.`,
// just to fulfill types
- [ErrorCodes.__EXTEND_POINT__]: ``
+ [ErrorCodes.__EXTEND_POINT__]: ``,
}
diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts
index 6a1f8b63b57..29e5f681300 100644
--- a/packages/compiler-core/src/index.ts
+++ b/packages/compiler-core/src/index.ts
@@ -2,31 +2,38 @@ export { baseCompile } from './compile'
// Also expose lower level APIs & types
export {
- CompilerOptions,
- ParserOptions,
- TransformOptions,
- CodegenOptions,
- HoistTransform,
- BindingMetadata,
- BindingTypes
+ type CompilerOptions,
+ type ParserOptions,
+ type TransformOptions,
+ type CodegenOptions,
+ type HoistTransform,
+ type BindingMetadata,
+ BindingTypes,
} from './options'
-export { baseParse, TextModes } from './parse'
+export { baseParse } from './parser'
export {
transform,
- TransformContext,
+ type TransformContext,
createTransformContext,
traverseNode,
createStructuralDirectiveTransform,
- NodeTransform,
- StructuralDirectiveTransform,
- DirectiveTransform
+ type NodeTransform,
+ type StructuralDirectiveTransform,
+ type DirectiveTransform,
} from './transform'
-export { generate, CodegenContext, CodegenResult } from './codegen'
+export {
+ generate,
+ type CodegenContext,
+ type CodegenResult,
+ type CodegenSourceMapGenerator,
+ type RawSourceMap,
+} from './codegen'
export {
ErrorCodes,
- CoreCompilerError,
- CompilerError,
- createCompilerError
+ errorMessages,
+ createCompilerError,
+ type CoreCompilerError,
+ type CompilerError,
} from './errors'
export * from './ast'
@@ -34,7 +41,7 @@ export * from './utils'
export * from './babelUtils'
export * from './runtimeHelpers'
-export { getBaseTransformPreset, TransformPreset } from './compile'
+export { getBaseTransformPreset, type TransformPreset } from './compile'
export { transformModel } from './transforms/vModel'
export { transformOn } from './transforms/vOn'
export { transformBind } from './transforms/vBind'
@@ -44,28 +51,28 @@ export { processFor, createForLoopParams } from './transforms/vFor'
export {
transformExpression,
processExpression,
- stringifyExpression
+ stringifyExpression,
} from './transforms/transformExpression'
export {
buildSlots,
- SlotFnBuilder,
+ type SlotFnBuilder,
trackVForSlotScopes,
- trackSlotScopes
+ trackSlotScopes,
} from './transforms/vSlot'
export {
transformElement,
resolveComponentType,
buildProps,
buildDirectiveArgs,
- PropsExpression
+ type PropsExpression,
} from './transforms/transformElement'
export { processSlotOutlet } from './transforms/transformSlotOutlet'
-export { getConstantType } from './transforms/hoistStatic'
+export { getConstantType } from './transforms/cacheStatic'
export { generateCodeFrame } from '@vue/shared'
// v2 compat only
export {
checkCompatEnabled,
warnDeprecation,
- CompilerDeprecationTypes
+ CompilerDeprecationTypes,
} from './compat/compatConfig'
diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts
index 1221772f706..1de865f42eb 100644
--- a/packages/compiler-core/src/options.ts
+++ b/packages/compiler-core/src/options.ts
@@ -1,13 +1,18 @@
-import { ElementNode, Namespace, TemplateChildNode, ParentNode } from './ast'
-import { TextModes } from './parse'
-import { CompilerError } from './errors'
-import {
- NodeTransform,
+import type {
+ ElementNode,
+ Namespace,
+ Namespaces,
+ ParentNode,
+ TemplateChildNode,
+} from './ast'
+import type { CompilerError } from './errors'
+import type {
DirectiveTransform,
- TransformContext
+ NodeTransform,
+ TransformContext,
} from './transform'
-import { CompilerCompatOptions } from './compat/compatConfig'
-import { ParserPlugin } from '@babel/parser'
+import type { CompilerCompatOptions } from './compat/compatConfig'
+import type { ParserPlugin } from '@babel/parser'
export interface ErrorHandlingOptions {
onWarn?: (warning: CompilerError) => void
@@ -17,6 +22,24 @@ export interface ErrorHandlingOptions {
export interface ParserOptions
extends ErrorHandlingOptions,
CompilerCompatOptions {
+ /**
+ * Base mode is platform agnostic and only parses HTML-like template syntax,
+ * treating all tags the same way. Specific tag parsing behavior can be
+ * configured by higher-level compilers.
+ *
+ * HTML mode adds additional logic for handling special parsing behavior in
+ * `
+ this.emitCodePoint(cp, consumed),
+ )
+ }
+ }
+
+ public reset(): void {
+ this.state = State.Text
+ this.mode = ParseMode.BASE
+ this.buffer = ''
+ this.sectionStart = 0
+ this.index = 0
+ this.baseState = State.Text
+ this.inRCDATA = false
+ this.currentSequence = undefined!
+ this.newlines.length = 0
+ this.delimiterOpen = defaultDelimitersOpen
+ this.delimiterClose = defaultDelimitersClose
+ }
+
+ /**
+ * Generate Position object with line / column information using recorded
+ * newline positions. We know the index is always going to be an already
+ * processed index, so all the newlines up to this index should have been
+ * recorded.
+ */
+ public getPos(index: number): Position {
+ let line = 1
+ let column = index + 1
+ for (let i = this.newlines.length - 1; i >= 0; i--) {
+ const newlineIndex = this.newlines[i]
+ if (index > newlineIndex) {
+ line = i + 2
+ column = index - newlineIndex
+ break
+ }
+ }
+ return {
+ column,
+ line,
+ offset: index,
+ }
+ }
+
+ private peek() {
+ return this.buffer.charCodeAt(this.index + 1)
+ }
+
+ private stateText(c: number): void {
+ if (c === CharCodes.Lt) {
+ if (this.index > this.sectionStart) {
+ this.cbs.ontext(this.sectionStart, this.index)
+ }
+ this.state = State.BeforeTagName
+ this.sectionStart = this.index
+ } else if (!__BROWSER__ && c === CharCodes.Amp) {
+ this.startEntity()
+ } else if (!this.inVPre && c === this.delimiterOpen[0]) {
+ this.state = State.InterpolationOpen
+ this.delimiterIndex = 0
+ this.stateInterpolationOpen(c)
+ }
+ }
+
+ public delimiterOpen: Uint8Array = defaultDelimitersOpen
+ public delimiterClose: Uint8Array = defaultDelimitersClose
+ private delimiterIndex = -1
+
+ private stateInterpolationOpen(c: number): void {
+ if (c === this.delimiterOpen[this.delimiterIndex]) {
+ if (this.delimiterIndex === this.delimiterOpen.length - 1) {
+ const start = this.index + 1 - this.delimiterOpen.length
+ if (start > this.sectionStart) {
+ this.cbs.ontext(this.sectionStart, start)
+ }
+ this.state = State.Interpolation
+ this.sectionStart = start
+ } else {
+ this.delimiterIndex++
+ }
+ } else if (this.inRCDATA) {
+ this.state = State.InRCDATA
+ this.stateInRCDATA(c)
+ } else {
+ this.state = State.Text
+ this.stateText(c)
+ }
+ }
+
+ private stateInterpolation(c: number): void {
+ if (c === this.delimiterClose[0]) {
+ this.state = State.InterpolationClose
+ this.delimiterIndex = 0
+ this.stateInterpolationClose(c)
+ }
+ }
+
+ private stateInterpolationClose(c: number) {
+ if (c === this.delimiterClose[this.delimiterIndex]) {
+ if (this.delimiterIndex === this.delimiterClose.length - 1) {
+ this.cbs.oninterpolation(this.sectionStart, this.index + 1)
+ if (this.inRCDATA) {
+ this.state = State.InRCDATA
+ } else {
+ this.state = State.Text
+ }
+ this.sectionStart = this.index + 1
+ } else {
+ this.delimiterIndex++
+ }
+ } else {
+ this.state = State.Interpolation
+ this.stateInterpolation(c)
+ }
+ }
+
+ public currentSequence: Uint8Array = undefined!
+ private sequenceIndex = 0
+ private stateSpecialStartSequence(c: number): void {
+ const isEnd = this.sequenceIndex === this.currentSequence.length
+ const isMatch = isEnd
+ ? // If we are at the end of the sequence, make sure the tag name has ended
+ isEndOfTagSection(c)
+ : // Otherwise, do a case-insensitive comparison
+ (c | 0x20) === this.currentSequence[this.sequenceIndex]
+
+ if (!isMatch) {
+ this.inRCDATA = false
+ } else if (!isEnd) {
+ this.sequenceIndex++
+ return
+ }
+
+ this.sequenceIndex = 0
+ this.state = State.InTagName
+ this.stateInTagName(c)
+ }
+
+ /** Look for an end tag. For and
- `).code
+ `).code,
).toMatchSnapshot()
})
diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/Transition.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/Transition.spec.ts.snap
index 8396cb7ff5b..aa08c1366a6 100644
--- a/packages/compiler-dom/__tests__/transforms/__snapshots__/Transition.spec.ts.snap
+++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/Transition.spec.ts.snap
@@ -1,4 +1,4 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`inject persisted when child has v-show 1`] = `
"const _Vue = Vue
diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap
index 176004794c9..5bc40d3fab5 100644
--- a/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap
+++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap
@@ -1,54 +1,183 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`stringify static html should bail on bindings that are hoisted but not stringifiable 1`] = `
+exports[`stringify static html > eligible content (elements > 20) + non-eligible content 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("
", 20),
+ _createElementVNode("div", { key: "1" }, "1", -1 /* CACHED */),
+ _createStaticVNode("
", 20)
+ ])))
+}"
+`;
+
+exports[`stringify static html > escape 1`] = `
+"const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("
1 + < & 1 + < & 1 + < & 1 + < & 1 + < &
", 1)
+ ])))
+}"
+`;
+
+exports[`stringify static html > serializing constant bindings 1`] = `
+"const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("
1 + false 1 + false 1 + false 1 + false 1 + false
", 1)
+ ])))
+}"
+`;
+
+exports[`stringify static html > serializing template string style 1`] = `
+"const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("
1 + false 1 + false 1 + false 1 + false 1 + false
", 1)
+ ])))
+}"
+`;
+
+exports[`stringify static html > should bail for
elements with null values 1`] = `
"const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
-const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, [
- /*#__PURE__*/_createElementVNode("span", { class: "foo" }, "foo"),
- /*#__PURE__*/_createElementVNode("span", { class: "foo" }, "foo"),
- /*#__PURE__*/_createElementVNode("span", { class: "foo" }, "foo"),
- /*#__PURE__*/_createElementVNode("span", { class: "foo" }, "foo"),
- /*#__PURE__*/_createElementVNode("span", { class: "foo" }, "foo"),
- /*#__PURE__*/_createElementVNode("img", { src: _imports_0_ })
-], -1 /* HOISTED */)
-const _hoisted_2 = [
- _hoisted_1
-]
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("select", null, [
+ _createElementVNode("option", { value: null }),
+ _createElementVNode("option", { value: "1" }),
+ _createElementVNode("option", { value: "1" }),
+ _createElementVNode("option", { value: "1" }),
+ _createElementVNode("option", { value: "1" }),
+ _createElementVNode("option", { value: "1" })
+ ], -1 /* CACHED */)
+ ])))
+}"
+`;
+
+exports[`stringify static html > should bail for elements with number values 1`] = `
+"const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("select", null, [
+ _createElementVNode("option", { value: 1 }),
+ _createElementVNode("option", { value: 1 }),
+ _createElementVNode("option", { value: 1 }),
+ _createElementVNode("option", { value: 1 }),
+ _createElementVNode("option", { value: 1 })
+ ], -1 /* CACHED */)
+ ])))
}"
`;
-exports[`stringify static html should work with bindings that are non-static but stringifiable 1`] = `
+exports[`stringify static html > should bail for comments 1`] = `
+"const { createCommentVNode: _createCommentVNode, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+const _hoisted_1 = { class: "a" }
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock(_Fragment, null, [
+ _createCommentVNode(" Comment 1 "),
+ _createElementVNode("div", _hoisted_1, [
+ _createCommentVNode(" Comment 2 "),
+ _cache[0] || (_cache[0] = _createStaticVNode(" ", 5))
+ ])
+ ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
+}"
+`;
+
+exports[`stringify static html > should bail on bindings that are cached but not stringifiable 1`] = `
+"const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createElementVNode("div", null, [
+ _createElementVNode("span", { class: "foo" }, "foo"),
+ _createElementVNode("span", { class: "foo" }, "foo"),
+ _createElementVNode("span", { class: "foo" }, "foo"),
+ _createElementVNode("span", { class: "foo" }, "foo"),
+ _createElementVNode("span", { class: "foo" }, "foo"),
+ _createElementVNode("img", { src: _imports_0_ })
+ ], -1 /* CACHED */)
+ ])))
+}"
+`;
+
+exports[`stringify static html > should work for elements with string values 1`] = `
"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
-const _hoisted_1 = /*#__PURE__*/_createStaticVNode("foo foo foo foo foo ", 1)
-const _hoisted_2 = [
- _hoisted_1
-]
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode(" ", 1)
+ ])))
+}"
+`;
+
+exports[`stringify static html > should work for multiple adjacent nodes 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
- return (_openBlock(), _createElementBlock("div", null, _hoisted_2))
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode(" ", 5)
+ ])))
}"
`;
-exports[`stringify static html stringify v-html 1`] = `
-"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode } = Vue
+exports[`stringify static html > should work on eligible content (elements > 20) 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("
", 1)
+ ])))
+}"
+`;
-const _hoisted_1 = /*#__PURE__*/_createStaticVNode("show-it
1 2
", 2)
+exports[`stringify static html > should work on eligible content (elements with binding > 5) 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
- return _hoisted_1
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("
", 1)
+ ])))
}"
`;
-exports[`stringify static html stringify v-text 1`] = `
+exports[`stringify static html > should work with bindings that are non-static but stringifiable 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
+
+return function render(_ctx, _cache) {
+ return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
+ _createStaticVNode("foo foo foo foo foo ", 1)
+ ])))
+}"
+`;
+
+exports[`stringify static html > stringify v-html 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode } = Vue
+
+return function render(_ctx, _cache) {
+ return _cache[0] || (_cache[0] = _createStaticVNode("show-it
1 2
", 2))
+}"
+`;
+
+exports[`stringify static html > stringify v-text 1`] = `
"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode } = Vue
-const _hoisted_1 = /*#__PURE__*/_createStaticVNode("<span>show-it </span>
1 2
", 2)
+return function render(_ctx, _cache) {
+ return _cache[0] || (_cache[0] = _createStaticVNode("<span>show-it </span>
1 2
", 2))
+}"
+`;
+
+exports[`stringify static html > stringify v-text with escape 1`] = `
+"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode } = Vue
return function render(_ctx, _cache) {
- return _hoisted_1
+ return _cache[0] || (_cache[0] = _createStaticVNode("text1
1 2
", 2))
}"
`;
diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
index 513f2572f8c..5b610745e41 100644
--- a/packages/compiler-dom/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
+++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: transform v-model errors should allow usage on custom element 1`] = `
+exports[`compiler: transform v-model > errors > should allow usage on custom element 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -16,7 +16,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model input w/ dynamic v-bind 1`] = `
+exports[`compiler: transform v-model > input w/ dynamic v-bind 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -32,7 +32,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model input w/ dynamic v-bind 2`] = `
+exports[`compiler: transform v-model > input w/ dynamic v-bind 2`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -48,7 +48,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model modifiers .lazy 1`] = `
+exports[`compiler: transform v-model > modifiers > .lazy 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -69,7 +69,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model modifiers .number 1`] = `
+exports[`compiler: transform v-model > modifiers > .number 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -90,7 +90,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model modifiers .trim 1`] = `
+exports[`compiler: transform v-model > modifiers > .trim 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -111,7 +111,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression 1`] = `
+exports[`compiler: transform v-model > simple expression 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -127,7 +127,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression for input (checkbox) 1`] = `
+exports[`compiler: transform v-model > simple expression for input (checkbox) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -144,7 +144,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression for input (dynamic type) 1`] = `
+exports[`compiler: transform v-model > simple expression for input (dynamic type) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -160,7 +160,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression for input (radio) 1`] = `
+exports[`compiler: transform v-model > simple expression for input (radio) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -177,7 +177,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression for input (text) 1`] = `
+exports[`compiler: transform v-model > simple expression for input (text) 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -194,7 +194,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression for select 1`] = `
+exports[`compiler: transform v-model > simple expression for select 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
@@ -210,7 +210,7 @@ return function render(_ctx, _cache) {
}"
`;
-exports[`compiler: transform v-model simple expression for textarea 1`] = `
+exports[`compiler: transform v-model > simple expression for textarea 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/vShow.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/vShow.spec.ts.snap
index fbd96bc428c..b0ed8d8d6bd 100644
--- a/packages/compiler-dom/__tests__/transforms/__snapshots__/vShow.spec.ts.snap
+++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/vShow.spec.ts.snap
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: v-show transform simple expression 1`] = `
+exports[`compiler: v-show transform > simple expression 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
diff --git a/packages/compiler-dom/__tests__/transforms/ignoreSideEffectTags.spec.ts b/packages/compiler-dom/__tests__/transforms/ignoreSideEffectTags.spec.ts
index 4df6ee297f3..f06b9fd52dd 100644
--- a/packages/compiler-dom/__tests__/transforms/ignoreSideEffectTags.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/ignoreSideEffectTags.spec.ts
@@ -1,4 +1,4 @@
-import { compile, CompilerError } from '../../src'
+import { type CompilerError, compile } from '../../src'
describe('compiler: ignore side effect tags', () => {
it('should ignore script', () => {
@@ -6,7 +6,7 @@ describe('compiler: ignore side effect tags', () => {
const { code } = compile(``, {
onError(e) {
err = e
- }
+ },
})
expect(code).not.toMatch('script')
expect(err).toBeDefined()
@@ -18,7 +18,7 @@ describe('compiler: ignore side effect tags', () => {
const { code } = compile(``, {
onError(e) {
err = e
- }
+ },
})
expect(code).not.toMatch('style')
expect(err).toBeDefined()
diff --git a/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts b/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts
index bedec9fc00a..f58e207d6cf 100644
--- a/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts
@@ -1,13 +1,13 @@
import {
- compile,
- NodeTypes,
CREATE_STATIC,
+ ConstantTypes,
+ NodeTypes,
+ compile,
createSimpleExpression,
- ConstantTypes
} from '../../src'
import {
+ StringifyThresholds,
stringifyStatic,
- StringifyThresholds
} from '../../src/transforms/stringifyStatic'
describe('stringify static html', () => {
@@ -15,177 +15,200 @@ describe('stringify static html', () => {
return compile(template, {
hoistStatic: true,
prefixIdentifiers: true,
- transformHoist: stringifyStatic
+ transformHoist: stringifyStatic,
})
}
function repeat(code: string, n: number): string {
- return new Array(n)
- .fill(0)
- .map(() => code)
- .join('')
+ return code.repeat(n)
+ }
+
+ /**
+ * Assert cached node NOT stringified
+ */
+ function cachedArrayBailedMatcher(n = 1) {
+ return {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: new Array(n).fill(0).map(() => ({
+ // should remain VNODE_CALL instead of JS_CALL_EXPRESSION
+ codegenNode: { type: NodeTypes.VNODE_CALL },
+ })),
+ },
+ }
+ }
+
+ /**
+ * Assert cached node is stringified (no content check)
+ */
+ function cachedArraySuccessMatcher(n = 1) {
+ return {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: new Array(n).fill(0).map(() => ({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: CREATE_STATIC,
+ })),
+ },
+ }
+ }
+
+ /**
+ * Assert cached node stringified with desired content and node count
+ */
+ function cachedArrayStaticNodeMatcher(content: string, count: number) {
+ return {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: CREATE_STATIC,
+ arguments: [JSON.stringify(content), String(count)],
+ },
+ ],
+ },
+ }
}
test('should bail on non-eligible static trees', () => {
const { ast } = compileWithStringify(
- ``
+ ``,
)
- // should be a normal vnode call
- expect(ast.hoists[0]!.type).toBe(NodeTypes.VNODE_CALL)
+ // should be cached children array
+ expect(ast.cached[0]!.value.type).toBe(NodeTypes.JS_ARRAY_EXPRESSION)
})
test('should work on eligible content (elements with binding > 5)', () => {
- const { ast } = compileWithStringify(
+ const { code, ast } = compileWithStringify(
`${repeat(
` `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )} `,
)
+
// should be optimized now
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `
${repeat(
- ` `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
- ),
- '1'
- ]
- }, // the children array is hoisted as well
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `
${repeat(
+ ` `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ 1,
+ ),
])
+
+ expect(code).toMatchSnapshot()
})
test('should work on eligible content (elements > 20)', () => {
- const { ast } = compileWithStringify(
+ const { code, ast } = compileWithStringify(
`
${repeat(
` `,
- StringifyThresholds.NODE_COUNT
- )}
`
+ StringifyThresholds.NODE_COUNT,
+ )}
`,
)
// should be optimized now
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `
${repeat(
- ` `,
- StringifyThresholds.NODE_COUNT
- )}
`
- ),
- '1'
- ]
- },
- // the children array is hoisted as well
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `
${repeat(` `, StringifyThresholds.NODE_COUNT)}
`,
+ 1,
+ ),
])
+
+ expect(code).toMatchSnapshot()
})
test('should work for multiple adjacent nodes', () => {
- const { ast } = compileWithStringify(
+ const { ast, code } = compileWithStringify(
`
${repeat(
` `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
)
- // should have 6 hoisted nodes (including the entire array),
- // but 2~5 should be null because they are merged into 1
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- repeat(
- `
`,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )
- ),
- '5'
- ]
- },
- null,
- null,
- null,
- null,
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ repeat(
+ `
`,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ ),
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ ),
])
+
+ expect(code).toMatchSnapshot()
})
test('serializing constant bindings', () => {
- const { ast } = compileWithStringify(
+ const { ast, code } = compileWithStringify(
`
${repeat(
`{{ 1 }} + {{ false }} `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
)
// should be optimized now
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `${repeat(
- `1 + false `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
- ),
- '1'
- ]
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `${repeat(
+ `1 + false `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ 1,
+ ),
])
+ expect(code).toMatchSnapshot()
+ })
+
+ // #12391
+ test('serializing template string style', () => {
+ const { ast, code } = compileWithStringify(
+ `${repeat(
+ `{{ 1 }} + {{ false }} `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ )
+ // should be optimized now
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `${repeat(
+ `1 + false `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ 1,
+ ),
+ ])
+ expect(code).toMatchSnapshot()
})
test('escape', () => {
- const { ast } = compileWithStringify(
+ const { ast, code } = compileWithStringify(
`${repeat(
`{{ 1 }} + {{ '<' }} ` +
`& `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )} `,
)
// should be optimized now
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `
${repeat(
- `1 + < ` + `& `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
- ),
- '1'
- ]
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `
${repeat(
+ `1 + < ` + `& `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ 1,
+ ),
])
+ expect(code).toMatchSnapshot()
})
- test('should bail on bindings that are hoisted but not stringifiable', () => {
+ test('should bail on bindings that are cached but not stringifiable', () => {
const { ast, code } = compile(
`
${repeat(
`
foo `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
)}
`,
{
hoistStatic: true,
@@ -198,7 +221,7 @@ describe('stringify static html', () => {
'_imports_0_',
false,
node.loc,
- ConstantTypes.CAN_HOIST
+ ConstantTypes.CAN_CACHE,
)
node.props[0] = {
type: NodeTypes.DIRECTIVE,
@@ -206,24 +229,14 @@ describe('stringify static html', () => {
arg: createSimpleExpression('src', true),
exp,
modifiers: [],
- loc: node.loc
+ loc: node.loc,
}
}
- }
- ]
- }
- )
- expect(ast.hoists).toMatchObject([
- {
- // the expression and the tree are still hoistable
- // but should stay NodeTypes.VNODE_CALL
- // if it's stringified it will be NodeTypes.JS_CALL_EXPRESSION
- type: NodeTypes.VNODE_CALL
+ },
+ ],
},
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
+ )
+ expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
expect(code).toMatchSnapshot()
})
@@ -233,7 +246,7 @@ describe('stringify static html', () => {
const { ast, code } = compile(
`
${repeat(
`
foo `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
)}
`,
{
hoistStatic: true,
@@ -246,7 +259,7 @@ describe('stringify static html', () => {
'_imports_0_',
false,
node.loc,
- ConstantTypes.CAN_STRINGIFY
+ ConstantTypes.CAN_STRINGIFY,
)
node.props[0] = {
type: NodeTypes.DIRECTIVE,
@@ -254,160 +267,98 @@ describe('stringify static html', () => {
arg: createSimpleExpression('src', true),
exp,
modifiers: [],
- loc: node.loc
+ loc: node.loc,
}
}
- }
- ]
- }
- )
- expect(ast.hoists).toMatchObject([
- {
- // the hoisted node should be NodeTypes.JS_CALL_EXPRESSION
- // of `createStaticVNode()` instead of dynamic NodeTypes.VNODE_CALL
- type: NodeTypes.JS_CALL_EXPRESSION
+ },
+ ],
},
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
+ )
+ expect(ast.cached).toMatchObject([cachedArraySuccessMatcher()])
expect(code).toMatchSnapshot()
})
// #1128
- test('should bail on non attribute bindings', () => {
+ test('should bail on non-attribute bindings', () => {
const { ast } = compileWithStringify(
`
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
)
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
+ expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
const { ast: ast2 } = compileWithStringify(
``
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}`,
)
- expect(ast2.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
- })
+ expect(ast2.cached).toMatchObject([cachedArrayBailedMatcher()])
- test('should bail on non attribute bindings', () => {
- const { ast } = compileWithStringify(
+ const { ast: ast3 } = compileWithStringify(
``
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )} `,
)
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
+ expect(ast3.cached).toMatchObject([cachedArrayBailedMatcher()])
- const { ast: ast2 } = compileWithStringify(
+ const { ast: ast4 } = compileWithStringify(
``
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )} `,
)
- expect(ast2.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
+ expect(ast4.cached).toMatchObject([cachedArrayBailedMatcher()])
})
test('should bail on tags that has placement constraints (eg.tables related tags)', () => {
const { ast } = compileWithStringify(
`${repeat(
`foo `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}`,
)
- expect(ast.hoists).toMatchObject([
- {
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- },
- {
- type: NodeTypes.JS_ARRAY_EXPRESSION
- }
- ])
+ expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
})
test('should bail inside slots', () => {
const { ast } = compileWithStringify(
`${repeat(
`
`,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )} `
- )
- expect(ast.hoists.length).toBe(
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}`,
)
- ast.hoists.forEach(node => {
- expect(node).toMatchObject({
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- })
- })
+ expect(ast.cached).toMatchObject([
+ cachedArrayBailedMatcher(StringifyThresholds.ELEMENT_WITH_BINDING_COUNT),
+ ])
const { ast: ast2 } = compileWithStringify(
`${repeat(
`
`,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )} `
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )} `,
)
- expect(ast2.hoists.length).toBe(
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )
- ast2.hoists.forEach(node => {
- expect(node).toMatchObject({
- type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
- })
- })
+ expect(ast2.cached).toMatchObject([
+ cachedArrayBailedMatcher(StringifyThresholds.ELEMENT_WITH_BINDING_COUNT),
+ ])
})
test('should remove attribute for `null`', () => {
const { ast } = compileWithStringify(
`${repeat(
` `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}`,
)
- expect(ast.hoists[0]).toMatchObject({
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `${repeat(
- ` `,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}`
- ),
- '5'
- ]
- })
+
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ repeat(` `, StringifyThresholds.ELEMENT_WITH_BINDING_COUNT),
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ ),
+ ])
})
// #6617
@@ -415,22 +366,27 @@ describe('stringify static html', () => {
const { ast } = compileWithStringify(
`enable ${repeat(
`
`,
- StringifyThresholds.NODE_COUNT
- )}`
+ StringifyThresholds.NODE_COUNT,
+ )}`,
)
- expect(ast.hoists[0]).toMatchObject({
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `enable ${repeat(
- `
`,
- StringifyThresholds.NODE_COUNT
- )}`
- ),
- '21'
- ]
- })
+ expect(ast.cached).toMatchObject([
+ {
+ type: NodeTypes.JS_CACHE_EXPRESSION,
+ value: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: CREATE_STATIC,
+ arguments: [
+ JSON.stringify(
+ `enable ${repeat(
+ `
`,
+ StringifyThresholds.NODE_COUNT,
+ )}`,
+ ),
+ '21',
+ ],
+ },
+ },
+ ])
})
test('should stringify svg', () => {
@@ -439,22 +395,37 @@ describe('stringify static html', () => {
const { ast } = compileWithStringify(
`${svg}${repeat(
repeated,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}
`
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}`,
)
- expect(ast.hoists[0]).toMatchObject({
- type: NodeTypes.JS_CALL_EXPRESSION,
- callee: CREATE_STATIC,
- arguments: [
- JSON.stringify(
- `${svg}${repeat(
- repeated,
- StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
- )}`
- ),
- '1'
- ]
- })
+
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `${svg}${repeat(
+ repeated,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}`,
+ 1,
+ ),
+ ])
+ })
+
+ test('should stringify mathML', () => {
+ const math = ``
+ const repeated = `1 `
+ const { ast } = compileWithStringify(
+ `${math}${repeat(
+ repeated,
+ StringifyThresholds.NODE_COUNT,
+ )}
`,
+ )
+
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `${math}${repeat(repeated, StringifyThresholds.NODE_COUNT)} `,
+ 1,
+ ),
+ ])
})
// #5439
@@ -477,4 +448,81 @@ describe('stringify static html', () => {
expect(code).toMatch(`<span>show-it </span>
`)
expect(code).toMatchSnapshot()
})
+
+ test('stringify v-text with escape', () => {
+ const { code } = compileWithStringify(`
+
+
+ 1 2
+
`)
+ expect(code).toMatch(`text1
`)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should work for elements with string values', () => {
+ const { ast, code } = compileWithStringify(
+ `${repeat(
+ ` `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ )
+ // should be optimized now
+ expect(ast.cached).toMatchObject([
+ cachedArrayStaticNodeMatcher(
+ `${repeat(
+ ` `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )} `,
+ 1,
+ ),
+ ])
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should bail for elements with number values', () => {
+ const { ast, code } = compileWithStringify(
+ `${repeat(
+ ` `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ )
+ expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should bail for comments', () => {
+ const { code } = compileWithStringify(
+ `${repeat(
+ ` `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ )
+ expect(code).toMatchSnapshot()
+ })
+
+ test('should bail for elements with null values', () => {
+ const { ast, code } = compileWithStringify(
+ ` ${repeat(
+ ` `,
+ StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
+ )}
`,
+ )
+ expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
+ expect(code).toMatchSnapshot()
+ })
+
+ test('eligible content (elements > 20) + non-eligible content', () => {
+ const { code } = compileWithStringify(
+ `${repeat(
+ `
`,
+ StringifyThresholds.NODE_COUNT,
+ )}
1
${repeat(
+ `
`,
+ StringifyThresholds.NODE_COUNT,
+ )}
`,
+ )
+
+ expect(code).toMatchSnapshot()
+ })
})
diff --git a/packages/compiler-dom/__tests__/transforms/transformStyle.spec.ts b/packages/compiler-dom/__tests__/transforms/transformStyle.spec.ts
index 6eee9f8ba38..51c40c45d98 100644
--- a/packages/compiler-dom/__tests__/transforms/transformStyle.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/transformStyle.spec.ts
@@ -1,10 +1,10 @@
import {
+ type CompilerOptions,
+ type ElementNode,
+ NodeTypes,
+ type VNodeCall,
baseParse as parse,
transform,
- CompilerOptions,
- ElementNode,
- NodeTypes,
- VNodeCall
} from '@vue/compiler-core'
import { transformBind } from '../../../compiler-core/src/transforms/vBind'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
@@ -12,16 +12,16 @@ import { transformStyle } from '../../src/transforms/transformStyle'
function transformWithStyleTransform(
template: string,
- options: CompilerOptions = {}
+ options: CompilerOptions = {},
) {
const ast = parse(template)
transform(ast, {
nodeTransforms: [transformStyle],
- ...options
+ ...options,
})
return {
root: ast,
- node: ast.children[0] as ElementNode
+ node: ast.children[0] as ElementNode,
}
}
@@ -34,13 +34,13 @@ describe('compiler: style transform', () => {
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `style`,
- isStatic: true
+ isStatic: true,
},
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{"color":"red"}`,
- isStatic: false
- }
+ isStatic: false,
+ },
})
})
@@ -48,8 +48,8 @@ describe('compiler: style transform', () => {
const { node } = transformWithStyleTransform(`
`, {
nodeTransforms: [transformStyle, transformElement],
directiveTransforms: {
- bind: transformBind
- }
+ bind: transformBind,
+ },
})
expect((node.codegenNode as VNodeCall).props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
@@ -58,15 +58,15 @@ describe('compiler: style transform', () => {
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `style`,
- isStatic: true
+ isStatic: true,
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{"color":"red"}`,
- isStatic: false
- }
- }
- ]
+ isStatic: false,
+ },
+ },
+ ],
})
// should not cause the STYLE patchFlag to be attached
expect((node.codegenNode as VNodeCall).patchFlag).toBeUndefined()
diff --git a/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts b/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
index 8c441cef0e4..bca2fdf9558 100644
--- a/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
@@ -1,15 +1,12 @@
import {
+ type CompilerOptions,
+ type PlainElementNode,
baseParse as parse,
transform,
- PlainElementNode,
- CompilerOptions
} from '@vue/compiler-core'
import { transformVHtml } from '../../src/transforms/vHtml'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
-import {
- createObjectMatcher,
- genFlagText
-} from '../../../compiler-core/__tests__/testUtils'
+import { createObjectMatcher } from '../../../compiler-core/__tests__/testUtils'
import { PatchFlags } from '@vue/shared'
import { DOMErrorCodes } from '../../src/errors'
@@ -18,9 +15,9 @@ function transformWithVHtml(template: string, options: CompilerOptions = {}) {
transform(ast, {
nodeTransforms: [transformElement],
directiveTransforms: {
- html: transformVHtml
+ html: transformVHtml,
},
- ...options
+ ...options,
})
return ast
}
@@ -31,40 +28,40 @@ describe('compiler: v-html transform', () => {
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
tag: `"div"`,
props: createObjectMatcher({
- innerHTML: `[test]`
+ innerHTML: `[test]`,
}),
children: undefined,
- patchFlag: genFlagText(PatchFlags.PROPS),
- dynamicProps: `["innerHTML"]`
+ patchFlag: PatchFlags.PROPS,
+ dynamicProps: `["innerHTML"]`,
})
})
it('should raise error and ignore children when v-html is present', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const ast = transformWithVHtml(`hello
`, {
- onError
+ onError,
})
expect(onError.mock.calls).toMatchObject([
- [{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }]
+ [{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }],
])
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
tag: `"div"`,
props: createObjectMatcher({
- innerHTML: `[test]`
+ innerHTML: `[test]`,
}),
children: undefined, // <-- children should have been removed
- patchFlag: genFlagText(PatchFlags.PROPS),
- dynamicProps: `["innerHTML"]`
+ patchFlag: PatchFlags.PROPS,
+ dynamicProps: `["innerHTML"]`,
})
})
it('should raise error if has no expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
transformWithVHtml(`
`, {
- onError
+ onError,
})
expect(onError.mock.calls).toMatchObject([
- [{ code: DOMErrorCodes.X_V_HTML_NO_EXPRESSION }]
+ [{ code: DOMErrorCodes.X_V_HTML_NO_EXPRESSION }],
])
})
})
diff --git a/packages/compiler-dom/__tests__/transforms/vModel.spec.ts b/packages/compiler-dom/__tests__/transforms/vModel.spec.ts
index 3da0b30085f..02d188f01b9 100644
--- a/packages/compiler-dom/__tests__/transforms/vModel.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vModel.spec.ts
@@ -1,8 +1,8 @@
import {
+ type CompilerOptions,
+ generate,
baseParse as parse,
transform,
- CompilerOptions,
- generate
} from '@vue/compiler-core'
import { transformModel } from '../../src/transforms/vModel'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
@@ -12,7 +12,7 @@ import {
V_MODEL_DYNAMIC,
V_MODEL_RADIO,
V_MODEL_SELECT,
- V_MODEL_TEXT
+ V_MODEL_TEXT,
} from '../../src/runtimeHelpers'
function transformWithModel(template: string, options: CompilerOptions = {}) {
@@ -20,9 +20,9 @@ function transformWithModel(template: string, options: CompilerOptions = {}) {
transform(ast, {
nodeTransforms: [transformElement],
directiveTransforms: {
- model: transformModel
+ model: transformModel,
},
- ...options
+ ...options,
})
return ast
}
@@ -70,7 +70,7 @@ describe('compiler: transform v-model', () => {
expect(generate(root).code).toMatchSnapshot()
const root2 = transformWithModel(
- ' '
+ ' ',
)
expect(root2.helpers).toContain(V_MODEL_DYNAMIC)
expect(generate(root2).code).toMatchSnapshot()
@@ -92,34 +92,34 @@ describe('compiler: transform v-model', () => {
describe('errors', () => {
test('plain elements with argument', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
transformWithModel(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT
- })
+ code: DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT,
+ }),
)
})
test('invalid element', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
transformWithModel(' ', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT
- })
+ code: DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT,
+ }),
)
})
test('should allow usage on custom element', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const root = transformWithModel(' ', {
onError,
- isCustomElement: tag => tag.startsWith('my-')
+ isCustomElement: tag => tag.startsWith('my-'),
})
expect(root.helpers).toContain(V_MODEL_TEXT)
expect(onError).not.toHaveBeenCalled()
@@ -127,16 +127,37 @@ describe('compiler: transform v-model', () => {
})
test('should raise error if used file input element', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
transformWithModel(` `, {
- onError
+ onError,
})
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT
- })
+ code: DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT,
+ }),
)
})
+
+ test('should error on dynamic value binding alongside v-model', () => {
+ const onError = vi.fn()
+ transformWithModel(` `, {
+ onError,
+ })
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE,
+ }),
+ )
+ })
+
+ // #3596
+ test('should NOT error on static value binding alongside v-model', () => {
+ const onError = vi.fn()
+ transformWithModel(` `, {
+ onError,
+ })
+ expect(onError).not.toHaveBeenCalled()
+ })
})
describe('modifiers', () => {
diff --git a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts
index efc7fee374f..ee9ea93c33d 100644
--- a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts
@@ -1,19 +1,19 @@
import {
- baseParse as parse,
- CompilerOptions,
- ElementNode,
+ BindingTypes,
+ type CompilerOptions,
+ type ElementNode,
+ NodeTypes,
+ type ObjectExpression,
TO_HANDLER_KEY,
+ type VNodeCall,
helperNameMap,
- NodeTypes,
- ObjectExpression,
+ baseParse as parse,
transform,
- VNodeCall
} from '@vue/compiler-core'
import { transformOn } from '../../src/transforms/vOn'
import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
import { transformExpression } from '../../../compiler-core/src/transforms/transformExpression'
-import { genFlagText } from '../../../compiler-core/__tests__/testUtils'
import { PatchFlags } from '@vue/shared'
function parseWithVOn(template: string, options: CompilerOptions = {}) {
@@ -21,32 +21,31 @@ function parseWithVOn(template: string, options: CompilerOptions = {}) {
transform(ast, {
nodeTransforms: [transformExpression, transformElement],
directiveTransforms: {
- on: transformOn
+ on: transformOn,
},
- ...options
+ ...options,
})
+ const node = (ast.children[0] as ElementNode).codegenNode as VNodeCall
return {
root: ast,
- props: (
- ((ast.children[0] as ElementNode).codegenNode as VNodeCall)
- .props as ObjectExpression
- ).properties
+ node,
+ props: (node.props as ObjectExpression).properties,
}
}
describe('compiler-dom: transform v-on', () => {
it('should support multiple modifiers w/ prefixIdentifiers: true', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
value: {
callee: V_ON_WITH_MODIFIERS,
- arguments: [{ content: '_ctx.test' }, '["stop","prevent"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["stop","prevent"]'],
+ },
})
})
@@ -54,8 +53,8 @@ describe('compiler-dom: transform v-on', () => {
const { props } = parseWithVOn(
`
`,
{
- prefixIdentifiers: true
- }
+ prefixIdentifiers: true,
+ },
)
const [clickProp, keyUpProp] = props
@@ -64,95 +63,95 @@ describe('compiler-dom: transform v-on', () => {
type: NodeTypes.JS_PROPERTY,
value: {
callee: V_ON_WITH_MODIFIERS,
- arguments: [{ content: '_ctx.test' }, '["stop"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["stop"]'],
+ },
})
expect(keyUpProp).toMatchObject({
type: NodeTypes.JS_PROPERTY,
value: {
callee: V_ON_WITH_KEYS,
- arguments: [{ content: '_ctx.test' }, '["enter"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["enter"]'],
+ },
})
})
it('should support multiple modifiers and event options w/ prefixIdentifiers: true', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
key: {
- content: `onClickCaptureOnce`
+ content: `onClickCaptureOnce`,
},
value: {
callee: V_ON_WITH_MODIFIERS,
- arguments: [{ content: '_ctx.test' }, '["stop"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["stop"]'],
+ },
})
})
it('should wrap keys guard for keyboard events or dynamic events', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
key: {
- content: `onKeydownCapture`
+ content: `onKeydownCapture`,
},
value: {
callee: V_ON_WITH_KEYS,
arguments: [
{
callee: V_ON_WITH_MODIFIERS,
- arguments: [{ content: '_ctx.test' }, '["stop","ctrl"]']
+ arguments: [{ content: '_ctx.test' }, '["stop","ctrl"]'],
},
- '["a"]'
- ]
- }
+ '["a"]',
+ ],
+ },
})
})
it('should not wrap keys guard if no key modifier is present', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
value: {
callee: V_ON_WITH_MODIFIERS,
- arguments: [{ content: '_ctx.test' }, '["exact"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["exact"]'],
+ },
})
})
it('should wrap keys guard for static key event w/ left/right modifiers', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
value: {
callee: V_ON_WITH_KEYS,
- arguments: [{ content: '_ctx.test' }, '["left"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["left"]'],
+ },
})
})
it('should wrap both for dynamic key event w/ left/right modifiers', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
@@ -161,41 +160,41 @@ describe('compiler-dom: transform v-on', () => {
arguments: [
{
callee: V_ON_WITH_MODIFIERS,
- arguments: [{ content: `_ctx.test` }, `["left"]`]
+ arguments: [{ content: `_ctx.test` }, `["left"]`],
},
- '["left"]'
- ]
- }
+ '["left"]',
+ ],
+ },
})
})
it('should not wrap normal guard if there is only keys guard', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
- prefixIdentifiers: true
+ prefixIdentifiers: true,
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
value: {
callee: V_ON_WITH_KEYS,
- arguments: [{ content: '_ctx.test' }, '["enter"]']
- }
+ arguments: [{ content: '_ctx.test' }, '["enter"]'],
+ },
})
})
test('should transform click.right', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`)
expect(prop.key).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `onContextmenu`
+ content: `onContextmenu`,
})
// dynamic
const {
- props: [prop2]
+ props: [prop2],
} = parseWithVOn(`
`)
// (_toHandlerKey(event)).toLowerCase() === "onclick" ? "onContextmenu" : (_toHandlerKey(event))
expect(prop2.key).toMatchObject({
@@ -206,34 +205,34 @@ describe('compiler-dom: transform v-on', () => {
children: [
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: 'event' },
- `)`
- ]
+ `)`,
+ ],
},
`) === "onClick" ? "onContextmenu" : (`,
{
children: [
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: 'event' },
- `)`
- ]
+ `)`,
+ ],
},
- `)`
- ]
+ `)`,
+ ],
})
})
test('should transform click.middle', () => {
const {
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`)
expect(prop.key).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
- content: `onMouseup`
+ content: `onMouseup`,
})
// dynamic
const {
- props: [prop2]
+ props: [prop2],
} = parseWithVOn(`
`)
// (_eventNaming(event)).toLowerCase() === "onclick" ? "onMouseup" : (_eventNaming(event))
expect(prop2.key).toMatchObject({
@@ -244,48 +243,62 @@ describe('compiler-dom: transform v-on', () => {
children: [
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: 'event' },
- `)`
- ]
+ `)`,
+ ],
},
`) === "onClick" ? "onMouseup" : (`,
{
children: [
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: 'event' },
- `)`
- ]
+ `)`,
+ ],
},
- `)`
- ]
+ `)`,
+ ],
})
})
test('cache handler w/ modifiers', () => {
const {
root,
- props: [prop]
+ props: [prop],
} = parseWithVOn(`
`, {
prefixIdentifiers: true,
- cacheHandlers: true
+ cacheHandlers: true,
})
- expect(root.cached).toBe(1)
+ expect(root.cached.length).toBe(1)
// should not treat cached handler as dynamicProp, so it should have no
// dynamicProps flags and only the hydration flag
expect((root as any).children[0].codegenNode.patchFlag).toBe(
- genFlagText(PatchFlags.HYDRATE_EVENTS)
+ PatchFlags.NEED_HYDRATION,
)
expect(prop).toMatchObject({
key: {
- content: `onKeyupCapture`
+ content: `onKeyupCapture`,
},
value: {
type: NodeTypes.JS_CACHE_EXPRESSION,
index: 0,
value: {
type: NodeTypes.JS_CALL_EXPRESSION,
- callee: V_ON_WITH_KEYS
- }
- }
+ callee: V_ON_WITH_KEYS,
+ },
+ },
+ })
+ })
+
+ test('should not have PROPS patchFlag for constant v-on handlers with modifiers', () => {
+ const { node } = parseWithVOn(`
`, {
+ prefixIdentifiers: true,
+ bindingMetadata: {
+ foo: BindingTypes.SETUP_CONST,
+ },
+ directiveTransforms: {
+ on: transformOn,
+ },
})
+ // should only have hydration flag
+ expect(node.patchFlag).toBe(PatchFlags.NEED_HYDRATION)
})
})
diff --git a/packages/compiler-dom/__tests__/transforms/vShow.spec.ts b/packages/compiler-dom/__tests__/transforms/vShow.spec.ts
index 3c70741cb82..11aa62464d3 100644
--- a/packages/compiler-dom/__tests__/transforms/vShow.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vShow.spec.ts
@@ -1,8 +1,8 @@
import {
+ type CompilerOptions,
+ generate,
baseParse as parse,
transform,
- generate,
- CompilerOptions
} from '@vue/compiler-core'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
import { transformShow } from '../../src/transforms/vShow'
@@ -13,9 +13,9 @@ function transformWithShow(template: string, options: CompilerOptions = {}) {
transform(ast, {
nodeTransforms: [transformElement],
directiveTransforms: {
- show: transformShow
+ show: transformShow,
},
- ...options
+ ...options,
})
return ast
}
@@ -28,14 +28,14 @@ describe('compiler: v-show transform', () => {
})
test('should raise error if has no expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
transformWithShow(`
`, { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
- code: DOMErrorCodes.X_V_SHOW_NO_EXPRESSION
- })
+ code: DOMErrorCodes.X_V_SHOW_NO_EXPRESSION,
+ }),
)
})
})
diff --git a/packages/compiler-dom/__tests__/transforms/vText.spec.ts b/packages/compiler-dom/__tests__/transforms/vText.spec.ts
index 75dbda31fd1..e96ab297298 100644
--- a/packages/compiler-dom/__tests__/transforms/vText.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vText.spec.ts
@@ -1,15 +1,12 @@
import {
+ type CompilerOptions,
+ type PlainElementNode,
baseParse as parse,
transform,
- PlainElementNode,
- CompilerOptions
} from '@vue/compiler-core'
import { transformVText } from '../../src/transforms/vText'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
-import {
- createObjectMatcher,
- genFlagText
-} from '../../../compiler-core/__tests__/testUtils'
+import { createObjectMatcher } from '../../../compiler-core/__tests__/testUtils'
import { PatchFlags } from '@vue/shared'
import { DOMErrorCodes } from '../../src/errors'
@@ -18,9 +15,9 @@ function transformWithVText(template: string, options: CompilerOptions = {}) {
transform(ast, {
nodeTransforms: [transformElement],
directiveTransforms: {
- text: transformVText
+ text: transformVText,
},
- ...options
+ ...options,
})
return ast
}
@@ -32,43 +29,43 @@ describe('compiler: v-text transform', () => {
tag: `"div"`,
props: createObjectMatcher({
textContent: {
- arguments: [{ content: 'test' }]
- }
+ arguments: [{ content: 'test' }],
+ },
}),
children: undefined,
- patchFlag: genFlagText(PatchFlags.PROPS),
- dynamicProps: `["textContent"]`
+ patchFlag: PatchFlags.PROPS,
+ dynamicProps: `["textContent"]`,
})
})
it('should raise error and ignore children when v-text is present', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
const ast = transformWithVText(`hello
`, {
- onError
+ onError,
})
expect(onError.mock.calls).toMatchObject([
- [{ code: DOMErrorCodes.X_V_TEXT_WITH_CHILDREN }]
+ [{ code: DOMErrorCodes.X_V_TEXT_WITH_CHILDREN }],
])
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
tag: `"div"`,
props: createObjectMatcher({
textContent: {
- arguments: [{ content: 'test' }]
- }
+ arguments: [{ content: 'test' }],
+ },
}),
children: undefined, // <-- children should have been removed
- patchFlag: genFlagText(PatchFlags.PROPS),
- dynamicProps: `["textContent"]`
+ patchFlag: PatchFlags.PROPS,
+ dynamicProps: `["textContent"]`,
})
})
it('should raise error if has no expression', () => {
- const onError = jest.fn()
+ const onError = vi.fn()
transformWithVText(`
`, {
- onError
+ onError,
})
expect(onError.mock.calls).toMatchObject([
- [{ code: DOMErrorCodes.X_V_TEXT_NO_EXPRESSION }]
+ [{ code: DOMErrorCodes.X_V_TEXT_NO_EXPRESSION }],
])
})
})
diff --git a/packages/compiler-dom/__tests__/transforms/validateHtmlNesting.spec.ts b/packages/compiler-dom/__tests__/transforms/validateHtmlNesting.spec.ts
new file mode 100644
index 00000000000..46d69846bae
--- /dev/null
+++ b/packages/compiler-dom/__tests__/transforms/validateHtmlNesting.spec.ts
@@ -0,0 +1,202 @@
+import { type CompilerError, compile } from '../../src'
+import { isValidHTMLNesting } from '../../src/htmlNesting'
+
+describe('validate html nesting', () => {
+ it('should warn with p > div', () => {
+ let err: CompilerError | undefined
+ compile(`
`, {
+ onWarn: e => (err = e),
+ })
+ expect(err).toBeDefined()
+ expect(err!.message).toMatch(` cannot be child of
`)
+ })
+
+ it('should not warn with select > hr', () => {
+ let err: CompilerError | undefined
+ compile(` `, {
+ onWarn: e => (err = e),
+ })
+ expect(err).toBeUndefined()
+ })
+
+ // #13318
+ it('should not warn when parent tag is template', () => {
+ let err: CompilerError | undefined
+ compile(` `, {
+ onWarn: e => (err = e),
+ })
+ expect(err).toBeUndefined()
+ })
+})
+
+/**
+ * Copied from https://github.com/MananTank/validate-html-nesting
+ * with ISC license
+ */
+describe('isValidHTMLNesting', () => {
+ test('form', () => {
+ // invalid
+ expect(isValidHTMLNesting('form', 'form')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('form', 'div')).toBe(true)
+ expect(isValidHTMLNesting('form', 'input')).toBe(true)
+ expect(isValidHTMLNesting('form', 'select')).toBe(true)
+ expect(isValidHTMLNesting('form', 'button')).toBe(true)
+ expect(isValidHTMLNesting('form', 'label')).toBe(true)
+ expect(isValidHTMLNesting('form', 'h1')).toBe(true)
+ })
+
+ test('p', () => {
+ // invalid
+ expect(isValidHTMLNesting('p', 'p')).toBe(false)
+ expect(isValidHTMLNesting('p', 'div')).toBe(false)
+ expect(isValidHTMLNesting('p', 'hr')).toBe(false)
+ expect(isValidHTMLNesting('p', 'blockquote')).toBe(false)
+ expect(isValidHTMLNesting('p', 'pre')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('p', 'a')).toBe(true)
+ expect(isValidHTMLNesting('p', 'span')).toBe(true)
+ expect(isValidHTMLNesting('p', 'abbr')).toBe(true)
+ expect(isValidHTMLNesting('p', 'button')).toBe(true)
+ expect(isValidHTMLNesting('p', 'b')).toBe(true)
+ expect(isValidHTMLNesting('p', 'i')).toBe(true)
+ expect(isValidHTMLNesting('p', 'input')).toBe(true)
+ expect(isValidHTMLNesting('p', 'label')).toBe(true)
+ })
+
+ test('a', () => {
+ // invalid
+ expect(isValidHTMLNesting('a', 'a')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('a', 'div')).toBe(true)
+ expect(isValidHTMLNesting('a', 'span')).toBe(true)
+ })
+
+ test('button', () => {
+ // invalid
+ expect(isValidHTMLNesting('button', 'button')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('button', 'div')).toBe(true)
+ expect(isValidHTMLNesting('button', 'span')).toBe(true)
+ })
+
+ test('table', () => {
+ // invalid
+ expect(isValidHTMLNesting('table', 'tr')).toBe(false)
+ expect(isValidHTMLNesting('table', 'table')).toBe(false)
+ expect(isValidHTMLNesting('table', 'td')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('table', 'thead')).toBe(true)
+ expect(isValidHTMLNesting('table', 'tbody')).toBe(true)
+ expect(isValidHTMLNesting('table', 'tfoot')).toBe(true)
+ expect(isValidHTMLNesting('table', 'caption')).toBe(true)
+ expect(isValidHTMLNesting('table', 'colgroup')).toBe(true)
+ })
+
+ test('td', () => {
+ // valid
+ expect(isValidHTMLNesting('td', 'span')).toBe(true)
+ expect(isValidHTMLNesting('tr', 'td')).toBe(true)
+
+ // invalid
+ expect(isValidHTMLNesting('td', 'td')).toBe(false)
+ expect(isValidHTMLNesting('div', 'td')).toBe(false)
+ })
+
+ test('tbody', () => {
+ // invalid
+ expect(isValidHTMLNesting('tbody', 'td')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('tbody', 'tr')).toBe(true)
+ })
+
+ test('tr', () => {
+ // invalid
+ expect(isValidHTMLNesting('tr', 'tr')).toBe(false)
+ expect(isValidHTMLNesting('table', 'tr')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('tbody', 'tr')).toBe(true)
+ expect(isValidHTMLNesting('thead', 'tr')).toBe(true)
+ expect(isValidHTMLNesting('tfoot', 'tr')).toBe(true)
+ expect(isValidHTMLNesting('tr', 'td')).toBe(true)
+ expect(isValidHTMLNesting('tr', 'th')).toBe(true)
+ })
+
+ test('li', () => {
+ // invalid
+ expect(isValidHTMLNesting('li', 'li')).toBe(false)
+ // valid
+ expect(isValidHTMLNesting('li', 'div')).toBe(true)
+ expect(isValidHTMLNesting('li', 'ul')).toBe(true)
+ })
+
+ test('headings', () => {
+ // invalid
+ expect(isValidHTMLNesting('h1', 'h1')).toBe(false)
+ expect(isValidHTMLNesting('h2', 'h1')).toBe(false)
+ expect(isValidHTMLNesting('h3', 'h1')).toBe(false)
+ expect(isValidHTMLNesting('h1', 'h6')).toBe(false)
+
+ // valid
+ expect(isValidHTMLNesting('h1', 'div')).toBe(true)
+ })
+
+ describe('SVG', () => {
+ test('svg', () => {
+ // invalid non-svg tags as children
+ expect(isValidHTMLNesting('svg', 'div')).toBe(false)
+ expect(isValidHTMLNesting('svg', 'img')).toBe(false)
+ expect(isValidHTMLNesting('svg', 'p')).toBe(false)
+ expect(isValidHTMLNesting('svg', 'h2')).toBe(false)
+ expect(isValidHTMLNesting('svg', 'span')).toBe(false)
+
+ // valid non-svg tags as children
+ expect(isValidHTMLNesting('svg', 'a')).toBe(true)
+ expect(isValidHTMLNesting('svg', 'textarea')).toBe(true)
+ expect(isValidHTMLNesting('svg', 'input')).toBe(true)
+ expect(isValidHTMLNesting('svg', 'select')).toBe(true)
+
+ // valid svg tags as children
+ expect(isValidHTMLNesting('svg', 'g')).toBe(true)
+ expect(isValidHTMLNesting('svg', 'ellipse')).toBe(true)
+ expect(isValidHTMLNesting('svg', 'feOffset')).toBe(true)
+ })
+
+ test('foreignObject', () => {
+ // valid
+ expect(isValidHTMLNesting('foreignObject', 'g')).toBe(true)
+ expect(isValidHTMLNesting('foreignObject', 'div')).toBe(true)
+ expect(isValidHTMLNesting('foreignObject', 'a')).toBe(true)
+ expect(isValidHTMLNesting('foreignObject', 'textarea')).toBe(true)
+ })
+
+ test('g', () => {
+ // valid
+ expect(isValidHTMLNesting('g', 'div')).toBe(true)
+ expect(isValidHTMLNesting('g', 'p')).toBe(true)
+ expect(isValidHTMLNesting('g', 'a')).toBe(true)
+ expect(isValidHTMLNesting('g', 'textarea')).toBe(true)
+ expect(isValidHTMLNesting('g', 'g')).toBe(true)
+ })
+
+ test('dl', () => {
+ // valid
+ expect(isValidHTMLNesting('dl', 'dt')).toBe(true)
+ expect(isValidHTMLNesting('dl', 'dd')).toBe(true)
+ expect(isValidHTMLNesting('dl', 'div')).toBe(true)
+ expect(isValidHTMLNesting('div', 'dt')).toBe(true)
+ expect(isValidHTMLNesting('div', 'dd')).toBe(true)
+
+ // invalid
+ expect(isValidHTMLNesting('span', 'dt')).toBe(false)
+ expect(isValidHTMLNesting('span', 'dd')).toBe(false)
+ })
+ })
+})
diff --git a/packages/compiler-dom/api-extractor.json b/packages/compiler-dom/api-extractor.json
deleted file mode 100644
index 5602b3a6fd2..00000000000
--- a/packages/compiler-dom/api-extractor.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "../../api-extractor.json",
- "mainEntryPointFilePath": "./dist/packages//src/index.d.ts",
- "dtsRollup": {
- "publicTrimmedFilePath": "./dist/.d.ts"
- }
-}
diff --git a/packages/compiler-dom/package.json b/packages/compiler-dom/package.json
index a9039c87039..38b62f05046 100644
--- a/packages/compiler-dom/package.json
+++ b/packages/compiler-dom/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-dom",
- "version": "3.2.45",
+ "version": "3.5.18",
"description": "@vue/compiler-dom",
"main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js",
@@ -11,6 +11,20 @@
"index.js",
"dist"
],
+ "exports": {
+ ".": {
+ "types": "./dist/compiler-dom.d.ts",
+ "node": {
+ "production": "./dist/compiler-dom.cjs.prod.js",
+ "development": "./dist/compiler-dom.cjs.js",
+ "default": "./index.js"
+ },
+ "module": "./dist/compiler-dom.esm-bundler.js",
+ "import": "./dist/compiler-dom.esm-bundler.js",
+ "require": "./index.js"
+ },
+ "./*": "./*"
+ },
"sideEffects": false,
"buildOptions": {
"name": "VueCompilerDOM",
@@ -37,7 +51,7 @@
},
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme",
"dependencies": {
- "@vue/shared": "3.2.45",
- "@vue/compiler-core": "3.2.45"
+ "@vue/shared": "workspace:*",
+ "@vue/compiler-core": "workspace:*"
}
}
diff --git a/packages/compiler-dom/src/decodeHtml.ts b/packages/compiler-dom/src/decodeHtml.ts
deleted file mode 100644
index 68b0277a434..00000000000
--- a/packages/compiler-dom/src/decodeHtml.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-import { ParserOptions } from '@vue/compiler-core'
-import namedCharacterReferences from './namedChars.json'
-
-// lazy compute this to make this file tree-shakable for browser
-let maxCRNameLength: number
-
-export const decodeHtml: ParserOptions['decodeEntities'] = (
- rawText,
- asAttr
-) => {
- let offset = 0
- const end = rawText.length
- let decodedText = ''
-
- function advance(length: number) {
- offset += length
- rawText = rawText.slice(length)
- }
-
- while (offset < end) {
- const head = /&(?:#x?)?/i.exec(rawText)
- if (!head || offset + head.index >= end) {
- const remaining = end - offset
- decodedText += rawText.slice(0, remaining)
- advance(remaining)
- break
- }
-
- // Advance to the "&".
- decodedText += rawText.slice(0, head.index)
- advance(head.index)
-
- if (head[0] === '&') {
- // Named character reference.
- let name = ''
- let value: string | undefined = undefined
- if (/[0-9a-z]/i.test(rawText[1])) {
- if (!maxCRNameLength) {
- maxCRNameLength = Object.keys(namedCharacterReferences).reduce(
- (max, name) => Math.max(max, name.length),
- 0
- )
- }
- for (let length = maxCRNameLength; !value && length > 0; --length) {
- name = rawText.slice(1, 1 + length)
- value = (namedCharacterReferences as Record)[name]
- }
- if (value) {
- const semi = name.endsWith(';')
- if (
- asAttr &&
- !semi &&
- /[=a-z0-9]/i.test(rawText[name.length + 1] || '')
- ) {
- decodedText += '&' + name
- advance(1 + name.length)
- } else {
- decodedText += value
- advance(1 + name.length)
- }
- } else {
- decodedText += '&' + name
- advance(1 + name.length)
- }
- } else {
- decodedText += '&'
- advance(1)
- }
- } else {
- // Numeric character reference.
- const hex = head[0] === ''
- const pattern = hex ? /^([0-9a-f]+);?/i : /^([0-9]+);?/
- const body = pattern.exec(rawText)
- if (!body) {
- decodedText += head[0]
- advance(head[0].length)
- } else {
- // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
- let cp = Number.parseInt(body[1], hex ? 16 : 10)
- if (cp === 0) {
- cp = 0xfffd
- } else if (cp > 0x10ffff) {
- cp = 0xfffd
- } else if (cp >= 0xd800 && cp <= 0xdfff) {
- cp = 0xfffd
- } else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) {
- // noop
- } else if (
- (cp >= 0x01 && cp <= 0x08) ||
- cp === 0x0b ||
- (cp >= 0x0d && cp <= 0x1f) ||
- (cp >= 0x7f && cp <= 0x9f)
- ) {
- cp = CCR_REPLACEMENTS[cp] || cp
- }
- decodedText += String.fromCodePoint(cp)
- advance(body[0].length)
- }
- }
- }
- return decodedText
-}
-
-// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
-const CCR_REPLACEMENTS: Record = {
- 0x80: 0x20ac,
- 0x82: 0x201a,
- 0x83: 0x0192,
- 0x84: 0x201e,
- 0x85: 0x2026,
- 0x86: 0x2020,
- 0x87: 0x2021,
- 0x88: 0x02c6,
- 0x89: 0x2030,
- 0x8a: 0x0160,
- 0x8b: 0x2039,
- 0x8c: 0x0152,
- 0x8e: 0x017d,
- 0x91: 0x2018,
- 0x92: 0x2019,
- 0x93: 0x201c,
- 0x94: 0x201d,
- 0x95: 0x2022,
- 0x96: 0x2013,
- 0x97: 0x2014,
- 0x98: 0x02dc,
- 0x99: 0x2122,
- 0x9a: 0x0161,
- 0x9b: 0x203a,
- 0x9c: 0x0153,
- 0x9e: 0x017e,
- 0x9f: 0x0178
-}
diff --git a/packages/compiler-dom/src/decodeHtmlBrowser.ts b/packages/compiler-dom/src/decodeHtmlBrowser.ts
index cca3bb12a6e..2e72d0fd1f7 100644
--- a/packages/compiler-dom/src/decodeHtmlBrowser.ts
+++ b/packages/compiler-dom/src/decodeHtmlBrowser.ts
@@ -8,9 +8,9 @@ export function decodeHtmlBrowser(raw: string, asAttr = false): string {
}
if (asAttr) {
decoder.innerHTML = ``
- return decoder.children[0].getAttribute('foo') as string
+ return decoder.children[0].getAttribute('foo')!
} else {
decoder.innerHTML = raw
- return decoder.textContent as string
+ return decoder.textContent!
}
}
diff --git a/packages/compiler-dom/src/errors.ts b/packages/compiler-dom/src/errors.ts
index 159bd4ba3b0..faf6fb56441 100644
--- a/packages/compiler-dom/src/errors.ts
+++ b/packages/compiler-dom/src/errors.ts
@@ -1,8 +1,8 @@
import {
- SourceLocation,
- CompilerError,
+ type CompilerError,
+ ErrorCodes,
+ type SourceLocation,
createCompilerError,
- ErrorCodes
} from '@vue/compiler-core'
export interface DOMCompilerError extends CompilerError {
@@ -11,17 +11,17 @@ export interface DOMCompilerError extends CompilerError {
export function createDOMCompilerError(
code: DOMErrorCodes,
- loc?: SourceLocation
+ loc?: SourceLocation,
) {
return createCompilerError(
code,
loc,
- __DEV__ || !__BROWSER__ ? DOMErrorMessages : undefined
+ __DEV__ || !__BROWSER__ ? DOMErrorMessages : undefined,
) as DOMCompilerError
}
-export const enum DOMErrorCodes {
- X_V_HTML_NO_EXPRESSION = ErrorCodes.__EXTEND_POINT__,
+export enum DOMErrorCodes {
+ X_V_HTML_NO_EXPRESSION = 53 /* ErrorCodes.__EXTEND_POINT__ */,
X_V_HTML_WITH_CHILDREN,
X_V_TEXT_NO_EXPRESSION,
X_V_TEXT_WITH_CHILDREN,
@@ -32,7 +32,20 @@ export const enum DOMErrorCodes {
X_V_SHOW_NO_EXPRESSION,
X_TRANSITION_INVALID_CHILDREN,
X_IGNORED_SIDE_EFFECT_TAG,
- __EXTEND_POINT__
+ __EXTEND_POINT__,
+}
+
+if (__TEST__) {
+ // esbuild cannot infer enum increments if first value is from another
+ // file, so we have to manually keep them in sync. this check ensures it
+ // errors out if there are collisions.
+ if (DOMErrorCodes.X_V_HTML_NO_EXPRESSION < ErrorCodes.__EXTEND_POINT__) {
+ throw new Error(
+ `DOMErrorCodes need to be updated to ${
+ ErrorCodes.__EXTEND_POINT__
+ } to match extension point from core ErrorCodes.`,
+ )
+ }
}
export const DOMErrorMessages: { [code: number]: string } = {
@@ -46,5 +59,5 @@ export const DOMErrorMessages: { [code: number]: string } = {
[DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
[DOMErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`,
[DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN]: `
expects exactly one child element or component.`,
- [DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG]: `Tags with side effect (
+ `)
+ expect(content).toMatch(`return { a, b }`)
+ assertCode(content)
+ })
+
test('should expose top level declarations', () => {
const { content, bindings } = compile(`
- `)
- // should generate working code
- assertCode(content)
- // should analyze bindings
- expect(bindings).toStrictEqual({
- foo: BindingTypes.PROPS,
- bar: BindingTypes.SETUP_CONST,
- props: BindingTypes.SETUP_REACTIVE_CONST
- })
-
- // should remove defineOptions import and call
- expect(content).not.toMatch('defineProps')
- // should generate correct setup signature
- expect(content).toMatch(`setup(__props, { expose }) {`)
- // should assign user identifier to it
- expect(content).toMatch(`const props = __props`)
- // should include context options in default export
- expect(content).toMatch(`export default {
- props: {
- foo: String
-},`)
- })
-
- test('defineProps w/ external definition', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`export default {
- props: propsModel,`)
- })
-
- // #4764
- test('defineProps w/ leading code', () => {
- const { content } = compile(`
-
- `)
- // props declaration should be inside setup, not moved along with the import
- expect(content).not.toMatch(`const props = __props\nimport`)
- assertCode(content)
- })
-
- test('defineEmits()', () => {
- const { content, bindings } = compile(`
-
- `)
- assertCode(content)
- expect(bindings).toStrictEqual({
- myEmit: BindingTypes.SETUP_CONST
- })
- // should remove defineOptions import and call
- expect(content).not.toMatch('defineEmits')
- // should generate correct setup signature
- expect(content).toMatch(`setup(__props, { expose, emit: myEmit }) {`)
- // should include context options in default export
- expect(content).toMatch(`export default {
- emits: ['foo', 'bar'],`)
- })
-
- test('defineProps/defineEmits in multi-variable declaration', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`const a = 1;`) // test correct removal
- expect(content).toMatch(`props: ['item'],`)
- expect(content).toMatch(`emits: ['a'],`)
- })
-
- // #6757
- test('defineProps/defineEmits in multi-variable declaration fix #6757 ', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`const a = 1;`) // test correct removal
- expect(content).toMatch(`props: ['item'],`)
- expect(content).toMatch(`emits: ['a'],`)
- })
-
- test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`props: ['item'],`)
- expect(content).toMatch(`emits: ['a'],`)
- })
-
- test('defineExpose()', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- // should remove defineOptions import and call
- expect(content).not.toMatch('defineExpose')
- // should generate correct setup signature
- expect(content).toMatch(`setup(__props, { expose }) {`)
- // should replace callee
- expect(content).toMatch(/\bexpose\(\{ foo: 123 \}\)/)
- })
-
- test('
-
- `)
- assertCode(content)
- })
-
describe('
+ `)
+ assertCode(content)
+
+ expect(content).toMatch(`console.log('test')`)
+ expect(content).toMatch(`const props = __props;`)
+ expect(content).toMatch(`const emit = __emit;`)
+ expect(content).toMatch(`(function () {})()`)
+ })
+
test('script setup first, named default export', () => {
const { content } = compile(`
+
+
+ `)
+ assertCode(content)
+ })
})
describe('imports', () => {
@@ -304,7 +215,7 @@ defineExpose({ foo: 123 })
compile(``).content
+ `).content,
)
})
@@ -315,7 +226,7 @@ defineExpose({ foo: 123 })
import a from 'a' // comment
import b from 'b'
- `).content
+ `).content,
)
})
@@ -327,7 +238,7 @@ defineExpose({ foo: 123 })
defineProps(['foo'])
defineEmits(['bar'])
const r = ref(0)
- `).content
+ `).content,
)
})
@@ -335,14 +246,22 @@ defineExpose({ foo: 123 })
const { content } = compile(
`
+
+
`,
- { reactivityTransform: true }
)
assertCode(content)
- expect(content).toMatch(`import { ref } from 'vue'`)
+ expect(content).toMatch(
+ `import { useCssVars as _useCssVars, unref as _unref } from 'vue'`,
+ )
+ expect(content).toMatch(`import { useCssVars, ref } from 'vue'`)
})
test('import dedupe between
-
-
-
-
- FooBar
-
- `)
- // FooBar: should not be matched by plain text or incorrect case
- // FooBaz: used as PascalCase component
- // FooQux: used as kebab-case component
- // foo: lowercase component
- expect(content).toMatch(
- `return { fooBar, get FooBaz() { return FooBaz }, ` +
- `get FooQux() { return FooQux }, get foo() { return foo } }`
- )
- assertCode(content)
- })
-
- test('directive', () => {
- const { content } = compile(`
-
-
-
-
- `)
- expect(content).toMatch(`return { get vMyDir() { return vMyDir } }`)
- assertCode(content)
- })
- // https://github.com/vuejs/core/issues/4599
- test('attribute expressions', () => {
- const { content } = compile(`
-
-
-
-
- `)
- expect(content).toMatch(
- `return { cond, get bar() { return bar }, get baz() { return baz } }`
- )
- assertCode(content)
- })
-
- test('vue interpolations', () => {
- const { content } = compile(`
-
-
- {{ x }} {{ yy }} {{ x$y }}
-
- `)
- // x: used in interpolation
- // y: should not be matched by {{ yy }} or 'y' in binding exps
- // x$y: #4274 should escape special chars when creating Regex
- expect(content).toMatch(
- `return { get x() { return x }, get z() { return z }, get x$y() { return x$y } }`
- )
- assertCode(content)
- })
-
- // #4340 interpolations in template strings
- test('js template string interpolations', () => {
- const { content } = compile(`
-
-
- {{ \`\${VAR}VAR2\${VAR3}\` }}
-
- `)
- // VAR2 should not be matched
- expect(content).toMatch(
- `return { get VAR() { return VAR }, get VAR3() { return VAR3 } }`
- )
- assertCode(content)
- })
-
- // edge case: last tag in template
- test('last tag', () => {
- const { content } = compile(`
-
-
-
-
-
- `)
- expect(content).toMatch(
- `return { get FooBaz() { return FooBaz }, get Last() { return Last } }`
- )
- assertCode(content)
- })
-
- test('TS annotations', () => {
- const { content } = compile(`
-
-
- {{ a as Foo }}
- {{ b() }}
- {{ Baz }}
- {{ data }}
-
-
- `)
- expect(content).toMatch(`return { a, b, get Baz() { return Baz } }`)
- assertCode(content)
- })
-
- // vuejs/vue#12591
- test('v-on inline statement', () => {
- // should not error
- compile(`
-
-
-
-
- `)
+ `)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.SETUP_MAYBE_REF,
+ })
})
})
@@ -568,7 +358,7 @@ defineExpose({ foo: 123 })
static
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
// check snapshot and make sure helper imports and
// hoists are placed correctly.
@@ -586,10 +376,10 @@ defineExpose({ foo: 123 })
defineExpose({ count })
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
assertCode(content)
- expect(content).toMatch(`setup(__props, { expose })`)
+ expect(content).toMatch(`setup(__props, { expose: __expose })`)
expect(content).toMatch(`expose({ count })`)
})
@@ -607,7 +397,7 @@ defineExpose({ foo: 123 })
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
expect(content).toMatch('[_unref(vMyDir)]')
expect(content).toMatch('_createVNode(ChildComp)')
@@ -636,7 +426,7 @@ defineExpose({ foo: 123 })
{{ tree.foo() }}
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
// no need to unref vue component import
expect(content).toMatch(`createVNode(Foo,`)
@@ -675,7 +465,7 @@ defineExpose({ foo: 123 })
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
// known const ref: set value
expect(content).toMatch(`(count).value = $event`)
@@ -683,8 +473,25 @@ defineExpose({ foo: 123 })
expect(content).toMatch(`_isRef(maybe) ? (maybe).value = $event : null`)
// let: handle both cases
expect(content).toMatch(
- `_isRef(lett) ? (lett).value = $event : lett = $event`
+ `_isRef(lett) ? (lett).value = $event : lett = $event`,
+ )
+ assertCode(content)
+ })
+
+ test('v-model w/ newlines codegen', () => {
+ const { content } = compile(
+ `
+
+
+
+ `,
+ { inlineTemplate: true },
)
+ expect(content).toMatch(`_isRef(count) ? (count).value = $event : null`)
assertCode(content)
})
@@ -703,7 +510,7 @@ defineExpose({ foo: 123 })
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
expect(content).not.toMatch(`_isRef(foo)`)
})
@@ -741,7 +548,7 @@ defineExpose({ foo: 123 })
}"/>
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
// known const ref: set value
expect(content).toMatch(`count.value = 1`)
@@ -749,7 +556,7 @@ defineExpose({ foo: 123 })
expect(content).toMatch(`maybe.value = count.value`)
// let: handle both cases
expect(content).toMatch(
- `_isRef(lett) ? lett.value = count.value : lett = count.value`
+ `_isRef(lett) ? lett.value = count.value : lett = count.value`,
)
expect(content).toMatch(`_isRef(v) ? v.value += 1 : v += 1`)
expect(content).toMatch(`_isRef(v) ? v.value -= 1 : v -= 1`)
@@ -775,7 +582,7 @@ defineExpose({ foo: 123 })
`,
- { inlineTemplate: true }
+ { inlineTemplate: true },
)
// known const ref: set value
expect(content).toMatch(`count.value++`)
@@ -785,552 +592,152 @@ defineExpose({ foo: 123 })
expect(content).toMatch(`--maybe.value`)
// let: handle both cases
expect(content).toMatch(`_isRef(lett) ? lett.value++ : lett++`)
- expect(content).toMatch(`_isRef(lett) ? --lett.value : --lett`)
- assertCode(content)
- })
-
- test('template destructure assignment codegen', () => {
- const { content } = compile(
- `
-
-
-
-
-
- `,
- { inlineTemplate: true }
- )
- // known const ref: set value
- expect(content).toMatch(`({ count: count.value } = val)`)
- // const but maybe ref (non-ref case ignored)
- expect(content).toMatch(`[maybe.value] = val`)
- // let: assumes non-ref
- expect(content).toMatch(`{ lett: lett } = val`)
- assertCode(content)
- })
-
- test('ssr codegen', () => {
- const { content } = compile(
- `
-
-
- {{ count }}
- static
-
-
- `,
- {
- inlineTemplate: true,
- templateOptions: {
- ssr: true
- }
- }
- )
- expect(content).toMatch(`\n __ssrInlineRender: true,\n`)
- expect(content).toMatch(`return (_ctx, _push`)
- expect(content).toMatch(`ssrInterpolate`)
- expect(content).not.toMatch(`useCssVars`)
- expect(content).toMatch(`"--${mockId}-count": (count.value)`)
- assertCode(content)
- })
- })
-
- describe('with TypeScript', () => {
- test('hoist type declarations', () => {
- const { content } = compile(`
- `)
- assertCode(content)
- })
-
- test('defineProps/Emit w/ runtime options', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`export default /*#__PURE__*/_defineComponent({
- props: { foo: String },
- emits: ['a', 'b'],
- setup(__props, { expose, emit }) {`)
- })
-
- test('defineProps w/ type', () => {
- const { content, bindings } = compile(`
- `)
- assertCode(content)
- expect(content).toMatch(`string: { type: String, required: true }`)
- expect(content).toMatch(`number: { type: Number, required: true }`)
- expect(content).toMatch(`boolean: { type: Boolean, required: true }`)
- expect(content).toMatch(`object: { type: Object, required: true }`)
- expect(content).toMatch(`objectLiteral: { type: Object, required: true }`)
- expect(content).toMatch(`fn: { type: Function, required: true }`)
- expect(content).toMatch(`functionRef: { type: Function, required: true }`)
- expect(content).toMatch(`objectRef: { type: Object, required: true }`)
- expect(content).toMatch(`dateTime: { type: Date, required: true }`)
- expect(content).toMatch(`array: { type: Array, required: true }`)
- expect(content).toMatch(`arrayRef: { type: Array, required: true }`)
- expect(content).toMatch(`tuple: { type: Array, required: true }`)
- expect(content).toMatch(`set: { type: Set, required: true }`)
- expect(content).toMatch(`literal: { type: String, required: true }`)
- expect(content).toMatch(`optional: { type: null, required: false }`)
- expect(content).toMatch(`recordRef: { type: Object, required: true }`)
- expect(content).toMatch(`interface: { type: Object, required: true }`)
- expect(content).toMatch(`alias: { type: Array, required: true }`)
- expect(content).toMatch(`method: { type: Function, required: true }`)
- expect(content).toMatch(`symbol: { type: Symbol, required: true }`)
- expect(content).toMatch(
- `union: { type: [String, Number], required: true }`
- )
- expect(content).toMatch(`literalUnion: { type: String, required: true }`)
- expect(content).toMatch(
- `literalUnionNumber: { type: Number, required: true }`
- )
- expect(content).toMatch(
- `literalUnionMixed: { type: [String, Number, Boolean], required: true }`
- )
- expect(content).toMatch(`intersection: { type: Object, required: true }`)
- expect(content).toMatch(`foo: { type: [Function, null], required: true }`)
- expect(bindings).toStrictEqual({
- string: BindingTypes.PROPS,
- number: BindingTypes.PROPS,
- boolean: BindingTypes.PROPS,
- object: BindingTypes.PROPS,
- objectLiteral: BindingTypes.PROPS,
- fn: BindingTypes.PROPS,
- functionRef: BindingTypes.PROPS,
- objectRef: BindingTypes.PROPS,
- dateTime: BindingTypes.PROPS,
- array: BindingTypes.PROPS,
- arrayRef: BindingTypes.PROPS,
- tuple: BindingTypes.PROPS,
- set: BindingTypes.PROPS,
- literal: BindingTypes.PROPS,
- optional: BindingTypes.PROPS,
- recordRef: BindingTypes.PROPS,
- interface: BindingTypes.PROPS,
- alias: BindingTypes.PROPS,
- method: BindingTypes.PROPS,
- symbol: BindingTypes.PROPS,
- union: BindingTypes.PROPS,
- literalUnion: BindingTypes.PROPS,
- literalUnionNumber: BindingTypes.PROPS,
- literalUnionMixed: BindingTypes.PROPS,
- intersection: BindingTypes.PROPS,
- foo: BindingTypes.PROPS
- })
- })
-
- test('defineProps w/ interface', () => {
- const { content, bindings } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`x: { type: Number, required: false }`)
- expect(bindings).toStrictEqual({
- x: BindingTypes.PROPS
- })
- })
-
- test('defineProps w/ extends interface', () => {
- const { content, bindings } = compile(`
-
-
- `)
- assertCode(content)
- expect(content).toMatch(`z: { type: Number, required: true }`)
- expect(content).toMatch(`y: { type: String, required: true }`)
- expect(content).toMatch(`x: { type: Number, required: false }`)
- expect(bindings).toStrictEqual({
- x: BindingTypes.PROPS,
- y: BindingTypes.PROPS,
- z: BindingTypes.PROPS
- })
- })
-
- test('defineProps w/ exported interface', () => {
- const { content, bindings } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`x: { type: Number, required: false }`)
- expect(bindings).toStrictEqual({
- x: BindingTypes.PROPS
- })
- })
-
- test('defineProps w/ exported interface in normal script', () => {
- const { content, bindings } = compile(`
-
-
- `)
- assertCode(content)
- expect(content).toMatch(`x: { type: Number, required: false }`)
- expect(bindings).toStrictEqual({
- x: BindingTypes.PROPS
- })
- })
-
- test('defineProps w/ type alias', () => {
- const { content, bindings } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`x: { type: Number, required: false }`)
- expect(bindings).toStrictEqual({
- x: BindingTypes.PROPS
- })
- })
-
- test('defineProps w/ exported type alias', () => {
- const { content, bindings } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`x: { type: Number, required: false }`)
- expect(bindings).toStrictEqual({
- x: BindingTypes.PROPS
- })
- })
-
- test('withDefaults (static)', () => {
- const { content, bindings } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(
- `foo: { type: String, required: false, default: 'hi' }`
- )
- expect(content).toMatch(`bar: { type: Number, required: false }`)
- expect(content).toMatch(`baz: { type: Boolean, required: true }`)
- expect(content).toMatch(
- `qux: { type: Function, required: false, default() { return 1 } }`
- )
- expect(content).toMatch(
- `quux: { type: Function, required: false, default() { } }`
- )
- expect(content).toMatch(
- `quuxx: { type: Promise, required: false, async default() { return await Promise.resolve('hi') } }`
- )
- expect(content).toMatch(
- `fred: { type: String, required: false, get default() { return 'fred' } }`
- )
- expect(content).toMatch(
- `{ foo: string, bar?: number, baz: boolean, qux(): number, quux(): void, quuxx: Promise, fred: string }`
- )
- expect(content).toMatch(`const props = __props`)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.PROPS,
- bar: BindingTypes.PROPS,
- baz: BindingTypes.PROPS,
- qux: BindingTypes.PROPS,
- quux: BindingTypes.PROPS,
- quuxx: BindingTypes.PROPS,
- fred: BindingTypes.PROPS,
- props: BindingTypes.SETUP_CONST
- })
- })
-
- // #7111
- test('withDefaults (static) w/ production mode', () => {
- const { content } = compile(
- `
-
- `,
- { isProd: true }
- )
- assertCode(content)
- expect(content).toMatch(`const props = __props`)
-
- // foo has no default value, the Function can be dropped
- expect(content).toMatch(`foo: null`)
- expect(content).toMatch(`bar: { type: Boolean }`)
- expect(content).toMatch(
- `baz: { type: [Boolean, Function], default: true }`
- )
- expect(content).toMatch(`qux: { default: 'hi' }`)
- })
-
- test('withDefaults (dynamic)', () => {
- const { content } = compile(`
-
- `)
+ expect(content).toMatch(`_isRef(lett) ? --lett.value : --lett`)
assertCode(content)
- expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
- expect(content).toMatch(
- `
- _mergeDefaults({
- foo: { type: String, required: false },
- bar: { type: Number, required: false },
- baz: { type: Boolean, required: true }
- }, { ...defaults })`.trim()
+ })
+
+ test('template destructure assignment codegen', () => {
+ const { content } = compile(
+ `
+
+
+
+
+
+ `,
+ { inlineTemplate: true },
)
+ // known const ref: set value
+ expect(content).toMatch(`({ count: count.value } = val)`)
+ // const but maybe ref (non-ref case ignored)
+ expect(content).toMatch(`[maybe.value] = val`)
+ // let: assumes non-ref
+ expect(content).toMatch(`{ lett: lett } = val`)
+ assertCode(content)
})
- // #7111
- test('withDefaults (dynamic) w/ production mode', () => {
+ test('ssr codegen', () => {
const { content } = compile(
`
-
- `,
- { isProd: true }
+
+
+ {{ count }}
+ static
+
+
+ `,
+ {
+ inlineTemplate: true,
+ templateOptions: {
+ ssr: true,
+ },
+ },
)
- assertCode(content)
- expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+ expect(content).toMatch(`\n __ssrInlineRender: true,\n`)
+ expect(content).toMatch(`return (_ctx, _push`)
+ expect(content).toMatch(`ssrInterpolate`)
+ expect(content).not.toMatch(`useCssVars`)
+ expect(content).toMatch(`":--${mockId}-count": (count.value)`)
+ expect(content).toMatch(`":--${mockId}-style\\\\.color": (style.color)`)
expect(content).toMatch(
- `
- _mergeDefaults({
- foo: { type: Function },
- bar: { type: Boolean },
- baz: { type: [Boolean, Function] },
- qux: null
- }, { ...defaults })`.trim()
+ `":--${mockId}-height\\\\ \\\\+\\\\ \\\\\\"px\\\\\\"": (height.value + "px")`,
)
- })
-
- test('defineEmits w/ type', () => {
- const { content } = compile(`
-
- `)
assertCode(content)
- expect(content).toMatch(`emit: ((e: 'foo' | 'bar') => void),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
})
- test('defineEmits w/ type (union)', () => {
- const type = `((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)`
+ test('the v-for wrapped in parentheses can be correctly parsed & inline is false', () => {
expect(() =>
- compile(`
-
- `)
- ).toThrow()
- })
-
- test('defineEmits w/ type (type literal w/ call signatures)', () => {
- const type = `{(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}`
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`emit: (${type}),`)
- expect(content).toMatch(`emits: ["foo", "bar", "baz"]`)
- })
-
- test('defineEmits w/ type (interface)', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
- })
-
- test('defineEmits w/ type (exported interface)', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
- })
-
- test('defineEmits w/ type (type alias)', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
- })
-
- test('defineEmits w/ type (exported type alias)', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
+ compile(
+ `
+
+
+
+
+ `,
+ {
+ inlineTemplate: false,
+ },
+ ),
+ ).not.toThrowError()
})
- test('defineEmits w/ type (referenced function type)', () => {
- const { content } = compile(`
-
- `)
+ test('unref + new expression', () => {
+ const { content } = compile(
+ `
+
+
+ {{ new Foo() }}
+ {{ new Foo.Bar() }}
+
+ `,
+ { inlineTemplate: true },
+ )
+ expect(content).toMatch(`new (_unref(Foo))()`)
+ expect(content).toMatch(`new (_unref(Foo)).Bar()`)
assertCode(content)
- expect(content).toMatch(`emit: ((e: 'foo' | 'bar') => void),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
})
- test('defineEmits w/ type (referenced exported function type)', () => {
- const { content } = compile(`
-
- `)
- assertCode(content)
- expect(content).toMatch(`emit: ((e: 'foo' | 'bar') => void),`)
- expect(content).toMatch(`emits: ["foo", "bar"]`)
+
+
+
+ `
+ const { content, map } = compile(source, { inlineTemplate: true })
+ expect(map).not.toBeUndefined()
+ const consumer = new SourceMapConsumer(map as RawSourceMap)
+ expect(
+ consumer.originalPositionFor(getPositionInCode(content, 'count')),
+ ).toMatchObject(getPositionInCode(source, `count`))
+ expect(
+ consumer.originalPositionFor(getPositionInCode(content, 'Error')),
+ ).toMatchObject(getPositionInCode(source, `Error`))
})
+ })
- // #5393
- test('defineEmits w/ type (interface ts type)', () => {
+ describe('with TypeScript', () => {
+ test('hoist type declarations', () => {
const { content } = compile(`
- `)
+ export interface Foo {}
+ type Bar = {}
+ `)
assertCode(content)
- expect(content).toMatch(`setup(__props, { expose, emit }) {`)
- expect(content).toMatch(`emits: ['foo']`)
})
test('runtime Enum', () => {
const { content, bindings } = compile(
``
+ `,
)
assertCode(content)
expect(bindings).toStrictEqual({
- Foo: BindingTypes.SETUP_CONST
+ Foo: BindingTypes.LITERAL_CONST,
})
})
@@ -1343,14 +750,14 @@ const emit = defineEmits(['a', 'b'])
`
+ `,
)
assertCode(content)
expect(bindings).toStrictEqual({
- D: BindingTypes.SETUP_CONST,
- C: BindingTypes.SETUP_CONST,
- B: BindingTypes.SETUP_CONST,
- Foo: BindingTypes.SETUP_CONST
+ D: BindingTypes.LITERAL_CONST,
+ C: BindingTypes.LITERAL_CONST,
+ B: BindingTypes.LITERAL_CONST,
+ Foo: BindingTypes.LITERAL_CONST,
})
})
@@ -1358,11 +765,12 @@ const emit = defineEmits(['a', 'b'])
const { content, bindings } = compile(
``
+ `,
+ { hoistStatic: true },
)
assertCode(content)
expect(bindings).toStrictEqual({
- Foo: BindingTypes.SETUP_CONST
+ Foo: BindingTypes.LITERAL_CONST,
})
})
@@ -1371,18 +779,24 @@ const emit = defineEmits(['a', 'b'])
``
+ `,
)
expect(content).toMatch(`return { get Baz() { return Baz } }`)
assertCode(content)
})
+
+ test('with generic attribute', () => {
+ const { content } = compile(`
+ `)
+ assertCode(content)
+ })
})
describe('async/await detection', () => {
function assertAwaitDetection(code: string, shouldAsync = true) {
- const { content } = compile(``, {
- reactivityTransform: true
- })
+ const { content } = compile(``)
if (shouldAsync) {
expect(content).toMatch(`let __temp, __restore`)
}
@@ -1400,7 +814,7 @@ const emit = defineEmits(['a', 'b'])
})
test('ref', () => {
- assertAwaitDetection(`let a = $ref(1 + (await foo))`)
+ assertAwaitDetection(`let a = ref(1 + (await foo))`)
})
// #4448
@@ -1489,7 +903,7 @@ const emit = defineEmits(['a', 'b'])
// class method
assertAwaitDetection(
`const cls = class Foo { async method() { await bar }}`,
- false
+ false,
)
})
})
@@ -1497,7 +911,7 @@ const emit = defineEmits(['a', 'b'])
describe('errors', () => {
test('`)
+ compile(``),
).toThrow(``)
+ `),
).toThrow(moduleErrorMsg)
expect(() =>
compile(``)
+ `),
).toThrow(moduleErrorMsg)
expect(() =>
compile(``)
+ `),
).toThrow(moduleErrorMsg)
})
- test('defineProps/Emit() w/ both type and non-type args', () => {
- expect(() => {
- compile(``)
- }).toThrow(`cannot accept both type and non-type arguments`)
-
- expect(() => {
- compile(``)
- }).toThrow(`cannot accept both type and non-type arguments`)
- })
-
test('defineProps/Emit() referencing local var', () => {
expect(() =>
compile(``)
+ `),
).toThrow(`cannot reference locally declared variables`)
expect(() =>
compile(``)
+ `),
).toThrow(`cannot reference locally declared variables`)
// #4644
@@ -1567,7 +967,7 @@ const emit = defineEmits(['a', 'b'])
default: () => bar
}
})
- `)
+ `),
).not.toThrow(`cannot reference locally declared variables`)
})
@@ -1583,7 +983,7 @@ const emit = defineEmits(['a', 'b'])
defineEmits({
foo: bar => bar > 1
})
- `).content
+ `).content,
)
})
@@ -1599,9 +999,41 @@ const emit = defineEmits(['a', 'b'])
defineEmits({
foo: () => bar > 1
})
- `).content
+ `).content,
)
})
+
+ test('defineModel() referencing local var', () => {
+ expect(() =>
+ compile(``),
+ ).toThrow(`cannot reference locally declared variables`)
+
+ // allow const
+ expect(() =>
+ compile(``),
+ ).not.toThrow(`cannot reference locally declared variables`)
+
+ // allow in get/set
+ expect(() =>
+ compile(``),
+ ).not.toThrow(`cannot reference locally declared variables`)
+ })
})
})
@@ -1633,7 +1065,7 @@ describe('SFC analyze
`)
expect(bindings).toStrictEqual({
- foo: BindingTypes.SETUP_CONST
+ foo: BindingTypes.LITERAL_CONST,
})
})
@@ -1713,7 +1145,7 @@ describe('SFC analyze `,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).toMatch(`const _sfc_ = {}`)
+ assertCode(content)
+ })
+
+ test('normal
+ `,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).not.toMatch('__default__')
+ expect(content).toMatch(`const _sfc_ = {}`)
+ assertCode(content)
+ })
+
+ test('
+ `,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).toMatch(
+ `const _sfc_ = /*@__PURE__*/Object.assign(__default__`,
+ )
+ assertCode(content)
+ })
+
+ test('
+ `,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).toMatch(
+ `const _sfc_ = /*@__PURE__*/Object.assign(__default__`,
+ )
+ assertCode(content)
+ })
+
+ test('`,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).toMatch(`const _sfc_ = {\n setup`)
+ assertCode(content)
+ })
+
+ test('`,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).toMatch(`const _sfc_ = /*@__PURE__*/_defineComponent(`)
+ assertCode(content)
+ })
+
+ test('
+ `,
+ {
+ genDefaultAs: '_sfc_',
+ },
+ )
+ expect(content).not.toMatch('export default')
+ expect(content).toMatch(
+ `const _sfc_ = /*@__PURE__*/_defineComponent({\n ...__default__`,
+ )
+ assertCode(content)
+ })
+
+ test('binding type for edge cases', () => {
+ const { bindings } = compile(
+ ``,
+ )
+ expect(bindings).toStrictEqual({
+ toRef: BindingTypes.SETUP_CONST,
+ props: BindingTypes.SETUP_REACTIVE_CONST,
+ foo: BindingTypes.SETUP_REF,
+ })
+ })
+
+ describe('parser plugins', () => {
+ test('import attributes', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+
+ expect(() =>
+ compile(`
+ `),
+ ).toThrow()
+ })
+
+ test('import attributes (user override for deprecated syntax)', () => {
+ const { content } = compile(
+ `
+
+ `,
+ {
+ babelParserPlugins: [
+ ['importAttributes', { deprecatedAssertSyntax: true }],
+ ],
+ },
+ )
+ assertCode(content)
+ })
+ })
+})
+
+describe('compileScript', () => {
+ test('should care about runtimeModuleName', () => {
+ const { content } = compile(
+ `
+
+ `,
+ {
+ templateOptions: {
+ compilerOptions: {
+ runtimeModuleName: 'npm:vue',
+ },
+ },
+ },
+ )
+ expect(content).toMatch(
+ `import { withAsyncContext as _withAsyncContext } from "npm:vue"\n`,
+ )
+ assertCode(content)
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap
new file mode 100644
index 00000000000..a25a384a979
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap
@@ -0,0 +1,285 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`defineEmits > basic usage 1`] = `
+"
+export default {
+ emits: ['foo', 'bar'],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+const myEmit = __emit
+
+return { myEmit }
+}
+
+}"
+`;
+
+exports[`defineEmits > w/ runtime options 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ['a', 'b'],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (exported interface) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+export interface Emits { (e: 'foo' | 'bar'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (exported type alias) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+export type Emits = { (e: 'foo' | 'bar'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (interface ts type) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+interface Emits { (e: 'foo'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ['foo'],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit: Emits = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (interface w/ extends) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+interface Base { (e: 'foo'): void }
+ interface Emits extends Base { (e: 'bar'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["bar", "foo"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (interface) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+interface Emits { (e: 'foo' | 'bar'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (property syntax string literal) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo:bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (property syntax) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (referenced exported function type) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+export type Emits = (e: 'foo' | 'bar') => void
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (referenced function type) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+type Emits = (e: 'foo' | 'bar') => void
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (type alias) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+type Emits = { (e: 'foo' | 'bar'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (type literal w/ call signatures) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar", "baz"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (type references in union) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+type BaseEmit = "change"
+ type Emit = "some" | "emit" | BaseEmit
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["some", "emit", "change", "another"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit;
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type (union) 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar", "baz"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
+
+exports[`defineEmits > w/ type from normal script 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+
+ export interface Emits { (e: 'foo' | 'bar'): void }
+
+export default /*@__PURE__*/_defineComponent({
+ emits: ["foo", "bar"],
+ setup(__props, { expose: __expose, emit: __emit }) {
+ __expose();
+
+ const emit = __emit
+
+return { emit }
+}
+
+})"
+`;
diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineExpose.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineExpose.spec.ts.snap
new file mode 100644
index 00000000000..f8754f8a9af
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineExpose.spec.ts.snap
@@ -0,0 +1,29 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`
+ `)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ myEmit: BindingTypes.SETUP_CONST,
+ })
+ // should remove defineEmits import and call
+ expect(content).not.toMatch('defineEmits')
+ // should generate correct setup signature
+ expect(content).toMatch(
+ `setup(__props, { expose: __expose, emit: __emit }) {`,
+ )
+ expect(content).toMatch('const myEmit = __emit')
+ // should include context options in default export
+ expect(content).toMatch(`export default {
+ emits: ['foo', 'bar'],`)
+ })
+
+ test('w/ runtime options', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`export default /*@__PURE__*/_defineComponent({
+ emits: ['a', 'b'],
+ setup(__props, { expose: __expose, emit: __emit }) {`)
+ expect(content).toMatch('const emit = __emit')
+ })
+
+ test('w/ type', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type (union)', () => {
+ const type = `((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)`
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar", "baz"]`)
+ })
+
+ test('w/ type (type literal w/ call signatures)', () => {
+ const type = `{(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}`
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar", "baz"]`)
+ })
+
+ test('w/ type (interface)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type (interface w/ extends)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["bar", "foo"]`)
+ })
+
+ test('w/ type (exported interface)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type from normal script', () => {
+ const { content } = compile(`
+
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type (type alias)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type (exported type alias)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type (referenced function type)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ test('w/ type (referenced exported function type)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ })
+
+ // #5393
+ test('w/ type (interface ts type)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`emits: ['foo']`)
+ })
+
+ test('w/ type (property syntax)', () => {
+ const { content } = compile(`
+
+ `)
+ expect(content).toMatch(`emits: ["foo", "bar"]`)
+ assertCode(content)
+ })
+
+ // #8040
+ test('w/ type (property syntax string literal)', () => {
+ const { content } = compile(`
+
+ `)
+ expect(content).toMatch(`emits: ["foo:bar"]`)
+ assertCode(content)
+ })
+
+ // #7943
+ test('w/ type (type references in union)', () => {
+ const { content } = compile(`
+
+ `)
+
+ expect(content).toMatch(`emits: ["some", "emit", "change", "another"]`)
+ assertCode(content)
+ })
+
+ describe('errors', () => {
+ test('w/ both type and non-type args', () => {
+ expect(() => {
+ compile(``)
+ }).toThrow(`cannot accept both type and non-type arguments`)
+ })
+
+ test('mixed usage of property / call signature', () => {
+ expect(() =>
+ compile(``),
+ ).toThrow(
+ `defineEmits() type cannot mixed call signature and property syntax.`,
+ )
+ })
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineExpose.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineExpose.spec.ts
new file mode 100644
index 00000000000..7b2a9f7cbe4
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/defineExpose.spec.ts
@@ -0,0 +1,26 @@
+import { assertCode, compileSFCScript as compile } from '../utils'
+
+test('defineExpose()', () => {
+ const { content } = compile(`
+
+`)
+ assertCode(content)
+ // should remove defineOptions import and call
+ expect(content).not.toMatch('defineExpose')
+ // should generate correct setup signature
+ expect(content).toMatch(`setup(__props, { expose: __expose }) {`)
+ // should replace callee
+ expect(content).toMatch(/\b__expose\(\{ foo: 123 \}\)/)
+})
+
+test('
+
+ `)
+ assertCode(content)
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts
new file mode 100644
index 00000000000..5d696a95d88
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts
@@ -0,0 +1,272 @@
+import { BindingTypes } from '@vue/compiler-core'
+import { assertCode, compileSFCScript as compile } from '../utils'
+
+describe('defineModel()', () => {
+ test('basic usage', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ )
+ assertCode(content)
+ expect(content).toMatch('props: {')
+ expect(content).toMatch('"modelValue": { required: true },')
+ expect(content).toMatch('"count": {},')
+ expect(content).toMatch('"toString": { type: Function },')
+ expect(content).toMatch(
+ 'emits: ["update:modelValue", "update:count", "update:toString"],',
+ )
+ expect(content).toMatch(
+ `const modelValue = _useModel(__props, "modelValue")`,
+ )
+ expect(content).toMatch(`const c = _useModel(__props, 'count')`)
+ expect(content).toMatch(`const toString = _useModel(__props, 'toString')`)
+ expect(content).toMatch(`return { modelValue, c, toString }`)
+ expect(content).not.toMatch('defineModel')
+
+ expect(bindings).toStrictEqual({
+ modelValue: BindingTypes.SETUP_REF,
+ count: BindingTypes.PROPS,
+ c: BindingTypes.SETUP_REF,
+ toString: BindingTypes.SETUP_REF,
+ })
+ })
+
+ test('w/ defineProps and defineEmits', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ )
+ assertCode(content)
+ expect(content).toMatch(`props: /*@__PURE__*/_mergeModels({ foo: String }`)
+ expect(content).toMatch(`"modelValue": { default: 0 }`)
+ expect(content).toMatch(`const count = _useModel(__props, "modelValue")`)
+ expect(content).not.toMatch('defineModel')
+ expect(bindings).toStrictEqual({
+ count: BindingTypes.SETUP_REF,
+ foo: BindingTypes.PROPS,
+ modelValue: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ array props', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ )
+ assertCode(content)
+ expect(content).toMatch(`props: /*@__PURE__*/_mergeModels(['foo', 'bar'], {
+ "count": {},
+ "countModifiers": {},
+ })`)
+ expect(content).toMatch(`const count = _useModel(__props, 'count')`)
+ expect(content).not.toMatch('defineModel')
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS,
+ count: BindingTypes.SETUP_REF,
+ })
+ })
+
+ test('w/ types, basic usage', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ )
+ assertCode(content)
+ expect(content).toMatch('"modelValue": { type: [Boolean, String] }')
+ expect(content).toMatch('"modelModifiers": {}')
+ expect(content).toMatch('"count": { type: Number }')
+ expect(content).toMatch(
+ '"disabled": { type: Number, ...{ required: false } }',
+ )
+ expect(content).toMatch('"any": { type: Boolean, skipCheck: true }')
+ expect(content).toMatch(
+ 'emits: ["update:modelValue", "update:count", "update:disabled", "update:any"]',
+ )
+
+ expect(content).toMatch(
+ `const modelValue = _useModel(__props, "modelValue")`,
+ )
+ expect(content).toMatch(`const count = _useModel(__props, 'count')`)
+ expect(content).toMatch(
+ `const disabled = _useModel(__props, 'disabled')`,
+ )
+ expect(content).toMatch(
+ `const any = _useModel(__props, 'any')`,
+ )
+
+ expect(bindings).toStrictEqual({
+ modelValue: BindingTypes.SETUP_REF,
+ count: BindingTypes.SETUP_REF,
+ disabled: BindingTypes.SETUP_REF,
+ any: BindingTypes.SETUP_REF,
+ })
+ })
+
+ test('w/ types, production mode', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch('"modelValue": { type: Boolean }')
+ expect(content).toMatch('"fn": {}')
+ expect(content).toMatch(
+ '"fnWithDefault": { type: Function, ...{ default: () => null } },',
+ )
+ expect(content).toMatch('"str": {}')
+ expect(content).toMatch('"optional": { required: false }')
+ expect(content).toMatch(
+ 'emits: ["update:modelValue", "update:fn", "update:fnWithDefault", "update:str", "update:optional"]',
+ )
+ expect(content).toMatch(
+ `const modelValue = _useModel(__props, "modelValue")`,
+ )
+ expect(content).toMatch(`const fn = _useModel<() => void>(__props, 'fn')`)
+ expect(content).toMatch(`const str = _useModel(__props, 'str')`)
+ expect(bindings).toStrictEqual({
+ modelValue: BindingTypes.SETUP_REF,
+ fn: BindingTypes.SETUP_REF,
+ fnWithDefault: BindingTypes.SETUP_REF,
+ str: BindingTypes.SETUP_REF,
+ optional: BindingTypes.SETUP_REF,
+ })
+ })
+
+ test('w/ types, production mode, boolean + multiple types', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch('"modelValue": { type: [Boolean, String, Object] }')
+ })
+
+ test('w/ types, production mode, function + runtime opts + multiple types', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch(
+ '"modelValue": { type: [Number, Function], ...{ default: () => 1 } }',
+ )
+ })
+
+ test('get / set transformers', () => {
+ const { content } = compile(
+ `
+
+ `,
+ )
+ assertCode(content)
+ expect(content).toMatch(/"modelValue": {\s+required: true,?\s+}/m)
+ expect(content).toMatch(
+ `_useModel(__props, "modelValue", {
+ get(v) { return v - 1 },
+ set: (v) => { return v + 1 },
+ })`,
+ )
+
+ const { content: content2 } = compile(
+ `
+
+ `,
+ )
+ assertCode(content2)
+ expect(content2).toMatch(
+ /"modelValue": {\s+default: 0,\s+required: true,?\s+}/m,
+ )
+ expect(content2).toMatch(
+ `_useModel(__props, "modelValue", {
+ get(v) { return v - 1 },
+ set: (v) => { return v + 1 },
+ })`,
+ )
+ })
+
+ test('usage w/ props destructure', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { propsDestructure: true },
+ )
+ assertCode(content)
+ expect(content).toMatch(`set: (v) => { return v + __props.x }`)
+ })
+
+ test('w/ Boolean And Function types, production mode', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch('"modelValue": { type: [Boolean, String] }')
+ expect(content).toMatch('emits: ["update:modelValue"]')
+ expect(content).toMatch(
+ `const modelValue = _useModel(__props, "modelValue")`,
+ )
+ expect(bindings).toStrictEqual({
+ modelValue: BindingTypes.SETUP_REF,
+ })
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineOptions.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineOptions.spec.ts
new file mode 100644
index 00000000000..286f1e11bfd
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/defineOptions.spec.ts
@@ -0,0 +1,149 @@
+import { assertCode, compileSFCScript as compile } from '../utils'
+
+describe('defineOptions()', () => {
+ test('basic usage', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ // should remove defineOptions import and call
+ expect(content).not.toMatch('defineOptions')
+ // should include context options in default export
+ expect(content).toMatch(
+ `export default /*@__PURE__*/Object.assign({ name: 'FooApp' }, `,
+ )
+ })
+
+ test('empty argument', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`export default {`)
+ // should remove defineOptions import and call
+ expect(content).not.toMatch('defineOptions')
+ })
+
+ it('should emit an error with two defineOptions', () => {
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError('[@vue/compiler-sfc] duplicate defineOptions() call')
+ })
+
+ it('should emit an error with props or emits property', () => {
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare props. Use defineProps() instead.',
+ )
+
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare emits. Use defineEmits() instead.',
+ )
+
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare expose. Use defineExpose() instead.',
+ )
+
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare slots. Use defineSlots() instead.',
+ )
+ })
+
+ it('should emit an error with type generic', () => {
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot accept type arguments',
+ )
+ })
+
+ it('should emit an error with type assertion', () => {
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare props. Use defineProps() instead.',
+ )
+ })
+
+ it('should emit an error with declaring props/emits/slots/expose', () => {
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare props. Use defineProps() instead',
+ )
+
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare emits. Use defineEmits() instead',
+ )
+
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare expose. Use defineExpose() instead',
+ )
+
+ expect(() =>
+ compile(`
+
+ `),
+ ).toThrowError(
+ '[@vue/compiler-sfc] defineOptions() cannot be used to declare slots. Use defineSlots() instead',
+ )
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts
new file mode 100644
index 00000000000..836badb51c8
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts
@@ -0,0 +1,811 @@
+import { BindingTypes } from '@vue/compiler-core'
+import { assertCode, compileSFCScript as compile } from '../utils'
+
+describe('defineProps', () => {
+ test('basic usage', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ // should generate working code
+ assertCode(content)
+ // should analyze bindings
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.LITERAL_CONST,
+ props: BindingTypes.SETUP_REACTIVE_CONST,
+ })
+
+ // should remove defineOptions import and call
+ expect(content).not.toMatch('defineProps')
+ // should generate correct setup signature
+ expect(content).toMatch(`setup(__props, { expose: __expose }) {`)
+ // should assign user identifier to it
+ expect(content).toMatch(`const props = __props`)
+ // should include context options in default export
+ expect(content).toMatch(`export default {
+ props: {
+ foo: String
+},`)
+ })
+
+ test('w/ external definition', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`export default {
+ props: propsModel,`)
+ })
+
+ // #4764
+ test('w/ leading code', () => {
+ const { content } = compile(`
+
+ `)
+ // props declaration should be inside setup, not moved along with the import
+ expect(content).not.toMatch(`const props = __props\nimport`)
+ assertCode(content)
+ })
+
+ test('defineProps w/ runtime options', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`export default /*@__PURE__*/_defineComponent({
+ props: { foo: String },
+ setup(__props, { expose: __expose }) {`)
+ })
+
+ test('w/ type', () => {
+ const { content, bindings } = compile(`
+ `)
+ assertCode(content)
+ expect(content).toMatch(`string: { type: String, required: true }`)
+ expect(content).toMatch(`number: { type: Number, required: true }`)
+ expect(content).toMatch(`boolean: { type: Boolean, required: true }`)
+ expect(content).toMatch(`object: { type: Object, required: true }`)
+ expect(content).toMatch(`objectLiteral: { type: Object, required: true }`)
+ expect(content).toMatch(`fn: { type: Function, required: true }`)
+ expect(content).toMatch(`functionRef: { type: Function, required: true }`)
+ expect(content).toMatch(`objectRef: { type: Object, required: true }`)
+ expect(content).toMatch(`dateTime: { type: Date, required: true }`)
+ expect(content).toMatch(`array: { type: Array, required: true }`)
+ expect(content).toMatch(`arrayRef: { type: Array, required: true }`)
+ expect(content).toMatch(`tuple: { type: Array, required: true }`)
+ expect(content).toMatch(`set: { type: Set, required: true }`)
+ expect(content).toMatch(`literal: { type: String, required: true }`)
+ expect(content).toMatch(`optional: { type: null, required: false }`)
+ expect(content).toMatch(`recordRef: { type: Object, required: true }`)
+ expect(content).toMatch(`interface: { type: Object, required: true }`)
+ expect(content).toMatch(`alias: { type: Array, required: true }`)
+ expect(content).toMatch(`method: { type: Function, required: true }`)
+ expect(content).toMatch(`symbol: { type: Symbol, required: true }`)
+ expect(content).toMatch(`error: { type: Error, required: true }`)
+ expect(content).toMatch(
+ `objectOrFn: { type: [Function, Object], required: true },`,
+ )
+ expect(content).toMatch(`extract: { type: Number, required: true }`)
+ expect(content).toMatch(
+ `exclude: { type: [Number, Boolean], required: true }`,
+ )
+ expect(content).toMatch(`uppercase: { type: String, required: true }`)
+ expect(content).toMatch(`params: { type: Array, required: true }`)
+ expect(content).toMatch(`nonNull: { type: String, required: true }`)
+ expect(content).toMatch(`union: { type: [String, Number], required: true }`)
+ expect(content).toMatch(`literalUnion: { type: String, required: true }`)
+ expect(content).toMatch(
+ `literalUnionNumber: { type: Number, required: true }`,
+ )
+ expect(content).toMatch(
+ `literalUnionMixed: { type: [String, Number, Boolean], required: true }`,
+ )
+ expect(content).toMatch(`intersection: { type: Object, required: true }`)
+ expect(content).toMatch(`intersection2: { type: String, required: true }`)
+ expect(content).toMatch(`foo: { type: [Function, null], required: true }`)
+ expect(content).toMatch(`unknown: { type: null, required: true }`)
+ // uninon containing unknown type: skip check
+ expect(content).toMatch(`unknownUnion: { type: null, required: true }`)
+ // intersection containing unknown type: narrow to the known types
+ expect(content).toMatch(
+ `unknownIntersection: { type: Object, required: true },`,
+ )
+ expect(content).toMatch(
+ `unknownUnionWithBoolean: { type: Boolean, required: true, skipCheck: true },`,
+ )
+ expect(content).toMatch(
+ `unknownUnionWithFunction: { type: Function, required: true, skipCheck: true }`,
+ )
+ expect(bindings).toStrictEqual({
+ string: BindingTypes.PROPS,
+ number: BindingTypes.PROPS,
+ boolean: BindingTypes.PROPS,
+ object: BindingTypes.PROPS,
+ objectLiteral: BindingTypes.PROPS,
+ fn: BindingTypes.PROPS,
+ functionRef: BindingTypes.PROPS,
+ objectRef: BindingTypes.PROPS,
+ dateTime: BindingTypes.PROPS,
+ array: BindingTypes.PROPS,
+ arrayRef: BindingTypes.PROPS,
+ tuple: BindingTypes.PROPS,
+ set: BindingTypes.PROPS,
+ literal: BindingTypes.PROPS,
+ optional: BindingTypes.PROPS,
+ recordRef: BindingTypes.PROPS,
+ interface: BindingTypes.PROPS,
+ alias: BindingTypes.PROPS,
+ method: BindingTypes.PROPS,
+ symbol: BindingTypes.PROPS,
+ error: BindingTypes.PROPS,
+ objectOrFn: BindingTypes.PROPS,
+ extract: BindingTypes.PROPS,
+ exclude: BindingTypes.PROPS,
+ union: BindingTypes.PROPS,
+ literalUnion: BindingTypes.PROPS,
+ literalUnionNumber: BindingTypes.PROPS,
+ literalUnionMixed: BindingTypes.PROPS,
+ intersection: BindingTypes.PROPS,
+ intersection2: BindingTypes.PROPS,
+ foo: BindingTypes.PROPS,
+ uppercase: BindingTypes.PROPS,
+ params: BindingTypes.PROPS,
+ nonNull: BindingTypes.PROPS,
+ unknown: BindingTypes.PROPS,
+ unknownUnion: BindingTypes.PROPS,
+ unknownIntersection: BindingTypes.PROPS,
+ unknownUnionWithBoolean: BindingTypes.PROPS,
+ unknownUnionWithFunction: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ interface', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ extends interface', () => {
+ const { content, bindings } = compile(`
+
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`z: { type: Number, required: true }`)
+ expect(content).toMatch(`y: { type: String, required: true }`)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ y: BindingTypes.PROPS,
+ z: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ extends intersection type', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`z: { type: Number, required: true }`)
+ expect(content).toMatch(`y: { type: String, required: true }`)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ y: BindingTypes.PROPS,
+ z: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ intersection type', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`y: { type: String, required: true }`)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ y: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ exported interface', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ exported interface in normal script', () => {
+ const { content, bindings } = compile(`
+
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ type alias', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ exported type alias', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`x: { type: Number, required: false }`)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.PROPS,
+ })
+ })
+
+ test('w/ TS assertion', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ expect(content).toMatch(`props: ['foo']`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ })
+ })
+
+ test('withDefaults (static)', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(
+ `foo: { type: String, required: false, default: 'hi' }`,
+ )
+ expect(content).toMatch(`bar: { type: Number, required: false }`)
+ expect(content).toMatch(`baz: { type: Boolean, required: true }`)
+ expect(content).toMatch(
+ `qux: { type: Function, required: false, default() { return 1 } }`,
+ )
+ expect(content).toMatch(
+ `quux: { type: Function, required: false, default() { } }`,
+ )
+ expect(content).toMatch(
+ `quuxx: { type: Promise, required: false, async default() { return await Promise.resolve('hi') } }`,
+ )
+ expect(content).toMatch(
+ `fred: { type: String, required: false, get default() { return 'fred' } }`,
+ )
+ expect(content).toMatch(`const props = __props`)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS,
+ baz: BindingTypes.PROPS,
+ qux: BindingTypes.PROPS,
+ quux: BindingTypes.PROPS,
+ quuxx: BindingTypes.PROPS,
+ fred: BindingTypes.PROPS,
+ props: BindingTypes.SETUP_CONST,
+ })
+ })
+
+ test('withDefaults (static) + normal script', () => {
+ const { content } = compile(`
+
+
+ `)
+ assertCode(content)
+ })
+
+ // #7111
+ test('withDefaults (static) w/ production mode', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch(`const props = __props`)
+
+ // foo has no default value, the Function can be dropped
+ expect(content).toMatch(`foo: {}`)
+ expect(content).toMatch(`bar: { type: Boolean }`)
+ expect(content).toMatch(`baz: { type: [Boolean, Function], default: true }`)
+ expect(content).toMatch(`qux: { default: 'hi' }`)
+ })
+
+ test('withDefaults (dynamic)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+ expect(content).toMatch(
+ `
+ _mergeDefaults({
+ foo: { type: String, required: false },
+ bar: { type: Number, required: false },
+ baz: { type: Boolean, required: true }
+ }, { ...defaults })`.trim(),
+ )
+ })
+
+ test('withDefaults (reference)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+ expect(content).toMatch(
+ `
+ _mergeDefaults({
+ foo: { type: String, required: false },
+ bar: { type: Number, required: false },
+ baz: { type: Boolean, required: true }
+ }, defaults)`.trim(),
+ )
+ })
+
+ // #7111
+ test('withDefaults (dynamic) w/ production mode', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+ expect(content).toMatch(
+ `
+ _mergeDefaults({
+ foo: { type: Function },
+ bar: { type: Boolean },
+ baz: { type: [Boolean, Function] },
+ qux: {}
+ }, { ...defaults })`.trim(),
+ )
+ })
+
+ test('withDefaults w/ dynamic object method', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+ expect(content).toMatch(
+ `
+ _mergeDefaults({
+ foo: { type: Function, required: false }
+ }, {
+ ['fo' + 'o']() { return 'foo' }
+ })`.trim(),
+ )
+ })
+
+ test('runtime inference for Enum', () => {
+ expect(
+ compile(
+ ``,
+ { hoistStatic: true },
+ ).content,
+ ).toMatch(`foo: { type: Number`)
+
+ expect(
+ compile(
+ ``,
+ { hoistStatic: true },
+ ).content,
+ ).toMatch(`foo: { type: String`)
+
+ expect(
+ compile(
+ ``,
+ { hoistStatic: true },
+ ).content,
+ ).toMatch(`foo: { type: [String, Number]`)
+
+ expect(
+ compile(
+ ``,
+ { hoistStatic: true },
+ ).content,
+ ).toMatch(`foo: { type: Number`)
+ })
+
+ // #8148
+ test('should not override local bindings', () => {
+ const { bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ bar: BindingTypes.SETUP_REF,
+ computed: BindingTypes.SETUP_CONST,
+ })
+ })
+
+ // #8289
+ test('destructure without enabling reactive destructure', () => {
+ const { content, bindings } = compile(
+ ``,
+ {
+ propsDestructure: false,
+ },
+ )
+ expect(content).toMatch(`const { foo } = __props`)
+ expect(content).toMatch(`return { foo }`)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.SETUP_CONST,
+ })
+ assertCode(content)
+ })
+
+ test('prohibiting reactive destructure', () => {
+ expect(() =>
+ compile(
+ ``,
+ {
+ propsDestructure: 'error',
+ },
+ ),
+ ).toThrow()
+ })
+
+ describe('errors', () => {
+ test('w/ both type and non-type args', () => {
+ expect(() => {
+ compile(``)
+ }).toThrow(`cannot accept both type and non-type arguments`)
+ })
+ })
+
+ test('should escape names w/ special symbols', () => {
+ const { content, bindings } = compile(`
+ `)
+ assertCode(content)
+ expect(content).toMatch(`"spa ce": { type: null, required: true }`)
+ expect(content).toMatch(
+ `"exclamation!mark": { type: null, required: true }`,
+ )
+ expect(content).toMatch(`"double\\"quote": { type: null, required: true }`)
+ expect(content).toMatch(`"hash#tag": { type: null, required: true }`)
+ expect(content).toMatch(`"dollar$sign": { type: null, required: true }`)
+ expect(content).toMatch(`"percentage%sign": { type: null, required: true }`)
+ expect(content).toMatch(`"amper&sand": { type: null, required: true }`)
+ expect(content).toMatch(`"single'quote": { type: null, required: true }`)
+ expect(content).toMatch(`"round(brack)ets": { type: null, required: true }`)
+ expect(content).toMatch(`"aste*risk": { type: null, required: true }`)
+ expect(content).toMatch(`"pl+us": { type: null, required: true }`)
+ expect(content).toMatch(`"com,ma": { type: null, required: true }`)
+ expect(content).toMatch(`"do.t": { type: null, required: true }`)
+ expect(content).toMatch(`"sla/sh": { type: null, required: true }`)
+ expect(content).toMatch(`"co:lon": { type: null, required: true }`)
+ expect(content).toMatch(`"semi;colon": { type: null, required: true }`)
+ expect(content).toMatch(`"angleets": { type: null, required: true }`)
+ expect(content).toMatch(`"equal=sign": { type: null, required: true }`)
+ expect(content).toMatch(`"question?mark": { type: null, required: true }`)
+ expect(content).toMatch(`"at@sign": { type: null, required: true }`)
+ expect(content).toMatch(
+ `"square[brack]ets": { type: null, required: true }`,
+ )
+ expect(content).toMatch(`"back\\\\slash": { type: null, required: true }`)
+ expect(content).toMatch(`"ca^ret": { type: null, required: true }`)
+ expect(content).toMatch(`"back\`tick": { type: null, required: true }`)
+ expect(content).toMatch(`"curly{bra}ces": { type: null, required: true }`)
+ expect(content).toMatch(`"pi|pe": { type: null, required: true }`)
+ expect(content).toMatch(`"til~de": { type: null, required: true }`)
+ expect(content).toMatch(`"da-sh": { type: null, required: true }`)
+ expect(bindings).toStrictEqual({
+ 'spa ce': BindingTypes.PROPS,
+ 'exclamation!mark': BindingTypes.PROPS,
+ 'double"quote': BindingTypes.PROPS,
+ 'hash#tag': BindingTypes.PROPS,
+ dollar$sign: BindingTypes.PROPS,
+ 'percentage%sign': BindingTypes.PROPS,
+ 'amper&sand': BindingTypes.PROPS,
+ "single'quote": BindingTypes.PROPS,
+ 'round(brack)ets': BindingTypes.PROPS,
+ 'aste*risk': BindingTypes.PROPS,
+ 'pl+us': BindingTypes.PROPS,
+ 'com,ma': BindingTypes.PROPS,
+ 'do.t': BindingTypes.PROPS,
+ 'sla/sh': BindingTypes.PROPS,
+ 'co:lon': BindingTypes.PROPS,
+ 'semi;colon': BindingTypes.PROPS,
+ 'angleets': BindingTypes.PROPS,
+ 'equal=sign': BindingTypes.PROPS,
+ 'question?mark': BindingTypes.PROPS,
+ 'at@sign': BindingTypes.PROPS,
+ 'square[brack]ets': BindingTypes.PROPS,
+ 'back\\slash': BindingTypes.PROPS,
+ 'ca^ret': BindingTypes.PROPS,
+ 'back`tick': BindingTypes.PROPS,
+ 'curly{bra}ces': BindingTypes.PROPS,
+ 'pi|pe': BindingTypes.PROPS,
+ 'til~de': BindingTypes.PROPS,
+ 'da-sh': BindingTypes.PROPS,
+ })
+ })
+
+ // #8989
+ test('custom element retains the props type & production mode', () => {
+ const { content } = compile(
+ ``,
+ { isProd: true, customElement: filename => /\.ce\.vue$/.test(filename) },
+ { filename: 'app.ce.vue' },
+ )
+
+ expect(content).toMatch(`foo: {type: Number}`)
+ assertCode(content)
+ })
+
+ test('custom element retains the props type & default value & production mode', () => {
+ const { content } = compile(
+ ``,
+ { isProd: true, customElement: filename => /\.ce\.vue$/.test(filename) },
+ { filename: 'app.ce.vue' },
+ )
+ expect(content).toMatch(`foo: { default: 5.5, type: Number }`)
+ assertCode(content)
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
new file mode 100644
index 00000000000..25dd817bbe5
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
@@ -0,0 +1,532 @@
+import { BindingTypes } from '@vue/compiler-core'
+import type { SFCScriptCompileOptions } from '../../src'
+import { assertCode, compileSFCScript } from '../utils'
+
+describe('sfc reactive props destructure', () => {
+ function compile(src: string, options?: Partial) {
+ return compileSFCScript(src, {
+ inlineTemplate: true,
+ ...options,
+ })
+ }
+
+ test('basic usage', () => {
+ const { content, bindings } = compile(`
+
+ {{ foo }}
+ `)
+ expect(content).not.toMatch(`const { foo } =`)
+ expect(content).toMatch(`console.log(__props.foo)`)
+ expect(content).toMatch(`_toDisplayString(__props.foo)`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ })
+ })
+
+ test('multiple variable declarations', () => {
+ const { content, bindings } = compile(`
+
+ {{ foo }} {{ hello }} {{ bar }}
+ `)
+ expect(content).not.toMatch(`const { foo } =`)
+ expect(content).toMatch(`const bar = 'fish', hello = 'world'`)
+ expect(content).toMatch(`_toDisplayString(hello)`)
+ expect(content).toMatch(`_toDisplayString(bar)`)
+ expect(content).toMatch(`_toDisplayString(__props.foo)`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.LITERAL_CONST,
+ hello: BindingTypes.LITERAL_CONST,
+ })
+ })
+
+ test('nested scope', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ expect(content).not.toMatch(`const { foo, bar } =`)
+ expect(content).toMatch(`console.log(foo)`)
+ expect(content).toMatch(`console.log(__props.bar)`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS,
+ test: BindingTypes.SETUP_CONST,
+ })
+ })
+
+ test('default values w/ array runtime declaration', () => {
+ const { content } = compile(`
+
+ `)
+ // literals can be used as-is, non-literals are always returned from a
+ // function
+ // functions need to be marked with a skip marker
+ expect(content)
+ .toMatch(`props: /*@__PURE__*/_mergeDefaults(['foo', 'bar', 'baz'], {
+ foo: 1,
+ bar: () => ({}),
+ func: () => {}, __skip_func: true
+})`)
+ assertCode(content)
+ })
+
+ test('default values w/ object runtime declaration', () => {
+ const { content } = compile(`
+
+ `)
+ // literals can be used as-is, non-literals are always returned from a
+ // function
+ // functions need to be marked with a skip marker since we cannot always
+ // safely infer whether runtime type is Function (e.g. if the runtime decl
+ // is imported, or spreads another object)
+ expect(content)
+ .toMatch(`props: /*@__PURE__*/_mergeDefaults({ foo: Number, bar: Object, func: Function, ext: null }, {
+ foo: 1,
+ bar: () => ({}),
+ func: () => {}, __skip_func: true,
+ ext: x, __skip_ext: true
+})`)
+ assertCode(content)
+ })
+ test('default values w/ runtime declaration & key is string', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ __propsAliases: {
+ fooBar: 'foo:bar',
+ },
+ foo: BindingTypes.PROPS,
+ 'foo:bar': BindingTypes.PROPS,
+ fooBar: BindingTypes.PROPS_ALIASED,
+ })
+
+ expect(content).toMatch(`
+ props: /*@__PURE__*/_mergeDefaults(['foo', 'foo:bar'], {
+ foo: 1,
+ "foo:bar": 'foo-bar'
+}),`)
+ assertCode(content)
+ })
+
+ test('default values w/ type declaration', () => {
+ const { content } = compile(`
+
+ `)
+ // literals can be used as-is, non-literals are always returned from a
+ // function
+ expect(content).toMatch(`props: {
+ foo: { type: Number, required: false, default: 1 },
+ bar: { type: Object, required: false, default: () => ({}) },
+ func: { type: Function, required: false, default: () => {} }
+ }`)
+ assertCode(content)
+ })
+
+ test('default values w/ type declaration & key is string', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ __propsAliases: {
+ fooBar: 'foo:bar',
+ },
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS,
+ 'foo:bar': BindingTypes.PROPS,
+ fooBar: BindingTypes.PROPS_ALIASED,
+ 'onUpdate:modelValue': BindingTypes.PROPS,
+ })
+ expect(content).toMatch(`
+ props: {
+ foo: { type: Number, required: true, default: 1 },
+ bar: { type: Number, required: true, default: 2 },
+ "foo:bar": { type: String, required: true, default: 'foo-bar' },
+ "onUpdate:modelValue": { type: Function, required: true }
+ },`)
+ assertCode(content)
+ })
+
+ test('default values w/ type declaration, prod mode', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ // literals can be used as-is, non-literals are always returned from a
+ // function
+ expect(content).toMatch(`props: {
+ foo: { default: 1 },
+ bar: { default: () => ({}) },
+ baz: {},
+ boola: { type: Boolean },
+ boolb: { type: [Boolean, Number] },
+ func: { type: Function, default: () => {} }
+ }`)
+ })
+
+ test('with TSInstantiationExpression', () => {
+ const { content } = compile(
+ `
+
+ `,
+ { isProd: true },
+ )
+ assertCode(content)
+ expect(content).toMatch(`const foo = __props.value<123>`)
+ })
+
+ test('aliasing', () => {
+ const { content, bindings } = compile(`
+
+ {{ foo + bar }}
+ `)
+ expect(content).not.toMatch(`const { foo: bar } =`)
+ expect(content).toMatch(`let x = foo`) // should not process
+ expect(content).toMatch(`let y = __props.foo`)
+ // should convert bar to __props.foo in template expressions
+ expect(content).toMatch(`_toDisplayString(__props.foo + __props.foo)`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.SETUP_LET,
+ y: BindingTypes.SETUP_LET,
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS_ALIASED,
+ __propsAliases: {
+ bar: 'foo',
+ },
+ })
+ })
+
+ // #5425
+ test('non-identifier prop names', () => {
+ const { content, bindings } = compile(`
+
+ {{ fooBar }}
+ `)
+ expect(content).toMatch(`x = __props["foo.bar"]`)
+ expect(content).toMatch(`toDisplayString(__props["foo.bar"])`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ x: BindingTypes.SETUP_LET,
+ 'foo.bar': BindingTypes.PROPS,
+ fooBar: BindingTypes.PROPS_ALIASED,
+ __propsAliases: {
+ fooBar: 'foo.bar',
+ },
+ })
+ })
+
+ test('rest spread', () => {
+ const { content, bindings } = compile(`
+
+ `)
+ expect(content).toMatch(
+ `const rest = _createPropsRestProxy(__props, ["foo","bar"])`,
+ )
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS,
+ baz: BindingTypes.PROPS,
+ rest: BindingTypes.SETUP_REACTIVE_CONST,
+ })
+ })
+
+ test('rest spread non-inline', () => {
+ const { content, bindings } = compile(
+ `
+
+ {{ rest.bar }}
+ `,
+ { inlineTemplate: false },
+ )
+ expect(content).toMatch(
+ `const rest = _createPropsRestProxy(__props, ["foo"])`,
+ )
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ bar: BindingTypes.PROPS,
+ rest: BindingTypes.SETUP_REACTIVE_CONST,
+ })
+ })
+
+ // #6960
+ test('computed static key', () => {
+ const { content, bindings } = compile(`
+
+ {{ foo }}
+ `)
+ expect(content).not.toMatch(`const { foo } =`)
+ expect(content).toMatch(`console.log(__props.foo)`)
+ expect(content).toMatch(`_toDisplayString(__props.foo)`)
+ assertCode(content)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ })
+ })
+
+ test('multi-variable declaration', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`const a = 1;`)
+ expect(content).toMatch(`props: ['item'],`)
+ })
+
+ // #6757
+ test('multi-variable declaration fix #6757 ', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`const a = 1;`)
+ expect(content).toMatch(`props: ['item'],`)
+ })
+
+ // #7422
+ test('multi-variable declaration fix #7422', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`const a = 0,`)
+ expect(content).toMatch(`b = 0;`)
+ expect(content).toMatch(`props: ['item'],`)
+ })
+
+ test('handle function parameters with same name as destructured props', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`console.log(__props.value)`)
+ })
+
+ test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`props: ['item'],`)
+ expect(content).toMatch(`emits: ['a'],`)
+ })
+
+ describe('errors', () => {
+ test('should error on deep destructure', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`destructure does not support nested patterns`)
+
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`destructure does not support nested patterns`)
+ })
+
+ test('should error on computed key', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`destructure cannot use computed key`)
+ })
+
+ test('should warn when used with withDefaults', () => {
+ compile(
+ ``,
+ )
+ expect(
+ `withDefaults() is unnecessary when using destructure`,
+ ).toHaveBeenWarned()
+ })
+
+ test('should error if destructure reference local vars', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`cannot reference locally declared variables`)
+ })
+
+ test('should error if assignment to destructured prop binding', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`Cannot assign to destructured props`)
+
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`Cannot assign to destructured props`)
+ })
+
+ test('should error when passing destructured prop into certain methods', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(
+ `"foo" is a destructured prop and should not be passed directly to watch().`,
+ )
+
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(
+ `"foo" is a destructured prop and should not be passed directly to watch().`,
+ )
+
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(
+ `"foo" is a destructured prop and should not be passed directly to toRef().`,
+ )
+
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(
+ `"foo" is a destructured prop and should not be passed directly to toRef().`,
+ )
+ })
+
+ // not comprehensive, but should help for most common cases
+ test('should error if default value type does not match declared type', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).toThrow(`Default value of prop "foo" does not match declared type.`)
+ })
+
+ // #8017
+ test('should not throw an error if the variable is not a props', () => {
+ expect(() =>
+ compile(
+ ``,
+ ),
+ ).not.toThrowError()
+ })
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineSlots.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineSlots.spec.ts
new file mode 100644
index 00000000000..357709afdf3
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/defineSlots.spec.ts
@@ -0,0 +1,40 @@
+import { assertCode, compileSFCScript as compile } from '../utils'
+
+describe('defineSlots()', () => {
+ test('basic usage', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`const slots = _useSlots()`)
+ expect(content).not.toMatch('defineSlots')
+ })
+
+ test('w/o return value', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).not.toMatch('defineSlots')
+ expect(content).not.toMatch(`_useSlots`)
+ })
+
+ test('w/o generic params', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`const slots = _useSlots()`)
+ expect(content).not.toMatch('defineSlots')
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/hoistStatic.spec.ts b/packages/compiler-sfc/__tests__/compileScript/hoistStatic.spec.ts
new file mode 100644
index 00000000000..ce6191777cc
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/hoistStatic.spec.ts
@@ -0,0 +1,219 @@
+import { BindingTypes } from '@vue/compiler-core'
+import type { SFCScriptCompileOptions } from '../../src'
+import { assertCode, compileSFCScript } from '../utils'
+
+describe('sfc hoist static', () => {
+ function compile(src: string, options?: Partial) {
+ return compileSFCScript(src, {
+ inlineTemplate: true,
+ hoistStatic: true,
+ ...options,
+ })
+ }
+
+ test('should hoist literal value', () => {
+ const code = `
+ const string = 'default value'
+ const number = 123
+ const boolean = false
+ const nil = null
+ const bigint = 100n
+ const template = \`str\`
+ `.trim()
+ const { content, bindings } = compile(`
+
+ `)
+
+ // should hoist to first line
+ expect(content.startsWith(code)).toBe(true)
+ expect(bindings).toStrictEqual({
+ string: BindingTypes.LITERAL_CONST,
+ number: BindingTypes.LITERAL_CONST,
+ boolean: BindingTypes.LITERAL_CONST,
+ nil: BindingTypes.LITERAL_CONST,
+ bigint: BindingTypes.LITERAL_CONST,
+ template: BindingTypes.LITERAL_CONST,
+ })
+ assertCode(content)
+ })
+
+ test('should hoist expressions', () => {
+ const code = `
+ const unary = !false
+ const binary = 1 + 2
+ const conditional = 1 ? 2 : 3
+ const sequence = (1, true, 'foo', 1)
+ `.trim()
+ const { content, bindings } = compile(`
+
+ `)
+ // should hoist to first line
+ expect(content.startsWith(code)).toBe(true)
+ expect(bindings).toStrictEqual({
+ binary: BindingTypes.LITERAL_CONST,
+ conditional: BindingTypes.LITERAL_CONST,
+ unary: BindingTypes.LITERAL_CONST,
+ sequence: BindingTypes.LITERAL_CONST,
+ })
+ assertCode(content)
+ })
+
+ test('should hoist w/ defineProps/Emits', () => {
+ const hoistCode = `const defaultValue = 'default value'`
+ const { content, bindings } = compile(`
+
+ `)
+
+ // should hoist to first line
+ expect(content.startsWith(hoistCode)).toBe(true)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.PROPS,
+ defaultValue: BindingTypes.LITERAL_CONST,
+ })
+ assertCode(content)
+ })
+
+ test('should not hoist a variable', () => {
+ const code = `
+ let KEY1 = 'default value'
+ var KEY2 = 123
+ const regex = /.*/g
+ const undef = undefined
+ `.trim()
+ const { content, bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ KEY1: BindingTypes.SETUP_LET,
+ KEY2: BindingTypes.SETUP_LET,
+ regex: BindingTypes.SETUP_CONST,
+ undef: BindingTypes.SETUP_MAYBE_REF,
+ })
+ expect(content).toMatch(`setup(__props) {\n\n ${code}`)
+ assertCode(content)
+ })
+
+ test('should not hoist a constant initialized to a reference value', () => {
+ const code = `
+ const KEY1 = Boolean
+ const KEY2 = [Boolean]
+ const KEY3 = [getCurrentInstance()]
+ let i = 0;
+ const KEY4 = (i++, 'foo')
+ enum KEY5 {
+ FOO = 1,
+ BAR = getCurrentInstance(),
+ }
+ const KEY6 = \`template\${i}\`
+ `.trim()
+ const { content, bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ KEY1: BindingTypes.SETUP_MAYBE_REF,
+ KEY2: BindingTypes.SETUP_CONST,
+ KEY3: BindingTypes.SETUP_CONST,
+ KEY4: BindingTypes.SETUP_CONST,
+ KEY5: BindingTypes.SETUP_CONST,
+ KEY6: BindingTypes.SETUP_CONST,
+ i: BindingTypes.SETUP_LET,
+ })
+ expect(content).toMatch(`setup(__props) {\n\n ${code}`)
+ assertCode(content)
+ })
+
+ test('should not hoist a object or array', () => {
+ const code = `
+ const obj = { foo: 'bar' }
+ const arr = [1, 2, 3]
+ `.trim()
+ const { content, bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ arr: BindingTypes.SETUP_CONST,
+ obj: BindingTypes.SETUP_CONST,
+ })
+ expect(content).toMatch(`setup(__props) {\n\n ${code}`)
+ assertCode(content)
+ })
+
+ test('should not hoist a function or class', () => {
+ const code = `
+ const fn = () => {}
+ function fn2() {}
+ class Foo {}
+ `.trim()
+ const { content, bindings } = compile(`
+
+ `)
+ expect(bindings).toStrictEqual({
+ Foo: BindingTypes.SETUP_CONST,
+ fn: BindingTypes.SETUP_CONST,
+ fn2: BindingTypes.SETUP_CONST,
+ })
+ expect(content).toMatch(`setup(__props) {\n\n ${code}`)
+ assertCode(content)
+ })
+
+ test('should enable when only script setup', () => {
+ const { content, bindings } = compile(`
+
+
+ `)
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.SETUP_CONST,
+ })
+ assertCode(content)
+ })
+
+ test('should not hoist when disabled', () => {
+ const { content, bindings } = compile(
+ `
+
+ `,
+ { hoistStatic: false },
+ )
+ expect(bindings).toStrictEqual({
+ foo: BindingTypes.SETUP_CONST,
+ })
+ assertCode(content)
+ })
+
+ test('template binding access in inline mode', () => {
+ const { content } = compile(
+ `
+
+ {{ foo }}
+ `,
+ )
+ expect(content).toMatch('_toDisplayString(foo)')
+ })
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts b/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts
new file mode 100644
index 00000000000..210fa09688a
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts
@@ -0,0 +1,267 @@
+import { assertCode, compileSFCScript as compile } from '../utils'
+
+// in dev mode, declared bindings are returned as an object from setup()
+// when using TS, users may import types which should not be returned as
+// values, so we need to check import usage in the template to determine
+// what to be returned.
+
+test('components', () => {
+ const { content } = compile(`
+
+
+
+
+
+ FooBar
+
+ `)
+ // FooBar: should not be matched by plain text or incorrect case
+ // FooBaz: used as PascalCase component
+ // FooQux: used as kebab-case component
+ // foo: lowercase component
+ expect(content).toMatch(
+ `return { fooBar, get FooBaz() { return FooBaz }, ` +
+ `get FooQux() { return FooQux }, get foo() { return foo } }`,
+ )
+ assertCode(content)
+})
+
+test('directive', () => {
+ const { content } = compile(`
+
+
+
+
+ `)
+ expect(content).toMatch(`return { get vMyDir() { return vMyDir } }`)
+ assertCode(content)
+})
+
+test('dynamic arguments', () => {
+ const { content } = compile(`
+
+
+
+
+
+
+
+
+
+ `)
+ expect(content).toMatch(
+ `return { get FooBar() { return FooBar }, get foo() { return foo }, ` +
+ `get bar() { return bar }, get baz() { return baz }, get msg() { return msg } }`,
+ )
+ assertCode(content)
+})
+
+// https://github.com/vuejs/core/issues/4599
+test('attribute expressions', () => {
+ const { content } = compile(`
+
+
+
+
+ `)
+ expect(content).toMatch(
+ `return { cond, get bar() { return bar }, get baz() { return baz } }`,
+ )
+ assertCode(content)
+})
+
+test('vue interpolations', () => {
+ const { content } = compile(`
+
+
+ {{ x }} {{ yy }} {{ x$y }}
+
+ `)
+ // x: used in interpolation
+ // y: should not be matched by {{ yy }} or 'y' in binding exps
+ // x$y: #4274 should escape special chars when creating Regex
+ expect(content).toMatch(
+ `return { get x() { return x }, get z() { return z }, get x$y() { return x$y } }`,
+ )
+ assertCode(content)
+})
+
+// #4340 interpolations in template strings
+test('js template string interpolations', () => {
+ const { content } = compile(`
+
+
+ {{ \`\${VAR}VAR2\${VAR3}\` }}
+
+ `)
+ // VAR2 should not be matched
+ expect(content).toMatch(
+ `return { get VAR() { return VAR }, get VAR3() { return VAR3 } }`,
+ )
+ assertCode(content)
+})
+
+// edge case: last tag in template
+test('last tag', () => {
+ const { content } = compile(`
+
+
+
+
+
+ `)
+ expect(content).toMatch(
+ `return { get FooBaz() { return FooBaz }, get Last() { return Last } }`,
+ )
+ assertCode(content)
+})
+
+test('TS annotations', () => {
+ const { content } = compile(`
+
+
+ {{ a as Foo }}
+ {{ b() }}
+ {{ Baz }}
+ {{ data }}
+
+
+ `)
+ expect(content).toMatch(`return { a, b, get Baz() { return Baz } }`)
+ assertCode(content)
+})
+
+// vuejs/vue#12591
+test('v-on inline statement', () => {
+ // should not error
+ compile(`
+
+
+
+
+ `)
+})
+
+test('template ref', () => {
+ const { content } = compile(`
+
+
+
+
+
+
+ `)
+ expect(content).toMatch(
+ 'return { get foo() { return foo }, get bar() { return bar }, get Baz() { return Baz } }',
+ )
+ assertCode(content)
+})
+
+// https://github.com/nuxt/nuxt/issues/22416
+test('property access', () => {
+ const { content } = compile(`
+
+
+ {{ Foo.Bar.Baz }}
+
+ `)
+ expect(content).toMatch('return { get Foo() { return Foo } }')
+ assertCode(content)
+})
+
+test('spread operator', () => {
+ const { content } = compile(`
+
+
+
+
+ `)
+ expect(content).toMatch('return { get Foo() { return Foo } }')
+ assertCode(content)
+})
+
+test('property access (whitespace)', () => {
+ const { content } = compile(`
+
+
+ {{ Foo . Bar . Baz }}
+
+ `)
+ expect(content).toMatch('return { get Foo() { return Foo } }')
+ assertCode(content)
+})
+
+// #9974
+test('namespace / dot component usage', () => {
+ const { content } = compile(`
+
+
+
+
+ `)
+ expect(content).toMatch('return { get Foo() { return Foo } }')
+ assertCode(content)
+})
+
+test('check when has explicit parse options', () => {
+ const { content } = compile(
+ `
+
+
+ {{ x }}
+
+ `,
+ undefined,
+ { templateParseOptions: {} },
+ )
+ expect(content).toMatch('return { get x() { return x } }')
+})
+
+// #11745
+test('shorthand binding w/ kebab-case', () => {
+ const { content } = compile(
+ `
+
+
+
+
+ `,
+ )
+ expect(content).toMatch('return { get fooBar() { return fooBar }')
+})
diff --git a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
new file mode 100644
index 00000000000..c6a2f9c38dd
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
@@ -0,0 +1,1566 @@
+import { normalize } from 'node:path'
+import type { Identifier } from '@babel/types'
+import { type SFCScriptCompileOptions, parse } from '../../src'
+import { ScriptCompileContext } from '../../src/script/context'
+import {
+ inferRuntimeType,
+ invalidateTypeCache,
+ recordImports,
+ registerTS,
+ resolveTypeElements,
+} from '../../src/script/resolveType'
+import { UNKNOWN_TYPE } from '../../src/script/utils'
+import ts from 'typescript'
+
+registerTS(() => ts)
+
+describe('resolveType', () => {
+ test('type literal', () => {
+ const { props, calls } = resolve(`defineProps<{
+ foo: number // property
+ bar(): void // method
+ 'baz': string // string literal key
+ (e: 'foo'): void // call signature
+ (e: 'bar'): void
+ }>()`)
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['Function'],
+ baz: ['String'],
+ })
+ expect(calls?.length).toBe(2)
+ })
+
+ test('reference type', () => {
+ expect(
+ resolve(`
+ type Aliased = { foo: number }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ test('reference exported type', () => {
+ expect(
+ resolve(`
+ export type Aliased = { foo: number }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ test('reference interface', () => {
+ expect(
+ resolve(`
+ interface Aliased { foo: number }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ test('reference exported interface', () => {
+ expect(
+ resolve(`
+ export interface Aliased { foo: number }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ test('reference interface extends', () => {
+ expect(
+ resolve(`
+ export interface A { a(): void }
+ export interface B extends A { b: boolean }
+ interface C { c: string }
+ interface Aliased extends B, C { foo: number }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ a: ['Function'],
+ b: ['Boolean'],
+ c: ['String'],
+ foo: ['Number'],
+ })
+ })
+
+ test('reference class', () => {
+ expect(
+ resolve(`
+ class Foo {}
+ defineProps<{ foo: Foo }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Object'],
+ })
+ })
+
+ test('function type', () => {
+ expect(
+ resolve(`
+ defineProps<(e: 'foo') => void>()
+ `).calls?.length,
+ ).toBe(1)
+ })
+
+ test('reference function type', () => {
+ expect(
+ resolve(`
+ type Fn = (e: 'foo') => void
+ defineProps()
+ `).calls?.length,
+ ).toBe(1)
+ })
+
+ test('intersection type', () => {
+ expect(
+ resolve(`
+ type Foo = { foo: number }
+ type Bar = { bar: string }
+ type Baz = { bar: string | boolean }
+ defineProps<{ self: any } & Foo & Bar & Baz>()
+ `).props,
+ ).toStrictEqual({
+ self: [UNKNOWN_TYPE],
+ foo: ['Number'],
+ // both Bar & Baz has 'bar', but Baz['bar] is wider so it should be
+ // preferred
+ bar: ['String', 'Boolean'],
+ })
+ })
+
+ test('intersection type with ignore', () => {
+ expect(
+ resolve(`
+ type Foo = { foo: number }
+ type Bar = { bar: string }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ // #7553
+ test('union type', () => {
+ expect(
+ resolve(`
+ interface CommonProps {
+ size?: 'xl' | 'l' | 'm' | 's' | 'xs'
+ }
+
+ type ConditionalProps =
+ | {
+ color: 'normal' | 'primary' | 'secondary'
+ appearance: 'normal' | 'outline' | 'text'
+ }
+ | {
+ color: number
+ appearance: 'outline'
+ note: string
+ }
+
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ size: ['String'],
+ color: ['String', 'Number'],
+ appearance: ['String'],
+ note: ['String'],
+ })
+ })
+
+ test('template string type', () => {
+ expect(
+ resolve(`
+ type T = 'foo' | 'bar'
+ type S = 'x' | 'y'
+ defineProps<{
+ [\`_\${T}_\${S}_\`]: string
+ }>()
+ `).props,
+ ).toStrictEqual({
+ _foo_x_: ['String'],
+ _foo_y_: ['String'],
+ _bar_x_: ['String'],
+ _bar_y_: ['String'],
+ })
+ })
+
+ test('mapped types w/ string manipulation', () => {
+ expect(
+ resolve(`
+ type T = 'foo' | 'bar'
+ defineProps<{ [K in T]: string | number } & {
+ [K in 'optional']?: boolean
+ } & {
+ [K in Capitalize]: string
+ } & {
+ [K in Uppercase>]: string
+ } & {
+ [K in \`x\${T}\`]: string
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String', 'Number'],
+ bar: ['String', 'Number'],
+ Foo: ['String'],
+ Bar: ['String'],
+ FOO: ['String'],
+ xfoo: ['String'],
+ xbar: ['String'],
+ optional: ['Boolean'],
+ })
+ })
+
+ test('utility type: Partial', () => {
+ expect(
+ resolve(`
+ type T = { foo: number, bar: string }
+ defineProps>()
+ `).raw.props,
+ ).toMatchObject({
+ foo: {
+ optional: true,
+ },
+ bar: {
+ optional: true,
+ },
+ })
+ })
+
+ test('utility type: Required', () => {
+ expect(
+ resolve(`
+ type T = { foo?: number, bar?: string }
+ defineProps>()
+ `).raw.props,
+ ).toMatchObject({
+ foo: {
+ optional: false,
+ },
+ bar: {
+ optional: false,
+ },
+ })
+ })
+
+ test('utility type: Pick', () => {
+ expect(
+ resolve(`
+ type T = { foo: number, bar: string, baz: boolean }
+ type K = 'foo' | 'bar'
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ })
+
+ test('utility type: Omit', () => {
+ expect(
+ resolve(`
+ type T = { foo: number, bar: string, baz: boolean }
+ type K = 'foo' | 'bar'
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ baz: ['Boolean'],
+ })
+ })
+
+ test('utility type: mapped type with Omit and Pick', () => {
+ expect(
+ resolve(`
+ type Optional = Omit & Partial>
+ interface Test {
+ foo: string;
+ bar?: string;
+ }
+ type OptionalTest = Optional
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ bar: ['String'],
+ })
+ })
+
+ test('utility type: ReadonlyArray', () => {
+ expect(
+ resolve(`
+ defineProps<{ foo: ReadonlyArray }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Array'],
+ })
+ })
+
+ test('utility type: ReadonlyMap & Readonly Set', () => {
+ expect(
+ resolve(`
+ defineProps<{ foo: ReadonlyMap, bar: ReadonlySet }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Map'],
+ bar: ['Set'],
+ })
+ })
+
+ test('indexed access type (literal)', () => {
+ expect(
+ resolve(`
+ type T = { bar: number }
+ type S = { nested: { foo: T['bar'] }}
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ test('indexed access type (advanced)', () => {
+ expect(
+ resolve(`
+ type K = 'foo' | 'bar'
+ type T = { foo: string, bar: number }
+ type S = { foo: { foo: T[string] }, bar: { bar: string } }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String', 'Number'],
+ bar: ['String'],
+ })
+ })
+
+ test('indexed access type (number)', () => {
+ expect(
+ resolve(`
+ type A = (string | number)[]
+ type AA = Array
+ type T = [1, 'foo']
+ type TT = [foo: 1, bar: 'foo']
+ defineProps<{ foo: A[number], bar: AA[number], tuple: T[number], namedTuple: TT[number] }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String', 'Number'],
+ bar: ['String'],
+ tuple: ['Number', 'String'],
+ namedTuple: ['Number', 'String'],
+ })
+ })
+
+ test('namespace', () => {
+ expect(
+ resolve(`
+ type X = string
+ namespace Foo {
+ type X = number
+ export namespace Bar {
+ export type A = {
+ foo: X
+ }
+ }
+ }
+ defineProps()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number'],
+ })
+ })
+
+ test('interface merging', () => {
+ expect(
+ resolve(`
+ interface Foo {
+ a: string
+ }
+ interface Foo {
+ b: number
+ }
+ defineProps<{
+ foo: Foo['a'],
+ bar: Foo['b']
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ })
+ })
+
+ test('namespace merging', () => {
+ expect(
+ resolve(`
+ namespace Foo {
+ export type A = string
+ }
+ namespace Foo {
+ export type B = number
+ }
+ defineProps<{
+ foo: Foo.A,
+ bar: Foo.B
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ })
+ })
+
+ test('namespace merging with other types', () => {
+ expect(
+ resolve(`
+ namespace Foo {
+ export type A = string
+ }
+ interface Foo {
+ b: number
+ }
+ defineProps<{
+ foo: Foo.A,
+ bar: Foo['b']
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ })
+ })
+
+ test('enum merging', () => {
+ expect(
+ resolve(`
+ enum Foo {
+ A = 1
+ }
+ enum Foo {
+ B = 'hi'
+ }
+ defineProps<{
+ foo: Foo
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Number', 'String'],
+ })
+ })
+
+ test('typeof', () => {
+ expect(
+ resolve(`
+ declare const a: string
+ defineProps<{ foo: typeof a }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+
+ test('readonly', () => {
+ expect(
+ resolve(`
+ defineProps<{ foo: readonly unknown[] }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Array'],
+ })
+ })
+
+ test('keyof', () => {
+ const files = {
+ '/foo.ts': `export type IMP = { ${1}: 1 };`,
+ }
+
+ const { props } = resolve(
+ `
+ import { IMP } from './foo'
+ interface Foo { foo: 1, ${1}: 1 }
+ type Bar = { bar: 1 }
+ declare const obj: Bar
+ declare const set: Set
+ declare const arr: Array
+
+ defineProps<{
+ imp: keyof IMP,
+ foo: keyof Foo,
+ bar: keyof Bar,
+ obj: keyof typeof obj,
+ set: keyof typeof set,
+ arr: keyof typeof arr
+ }>()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ imp: ['Number'],
+ foo: ['String', 'Number'],
+ bar: ['String'],
+ obj: ['String'],
+ set: ['String'],
+ arr: ['String', 'Number'],
+ })
+ })
+
+ test('keyof: index signature', () => {
+ const { props } = resolve(
+ `
+ declare const num: number;
+ interface Foo {
+ [key: symbol]: 1
+ [key: string]: 1
+ [key: typeof num]: 1,
+ }
+
+ type Test = T
+ type Bar = {
+ [key: string]: 1
+ [key: Test]: 1
+ }
+
+ defineProps<{
+ foo: keyof Foo
+ bar: keyof Bar
+ }>()
+ `,
+ )
+
+ expect(props).toStrictEqual({
+ foo: ['Symbol', 'String', 'Number'],
+ bar: [UNKNOWN_TYPE],
+ })
+ })
+
+ // #11129
+ test('keyof: intersection type', () => {
+ const { props } = resolve(`
+ type A = { name: string }
+ type B = A & { [key: number]: string }
+ defineProps<{
+ foo: keyof B
+ }>()`)
+ expect(props).toStrictEqual({
+ foo: ['String', 'Number'],
+ })
+ })
+
+ test('keyof: union type', () => {
+ const { props } = resolve(`
+ type A = { name: string }
+ type B = A | { [key: number]: string }
+ defineProps<{
+ foo: keyof B
+ }>()`)
+ expect(props).toStrictEqual({
+ foo: ['String', 'Number'],
+ })
+ })
+
+ test('keyof: utility type', () => {
+ const { props } = resolve(
+ `
+ type Foo = Record
+ type Bar = { [key: string]: any }
+ type AnyRecord = Record
+ type Baz = { a: 1, ${1}: 2, b: 3}
+
+ defineProps<{
+ record: keyof Foo,
+ anyRecord: keyof AnyRecord
+ partial: keyof Partial,
+ required: keyof Required,
+ readonly: keyof Readonly,
+ pick: keyof Pick
+ extract: keyof Extract
+ }>()
+ `,
+ )
+
+ expect(props).toStrictEqual({
+ record: ['Symbol', 'String'],
+ anyRecord: ['String', 'Number', 'Symbol'],
+ partial: ['String'],
+ required: ['String'],
+ readonly: ['String'],
+ pick: ['String', 'Number'],
+ extract: ['String', 'Number'],
+ })
+ })
+
+ test('keyof: fallback to Unknown', () => {
+ const { props } = resolve(
+ `
+ interface Barr {}
+ interface Bar extends Barr {}
+ type Foo = keyof Bar
+ defineProps<{ foo: Foo }>()
+ `,
+ )
+
+ expect(props).toStrictEqual({
+ foo: [UNKNOWN_TYPE],
+ })
+ })
+
+ test('keyof: nested object with number', () => {
+ const { props } = resolve(
+ `
+ interface Type {
+ deep: {
+ 1: any
+ }
+ }
+
+ defineProps<{
+ route: keyof Type['deep']
+ }>()`,
+ )
+
+ expect(props).toStrictEqual({
+ route: ['Number'],
+ })
+ })
+
+ test('keyof: nested object with string', () => {
+ const { props } = resolve(
+ `
+ interface Type {
+ deep: {
+ foo: any
+ }
+ }
+
+ defineProps<{
+ route: keyof Type['deep']
+ }>()`,
+ )
+
+ expect(props).toStrictEqual({
+ route: ['String'],
+ })
+ })
+
+ test('keyof: nested object with intermediate', () => {
+ const { props } = resolve(
+ `
+ interface Type {
+ deep: {
+ foo: any
+ }
+ }
+
+ type Foo = Type['deep']
+
+ defineProps<{
+ route: keyof Foo
+ }>()`,
+ )
+
+ expect(props).toStrictEqual({
+ route: ['String'],
+ })
+ })
+
+ test('ExtractPropTypes (element-plus)', () => {
+ const { props, raw } = resolve(
+ `
+ import { ExtractPropTypes } from 'vue'
+ declare const props: {
+ foo: StringConstructor,
+ bar: {
+ type: import('foo').EpPropFinalized,
+ required: true
+ }
+ }
+ type Props = ExtractPropTypes
+ defineProps()
+ `,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ bar: ['Boolean'],
+ })
+ expect(raw.props.bar.optional).toBe(false)
+ })
+
+ test('ExtractPropTypes (antd)', () => {
+ const { props } = resolve(
+ `
+ declare const props: () => {
+ foo: StringConstructor,
+ bar: { type: PropType }
+ }
+ type Props = Partial>>
+ defineProps()
+ `,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ bar: ['Boolean'],
+ })
+ })
+
+ // #11266
+ test('correctly parse type annotation for declared function', () => {
+ const { props } = resolve(`
+ import { ExtractPropTypes } from 'vue'
+ interface UploadFile {
+ xhr?: T
+ }
+ declare function uploadProps(): {
+ fileList: {
+ type: PropType[]>
+ default: UploadFile[]
+ }
+ }
+ type UploadProps = ExtractPropTypes>
+ defineProps()`)
+ expect(props).toStrictEqual({
+ fileList: ['Array'],
+ })
+ })
+
+ describe('type alias declaration', () => {
+ // #13240
+ test('function type', () => {
+ expect(
+ resolve(`
+ type FunFoo = (item: O) => boolean;
+ type FunBar = FunFoo;
+ defineProps<{
+ foo?: FunFoo;
+ bar?: FunBar;
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['Function'],
+ bar: ['Function'],
+ })
+ })
+
+ test('fallback to Unknown', () => {
+ expect(
+ resolve(`
+ type Brand = T & {};
+ defineProps<{
+ foo: Brand;
+ }>()
+ `).props,
+ ).toStrictEqual({
+ foo: [UNKNOWN_TYPE],
+ })
+ })
+ })
+
+ describe('generics', () => {
+ test('generic with type literal', () => {
+ expect(
+ resolve(`
+ type Props = T
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+
+ test('generic used in intersection', () => {
+ expect(
+ resolve(`
+ type Foo = { foo: string; }
+ type Bar = { bar: number; }
+ type Props = T & U & { baz: boolean }
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ baz: ['Boolean'],
+ })
+ })
+
+ test('generic type /w generic type alias', () => {
+ expect(
+ resolve(`
+ type Aliased = Readonly>
+ type Props = Aliased
+ type Foo = { foo: string; }
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+
+ test('generic type /w aliased type literal', () => {
+ expect(
+ resolve(`
+ type Aliased = { foo: T }
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+
+ test('generic type /w interface', () => {
+ expect(
+ resolve(`
+ interface Props {
+ foo: T
+ }
+ type Foo = string
+ defineProps>()
+ `).props,
+ ).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+
+ test('generic from external-file', () => {
+ const files = {
+ '/foo.ts': 'export type P = { foo: T }',
+ }
+ const { props } = resolve(
+ `
+ import { P } from './foo'
+ defineProps>()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+ })
+
+ describe('external type imports', () => {
+ test('relative ts', () => {
+ const files = {
+ '/foo.ts': 'export type P = { foo: number }',
+ '/bar.d.ts':
+ 'type X = { bar: string }; export { X as Y };' +
+ // verify that we can parse syntax that is only valid in d.ts
+ 'export const baz: boolean',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo'
+ import { Y as PP } from './bar'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ // #10635
+ test('relative tsx', () => {
+ const files = {
+ '/foo.tsx': 'export type P = { foo: number }',
+ '/bar/index.tsx': 'export type PP = { bar: string }',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo'
+ import { PP } from './bar'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test.runIf(process.platform === 'win32')('relative ts on Windows', () => {
+ const files = {
+ 'C:\\Test\\FolderA\\foo.ts': 'export type P = { foo: number }',
+ 'C:\\Test\\FolderA\\bar.d.ts':
+ 'type X = { bar: string }; export { X as Y };' +
+ // verify that we can parse syntax that is only valid in d.ts
+ 'export const baz: boolean',
+ 'C:\\Test\\FolderB\\buz.ts': 'export type Z = { buz: string }',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo'
+ import { Y as PP } from './bar'
+ import { Z as PPP } from '../FolderB/buz'
+ defineProps
()
+ `,
+ files,
+ {},
+ 'C:\\Test\\FolderA\\Test.vue',
+ )
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ buz: ['String'],
+ })
+ expect(deps && [...deps].map(normalize)).toStrictEqual(
+ Object.keys(files).map(normalize),
+ )
+ })
+
+ // #8244
+ test('utility type in external file', () => {
+ const files = {
+ '/foo.ts': 'type A = { n?: number }; export type B = Required',
+ }
+ const { props } = resolve(
+ `
+ import { B } from './foo'
+ defineProps()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ n: ['Number'],
+ })
+ })
+
+ test('relative vue', () => {
+ const files = {
+ '/foo.vue':
+ '',
+ '/bar.vue':
+ '',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo.vue'
+ import { P as PP } from './bar.vue'
+ defineProps ()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('relative (chained)', () => {
+ const files = {
+ '/foo.ts': `import type { P as PP } from './nested/bar.vue'
+ export type P = { foo: number } & PP`,
+ '/nested/bar.vue':
+ '',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('relative (chained, re-export)', () => {
+ const files = {
+ '/foo.ts': `export { P as PP } from './bar'`,
+ '/bar.ts': 'export type P = { bar: string }',
+ }
+ const { props, deps } = resolve(
+ `
+ import { PP as P } from './foo'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('relative (chained, export *)', () => {
+ const files = {
+ '/foo.ts': `export * from './bar'`,
+ '/bar.ts': 'export type P = { bar: string }',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('relative (default export)', () => {
+ const files = {
+ '/foo.ts': `export default interface P { foo: string }`,
+ '/bar.ts': `type X = { bar: string }; export default X`,
+ }
+ const { props, deps } = resolve(
+ `
+ import P from './foo'
+ import X from './bar'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('relative (default re-export)', () => {
+ const files = {
+ '/bar.ts': `export { default } from './foo'`,
+ '/foo.ts': `export default interface P { foo: string }; export interface PP { bar: number }`,
+ '/baz.ts': `export { PP as default } from './foo'`,
+ }
+ const { props, deps } = resolve(
+ `
+ import P from './bar'
+ import PP from './baz'
+ defineProps
()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('relative (re-export /w same source type name)', () => {
+ const files = {
+ '/foo.ts': `export default interface P { foo: string }`,
+ '/bar.ts': `export default interface PP { bar: number }`,
+ '/baz.ts': `export { default as X } from './foo'; export { default as XX } from './bar'; `,
+ }
+ const { props, deps } = resolve(
+ `import { X, XX } from './baz'
+ defineProps()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ })
+ expect(deps && [...deps]).toStrictEqual(['/baz.ts', '/foo.ts', '/bar.ts'])
+ })
+
+ test('relative (dynamic import)', () => {
+ const files = {
+ '/foo.ts': `export type P = { foo: string, bar: import('./bar').N }`,
+ '/bar.ts': 'export type N = number',
+ }
+ const { props, deps } = resolve(
+ `
+ defineProps()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ bar: ['Number'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ // #8339
+ test('relative, .js import', () => {
+ const files = {
+ '/foo.d.ts':
+ 'import { PP } from "./bar.js"; export type P = { foo: PP }',
+ '/bar.d.ts': 'export type PP = "foo" | "bar"',
+ }
+ const { props, deps } = resolve(
+ `
+ import { P } from './foo'
+ defineProps()
+ `,
+ files,
+ )
+ expect(props).toStrictEqual({
+ foo: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('ts module resolve', () => {
+ const files = {
+ '/node_modules/foo/package.json': JSON.stringify({
+ types: 'index.d.ts',
+ }),
+ '/node_modules/foo/index.d.ts': 'export type P = { foo: number }',
+ '/tsconfig.json': JSON.stringify({
+ compilerOptions: {
+ paths: {
+ bar: ['./pp.ts'],
+ },
+ },
+ }),
+ '/pp.ts': 'export type PP = { bar: string }',
+ }
+
+ const { props, deps } = resolve(
+ `
+ import { P } from 'foo'
+ import { PP } from 'bar'
+ defineProps
()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual([
+ '/node_modules/foo/index.d.ts',
+ '/pp.ts',
+ ])
+ })
+
+ test('ts module resolve w/ project reference & extends', () => {
+ const files = {
+ '/tsconfig.json': JSON.stringify({
+ references: [
+ {
+ path: './tsconfig.app.json',
+ },
+ ],
+ }),
+ '/tsconfig.app.json': JSON.stringify({
+ include: ['**/*.ts', '**/*.vue'],
+ extends: './tsconfig.web.json',
+ }),
+ '/tsconfig.web.json': JSON.stringify({
+ compilerOptions: {
+ composite: true,
+ paths: {
+ bar: ['./user.ts'],
+ },
+ },
+ }),
+ '/user.ts': 'export type User = { bar: string }',
+ }
+
+ const { props, deps } = resolve(
+ `
+ import { User } from 'bar'
+ defineProps()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(['/user.ts'])
+ })
+
+ test('ts module resolve w/ project reference folder', () => {
+ const files = {
+ '/tsconfig.json': JSON.stringify({
+ references: [
+ {
+ path: './web',
+ },
+ {
+ path: './empty',
+ },
+ {
+ path: './noexists-should-ignore',
+ },
+ ],
+ }),
+ '/web/tsconfig.json': JSON.stringify({
+ include: ['../**/*.ts', '../**/*.vue'],
+ compilerOptions: {
+ composite: true,
+ paths: {
+ bar: ['../user.ts'],
+ },
+ },
+ }),
+ // tsconfig with no include / paths defined, should match nothing
+ '/empty/tsconfig.json': JSON.stringify({
+ compilerOptions: {
+ composite: true,
+ },
+ }),
+ '/user.ts': 'export type User = { bar: string }',
+ }
+
+ const { props, deps } = resolve(
+ `
+ import { User } from 'bar'
+ defineProps()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(['/user.ts'])
+ })
+
+ // #11382
+ test('ts module resolve circular project reference', () => {
+ const files = {
+ '/tsconfig.json': JSON.stringify({
+ exclude: ['**/*.ts', '**/*.vue'],
+ references: [
+ {
+ path: './tsconfig.web.json',
+ },
+ ],
+ }),
+ '/tsconfig.web.json': JSON.stringify({
+ include: ['**/*.ts', '**/*.vue'],
+ compilerOptions: {
+ composite: true,
+ paths: {
+ user: ['./user.ts'],
+ },
+ },
+ references: [
+ {
+ // circular reference
+ path: './tsconfig.json',
+ },
+ ],
+ }),
+ '/user.ts': 'export type User = { bar: string }',
+ }
+
+ const { props, deps } = resolve(
+ `
+ import { User } from 'user'
+ defineProps()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(['/user.ts'])
+ })
+
+ test('ts module resolve w/ path aliased vue file', () => {
+ const files = {
+ '/tsconfig.json': JSON.stringify({
+ compilerOptions: {
+ include: ['**/*.ts', '**/*.vue'],
+ paths: {
+ '@/*': ['./src/*'],
+ },
+ },
+ }),
+ '/src/Foo.vue':
+ '',
+ }
+
+ const { props, deps } = resolve(
+ `
+ import { P } from '@/Foo.vue'
+ defineProps()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(['/src/Foo.vue'])
+ })
+
+ test('global types', () => {
+ const files = {
+ // ambient
+ '/app.d.ts':
+ 'declare namespace App { interface User { name: string } }',
+ // module - should only respect the declare global block
+ '/global.d.ts': `
+ declare type PP = { bar: number }
+ declare global {
+ type PP = { bar: string }
+ }
+ export {}
+ `,
+ }
+
+ const { props, deps } = resolve(`defineProps()`, files, {
+ globalTypeFiles: Object.keys(files),
+ })
+
+ expect(props).toStrictEqual({
+ name: ['String'],
+ bar: ['String'],
+ })
+ expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+ })
+
+ test('global types with ambient references', () => {
+ const files = {
+ // with references
+ '/backend.d.ts': `
+ declare namespace App.Data {
+ export type AircraftData = {
+ id: string
+ manufacturer: App.Data.Listings.ManufacturerData
+ }
+ }
+ declare namespace App.Data.Listings {
+ export type ManufacturerData = {
+ id: string
+ }
+ }
+ `,
+ }
+
+ const { props } = resolve(`defineProps()`, files, {
+ globalTypeFiles: Object.keys(files),
+ })
+
+ expect(props).toStrictEqual({
+ id: ['String'],
+ manufacturer: ['Object'],
+ })
+ })
+
+ // #9871
+ test('shared generics with different args', () => {
+ const files = {
+ '/foo.ts': `export interface Foo { value: T }`,
+ }
+ const { props } = resolve(
+ `import type { Foo } from './foo'
+ defineProps>()`,
+ files,
+ undefined,
+ `/One.vue`,
+ )
+ expect(props).toStrictEqual({
+ value: ['String'],
+ })
+ const { props: props2 } = resolve(
+ `import type { Foo } from './foo'
+ defineProps>()`,
+ files,
+ undefined,
+ `/Two.vue`,
+ false /* do not invalidate cache */,
+ )
+ expect(props2).toStrictEqual({
+ value: ['Number'],
+ })
+ })
+ })
+
+ describe('errors', () => {
+ test('failed type reference', () => {
+ expect(() => resolve(`defineProps()`)).toThrow(
+ `Unresolvable type reference`,
+ )
+ })
+
+ test('unsupported computed keys', () => {
+ expect(() => resolve(`defineProps<{ [Foo]: string }>()`)).toThrow(
+ `Unsupported computed key in type referenced by a macro`,
+ )
+ })
+
+ test('unsupported index type', () => {
+ expect(() => resolve(`defineProps()`)).toThrow(
+ `Unsupported type when resolving index type`,
+ )
+ })
+
+ test('failed import source resolve', () => {
+ expect(() =>
+ resolve(`import { X } from './foo'; defineProps()`),
+ ).toThrow(`Failed to resolve import source "./foo"`)
+ })
+
+ test('should not error on unresolved type when inferring runtime type', () => {
+ expect(() => resolve(`defineProps<{ foo: T }>()`)).not.toThrow()
+ expect(() => resolve(`defineProps<{ foo: T['bar'] }>()`)).not.toThrow()
+ expect(() =>
+ resolve(`
+ import type P from 'unknown'
+ defineProps<{ foo: P }>()
+ `),
+ ).not.toThrow()
+ })
+
+ test('error against failed extends', () => {
+ expect(() =>
+ resolve(`
+ import type Base from 'unknown'
+ interface Props extends Base {}
+ defineProps()
+ `),
+ ).toThrow(`@vue-ignore`)
+ })
+
+ test('allow ignoring failed extends', () => {
+ let res: any
+
+ expect(
+ () =>
+ (res = resolve(`
+ import type Base from 'unknown'
+ interface Props extends /*@vue-ignore*/ Base {
+ foo: string
+ }
+ defineProps()
+ `)),
+ ).not.toThrow(`@vue-ignore`)
+
+ expect(res.props).toStrictEqual({
+ foo: ['String'],
+ })
+ })
+ })
+
+ describe('template literals', () => {
+ test('mapped types with string type', () => {
+ expect(
+ resolve(`
+ type X = 'a' | 'b'
+ defineProps<{[K in X as \`\${K}_foo\`]: string}>()
+ `).props,
+ ).toStrictEqual({
+ a_foo: ['String'],
+ b_foo: ['String'],
+ })
+ })
+
+ // #10962
+ test('mapped types with generic parameters', () => {
+ const { props } = resolve(`
+ type Breakpoints = 'sm' | 'md' | 'lg'
+ type BreakpointFactory = {
+ [K in Breakpoints as \`\${T}\${Capitalize}\`]: V
+ }
+ type ColsBreakpoints = BreakpointFactory<'cols', number>
+ defineProps()
+ `)
+ expect(props).toStrictEqual({
+ colsSm: ['Number'],
+ colsMd: ['Number'],
+ colsLg: ['Number'],
+ })
+ })
+
+ test('allowArbitraryExtensions', () => {
+ const files = {
+ '/foo.d.vue.ts': 'export type Foo = number;',
+ '/foo.vue': '
',
+ '/bar.d.css.ts': 'export type Bar = string;',
+ '/bar.css': ':root { --color: red; }',
+ }
+
+ const { props } = resolve(
+ `
+ import { Foo } from './foo.vue'
+ import { Bar } from './bar.css'
+ defineProps<{ foo: Foo; bar: Bar }>()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ })
+ })
+})
+
+function resolve(
+ code: string,
+ files: Record = {},
+ options?: Partial,
+ sourceFileName: string = '/Test.vue',
+ invalidateCache = true,
+) {
+ const { descriptor } = parse(``, {
+ filename: sourceFileName,
+ })
+ const ctx = new ScriptCompileContext(descriptor, {
+ id: 'test',
+ fs: {
+ fileExists(file) {
+ return !!(files[file] ?? files[normalize(file)])
+ },
+ readFile(file) {
+ return files[file] ?? files[normalize(file)]
+ },
+ },
+ ...options,
+ })
+
+ if (invalidateCache) {
+ for (const file in files) {
+ invalidateTypeCache(file)
+ }
+ }
+
+ // ctx.userImports is collected when calling compileScript(), but we are
+ // skipping that here, so need to manually register imports
+ ctx.userImports = recordImports(ctx.scriptSetupAst!.body) as any
+
+ let target: any
+ for (const s of ctx.scriptSetupAst!.body) {
+ if (
+ s.type === 'ExpressionStatement' &&
+ s.expression.type === 'CallExpression' &&
+ (s.expression.callee as Identifier).name === 'defineProps'
+ ) {
+ target = s.expression.typeParameters!.params[0]
+ }
+ }
+ const raw = resolveTypeElements(ctx, target)
+ const props: Record = {}
+ for (const key in raw.props) {
+ props[key] = inferRuntimeType(ctx, raw.props[key])
+ }
+ return {
+ props,
+ calls: raw.calls,
+ deps: ctx.deps,
+ raw,
+ }
+}
diff --git a/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts b/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts
deleted file mode 100644
index 6fcc0e59068..00000000000
--- a/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts
+++ /dev/null
@@ -1,262 +0,0 @@
-import { BindingTypes } from '@vue/compiler-core'
-import { SFCScriptCompileOptions } from '../src'
-import { compileSFCScript, assertCode } from './utils'
-
-describe('sfc props transform', () => {
- function compile(src: string, options?: Partial) {
- return compileSFCScript(src, {
- inlineTemplate: true,
- reactivityTransform: true,
- ...options
- })
- }
-
- test('basic usage', () => {
- const { content, bindings } = compile(`
-
- {{ foo }}
- `)
- expect(content).not.toMatch(`const { foo } =`)
- expect(content).toMatch(`console.log(__props.foo)`)
- expect(content).toMatch(`_toDisplayString(__props.foo)`)
- assertCode(content)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.PROPS
- })
- })
-
- test('nested scope', () => {
- const { content, bindings } = compile(`
-
- `)
- expect(content).not.toMatch(`const { foo, bar } =`)
- expect(content).toMatch(`console.log(foo)`)
- expect(content).toMatch(`console.log(__props.bar)`)
- assertCode(content)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.PROPS,
- bar: BindingTypes.PROPS,
- test: BindingTypes.SETUP_CONST
- })
- })
-
- test('default values w/ runtime declaration', () => {
- const { content } = compile(`
-
- `)
- // literals can be used as-is, non-literals are always returned from a
- // function
- expect(content).toMatch(`props: _mergeDefaults(['foo', 'bar'], {
- foo: 1,
- bar: () => ({})
-})`)
- assertCode(content)
- })
-
- test('default values w/ type declaration', () => {
- const { content } = compile(`
-
- `)
- // literals can be used as-is, non-literals are always returned from a
- // function
- expect(content).toMatch(`props: {
- foo: { type: Number, required: false, default: 1 },
- bar: { type: Object, required: false, default: () => ({}) }
- }`)
- assertCode(content)
- })
-
- test('default values w/ type declaration, prod mode', () => {
- const { content } = compile(
- `
-
- `,
- { isProd: true }
- )
- // literals can be used as-is, non-literals are always returned from a
- // function
- expect(content).toMatch(`props: {
- foo: { default: 1 },
- bar: { default: () => ({}) },
- baz: null,
- boola: { type: Boolean },
- boolb: { type: [Boolean, Number] },
- func: { type: Function, default: () => (() => {}) }
- }`)
- assertCode(content)
- })
-
- test('aliasing', () => {
- const { content, bindings } = compile(`
-
- {{ foo + bar }}
- `)
- expect(content).not.toMatch(`const { foo: bar } =`)
- expect(content).toMatch(`let x = foo`) // should not process
- expect(content).toMatch(`let y = __props.foo`)
- // should convert bar to __props.foo in template expressions
- expect(content).toMatch(`_toDisplayString(__props.foo + __props.foo)`)
- assertCode(content)
- expect(bindings).toStrictEqual({
- x: BindingTypes.SETUP_LET,
- y: BindingTypes.SETUP_LET,
- foo: BindingTypes.PROPS,
- bar: BindingTypes.PROPS_ALIASED,
- __propsAliases: {
- bar: 'foo'
- }
- })
- })
-
- // #5425
- test('non-identifier prop names', () => {
- const { content, bindings } = compile(`
-
- {{ fooBar }}
- `)
- expect(content).toMatch(`x = __props["foo.bar"]`)
- expect(content).toMatch(`toDisplayString(__props["foo.bar"])`)
- assertCode(content)
- expect(bindings).toStrictEqual({
- x: BindingTypes.SETUP_LET,
- 'foo.bar': BindingTypes.PROPS,
- fooBar: BindingTypes.PROPS_ALIASED,
- __propsAliases: {
- fooBar: 'foo.bar'
- }
- })
- })
-
- test('rest spread', () => {
- const { content, bindings } = compile(`
-
- `)
- expect(content).toMatch(
- `const rest = _createPropsRestProxy(__props, ["foo","bar"])`
- )
- assertCode(content)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.PROPS,
- bar: BindingTypes.PROPS,
- baz: BindingTypes.PROPS,
- rest: BindingTypes.SETUP_REACTIVE_CONST
- })
- })
-
- test('$$() escape', () => {
- const { content } = compile(`
-
- `)
- expect(content).toMatch(`const __props_foo = _toRef(__props, 'foo')`)
- expect(content).toMatch(`const __props_bar = _toRef(__props, 'bar')`)
- expect(content).toMatch(`console.log((__props_foo))`)
- expect(content).toMatch(`console.log((__props_bar))`)
- expect(content).toMatch(`({ foo: __props_foo, baz: __props_bar })`)
- assertCode(content)
- })
-
- // #6960
- test('computed static key', () => {
- const { content, bindings } = compile(`
-
- {{ foo }}
- `)
- expect(content).not.toMatch(`const { foo } =`)
- expect(content).toMatch(`console.log(__props.foo)`)
- expect(content).toMatch(`_toDisplayString(__props.foo)`)
- assertCode(content)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.PROPS
- })
- })
-
- describe('errors', () => {
- test('should error on deep destructure', () => {
- expect(() =>
- compile(
- ``
- )
- ).toThrow(`destructure does not support nested patterns`)
-
- expect(() =>
- compile(
- ``
- )
- ).toThrow(`destructure does not support nested patterns`)
- })
-
- test('should error on computed key', () => {
- expect(() =>
- compile(
- ``
- )
- ).toThrow(`destructure cannot use computed key`)
- })
-
- test('should error when used with withDefaults', () => {
- expect(() =>
- compile(
- ``
- )
- ).toThrow(`withDefaults() is unnecessary when using destructure`)
- })
-
- test('should error if destructure reference local vars', () => {
- expect(() =>
- compile(
- ``
- )
- ).toThrow(`cannot reference locally declared variables`)
- })
-
- test('should error if assignment to constant variable', () => {
- expect(() =>
- compile(
- ``
- )
- ).toThrow(`Assignment to constant variable.`)
- })
- })
-})
diff --git a/packages/compiler-sfc/__tests__/compileScriptRefTransform.spec.ts b/packages/compiler-sfc/__tests__/compileScriptRefTransform.spec.ts
deleted file mode 100644
index 8ae5275661e..00000000000
--- a/packages/compiler-sfc/__tests__/compileScriptRefTransform.spec.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-import { BindingTypes } from '@vue/compiler-core'
-import { compileSFCScript as compile, assertCode } from './utils'
-
-// this file only tests integration with SFC - main test case for the ref
-// transform can be found in /packages/reactivity-transform/__tests__
-describe('sfc ref transform', () => {
- function compileWithReactivityTransform(src: string) {
- return compile(src, { reactivityTransform: true })
- }
-
- test('$ unwrapping', () => {
- const { content, bindings } = compileWithReactivityTransform(``)
- expect(content).not.toMatch(`$(ref())`)
- expect(content).not.toMatch(`$(ref(1))`)
- expect(content).not.toMatch(`$(shallowRef({`)
- expect(content).toMatch(`let foo = (ref())`)
- expect(content).toMatch(`let a = (ref(1))`)
- expect(content).toMatch(`
- let b = (shallowRef({
- count: 0
- }))
- `)
- // normal declarations left untouched
- expect(content).toMatch(`let c = () => {}`)
- expect(content).toMatch(`let d`)
- expect(content).toMatch(
- `return { foo, a, b, get c() { return c }, set c(v) { c = v }, ` +
- `get d() { return d }, set d(v) { d = v }, ref, shallowRef }`
- )
- assertCode(content)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.SETUP_REF,
- a: BindingTypes.SETUP_REF,
- b: BindingTypes.SETUP_REF,
- c: BindingTypes.SETUP_LET,
- d: BindingTypes.SETUP_LET,
- ref: BindingTypes.SETUP_CONST,
- shallowRef: BindingTypes.SETUP_CONST
- })
- })
-
- test('$ref & $shallowRef declarations', () => {
- const { content, bindings } = compileWithReactivityTransform(``)
- expect(content).toMatch(
- `import { ref as _ref, shallowRef as _shallowRef } from 'vue'`
- )
- expect(content).not.toMatch(`$ref()`)
- expect(content).not.toMatch(`$ref(1)`)
- expect(content).not.toMatch(`$shallowRef({`)
- expect(content).toMatch(`let foo = _ref()`)
- expect(content).toMatch(`let a = _ref(1)`)
- expect(content).toMatch(`
- let b = _shallowRef({
- count: 0
- })
- `)
- // normal declarations left untouched
- expect(content).toMatch(`let c = () => {}`)
- expect(content).toMatch(`let d`)
- assertCode(content)
- expect(bindings).toStrictEqual({
- foo: BindingTypes.SETUP_REF,
- a: BindingTypes.SETUP_REF,
- b: BindingTypes.SETUP_REF,
- c: BindingTypes.SETUP_LET,
- d: BindingTypes.SETUP_LET
- })
- })
-
- test('usage in normal `)
- expect(content).not.toMatch(`$ref(0)`)
- expect(content).toMatch(`import { ref as _ref } from 'vue'`)
- expect(content).toMatch(`let count = _ref(0)`)
- expect(content).toMatch(`count.value++`)
- expect(content).toMatch(`return ({ count })`)
- assertCode(content)
- })
-
- test('usage /w typescript', () => {
- const { content } = compileWithReactivityTransform(`
-
- `)
- expect(content).toMatch(`import { ref as _ref`)
- expect(content).toMatch(`let msg = _ref('foo')`)
- expect(content).toMatch(`let bar = _ref ('bar')`)
- assertCode(content)
- })
-
- test('usage with normal
- `)
- // should dedupe helper imports
- expect(content).toMatch(`import { ref as _ref } from 'vue'`)
-
- expect(content).toMatch(`let a = _ref(0)`)
- expect(content).toMatch(`let b = _ref(0)`)
-
- // root level ref binding declared in
-
- `)
- expect(content).toMatch(`console.log(data.value)`)
- assertCode(content)
- })
-
- describe('errors', () => {
- test('defineProps/Emit() referencing ref declarations', () => {
- expect(() =>
- compile(
- ``,
- { reactivityTransform: true }
- )
- ).toThrow(`cannot reference locally declared variables`)
-
- expect(() =>
- compile(
- ``,
- { reactivityTransform: true }
- )
- ).toThrow(`cannot reference locally declared variables`)
- })
- })
-})
diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts
index a343fe6b6fa..9b7e7c53710 100644
--- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts
@@ -1,24 +1,20 @@
-/**
- * @jest-environment node
- */
-
import {
+ type SFCStyleCompileOptions,
compileStyle,
compileStyleAsync,
- SFCStyleCompileOptions
} from '../src/compileStyle'
-import path from 'path'
+import path from 'node:path'
export function compileScoped(
source: string,
- options?: Partial
+ options?: Partial,
): string {
const res = compileStyle({
source,
filename: 'test.css',
id: 'data-v-test',
scoped: true,
- ...options
+ ...options,
})
if (res.errors.length) {
res.errors.forEach(err => {
@@ -32,34 +28,90 @@ export function compileScoped(
describe('SFC scoped CSS', () => {
test('simple selectors', () => {
expect(compileScoped(`h1 { color: red; }`)).toMatch(
- `h1[data-v-test] { color: red;`
+ `h1[data-v-test] { color: red;`,
)
expect(compileScoped(`.foo { color: red; }`)).toMatch(
- `.foo[data-v-test] { color: red;`
+ `.foo[data-v-test] { color: red;`,
)
})
test('descendent selector', () => {
expect(compileScoped(`h1 .foo { color: red; }`)).toMatch(
- `h1 .foo[data-v-test] { color: red;`
+ `h1 .foo[data-v-test] { color: red;`,
+ )
+
+ // #13387
+ expect(
+ compileScoped(`main {
+ width: 100%;
+ > * {
+ max-width: 200px;
+ }
+}`),
+ ).toMatchInlineSnapshot(`
+ "main {
+&[data-v-test] {
+ width: 100%;
+}
+> *[data-v-test] {
+ max-width: 200px;
+}
+}"`)
+ })
+
+ test('nesting selector', () => {
+ expect(compileScoped(`h1 { color: red; .foo { color: red; } }`)).toMatch(
+ `h1 {\n&[data-v-test] { color: red;\n}\n.foo[data-v-test] { color: red;`,
+ )
+ })
+
+ test('nesting selector with atrule and comment', () => {
+ expect(
+ compileScoped(
+ `h1 {
+color: red;
+/*background-color: pink;*/
+@media only screen and (max-width: 800px) {
+ background-color: green;
+ .bar { color: white }
+}
+.foo { color: red; }
+}`,
+ ),
+ ).toMatch(
+ `h1 {
+&[data-v-test] {
+color: red
+/*background-color: pink;*/
+}
+@media only screen and (max-width: 800px) {
+&[data-v-test] {
+ background-color: green
+}
+.bar[data-v-test] { color: white
+}
+}
+.foo[data-v-test] { color: red;
+}
+}`,
)
})
test('multiple selectors', () => {
expect(compileScoped(`h1 .foo, .bar, .baz { color: red; }`)).toMatch(
- `h1 .foo[data-v-test], .bar[data-v-test], .baz[data-v-test] { color: red;`
+ `h1 .foo[data-v-test], .bar[data-v-test], .baz[data-v-test] { color: red;`,
)
})
test('pseudo class', () => {
expect(compileScoped(`.foo:after { color: red; }`)).toMatch(
- `.foo[data-v-test]:after { color: red;`
+ `.foo[data-v-test]:after { color: red;`,
)
})
test('pseudo element', () => {
expect(compileScoped(`::selection { display: none; }`)).toMatch(
- '[data-v-test]::selection {'
+ '[data-v-test]::selection {',
)
})
@@ -89,6 +141,23 @@ describe('SFC scoped CSS', () => {
".baz .qux[data-v-test] .foo .bar { color: red;
}"
`)
+ expect(compileScoped(`:is(.foo :deep(.bar)) { color: red; }`))
+ .toMatchInlineSnapshot(`
+ ":is(.foo[data-v-test] .bar) { color: red;
+ }"
+ `)
+ expect(compileScoped(`:where(.foo :deep(.bar)) { color: red; }`))
+ .toMatchInlineSnapshot(`
+ ":where(.foo[data-v-test] .bar) { color: red;
+ }"
+ `)
+ expect(compileScoped(`:deep(.foo) { color: red; .bar { color: red; } }`))
+ .toMatchInlineSnapshot(`
+ "[data-v-test] .foo { color: red;
+ .bar { color: red;
+ }
+ }"
+ `)
})
test('::v-slotted', () => {
@@ -138,6 +207,66 @@ describe('SFC scoped CSS', () => {
`)
})
+ test(':is() and :where() with multiple selectors', () => {
+ expect(compileScoped(`:is(.foo) { color: red; }`)).toMatchInlineSnapshot(`
+ ":is(.foo[data-v-test]) { color: red;
+ }"
+ `)
+ expect(compileScoped(`:where(.foo, .bar) { color: red; }`))
+ .toMatchInlineSnapshot(`
+ ":where(.foo[data-v-test], .bar[data-v-test]) { color: red;
+ }"
+ `)
+ expect(compileScoped(`:is(.foo, .bar) div { color: red; }`))
+ .toMatchInlineSnapshot(`
+ ":is(.foo, .bar) div[data-v-test] { color: red;
+ }"
+ `)
+ })
+
+ // #10511
+ test(':is() and :where() in compound selectors', () => {
+ expect(
+ compileScoped(`.div { color: red; } .div:where(:hover) { color: blue; }`),
+ ).toMatchInlineSnapshot(`
+ ".div[data-v-test] { color: red;
+ }
+ .div[data-v-test]:where(:hover) { color: blue;
+ }"
+ `)
+
+ expect(
+ compileScoped(`.div { color: red; } .div:is(:hover) { color: blue; }`),
+ ).toMatchInlineSnapshot(`
+ ".div[data-v-test] { color: red;
+ }
+ .div[data-v-test]:is(:hover) { color: blue;
+ }"
+ `)
+
+ expect(
+ compileScoped(
+ `.div { color: red; } .div:where(.foo:hover) { color: blue; }`,
+ ),
+ ).toMatchInlineSnapshot(`
+ ".div[data-v-test] { color: red;
+ }
+ .div[data-v-test]:where(.foo:hover) { color: blue;
+ }"
+ `)
+
+ expect(
+ compileScoped(
+ `.div { color: red; } .div:is(.foo:hover) { color: blue; }`,
+ ),
+ ).toMatchInlineSnapshot(`
+ ".div[data-v-test] { color: red;
+ }
+ .div[data-v-test]:is(.foo:hover) { color: blue;
+ }"
+ `)
+ })
+
test('media query', () => {
expect(compileScoped(`@media print { .foo { color: red }}`))
.toMatchInlineSnapshot(`
@@ -194,30 +323,30 @@ describe('SFC scoped CSS', () => {
to { opacity: 1; }
}
`,
- { id: 'data-v-test' }
+ { id: 'data-v-test' },
)
expect(style).toContain(
- `.anim[data-v-test] {\n animation: color-test 5s infinite, other 5s;`
+ `.anim[data-v-test] {\n animation: color-test 5s infinite, other 5s;`,
)
expect(style).toContain(
- `.anim-2[data-v-test] {\n animation-name: color-test`
+ `.anim-2[data-v-test] {\n animation-name: color-test`,
)
expect(style).toContain(
- `.anim-3[data-v-test] {\n animation: 5s color-test infinite, 5s other;`
+ `.anim-3[data-v-test] {\n animation: 5s color-test infinite, 5s other;`,
)
expect(style).toContain(`@keyframes color-test {`)
expect(style).toContain(`@-webkit-keyframes color-test {`)
expect(style).toContain(
- `.anim-multiple[data-v-test] {\n animation: color-test 5s infinite,opacity-test 2s;`
+ `.anim-multiple[data-v-test] {\n animation: color-test 5s infinite,opacity-test 2s;`,
)
expect(style).toContain(
- `.anim-multiple-2[data-v-test] {\n animation-name: color-test,opacity-test;`
+ `.anim-multiple-2[data-v-test] {\n animation-name: color-test,opacity-test;`,
)
expect(style).toContain(`@keyframes opacity-test {\nfrom { opacity: 0;`)
expect(style).toContain(
- `@-webkit-keyframes opacity-test {\nfrom { opacity: 0;`
+ `@-webkit-keyframes opacity-test {\nfrom { opacity: 0;`,
)
})
@@ -242,7 +371,7 @@ describe('SFC scoped CSS', () => {
}"
`)
expect(
- `::v-deep usage as a combinator has been deprecated.`
+ `::v-deep usage as a combinator has been deprecated.`,
).toHaveBeenWarned()
})
@@ -253,7 +382,7 @@ describe('SFC scoped CSS', () => {
}"
`)
expect(
- `the >>> and /deep/ combinators have been deprecated.`
+ `the >>> and /deep/ combinators have been deprecated.`,
).toHaveBeenWarned()
})
@@ -264,7 +393,7 @@ describe('SFC scoped CSS', () => {
}"
`)
expect(
- `the >>> and /deep/ combinators have been deprecated.`
+ `the >>> and /deep/ combinators have been deprecated.`,
).toHaveBeenWarned()
})
})
@@ -276,7 +405,7 @@ describe('SFC CSS modules', () => {
source: `.red { color: red }\n.green { color: green }\n:global(.blue) { color: blue }`,
filename: `test.css`,
id: 'test',
- modules: true
+ modules: true,
})
expect(result.modules).toBeDefined()
expect(result.modules!.red).toMatch('_red_')
@@ -293,8 +422,8 @@ describe('SFC CSS modules', () => {
modulesOptions: {
scopeBehaviour: 'global',
generateScopedName: `[name]__[local]__[hash:base64:5]`,
- localsConvention: 'camelCaseOnly'
- }
+ localsConvention: 'camelCaseOnly',
+ },
})
expect(result.modules).toBeDefined()
expect(result.modules!.fooBar).toMatch('__foo-bar__')
@@ -310,11 +439,11 @@ describe('SFC style preprocessors', () => {
`,
filename: path.resolve(__dirname, './fixture/test.scss'),
id: '',
- preprocessLang: 'scss'
+ preprocessLang: 'scss',
})
expect([...res.dependencies]).toStrictEqual([
- path.join(__dirname, './fixture/import.scss')
+ path.join(__dirname, './fixture/import.scss'),
])
})
@@ -325,7 +454,7 @@ describe('SFC style preprocessors', () => {
@mixin square($size) {
width: $size;
height: $size;
- }`
+ }`,
},
source: `
.square {
@@ -334,7 +463,7 @@ describe('SFC style preprocessors', () => {
`,
filename: path.resolve(__dirname, './fixture/test.scss'),
id: '',
- preprocessLang: 'scss'
+ preprocessLang: 'scss',
})
expect(res.errors.length).toBe(0)
@@ -357,14 +486,33 @@ describe('SFC style preprocessors', () => {
width: $size;
height: $size;
}`
- }
+ },
},
source,
filename,
id: '',
- preprocessLang: 'scss'
+ preprocessLang: 'scss',
})
expect(res.errors.length).toBe(0)
})
+
+ test('should mount scope on correct selector when have universal selector', () => {
+ expect(compileScoped(`* { color: red; }`)).toMatchInlineSnapshot(`
+ "[data-v-test] { color: red;
+ }"
+ `)
+ expect(compileScoped('* .foo { color: red; }')).toMatchInlineSnapshot(`
+ ".foo[data-v-test] { color: red;
+ }"
+ `)
+ expect(compileScoped(`*.foo { color: red; }`)).toMatchInlineSnapshot(`
+ ".foo[data-v-test] { color: red;
+ }"
+ `)
+ expect(compileScoped(`.foo * { color: red; }`)).toMatchInlineSnapshot(`
+ ".foo[data-v-test] * { color: red;
+ }"
+ `)
+ })
})
diff --git a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
index b471b67c9ca..81cf75a912d 100644
--- a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
@@ -1,13 +1,17 @@
+import { type RawSourceMap, SourceMapConsumer } from 'source-map-js'
+import { parse as babelParse } from '@babel/parser'
import {
+ type SFCTemplateCompileOptions,
compileTemplate,
- SFCTemplateCompileOptions
} from '../src/compileTemplate'
-import { parse, SFCTemplateBlock } from '../src/parse'
+import { type SFCTemplateBlock, parse } from '../src/parse'
+import { compileScript } from '../src'
+import { getPositionInCode } from './utils'
function compile(opts: Omit) {
return compileTemplate({
...opts,
- id: ''
+ id: '',
})
}
@@ -48,28 +52,55 @@ body
p Cool Pug example!
`,
- { filename: 'example.vue', sourceMap: true }
+ { filename: 'example.vue', sourceMap: true },
).descriptor.template as SFCTemplateBlock
const result = compile({
filename: 'example.vue',
source: template.content,
- preprocessLang: template.lang
+ preprocessLang: template.lang,
})
expect(result.errors.length).toBe(0)
})
+test('preprocess pug with indents and blank lines', () => {
+ const template = parse(
+ `
+
+ body
+ h1 The next line contains four spaces.
+
+ div.container
+ p The next line is empty.
+ p This is the last line.
+
+`,
+ { filename: 'example.vue', sourceMap: true },
+ ).descriptor.template as SFCTemplateBlock
+
+ const result = compile({
+ filename: 'example.vue',
+ source: template.content,
+ preprocessLang: template.lang,
+ })
+
+ expect(result.errors.length).toBe(0)
+ expect(result.source).toBe(
+ 'The next line contains four spaces. This is the last line.
',
+ )
+})
+
test('warn missing preprocessor', () => {
const template = parse(`hi \n`, {
filename: 'example.vue',
- sourceMap: true
+ sourceMap: true,
}).descriptor.template as SFCTemplateBlock
const result = compile({
filename: 'example.vue',
source: template.content,
- preprocessLang: template.lang
+ preprocessLang: template.lang,
})
expect(result.errors.length).toBe(1)
@@ -81,8 +112,8 @@ test('transform asset url options', () => {
const { code: code1 } = compile({
...input,
transformAssetUrls: {
- tags: { foo: ['bar'] }
- }
+ tags: { foo: ['bar'] },
+ },
})
expect(code1).toMatch(`import _imports_0 from 'baz'\n`)
@@ -90,15 +121,15 @@ test('transform asset url options', () => {
const { code: code2 } = compile({
...input,
transformAssetUrls: {
- foo: ['bar']
- }
+ foo: ['bar'],
+ },
})
expect(code2).toMatch(`import _imports_0 from 'baz'\n`)
// false option
const { code: code3 } = compile({
...input,
- transformAssetUrls: false
+ transformAssetUrls: false,
})
expect(code3).not.toMatch(`import _imports_0 from 'baz'\n`)
})
@@ -107,25 +138,223 @@ test('source map', () => {
const template = parse(
`
-
+
`,
- { filename: 'example.vue', sourceMap: true }
- ).descriptor.template as SFCTemplateBlock
+ { filename: 'example.vue', sourceMap: true },
+ ).descriptor.template!
- const result = compile({
+ const { code, map } = compile({
+ filename: 'example.vue',
+ source: template.content,
+ })
+
+ expect(map!.sources).toEqual([`example.vue`])
+ expect(map!.sourcesContent).toEqual([template.content])
+
+ const consumer = new SourceMapConsumer(map as RawSourceMap)
+ expect(
+ consumer.originalPositionFor(getPositionInCode(code, 'foobar')),
+ ).toMatchObject(getPositionInCode(template.content, `foobar`))
+})
+
+test('source map: v-if generated comment should not have original position', () => {
+ const template = parse(
+ `
+
+
+
+ `,
+ { filename: 'example.vue', sourceMap: true },
+ ).descriptor.template!
+
+ const { code, map } = compile({
filename: 'example.vue',
- source: template.content
+ source: template.content,
})
- expect(result.map).toMatchSnapshot()
+ expect(map!.sources).toEqual([`example.vue`])
+ expect(map!.sourcesContent).toEqual([template.content])
+
+ const consumer = new SourceMapConsumer(map as RawSourceMap)
+ const commentNode = code.match(/_createCommentVNode\("v-if", true\)/)
+ expect(commentNode).not.toBeNull()
+ const commentPosition = getPositionInCode(code, commentNode![0])
+ const originalPosition = consumer.originalPositionFor(commentPosition)
+ // the comment node should not be mapped to the original source
+ expect(originalPosition.column).toBeNull()
+ expect(originalPosition.line).toBeNull()
+ expect(originalPosition.source).toBeNull()
+})
+
+test('should work w/ AST from descriptor', () => {
+ const source = `
+
+
+
+ `
+ const template = parse(source, {
+ filename: 'example.vue',
+ sourceMap: true,
+ }).descriptor.template!
+
+ expect(template.ast!.source).toBe(source)
+
+ const { code, map } = compile({
+ filename: 'example.vue',
+ source: template.content,
+ ast: template.ast,
+ })
+
+ expect(map!.sources).toEqual([`example.vue`])
+ // when reusing AST from SFC parse for template compile,
+ // the source corresponds to the entire SFC
+ expect(map!.sourcesContent).toEqual([source])
+
+ const consumer = new SourceMapConsumer(map as RawSourceMap)
+ expect(
+ consumer.originalPositionFor(getPositionInCode(code, 'foobar')),
+ ).toMatchObject(getPositionInCode(source, `foobar`))
+
+ expect(code).toBe(
+ compile({
+ filename: 'example.vue',
+ source: template.content,
+ }).code,
+ )
+})
+
+test('should work w/ AST from descriptor in SSR mode', () => {
+ const source = `
+
+
+
+ `
+ const template = parse(source, {
+ filename: 'example.vue',
+ sourceMap: true,
+ }).descriptor.template!
+
+ expect(template.ast!.source).toBe(source)
+
+ const { code, map } = compile({
+ filename: 'example.vue',
+ source: '', // make sure it's actually using the AST instead of source
+ ast: template.ast,
+ ssr: true,
+ })
+
+ expect(map!.sources).toEqual([`example.vue`])
+ // when reusing AST from SFC parse for template compile,
+ // the source corresponds to the entire SFC
+ expect(map!.sourcesContent).toEqual([source])
+
+ const consumer = new SourceMapConsumer(map as RawSourceMap)
+ expect(
+ consumer.originalPositionFor(getPositionInCode(code, 'foobar')),
+ ).toMatchObject(getPositionInCode(source, `foobar`))
+
+ expect(code).toBe(
+ compile({
+ filename: 'example.vue',
+ source: template.content,
+ ssr: true,
+ }).code,
+ )
+})
+
+test('should not reuse AST if using custom compiler', () => {
+ const source = `
+
+
+
+ `
+ const template = parse(source, {
+ filename: 'example.vue',
+ sourceMap: true,
+ }).descriptor.template!
+
+ const { code } = compile({
+ filename: 'example.vue',
+ source: template.content,
+ ast: template.ast,
+ compiler: {
+ parse: () => null as any,
+ // @ts-expect-error
+ compile: input => ({ code: input }),
+ },
+ })
+
+ // what we really want to assert is that the `input` received by the custom
+ // compiler is the source string, not the AST.
+ expect(code).toBe(template.content)
+})
+
+test('should force re-parse on already transformed AST', () => {
+ const source = `
+
+
+
+ `
+ const template = parse(source, {
+ filename: 'example.vue',
+ sourceMap: true,
+ }).descriptor.template!
+
+ // force set to empty, if this is reused then it won't generate proper code
+ template.ast!.children = []
+ template.ast!.transformed = true
+
+ const { code } = compile({
+ filename: 'example.vue',
+ source: '',
+ ast: template.ast,
+ })
+
+ expect(code).toBe(
+ compile({
+ filename: 'example.vue',
+ source: template.content,
+ }).code,
+ )
+})
+
+test('should force re-parse with correct compiler in SSR mode', () => {
+ const source = `
+
+
+
+ `
+ const template = parse(source, {
+ filename: 'example.vue',
+ sourceMap: true,
+ }).descriptor.template!
+
+ // force set to empty, if this is reused then it won't generate proper code
+ template.ast!.children = []
+ template.ast!.transformed = true
+
+ const { code } = compile({
+ filename: 'example.vue',
+ source: '',
+ ast: template.ast,
+ ssr: true,
+ })
+
+ expect(code).toBe(
+ compile({
+ filename: 'example.vue',
+ source: template.content,
+ ssr: true,
+ }).code,
+ )
})
test('template errors', () => {
const result = compile({
filename: 'example.vue',
- source: `
`
+ source: `
`,
})
expect(result.errors).toMatchSnapshot()
})
@@ -137,20 +366,20 @@ test('preprocessor errors', () => {
div(class='class)
`,
- { filename: 'example.vue', sourceMap: true }
+ { filename: 'example.vue', sourceMap: true },
).descriptor.template as SFCTemplateBlock
const result = compile({
filename: 'example.vue',
source: template.content,
- preprocessLang: template.lang
+ preprocessLang: template.lang,
})
expect(result.errors.length).toBe(1)
const message = result.errors[0].toString()
expect(message).toMatch(`Error: example.vue:3:1`)
expect(message).toMatch(
- `The end of the string reached with no closing bracket ) found.`
+ `The end of the string reached with no closing bracket ) found.`,
)
})
@@ -164,7 +393,7 @@ test('should generate the correct imports expression', () => {
`,
- ssr: true
+ ssr: true,
})
expect(code).toMatch(`_ssrRenderAttr(\"src\", _imports_1)`)
expect(code).toMatch(`_createVNode(\"img\", { src: _imports_1 })`)
@@ -186,7 +415,7 @@ test('should not hoist srcset URLs in SSR mode', () => {
`,
- ssr: true
+ ssr: true,
})
expect(code).toMatchSnapshot()
})
@@ -199,3 +428,87 @@ test('dynamic v-on + static v-on should merged', () => {
expect(result.code).toMatchSnapshot()
})
+
+// #9853 regression found in Nuxt tests
+// walkIdentifiers can get called multiple times on the same node
+// due to #9729 calling it during SFC template usage check.
+// conditions needed:
+// 1. `
+
+ {{ list.map((t, index) => ({ t: t })) }}
+
+ `
+ const { descriptor } = parse(src)
+ // compileScript triggers importUsageCheck
+ compileScript(descriptor, { id: 'xxx' })
+ const { code } = compileTemplate({
+ id: 'xxx',
+ filename: 'test.vue',
+ ast: descriptor.template!.ast,
+ source: descriptor.template!.content,
+ })
+ expect(code).not.toMatch(`_ctx.t`)
+})
+
+test('prefixing edge case for reused AST ssr mode', () => {
+ const src = `
+
+
+
+
+
+
+ `
+ const { descriptor } = parse(src)
+ // compileScript triggers importUsageCheck
+ compileScript(descriptor, { id: 'xxx' })
+ expect(() =>
+ compileTemplate({
+ id: 'xxx',
+ filename: 'test.vue',
+ ast: descriptor.template!.ast,
+ source: descriptor.template!.content,
+ ssr: true,
+ }),
+ ).not.toThrowError()
+})
+
+// #10852
+test('non-identifier expression in legacy filter syntax', () => {
+ const src = `
+
+
+ Today is
+ {{ new Date() | formatDate }}
+
+
+ `
+
+ const { descriptor } = parse(src)
+ const compilationResult = compileTemplate({
+ id: 'xxx',
+ filename: 'test.vue',
+ ast: descriptor.template!.ast,
+ source: descriptor.template!.content,
+ ssr: false,
+ compilerOptions: {
+ compatConfig: {
+ MODE: 2,
+ },
+ },
+ })
+
+ expect(() => {
+ babelParse(compilationResult.code, { sourceType: 'module' })
+ }).not.toThrow()
+})
diff --git a/packages/compiler-sfc/__tests__/cssVars.spec.ts b/packages/compiler-sfc/__tests__/cssVars.spec.ts
index 6cccf40ece0..323c9c7a599 100644
--- a/packages/compiler-sfc/__tests__/cssVars.spec.ts
+++ b/packages/compiler-sfc/__tests__/cssVars.spec.ts
@@ -1,5 +1,5 @@
import { compileStyle, parse } from '../src'
-import { mockId, compileSFCScript, assertCode } from './utils'
+import { assertCode, compileSFCScript, mockId } from './utils'
describe('CSS vars injection', () => {
test('generating correct code for nested paths', () => {
@@ -8,7 +8,7 @@ describe('CSS vars injection', () => {
``
+ }`,
)
expect(content).toMatch(`_useCssVars(_ctx => ({
"${mockId}-color": (_ctx.color),
@@ -32,7 +32,7 @@ describe('CSS vars injection', () => {
div {
font-size: v-bind(size);
}
- `
+ `,
)
expect(content).toMatch(`_useCssVars(_ctx => ({
"${mockId}-size": (_ctx.size)
@@ -57,7 +57,7 @@ describe('CSS vars injection', () => {
font-size: v-bind(size);
border: v-bind(foo);
}
- `
+ `,
)
// should handle:
// 1. local const bindings
@@ -69,7 +69,7 @@ describe('CSS vars injection', () => {
"${mockId}-foo": (__props.foo)
})`)
expect(content).toMatch(
- `import { useCssVars as _useCssVars, unref as _unref } from 'vue'`
+ `import { useCssVars as _useCssVars, unref as _unref } from 'vue'`,
)
assertCode(content)
})
@@ -85,7 +85,7 @@ describe('CSS vars injection', () => {
font-family: v-bind(フォント);
}`,
filename: 'test.css',
- id: 'data-v-test'
+ id: 'data-v-test',
})
expect(code).toMatchInlineSnapshot(`
".foo {
@@ -106,7 +106,7 @@ describe('CSS vars injection', () => {
color: v-bind(color);
font-size: v-bind('font.size');
}`,
- { isProd: true }
+ { isProd: true },
)
expect(content).toMatch(`_useCssVars(_ctx => ({
"4003f1a6": (_ctx.color),
@@ -120,7 +120,7 @@ describe('CSS vars injection', () => {
}`,
filename: 'test.css',
id: mockId,
- isProd: true
+ isProd: true,
})
expect(code).toMatchInlineSnapshot(`
".foo {
@@ -135,8 +135,8 @@ describe('CSS vars injection', () => {
assertCode(
compileSFCScript(
`\n` +
- ``
- ).content
+ ``,
+ ).content,
)
})
@@ -144,8 +144,8 @@ describe('CSS vars injection', () => {
assertCode(
compileSFCScript(
`\n` +
- ``
- ).content
+ ``,
+ ).content,
)
})
@@ -155,8 +155,8 @@ describe('CSS vars injection', () => {
`\n` + ``
- ).content
+ \n` + ``,
+ ).content,
)
})
@@ -164,8 +164,8 @@ describe('CSS vars injection', () => {
assertCode(
compileSFCScript(
`\n` +
- ``
- ).content
+ ``,
+ ).content,
)
})
@@ -178,7 +178,7 @@ describe('CSS vars injection', () => {
div{ /* color: v-bind(color); */ width:20; }
div{ width: v-bind(width); }
/* comment */
- `
+ `,
)
expect(content).not.toMatch(`"${mockId}-color": (color)`)
@@ -198,7 +198,7 @@ describe('CSS vars injection', () => {
p {
color: v-bind(color);
}
- `
+ `,
)
// color should only be injected once, even if it is twice in style
expect(content).toMatch(`_useCssVars(_ctx => ({
@@ -229,7 +229,7 @@ describe('CSS vars injection', () => {
p {
color: v-bind(((a + b)) / (2 * a));
}
- `
+ `,
)
expect(content).toMatch(`_useCssVars(_ctx => ({
"${mockId}-foo": (_unref(foo)),
@@ -243,7 +243,7 @@ describe('CSS vars injection', () => {
// #6022
test('should be able to parse incomplete expressions', () => {
const {
- descriptor: { cssVars }
+ descriptor: { cssVars },
} = parse(
`
`
+ `,
)
expect(cssVars).toMatchObject([`count.toString(`, `xxx`])
})
+
+ // #7759
+ test('It should correctly parse the case where there is no space after the script tag', () => {
+ const { content } = compileSFCScript(
+ `
+ `,
+ )
+ expect(content).toMatch(
+ `export default {\n setup(__props, { expose: __expose }) {\n __expose();\n\n_useCssVars(_ctx => ({\n "xxxxxxxx-background": (_unref(background))\n}))`,
+ )
+ })
+
+ describe('skip codegen in SSR', () => {
+ test('script setup, inline', () => {
+ const { content } = compileSFCScript(
+ `\n` +
+ ``,
+ {
+ inlineTemplate: true,
+ templateOptions: {
+ ssr: true,
+ },
+ },
+ )
+ expect(content).not.toMatch(`_useCssVars`)
+ })
+
+ // #6926
+ test('script, non-inline', () => {
+ const { content } = compileSFCScript(
+ `\n` +
+ ``,
+ {
+ inlineTemplate: false,
+ templateOptions: {
+ ssr: true,
+ },
+ },
+ )
+ expect(content).not.toMatch(`_useCssVars`)
+ })
+
+ test('normal script', () => {
+ const { content } = compileSFCScript(
+ `\n` +
+ ``,
+ {
+ templateOptions: {
+ ssr: true,
+ },
+ },
+ )
+ expect(content).not.toMatch(`_useCssVars`)
+ })
+ })
})
})
diff --git a/packages/compiler-sfc/__tests__/parse.spec.ts b/packages/compiler-sfc/__tests__/parse.spec.ts
index 5f1db5e2499..265655e47ef 100644
--- a/packages/compiler-sfc/__tests__/parse.spec.ts
+++ b/packages/compiler-sfc/__tests__/parse.spec.ts
@@ -1,21 +1,72 @@
import { parse } from '../src'
-import { baseParse, baseCompile } from '@vue/compiler-core'
-import { SourceMapConsumer } from 'source-map'
+import {
+ ElementTypes,
+ NodeTypes,
+ baseCompile,
+ createRoot,
+} from '@vue/compiler-core'
+import { SourceMapConsumer } from 'source-map-js'
describe('compiler:sfc', () => {
describe('source map', () => {
test('style block', () => {
// Padding determines how many blank lines will there be before the style block
const padding = Math.round(Math.random() * 10)
- const style = parse(
- `${'\n'.repeat(padding)}\n`
- ).descriptor.styles[0]
+ const src =
+ `${'\n'.repeat(padding)}` +
+ `
- expect(style.map).not.toBeUndefined()
+
- const consumer = new SourceMapConsumer(style.map!)
+
+
+`
+ const {
+ descriptor: { styles },
+ } = parse(src)
+
+ expect(styles[0].map).not.toBeUndefined()
+ const consumer = new SourceMapConsumer(styles[0].map!)
+ const lineOffset =
+ src.slice(0, src.indexOf(`\n`.replace(
/./g,
- ' '
- ) + '\n{ "greeting": "hello" }\n'
+ ' ',
+ ) + '\n{ "greeting": "hello" }\n',
)
})
@@ -121,9 +192,8 @@ h1 { color: red }
end: {
line: 3,
column: 1,
- offset: 10 + content.length
+ offset: 10 + content.length,
},
- source: content
})
})
@@ -132,9 +202,8 @@ h1 { color: red }
expect(descriptor.template).toBeTruthy()
expect(descriptor.template!.content).toBeFalsy()
expect(descriptor.template!.loc).toMatchObject({
- start: { line: 1, column: 1, offset: 0 },
- end: { line: 1, column: 1, offset: 0 },
- source: ''
+ start: { line: 1, column: 12, offset: 11 },
+ end: { line: 1, column: 12, offset: 11 },
})
})
@@ -145,7 +214,6 @@ h1 { color: red }
expect(descriptor.template!.loc).toMatchObject({
start: { line: 1, column: 11, offset: 10 },
end: { line: 1, column: 11, offset: 10 },
- source: ''
})
})
@@ -156,7 +224,7 @@ h1 { color: red }
expect(parse(``).descriptor.styles.length).toBe(0)
expect(parse(` `).descriptor.customBlocks.length).toBe(0)
expect(
- parse(` \n\t `).descriptor.customBlocks.length
+ parse(` \n\t `).descriptor.customBlocks.length,
).toBe(0)
})
@@ -167,25 +235,28 @@ h1 { color: red }
expect(descriptor.script!.attrs['src']).toBe('com')
})
+ test('should not expose ast on template node if has src import', () => {
+ const { descriptor } = parse(` `)
+ expect(descriptor.template!.ast).toBeUndefined()
+ })
+
test('ignoreEmpty: false', () => {
const { descriptor } = parse(
`\n`,
{
- ignoreEmpty: false
- }
+ ignoreEmpty: false,
+ },
)
expect(descriptor.script).toBeTruthy()
expect(descriptor.script!.loc).toMatchObject({
- source: '',
start: { line: 1, column: 9, offset: 8 },
- end: { line: 1, column: 9, offset: 8 }
+ end: { line: 1, column: 9, offset: 8 },
})
expect(descriptor.scriptSetup).toBeTruthy()
expect(descriptor.scriptSetup!.loc).toMatchObject({
- source: '\n',
start: { line: 2, column: 15, offset: 32 },
- end: { line: 3, column: 1, offset: 33 }
+ end: { line: 3, column: 1, offset: 33 },
})
})
@@ -201,20 +272,22 @@ h1 { color: red }
test('treat empty lang attribute as the html', () => {
const content = `ok
`
const { descriptor, errors } = parse(
- `${content} `
+ `${content} `,
)
expect(descriptor.template!.content).toBe(content)
expect(errors.length).toBe(0)
})
// #1120
- test('alternative template lang should be treated as plain text', () => {
- const content = `p(v-if="1 < 2") test`
+ test('template with preprocessor lang should be treated as plain text', () => {
+ const content = `p(v-if="1 < 2") test
`
const { descriptor, errors } = parse(
- `` + content + ` `
+ `` + content + ` `,
)
expect(errors.length).toBe(0)
expect(descriptor.template!.content).toBe(content)
+ // should not attempt to parse the content
+ expect(descriptor.template!.ast!.children.length).toBe(1)
})
//#2566
@@ -233,17 +306,17 @@ h1 { color: red }
expect(parse(`hi `).descriptor.slotted).toBe(false)
expect(
parse(`hi `).descriptor
- .slotted
+ .slotted,
).toBe(false)
expect(
parse(
- `hi `
- ).descriptor.slotted
+ `hi `,
+ ).descriptor.slotted,
).toBe(true)
expect(
parse(
- `hi `
- ).descriptor.slotted
+ `hi `,
+ ).descriptor.slotted,
).toBe(true)
})
@@ -260,21 +333,54 @@ h1 { color: red }
test('custom compiler', () => {
const { errors } = parse(` `, {
compiler: {
- parse: baseParse,
- compile: baseCompile
- }
+ parse: (_, options) => {
+ options.onError!(new Error('foo') as any)
+ return createRoot([])
+ },
+ compile: baseCompile,
+ },
})
- expect(errors.length).toBe(1)
+ expect(errors.length).toBe(2)
+ // error thrown by the custom parse
+ expect(errors[0].message).toBe('foo')
+ // error thrown based on the returned root
+ expect(errors[1].message).toMatch('At least one')
})
test('treat custom blocks as raw text', () => {
const { errors, descriptor } = parse(
- ` <-& `
+ ` <-& `,
)
expect(errors.length).toBe(0)
expect(descriptor.customBlocks[0].content).toBe(` <-& `)
})
+ test('should accept parser options', () => {
+ const { errors, descriptor } = parse(` `, {
+ templateParseOptions: {
+ isCustomElement: t => t === 'hello',
+ },
+ })
+ expect(errors.length).toBe(0)
+ expect(descriptor.template!.ast!.children[0]).toMatchObject({
+ type: NodeTypes.ELEMENT,
+ tag: 'hello',
+ tagType: ElementTypes.ELEMENT,
+ })
+
+ // test cache invalidation on different options
+ const { descriptor: d2 } = parse(` `, {
+ templateParseOptions: {
+ isCustomElement: t => t !== 'hello',
+ },
+ })
+ expect(d2.template!.ast!.children[0]).toMatchObject({
+ type: NodeTypes.ELEMENT,
+ tag: 'hello',
+ tagType: ElementTypes.COMPONENT,
+ })
+ })
+
describe('warnings', () => {
function assertWarning(errors: Error[], msg: string) {
expect(errors.some(e => e.message.match(msg))).toBe(true)
@@ -283,7 +389,7 @@ h1 { color: red }
test('should only allow single template element', () => {
assertWarning(
parse(`
`).errors,
- `Single file component can contain only one element`
+ `Single file component can contain only one element`,
)
})
@@ -291,24 +397,24 @@ h1 { color: red }
assertWarning(
parse(``)
.errors,
- `Single file component can contain only one `
+ ``,
).errors,
- `Single file component can contain only one `
- ).errors.length
+ ``,
+ ).errors.length,
).toBe(0)
})
@@ -316,7 +422,17 @@ h1 { color: red }
test('should throw error if no or
-
-
-
-
-
-
-
diff --git a/packages/sfc-playground/src/icons/GitHub.vue b/packages/sfc-playground/src/icons/GitHub.vue
deleted file mode 100644
index cc2506a787d..00000000000
--- a/packages/sfc-playground/src/icons/GitHub.vue
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
diff --git a/packages/sfc-playground/src/icons/Moon.vue b/packages/sfc-playground/src/icons/Moon.vue
deleted file mode 100644
index 30c6eb515f1..00000000000
--- a/packages/sfc-playground/src/icons/Moon.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/packages/sfc-playground/src/icons/Sun.vue b/packages/sfc-playground/src/icons/Sun.vue
deleted file mode 100644
index 4e4b1f409f9..00000000000
--- a/packages/sfc-playground/src/icons/Sun.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/sfc-playground/vite.config.ts b/packages/sfc-playground/vite.config.ts
deleted file mode 100644
index 44d5a53509f..00000000000
--- a/packages/sfc-playground/vite.config.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import fs from 'fs'
-import path from 'path'
-import { defineConfig, Plugin } from 'vite'
-import vue from '@vitejs/plugin-vue'
-import execa from 'execa'
-
-const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7)
-
-export default defineConfig({
- plugins: [vue(), copyVuePlugin()],
- define: {
- __COMMIT__: JSON.stringify(commit),
- __VUE_PROD_DEVTOOLS__: JSON.stringify(true)
- },
- optimizeDeps: {
- exclude: ['@vue/repl']
- }
-})
-
-function copyVuePlugin(): Plugin {
- return {
- name: 'copy-vue',
- generateBundle() {
- const copyFile = (file: string) => {
- const filePath = path.resolve(__dirname, file)
- const basename = path.basename(file)
- if (!fs.existsSync(filePath)) {
- throw new Error(
- `${basename} not built. ` +
- `Run "nr build vue -f esm-browser" first.`
- )
- }
- this.emitFile({
- type: 'asset',
- fileName: basename,
- source: fs.readFileSync(filePath, 'utf-8')
- })
- }
-
- copyFile(`../vue/dist/vue.runtime.esm-browser.js`)
- copyFile(`../server-renderer/dist/server-renderer.esm-browser.js`)
- }
- }
-}
diff --git a/packages/shared/__tests__/__snapshots__/codeframe.spec.ts.snap b/packages/shared/__tests__/__snapshots__/codeframe.spec.ts.snap
index a66fac9209d..28486d71723 100644
--- a/packages/shared/__tests__/__snapshots__/codeframe.spec.ts.snap
+++ b/packages/shared/__tests__/__snapshots__/codeframe.spec.ts.snap
@@ -1,6 +1,32 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`compiler: codeframe line in middle 1`] = `
+exports[`compiler: codeframe > invalid start and end 1`] = `
+"1 | "
`;
-exports[`compiler: codeframe line near top 1`] = `
+exports[`compiler: codeframe > line near top 1`] = `
"1 |
2 |
| ^^^^^^^^^
@@ -25,7 +51,7 @@ exports[`compiler: codeframe line near top 1`] = `
4 |
hi "
`;
-exports[`compiler: codeframe multi-line highlights 1`] = `
+exports[`compiler: codeframe > multi-line highlights 1`] = `
"1 |
newline sequences - unix 1`] = `
"8 |
9 |
10 |
@@ -49,7 +75,7 @@ exports[`compiler: codeframe newline sequences - unix 1`] = `
| ^^^^^^^^^^^^"
`;
-exports[`compiler: codeframe newline sequences - windows 1`] = `
+exports[`compiler: codeframe > newline sequences - windows 1`] = `
"8 |
9 |
10 |
diff --git a/packages/shared/__tests__/codeframe.spec.ts b/packages/shared/__tests__/codeframe.spec.ts
index 5083100485d..41ad08b2a9b 100644
--- a/packages/shared/__tests__/codeframe.spec.ts
+++ b/packages/shared/__tests__/codeframe.spec.ts
@@ -44,6 +44,12 @@ attr
expect(generateCodeFrame(source, attrStart, attrEnd)).toMatchSnapshot()
})
+ test('invalid start and end', () => {
+ expect(generateCodeFrame(source, -Infinity, 0)).toMatchSnapshot()
+ expect(generateCodeFrame(source, 0, Infinity)).toMatchSnapshot()
+ expect(generateCodeFrame(source, Infinity, 0)).toMatchSnapshot()
+ })
+
{
const source = `
@@ -75,7 +81,7 @@ attr
const keyEnd =
windowsNewLineSource.indexOf(endToken, keyStart) + endToken.length
expect(
- generateCodeFrame(windowsNewLineSource, keyStart, keyEnd)
+ generateCodeFrame(windowsNewLineSource, keyStart, keyEnd),
).toMatchSnapshot()
})
@@ -84,7 +90,7 @@ attr
const keyEnd =
unixNewlineSource.indexOf(endToken, keyStart) + endToken.length
expect(
- generateCodeFrame(unixNewlineSource, keyStart, keyEnd)
+ generateCodeFrame(unixNewlineSource, keyStart, keyEnd),
).toMatchSnapshot()
})
}
diff --git a/packages/shared/__tests__/cssVars.spec.ts b/packages/shared/__tests__/cssVars.spec.ts
new file mode 100644
index 00000000000..747ab067d25
--- /dev/null
+++ b/packages/shared/__tests__/cssVars.spec.ts
@@ -0,0 +1,27 @@
+import { normalizeCssVarValue } from '../src'
+
+describe('utils/cssVars', () => {
+ test('should normalize css binding values correctly', () => {
+ expect(normalizeCssVarValue(null)).toBe('initial')
+ expect(normalizeCssVarValue(undefined)).toBe('initial')
+ expect(normalizeCssVarValue('')).toBe(' ')
+ expect(normalizeCssVarValue(' ')).toBe(' ')
+ expect(normalizeCssVarValue('foo')).toBe('foo')
+ expect(normalizeCssVarValue(0)).toBe('0')
+ })
+
+ test('should warn on invalid css binding values', () => {
+ const warning =
+ '[Vue warn] Invalid value used for CSS binding. Expected a string or a finite number but received:'
+ expect(normalizeCssVarValue(NaN)).toBe('NaN')
+ expect(warning).toHaveBeenWarnedTimes(1)
+ expect(normalizeCssVarValue(Infinity)).toBe('Infinity')
+ expect(warning).toHaveBeenWarnedTimes(2)
+ expect(normalizeCssVarValue(-Infinity)).toBe('-Infinity')
+ expect(warning).toHaveBeenWarnedTimes(3)
+ expect(normalizeCssVarValue({})).toBe('[object Object]')
+ expect(warning).toHaveBeenWarnedTimes(4)
+ expect(normalizeCssVarValue([])).toBe('')
+ expect(warning).toHaveBeenWarnedTimes(5)
+ })
+})
diff --git a/packages/shared/__tests__/escapeHtml.spec.ts b/packages/shared/__tests__/escapeHtml.spec.ts
index 34505d3eadc..30004706af7 100644
--- a/packages/shared/__tests__/escapeHtml.spec.ts
+++ b/packages/shared/__tests__/escapeHtml.spec.ts
@@ -1,11 +1,31 @@
-import { escapeHtml } from '../src'
-
-test('ssr: escapeHTML', () => {
- expect(escapeHtml(`foo`)).toBe(`foo`)
- expect(escapeHtml(true)).toBe(`true`)
- expect(escapeHtml(false)).toBe(`false`)
- expect(escapeHtml(`a && b`)).toBe(`a && b`)
- expect(escapeHtml(`"foo"`)).toBe(`"foo"`)
- expect(escapeHtml(`'bar'`)).toBe(`'bar'`)
- expect(escapeHtml(``)).toBe(`<div>`)
+import { escapeHtml, escapeHtmlComment } from '../src'
+
+describe('escapeHtml', () => {
+ test('ssr: escapeHTML', () => {
+ expect(escapeHtml(`foo`)).toBe(`foo`)
+ expect(escapeHtml(true)).toBe(`true`)
+ expect(escapeHtml(false)).toBe(`false`)
+ expect(escapeHtml(`a && b`)).toBe(`a && b`)
+ expect(escapeHtml(`"foo"`)).toBe(`"foo"`)
+ expect(escapeHtml(`'bar'`)).toBe(`'bar'`)
+ expect(escapeHtml(`
`)).toBe(`<div>`)
+ })
+
+ test('ssr: escapeHTMLComment', () => {
+ const input = ''
+ const result = escapeHtmlComment(input)
+ expect(result).toEqual(' Hello World! ')
+ })
+
+ test('ssr: escapeHTMLComment', () => {
+ const input = ' Hello World!'
+ const result = escapeHtmlComment(input)
+ expect(result).toEqual(' Comment 1 Hello ! Comment 2 World!')
+ })
+
+ test('should not affect non-comment strings', () => {
+ const input = 'Hello World'
+ const result = escapeHtmlComment(input)
+ expect(result).toEqual(input)
+ })
})
diff --git a/packages/shared/__tests__/looseEqual.spec.ts b/packages/shared/__tests__/looseEqual.spec.ts
index 24bd48c1015..2dea58ce586 100644
--- a/packages/shared/__tests__/looseEqual.spec.ts
+++ b/packages/shared/__tests__/looseEqual.spec.ts
@@ -1,3 +1,6 @@
+/**
+ * @vitest-environment jsdom
+ */
import { looseEqual } from '../src'
describe('utils/looseEqual', () => {
@@ -66,27 +69,27 @@ describe('utils/looseEqual', () => {
const date2 = new Date(2019, 1, 2, 3, 4, 5, 7)
const file1 = new File([''], 'filename.txt', {
type: 'text/plain',
- lastModified: date1.getTime()
+ lastModified: date1.getTime(),
})
const file2 = new File([''], 'filename.txt', {
type: 'text/plain',
- lastModified: date1.getTime()
+ lastModified: date1.getTime(),
})
const file3 = new File([''], 'filename.txt', {
type: 'text/plain',
- lastModified: date2.getTime()
+ lastModified: date2.getTime(),
})
const file4 = new File([''], 'filename.csv', {
type: 'text/csv',
- lastModified: date1.getTime()
+ lastModified: date1.getTime(),
})
const file5 = new File(['abcdef'], 'filename.txt', {
type: 'text/plain',
- lastModified: date1.getTime()
+ lastModified: date1.getTime(),
})
const file6 = new File(['12345'], 'filename.txt', {
type: 'text/plain',
- lastModified: date1.getTime()
+ lastModified: date1.getTime(),
})
// Identical file object references
@@ -175,7 +178,7 @@ describe('utils/looseEqual', () => {
const date1 = new Date(2019, 1, 2, 3, 4, 5, 6)
const file1 = new File([''], 'filename.txt', {
type: 'text/plain',
- lastModified: date1.getTime()
+ lastModified: date1.getTime(),
})
expect(looseEqual(123, '123')).toBe(true)
diff --git a/packages/shared/__tests__/normalizeProp.spec.ts b/packages/shared/__tests__/normalizeProp.spec.ts
index a3cb104c003..00c6b294da1 100644
--- a/packages/shared/__tests__/normalizeProp.spec.ts
+++ b/packages/shared/__tests__/normalizeProp.spec.ts
@@ -1,22 +1,81 @@
-import { normalizeClass, parseStringStyle } from '../src'
+import {
+ normalizeClass,
+ normalizeProps,
+ normalizeStyle,
+ parseStringStyle,
+ stringifyStyle,
+} from '../src'
describe('normalizeClass', () => {
+ test('handles undefined correctly', () => {
+ expect(normalizeClass(undefined)).toEqual('')
+ })
+
test('handles string correctly', () => {
expect(normalizeClass('foo')).toEqual('foo')
})
test('handles array correctly', () => {
expect(normalizeClass(['foo', undefined, true, false, 'bar'])).toEqual(
- 'foo bar'
+ 'foo bar',
)
})
+ test('handles string containing spaces correctly', () => {
+ expect(normalizeClass('foo1 ')).toEqual('foo1')
+ expect(normalizeClass(['foo ', ' baz '])).toEqual('foo baz')
+ })
+
+ test('handles empty array correctly', () => {
+ expect(normalizeClass([])).toEqual('')
+ })
+
+ test('handles nested array correctly', () => {
+ expect(normalizeClass(['foo', ['bar'], [['baz']]])).toEqual('foo bar baz')
+ })
+
test('handles object correctly', () => {
expect(normalizeClass({ foo: true, bar: false, baz: true })).toEqual(
- 'foo baz'
+ 'foo baz',
)
})
+ test('handles empty object correctly', () => {
+ expect(normalizeClass({})).toEqual('')
+ })
+
+ test('handles arrays and objects correctly', () => {
+ expect(
+ normalizeClass(['foo', ['bar'], { baz: true }, [{ qux: true }]]),
+ ).toEqual('foo bar baz qux')
+ })
+
+ test('handles array of objects with falsy values', () => {
+ expect(
+ normalizeClass([
+ { foo: false },
+ { bar: 0 },
+ { baz: -0 },
+ { qux: '' },
+ { quux: null },
+ { corge: undefined },
+ { grault: NaN },
+ ]),
+ ).toEqual('')
+ })
+
+ test('handles array of objects with truthy values', () => {
+ expect(
+ normalizeClass([
+ { foo: true },
+ { bar: 'not-empty' },
+ { baz: 1 },
+ { qux: {} },
+ { quux: [] },
+ ]),
+ ).toEqual('foo bar baz qux quux')
+ })
+
// #6777
test('parse multi-line inline style', () => {
expect(
@@ -28,7 +87,7 @@ describe('normalizeClass', () => {
#ccc 0.5em,
white 0,
white 0.75em
- );`)
+ );`),
).toMatchInlineSnapshot(`
{
"background": "linear-gradient(white, white) padding-box,
@@ -44,3 +103,132 @@ describe('normalizeClass', () => {
`)
})
})
+
+describe('normalizeStyle', () => {
+ test('handles string correctly', () => {
+ expect(normalizeStyle('foo')).toEqual('foo')
+ })
+
+ test('handles array correctly', () => {
+ const style: any = normalizeStyle([
+ `border: 1px solid transparent;
+ background: linear-gradient(white, white) padding-box,
+ repeating-linear-gradient(
+ -45deg,
+ #ccc 0,
+ #ccc 0.5em,
+ white 0,
+ white 0.75em
+ );`,
+ ])
+
+ expect(style.border).toEqual('1px solid transparent')
+
+ expect(style.background).toEqual(`linear-gradient(white, white) padding-box,
+ repeating-linear-gradient(
+ -45deg,
+ #ccc 0,
+ #ccc 0.5em,
+ white 0,
+ white 0.75em
+ )`)
+ })
+
+ test('handles object correctly', () => {
+ const styleObj = {
+ border: '1px solid transparent',
+ background: `linear-gradient(white, white) padding-box,
+ repeating-linear-gradient(
+ -45deg,
+ #ccc 0,
+ #ccc 0.5em,
+ white 0,
+ white 0.75em
+ )`,
+ }
+ const style: any = normalizeStyle(styleObj)
+ expect(style.border).toEqual(styleObj.border)
+ expect(style.background).toEqual(styleObj.background)
+ })
+})
+
+describe('stringifyStyle', () => {
+ test('should return empty string for undefined', () => {
+ expect(stringifyStyle(undefined)).toBe('')
+ expect(stringifyStyle('')).toBe('')
+ expect(stringifyStyle('color: blue;')).toBe('color: blue;')
+ })
+
+ test('should return valid CSS string for normalized style object', () => {
+ const style = {
+ color: 'blue',
+ fontSize: '14px',
+ backgroundColor: 'white',
+ opacity: 0.8,
+ margin: 0,
+ '--custom-color': 'red',
+ }
+
+ expect(stringifyStyle(style)).toBe(
+ 'color:blue;font-size:14px;background-color:white;opacity:0.8;margin:0;--custom-color:red;',
+ )
+ })
+
+ test('should ignore non-string or non-number values in style object', () => {
+ const style: any = {
+ color: 'blue',
+ fontSize: '14px',
+ lineHeight: true,
+ padding: null,
+ margin: undefined,
+ }
+
+ const expected = 'color:blue;font-size:14px;'
+ expect(stringifyStyle(style)).toBe(expected)
+ })
+})
+
+describe('normalizeProps', () => {
+ test('should return null when props is null', () => {
+ const props = null
+ const result = normalizeProps(props)
+ expect(result).toBeNull()
+ })
+
+ test('should normalize class prop when it is an array', () => {
+ const props = {
+ class: ['class1', 'class2'],
+ }
+ const result = normalizeProps(props)
+ expect(result).toEqual({
+ class: 'class1 class2',
+ })
+ })
+
+ test('should normalize class prop when it is an object', () => {
+ const props = {
+ class: {
+ class1: true,
+ class2: false,
+ class3: true,
+ },
+ }
+ const result = normalizeProps(props)
+ expect(result).toEqual({
+ class: 'class1 class3',
+ })
+ })
+
+ test('should normalize style prop', () => {
+ const props = {
+ style: ['color: blue', 'font-size: 14px'],
+ }
+ const result = normalizeProps(props)
+ expect(result).toEqual({
+ style: {
+ color: 'blue',
+ 'font-size': '14px',
+ },
+ })
+ })
+})
diff --git a/packages/shared/__tests__/toDisplayString.spec.ts b/packages/shared/__tests__/toDisplayString.spec.ts
index b556402f6b8..cd8db0b4726 100644
--- a/packages/shared/__tests__/toDisplayString.spec.ts
+++ b/packages/shared/__tests__/toDisplayString.spec.ts
@@ -1,3 +1,6 @@
+/**
+ * @vitest-environment jsdom
+ */
import { computed, ref } from '@vue/reactivity'
import { toDisplayString } from '../src'
@@ -8,12 +11,28 @@ describe('toDisplayString', () => {
})
test('primitive values', () => {
+ expect(toDisplayString(0)).toBe('0')
expect(toDisplayString(1)).toBe('1')
+ expect(toDisplayString(NaN)).toBe('NaN')
expect(toDisplayString(true)).toBe('true')
expect(toDisplayString(false)).toBe('false')
expect(toDisplayString('hello')).toBe('hello')
})
+ test('primitive values in refs', () => {
+ expect(toDisplayString(ref(0))).toBe('0')
+ expect(toDisplayString(ref(1))).toBe('1')
+ expect(toDisplayString(ref(NaN))).toBe('NaN')
+ expect(toDisplayString(ref(true))).toBe('true')
+ expect(toDisplayString(ref(false))).toBe('false')
+ expect(toDisplayString(ref('hello'))).toBe('hello')
+ })
+
+ test('symbol values', () => {
+ expect(toDisplayString(Symbol('hello'))).toBe('Symbol(hello)')
+ expect(toDisplayString(ref(Symbol('hello')))).toBe('Symbol(hello)')
+ })
+
test('Object and Arrays', () => {
const obj = { foo: 123 }
expect(toDisplayString(obj)).toBe(JSON.stringify(obj, null, 2))
@@ -24,19 +43,19 @@ describe('toDisplayString', () => {
foo: 555,
toString() {
return 'override'
- }
+ },
}
expect(toDisplayString(objWithToStringOverride)).toBe('override')
const objWithNonInvokableToString = {
foo: 555,
- toString: null
+ toString: null,
}
expect(toDisplayString(objWithNonInvokableToString)).toBe(
`{
"foo": 555,
"toString": null
-}`
+}`,
)
// object created from null does not have .toString in its prototype
@@ -45,7 +64,7 @@ describe('toDisplayString', () => {
expect(toDisplayString(nullObjectWithoutToString)).toBe(
`{
"bar": 1
-}`
+}`,
)
// array toString override is ignored
@@ -57,7 +76,7 @@ describe('toDisplayString', () => {
1,
2,
3
-]`
+]`,
)
})
@@ -67,8 +86,8 @@ describe('toDisplayString', () => {
expect(
toDisplayString({
n,
- np
- })
+ np,
+ }),
).toBe(JSON.stringify({ n: 1, np: 2 }, null, 2))
})
@@ -86,7 +105,7 @@ describe('toDisplayString', () => {
test('native objects', () => {
const div = document.createElement('div')
- expect(toDisplayString(div)).toBe('[object HTMLDivElement]')
+ expect(toDisplayString(div)).toMatch('[object HTMLDivElement]')
expect(toDisplayString({ div })).toMatchInlineSnapshot(`
"{
"div": "[object HTMLDivElement]"
@@ -97,7 +116,7 @@ describe('toDisplayString', () => {
test('Map and Set', () => {
const m = new Map
([
[1, 'foo'],
- [{ baz: 1 }, { foo: 'bar', qux: 2 }]
+ [{ baz: 1 }, { foo: 'bar', qux: 2 }],
])
const s = new Set([1, { foo: 'bar' }, m])
@@ -135,8 +154,8 @@ describe('toDisplayString', () => {
expect(
toDisplayString({
m,
- s
- })
+ s,
+ }),
).toMatchInlineSnapshot(`
"{
"m": {
@@ -168,4 +187,49 @@ describe('toDisplayString', () => {
}"
`)
})
+
+ //#9727
+ test('Map with Symbol keys', () => {
+ const m = new Map([
+ [Symbol(), 'foo'],
+ [Symbol(), 'bar'],
+ [Symbol('baz'), 'baz'],
+ ])
+ expect(toDisplayString(m)).toMatchInlineSnapshot(`
+ "{
+ "Map(3)": {
+ "Symbol(0) =>": "foo",
+ "Symbol(1) =>": "bar",
+ "Symbol(baz) =>": "baz"
+ }
+ }"
+ `)
+ // confirming the symbol renders Symbol(foo)
+ expect(toDisplayString(new Map([[Symbol('foo'), 'foo']]))).toContain(
+ String(Symbol('foo')),
+ )
+ })
+
+ test('Set with Symbol values', () => {
+ const s = new Set([Symbol('foo'), Symbol('bar'), Symbol()])
+ expect(toDisplayString(s)).toMatchInlineSnapshot(`
+ "{
+ "Set(3)": [
+ "Symbol(foo)",
+ "Symbol(bar)",
+ "Symbol()"
+ ]
+ }"
+ `)
+ })
+
+ test('Object with Symbol values', () => {
+ expect(toDisplayString({ foo: Symbol('x'), bar: Symbol() }))
+ .toMatchInlineSnapshot(`
+ "{
+ "foo": "Symbol(x)",
+ "bar": "Symbol()"
+ }"
+ `)
+ })
})
diff --git a/packages/shared/api-extractor.json b/packages/shared/api-extractor.json
deleted file mode 100644
index 5602b3a6fd2..00000000000
--- a/packages/shared/api-extractor.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "../../api-extractor.json",
- "mainEntryPointFilePath": "./dist/packages//src/index.d.ts",
- "dtsRollup": {
- "publicTrimmedFilePath": "./dist/.d.ts"
- }
-}
diff --git a/packages/shared/package.json b/packages/shared/package.json
index 5bb2d41f864..63a10598ce8 100644
--- a/packages/shared/package.json
+++ b/packages/shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/shared",
- "version": "3.2.45",
+ "version": "3.5.18",
"description": "internal utils shared across @vue packages",
"main": "index.js",
"module": "dist/shared.esm-bundler.js",
@@ -9,6 +9,20 @@
"index.js",
"dist"
],
+ "exports": {
+ ".": {
+ "types": "./dist/shared.d.ts",
+ "node": {
+ "production": "./dist/shared.cjs.prod.js",
+ "development": "./dist/shared.cjs.js",
+ "default": "./index.js"
+ },
+ "module": "./dist/shared.esm-bundler.js",
+ "import": "./dist/shared.esm-bundler.js",
+ "require": "./index.js"
+ },
+ "./*": "./*"
+ },
"sideEffects": false,
"buildOptions": {
"formats": [
diff --git a/packages/shared/src/codeframe.ts b/packages/shared/src/codeframe.ts
index 82b38bfb330..1fdb606aed0 100644
--- a/packages/shared/src/codeframe.ts
+++ b/packages/shared/src/codeframe.ts
@@ -3,8 +3,14 @@ const range: number = 2
export function generateCodeFrame(
source: string,
start = 0,
- end = source.length
+ end: number = source.length,
): string {
+ // Ensure start and end are within the source length
+ start = Math.max(0, Math.min(start, source.length))
+ end = Math.max(0, Math.min(end, source.length))
+
+ if (start > end) return ''
+
// Split the content into individual lines but capture the newline sequence
// that separated each line. This is important because the actual sequence is
// needed to properly take into account the full line length for offset
@@ -28,7 +34,7 @@ export function generateCodeFrame(
res.push(
`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${
lines[j]
- }`
+ }`,
)
const lineLength = lines[j].length
const newLineSeqLength =
@@ -39,7 +45,7 @@ export function generateCodeFrame(
const pad = start - (count - (lineLength + newLineSeqLength))
const length = Math.max(
1,
- end > count ? lineLength - pad : end - start
+ end > count ? lineLength - pad : end - start,
)
res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length))
} else if (j > i) {
diff --git a/packages/shared/src/cssVars.ts b/packages/shared/src/cssVars.ts
new file mode 100644
index 00000000000..0c69b606f5d
--- /dev/null
+++ b/packages/shared/src/cssVars.ts
@@ -0,0 +1,24 @@
+/**
+ * Normalize CSS var value created by `v-bind` in `
+
+
diff --git a/packages/vue/__tests__/e2e/hydration-strat-media.html b/packages/vue/__tests__/e2e/hydration-strat-media.html
new file mode 100644
index 00000000000..954a73d0467
--- /dev/null
+++ b/packages/vue/__tests__/e2e/hydration-strat-media.html
@@ -0,0 +1,49 @@
+
+
+resize the window width to < 500px to hydrate
+0
+
+
diff --git a/packages/vue/__tests__/e2e/hydration-strat-visible.html b/packages/vue/__tests__/e2e/hydration-strat-visible.html
new file mode 100644
index 00000000000..489222f8606
--- /dev/null
+++ b/packages/vue/__tests__/e2e/hydration-strat-visible.html
@@ -0,0 +1,70 @@
+
+
+scroll to the bottom to hydrate
+0
+
+
+
diff --git a/packages/vue/__tests__/e2e/hydrationStrategies.spec.ts b/packages/vue/__tests__/e2e/hydrationStrategies.spec.ts
new file mode 100644
index 00000000000..d792edf1960
--- /dev/null
+++ b/packages/vue/__tests__/e2e/hydrationStrategies.spec.ts
@@ -0,0 +1,159 @@
+import path from 'node:path'
+import { setupPuppeteer } from './e2eUtils'
+import type { Ref } from '../../src/runtime'
+
+declare const window: Window & {
+ isHydrated: boolean
+ isRootMounted: boolean
+ teardownCalled?: boolean
+ show: Ref
+}
+
+describe('async component hydration strategies', () => {
+ const { page, click, text, count } = setupPuppeteer(['--window-size=800,600'])
+
+ async function goToCase(name: string, query = '') {
+ const file = `file://${path.resolve(__dirname, `./hydration-strat-${name}.html${query}`)}`
+ await page().goto(file)
+ }
+
+ async function assertHydrationSuccess(n = '1') {
+ await click('button')
+ expect(await text('button')).toBe(n)
+ }
+
+ test('idle', async () => {
+ const messages: string[] = []
+ page().on('console', e => messages.push(e.text()))
+
+ await goToCase('idle')
+ // not hydrated yet
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ // wait for hydration
+ await page().waitForFunction(() => window.isHydrated)
+ // assert message order: hyration should happen after already queued main thread work
+ expect(messages.slice(1)).toMatchObject(['resolve', 'busy', 'hydrated'])
+ await assertHydrationSuccess()
+ })
+
+ test('visible', async () => {
+ await goToCase('visible')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ // scroll down
+ await page().evaluate(() => window.scrollTo({ top: 1000 }))
+ await page().waitForFunction(() => window.isHydrated)
+ await assertHydrationSuccess()
+ })
+
+ test('visible (with rootMargin)', async () => {
+ await goToCase('visible', '?rootMargin=1000')
+ await page().waitForFunction(() => window.isRootMounted)
+ // should hydrate without needing to scroll
+ await page().waitForFunction(() => window.isHydrated)
+ await assertHydrationSuccess()
+ })
+
+ test('visible (fragment)', async () => {
+ await goToCase('visible', '?fragment')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ expect(await count('span')).toBe(2)
+ // scroll down
+ await page().evaluate(() => window.scrollTo({ top: 1000 }))
+ await page().waitForFunction(() => window.isHydrated)
+ await assertHydrationSuccess()
+ })
+
+ test('visible (root v-if) should not throw error', async () => {
+ const spy = vi.fn()
+ const currentPage = page()
+ currentPage.on('pageerror', spy)
+ await goToCase('visible', '?v-if')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ expect(spy).toBeCalledTimes(0)
+ currentPage.off('pageerror', spy)
+ })
+
+ test('media query', async () => {
+ await goToCase('media')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ // resize
+ await page().setViewport({ width: 400, height: 600 })
+ await page().waitForFunction(() => window.isHydrated)
+ await assertHydrationSuccess()
+ })
+
+ // #13255
+ test('media query (patched before hydration)', async () => {
+ const spy = vi.fn()
+ const currentPage = page()
+ currentPage.on('pageerror', spy)
+
+ const warn: any[] = []
+ currentPage.on('console', e => warn.push(e.text()))
+
+ await goToCase('media')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+
+ // patch
+ await page().evaluate(() => (window.show.value = false))
+ await click('button')
+ expect(await text('button')).toBe('1')
+
+ // resize
+ await page().setViewport({ width: 400, height: 600 })
+ await page().waitForFunction(() => window.isHydrated)
+ await assertHydrationSuccess('2')
+
+ expect(spy).toBeCalledTimes(0)
+ currentPage.off('pageerror', spy)
+ expect(
+ warn.some(w => w.includes('Skipping lazy hydration for component')),
+ ).toBe(true)
+ })
+
+ test('interaction', async () => {
+ await goToCase('interaction')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ await click('button')
+ await page().waitForFunction(() => window.isHydrated)
+ // should replay event
+ expect(await text('button')).toBe('1')
+ await assertHydrationSuccess('2')
+ })
+
+ test('interaction (fragment)', async () => {
+ await goToCase('interaction', '?fragment')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ await click('button')
+ await page().waitForFunction(() => window.isHydrated)
+ // should replay event
+ expect(await text('button')).toBe('1')
+ await assertHydrationSuccess('2')
+ })
+
+ test('custom', async () => {
+ await goToCase('custom')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ await click('#custom-trigger')
+ await page().waitForFunction(() => window.isHydrated)
+ await assertHydrationSuccess()
+ })
+
+ test('custom teardown', async () => {
+ await goToCase('custom')
+ await page().waitForFunction(() => window.isRootMounted)
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ await page().evaluate(() => (window.show.value = false))
+ expect(await text('#app')).toBe('off')
+ expect(await page().evaluate(() => window.isHydrated)).toBe(false)
+ expect(await page().evaluate(() => window.teardownCalled)).toBe(true)
+ })
+})
diff --git a/packages/vue/examples/__tests__/markdown.spec.ts b/packages/vue/__tests__/e2e/markdown.spec.ts
similarity index 69%
rename from packages/vue/examples/__tests__/markdown.spec.ts
rename to packages/vue/__tests__/e2e/markdown.spec.ts
index 35df22a2570..8764e66266c 100644
--- a/packages/vue/examples/__tests__/markdown.spec.ts
+++ b/packages/vue/__tests__/e2e/markdown.spec.ts
@@ -1,9 +1,5 @@
-import path from 'path'
-import {
- setupPuppeteer,
- expectByPolling,
- E2E_TIMEOUT
-} from '../../__tests__/e2eUtils'
+import path from 'node:path'
+import { E2E_TIMEOUT, expectByPolling, setupPuppeteer } from './e2eUtils'
describe('e2e: markdown', () => {
const { page, isVisible, value, html } = setupPuppeteer()
@@ -11,13 +7,13 @@ describe('e2e: markdown', () => {
async function testMarkdown(apiType: 'classic' | 'composition') {
const baseUrl = `file://${path.resolve(
__dirname,
- `../${apiType}/markdown.html#test`
+ `../../examples/${apiType}/markdown.html#test`,
)}`
await page().goto(baseUrl)
expect(await isVisible('#editor')).toBe(true)
expect(await value('textarea')).toBe('# hello')
- expect(await html('#editor div')).toBe('hello \n')
+ expect(await html('#editor div')).toBe('hello \n')
await page().type('textarea', '\n## foo\n\n- bar\n- baz')
@@ -27,9 +23,9 @@ describe('e2e: markdown', () => {
await expectByPolling(
() => html('#editor div'),
- 'hello \n' +
- 'foo \n' +
- '\n'
+ 'hello \n' +
+ 'foo \n' +
+ '\n',
)
}
@@ -38,7 +34,7 @@ describe('e2e: markdown', () => {
async () => {
await testMarkdown('classic')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
test(
@@ -46,6 +42,6 @@ describe('e2e: markdown', () => {
async () => {
await testMarkdown('composition')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
})
diff --git a/packages/vue/__tests__/e2e/memory-leak.spec.ts b/packages/vue/__tests__/e2e/memory-leak.spec.ts
new file mode 100644
index 00000000000..2412cea2b0a
--- /dev/null
+++ b/packages/vue/__tests__/e2e/memory-leak.spec.ts
@@ -0,0 +1,85 @@
+import { E2E_TIMEOUT, setupPuppeteer } from './e2eUtils'
+import path from 'node:path'
+
+const { page, html, click } = setupPuppeteer()
+
+beforeEach(async () => {
+ await page().setContent(`
`)
+ await page().addScriptTag({
+ path: path.resolve(__dirname, '../../dist/vue.global.js'),
+ })
+})
+
+describe('not leaking', async () => {
+ // #13661
+ test(
+ 'cached text vnodes should not retaining detached DOM nodes',
+ async () => {
+ const client = await page().createCDPSession()
+ await page().evaluate(async () => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ components: {
+ Comp1: {
+ template: `
+
+ {{ test.length }}
+ `,
+ setup() {
+ const test = ref([...Array(3000)].map((_, i) => ({ i })))
+ // @ts-expect-error
+ window.__REF__ = new WeakRef(test)
+
+ return { test }
+ },
+ },
+ Comp2: {
+ template: `comp2 `,
+ },
+ },
+ template: `
+ button
+
+
+
+ text node
+
+
+ `,
+ setup() {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ },
+ }).mount('#app')
+ })
+
+ expect(await html('#app')).toBe(
+ `button ` +
+ `` +
+ ` ` +
+ `
comp2 ` +
+ ` text node ` +
+ `` +
+ `` +
+ `3000
`,
+ )
+
+ await click('#toggleBtn')
+ expect(await html('#app')).toBe(
+ `button `,
+ )
+
+ const isCollected = async () =>
+ // @ts-expect-error
+ await page().evaluate(() => window.__REF__.deref() === undefined)
+
+ while ((await isCollected()) === false) {
+ await client.send('HeapProfiler.collectGarbage')
+ }
+
+ expect(await isCollected()).toBe(true)
+ },
+ E2E_TIMEOUT,
+ )
+})
diff --git a/packages/vue/__tests__/e2e/ssr-custom-element.spec.ts b/packages/vue/__tests__/e2e/ssr-custom-element.spec.ts
new file mode 100644
index 00000000000..c875f1bee69
--- /dev/null
+++ b/packages/vue/__tests__/e2e/ssr-custom-element.spec.ts
@@ -0,0 +1,174 @@
+import path from 'node:path'
+import { setupPuppeteer } from './e2eUtils'
+
+const { page, click, text } = setupPuppeteer()
+
+beforeEach(async () => {
+ await page().addScriptTag({
+ path: path.resolve(__dirname, '../../dist/vue.global.js'),
+ })
+})
+
+async function setContent(html: string) {
+ await page().setContent(`${html}
`)
+}
+
+// this must be tested in actual Chrome because jsdom does not support
+// declarative shadow DOM
+test('ssr custom element hydration', async () => {
+ await setContent(
+ `1 1 `,
+ )
+
+ await page().evaluate(() => {
+ const {
+ h,
+ ref,
+ defineSSRCustomElement,
+ defineAsyncComponent,
+ onMounted,
+ useHost,
+ } = (window as any).Vue
+
+ const def = {
+ setup() {
+ const count = ref(1)
+ const el = useHost()
+ onMounted(() => (el.style.border = '1px solid red'))
+
+ return () => h('button', { onClick: () => count.value++ }, count.value)
+ },
+ }
+
+ customElements.define('my-element', defineSSRCustomElement(def))
+ customElements.define(
+ 'my-element-async',
+ defineSSRCustomElement(
+ defineAsyncComponent(
+ () =>
+ new Promise(r => {
+ ;(window as any).resolve = () => r(def)
+ }),
+ ),
+ ),
+ )
+ })
+
+ function getColor() {
+ return page().evaluate(() => {
+ return [
+ (document.querySelector('my-element') as any).style.border,
+ (document.querySelector('my-element-async') as any).style.border,
+ ]
+ })
+ }
+
+ expect(await getColor()).toMatchObject(['1px solid red', ''])
+ await page().evaluate(() => (window as any).resolve()) // exposed by test
+ expect(await getColor()).toMatchObject(['1px solid red', '1px solid red'])
+
+ async function assertInteraction(el: string) {
+ const selector = `${el} >>> button`
+ expect(await text(selector)).toBe('1')
+ await click(selector)
+ expect(await text(selector)).toBe('2')
+ }
+
+ await assertInteraction('my-element')
+ await assertInteraction('my-element-async')
+})
+
+test('work with Teleport (shadowRoot: false)', async () => {
+ await setContent(
+ `
default `,
+ )
+
+ await page().evaluate(() => {
+ const { h, defineSSRCustomElement, Teleport, renderSlot } = (window as any)
+ .Vue
+ const Y = defineSSRCustomElement(
+ {
+ render() {
+ return h(
+ Teleport,
+ { to: '#test' },
+ {
+ default: () => [renderSlot(this.$slots, 'default')],
+ },
+ )
+ },
+ },
+ { shadowRoot: false },
+ )
+ customElements.define('my-y', Y)
+ const P = defineSSRCustomElement(
+ {
+ render() {
+ return renderSlot(this.$slots, 'default')
+ },
+ },
+ { shadowRoot: false },
+ )
+ customElements.define('my-p', P)
+ })
+
+ function getInnerHTML() {
+ return page().evaluate(() => {
+ return (document.querySelector('#test') as any).innerHTML
+ })
+ }
+
+ expect(await getInnerHTML()).toBe('default ')
+})
+
+// #11641
+test('pass key to custom element', async () => {
+ const messages: string[] = []
+ page().on('console', e => messages.push(e.text()))
+
+ await setContent(
+ `1
`,
+ )
+ await page().evaluate(() => {
+ const {
+ h,
+ ref,
+ defineSSRCustomElement,
+ onBeforeUnmount,
+ onMounted,
+ createSSRApp,
+ renderList,
+ } = (window as any).Vue
+
+ const MyElement = defineSSRCustomElement({
+ props: {
+ str: String,
+ },
+ setup(props: any) {
+ onMounted(() => {
+ console.log('child mounted')
+ })
+ onBeforeUnmount(() => {
+ console.log('child unmount')
+ })
+ return () => h('div', props.str)
+ },
+ })
+ customElements.define('my-element', MyElement)
+
+ createSSRApp({
+ setup() {
+ const arr = ref(['1'])
+ // pass key to custom element
+ return () =>
+ renderList(arr.value, (i: string) =>
+ h('my-element', { key: i, str: i }, null),
+ )
+ },
+ }).mount('#app')
+ })
+
+ expect(messages.includes('child mounted')).toBe(true)
+ expect(messages.includes('child unmount')).toBe(false)
+ expect(await text('my-element >>> div')).toBe('1')
+})
diff --git a/packages/vue/examples/__tests__/svg.spec.ts b/packages/vue/__tests__/e2e/svg.spec.ts
similarity index 94%
rename from packages/vue/examples/__tests__/svg.spec.ts
rename to packages/vue/__tests__/e2e/svg.spec.ts
index 6754d63030c..37081e4c03c 100644
--- a/packages/vue/examples/__tests__/svg.spec.ts
+++ b/packages/vue/__tests__/e2e/svg.spec.ts
@@ -1,5 +1,5 @@
-import path from 'path'
-import { setupPuppeteer, E2E_TIMEOUT } from '../../__tests__/e2eUtils'
+import path from 'node:path'
+import { E2E_TIMEOUT, setupPuppeteer } from './e2eUtils'
declare const globalStats: {
label: string
@@ -9,7 +9,7 @@ declare const globalStats: {
declare function valueToPoint(
value: number,
index: number,
- total: number
+ total: number,
): {
x: number
y: number
@@ -33,8 +33,8 @@ describe('e2e: svg', () => {
document.querySelector('polygon')!.attributes[0].value === points
)
},
- [total]
- )
+ [total],
+ ),
).toBe(true)
}
@@ -47,12 +47,12 @@ describe('e2e: svg', () => {
return [point.x, point.y]
})
},
- [total]
+ [total],
)
for (let i = 0; i < total; i++) {
const textPosition = await page().$eval(
`text:nth-child(${i + 3})`,
- node => [+node.attributes[0].value, +node.attributes[1].value]
+ node => [+node.attributes[0].value, +node.attributes[1].value],
)
expect(textPosition).toEqual(positions[i])
}
@@ -73,7 +73,7 @@ describe('e2e: svg', () => {
async function testSvg(apiType: 'classic' | 'composition') {
const baseUrl = `file://${path.resolve(
__dirname,
- `../${apiType}/svg.html`
+ `../../examples/${apiType}/svg.html`,
)}`
await page().goto(baseUrl)
@@ -144,7 +144,7 @@ describe('e2e: svg', () => {
async () => {
await testSvg('classic')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
test(
@@ -152,6 +152,6 @@ describe('e2e: svg', () => {
async () => {
await testSvg('composition')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
})
diff --git a/packages/vue/examples/__tests__/todomvc.spec.ts b/packages/vue/__tests__/e2e/todomvc.spec.ts
similarity index 92%
rename from packages/vue/examples/__tests__/todomvc.spec.ts
rename to packages/vue/__tests__/e2e/todomvc.spec.ts
index f6f1b05e576..c76bba53515 100644
--- a/packages/vue/examples/__tests__/todomvc.spec.ts
+++ b/packages/vue/__tests__/e2e/todomvc.spec.ts
@@ -1,5 +1,5 @@
-import path from 'path'
-import { setupPuppeteer, E2E_TIMEOUT } from '../../__tests__/e2eUtils'
+import path from 'node:path'
+import { E2E_TIMEOUT, setupPuppeteer } from './e2eUtils'
describe('e2e: todomvc', () => {
const {
@@ -13,7 +13,8 @@ describe('e2e: todomvc', () => {
isFocused,
classList,
enterValue,
- clearValue
+ clearValue,
+ timeout,
} = setupPuppeteer()
async function removeItemAt(n: number) {
@@ -26,7 +27,7 @@ describe('e2e: todomvc', () => {
async function testTodomvc(apiType: 'classic' | 'composition') {
const baseUrl = `file://${path.resolve(
__dirname,
- `../${apiType}/todomvc.html`
+ `../../examples/${apiType}/todomvc.html`,
)}`
await page().goto(baseUrl)
@@ -101,6 +102,7 @@ describe('e2e: todomvc', () => {
// active filter
await click('.filters li:nth-child(2) a')
+ await timeout(1)
expect(await count('.todo')).toBe(1)
expect(await count('.todo.completed')).toBe(0)
// add item with filter active
@@ -109,6 +111,7 @@ describe('e2e: todomvc', () => {
// completed filter
await click('.filters li:nth-child(3) a')
+ await timeout(1)
expect(await count('.todo')).toBe(2)
expect(await count('.todo.completed')).toBe(2)
@@ -128,13 +131,15 @@ describe('e2e: todomvc', () => {
await click('.todo .toggle')
expect(await count('.todo')).toBe(1)
await click('.filters li:nth-child(2) a')
+ await timeout(1)
expect(await count('.todo')).toBe(3)
await click('.todo .toggle')
expect(await count('.todo')).toBe(2)
// editing triggered by blur
await click('.filters li:nth-child(1) a')
- await click('.todo:nth-child(1) label', { clickCount: 2 })
+ await timeout(1)
+ await click('.todo:nth-child(1) label', { count: 2 })
expect(await count('.todo.editing')).toBe(1)
expect(await isFocused('.todo:nth-child(1) .edit')).toBe(true)
await clearValue('.todo:nth-child(1) .edit')
@@ -144,13 +149,13 @@ describe('e2e: todomvc', () => {
expect(await text('.todo:nth-child(1) label')).toBe('edited!')
// editing triggered by enter
- await click('.todo label', { clickCount: 2 })
+ await click('.todo label', { count: 2 })
await enterValue('.todo:nth-child(1) .edit', 'edited again!')
expect(await count('.todo.editing')).toBe(0)
expect(await text('.todo:nth-child(1) label')).toBe('edited again!')
// cancel
- await click('.todo label', { clickCount: 2 })
+ await click('.todo label', { count: 2 })
await clearValue('.todo:nth-child(1) .edit')
await page().type('.todo:nth-child(1) .edit', 'edited!')
await page().keyboard.press('Escape')
@@ -158,7 +163,7 @@ describe('e2e: todomvc', () => {
expect(await text('.todo:nth-child(1) label')).toBe('edited again!')
// empty value should remove
- await click('.todo label', { clickCount: 2 })
+ await click('.todo label', { count: 2 })
await enterValue('.todo:nth-child(1) .edit', ' ')
expect(await count('.todo')).toBe(3)
@@ -174,7 +179,7 @@ describe('e2e: todomvc', () => {
async () => {
await testTodomvc('classic')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
test(
@@ -182,6 +187,6 @@ describe('e2e: todomvc', () => {
async () => {
await testTodomvc('composition')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
})
diff --git a/packages/vue/__tests__/transition.html b/packages/vue/__tests__/e2e/transition.html
similarity index 55%
rename from packages/vue/__tests__/transition.html
rename to packages/vue/__tests__/e2e/transition.html
index 51553064554..ab404d67dc7 100644
--- a/packages/vue/__tests__/transition.html
+++ b/packages/vue/__tests__/e2e/transition.html
@@ -1,4 +1,4 @@
-
+
diff --git a/packages/vue/examples/__tests__/tree.spec.ts b/packages/vue/__tests__/e2e/tree.spec.ts
similarity index 86%
rename from packages/vue/examples/__tests__/tree.spec.ts
rename to packages/vue/__tests__/e2e/tree.spec.ts
index e1d14090f30..557712bc9db 100644
--- a/packages/vue/examples/__tests__/tree.spec.ts
+++ b/packages/vue/__tests__/e2e/tree.spec.ts
@@ -1,5 +1,5 @@
-import path from 'path'
-import { setupPuppeteer, E2E_TIMEOUT } from '../../__tests__/e2eUtils'
+import path from 'node:path'
+import { E2E_TIMEOUT, setupPuppeteer } from './e2eUtils'
describe('e2e: tree', () => {
const { page, click, count, text, children, isVisible } = setupPuppeteer()
@@ -7,7 +7,7 @@ describe('e2e: tree', () => {
async function testTree(apiType: 'classic' | 'composition') {
const baseUrl = `file://${path.resolve(
__dirname,
- `../${apiType}/tree.html`
+ `../../examples/${apiType}/tree.html`,
)}`
await page().goto(baseUrl)
@@ -23,57 +23,57 @@ describe('e2e: tree', () => {
expect((await children('#demo li ul')).length).toBe(4)
expect(await text('#demo li div span')).toContain('[-]')
expect(await text('#demo > .item > ul > .item:nth-child(1)')).toContain(
- 'hello'
+ 'hello',
)
expect(await text('#demo > .item > ul > .item:nth-child(2)')).toContain(
- 'wat'
+ 'wat',
)
expect(await text('#demo > .item > ul > .item:nth-child(3)')).toContain(
- 'child folder'
+ 'child folder',
)
expect(await text('#demo > .item > ul > .item:nth-child(3)')).toContain(
- '[+]'
+ '[+]',
)
// add items to root
await click('#demo > .item > ul > .add')
expect((await children('#demo li ul')).length).toBe(5)
expect(await text('#demo > .item > ul > .item:nth-child(1)')).toContain(
- 'hello'
+ 'hello',
)
expect(await text('#demo > .item > ul > .item:nth-child(2)')).toContain(
- 'wat'
+ 'wat',
)
expect(await text('#demo > .item > ul > .item:nth-child(3)')).toContain(
- 'child folder'
+ 'child folder',
)
expect(await text('#demo > .item > ul > .item:nth-child(3)')).toContain(
- '[+]'
+ '[+]',
)
expect(await text('#demo > .item > ul > .item:nth-child(4)')).toContain(
- 'new stuff'
+ 'new stuff',
)
// add another item
await click('#demo > .item > ul > .add')
expect((await children('#demo li ul')).length).toBe(6)
expect(await text('#demo > .item > ul > .item:nth-child(1)')).toContain(
- 'hello'
+ 'hello',
)
expect(await text('#demo > .item > ul > .item:nth-child(2)')).toContain(
- 'wat'
+ 'wat',
)
expect(await text('#demo > .item > ul > .item:nth-child(3)')).toContain(
- 'child folder'
+ 'child folder',
)
expect(await text('#demo > .item > ul > .item:nth-child(3)')).toContain(
- '[+]'
+ '[+]',
)
expect(await text('#demo > .item > ul > .item:nth-child(4)')).toContain(
- 'new stuff'
+ 'new stuff',
)
expect(await text('#demo > .item > ul > .item:nth-child(5)')).toContain(
- 'new stuff'
+ 'new stuff',
)
await click('#demo ul .bold')
@@ -88,12 +88,12 @@ describe('e2e: tree', () => {
expect(await isVisible('#demo ul')).toBe(true)
expect(await text('#demo li div span')).toContain('[-]')
- await click('#demo ul > .item div', { clickCount: 2 })
+ await click('#demo ul > .item div', { count: 2 })
expect(await count('.item')).toBe(15)
expect(await count('.item > ul')).toBe(5)
expect(await text('#demo ul > .item:nth-child(1)')).toContain('[-]')
expect((await children('#demo ul > .item:nth-child(1) > ul')).length).toBe(
- 2
+ 2,
)
}
@@ -102,7 +102,7 @@ describe('e2e: tree', () => {
async () => {
await testTree('classic')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
test(
@@ -110,6 +110,6 @@ describe('e2e: tree', () => {
async () => {
await testTree('composition')
},
- E2E_TIMEOUT
+ E2E_TIMEOUT,
)
})
diff --git a/packages/vue/__tests__/e2e/trusted-types.html b/packages/vue/__tests__/e2e/trusted-types.html
new file mode 100644
index 00000000000..181dd0465da
--- /dev/null
+++ b/packages/vue/__tests__/e2e/trusted-types.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ Vue App
+
+
+
+
+
+
+
diff --git a/packages/vue/__tests__/e2e/trusted-types.spec.ts b/packages/vue/__tests__/e2e/trusted-types.spec.ts
new file mode 100644
index 00000000000..927f5949254
--- /dev/null
+++ b/packages/vue/__tests__/e2e/trusted-types.spec.ts
@@ -0,0 +1,103 @@
+import { once } from 'node:events'
+import { createServer } from 'node:http'
+import path from 'node:path'
+import { beforeAll } from 'vitest'
+import serveHandler from 'serve-handler'
+
+import { E2E_TIMEOUT, setupPuppeteer } from './e2eUtils'
+
+// use the `vue` package root as the public directory
+// because we need to serve the Vue runtime for the tests
+const serverRoot = path.resolve(import.meta.dirname, '../../')
+const testPort = 9090
+const basePath = path.relative(
+ serverRoot,
+ path.resolve(import.meta.dirname, './trusted-types.html'),
+)
+const baseUrl = `http://localhost:${testPort}/${basePath}`
+
+const { page, html } = setupPuppeteer()
+
+let server: ReturnType
+beforeAll(async () => {
+ // sets up the static server
+ server = createServer((req, res) => {
+ return serveHandler(req, res, {
+ public: serverRoot,
+ cleanUrls: false,
+ })
+ })
+
+ server.listen(testPort)
+ await once(server, 'listening')
+})
+
+afterAll(async () => {
+ server.close()
+ await once(server, 'close')
+})
+
+describe('e2e: trusted types', () => {
+ beforeEach(async () => {
+ await page().goto(baseUrl)
+ await page().waitForSelector('#app')
+ })
+
+ test(
+ 'should render the hello world app',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref, h } = (window as any).Vue
+ createApp({
+ setup() {
+ const msg = ref('✅success: hello world')
+ return function render() {
+ return h('div', msg.value)
+ }
+ },
+ }).mount('#app')
+ })
+ expect(await html('#app')).toContain('✅success: hello world
')
+ },
+ E2E_TIMEOUT,
+ )
+
+ test(
+ 'should render static vnode without error',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, createStaticVNode } = (window as any).Vue
+ createApp({
+ render() {
+ return createStaticVNode('✅success: static vnode
')
+ },
+ }).mount('#app')
+ })
+ expect(await html('#app')).toContain('✅success: static vnode
')
+ },
+ E2E_TIMEOUT,
+ )
+
+ test(
+ 'should accept v-html with custom policy',
+ async () => {
+ await page().evaluate(() => {
+ const testPolicy = (window as any).trustedTypes.createPolicy('test', {
+ createHTML: (input: string): string => input,
+ })
+
+ const { createApp, ref, h } = (window as any).Vue
+ createApp({
+ setup() {
+ const msg = ref('✅success: v-html')
+ return function render() {
+ return h('div', { innerHTML: testPolicy.createHTML(msg.value) })
+ }
+ },
+ }).mount('#app')
+ })
+ expect(await html('#app')).toContain('✅success: v-html
')
+ },
+ E2E_TIMEOUT,
+ )
+})
diff --git a/packages/vue/__tests__/e2e/vModel.spec.ts b/packages/vue/__tests__/e2e/vModel.spec.ts
new file mode 100644
index 00000000000..e1a06bda532
--- /dev/null
+++ b/packages/vue/__tests__/e2e/vModel.spec.ts
@@ -0,0 +1,57 @@
+import path from 'node:path'
+import { setupPuppeteer } from './e2eUtils'
+
+const { page, click, isChecked } = setupPuppeteer()
+import { nextTick } from 'vue'
+
+beforeEach(async () => {
+ await page().addScriptTag({
+ path: path.resolve(__dirname, '../../dist/vue.global.js'),
+ })
+ await page().setContent(`
`)
+})
+
+// #12144
+test('checkbox click with v-model', async () => {
+ await page().evaluate(() => {
+ const { createApp } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ First
+
+
+
+
+ Second
+
+ `,
+ data() {
+ return {
+ first: true,
+ second: false,
+ }
+ },
+ methods: {
+ secondClick(this: any) {
+ this.first = false
+ },
+ },
+ }).mount('#app')
+ })
+
+ expect(await isChecked('#first')).toBe(true)
+ expect(await isChecked('#second')).toBe(false)
+ await click('#second')
+ await nextTick()
+ expect(await isChecked('#first')).toBe(false)
+ expect(await isChecked('#second')).toBe(true)
+})
diff --git a/packages/vue/__tests__/e2eUtils.ts b/packages/vue/__tests__/e2eUtils.ts
deleted file mode 100644
index 426257f51c5..00000000000
--- a/packages/vue/__tests__/e2eUtils.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import puppeteer from 'puppeteer'
-
-export const E2E_TIMEOUT = 30 * 1000
-
-const puppeteerOptions = process.env.CI
- ? { args: ['--no-sandbox', '--disable-setuid-sandbox'] }
- : {}
-
-const maxTries = 30
-export const timeout = (n: number) => new Promise(r => setTimeout(r, n))
-
-export async function expectByPolling(
- poll: () => Promise,
- expected: string
-) {
- for (let tries = 0; tries < maxTries; tries++) {
- const actual = (await poll()) || ''
- if (actual.indexOf(expected) > -1 || tries === maxTries - 1) {
- expect(actual).toMatch(expected)
- break
- } else {
- await timeout(50)
- }
- }
-}
-
-export function setupPuppeteer() {
- let browser: puppeteer.Browser
- let page: puppeteer.Page
-
- beforeAll(async () => {
- browser = await puppeteer.launch(puppeteerOptions)
- }, 20000)
-
- beforeEach(async () => {
- page = await browser.newPage()
-
- await page.evaluateOnNewDocument(() => {
- localStorage.clear()
- })
-
- page.on('console', e => {
- if (e.type() === 'error') {
- const err = e.args()[0]
- console.error(
- `Error from Puppeteer-loaded page:\n`,
- err.remoteObject().description
- )
- }
- })
- })
-
- afterEach(async () => {
- await page.close()
- })
-
- afterAll(async () => {
- await browser.close()
- })
-
- async function click(selector: string, options?: puppeteer.ClickOptions) {
- await page.click(selector, options)
- }
-
- async function count(selector: string) {
- return (await page.$$(selector)).length
- }
-
- async function text(selector: string) {
- return await page.$eval(selector, node => node.textContent)
- }
-
- async function value(selector: string) {
- return await page.$eval(selector, node => (node as HTMLInputElement).value)
- }
-
- async function html(selector: string) {
- return await page.$eval(selector, node => node.innerHTML)
- }
-
- async function classList(selector: string) {
- return await page.$eval(selector, (node: any) => [...node.classList])
- }
-
- async function children(selector: string) {
- return await page.$eval(selector, (node: any) => [...node.children])
- }
-
- async function isVisible(selector: string) {
- const display = await page.$eval(selector, node => {
- return window.getComputedStyle(node).display
- })
- return display !== 'none'
- }
-
- async function isChecked(selector: string) {
- return await page.$eval(
- selector,
- node => (node as HTMLInputElement).checked
- )
- }
-
- async function isFocused(selector: string) {
- return await page.$eval(selector, node => node === document.activeElement)
- }
-
- async function setValue(selector: string, value: string) {
- await page.$eval(
- selector,
- (node, value) => {
- ;(node as HTMLInputElement).value = value as string
- node.dispatchEvent(new Event('input'))
- },
- value
- )
- }
-
- async function typeValue(selector: string, value: string) {
- const el = (await page.$(selector))!
- await el.evaluate(node => ((node as HTMLInputElement).value = ''))
- await el.type(value)
- }
-
- async function enterValue(selector: string, value: string) {
- const el = (await page.$(selector))!
- await el.evaluate(node => ((node as HTMLInputElement).value = ''))
- await el.type(value)
- await el.press('Enter')
- }
-
- async function clearValue(selector: string) {
- return await page.$eval(
- selector,
- node => ((node as HTMLInputElement).value = '')
- )
- }
-
- function timeout(time: number) {
- return page.evaluate(time => {
- return new Promise(r => {
- setTimeout(r, time)
- })
- }, time)
- }
-
- function nextFrame() {
- return page.evaluate(() => {
- return new Promise(resolve => {
- requestAnimationFrame(() => {
- requestAnimationFrame(resolve)
- })
- })
- })
- }
-
- return {
- page: () => page,
- click,
- count,
- text,
- value,
- html,
- classList,
- children,
- isVisible,
- isChecked,
- isFocused,
- setValue,
- typeValue,
- enterValue,
- clearValue,
- timeout,
- nextFrame
- }
-}
diff --git a/packages/vue/__tests__/index.spec.ts b/packages/vue/__tests__/index.spec.ts
index a51c7fd97a9..0c969f15981 100644
--- a/packages/vue/__tests__/index.spec.ts
+++ b/packages/vue/__tests__/index.spec.ts
@@ -1,5 +1,5 @@
import { EMPTY_ARR } from '@vue/shared'
-import { createApp, ref, nextTick, reactive } from '../src'
+import { createApp, nextTick, reactive, ref } from '../src'
describe('compiler + runtime integration', () => {
it('should support runtime template compilation', () => {
@@ -8,9 +8,9 @@ describe('compiler + runtime integration', () => {
template: `{{ count }}`,
data() {
return {
- count: 0
+ count: 0,
}
- }
+ },
}
createApp(App).mount(container)
expect(container.innerHTML).toBe(`0`)
@@ -21,11 +21,11 @@ describe('compiler + runtime integration', () => {
const one = {
name: 'one',
template: 'one',
- created: jest.fn(),
- mounted: jest.fn(),
- activated: jest.fn(),
- deactivated: jest.fn(),
- unmounted: jest.fn()
+ created: vi.fn(),
+ mounted: vi.fn(),
+ activated: vi.fn(),
+ deactivated: vi.fn(),
+ unmounted: vi.fn(),
}
const toggle = ref(true)
@@ -38,12 +38,12 @@ describe('compiler + runtime integration', () => {
`,
data() {
return {
- toggle
+ toggle,
}
},
components: {
- One: one
- }
+ One: one,
+ },
}
createApp(App).mount(container)
expect(container.innerHTML).toBe(`one`)
@@ -83,9 +83,9 @@ describe('compiler + runtime integration', () => {
template: `#template`,
data() {
return {
- count: 0
+ count: 0,
}
- }
+ },
}
createApp(App).mount(container)
expect(container.innerHTML).toBe(`0`)
@@ -101,9 +101,9 @@ describe('compiler + runtime integration', () => {
template,
data() {
return {
- count: 0
+ count: 0,
}
- }
+ },
}
createApp(App).mount(container)
expect(container.innerHTML).toBe(`0`)
@@ -112,28 +112,28 @@ describe('compiler + runtime integration', () => {
it('should warn template compilation errors with codeframe', () => {
const container = document.createElement('div')
const App = {
- template: ``
+ template: `
`,
}
createApp(App).mount(container)
expect(
- `Template compilation error: Element is missing end tag`
+ `Template compilation error: Element is missing end tag`,
).toHaveBeenWarned()
expect(
`
1 |
- | ^`.trim()
+ | ^`.trim(),
).toHaveBeenWarned()
expect(`v-if/v-else-if is missing expression`).toHaveBeenWarned()
expect(
`
1 |
- | ^^^^`.trim()
+ | ^^^^`.trim(),
).toHaveBeenWarned()
})
it('should support custom element via config.isCustomElement (deprecated)', () => {
const app = createApp({
- template: '
'
+ template: '
',
})
const container = document.createElement('div')
app.config.isCustomElement = tag => tag === 'custom'
@@ -143,7 +143,7 @@ describe('compiler + runtime integration', () => {
it('should support custom element via config.compilerOptions.isCustomElement', () => {
const app = createApp({
- template: '
'
+ template: '
',
})
const container = document.createElement('div')
app.config.compilerOptions.isCustomElement = tag => tag === 'custom'
@@ -154,8 +154,8 @@ describe('compiler + runtime integration', () => {
it('should support using element innerHTML as template', () => {
const app = createApp({
data: () => ({
- msg: 'hello'
- })
+ msg: 'hello',
+ }),
})
const container = document.createElement('div')
container.innerHTML = '{{msg}}'
@@ -166,15 +166,15 @@ describe('compiler + runtime integration', () => {
it('should support selector of rootContainer', () => {
const container = document.createElement('div')
const origin = document.querySelector
- document.querySelector = jest.fn().mockReturnValue(container)
+ document.querySelector = vi.fn().mockReturnValue(container)
const App = {
template: `{{ count }}`,
data() {
return {
- count: 0
+ count: 0,
}
- }
+ },
}
createApp(App).mount('#app')
expect(container.innerHTML).toBe(`0`)
@@ -183,7 +183,7 @@ describe('compiler + runtime integration', () => {
it('should warn when template is not available', () => {
const app = createApp({
- template: {}
+ template: {},
})
const container = document.createElement('div')
app.mount(container)
@@ -192,30 +192,30 @@ describe('compiler + runtime integration', () => {
it('should warn when template is is not found', () => {
const app = createApp({
- template: '#not-exist-id'
+ template: '#not-exist-id',
})
const container = document.createElement('div')
app.mount(container)
expect(
- '[Vue warn]: Template element not found or is empty: #not-exist-id'
+ '[Vue warn]: Template element not found or is empty: #not-exist-id',
).toHaveBeenWarned()
})
it('should warn when container is not found', () => {
const origin = document.querySelector
- document.querySelector = jest.fn().mockReturnValue(null)
+ document.querySelector = vi.fn().mockReturnValue(null)
const App = {
template: `{{ count }}`,
data() {
return {
- count: 0
+ count: 0,
}
- }
+ },
}
createApp(App).mount('#not-exist-id')
expect(
- '[Vue warn]: Failed to mount app: mount target selector "#not-exist-id" returned null.'
+ '[Vue warn]: Failed to mount app: mount target selector "#not-exist-id" returned null.',
).toHaveBeenWarned()
document.querySelector = origin
})
@@ -226,7 +226,7 @@ describe('compiler + runtime integration', () => {
const target = document.createElement('div')
const count = ref(0)
const origin = document.querySelector
- document.querySelector = jest.fn().mockReturnValue(target)
+ document.querySelector = vi.fn().mockReturnValue(target)
const App = {
template: `
@@ -238,9 +238,9 @@ describe('compiler + runtime integration', () => {
`,
data() {
return {
- count
+ count,
}
- }
+ },
}
createApp(App).mount(container)
expect(container.innerHTML).toBe(``)
@@ -265,7 +265,7 @@ describe('compiler + runtime integration', () => {
setup() {
return { ok }
},
- template: `
`
+ template: `
`,
}
const container = document.createElement('div')
createApp(App).mount(container)
@@ -282,7 +282,7 @@ describe('compiler + runtime integration', () => {
setup() {
return { list }
},
- template: `
`
+ template: `
`,
}
const container = document.createElement('div')
createApp(App).mount(container)
@@ -296,7 +296,7 @@ describe('compiler + runtime integration', () => {
// #2413
it('EMPTY_ARR should not change', () => {
const App = {
- template: `
{{ v }}
`
+ template: `
{{ v }}
`,
}
const container = document.createElement('div')
createApp(App).mount(container)
@@ -305,7 +305,7 @@ describe('compiler + runtime integration', () => {
test('BigInt support', () => {
const app = createApp({
- template: `
{{ BigInt(BigInt(100000111)) + BigInt(2000000000n) * 30000000n }}
`
+ template: `
{{ BigInt(BigInt(100000111)) + BigInt(2000000000n) * 30000000n }}
`,
})
const root = document.createElement('div')
app.mount(root)
diff --git a/packages/vue/__tests__/mathmlNamespace.spec.ts b/packages/vue/__tests__/mathmlNamespace.spec.ts
new file mode 100644
index 00000000000..c3f8ab7ab3e
--- /dev/null
+++ b/packages/vue/__tests__/mathmlNamespace.spec.ts
@@ -0,0 +1,80 @@
+// MathML logic is technically dom-specific, but the logic is placed in core
+// because splitting it out of core would lead to unnecessary complexity in both
+// the renderer and compiler implementations.
+// Related files:
+// - runtime-core/src/renderer.ts
+// - compiler-core/src/transforms/transformElement.ts
+
+import { vtcKey } from '../../runtime-dom/src/components/Transition'
+import { h, nextTick, ref, render } from '../src'
+
+describe('MathML support', () => {
+ afterEach(() => {
+ document.body.innerHTML = ''
+ })
+
+ test('should mount elements with correct html namespace', () => {
+ const root = document.createElement('div')
+ document.body.appendChild(root)
+ const App = {
+ template: `
+
+
+
+
+ x
+ 2
+
+ +
+ y
+
+
+
+
+
+
+
+
+ `,
+ }
+ render(h(App), root)
+ const e0 = document.getElementById('e0')!
+ expect(e0.namespaceURI).toMatch('Math')
+ expect(e0.querySelector('#e1')!.namespaceURI).toMatch('Math')
+ expect(e0.querySelector('#e2')!.namespaceURI).toMatch('Math')
+ expect(e0.querySelector('#e3')!.namespaceURI).toMatch('Math')
+ expect(e0.querySelector('#e4')!.namespaceURI).toMatch('xhtml')
+ expect(e0.querySelector('#e5')!.namespaceURI).toMatch('svg')
+ })
+
+ test('should patch elements with correct namespaces', async () => {
+ const root = document.createElement('div')
+ document.body.appendChild(root)
+ const cls = ref('foo')
+ const App = {
+ setup: () => ({ cls }),
+ template: `
+
+ `,
+ }
+ render(h(App), root)
+ const f1 = document.querySelector('#f1')!
+ const f2 = document.querySelector('#f2')!
+ expect(f1.getAttribute('class')).toBe('foo')
+ expect(f2.className).toBe('foo')
+
+ // set a transition class on the
- which is only respected on non-svg
+ // patches
+ ;(f2 as any)[vtcKey] = ['baz']
+ cls.value = 'bar'
+ await nextTick()
+ expect(f1.getAttribute('class')).toBe('bar')
+ expect(f2.className).toBe('bar baz')
+ })
+})
diff --git a/packages/vue/__tests__/runtimeCompilerOptions.spec.ts b/packages/vue/__tests__/runtimeCompilerOptions.spec.ts
index 3222462fea3..b144be448d2 100644
--- a/packages/vue/__tests__/runtimeCompilerOptions.spec.ts
+++ b/packages/vue/__tests__/runtimeCompilerOptions.spec.ts
@@ -3,7 +3,7 @@ import { createApp } from 'vue'
describe('config.compilerOptions', () => {
test('isCustomElement', () => {
const app = createApp({
- template: `
`
+ template: `
`,
})
app.config.compilerOptions.isCustomElement = (tag: string) => tag === 'foo'
const root = document.createElement('div')
@@ -13,7 +13,7 @@ describe('config.compilerOptions', () => {
test('comments', () => {
const app = createApp({
- template: `
`
+ template: `
`,
})
app.config.compilerOptions.comments = true
// the comments option is only relevant in production mode
@@ -26,7 +26,7 @@ describe('config.compilerOptions', () => {
test('whitespace', () => {
const app = createApp({
- template: `
\n
`
+ template: `
\n
`,
})
app.config.compilerOptions.whitespace = 'preserve'
const root = document.createElement('div')
@@ -38,7 +38,7 @@ describe('config.compilerOptions', () => {
test('delimiters', () => {
const app = createApp({
data: () => ({ foo: 'hi' }),
- template: `[[ foo ]]`
+ template: `[[ foo ]]`,
})
app.config.compilerOptions.delimiters = [`[[`, `]]`]
const root = document.createElement('div')
@@ -52,8 +52,8 @@ describe('per-component compilerOptions', () => {
const app = createApp({
template: `
`,
compilerOptions: {
- isCustomElement: (tag: string) => tag === 'foo'
- }
+ isCustomElement: (tag: string) => tag === 'foo',
+ },
})
const root = document.createElement('div')
app.mount(root)
@@ -64,8 +64,8 @@ describe('per-component compilerOptions', () => {
const app = createApp({
template: `
`,
compilerOptions: {
- comments: true
- }
+ comments: true,
+ },
})
app.config.compilerOptions.comments = false
// the comments option is only relevant in production mode
@@ -80,8 +80,8 @@ describe('per-component compilerOptions', () => {
const app = createApp({
template: `
\n
`,
compilerOptions: {
- whitespace: 'preserve'
- }
+ whitespace: 'preserve',
+ },
})
const root = document.createElement('div')
app.mount(root)
@@ -94,8 +94,8 @@ describe('per-component compilerOptions', () => {
data: () => ({ foo: 'hi' }),
template: `[[ foo ]]`,
compilerOptions: {
- delimiters: [`[[`, `]]`]
- }
+ delimiters: [`[[`, `]]`],
+ },
})
const root = document.createElement('div')
app.mount(root)
diff --git a/packages/vue/__tests__/svgNamespace.spec.ts b/packages/vue/__tests__/svgNamespace.spec.ts
index 433e8d36d4c..978f9bbb1fc 100644
--- a/packages/vue/__tests__/svgNamespace.spec.ts
+++ b/packages/vue/__tests__/svgNamespace.spec.ts
@@ -5,10 +5,15 @@
// - runtime-core/src/renderer.ts
// - compiler-core/src/transforms/transformElement.ts
-import { render, h, ref, nextTick } from '../src'
+import { vtcKey } from '../../runtime-dom/src/components/Transition'
+import { h, nextTick, ref, render } from '../src'
describe('SVG support', () => {
- test('should mount elements with correct namespaces', () => {
+ afterEach(() => {
+ document.body.innerHTML = ''
+ })
+
+ test('should mount elements with correct html namespace', () => {
const root = document.createElement('div')
document.body.appendChild(root)
const App = {
@@ -17,10 +22,12 @@ describe('SVG support', () => {
+
+
- `
+ `,
}
render(h(App), root)
const e0 = document.getElementById('e0')!
@@ -28,6 +35,8 @@ describe('SVG support', () => {
expect(e0.querySelector('#e1')!.namespaceURI).toMatch('svg')
expect(e0.querySelector('#e2')!.namespaceURI).toMatch('svg')
expect(e0.querySelector('#e3')!.namespaceURI).toMatch('xhtml')
+ expect(e0.querySelector('#e4')!.namespaceURI).toMatch('svg')
+ expect(e0.querySelector('#e5')!.namespaceURI).toMatch('Math')
})
test('should patch elements with correct namespaces', async () => {
@@ -44,7 +53,7 @@ describe('SVG support', () => {
- `
+ `,
}
render(h(App), root)
const f1 = document.querySelector('#f1')!
@@ -54,7 +63,7 @@ describe('SVG support', () => {
// set a transition class on the
- which is only respected on non-svg
// patches
- ;(f2 as any)._vtc = ['baz']
+ ;(f2 as any)[vtcKey] = ['baz']
cls.value = 'bar'
await nextTick()
expect(f1.getAttribute('class')).toBe('bar')
diff --git a/packages/vue/api-extractor.json b/packages/vue/api-extractor.json
deleted file mode 100644
index b677d51cd8d..00000000000
--- a/packages/vue/api-extractor.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "../../api-extractor.json",
- "mainEntryPointFilePath": "./dist/packages/
/src/index.d.ts",
- "dtsRollup": {
- "publicTrimmedFilePath": "./dist/.d.ts"
- }
-}
diff --git a/packages/vue/compiler-sfc/index.browser.js b/packages/vue/compiler-sfc/index.browser.js
new file mode 100644
index 00000000000..774f9da2742
--- /dev/null
+++ b/packages/vue/compiler-sfc/index.browser.js
@@ -0,0 +1 @@
+module.exports = require('@vue/compiler-sfc')
diff --git a/packages/vue/compiler-sfc/index.browser.mjs b/packages/vue/compiler-sfc/index.browser.mjs
new file mode 100644
index 00000000000..3c30abc8ccf
--- /dev/null
+++ b/packages/vue/compiler-sfc/index.browser.mjs
@@ -0,0 +1 @@
+export * from '@vue/compiler-sfc'
diff --git a/packages/vue/compiler-sfc/index.d.mts b/packages/vue/compiler-sfc/index.d.mts
new file mode 100644
index 00000000000..3c30abc8ccf
--- /dev/null
+++ b/packages/vue/compiler-sfc/index.d.mts
@@ -0,0 +1 @@
+export * from '@vue/compiler-sfc'
diff --git a/packages/vue/compiler-sfc/index.js b/packages/vue/compiler-sfc/index.js
index 774f9da2742..2b85ad129ef 100644
--- a/packages/vue/compiler-sfc/index.js
+++ b/packages/vue/compiler-sfc/index.js
@@ -1 +1,3 @@
module.exports = require('@vue/compiler-sfc')
+
+require('./register-ts.js')
diff --git a/packages/vue/compiler-sfc/index.mjs b/packages/vue/compiler-sfc/index.mjs
index 8df9a989d18..ae5d6e8e5ca 100644
--- a/packages/vue/compiler-sfc/index.mjs
+++ b/packages/vue/compiler-sfc/index.mjs
@@ -1 +1,3 @@
-export * from '@vue/compiler-sfc'
\ No newline at end of file
+export * from '@vue/compiler-sfc'
+
+import './register-ts.js'
diff --git a/packages/vue/compiler-sfc/package.json b/packages/vue/compiler-sfc/package.json
index 1b15fb844ac..4cf44a46cb3 100644
--- a/packages/vue/compiler-sfc/package.json
+++ b/packages/vue/compiler-sfc/package.json
@@ -1,5 +1,4 @@
{
"main": "index.js",
- "module": "index.mjs",
- "types": "index.d.ts"
-}
\ No newline at end of file
+ "module": "index.mjs"
+}
diff --git a/packages/vue/compiler-sfc/register-ts.js b/packages/vue/compiler-sfc/register-ts.js
new file mode 100644
index 00000000000..36de2a350d6
--- /dev/null
+++ b/packages/vue/compiler-sfc/register-ts.js
@@ -0,0 +1,3 @@
+if (typeof require !== 'undefined') {
+ require('@vue/compiler-sfc').registerTS(() => require('typescript'))
+}
diff --git a/packages/vue/examples/classic/commits.html b/packages/vue/examples/classic/commits.html
index 811f0edc258..601f49544cd 100644
--- a/packages/vue/examples/classic/commits.html
+++ b/packages/vue/examples/classic/commits.html
@@ -3,59 +3,68 @@
diff --git a/packages/vue/examples/classic/grid.html b/packages/vue/examples/classic/grid.html
index 39fbc92080f..60272b9acd4 100644
--- a/packages/vue/examples/classic/grid.html
+++ b/packages/vue/examples/classic/grid.html
@@ -26,142 +26,141 @@
-
- Search
-
-
+ Search
+
diff --git a/packages/vue/examples/classic/markdown.html b/packages/vue/examples/classic/markdown.html
index f70a75d692e..a51f4c6ca39 100644
--- a/packages/vue/examples/classic/markdown.html
+++ b/packages/vue/examples/classic/markdown.html
@@ -8,55 +8,58 @@
diff --git a/packages/vue/examples/classic/svg.html b/packages/vue/examples/classic/svg.html
index f2a1c19bff1..a0e25075ec5 100644
--- a/packages/vue/examples/classic/svg.html
+++ b/packages/vue/examples/classic/svg.html
@@ -1,37 +1,33 @@
@@ -49,23 +45,25 @@
@@ -77,86 +75,92 @@
{{stat.label}}
-
+
{{stat.value}}
X
-
+
Add a Stat
{{ stats }}
diff --git a/packages/vue/examples/classic/todomvc.html b/packages/vue/examples/classic/todomvc.html
index 7a53a598f92..56a4932ec8e 100644
--- a/packages/vue/examples/classic/todomvc.html
+++ b/packages/vue/examples/classic/todomvc.html
@@ -1,49 +1,81 @@
-
+
@@ -51,146 +83,146 @@ todos
diff --git a/packages/vue/examples/classic/tree.html b/packages/vue/examples/classic/tree.html
index c447b76ca76..8d7b13d7408 100644
--- a/packages/vue/examples/classic/tree.html
+++ b/packages/vue/examples/classic/tree.html
@@ -22,43 +22,42 @@
(You can double click on an item to turn it into a folder.)
@@ -69,43 +68,37 @@
diff --git a/packages/vue/examples/composition/grid.html b/packages/vue/examples/composition/grid.html
index b2849fad3bc..8af8817fd71 100644
--- a/packages/vue/examples/composition/grid.html
+++ b/packages/vue/examples/composition/grid.html
@@ -26,148 +26,147 @@
-
- Search
-
-
+ Search
+
diff --git a/packages/vue/examples/composition/markdown.html b/packages/vue/examples/composition/markdown.html
index 151a8a8c141..e7a8550ca67 100644
--- a/packages/vue/examples/composition/markdown.html
+++ b/packages/vue/examples/composition/markdown.html
@@ -8,55 +8,62 @@
diff --git a/packages/vue/examples/composition/svg.html b/packages/vue/examples/composition/svg.html
index 4bdca965960..67e29a6b7e1 100644
--- a/packages/vue/examples/composition/svg.html
+++ b/packages/vue/examples/composition/svg.html
@@ -1,39 +1,37 @@
@@ -51,24 +49,26 @@
@@ -80,93 +80,99 @@
{{stat.label}}
-
+
{{stat.value}}
X
-
+
Add a Stat
{{ stats }}
diff --git a/packages/vue/examples/composition/todomvc.html b/packages/vue/examples/composition/todomvc.html
index 37bfeb86cb0..510e22b1b1f 100644
--- a/packages/vue/examples/composition/todomvc.html
+++ b/packages/vue/examples/composition/todomvc.html
@@ -1,51 +1,86 @@
-
+
@@ -53,154 +88,155 @@ todos
diff --git a/packages/vue/examples/composition/tree.html b/packages/vue/examples/composition/tree.html
index a80a8ac964a..75330bf11f0 100644
--- a/packages/vue/examples/composition/tree.html
+++ b/packages/vue/examples/composition/tree.html
@@ -22,46 +22,46 @@
(You can double click on an item to turn it into a folder.)
@@ -72,43 +72,37 @@
diff --git a/packages/vue/examples/transition/modal.html b/packages/vue/examples/transition/modal.html
index 03180539a4c..96a16cfdabe 100644
--- a/packages/vue/examples/transition/modal.html
+++ b/packages/vue/examples/transition/modal.html
@@ -33,10 +33,10 @@
@@ -56,57 +56,57 @@ custom header
diff --git a/packages/vue/index.mjs b/packages/vue/index.mjs
index 8b43612483a..fcb9204cbc7 100644
--- a/packages/vue/index.mjs
+++ b/packages/vue/index.mjs
@@ -1 +1 @@
-export * from './index.js'
\ No newline at end of file
+export * from './index.js'
diff --git a/packages/vue/jsx-runtime/index.d.ts b/packages/vue/jsx-runtime/index.d.ts
new file mode 100644
index 00000000000..af5ffe2ac24
--- /dev/null
+++ b/packages/vue/jsx-runtime/index.d.ts
@@ -0,0 +1,25 @@
+/* eslint-disable @typescript-eslint/prefer-ts-expect-error */
+import type { NativeElements, ReservedProps, VNode } from '@vue/runtime-dom'
+
+/**
+ * JSX namespace for usage with @jsxImportsSource directive
+ * when ts compilerOptions.jsx is 'react-jsx' or 'react-jsxdev'
+ * https://www.typescriptlang.org/tsconfig#jsxImportSource
+ */
+export { h as jsx, h as jsxDEV, Fragment, h as jsxs } from '@vue/runtime-dom'
+
+export namespace JSX {
+ export interface Element extends VNode {}
+ export interface ElementClass {
+ $props: {}
+ }
+ export interface ElementAttributesProperty {
+ $props: {}
+ }
+ export interface IntrinsicElements extends NativeElements {
+ // allow arbitrary elements
+ // @ts-ignore suppress ts:2374 = Duplicate string index signature.
+ [name: string]: any
+ }
+ export interface IntrinsicAttributes extends ReservedProps {}
+}
diff --git a/packages/vue/jsx-runtime/index.js b/packages/vue/jsx-runtime/index.js
new file mode 100644
index 00000000000..73b137d5261
--- /dev/null
+++ b/packages/vue/jsx-runtime/index.js
@@ -0,0 +1,15 @@
+const { h, Fragment } = require('vue')
+
+function jsx(type, props, key) {
+ const { children } = props
+ delete props.children
+ if (arguments.length > 2) {
+ props.key = key
+ }
+ return h(type, props, children)
+}
+
+exports.jsx = jsx
+exports.jsxs = jsx
+exports.jsxDEV = jsx
+exports.Fragment = Fragment
diff --git a/packages/vue/jsx-runtime/index.mjs b/packages/vue/jsx-runtime/index.mjs
new file mode 100644
index 00000000000..e2528cba447
--- /dev/null
+++ b/packages/vue/jsx-runtime/index.mjs
@@ -0,0 +1,12 @@
+import { h, Fragment } from 'vue'
+
+function jsx(type, props, key) {
+ const { children } = props
+ delete props.children
+ if (arguments.length > 2) {
+ props.key = key
+ }
+ return h(type, props, children)
+}
+
+export { Fragment, jsx, jsx as jsxs, jsx as jsxDEV }
diff --git a/packages/vue/jsx-runtime/package.json b/packages/vue/jsx-runtime/package.json
new file mode 100644
index 00000000000..778c7ebf51c
--- /dev/null
+++ b/packages/vue/jsx-runtime/package.json
@@ -0,0 +1,5 @@
+{
+ "main": "index.js",
+ "module": "index.mjs",
+ "types": "index.d.ts"
+}
diff --git a/packages/vue/jsx.d.ts b/packages/vue/jsx.d.ts
new file mode 100644
index 00000000000..1fa1e326676
--- /dev/null
+++ b/packages/vue/jsx.d.ts
@@ -0,0 +1,22 @@
+/* eslint-disable @typescript-eslint/prefer-ts-expect-error */
+// global JSX namespace registration
+// somehow we have to copy=pase the jsx-runtime types here to make TypeScript happy
+import type { NativeElements, ReservedProps, VNode } from '@vue/runtime-dom'
+
+declare global {
+ namespace JSX {
+ export interface Element extends VNode {}
+ export interface ElementClass {
+ $props: {}
+ }
+ export interface ElementAttributesProperty {
+ $props: {}
+ }
+ export interface IntrinsicElements extends NativeElements {
+ // allow arbitrary elements
+ // @ts-ignore suppress ts:2374 = Duplicate string index signature.
+ [name: string]: any
+ }
+ export interface IntrinsicAttributes extends ReservedProps {}
+ }
+}
diff --git a/packages/vue/macros-global.d.ts b/packages/vue/macros-global.d.ts
deleted file mode 100644
index 9b6f5a5392f..00000000000
--- a/packages/vue/macros-global.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import {
- $ as _$,
- $$ as _$$,
- $ref as _$ref,
- $shallowRef as _$shallowRef,
- $computed as _$computed,
- $customRef as _$customRef,
- $toRef as _$toRef
-} from './macros'
-
-declare global {
- const $: typeof _$
- const $$: typeof _$$
- const $ref: typeof _$ref
- const $shallowRef: typeof _$shallowRef
- const $computed: typeof _$computed
- const $customRef: typeof _$customRef
- const $toRef: typeof _$toRef
-}
diff --git a/packages/vue/macros.d.ts b/packages/vue/macros.d.ts
deleted file mode 100644
index 68ccda6ee23..00000000000
--- a/packages/vue/macros.d.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import {
- Ref,
- UnwrapRef,
- ComputedRef,
- WritableComputedOptions,
- DebuggerOptions,
- WritableComputedRef,
- CustomRefFactory
-} from '@vue/runtime-dom'
-
-export declare const RefType: unique symbol
-
-export declare const enum RefTypes {
- Ref = 1,
- ComputedRef = 2,
- WritableComputedRef = 3
-}
-
-type RefValue
= T extends null | undefined ? T : ReactiveVariable
-
-type ReactiveVariable = T & { [RefType]?: RefTypes.Ref }
-
-type ComputedRefValue = T extends null | undefined ? T : ComputedVariable
-
-type ComputedVariable = T & { [RefType]?: RefTypes.ComputedRef }
-
-type WritableComputedRefValue = T extends null | undefined
- ? T
- : WritableComputedVariable
-
-type WritableComputedVariable = T & {
- [RefType]?: RefTypes.WritableComputedRef
-}
-
-type NormalObject = T & { [RefType]?: never }
-
-/**
- * Vue ref transform macro for binding refs as reactive variables.
- */
-export declare function $(arg: ComputedRef): ComputedRefValue
-export declare function $(
- arg: WritableComputedRef
-): WritableComputedRefValue
-export declare function $(arg: Ref): RefValue
-export declare function $(arg?: T): DestructureRefs
-
-type DestructureRefs = {
- [K in keyof T]: T[K] extends ComputedRef
- ? ComputedRefValue
- : T[K] extends WritableComputedRef
- ? WritableComputedRefValue
- : T[K] extends Ref
- ? RefValue
- : T[K]
-}
-
-/**
- * Vue ref transform macro for accessing underlying refs of reactive variables.
- */
-export declare function $$(arg: NormalObject): ToRawRefs
-export declare function $$(value: RefValue): Ref
-export declare function $$(value: ComputedRefValue): ComputedRef
-export declare function $$(
- value: WritableComputedRefValue
-): WritableComputedRef
-
-type ToRawRefs = {
- [K in keyof T]: T[K] extends RefValue
- ? Ref
- : T[K] extends ComputedRefValue
- ? ComputedRef
- : T[K] extends WritableComputedRefValue
- ? WritableComputedRef
- : T[K] extends object
- ? T[K] extends
- | Function
- | Map
- | Set
- | WeakMap
- | WeakSet
- ? T[K]
- : ToRawRefs
- : T[K]
-}
-
-export declare function $ref(): RefValue
-export declare function $ref(arg: T | Ref): RefValue>
-
-export declare function $shallowRef(): RefValue
-export declare function $shallowRef(arg: T): RefValue
-
-export declare function $toRef(
- object: T,
- key: K
-): RefValue
-
-export declare function $toRef(
- object: T,
- key: K,
- defaultValue: T[K]
-): RefValue>
-
-export declare function $customRef(factory: CustomRefFactory): RefValue
-
-export declare function $computed(
- getter: () => T,
- debuggerOptions?: DebuggerOptions
-): ComputedRefValue
-export declare function $computed(
- options: WritableComputedOptions,
- debuggerOptions?: DebuggerOptions
-): WritableComputedRefValue
diff --git a/packages/vue/package.json b/packages/vue/package.json
index 63228a40154..897bdec9e24 100644
--- a/packages/vue/package.json
+++ b/packages/vue/package.json
@@ -1,6 +1,6 @@
{
"name": "vue",
- "version": "3.2.45",
+ "version": "3.5.18",
"description": "The progressive JavaScript framework for building modern web UI.",
"main": "index.js",
"module": "dist/vue.runtime.esm-bundler.js",
@@ -13,34 +13,61 @@
"dist",
"compiler-sfc",
"server-renderer",
- "macros.d.ts",
- "macros-global.d.ts",
- "ref-macros.d.ts"
+ "jsx-runtime",
+ "jsx.d.ts"
],
"exports": {
".": {
"import": {
+ "types": "./dist/vue.d.mts",
"node": "./index.mjs",
"default": "./dist/vue.runtime.esm-bundler.js"
},
- "require": "./index.js",
- "types": "./dist/vue.d.ts"
+ "require": {
+ "types": "./dist/vue.d.ts",
+ "node": {
+ "production": "./dist/vue.cjs.prod.js",
+ "development": "./dist/vue.cjs.js",
+ "default": "./index.js"
+ },
+ "default": "./index.js"
+ }
},
"./server-renderer": {
- "import": "./server-renderer/index.mjs",
- "require": "./server-renderer/index.js",
- "types": "./server-renderer/index.d.ts"
+ "import": {
+ "types": "./server-renderer/index.d.mts",
+ "default": "./server-renderer/index.mjs"
+ },
+ "require": {
+ "types": "./server-renderer/index.d.ts",
+ "default": "./server-renderer/index.js"
+ }
},
"./compiler-sfc": {
- "import": "./compiler-sfc/index.mjs",
- "require": "./compiler-sfc/index.js",
- "types": "./compiler-sfc/index.d.ts"
+ "import": {
+ "types": "./compiler-sfc/index.d.mts",
+ "browser": "./compiler-sfc/index.browser.mjs",
+ "default": "./compiler-sfc/index.mjs"
+ },
+ "require": {
+ "types": "./compiler-sfc/index.d.ts",
+ "browser": "./compiler-sfc/index.browser.js",
+ "default": "./compiler-sfc/index.js"
+ }
},
+ "./jsx-runtime": {
+ "types": "./jsx-runtime/index.d.ts",
+ "import": "./jsx-runtime/index.mjs",
+ "require": "./jsx-runtime/index.js"
+ },
+ "./jsx-dev-runtime": {
+ "types": "./jsx-runtime/index.d.ts",
+ "import": "./jsx-runtime/index.mjs",
+ "require": "./jsx-runtime/index.js"
+ },
+ "./jsx": "./jsx.d.ts",
"./dist/*": "./dist/*",
- "./package.json": "./package.json",
- "./macros": "./macros.d.ts",
- "./macros-global": "./macros-global.d.ts",
- "./ref-macros": "./ref-macros.d.ts"
+ "./package.json": "./package.json"
},
"buildOptions": {
"name": "Vue",
@@ -68,10 +95,18 @@
},
"homepage": "https://github.com/vuejs/core/tree/main/packages/vue#readme",
"dependencies": {
- "@vue/shared": "3.2.45",
- "@vue/compiler-dom": "3.2.45",
- "@vue/runtime-dom": "3.2.45",
- "@vue/compiler-sfc": "3.2.45",
- "@vue/server-renderer": "3.2.45"
+ "@vue/shared": "workspace:*",
+ "@vue/compiler-dom": "workspace:*",
+ "@vue/runtime-dom": "workspace:*",
+ "@vue/compiler-sfc": "workspace:*",
+ "@vue/server-renderer": "workspace:*"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
}
diff --git a/packages/vue/ref-macros.d.ts b/packages/vue/ref-macros.d.ts
deleted file mode 100644
index 6afce7f70a3..00000000000
--- a/packages/vue/ref-macros.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// TODO deprecated file - to be removed when out of experimental
-import './macros-global'
diff --git a/packages/vue/server-renderer/index.d.mts b/packages/vue/server-renderer/index.d.mts
new file mode 100644
index 00000000000..ac614729c75
--- /dev/null
+++ b/packages/vue/server-renderer/index.d.mts
@@ -0,0 +1 @@
+export * from '@vue/server-renderer'
diff --git a/packages/vue/server-renderer/index.mjs b/packages/vue/server-renderer/index.mjs
index 3e081c15a23..ac614729c75 100644
--- a/packages/vue/server-renderer/index.mjs
+++ b/packages/vue/server-renderer/index.mjs
@@ -1 +1 @@
-export * from '@vue/server-renderer'
\ No newline at end of file
+export * from '@vue/server-renderer'
diff --git a/packages/vue/server-renderer/package.json b/packages/vue/server-renderer/package.json
index 1b15fb844ac..4cf44a46cb3 100644
--- a/packages/vue/server-renderer/package.json
+++ b/packages/vue/server-renderer/package.json
@@ -1,5 +1,4 @@
{
"main": "index.js",
- "module": "index.mjs",
- "types": "index.d.ts"
-}
\ No newline at end of file
+ "module": "index.mjs"
+}
diff --git a/packages/vue/src/dev.ts b/packages/vue/src/dev.ts
index 99ba49a2085..a9ad81e3ba5 100644
--- a/packages/vue/src/dev.ts
+++ b/packages/vue/src/dev.ts
@@ -1,11 +1,11 @@
import { initCustomFormatter } from '@vue/runtime-dom'
-export function initDev() {
+export function initDev(): void {
if (__BROWSER__) {
if (!__ESM_BUNDLER__) {
console.info(
`You are running a development build of Vue.\n` +
- `Make sure to use the production build (*.prod.js) when deploying for production.`
+ `Make sure to use the production build (*.prod.js) when deploying for production.`,
)
}
diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts
index 8215be7476e..785f3fd4bb4 100644
--- a/packages/vue/src/index.ts
+++ b/packages/vue/src/index.ts
@@ -1,11 +1,25 @@
// This entry is the "full-build" that includes both the runtime
// and the compiler, and supports on-the-fly compilation of the template option.
import { initDev } from './dev'
-import { compile, CompilerOptions, CompilerError } from '@vue/compiler-dom'
-import { registerRuntimeCompiler, RenderFunction, warn } from '@vue/runtime-dom'
+import {
+ type CompilerError,
+ type CompilerOptions,
+ compile,
+} from '@vue/compiler-dom'
+import {
+ type RenderFunction,
+ registerRuntimeCompiler,
+ warn,
+} from '@vue/runtime-dom'
import * as runtimeDom from '@vue/runtime-dom'
-import { isString, NOOP, generateCodeFrame, extend } from '@vue/shared'
-import { InternalRenderFunction } from 'packages/runtime-core/src/component'
+import {
+ NOOP,
+ extend,
+ genCacheKey,
+ generateCodeFrame,
+ isString,
+} from '@vue/shared'
+import type { InternalRenderFunction } from 'packages/runtime-core/src/component'
if (__DEV__) {
initDev()
@@ -15,7 +29,7 @@ const compileCache: Record = Object.create(null)
function compileToFunction(
template: string | HTMLElement,
- options?: CompilerOptions
+ options?: CompilerOptions,
): RenderFunction {
if (!isString(template)) {
if (template.nodeType) {
@@ -26,7 +40,7 @@ function compileToFunction(
}
}
- const key = template
+ const key = genCacheKey(template, options)
const cached = compileCache[key]
if (cached) {
return cached
@@ -48,9 +62,9 @@ function compileToFunction(
{
hoistStatic: true,
onError: __DEV__ ? onError : undefined,
- onWarn: __DEV__ ? e => onError(e, true) : NOOP
+ onWarn: __DEV__ ? e => onError(e, true) : NOOP,
} as CompilerOptions,
- options
+ options,
)
if (!opts.isCustomElement && typeof customElements !== 'undefined') {
@@ -68,7 +82,7 @@ function compileToFunction(
generateCodeFrame(
template as string,
err.loc.start.offset,
- err.loc.end.offset
+ err.loc.end.offset,
)
warn(codeFrame ? `${message}\n${codeFrame}` : message)
}
diff --git a/packages/vue/src/runtime.ts b/packages/vue/src/runtime.ts
index 7fe70670a5e..76f5fc74e25 100644
--- a/packages/vue/src/runtime.ts
+++ b/packages/vue/src/runtime.ts
@@ -9,17 +9,17 @@ if (__DEV__) {
export * from '@vue/runtime-dom'
-export const compile = () => {
+export const compile = (): void => {
if (__DEV__) {
warn(
`Runtime compilation is not supported in this build of Vue.` +
(__ESM_BUNDLER__
? ` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".`
: __ESM_BROWSER__
- ? ` Use "vue.esm-browser.js" instead.`
- : __GLOBAL__
- ? ` Use "vue.global.js" instead.`
- : ``) /* should not happen */
+ ? ` Use "vue.esm-browser.js" instead.`
+ : __GLOBAL__
+ ? ` Use "vue.global.js" instead.`
+ : ``) /* should not happen */,
)
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 98d9440e181..3bc2d0579b4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,6202 +1,5935 @@
-lockfileVersion: 5.4
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+catalogs:
+ default:
+ '@babel/parser':
+ specifier: ^7.28.0
+ version: 7.28.0
+ '@babel/types':
+ specifier: ^7.28.1
+ version: 7.28.1
+ '@vitejs/plugin-vue':
+ specifier: ^5.2.4
+ version: 5.2.4
+ estree-walker:
+ specifier: ^2.0.2
+ version: 2.0.2
+ magic-string:
+ specifier: ^0.30.17
+ version: 0.30.17
+ source-map-js:
+ specifier: ^1.2.1
+ version: 1.2.1
+ vite:
+ specifier: ^5.4.15
+ version: 5.4.15
importers:
.:
- specifiers:
- '@babel/types': ^7.12.0
- '@esbuild-plugins/node-modules-polyfill': ^0.1.4
- '@microsoft/api-extractor': ~7.20.0
- '@rollup/plugin-commonjs': ^23.0.2
- '@rollup/plugin-json': ^5.0.1
- '@rollup/plugin-node-resolve': ^15.0.1
- '@rollup/plugin-replace': ^5.0.1
- '@rollup/plugin-terser': ^0.1.0
- '@types/hash-sum': ^1.0.0
- '@types/jest': ^29.2.2
- '@types/node': ^16.4.7
- '@typescript-eslint/parser': ^5.23.0
- '@vue/consolidate': 0.17.3
- '@vue/reactivity': workspace:*
- '@vue/runtime-core': workspace:*
- '@vue/runtime-dom': workspace:*
- brotli: ^1.3.2
- chalk: ^4.1.0
- conventional-changelog-cli: ^2.0.31
- csstype: ^3.0.3
- enquirer: ^2.3.2
- esbuild: ^0.15.13
- eslint: ^7.7.0
- eslint-plugin-jest: 26.1.5
- execa: ^4.0.2
- fs-extra: ^9.0.1
- jest: ^29.3.1
- jest-environment-jsdom: ^29.3.1
- lint-staged: ^10.2.10
- lodash: ^4.17.15
- marked: ^4.0.10
- minimist: ^1.2.0
- npm-run-all: ^4.1.5
- prettier: ^2.7.1
- pug: ^3.0.1
- puppeteer: ^19.2.2
- rollup: ~3.2.3
- rollup-plugin-node-builtins: ^2.1.2
- rollup-plugin-node-globals: ^1.4.0
- rollup-plugin-polyfill-node: ^0.11.0
- rollup-plugin-typescript2: ^0.34.1
- semver: ^7.3.2
- serve: ^12.0.0
- simple-git-hooks: ^2.8.1
- terser: ^5.15.1
- todomvc-app-css: ^2.3.0
- ts-jest: ^29.0.3
- tslib: ^2.4.0
- typescript: ^4.8.0
- vite: ^3.0.0
- vue: workspace:*
devDependencies:
- '@babel/types': 7.16.0
- '@esbuild-plugins/node-modules-polyfill': 0.1.4_esbuild@0.15.13
- '@microsoft/api-extractor': 7.20.1
- '@rollup/plugin-commonjs': 23.0.2_rollup@3.2.3
- '@rollup/plugin-json': 5.0.1_rollup@3.2.3
- '@rollup/plugin-node-resolve': 15.0.1_rollup@3.2.3
- '@rollup/plugin-replace': 5.0.1_rollup@3.2.3
- '@rollup/plugin-terser': 0.1.0_rollup@3.2.3
- '@types/hash-sum': 1.0.0
- '@types/jest': 29.2.2
- '@types/node': 16.11.12
- '@typescript-eslint/parser': 5.23.0_td6yqss6ra3qoebludh4ctrhym
- '@vue/consolidate': 0.17.3
- '@vue/reactivity': link:packages/reactivity
- '@vue/runtime-core': link:packages/runtime-core
- '@vue/runtime-dom': link:packages/runtime-dom
- brotli: 1.3.2
- chalk: 4.1.2
- conventional-changelog-cli: 2.1.1
- csstype: 3.0.10
- enquirer: 2.3.6
- esbuild: 0.15.13
- eslint: 7.32.0
- eslint-plugin-jest: 26.1.5_h6y6ce27mgasm6fmt6a3uqj6ne
- execa: 4.1.0
- fs-extra: 9.1.0
- jest: 29.3.1_@types+node@16.11.12
- jest-environment-jsdom: 29.3.1
- lint-staged: 10.5.4
- lodash: 4.17.21
- marked: 4.0.10
- minimist: 1.2.5
- npm-run-all: 4.1.5
- prettier: 2.7.1
- pug: 3.0.2
- puppeteer: 19.2.2
- rollup: 3.2.3
- rollup-plugin-node-builtins: 2.1.2
- rollup-plugin-node-globals: 1.4.0
- rollup-plugin-polyfill-node: 0.11.0_rollup@3.2.3
- rollup-plugin-typescript2: 0.34.1_6q6ezahorvzz2ktdwmpggsjixa
- semver: 7.3.5
- serve: 12.0.1
- simple-git-hooks: 2.8.1
- terser: 5.15.1
- todomvc-app-css: 2.4.1
- ts-jest: 29.0.3_ok3qeoyoqhjjfsg3bzze2edrgy
- tslib: 2.4.0
- typescript: 4.8.2
- vite: 3.0.9_terser@5.15.1
- vue: link:packages/vue
+ '@babel/parser':
+ specifier: 'catalog:'
+ version: 7.28.0
+ '@babel/types':
+ specifier: 'catalog:'
+ version: 7.28.1
+ '@rollup/plugin-alias':
+ specifier: ^5.1.1
+ version: 5.1.1(rollup@4.45.1)
+ '@rollup/plugin-commonjs':
+ specifier: ^28.0.6
+ version: 28.0.6(rollup@4.45.1)
+ '@rollup/plugin-json':
+ specifier: ^6.1.0
+ version: 6.1.0(rollup@4.45.1)
+ '@rollup/plugin-node-resolve':
+ specifier: ^16.0.1
+ version: 16.0.1(rollup@4.45.1)
+ '@rollup/plugin-replace':
+ specifier: 5.0.4
+ version: 5.0.4(rollup@4.45.1)
+ '@swc/core':
+ specifier: ^1.13.1
+ version: 1.13.1
+ '@types/hash-sum':
+ specifier: ^1.0.2
+ version: 1.0.2
+ '@types/node':
+ specifier: ^22.16.5
+ version: 22.16.5
+ '@types/semver':
+ specifier: ^7.7.0
+ version: 7.7.0
+ '@types/serve-handler':
+ specifier: ^6.1.4
+ version: 6.1.4
+ '@vitest/coverage-v8':
+ specifier: ^3.1.4
+ version: 3.1.4(vitest@3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2))
+ '@vitest/eslint-plugin':
+ specifier: ^1.2.1
+ version: 1.2.1(eslint@9.27.0)(typescript@5.6.3)(vitest@3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2))
+ '@vue/consolidate':
+ specifier: 1.0.0
+ version: 1.0.0
+ conventional-changelog-cli:
+ specifier: ^5.0.0
+ version: 5.0.0(conventional-commits-filter@5.0.0)
+ enquirer:
+ specifier: ^2.4.1
+ version: 2.4.1
+ esbuild:
+ specifier: ^0.25.8
+ version: 0.25.8
+ esbuild-plugin-polyfill-node:
+ specifier: ^0.3.0
+ version: 0.3.0(esbuild@0.25.8)
+ eslint:
+ specifier: ^9.27.0
+ version: 9.27.0
+ eslint-plugin-import-x:
+ specifier: ^4.13.1
+ version: 4.13.1(eslint@9.27.0)(typescript@5.6.3)
+ estree-walker:
+ specifier: 'catalog:'
+ version: 2.0.2
+ jsdom:
+ specifier: ^26.1.0
+ version: 26.1.0
+ lint-staged:
+ specifier: ^16.0.0
+ version: 16.0.0
+ lodash:
+ specifier: ^4.17.21
+ version: 4.17.21
+ magic-string:
+ specifier: ^0.30.17
+ version: 0.30.17
+ markdown-table:
+ specifier: ^3.0.4
+ version: 3.0.4
+ marked:
+ specifier: 13.0.3
+ version: 13.0.3
+ npm-run-all2:
+ specifier: ^7.0.2
+ version: 7.0.2
+ picocolors:
+ specifier: ^1.1.1
+ version: 1.1.1
+ prettier:
+ specifier: ^3.5.3
+ version: 3.5.3
+ pretty-bytes:
+ specifier: ^6.1.1
+ version: 6.1.1
+ pug:
+ specifier: ^3.0.3
+ version: 3.0.3
+ puppeteer:
+ specifier: ~24.9.0
+ version: 24.9.0(typescript@5.6.3)
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
+ rollup:
+ specifier: ^4.45.1
+ version: 4.45.1
+ rollup-plugin-dts:
+ specifier: ^6.2.1
+ version: 6.2.1(rollup@4.45.1)(typescript@5.6.3)
+ rollup-plugin-esbuild:
+ specifier: ^6.2.1
+ version: 6.2.1(esbuild@0.25.8)(rollup@4.45.1)
+ rollup-plugin-polyfill-node:
+ specifier: ^0.13.0
+ version: 0.13.0(rollup@4.45.1)
+ semver:
+ specifier: ^7.7.2
+ version: 7.7.2
+ serve:
+ specifier: ^14.2.4
+ version: 14.2.4
+ serve-handler:
+ specifier: ^6.1.6
+ version: 6.1.6
+ simple-git-hooks:
+ specifier: ^2.13.0
+ version: 2.13.0
+ todomvc-app-css:
+ specifier: ^2.4.3
+ version: 2.4.3
+ tslib:
+ specifier: ^2.8.1
+ version: 2.8.1
+ typescript:
+ specifier: ~5.6.2
+ version: 5.6.3
+ typescript-eslint:
+ specifier: ^8.32.1
+ version: 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ vite:
+ specifier: 'catalog:'
+ version: 5.4.15(@types/node@22.16.5)(sass@1.89.2)
+ vitest:
+ specifier: ^3.1.4
+ version: 3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2)
+
+ packages-private/dts-built-test:
+ dependencies:
+ '@vue/reactivity':
+ specifier: workspace:*
+ version: link:../../packages/reactivity
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ vue:
+ specifier: workspace:*
+ version: link:../../packages/vue
+
+ packages-private/dts-test:
+ dependencies:
+ dts-built-test:
+ specifier: workspace:*
+ version: link:../dts-built-test
+ vue:
+ specifier: workspace:*
+ version: link:../../packages/vue
+
+ packages-private/sfc-playground:
+ dependencies:
+ '@vue/repl':
+ specifier: ^4.6.2
+ version: 4.6.2
+ file-saver:
+ specifier: ^2.0.5
+ version: 2.0.5
+ jszip:
+ specifier: ^3.10.1
+ version: 3.10.1
+ vue:
+ specifier: workspace:*
+ version: link:../../packages/vue
+ devDependencies:
+ '@vitejs/plugin-vue':
+ specifier: 'catalog:'
+ version: 5.2.4(vite@5.4.15(@types/node@22.16.5)(sass@1.89.2))(vue@packages+vue)
+ vite:
+ specifier: 'catalog:'
+ version: 5.4.15(@types/node@22.16.5)(sass@1.89.2)
+
+ packages-private/template-explorer:
+ dependencies:
+ monaco-editor:
+ specifier: ^0.52.2
+ version: 0.52.2
+ source-map-js:
+ specifier: ^1.2.1
+ version: 1.2.1
+
+ packages-private/vite-debug:
+ devDependencies:
+ '@vitejs/plugin-vue':
+ specifier: 'catalog:'
+ version: 5.2.4(vite@5.4.15(@types/node@22.16.5)(sass@1.89.2))(vue@packages+vue)
+ vite:
+ specifier: 'catalog:'
+ version: 5.4.15(@types/node@22.16.5)(sass@1.89.2)
+ vue:
+ specifier: workspace:*
+ version: link:../../packages/vue
packages/compiler-core:
- specifiers:
- '@babel/parser': ^7.16.4
- '@babel/types': ^7.16.0
- '@vue/shared': 3.2.45
- estree-walker: ^2.0.2
- source-map: ^0.6.1
- dependencies:
- '@babel/parser': 7.16.4
- '@vue/shared': link:../shared
- estree-walker: 2.0.2
- source-map: 0.6.1
+ dependencies:
+ '@babel/parser':
+ specifier: 'catalog:'
+ version: 7.28.0
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
+ entities:
+ specifier: ^4.5.0
+ version: 4.5.0
+ estree-walker:
+ specifier: 'catalog:'
+ version: 2.0.2
+ source-map-js:
+ specifier: 'catalog:'
+ version: 1.2.1
devDependencies:
- '@babel/types': 7.16.0
+ '@babel/types':
+ specifier: 'catalog:'
+ version: 7.28.1
packages/compiler-dom:
- specifiers:
- '@vue/compiler-core': 3.2.45
- '@vue/shared': 3.2.45
dependencies:
- '@vue/compiler-core': link:../compiler-core
- '@vue/shared': link:../shared
+ '@vue/compiler-core':
+ specifier: workspace:*
+ version: link:../compiler-core
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
packages/compiler-sfc:
- specifiers:
- '@babel/parser': ^7.16.4
- '@babel/types': ^7.16.0
- '@types/estree': ^0.0.48
- '@types/lru-cache': ^5.1.0
- '@vue/compiler-core': 3.2.45
- '@vue/compiler-dom': 3.2.45
- '@vue/compiler-ssr': 3.2.45
- '@vue/consolidate': ^0.17.3
- '@vue/reactivity-transform': 3.2.45
- '@vue/shared': 3.2.45
- estree-walker: ^2.0.2
- hash-sum: ^2.0.0
- lru-cache: ^5.1.1
- magic-string: ^0.25.7
- merge-source-map: ^1.1.0
- postcss: ^8.1.10
- postcss-modules: ^4.0.0
- postcss-selector-parser: ^6.0.4
- pug: ^3.0.1
- sass: ^1.26.9
- source-map: ^0.6.1
- dependencies:
- '@babel/parser': 7.16.4
- '@vue/compiler-core': link:../compiler-core
- '@vue/compiler-dom': link:../compiler-dom
- '@vue/compiler-ssr': link:../compiler-ssr
- '@vue/reactivity-transform': link:../reactivity-transform
- '@vue/shared': link:../shared
- estree-walker: 2.0.2
- magic-string: 0.25.7
- postcss: 8.4.4
- source-map: 0.6.1
+ dependencies:
+ '@babel/parser':
+ specifier: 'catalog:'
+ version: 7.28.0
+ '@vue/compiler-core':
+ specifier: workspace:*
+ version: link:../compiler-core
+ '@vue/compiler-dom':
+ specifier: workspace:*
+ version: link:../compiler-dom
+ '@vue/compiler-ssr':
+ specifier: workspace:*
+ version: link:../compiler-ssr
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
+ estree-walker:
+ specifier: 'catalog:'
+ version: 2.0.2
+ magic-string:
+ specifier: 'catalog:'
+ version: 0.30.17
+ postcss:
+ specifier: ^8.5.6
+ version: 8.5.6
+ source-map-js:
+ specifier: 'catalog:'
+ version: 1.2.1
devDependencies:
- '@babel/types': 7.16.0
- '@types/estree': 0.0.48
- '@types/lru-cache': 5.1.1
- '@vue/consolidate': 0.17.3
- hash-sum: 2.0.0
- lru-cache: 5.1.1
- merge-source-map: 1.1.0
- postcss-modules: 4.2.2_postcss@8.4.4
- postcss-selector-parser: 6.0.7
- pug: 3.0.2
- sass: 1.45.0
+ '@babel/types':
+ specifier: 'catalog:'
+ version: 7.28.1
+ '@vue/consolidate':
+ specifier: ^1.0.0
+ version: 1.0.0
+ hash-sum:
+ specifier: ^2.0.0
+ version: 2.0.0
+ lru-cache:
+ specifier: 10.1.0
+ version: 10.1.0
+ merge-source-map:
+ specifier: ^1.1.0
+ version: 1.1.0
+ minimatch:
+ specifier: ~10.0.3
+ version: 10.0.3
+ postcss-modules:
+ specifier: ^6.0.1
+ version: 6.0.1(postcss@8.5.6)
+ postcss-selector-parser:
+ specifier: ^7.1.0
+ version: 7.1.0
+ pug:
+ specifier: ^3.0.3
+ version: 3.0.3
+ sass:
+ specifier: ^1.89.2
+ version: 1.89.2
packages/compiler-ssr:
- specifiers:
- '@vue/compiler-dom': 3.2.45
- '@vue/shared': 3.2.45
dependencies:
- '@vue/compiler-dom': link:../compiler-dom
- '@vue/shared': link:../shared
+ '@vue/compiler-dom':
+ specifier: workspace:*
+ version: link:../compiler-dom
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
packages/reactivity:
- specifiers:
- '@vue/shared': 3.2.45
- dependencies:
- '@vue/shared': link:../shared
-
- packages/reactivity-transform:
- specifiers:
- '@babel/core': ^7.16.0
- '@babel/parser': ^7.16.4
- '@babel/types': ^7.16.0
- '@vue/compiler-core': 3.2.45
- '@vue/shared': 3.2.45
- estree-walker: ^2.0.2
- magic-string: ^0.25.7
- dependencies:
- '@babel/parser': 7.16.4
- '@vue/compiler-core': link:../compiler-core
- '@vue/shared': link:../shared
- estree-walker: 2.0.2
- magic-string: 0.25.7
- devDependencies:
- '@babel/core': 7.16.0
- '@babel/types': 7.16.0
+ dependencies:
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
packages/runtime-core:
- specifiers:
- '@vue/reactivity': 3.2.45
- '@vue/shared': 3.2.45
dependencies:
- '@vue/reactivity': link:../reactivity
- '@vue/shared': link:../shared
+ '@vue/reactivity':
+ specifier: workspace:*
+ version: link:../reactivity
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
packages/runtime-dom:
- specifiers:
- '@vue/runtime-core': 3.2.45
- '@vue/shared': 3.2.45
- csstype: ^2.6.8
dependencies:
- '@vue/runtime-core': link:../runtime-core
- '@vue/shared': link:../shared
- csstype: 2.6.19
+ '@vue/reactivity':
+ specifier: workspace:*
+ version: link:../reactivity
+ '@vue/runtime-core':
+ specifier: workspace:*
+ version: link:../runtime-core
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
+ csstype:
+ specifier: ^3.1.3
+ version: 3.1.3
+ devDependencies:
+ '@types/trusted-types':
+ specifier: ^2.0.7
+ version: 2.0.7
packages/runtime-test:
- specifiers:
- '@vue/runtime-core': 3.2.45
- '@vue/shared': 3.2.45
dependencies:
- '@vue/runtime-core': link:../runtime-core
- '@vue/shared': link:../shared
+ '@vue/runtime-core':
+ specifier: workspace:*
+ version: link:../runtime-core
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
packages/server-renderer:
- specifiers:
- '@vue/compiler-ssr': 3.2.45
- '@vue/shared': 3.2.45
- dependencies:
- '@vue/compiler-ssr': link:../compiler-ssr
- '@vue/shared': link:../shared
-
- packages/sfc-playground:
- specifiers:
- '@vitejs/plugin-vue': ^3.0.0
- '@vue/repl': ^1.3.0
- file-saver: ^2.0.5
- jszip: ^3.6.0
- vite: ^3.0.0
- vue: 3.2.45
- dependencies:
- '@vue/repl': 1.3.0_vue@packages+vue
- file-saver: 2.0.5
- jszip: 3.7.1
- vue: link:../vue
- devDependencies:
- '@vitejs/plugin-vue': 3.1.0_yvvbnwjsosvjg6n7dkt3ewqphy
- vite: 3.0.9
-
- packages/shared:
- specifiers: {}
-
- packages/size-check:
- specifiers: {}
-
- packages/template-explorer:
- specifiers:
- monaco-editor: ^0.20.0
- source-map: ^0.6.1
dependencies:
- monaco-editor: 0.20.0
- source-map: 0.6.1
+ '@vue/compiler-ssr':
+ specifier: workspace:*
+ version: link:../compiler-ssr
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
+ vue:
+ specifier: workspace:*
+ version: link:../vue
+
+ packages/shared: {}
packages/vue:
- specifiers:
- '@vue/compiler-dom': 3.2.45
- '@vue/compiler-sfc': 3.2.45
- '@vue/runtime-dom': 3.2.45
- '@vue/server-renderer': 3.2.45
- '@vue/shared': 3.2.45
- dependencies:
- '@vue/compiler-dom': link:../compiler-dom
- '@vue/compiler-sfc': link:../compiler-sfc
- '@vue/runtime-dom': link:../runtime-dom
- '@vue/server-renderer': link:../server-renderer
- '@vue/shared': link:../shared
+ dependencies:
+ '@vue/compiler-dom':
+ specifier: workspace:*
+ version: link:../compiler-dom
+ '@vue/compiler-sfc':
+ specifier: workspace:*
+ version: link:../compiler-sfc
+ '@vue/runtime-dom':
+ specifier: workspace:*
+ version: link:../runtime-dom
+ '@vue/server-renderer':
+ specifier: workspace:*
+ version: link:../server-renderer
+ '@vue/shared':
+ specifier: workspace:*
+ version: link:../shared
+ typescript:
+ specifier: '*'
+ version: 5.6.3
packages/vue-compat:
- specifiers:
- '@babel/parser': ^7.16.4
- estree-walker: ^2.0.2
- source-map: ^0.6.1
dependencies:
- '@babel/parser': 7.16.4
- estree-walker: 2.0.2
- source-map: 0.6.1
+ '@babel/parser':
+ specifier: 'catalog:'
+ version: 7.28.0
+ estree-walker:
+ specifier: 'catalog:'
+ version: 2.0.2
+ source-map-js:
+ specifier: 'catalog:'
+ version: 1.2.1
+ vue:
+ specifier: workspace:*
+ version: link:../vue
packages:
- /@babel/code-frame/7.12.11:
- resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==}
- dependencies:
- '@babel/highlight': 7.16.0
- dev: true
+ '@ampproject/remapping@2.3.0':
+ resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+ engines: {node: '>=6.0.0'}
- /@babel/code-frame/7.16.0:
- resolution: {integrity: sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/highlight': 7.16.0
- dev: true
+ '@asamuzakjp/css-color@2.8.2':
+ resolution: {integrity: sha512-RtWv9jFN2/bLExuZgFFZ0I3pWWeezAHGgrmjqGGWclATl1aDe3yhCUaI0Ilkp6OCk9zX7+FjvDasEX8Q9Rxc5w==}
- /@babel/code-frame/7.18.6:
- resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
+ '@babel/code-frame@7.26.2':
+ resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/highlight': 7.18.6
- dev: true
- /@babel/compat-data/7.16.4:
- resolution: {integrity: sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==}
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
- dev: true
- /@babel/core/7.16.0:
- resolution: {integrity: sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==}
+ '@babel/helper-validator-identifier@7.27.1':
+ resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.18.6
- '@babel/generator': 7.16.0
- '@babel/helper-compilation-targets': 7.16.3_@babel+core@7.16.0
- '@babel/helper-module-transforms': 7.16.0
- '@babel/helpers': 7.16.3
- '@babel/parser': 7.16.4
- '@babel/template': 7.16.0
- '@babel/traverse': 7.16.3
- '@babel/types': 7.16.0
- convert-source-map: 1.8.0
- debug: 4.3.3
- gensync: 1.0.0-beta.2
- json5: 2.2.0
- semver: 6.3.0
- source-map: 0.5.7
- transitivePeerDependencies:
- - supports-color
- dev: true
- /@babel/generator/7.16.0:
- resolution: {integrity: sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- jsesc: 2.5.2
- source-map: 0.5.7
- dev: true
+ '@babel/parser@7.28.0':
+ resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
- /@babel/helper-compilation-targets/7.16.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==}
+ '@babel/types@7.28.1':
+ resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==}
engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
- dependencies:
- '@babel/compat-data': 7.16.4
- '@babel/core': 7.16.0
- '@babel/helper-validator-option': 7.14.5
- browserslist: 4.18.1
- semver: 6.3.0
- dev: true
- /@babel/helper-function-name/7.16.0:
- resolution: {integrity: sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-get-function-arity': 7.16.0
- '@babel/template': 7.16.0
- '@babel/types': 7.16.0
- dev: true
+ '@bcoe/v8-coverage@1.0.2':
+ resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
+ engines: {node: '>=18'}
- /@babel/helper-get-function-arity/7.16.0:
- resolution: {integrity: sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@conventional-changelog/git-client@1.0.1':
+ resolution: {integrity: sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ conventional-commits-filter: ^5.0.0
+ conventional-commits-parser: ^6.0.0
+ peerDependenciesMeta:
+ conventional-commits-filter:
+ optional: true
+ conventional-commits-parser:
+ optional: true
- /@babel/helper-hoist-variables/7.16.0:
- resolution: {integrity: sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@csstools/color-helpers@5.0.1':
+ resolution: {integrity: sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==}
+ engines: {node: '>=18'}
- /@babel/helper-member-expression-to-functions/7.16.0:
- resolution: {integrity: sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@csstools/css-calc@2.1.1':
+ resolution: {integrity: sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^3.0.4
+ '@csstools/css-tokenizer': ^3.0.3
- /@babel/helper-module-imports/7.16.0:
- resolution: {integrity: sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@csstools/css-color-parser@3.0.7':
+ resolution: {integrity: sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^3.0.4
+ '@csstools/css-tokenizer': ^3.0.3
- /@babel/helper-module-transforms/7.16.0:
- resolution: {integrity: sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-module-imports': 7.16.0
- '@babel/helper-replace-supers': 7.16.0
- '@babel/helper-simple-access': 7.16.0
- '@babel/helper-split-export-declaration': 7.16.0
- '@babel/helper-validator-identifier': 7.19.1
- '@babel/template': 7.16.0
- '@babel/traverse': 7.16.3
- '@babel/types': 7.16.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@csstools/css-parser-algorithms@3.0.4':
+ resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@csstools/css-tokenizer': ^3.0.3
- /@babel/helper-optimise-call-expression/7.16.0:
- resolution: {integrity: sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@csstools/css-tokenizer@3.0.3':
+ resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==}
+ engines: {node: '>=18'}
- /@babel/helper-plugin-utils/7.14.5:
- resolution: {integrity: sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==}
- engines: {node: '>=6.9.0'}
- dev: true
+ '@emnapi/core@1.4.3':
+ resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==}
- /@babel/helper-plugin-utils/7.20.2:
- resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==}
- engines: {node: '>=6.9.0'}
- dev: true
+ '@emnapi/runtime@1.4.3':
+ resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
- /@babel/helper-replace-supers/7.16.0:
- resolution: {integrity: sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-member-expression-to-functions': 7.16.0
- '@babel/helper-optimise-call-expression': 7.16.0
- '@babel/traverse': 7.16.3
- '@babel/types': 7.16.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@emnapi/wasi-threads@1.0.2':
+ resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==}
- /@babel/helper-simple-access/7.16.0:
- resolution: {integrity: sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
- /@babel/helper-split-export-declaration/7.16.0:
- resolution: {integrity: sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@esbuild/aix-ppc64@0.25.8':
+ resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
- /@babel/helper-validator-identifier/7.15.7:
- resolution: {integrity: sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==}
- engines: {node: '>=6.9.0'}
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
- /@babel/helper-validator-identifier/7.19.1:
- resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
- engines: {node: '>=6.9.0'}
- dev: true
+ '@esbuild/android-arm64@0.25.8':
+ resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
- /@babel/helper-validator-option/7.14.5:
- resolution: {integrity: sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==}
- engines: {node: '>=6.9.0'}
- dev: true
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
- /@babel/helpers/7.16.3:
- resolution: {integrity: sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/template': 7.16.0
- '@babel/traverse': 7.16.3
- '@babel/types': 7.16.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/android-arm@0.25.8':
+ resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
- /@babel/highlight/7.16.0:
- resolution: {integrity: sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-validator-identifier': 7.15.7
- chalk: 2.4.2
- js-tokens: 4.0.0
- dev: true
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
- /@babel/highlight/7.18.6:
- resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-validator-identifier': 7.19.1
- chalk: 2.4.2
- js-tokens: 4.0.0
- dev: true
+ '@esbuild/android-x64@0.25.8':
+ resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
- /@babel/parser/7.16.4:
- resolution: {integrity: sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dependencies:
- '@babel/types': 7.16.0
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
- /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.16.0:
- resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/darwin-arm64@0.25.8':
+ resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
- /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
- /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.16.0:
- resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/darwin-x64@0.25.8':
+ resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
- /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.16.0:
- resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
- /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/freebsd-arm64@0.25.8':
+ resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
- /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.16.0:
- resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
- /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.16.0:
- resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/freebsd-x64@0.25.8':
+ resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
- /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
- /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.16.0:
- resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/linux-arm64@0.25.8':
+ resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
- /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
- /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/linux-arm@0.25.8':
+ resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
- /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.16.0:
- resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
- /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.16.0:
- resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.20.2
- dev: true
+ '@esbuild/linux-ia32@0.25.8':
+ resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
- /@babel/plugin-syntax-typescript/7.16.0_@babel+core@7.16.0:
- resolution: {integrity: sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/helper-plugin-utils': 7.14.5
- dev: true
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
- /@babel/template/7.16.0:
- resolution: {integrity: sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.18.6
- '@babel/parser': 7.16.4
- '@babel/types': 7.16.0
- dev: true
+ '@esbuild/linux-loong64@0.25.8':
+ resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
- /@babel/traverse/7.16.3:
- resolution: {integrity: sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.18.6
- '@babel/generator': 7.16.0
- '@babel/helper-function-name': 7.16.0
- '@babel/helper-hoist-variables': 7.16.0
- '@babel/helper-split-export-declaration': 7.16.0
- '@babel/parser': 7.16.4
- '@babel/types': 7.16.0
- debug: 4.3.3
- globals: 11.12.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
- /@babel/types/7.16.0:
- resolution: {integrity: sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-validator-identifier': 7.15.7
- to-fast-properties: 2.0.0
+ '@esbuild/linux-mips64el@0.25.8':
+ resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
- /@bcoe/v8-coverage/0.2.3:
- resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
- dev: true
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
- /@esbuild-plugins/node-modules-polyfill/0.1.4_esbuild@0.15.13:
- resolution: {integrity: sha512-uZbcXi0zbmKC/050p3gJnne5Qdzw8vkXIv+c2BW0Lsc1ji1SkrxbKPUy5Efr0blbTu1SL8w4eyfpnSdPg3G0Qg==}
- peerDependencies:
- esbuild: '*'
- dependencies:
- esbuild: 0.15.13
- escape-string-regexp: 4.0.0
- rollup-plugin-node-polyfills: 0.2.1
- dev: true
+ '@esbuild/linux-ppc64@0.25.8':
+ resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
- /@esbuild/android-arm/0.15.13:
- resolution: {integrity: sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==}
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
engines: {node: '>=12'}
- cpu: [arm]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
+ cpu: [riscv64]
+ os: [linux]
- /@esbuild/linux-loong64/0.14.54:
- resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==}
- engines: {node: '>=12'}
- cpu: [loong64]
+ '@esbuild/linux-riscv64@0.25.8':
+ resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-loong64/0.15.13:
- resolution: {integrity: sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==}
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
engines: {node: '>=12'}
- cpu: [loong64]
+ cpu: [s390x]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@eslint/eslintrc/0.4.3:
- resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==}
- engines: {node: ^10.12.0 || >=12.0.0}
- dependencies:
- ajv: 6.12.6
- debug: 4.3.3
- espree: 7.3.1
- globals: 13.12.0
- ignore: 4.0.6
- import-fresh: 3.3.0
- js-yaml: 3.14.1
- minimatch: 3.0.4
- strip-json-comments: 3.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/linux-s390x@0.25.8':
+ resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
- /@humanwhocodes/config-array/0.5.0:
- resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==}
- engines: {node: '>=10.10.0'}
- dependencies:
- '@humanwhocodes/object-schema': 1.2.1
- debug: 4.3.3
- minimatch: 3.0.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
- /@humanwhocodes/object-schema/1.2.1:
- resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
- dev: true
+ '@esbuild/linux-x64@0.25.8':
+ resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
- /@hutson/parse-repository-url/3.0.2:
- resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==}
- engines: {node: '>=6.9.0'}
- dev: true
+ '@esbuild/netbsd-arm64@0.25.8':
+ resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
- /@istanbuljs/load-nyc-config/1.1.0:
- resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
- engines: {node: '>=8'}
- dependencies:
- camelcase: 5.3.1
- find-up: 4.1.0
- get-package-type: 0.1.0
- js-yaml: 3.14.1
- resolve-from: 5.0.0
- dev: true
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
- /@istanbuljs/schema/0.1.3:
- resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
- engines: {node: '>=8'}
- dev: true
+ '@esbuild/netbsd-x64@0.25.8':
+ resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
- /@jest/console/29.3.1:
- resolution: {integrity: sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- chalk: 4.1.2
- jest-message-util: 29.3.1
- jest-util: 29.3.1
- slash: 3.0.0
- dev: true
-
- /@jest/core/29.3.1:
- resolution: {integrity: sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
- dependencies:
- '@jest/console': 29.3.1
- '@jest/reporters': 29.3.1
- '@jest/test-result': 29.3.1
- '@jest/transform': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- ansi-escapes: 4.3.2
- chalk: 4.1.2
- ci-info: 3.3.0
- exit: 0.1.2
- graceful-fs: 4.2.10
- jest-changed-files: 29.2.0
- jest-config: 29.3.1_@types+node@16.18.2
- jest-haste-map: 29.3.1
- jest-message-util: 29.3.1
- jest-regex-util: 29.2.0
- jest-resolve: 29.3.1
- jest-resolve-dependencies: 29.3.1
- jest-runner: 29.3.1
- jest-runtime: 29.3.1
- jest-snapshot: 29.3.1
- jest-util: 29.3.1
- jest-validate: 29.3.1
- jest-watcher: 29.3.1
- micromatch: 4.0.4
- pretty-format: 29.3.1
- slash: 3.0.0
- strip-ansi: 6.0.1
- transitivePeerDependencies:
- - supports-color
- - ts-node
- dev: true
+ '@esbuild/openbsd-arm64@0.25.8':
+ resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
- /@jest/environment/29.3.1:
- resolution: {integrity: sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/fake-timers': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- jest-mock: 29.3.1
- dev: true
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
- /@jest/expect-utils/29.3.1:
- resolution: {integrity: sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- jest-get-type: 29.2.0
- dev: true
+ '@esbuild/openbsd-x64@0.25.8':
+ resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
- /@jest/expect/29.3.1:
- resolution: {integrity: sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- expect: 29.3.1
- jest-snapshot: 29.3.1
- transitivePeerDependencies:
- - supports-color
- dev: true
-
- /@jest/fake-timers/29.3.1:
- resolution: {integrity: sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/types': 29.3.1
- '@sinonjs/fake-timers': 9.1.2
- '@types/node': 16.18.2
- jest-message-util: 29.3.1
- jest-mock: 29.3.1
- jest-util: 29.3.1
- dev: true
-
- /@jest/globals/29.3.1:
- resolution: {integrity: sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/environment': 29.3.1
- '@jest/expect': 29.3.1
- '@jest/types': 29.3.1
- jest-mock: 29.3.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/openharmony-arm64@0.25.8':
+ resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/sunos-x64@0.25.8':
+ resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-arm64@0.25.8':
+ resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.8':
+ resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.8':
+ resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
- /@jest/reporters/29.3.1:
- resolution: {integrity: sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ '@eslint-community/eslint-utils@4.6.1':
+ resolution: {integrity: sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
- dependencies:
- '@bcoe/v8-coverage': 0.2.3
- '@jest/console': 29.3.1
- '@jest/test-result': 29.3.1
- '@jest/transform': 29.3.1
- '@jest/types': 29.3.1
- '@jridgewell/trace-mapping': 0.3.17
- '@types/node': 16.18.2
- chalk: 4.1.2
- collect-v8-coverage: 1.0.1
- exit: 0.1.2
- glob: 7.2.3
- graceful-fs: 4.2.10
- istanbul-lib-coverage: 3.2.0
- istanbul-lib-instrument: 5.1.0
- istanbul-lib-report: 3.0.0
- istanbul-lib-source-maps: 4.0.1
- istanbul-reports: 3.1.5
- jest-message-util: 29.3.1
- jest-util: 29.3.1
- jest-worker: 29.3.1
- slash: 3.0.0
- string-length: 4.0.2
- strip-ansi: 6.0.1
- v8-to-istanbul: 9.0.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
- /@jest/schemas/29.0.0:
- resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@sinclair/typebox': 0.24.51
- dev: true
+ '@eslint-community/eslint-utils@4.7.0':
+ resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
- /@jest/source-map/29.2.0:
- resolution: {integrity: sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jridgewell/trace-mapping': 0.3.17
- callsites: 3.1.0
- graceful-fs: 4.2.10
- dev: true
-
- /@jest/test-result/29.3.1:
- resolution: {integrity: sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/console': 29.3.1
- '@jest/types': 29.3.1
- '@types/istanbul-lib-coverage': 2.0.3
- collect-v8-coverage: 1.0.1
- dev: true
-
- /@jest/test-sequencer/29.3.1:
- resolution: {integrity: sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/test-result': 29.3.1
- graceful-fs: 4.2.10
- jest-haste-map: 29.3.1
- slash: 3.0.0
- dev: true
-
- /@jest/transform/29.3.1:
- resolution: {integrity: sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@babel/core': 7.16.0
- '@jest/types': 29.3.1
- '@jridgewell/trace-mapping': 0.3.17
- babel-plugin-istanbul: 6.1.1
- chalk: 4.1.2
- convert-source-map: 2.0.0
- fast-json-stable-stringify: 2.1.0
- graceful-fs: 4.2.10
- jest-haste-map: 29.3.1
- jest-regex-util: 29.2.0
- jest-util: 29.3.1
- micromatch: 4.0.4
- pirates: 4.0.4
- slash: 3.0.0
- write-file-atomic: 4.0.2
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@eslint-community/regexpp@4.12.1':
+ resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- /@jest/types/29.3.1:
- resolution: {integrity: sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/schemas': 29.0.0
- '@types/istanbul-lib-coverage': 2.0.3
- '@types/istanbul-reports': 3.0.1
- '@types/node': 16.18.2
- '@types/yargs': 17.0.13
- chalk: 4.1.2
- dev: true
+ '@eslint/config-array@0.20.0':
+ resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@jridgewell/gen-mapping/0.3.2:
- resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
- engines: {node: '>=6.0.0'}
- dependencies:
- '@jridgewell/set-array': 1.1.2
- '@jridgewell/sourcemap-codec': 1.4.14
- '@jridgewell/trace-mapping': 0.3.17
- dev: true
+ '@eslint/config-helpers@0.2.1':
+ resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@jridgewell/resolve-uri/3.1.0:
- resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
- engines: {node: '>=6.0.0'}
- dev: true
+ '@eslint/core@0.14.0':
+ resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@jridgewell/set-array/1.1.2:
- resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
- engines: {node: '>=6.0.0'}
- dev: true
+ '@eslint/eslintrc@3.3.1':
+ resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@jridgewell/source-map/0.3.2:
- resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==}
- dependencies:
- '@jridgewell/gen-mapping': 0.3.2
- '@jridgewell/trace-mapping': 0.3.17
- dev: true
+ '@eslint/js@9.27.0':
+ resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@jridgewell/sourcemap-codec/1.4.14:
- resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
- dev: true
+ '@eslint/object-schema@2.1.6':
+ resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@jridgewell/trace-mapping/0.3.17:
- resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
- dependencies:
- '@jridgewell/resolve-uri': 3.1.0
- '@jridgewell/sourcemap-codec': 1.4.14
- dev: true
+ '@eslint/plugin-kit@0.3.1':
+ resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@microsoft/api-extractor-model/7.16.0:
- resolution: {integrity: sha512-0FOrbNIny8mzBrzQnSIkEjAXk0JMSnPmWYxt3ZDTPVg9S8xIPzB6lfgTg9+Mimu0RKCpGKBpd+v2WcR5vGzyUQ==}
- dependencies:
- '@microsoft/tsdoc': 0.13.2
- '@microsoft/tsdoc-config': 0.15.2
- '@rushstack/node-core-library': 3.45.1
- dev: true
+ '@humanfs/core@0.19.1':
+ resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
+ engines: {node: '>=18.18.0'}
- /@microsoft/api-extractor/7.20.1:
- resolution: {integrity: sha512-T7cqcK+JpvHGOj7cD2ZCCWS7Xgru1uOqZwrV/FSUdyKVs5fopZcbBSuetwD/akst3O7Ypryg3UOLP54S/vnVmA==}
- hasBin: true
- dependencies:
- '@microsoft/api-extractor-model': 7.16.0
- '@microsoft/tsdoc': 0.13.2
- '@microsoft/tsdoc-config': 0.15.2
- '@rushstack/node-core-library': 3.45.1
- '@rushstack/rig-package': 0.3.8
- '@rushstack/ts-command-line': 4.10.7
- colors: 1.2.5
- lodash: 4.17.21
- resolve: 1.17.0
- semver: 7.3.5
- source-map: 0.6.1
- typescript: 4.5.5
- dev: true
+ '@humanfs/node@0.16.6':
+ resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==}
+ engines: {node: '>=18.18.0'}
- /@microsoft/tsdoc-config/0.15.2:
- resolution: {integrity: sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==}
- dependencies:
- '@microsoft/tsdoc': 0.13.2
- ajv: 6.12.6
- jju: 1.4.0
- resolve: 1.19.0
- dev: true
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/retry@0.3.1':
+ resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
+ engines: {node: '>=18.18'}
+
+ '@humanwhocodes/retry@0.4.2':
+ resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==}
+ engines: {node: '>=18.18'}
+
+ '@hutson/parse-repository-url@5.0.0':
+ resolution: {integrity: sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==}
+ engines: {node: '>=10.13.0'}
+
+ '@isaacs/balanced-match@4.0.1':
+ resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
+ engines: {node: 20 || >=22}
+
+ '@isaacs/brace-expansion@5.0.0':
+ resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
+ engines: {node: 20 || >=22}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
- /@microsoft/tsdoc/0.13.2:
- resolution: {integrity: sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==}
- dev: true
+ '@istanbuljs/schema@0.1.3':
+ resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
+ engines: {node: '>=8'}
+
+ '@jridgewell/gen-mapping@0.3.5':
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
- /@nodelib/fs.scandir/2.1.5:
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@jspm/core@2.0.1':
+ resolution: {integrity: sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==}
+
+ '@napi-rs/wasm-runtime@0.2.9':
+ resolution: {integrity: sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==}
+
+ '@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
- dependencies:
- '@nodelib/fs.stat': 2.0.5
- run-parallel: 1.2.0
- dev: true
- /@nodelib/fs.stat/2.0.5:
+ '@nodelib/fs.stat@2.0.5':
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
- dev: true
- /@nodelib/fs.walk/1.2.8:
+ '@nodelib/fs.walk@1.2.8':
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
- dependencies:
- '@nodelib/fs.scandir': 2.1.5
- fastq: 1.13.0
- dev: true
- /@rollup/plugin-commonjs/23.0.2_rollup@3.2.3:
- resolution: {integrity: sha512-e9ThuiRf93YlVxc4qNIurvv+Hp9dnD+4PjOqQs5vAYfcZ3+AXSrcdzXnVjWxcGQOa6KGJFcRZyUI3ktWLavFjg==}
+ '@parcel/watcher-android-arm64@2.4.1':
+ resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ '@parcel/watcher-darwin-arm64@2.4.1':
+ resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@parcel/watcher-darwin-x64@2.4.1':
+ resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@parcel/watcher-freebsd-x64@2.4.1':
+ resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@parcel/watcher-linux-arm-glibc@2.4.1':
+ resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@parcel/watcher-linux-arm64-glibc@2.4.1':
+ resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@parcel/watcher-linux-arm64-musl@2.4.1':
+ resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@parcel/watcher-linux-x64-glibc@2.4.1':
+ resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@parcel/watcher-linux-x64-musl@2.4.1':
+ resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@parcel/watcher-win32-arm64@2.4.1':
+ resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@parcel/watcher-win32-ia32@2.4.1':
+ resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@parcel/watcher-win32-x64@2.4.1':
+ resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@parcel/watcher@2.4.1':
+ resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==}
+ engines: {node: '>= 10.0.0'}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
+ '@puppeteer/browsers@2.10.5':
+ resolution: {integrity: sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@rollup/plugin-alias@5.1.1':
+ resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
- rollup: ^2.68.0||^3.0.0
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- '@rollup/pluginutils': 5.0.2_rollup@3.2.3
- commondir: 1.0.1
- estree-walker: 2.0.2
- glob: 8.0.3
- is-reference: 1.2.1
- magic-string: 0.26.7
- rollup: 3.2.3
- dev: true
- /@rollup/plugin-inject/5.0.2_rollup@3.2.3:
- resolution: {integrity: sha512-zRthPC/sZ2OaQwPh2LvFn0A+3SyMAZR1Vqsp89mWkIuGXKswT8ty1JWj1pf7xdZvft4gHZaCuhdopuiCwjclWg==}
- engines: {node: '>=14.0.0'}
+ '@rollup/plugin-commonjs@28.0.6':
+ resolution: {integrity: sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==}
+ engines: {node: '>=16.0.0 || 14 >= 14.17'}
peerDependencies:
- rollup: ^1.20.0||^2.0.0||^3.0.0
+ rollup: ^2.68.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- '@rollup/pluginutils': 5.0.2_rollup@3.2.3
- estree-walker: 2.0.2
- magic-string: 0.26.7
- rollup: 3.2.3
- dev: true
- /@rollup/plugin-json/5.0.1_rollup@3.2.3:
- resolution: {integrity: sha512-QCwhZZLvM8nRcTHyR1vOgyTMiAnjiNj1ebD/BMRvbO1oc/z14lZH6PfxXeegee2B6mky/u9fia4fxRM4TqrUaw==}
+ '@rollup/plugin-inject@5.0.5':
+ resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==}
engines: {node: '>=14.0.0'}
peerDependencies:
- rollup: ^1.20.0||^2.0.0||^3.0.0
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- '@rollup/pluginutils': 5.0.2_rollup@3.2.3
- rollup: 3.2.3
- dev: true
- /@rollup/plugin-node-resolve/15.0.1_rollup@3.2.3:
- resolution: {integrity: sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==}
+ '@rollup/plugin-json@6.1.0':
+ resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==}
engines: {node: '>=14.0.0'}
peerDependencies:
- rollup: ^2.78.0||^3.0.0
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- '@rollup/pluginutils': 5.0.2_rollup@3.2.3
- '@types/resolve': 1.20.2
- deepmerge: 4.2.2
- is-builtin-module: 3.2.0
- is-module: 1.0.0
- resolve: 1.22.1
- rollup: 3.2.3
- dev: true
- /@rollup/plugin-replace/5.0.1_rollup@3.2.3:
- resolution: {integrity: sha512-Z3MfsJ4CK17BfGrZgvrcp/l6WXoKb0kokULO+zt/7bmcyayokDaQ2K3eDJcRLCTAlp5FPI4/gz9MHAsosz4Rag==}
+ '@rollup/plugin-node-resolve@16.0.1':
+ resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==}
engines: {node: '>=14.0.0'}
peerDependencies:
- rollup: ^1.20.0||^2.0.0||^3.0.0
+ rollup: ^2.78.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- '@rollup/pluginutils': 5.0.2_rollup@3.2.3
- magic-string: 0.26.7
- rollup: 3.2.3
- dev: true
- /@rollup/plugin-terser/0.1.0_rollup@3.2.3:
- resolution: {integrity: sha512-N2KK+qUfHX2hBzVzM41UWGLrEmcjVC37spC8R3c9mt3oEDFKh3N2e12/lLp9aVSt86veR0TQiCNQXrm8C6aiUQ==}
+ '@rollup/plugin-replace@5.0.4':
+ resolution: {integrity: sha512-E2hmRnlh09K8HGT0rOnnri9OTh+BILGr7NVJGB30S4E3cLRn3J0xjdiyOZ74adPs4NiAMgrjUMGAZNJDBgsdmQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
- rollup: ^2.x || ^3.x
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- rollup: 3.2.3
- terser: 5.15.1
- dev: true
-
- /@rollup/pluginutils/4.2.1:
- resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
- engines: {node: '>= 8.0.0'}
- dependencies:
- estree-walker: 2.0.2
- picomatch: 2.3.1
- dev: true
- /@rollup/pluginutils/5.0.2_rollup@3.2.3:
- resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
+ '@rollup/pluginutils@5.1.0':
+ resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
- rollup: ^1.20.0||^2.0.0||^3.0.0
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
- dependencies:
- '@types/estree': 1.0.0
- estree-walker: 2.0.2
- picomatch: 2.3.1
- rollup: 3.2.3
- dev: true
-
- /@rushstack/node-core-library/3.45.1:
- resolution: {integrity: sha512-BwdssTNe007DNjDBxJgInHg8ePytIPyT0La7ZZSQZF9+rSkT42AygXPGvbGsyFfEntjr4X37zZSJI7yGzL16cQ==}
- dependencies:
- '@types/node': 12.20.24
- colors: 1.2.5
- fs-extra: 7.0.1
- import-lazy: 4.0.0
- jju: 1.4.0
- resolve: 1.17.0
- semver: 7.3.5
- timsort: 0.3.0
- z-schema: 5.0.4
- dev: true
-
- /@rushstack/rig-package/0.3.8:
- resolution: {integrity: sha512-MDWg1xovea99PWloSiYMjFcCLsrdjFtYt6aOyHNs5ojn5mxrzR6U9F83hvbQjTWnKPMvZtr0vcek+4n+OQOp3Q==}
- dependencies:
- resolve: 1.17.0
- strip-json-comments: 3.1.1
- dev: true
- /@rushstack/ts-command-line/4.10.7:
- resolution: {integrity: sha512-CjS+DfNXUSO5Ab2wD1GBGtUTnB02OglRWGqfaTcac9Jn45V5MeUOsq/wA8wEeS5Y/3TZ2P1k+IWdVDiuOFP9Og==}
- dependencies:
- '@types/argparse': 1.0.38
- argparse: 1.0.10
- colors: 1.2.5
- string-argv: 0.3.1
- dev: true
-
- /@sinclair/typebox/0.24.51:
- resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==}
- dev: true
+ '@rollup/rollup-android-arm-eabi@4.45.1':
+ resolution: {integrity: sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==}
+ cpu: [arm]
+ os: [android]
- /@sinonjs/commons/1.8.3:
- resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==}
- dependencies:
- type-detect: 4.0.8
- dev: true
+ '@rollup/rollup-android-arm64@4.45.1':
+ resolution: {integrity: sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==}
+ cpu: [arm64]
+ os: [android]
- /@sinonjs/fake-timers/9.1.2:
- resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==}
- dependencies:
- '@sinonjs/commons': 1.8.3
- dev: true
+ '@rollup/rollup-darwin-arm64@4.45.1':
+ resolution: {integrity: sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==}
+ cpu: [arm64]
+ os: [darwin]
- /@tootallnate/once/2.0.0:
- resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
- engines: {node: '>= 10'}
- dev: true
+ '@rollup/rollup-darwin-x64@4.45.1':
+ resolution: {integrity: sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==}
+ cpu: [x64]
+ os: [darwin]
- /@types/argparse/1.0.38:
- resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
- dev: true
+ '@rollup/rollup-freebsd-arm64@4.45.1':
+ resolution: {integrity: sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==}
+ cpu: [arm64]
+ os: [freebsd]
- /@types/babel__core/7.1.17:
- resolution: {integrity: sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==}
- dependencies:
- '@babel/parser': 7.16.4
- '@babel/types': 7.16.0
- '@types/babel__generator': 7.6.3
- '@types/babel__template': 7.4.1
- '@types/babel__traverse': 7.14.2
- dev: true
+ '@rollup/rollup-freebsd-x64@4.45.1':
+ resolution: {integrity: sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==}
+ cpu: [x64]
+ os: [freebsd]
- /@types/babel__generator/7.6.3:
- resolution: {integrity: sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@rollup/rollup-linux-arm-gnueabihf@4.45.1':
+ resolution: {integrity: sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==}
+ cpu: [arm]
+ os: [linux]
- /@types/babel__template/7.4.1:
- resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
- dependencies:
- '@babel/parser': 7.16.4
- '@babel/types': 7.16.0
- dev: true
+ '@rollup/rollup-linux-arm-musleabihf@4.45.1':
+ resolution: {integrity: sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==}
+ cpu: [arm]
+ os: [linux]
- /@types/babel__traverse/7.14.2:
- resolution: {integrity: sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
+ '@rollup/rollup-linux-arm64-gnu@4.45.1':
+ resolution: {integrity: sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==}
+ cpu: [arm64]
+ os: [linux]
- /@types/estree/0.0.48:
- resolution: {integrity: sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==}
- dev: true
+ '@rollup/rollup-linux-arm64-musl@4.45.1':
+ resolution: {integrity: sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==}
+ cpu: [arm64]
+ os: [linux]
- /@types/estree/1.0.0:
- resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
- dev: true
+ '@rollup/rollup-linux-loongarch64-gnu@4.45.1':
+ resolution: {integrity: sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==}
+ cpu: [loong64]
+ os: [linux]
- /@types/graceful-fs/4.1.5:
- resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
- dependencies:
- '@types/node': 16.18.2
- dev: true
+ '@rollup/rollup-linux-powerpc64le-gnu@4.45.1':
+ resolution: {integrity: sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==}
+ cpu: [ppc64]
+ os: [linux]
- /@types/hash-sum/1.0.0:
- resolution: {integrity: sha512-FdLBT93h3kcZ586Aee66HPCVJ6qvxVjBlDWNmxSGSbCZe9hTsjRKdSsl4y1T+3zfujxo9auykQMnFsfyHWD7wg==}
- dev: true
+ '@rollup/rollup-linux-riscv64-gnu@4.45.1':
+ resolution: {integrity: sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==}
+ cpu: [riscv64]
+ os: [linux]
- /@types/istanbul-lib-coverage/2.0.3:
- resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==}
- dev: true
+ '@rollup/rollup-linux-riscv64-musl@4.45.1':
+ resolution: {integrity: sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==}
+ cpu: [riscv64]
+ os: [linux]
- /@types/istanbul-lib-report/3.0.0:
- resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
- dependencies:
- '@types/istanbul-lib-coverage': 2.0.3
- dev: true
+ '@rollup/rollup-linux-s390x-gnu@4.45.1':
+ resolution: {integrity: sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==}
+ cpu: [s390x]
+ os: [linux]
- /@types/istanbul-reports/3.0.1:
- resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
- dependencies:
- '@types/istanbul-lib-report': 3.0.0
- dev: true
+ '@rollup/rollup-linux-x64-gnu@4.45.1':
+ resolution: {integrity: sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==}
+ cpu: [x64]
+ os: [linux]
- /@types/jest/29.2.2:
- resolution: {integrity: sha512-og1wAmdxKoS71K2ZwSVqWPX6OVn3ihZ6ZT2qvZvZQm90lJVDyXIjYcu4Khx2CNIeaFv12rOU/YObOsI3VOkzog==}
- dependencies:
- expect: 29.3.1
- pretty-format: 29.3.1
- dev: true
+ '@rollup/rollup-linux-x64-musl@4.45.1':
+ resolution: {integrity: sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==}
+ cpu: [x64]
+ os: [linux]
- /@types/jsdom/20.0.1:
- resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
- dependencies:
- '@types/node': 16.18.2
- '@types/tough-cookie': 4.0.2
- parse5: 7.1.1
- dev: true
+ '@rollup/rollup-win32-arm64-msvc@4.45.1':
+ resolution: {integrity: sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==}
+ cpu: [arm64]
+ os: [win32]
- /@types/json-schema/7.0.11:
- resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
- dev: true
+ '@rollup/rollup-win32-ia32-msvc@4.45.1':
+ resolution: {integrity: sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==}
+ cpu: [ia32]
+ os: [win32]
- /@types/lru-cache/5.1.1:
- resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==}
- dev: true
+ '@rollup/rollup-win32-x64-msvc@4.45.1':
+ resolution: {integrity: sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==}
+ cpu: [x64]
+ os: [win32]
- /@types/minimist/1.2.2:
- resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
- dev: true
+ '@swc/core-darwin-arm64@1.13.1':
+ resolution: {integrity: sha512-zO6SW/jSMTUORPm6dUZFPUwf+EFWZsaXWMGXadRG6akCofYpoQb8pcY2QZkVr43z8TMka6BtXpyoD/DJ0iOPHQ==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [darwin]
- /@types/node/12.20.24:
- resolution: {integrity: sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==}
- dev: true
+ '@swc/core-darwin-x64@1.13.1':
+ resolution: {integrity: sha512-8RjaTZYxrlYKE5PgzZYWSOT4mAsyhIuh30Nu4dnn/2r0Ef68iNCbvX4ynGnFMhOIhqunjQbJf+mJKpwTwdHXhw==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [darwin]
- /@types/node/16.11.12:
- resolution: {integrity: sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==}
- dev: true
+ '@swc/core-linux-arm-gnueabihf@1.13.1':
+ resolution: {integrity: sha512-jEqK6pECs2m4BpL2JA/4CCkq04p6iFOEtVNXTisO+lJ3zwmxlnIEm9UfJZG6VSu8GS9MHRKGB0ieZ1tEdN1qDA==}
+ engines: {node: '>=10'}
+ cpu: [arm]
+ os: [linux]
- /@types/node/16.18.2:
- resolution: {integrity: sha512-KIGQJyya+opDCFvDSZMNNS899ov5jlNdtN7PypgHWeb8e+5vWISdwTRo/ClsNVlmDihzOGqFyNBDamUs7TQQCA==}
- dev: true
+ '@swc/core-linux-arm64-gnu@1.13.1':
+ resolution: {integrity: sha512-PbkuIOYXO/gQbWQ7NnYIwm59ygNqmUcF8LBeoKvxhx1VtOwE+9KiTfoplOikkPLhMiTzKsd8qentTslbITIg+Q==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
- /@types/normalize-package-data/2.4.1:
- resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
- dev: true
+ '@swc/core-linux-arm64-musl@1.13.1':
+ resolution: {integrity: sha512-JaqFdBCarIBKiMu5bbAp+kWPMNGg97ej+7KzbKOzWP5pRptqKi86kCDZT3WmjPe8hNG6dvBwbm7Y8JNry5LebQ==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
- /@types/parse-json/4.0.0:
- resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
- dev: true
+ '@swc/core-linux-x64-gnu@1.13.1':
+ resolution: {integrity: sha512-t4cLkku10YECDaakWUH0452WJHIZtrLPRwezt6BdoMntVMwNjvXRX7C8bGuYcKC3YxRW7enZKFpozLhQIQ37oA==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
- /@types/prettier/2.4.2:
- resolution: {integrity: sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==}
- dev: true
+ '@swc/core-linux-x64-musl@1.13.1':
+ resolution: {integrity: sha512-fSMwZOaG+3ukUucbEbzz9GhzGhUhXoCPqHe9qW0/Vc2IZRp538xalygKyZynYweH5d9EHux1aj3+IO8/xBaoiA==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
- /@types/resolve/1.20.2:
- resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
- dev: true
+ '@swc/core-win32-arm64-msvc@1.13.1':
+ resolution: {integrity: sha512-tweCXK/79vAwj1NhAsYgICy8T1z2QEairmN2BFEBYFBFNMEB1iI1YlXwBkBtuihRvgZrTh1ORusKa4jLYzLCZA==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [win32]
- /@types/stack-utils/2.0.1:
- resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
- dev: true
+ '@swc/core-win32-ia32-msvc@1.13.1':
+ resolution: {integrity: sha512-zi7hO9D+2R2yQN9D7T10/CAI9KhuXkNkz8tcJOW6+dVPtAk/gsIC5NoGPELjgrAlLL9CS38ZQpLDslLfpP15ng==}
+ engines: {node: '>=10'}
+ cpu: [ia32]
+ os: [win32]
- /@types/tough-cookie/4.0.2:
- resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==}
- dev: true
+ '@swc/core-win32-x64-msvc@1.13.1':
+ resolution: {integrity: sha512-KubYjzqs/nz3H69ncX/XHKsC8c1xqc7UvonQAj26BhbL22HBsqdAaVutZ+Obho6RMpd3F5qQ95ldavUTWskRrw==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [win32]
- /@types/yargs-parser/20.2.1:
- resolution: {integrity: sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==}
- dev: true
+ '@swc/core@1.13.1':
+ resolution: {integrity: sha512-jEKKErLC6uwSqA+p6bmZR08usZM5Fpc+HdEu5CAzvye0q43yf1si1kjhHEa9XMkz0A2SAaal3eKCg/YYmtOsCA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@swc/helpers': '>=0.5.17'
+ peerDependenciesMeta:
+ '@swc/helpers':
+ optional: true
- /@types/yargs/17.0.13:
- resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==}
- dependencies:
- '@types/yargs-parser': 20.2.1
- dev: true
+ '@swc/counter@0.1.3':
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
- /@types/yauzl/2.10.0:
- resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==}
- requiresBuild: true
- dependencies:
- '@types/node': 16.18.2
- dev: true
- optional: true
+ '@swc/types@0.1.23':
+ resolution: {integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==}
- /@typescript-eslint/parser/5.23.0_td6yqss6ra3qoebludh4ctrhym:
- resolution: {integrity: sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ '@tootallnate/quickjs-emscripten@0.23.0':
+ resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
+
+ '@tybys/wasm-util@0.9.0':
+ resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
+
+ '@types/estree@1.0.7':
+ resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/hash-sum@1.0.2':
+ resolution: {integrity: sha512-UP28RddqY8xcU0SCEp9YKutQICXpaAq9N8U2klqF5hegGha7KzTOL8EdhIIV3bOSGBzjEpN9bU/d+nNZBdJYVw==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/node@22.16.5':
+ resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==}
+
+ '@types/normalize-package-data@2.4.4':
+ resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
+
+ '@types/resolve@1.20.2':
+ resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
+
+ '@types/semver@7.7.0':
+ resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==}
+
+ '@types/serve-handler@6.1.4':
+ resolution: {integrity: sha512-aXy58tNie0NkuSCY291xUxl0X+kGYy986l4kqW6Gi4kEXgr6Tx0fpSH7YwUSa5usPpG3s9DBeIR6hHcDtL2IvQ==}
+
+ '@types/trusted-types@2.0.7':
+ resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
+
+ '@types/yauzl@2.10.3':
+ resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
+
+ '@typescript-eslint/eslint-plugin@8.32.1':
+ resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
- typescript: '*'
- peerDependenciesMeta:
- typescript:
- optional: true
- dependencies:
- '@typescript-eslint/scope-manager': 5.23.0
- '@typescript-eslint/types': 5.23.0
- '@typescript-eslint/typescript-estree': 5.23.0_typescript@4.8.2
- debug: 4.3.3
- eslint: 7.32.0
- typescript: 4.8.2
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.9.0'
- /@typescript-eslint/scope-manager/5.19.0:
- resolution: {integrity: sha512-Fz+VrjLmwq5fbQn5W7cIJZ066HxLMKvDEmf4eu1tZ8O956aoX45jAuBB76miAECMTODyUxH61AQM7q4/GOMQ5g==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dependencies:
- '@typescript-eslint/types': 5.19.0
- '@typescript-eslint/visitor-keys': 5.19.0
- dev: true
+ '@typescript-eslint/parser@8.32.1':
+ resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.9.0'
- /@typescript-eslint/scope-manager/5.23.0:
- resolution: {integrity: sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dependencies:
- '@typescript-eslint/types': 5.23.0
- '@typescript-eslint/visitor-keys': 5.23.0
- dev: true
+ '@typescript-eslint/scope-manager@8.32.1':
+ resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@typescript-eslint/types/5.19.0:
- resolution: {integrity: sha512-zR1ithF4Iyq1wLwkDcT+qFnhs8L5VUtjgac212ftiOP/ZZUOCuuF2DeGiZZGQXGoHA50OreZqLH5NjDcDqn34w==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dev: true
+ '@typescript-eslint/type-utils@8.32.1':
+ resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.9.0'
- /@typescript-eslint/types/5.23.0:
- resolution: {integrity: sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dev: true
+ '@typescript-eslint/types@8.32.1':
+ resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- /@typescript-eslint/typescript-estree/5.19.0_typescript@4.8.2:
- resolution: {integrity: sha512-dRPuD4ocXdaE1BM/dNR21elSEUPKaWgowCA0bqJ6YbYkvtrPVEvZ+zqcX5a8ECYn3q5iBSSUcBBD42ubaOp0Hw==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ '@typescript-eslint/typescript-estree@8.32.1':
+ resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <5.9.0'
+
+ '@typescript-eslint/utils@8.32.1':
+ resolution: {integrity: sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.9.0'
+
+ '@typescript-eslint/visitor-keys@8.32.1':
+ resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@unrs/resolver-binding-darwin-arm64@1.7.2':
+ resolution: {integrity: sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@unrs/resolver-binding-darwin-x64@1.7.2':
+ resolution: {integrity: sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@unrs/resolver-binding-freebsd-x64@1.7.2':
+ resolution: {integrity: sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2':
+ resolution: {integrity: sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.7.2':
+ resolution: {integrity: sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA==}
+ cpu: [arm]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm64-gnu@1.7.2':
+ resolution: {integrity: sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm64-musl@1.7.2':
+ resolution: {integrity: sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.7.2':
+ resolution: {integrity: sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.7.2':
+ resolution: {integrity: sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-riscv64-musl@1.7.2':
+ resolution: {integrity: sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-s390x-gnu@1.7.2':
+ resolution: {integrity: sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-x64-gnu@1.7.2':
+ resolution: {integrity: sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-x64-musl@1.7.2':
+ resolution: {integrity: sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@unrs/resolver-binding-wasm32-wasi@1.7.2':
+ resolution: {integrity: sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+
+ '@unrs/resolver-binding-win32-arm64-msvc@1.7.2':
+ resolution: {integrity: sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@unrs/resolver-binding-win32-ia32-msvc@1.7.2':
+ resolution: {integrity: sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@unrs/resolver-binding-win32-x64-msvc@1.7.2':
+ resolution: {integrity: sha512-friS8NEQfHaDbkThxopGk+LuE5v3iY0StruifjQEt7SLbA46OnfgMO15sOTkbpJkol6RB+1l1TYPXh0sCddpvA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@vitejs/plugin-vue@5.2.4':
+ resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
- typescript: '*'
+ vite: ^5.0.0 || ^6.0.0
+ vue: ^3.2.25
+
+ '@vitest/coverage-v8@3.1.4':
+ resolution: {integrity: sha512-G4p6OtioySL+hPV7Y6JHlhpsODbJzt1ndwHAFkyk6vVjpK03PFsKnauZIzcd0PrK4zAbc5lc+jeZ+eNGiMA+iw==}
+ peerDependencies:
+ '@vitest/browser': 3.1.4
+ vitest: 3.1.4
peerDependenciesMeta:
- typescript:
+ '@vitest/browser':
optional: true
- dependencies:
- '@typescript-eslint/types': 5.19.0
- '@typescript-eslint/visitor-keys': 5.19.0
- debug: 4.3.3
- globby: 11.0.4
- is-glob: 4.0.3
- semver: 7.3.5
- tsutils: 3.21.0_typescript@4.8.2
- typescript: 4.8.2
- transitivePeerDependencies:
- - supports-color
- dev: true
- /@typescript-eslint/typescript-estree/5.23.0_typescript@4.8.2:
- resolution: {integrity: sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ '@vitest/eslint-plugin@1.2.1':
+ resolution: {integrity: sha512-JQr1jdVcrsoS7Sdzn83h9sq4DvREf9Q/onTZbJCqTVlv/76qb+TZrLv/9VhjnjSMHweQH5FdpMDeCR6aDe2fgw==}
peerDependencies:
- typescript: '*'
+ eslint: '>= 8.57.0'
+ typescript: '>= 5.0.0'
+ vitest: '*'
peerDependenciesMeta:
typescript:
optional: true
- dependencies:
- '@typescript-eslint/types': 5.23.0
- '@typescript-eslint/visitor-keys': 5.23.0
- debug: 4.3.3
- globby: 11.0.4
- is-glob: 4.0.3
- semver: 7.3.5
- tsutils: 3.21.0_typescript@4.8.2
- typescript: 4.8.2
- transitivePeerDependencies:
- - supports-color
- dev: true
+ vitest:
+ optional: true
- /@typescript-eslint/utils/5.19.0_td6yqss6ra3qoebludh4ctrhym:
- resolution: {integrity: sha512-ZuEckdupXpXamKvFz/Ql8YnePh2ZWcwz7APICzJL985Rp5C2AYcHO62oJzIqNhAMtMK6XvrlBTZeNG8n7gS3lQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- peerDependencies:
- eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
- dependencies:
- '@types/json-schema': 7.0.11
- '@typescript-eslint/scope-manager': 5.19.0
- '@typescript-eslint/types': 5.19.0
- '@typescript-eslint/typescript-estree': 5.19.0_typescript@4.8.2
- eslint: 7.32.0
- eslint-scope: 5.1.1
- eslint-utils: 3.0.0_eslint@7.32.0
- transitivePeerDependencies:
- - supports-color
- - typescript
- dev: true
+ '@vitest/expect@3.1.4':
+ resolution: {integrity: sha512-xkD/ljeliyaClDYqHPNCiJ0plY5YIcM0OlRiZizLhlPmpXWpxnGMyTZXOHFhFeG7w9P5PBeL4IdtJ/HeQwTbQA==}
- /@typescript-eslint/visitor-keys/5.19.0:
- resolution: {integrity: sha512-Ym7zZoMDZcAKWsULi2s7UMLREdVQdScPQ/fKWMYefarCztWlHPFVJo8racf8R0Gc8FAEJ2eD4of8As1oFtnQlQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dependencies:
- '@typescript-eslint/types': 5.19.0
- eslint-visitor-keys: 3.3.0
- dev: true
+ '@vitest/mocker@3.1.4':
+ resolution: {integrity: sha512-8IJ3CvwtSw/EFXqWFL8aCMu+YyYXG2WUSrQbViOZkWTKTVicVwZ/YiEZDSqD00kX+v/+W+OnxhNWoeVKorHygA==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^5.0.0 || ^6.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
- /@typescript-eslint/visitor-keys/5.23.0:
- resolution: {integrity: sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dependencies:
- '@typescript-eslint/types': 5.23.0
- eslint-visitor-keys: 3.3.0
- dev: true
+ '@vitest/pretty-format@3.1.4':
+ resolution: {integrity: sha512-cqv9H9GvAEoTaoq+cYqUTCGscUjKqlJZC7PRwY5FMySVj5J+xOm1KQcCiYHJOEzOKRUhLH4R2pTwvFlWCEScsg==}
- /@vitejs/plugin-vue/3.1.0_yvvbnwjsosvjg6n7dkt3ewqphy:
- resolution: {integrity: sha512-fmxtHPjSOEIRg6vHYDaem+97iwCUg/uSIaTzp98lhELt2ISOQuDo2hbkBdXod0g15IhfPMQmAxh4heUks2zvDA==}
- engines: {node: ^14.18.0 || >=16.0.0}
- peerDependencies:
- vite: ^3.0.0
- vue: ^3.2.25
- dependencies:
- vite: 3.0.9
- vue: link:packages/vue
- dev: true
+ '@vitest/runner@3.1.4':
+ resolution: {integrity: sha512-djTeF1/vt985I/wpKVFBMWUlk/I7mb5hmD5oP8K9ACRmVXgKTae3TUOtXAEBfslNKPzUQvnKhNd34nnRSYgLNQ==}
- /@vue/consolidate/0.17.3:
- resolution: {integrity: sha512-nl0SWcTMzaaTnJ5G6V8VlMDA1CVVrNnaQKF1aBZU3kXtjgU9jtHMsEAsgjoRUx+T0EVJk9TgbmxGhK3pOk22zw==}
- engines: {node: '>= 0.12.0'}
- dev: true
+ '@vitest/snapshot@3.1.4':
+ resolution: {integrity: sha512-JPHf68DvuO7vilmvwdPr9TS0SuuIzHvxeaCkxYcCD4jTk67XwL45ZhEHFKIuCm8CYstgI6LZ4XbwD6ANrwMpFg==}
- /@vue/repl/1.3.0_vue@packages+vue:
- resolution: {integrity: sha512-L2Jr9+M6z2+gW6i5ZuUXwCMfXtyHDSSyw4fViL0QezXLLOctqTw+o6sYUsgvErkreb9oI0kcZPpWkkW7lGeuiA==}
- peerDependencies:
- vue: ^3.2.13
- dependencies:
- vue: link:packages/vue
- dev: false
+ '@vitest/spy@3.1.4':
+ resolution: {integrity: sha512-Xg1bXhu+vtPXIodYN369M86K8shGLouNjoVI78g8iAq2rFoHFdajNvJJ5A/9bPMFcfQqdaCpOgWKEoMQg/s0Yg==}
- /@zeit/schemas/2.6.0:
- resolution: {integrity: sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==}
- dev: true
+ '@vitest/utils@3.1.4':
+ resolution: {integrity: sha512-yriMuO1cfFhmiGc8ataN51+9ooHRuURdfAZfwFd3usWynjzpLslZdYnRegTv32qdgtJTsj15FoeZe2g15fY1gg==}
- /JSONStream/1.3.5:
- resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
- hasBin: true
- dependencies:
- jsonparse: 1.3.1
- through: 2.3.8
- dev: true
+ '@vue/consolidate@1.0.0':
+ resolution: {integrity: sha512-oTyUE+QHIzLw2PpV14GD/c7EohDyP64xCniWTcqcEmTd699eFqTIwOmtDYjcO1j3QgdXoJEoWv1/cCdLrRoOfg==}
+ engines: {node: '>= 0.12.0'}
- /abab/2.0.6:
- resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
- dev: true
+ '@vue/repl@4.6.2':
+ resolution: {integrity: sha512-Rjl/X++MbfWNncry+qiIadY5BdrB3hp0Iu9W7R9eLJAce3hXnjUiykMK5rLAkQJpB6N83SR0LGNJbKg7gpzplg==}
- /abstract-leveldown/0.12.4:
- resolution: {integrity: sha512-TOod9d5RDExo6STLMGa+04HGkl+TlMfbDnTyN93/ETJ9DpQ0DaYLqcMZlbXvdc4W3vVo1Qrl+WhSp8zvDsJ+jA==}
- dependencies:
- xtend: 3.0.0
- dev: true
+ '@zeit/schemas@2.36.0':
+ resolution: {integrity: sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==}
- /accepts/1.3.7:
- resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==}
+ accepts@1.3.8:
+ resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
- dependencies:
- mime-types: 2.1.34
- negotiator: 0.6.2
- dev: true
- /acorn-globals/7.0.1:
- resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==}
- dependencies:
- acorn: 8.8.1
- acorn-walk: 8.2.0
- dev: true
-
- /acorn-jsx/5.3.2_acorn@7.4.1:
+ acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
- dependencies:
- acorn: 7.4.1
- dev: true
- /acorn-walk/8.2.0:
- resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
- engines: {node: '>=0.4.0'}
- dev: true
-
- /acorn/5.7.4:
- resolution: {integrity: sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==}
- engines: {node: '>=0.4.0'}
- hasBin: true
- dev: true
-
- /acorn/7.4.1:
+ acorn@7.4.1:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
engines: {node: '>=0.4.0'}
hasBin: true
- dev: true
- /acorn/8.8.1:
- resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==}
+ acorn@8.14.0:
+ resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
engines: {node: '>=0.4.0'}
hasBin: true
- dev: true
-
- /add-stream/1.0.0:
- resolution: {integrity: sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=}
- dev: true
- /agent-base/6.0.2:
- resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
- engines: {node: '>= 6.0.0'}
- dependencies:
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ add-stream@1.0.0:
+ resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==}
- /aggregate-error/3.1.0:
- resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
- engines: {node: '>=8'}
- dependencies:
- clean-stack: 2.2.0
- indent-string: 4.0.0
- dev: true
+ agent-base@7.1.3:
+ resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
+ engines: {node: '>= 14'}
- /ajv/6.12.6:
+ ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
- dependencies:
- fast-deep-equal: 3.1.3
- fast-json-stable-stringify: 2.1.0
- json-schema-traverse: 0.4.1
- uri-js: 4.4.1
- dev: true
- /ajv/8.8.2:
- resolution: {integrity: sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==}
- dependencies:
- fast-deep-equal: 3.1.3
- json-schema-traverse: 1.0.0
- require-from-string: 2.0.2
- uri-js: 4.4.1
- dev: true
+ ajv@8.12.0:
+ resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
- /ansi-align/2.0.0:
- resolution: {integrity: sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=}
- dependencies:
- string-width: 2.1.1
- dev: true
+ ansi-align@3.0.1:
+ resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
- /ansi-colors/4.1.1:
- resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==}
+ ansi-colors@4.1.3:
+ resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
- dev: true
-
- /ansi-escapes/4.3.2:
- resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
- engines: {node: '>=8'}
- dependencies:
- type-fest: 0.21.3
- dev: true
- /ansi-regex/3.0.0:
- resolution: {integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=}
- engines: {node: '>=4'}
- dev: true
+ ansi-escapes@7.0.0:
+ resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==}
+ engines: {node: '>=18'}
- /ansi-regex/5.0.1:
+ ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
- dev: true
- /ansi-styles/3.2.1:
- resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
- engines: {node: '>=4'}
- dependencies:
- color-convert: 1.9.3
- dev: true
+ ansi-regex@6.0.1:
+ resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+ engines: {node: '>=12'}
- /ansi-styles/4.3.0:
+ ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
- dependencies:
- color-convert: 2.0.1
- dev: true
-
- /ansi-styles/5.2.0:
- resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
- engines: {node: '>=10'}
- dev: true
- /anymatch/3.1.2:
- resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
- engines: {node: '>= 8'}
- dependencies:
- normalize-path: 3.0.0
- picomatch: 2.3.1
- dev: true
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
- /arch/2.2.0:
+ arch@2.2.0:
resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
- dev: true
-
- /arg/2.0.0:
- resolution: {integrity: sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==}
- dev: true
-
- /argparse/1.0.10:
- resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
- dependencies:
- sprintf-js: 1.0.3
- dev: true
- /array-ify/1.0.0:
- resolution: {integrity: sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=}
- dev: true
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
- /array-union/2.1.0:
- resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
- engines: {node: '>=8'}
- dev: true
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
- /arrify/1.0.1:
- resolution: {integrity: sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=}
- engines: {node: '>=0.10.0'}
- dev: true
+ array-ify@1.0.0:
+ resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
- /asap/2.0.6:
+ asap@2.0.6:
resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
- dev: true
-
- /asn1.js/5.4.1:
- resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
- dependencies:
- bn.js: 4.12.0
- inherits: 2.0.4
- minimalistic-assert: 1.0.1
- safer-buffer: 2.1.2
- dev: true
-
- /assert-never/1.2.1:
- resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==}
- dev: true
-
- /astral-regex/2.0.0:
- resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
- engines: {node: '>=8'}
- dev: true
-
- /asynckit/0.4.0:
- resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
- dev: true
- /at-least-node/1.0.0:
- resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
- engines: {node: '>= 4.0.0'}
- dev: true
-
- /babel-jest/29.3.1_@babel+core@7.16.0:
- resolution: {integrity: sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@babel/core': ^7.8.0
- dependencies:
- '@babel/core': 7.16.0
- '@jest/transform': 29.3.1
- '@types/babel__core': 7.1.17
- babel-plugin-istanbul: 6.1.1
- babel-preset-jest: 29.2.0_@babel+core@7.16.0
- chalk: 4.1.2
- graceful-fs: 4.2.10
- slash: 3.0.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ assert-never@1.3.0:
+ resolution: {integrity: sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==}
- /babel-plugin-istanbul/6.1.1:
- resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
- engines: {node: '>=8'}
- dependencies:
- '@babel/helper-plugin-utils': 7.14.5
- '@istanbuljs/load-nyc-config': 1.1.0
- '@istanbuljs/schema': 0.1.3
- istanbul-lib-instrument: 5.1.0
- test-exclude: 6.0.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
- /babel-plugin-jest-hoist/29.2.0:
- resolution: {integrity: sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@babel/template': 7.16.0
- '@babel/types': 7.16.0
- '@types/babel__core': 7.1.17
- '@types/babel__traverse': 7.14.2
- dev: true
+ ast-types@0.13.4:
+ resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
+ engines: {node: '>=4'}
- /babel-preset-current-node-syntax/1.0.1_@babel+core@7.16.0:
- resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
- peerDependencies:
- '@babel/core': ^7.0.0
- dependencies:
- '@babel/core': 7.16.0
- '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.16.0
- '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.16.0
- '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.16.0
- '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.16.0
- '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.16.0
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.16.0
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.16.0
- '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.16.0
- '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.16.0
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.16.0
- '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.16.0
- '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.16.0
- dev: true
-
- /babel-preset-jest/29.2.0_@babel+core@7.16.0:
- resolution: {integrity: sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@babel/core': ^7.0.0
- dependencies:
- '@babel/core': 7.16.0
- babel-plugin-jest-hoist: 29.2.0
- babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.0
- dev: true
+ b4a@1.6.6:
+ resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==}
- /babel-walk/3.0.0-canary-5:
+ babel-walk@3.0.0-canary-5:
resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==}
engines: {node: '>= 10.0.0'}
- dependencies:
- '@babel/types': 7.16.0
- dev: true
- /balanced-match/1.0.2:
+ balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
- dev: true
- /base64-js/1.5.1:
- resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
- dev: true
+ bare-events@2.4.2:
+ resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==}
- /big.js/5.2.2:
- resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
- dev: true
+ bare-fs@4.0.1:
+ resolution: {integrity: sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==}
+ engines: {bare: '>=1.7.0'}
- /binary-extensions/2.2.0:
- resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
- engines: {node: '>=8'}
- dev: true
-
- /bl/0.8.2:
- resolution: {integrity: sha512-pfqikmByp+lifZCS0p6j6KreV6kNU6Apzpm2nKOk+94cZb/jvle55+JxWiByUQ0Wo/+XnDXEy5MxxKMb6r0VIw==}
- dependencies:
- readable-stream: 1.0.34
- dev: true
+ bare-os@3.4.0:
+ resolution: {integrity: sha512-9Ous7UlnKbe3fMi7Y+qh0DwAup6A1JkYgPnjvMDNOlmnxNRQvQ/7Nst+OnUQKzk0iAT0m9BisbDVp9gCv8+ETA==}
+ engines: {bare: '>=1.6.0'}
- /bl/4.1.0:
- resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
- dependencies:
- buffer: 5.7.1
- inherits: 2.0.4
- readable-stream: 3.6.0
- dev: true
+ bare-path@3.0.0:
+ resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==}
- /bn.js/4.12.0:
- resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
- dev: true
+ bare-stream@2.1.3:
+ resolution: {integrity: sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==}
- /bn.js/5.2.1:
- resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==}
- dev: true
+ basic-ftp@5.0.5:
+ resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
+ engines: {node: '>=10.0.0'}
- /boxen/1.3.0:
- resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==}
- engines: {node: '>=4'}
- dependencies:
- ansi-align: 2.0.0
- camelcase: 4.1.0
- chalk: 2.4.2
- cli-boxes: 1.0.0
- string-width: 2.1.1
- term-size: 1.2.0
- widest-line: 2.0.1
- dev: true
+ boxen@7.0.0:
+ resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==}
+ engines: {node: '>=14.16'}
- /brace-expansion/1.1.11:
+ brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
- dependencies:
- balanced-match: 1.0.2
- concat-map: 0.0.1
- dev: true
- /brace-expansion/2.0.1:
+ brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
- dependencies:
- balanced-match: 1.0.2
- dev: true
- /braces/3.0.2:
- resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
- dependencies:
- fill-range: 7.0.1
- dev: true
- /brorand/1.1.0:
- resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==}
- dev: true
+ buffer-crc32@0.2.13:
+ resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
- /brotli/1.3.2:
- resolution: {integrity: sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y=}
- dependencies:
- base64-js: 1.5.1
- dev: true
+ bytes@3.0.0:
+ resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
+ engines: {node: '>= 0.8'}
- /browserify-aes/1.2.0:
- resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==}
- dependencies:
- buffer-xor: 1.0.3
- cipher-base: 1.0.4
- create-hash: 1.2.0
- evp_bytestokey: 1.0.3
- inherits: 2.0.4
- safe-buffer: 5.2.1
- dev: true
+ cac@6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+ engines: {node: '>=8'}
- /browserify-cipher/1.0.1:
- resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==}
- dependencies:
- browserify-aes: 1.2.0
- browserify-des: 1.0.2
- evp_bytestokey: 1.0.3
- dev: true
+ call-bind@1.0.7:
+ resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+ engines: {node: '>= 0.4'}
- /browserify-des/1.0.2:
- resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
- dependencies:
- cipher-base: 1.0.4
- des.js: 1.0.1
- inherits: 2.0.4
- safe-buffer: 5.2.1
- dev: true
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
- /browserify-fs/1.0.0:
- resolution: {integrity: sha512-8LqHRPuAEKvyTX34R6tsw4bO2ro6j9DmlYBhiYWHRM26Zv2cBw1fJOU0NeUQ0RkXkPn/PFBjhA0dm4AgaBurTg==}
- dependencies:
- level-filesystem: 1.2.0
- level-js: 2.2.4
- levelup: 0.18.6
- dev: true
+ camelcase@7.0.1:
+ resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
+ engines: {node: '>=14.16'}
- /browserify-rsa/4.1.0:
- resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==}
- dependencies:
- bn.js: 5.2.1
- randombytes: 2.1.0
- dev: true
+ chai@5.2.0:
+ resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
+ engines: {node: '>=12'}
- /browserify-sign/4.2.1:
- resolution: {integrity: sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==}
- dependencies:
- bn.js: 5.2.1
- browserify-rsa: 4.1.0
- create-hash: 1.2.0
- create-hmac: 1.1.7
- elliptic: 6.5.4
- inherits: 2.0.4
- parse-asn1: 5.1.6
- readable-stream: 3.6.0
- safe-buffer: 5.2.1
- dev: true
+ chalk-template@0.4.0:
+ resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==}
+ engines: {node: '>=12'}
- /browserslist/4.18.1:
- resolution: {integrity: sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==}
- engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
- hasBin: true
- dependencies:
- caniuse-lite: 1.0.30001286
- electron-to-chromium: 1.4.16
- escalade: 3.1.1
- node-releases: 2.0.1
- picocolors: 1.0.0
- dev: true
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
- /bs-logger/0.2.6:
- resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
- engines: {node: '>= 6'}
- dependencies:
- fast-json-stable-stringify: 2.1.0
- dev: true
+ chalk@5.0.1:
+ resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- /bser/2.1.1:
- resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
- dependencies:
- node-int64: 0.4.0
- dev: true
+ chalk@5.4.1:
+ resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- /buffer-crc32/0.2.13:
- resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
- dev: true
+ character-parser@2.2.0:
+ resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==}
- /buffer-es6/4.9.3:
- resolution: {integrity: sha512-Ibt+oXxhmeYJSsCkODPqNpPmyegefiD8rfutH1NYGhMZQhSp95Rz7haemgnJ6dxa6LT+JLLbtgOMORRluwKktw==}
- dev: true
+ check-error@2.1.1:
+ resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
+ engines: {node: '>= 16'}
- /buffer-from/1.1.2:
- resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
- dev: true
+ chokidar@4.0.1:
+ resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==}
+ engines: {node: '>= 14.16.0'}
- /buffer-xor/1.0.3:
- resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==}
- dev: true
+ chromium-bidi@5.1.0:
+ resolution: {integrity: sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==}
+ peerDependencies:
+ devtools-protocol: '*'
- /buffer/5.7.1:
- resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
- dependencies:
- base64-js: 1.5.1
- ieee754: 1.2.1
- dev: true
+ cli-boxes@3.0.0:
+ resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
+ engines: {node: '>=10'}
- /builtin-modules/3.3.0:
- resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
- engines: {node: '>=6'}
- dev: true
+ cli-cursor@5.0.0:
+ resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
+ engines: {node: '>=18'}
- /bytes/3.0.0:
- resolution: {integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=}
- engines: {node: '>= 0.8'}
- dev: true
+ cli-truncate@4.0.0:
+ resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
+ engines: {node: '>=18'}
- /call-bind/1.0.2:
- resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
- dependencies:
- function-bind: 1.1.1
- get-intrinsic: 1.1.1
- dev: true
+ clipboardy@3.0.0:
+ resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- /callsites/3.1.0:
- resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ colorette@2.0.20:
+ resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+
+ commander@13.1.0:
+ resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
+ engines: {node: '>=18'}
+
+ comment-parser@1.4.1:
+ resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==}
+ engines: {node: '>= 12.0.0'}
+
+ commondir@1.0.1:
+ resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
+
+ compare-func@2.0.0:
+ resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
+
+ compressible@2.0.18:
+ resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
+ engines: {node: '>= 0.6'}
+
+ compression@1.7.4:
+ resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
+ engines: {node: '>= 0.8.0'}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ constantinople@4.0.1:
+ resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==}
+
+ content-disposition@0.5.2:
+ resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==}
+ engines: {node: '>= 0.6'}
+
+ conventional-changelog-angular@8.0.0:
+ resolution: {integrity: sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-atom@5.0.0:
+ resolution: {integrity: sha512-WfzCaAvSCFPkznnLgLnfacRAzjgqjLUjvf3MftfsJzQdDICqkOOpcMtdJF3wTerxSpv2IAAjX8doM3Vozqle3g==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-cli@5.0.0:
+ resolution: {integrity: sha512-9Y8fucJe18/6ef6ZlyIlT2YQUbczvoQZZuYmDLaGvcSBP+M6h+LAvf7ON7waRxKJemcCII8Yqu5/8HEfskTxJQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ conventional-changelog-codemirror@5.0.0:
+ resolution: {integrity: sha512-8gsBDI5Y3vrKUCxN6Ue8xr6occZ5nsDEc4C7jO/EovFGozx8uttCAyfhRrvoUAWi2WMm3OmYs+0mPJU7kQdYWQ==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-conventionalcommits@8.0.0:
+ resolution: {integrity: sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-core@8.0.0:
+ resolution: {integrity: sha512-EATUx5y9xewpEe10UEGNpbSHRC6cVZgO+hXQjofMqpy+gFIrcGvH3Fl6yk2VFKh7m+ffenup2N7SZJYpyD9evw==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-ember@5.0.0:
+ resolution: {integrity: sha512-RPflVfm5s4cSO33GH/Ey26oxhiC67akcxSKL8CLRT3kQX2W3dbE19sSOM56iFqUJYEwv9mD9r6k79weWe1urfg==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-eslint@6.0.0:
+ resolution: {integrity: sha512-eiUyULWjzq+ybPjXwU6NNRflApDWlPEQEHvI8UAItYW/h22RKkMnOAtfCZxMmrcMO1OKUWtcf2MxKYMWe9zJuw==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-express@5.0.0:
+ resolution: {integrity: sha512-D8Q6WctPkQpvr2HNCCmwU5GkX22BVHM0r4EW8vN0230TSyS/d6VQJDAxGb84lbg0dFjpO22MwmsikKL++Oo/oQ==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-jquery@6.0.0:
+ resolution: {integrity: sha512-2kxmVakyehgyrho2ZHBi90v4AHswkGzHuTaoH40bmeNqUt20yEkDOSpw8HlPBfvEQBwGtbE+5HpRwzj6ac2UfA==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-jshint@5.0.0:
+ resolution: {integrity: sha512-gGNphSb/opc76n2eWaO6ma4/Wqu3tpa2w7i9WYqI6Cs2fncDSI2/ihOfMvXveeTTeld0oFvwMVNV+IYQIk3F3g==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-preset-loader@5.0.0:
+ resolution: {integrity: sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-writer@8.0.0:
+ resolution: {integrity: sha512-TQcoYGRatlAnT2qEWDON/XSfnVG38JzA7E0wcGScu7RElQBkg9WWgZd1peCWFcWDh1xfb2CfsrcvOn1bbSzztA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ conventional-changelog@6.0.0:
+ resolution: {integrity: sha512-tuUH8H/19VjtD9Ig7l6TQRh+Z0Yt0NZ6w/cCkkyzUbGQTnUEmKfGtkC9gGfVgCfOL1Rzno5NgNF4KY8vR+Jo3w==}
+ engines: {node: '>=18'}
+
+ conventional-commits-filter@5.0.0:
+ resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==}
+ engines: {node: '>=18'}
+
+ conventional-commits-parser@6.0.0:
+ resolution: {integrity: sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ core-util-is@1.0.3:
+ resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+
+ cosmiconfig@9.0.0:
+ resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ typescript: '>=4.9.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ cssstyle@4.2.1:
+ resolution: {integrity: sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==}
+ engines: {node: '>=18'}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ data-uri-to-buffer@6.0.2:
+ resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
+ engines: {node: '>= 14'}
+
+ data-urls@5.0.0:
+ resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
+ engines: {node: '>=18'}
+
+ debug@2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.0:
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.1:
+ resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decimal.js@10.5.0:
+ resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==}
+
+ deep-eql@5.0.2:
+ resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
+ engines: {node: '>=6'}
+
+ deep-extend@0.6.0:
+ resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
+ engines: {node: '>=4.0.0'}
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ deepmerge@4.3.1:
+ resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
+ engines: {node: '>=0.10.0'}
+
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
+ degenerator@5.0.1:
+ resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
+ engines: {node: '>= 14'}
+
+ detect-libc@1.0.3:
+ resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+
+ devtools-protocol@0.0.1439962:
+ resolution: {integrity: sha512-jJF48UdryzKiWhJ1bLKr7BFWUQCEIT5uCNbDLqkQJBtkFxYzILJH44WN0PDKMIlGDN7Utb8vyUY85C3w4R/t2g==}
+
+ doctypes@1.1.0:
+ resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==}
+
+ dot-prop@5.3.0:
+ resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
+ engines: {node: '>=8'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ emoji-regex@10.3.0:
+ resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ end-of-stream@1.4.4:
+ resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+
+ enquirer@2.4.1:
+ resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
+ engines: {node: '>=8.6'}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ env-paths@2.2.1:
+ resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
+ engines: {node: '>=6'}
+
+ environment@1.1.0:
+ resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
+ engines: {node: '>=18'}
+
+ error-ex@1.3.2:
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+
+ es-define-property@1.0.0:
+ resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-module-lexer@1.6.0:
+ resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
+
+ es-module-lexer@1.7.0:
+ resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
+
+ esbuild-plugin-polyfill-node@0.3.0:
+ resolution: {integrity: sha512-SHG6CKUfWfYyYXGpW143NEZtcVVn8S/WHcEOxk62LuDXnY4Zpmc+WmxJKN6GMTgTClXJXhEM5KQlxKY6YjbucQ==}
+ peerDependencies:
+ esbuild: '*'
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ esbuild@0.25.8:
+ resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.1.2:
+ resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ escodegen@2.1.0:
+ resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
+ engines: {node: '>=6.0'}
+ hasBin: true
+
+ eslint-import-context@0.1.4:
+ resolution: {integrity: sha512-x3+etvB5TPxjFIq2m4tTnpt/9Ekp5GZKzXNp5ExLaS7Qv9E5BVs/Td7jxSnRtSzrgTCExXZlc0MuOdSuDLURiQ==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ unrs-resolver: ^1.0.0
+ peerDependenciesMeta:
+ unrs-resolver:
+ optional: true
+
+ eslint-import-resolver-node@0.3.9:
+ resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
+
+ eslint-plugin-import-x@4.13.1:
+ resolution: {integrity: sha512-Ua4HZBmG5TNr18q3Is+nT6mKCzNNpycqtv/+TkIK7E3w4LBlPlZI6vLwmDjXdIZtJPP2Z1Oh5+wksWwlcCjMpA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+
+ eslint-scope@8.3.0:
+ resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@4.2.0:
+ resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint@9.27.0:
+ resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+
+ espree@10.3.0:
+ resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ esquery@1.6.0:
+ resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ eventemitter3@5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+
+ execa@5.1.1:
+ resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+ engines: {node: '>=10'}
+
+ expect-type@1.2.1:
+ resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
+ engines: {node: '>=12.0.0'}
+
+ extract-zip@2.0.1:
+ resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
+ engines: {node: '>= 10.17.0'}
+ hasBin: true
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-fifo@1.3.2:
+ resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fastq@1.19.1:
+ resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
+
+ fd-slicer@1.1.0:
+ resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
+
+ fdir@6.4.4:
+ resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ file-entry-cache@8.0.0:
+ resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+ engines: {node: '>=16.0.0'}
+
+ file-saver@2.0.5:
+ resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up-simple@1.0.0:
+ resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==}
+ engines: {node: '>=18'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat-cache@4.0.1:
+ resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+ engines: {node: '>=16'}
+
+ flatted@3.3.1:
+ resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
+
+ foreground-child@3.3.0:
+ resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+ engines: {node: '>=14'}
+
+ fs-extra@11.2.0:
+ resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
+ engines: {node: '>=14.14'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ generic-names@4.0.0:
+ resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-east-asian-width@1.2.0:
+ resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
+ engines: {node: '>=18'}
+
+ get-intrinsic@1.2.4:
+ resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+ engines: {node: '>= 0.4'}
+
+ get-stream@5.2.0:
+ resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
+ engines: {node: '>=8'}
+
+ get-stream@6.0.1:
+ resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+ engines: {node: '>=10'}
+
+ get-tsconfig@4.10.0:
+ resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==}
+
+ get-tsconfig@4.10.1:
+ resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
+
+ get-uri@6.0.3:
+ resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==}
+ engines: {node: '>= 14'}
+
+ git-raw-commits@5.0.0:
+ resolution: {integrity: sha512-I2ZXrXeOc0KrCvC7swqtIFXFN+rbjnC7b2T943tvemIOVNl+XP8YnA9UVwqFhzzLClnSA60KR/qEjLpXzs73Qg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ git-semver-tags@8.0.0:
+ resolution: {integrity: sha512-N7YRIklvPH3wYWAR2vysaqGLPRcpwQ0GKdlqTiVN5w1UmCdaeY3K8s6DMKRCh54DDdzyt/OAB6C8jgVtb7Y2Fg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@10.4.5:
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ hasBin: true
+
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ globals@14.0.0:
+ resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+ engines: {node: '>=18'}
+
+ gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+
+ handlebars@4.7.8:
+ resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==}
+ engines: {node: '>=0.4.7'}
+ hasBin: true
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+
+ has-proto@1.0.3:
+ resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hash-sum@2.0.0:
+ resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ hosted-git-info@7.0.2:
+ resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ html-encoding-sniffer@4.0.0:
+ resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
+ engines: {node: '>=18'}
+
+ html-escaper@2.0.2:
+ resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+
+ http-proxy-agent@7.0.2:
+ resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
+ engines: {node: '>= 14'}
+
+ https-proxy-agent@7.0.6:
+ resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+ engines: {node: '>= 14'}
+
+ human-signals@2.1.0:
+ resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+ engines: {node: '>=10.17.0'}
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
+ icss-utils@5.1.0:
+ resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
+ engines: {node: ^10 || ^12 || >= 14}
+ peerDependencies:
+ postcss: ^8.1.0
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ ignore@7.0.4:
+ resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==}
+ engines: {node: '>= 4'}
+
+ immediate@3.0.6:
+ resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
+
+ immutable@5.0.2:
+ resolution: {integrity: sha512-1NU7hWZDkV7hJ4PJ9dur9gTNQ4ePNPN4k9/0YhwjzykTi/+3Q5pF93YU5QoVj8BuOnhLgaY8gs0U2pj4kSYVcw==}
+
+ import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+
+ import-meta-resolve@3.1.1:
+ resolution: {integrity: sha512-qeywsE/KC3w9Fd2ORrRDUw6nS/nLwZpXgfrOc2IILvZYnCaEMd+D56Vfg9k4G29gIeVi3XKql1RQatME8iYsiw==}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ index-to-position@0.1.2:
+ resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==}
+ engines: {node: '>=18'}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ini@1.3.8:
+ resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+
+ ip-address@9.0.5:
+ resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
+ engines: {node: '>= 12'}
+
+ is-arrayish@0.2.1:
+ resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+
+ is-core-module@2.15.0:
+ resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==}
+ engines: {node: '>= 0.4'}
+
+ is-docker@2.2.1:
+ resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ is-expression@4.0.0:
+ resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-fullwidth-code-point@4.0.0:
+ resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+ engines: {node: '>=12'}
+
+ is-fullwidth-code-point@5.0.0:
+ resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==}
+ engines: {node: '>=18'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-module@1.0.0:
+ resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-obj@2.0.0:
+ resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
+ engines: {node: '>=8'}
+
+ is-port-reachable@4.0.0:
+ resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ is-potential-custom-element-name@1.0.1:
+ resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
+
+ is-promise@2.2.2:
+ resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==}
+
+ is-reference@1.2.1:
+ resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
+
+ is-regex@1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+
+ is-stream@2.0.1:
+ resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+ engines: {node: '>=8'}
+
+ is-wsl@2.2.0:
+ resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+ engines: {node: '>=8'}
+
+ isarray@1.0.0:
+ resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ isexe@3.1.1:
+ resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
+ engines: {node: '>=16'}
+
+ istanbul-lib-coverage@3.2.2:
+ resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
+ engines: {node: '>=8'}
+
+ istanbul-lib-report@3.0.1:
+ resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
+ engines: {node: '>=10'}
+
+ istanbul-lib-source-maps@5.0.6:
+ resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==}
+ engines: {node: '>=10'}
+
+ istanbul-reports@3.1.7:
+ resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
+ engines: {node: '>=8'}
+
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
+ jackspeak@4.0.1:
+ resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==}
+ engines: {node: 20 || >=22}
+
+ js-stringify@1.0.2:
+ resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+
+ jsbn@1.1.0:
+ resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
+
+ jsdom@26.1.0:
+ resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ canvas: ^3.0.0
+ peerDependenciesMeta:
+ canvas:
+ optional: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
+ json-parse-even-better-errors@4.0.0:
+ resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ jsonfile@6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+
+ jstransformer@1.0.0:
+ resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==}
+
+ jszip@3.10.1:
+ resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ lie@3.3.0:
+ resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+
+ lilconfig@3.1.3:
+ resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ lint-staged@16.0.0:
+ resolution: {integrity: sha512-sUCprePs6/rbx4vKC60Hez6X10HPkpDJaGcy3D1NdwR7g1RcNkWL8q9mJMreOqmHBTs+1sNFp+wOiX9fr+hoOQ==}
+ engines: {node: '>=20.18'}
+ hasBin: true
+
+ listr2@8.3.3:
+ resolution: {integrity: sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==}
+ engines: {node: '>=18.0.0'}
+
+ loader-utils@3.3.1:
+ resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==}
+ engines: {node: '>= 12.13.0'}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash.camelcase@4.3.0:
+ resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+ log-update@6.1.0:
+ resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
+ engines: {node: '>=18'}
+
+ loupe@3.1.3:
+ resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
+
+ lru-cache@10.1.0:
+ resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==}
+ engines: {node: 14 || >=16.14}
+
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
+ lru-cache@11.0.0:
+ resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==}
+ engines: {node: 20 || >=22}
+
+ lru-cache@11.0.2:
+ resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==}
+ engines: {node: 20 || >=22}
+
+ lru-cache@7.18.3:
+ resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
+ engines: {node: '>=12'}
+
+ magic-string@0.30.17:
+ resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+
+ magicast@0.3.5:
+ resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
+
+ make-dir@4.0.0:
+ resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
+ engines: {node: '>=10'}
+
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ marked@13.0.3:
+ resolution: {integrity: sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==}
+ engines: {node: '>= 18'}
+ hasBin: true
+
+ memorystream@0.3.1:
+ resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
+ engines: {node: '>= 0.10.0'}
+
+ meow@13.2.0:
+ resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==}
+ engines: {node: '>=18'}
+
+ merge-source-map@1.1.0:
+ resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==}
+
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.33.0:
+ resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-db@1.53.0:
+ resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.18:
+ resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+
+ mimic-function@5.0.1:
+ resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
+ engines: {node: '>=18'}
+
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
+ minimatch@10.0.3:
+ resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==}
+ engines: {node: 20 || >=22}
+
+ minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ mitt@3.0.1:
+ resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+
+ monaco-editor@0.52.2:
+ resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==}
+
+ ms@2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nano-spawn@1.0.2:
+ resolution: {integrity: sha512-21t+ozMQDAL/UGgQVBbZ/xXvNO10++ZPuTmKRO8k9V3AClVRht49ahtDjfY8l1q6nSHOrE5ASfthzH3ol6R/hg==}
+ engines: {node: '>=20.17'}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ napi-postinstall@0.2.3:
+ resolution: {integrity: sha512-Mi7JISo/4Ij2tDZ2xBE2WH+/KvVlkhA6juEjpEeRAVPNCpN3nxJo/5FhDNKgBcdmcmhaH6JjgST4xY/23ZYK0w==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ negotiator@0.6.3:
+ resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
+ engines: {node: '>= 0.6'}
+
+ neo-async@2.6.2:
+ resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+
+ netmask@2.0.2:
+ resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
+ engines: {node: '>= 0.4.0'}
+
+ node-addon-api@7.1.1:
+ resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
+
+ normalize-package-data@6.0.2:
+ resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ npm-normalize-package-bin@4.0.0:
+ resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ npm-run-all2@7.0.2:
+ resolution: {integrity: sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==}
+ engines: {node: ^18.17.0 || >=20.5.0, npm: '>= 9'}
+ hasBin: true
+
+ npm-run-path@4.0.1:
+ resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
+ engines: {node: '>=8'}
+
+ nwsapi@2.2.16:
+ resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ on-headers@1.0.2:
+ resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
+ engines: {node: '>= 0.8'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+
+ onetime@7.0.0:
+ resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
+ engines: {node: '>=18'}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ pac-proxy-agent@7.1.0:
+ resolution: {integrity: sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==}
+ engines: {node: '>= 14'}
+
+ pac-resolver@7.0.1:
+ resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
+ engines: {node: '>= 14'}
+
+ package-json-from-dist@1.0.0:
+ resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
+
+ pako@1.0.11:
+ resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ parse-json@5.2.0:
+ resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
+ engines: {node: '>=8'}
+
+ parse-json@8.1.0:
+ resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==}
+ engines: {node: '>=18'}
+
+ parse5@7.2.1:
+ resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-is-inside@1.0.2:
+ resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ path-to-regexp@3.3.0:
+ resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ pathval@2.0.0:
+ resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
+ engines: {node: '>= 14.16'}
+
+ pend@1.2.0:
+ resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.2:
+ resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+ engines: {node: '>=12'}
+
+ pidtree@0.6.0:
+ resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+
+ postcss-modules-extract-imports@3.1.0:
+ resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==}
+ engines: {node: ^10 || ^12 || >= 14}
+ peerDependencies:
+ postcss: ^8.1.0
+
+ postcss-modules-local-by-default@4.0.5:
+ resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==}
+ engines: {node: ^10 || ^12 || >= 14}
+ peerDependencies:
+ postcss: ^8.1.0
+
+ postcss-modules-scope@3.2.0:
+ resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==}
+ engines: {node: ^10 || ^12 || >= 14}
+ peerDependencies:
+ postcss: ^8.1.0
+
+ postcss-modules-values@4.0.0:
+ resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==}
+ engines: {node: ^10 || ^12 || >= 14}
+ peerDependencies:
+ postcss: ^8.1.0
+
+ postcss-modules@6.0.1:
+ resolution: {integrity: sha512-zyo2sAkVvuZFFy0gc2+4O+xar5dYlaVy/ebO24KT0ftk/iJevSNyPyQellsBLlnccwh7f6V6Y4GvuKRYToNgpQ==}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss-selector-parser@7.1.0:
+ resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.5.6:
+ resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prettier@3.5.3:
+ resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ pretty-bytes@6.1.1:
+ resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
+ engines: {node: ^14.13.1 || >=16.0.0}
+
+ process-nextick-args@2.0.1:
+ resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+
+ progress@2.0.3:
+ resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
+ engines: {node: '>=0.4.0'}
+
+ promise@7.3.1:
+ resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==}
+
+ proxy-agent@6.5.0:
+ resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==}
+ engines: {node: '>= 14'}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
+ pug-attrs@3.0.0:
+ resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==}
+
+ pug-code-gen@3.0.3:
+ resolution: {integrity: sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==}
+
+ pug-error@2.1.0:
+ resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==}
+
+ pug-filters@4.0.0:
+ resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==}
+
+ pug-lexer@5.0.1:
+ resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==}
+
+ pug-linker@4.0.0:
+ resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==}
+
+ pug-load@3.0.0:
+ resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==}
+
+ pug-parser@6.0.0:
+ resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==}
+
+ pug-runtime@3.0.1:
+ resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==}
+
+ pug-strip-comments@2.0.0:
+ resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==}
+
+ pug-walk@2.0.0:
+ resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==}
+
+ pug@3.0.3:
+ resolution: {integrity: sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==}
+
+ pump@3.0.0:
+ resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ puppeteer-core@24.9.0:
+ resolution: {integrity: sha512-HFdCeH/wx6QPz8EncafbCqJBqaCG1ENW75xg3cLFMRUoqZDgByT6HSueiumetT2uClZxwqj0qS4qMVZwLHRHHw==}
+ engines: {node: '>=18'}
+
+ puppeteer@24.9.0:
+ resolution: {integrity: sha512-L0pOtALIx8rgDt24Y+COm8X52v78gNtBOW6EmUcEPci0TYD72SAuaXKqasRIx4JXxmg2Tkw5ySKcpPOwN8xXnQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ queue-tick@1.0.1:
+ resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
+
+ range-parser@1.2.0:
+ resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==}
+ engines: {node: '>= 0.6'}
+
+ rc@1.2.8:
+ resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
+ hasBin: true
+
+ read-package-json-fast@4.0.0:
+ resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ read-package-up@11.0.0:
+ resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==}
+ engines: {node: '>=18'}
+
+ read-pkg@9.0.1:
+ resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==}
+ engines: {node: '>=18'}
+
+ readable-stream@2.3.8:
+ resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+
+ readdirp@4.0.1:
+ resolution: {integrity: sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==}
+ engines: {node: '>= 14.16.0'}
+
+ registry-auth-token@3.3.2:
+ resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==}
+
+ registry-url@3.1.0:
+ resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==}
+ engines: {node: '>=0.10.0'}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
+ restore-cursor@5.1.0:
+ resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
+ engines: {node: '>=18'}
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ rollup-plugin-dts@6.2.1:
+ resolution: {integrity: sha512-sR3CxYUl7i2CHa0O7bA45mCrgADyAQ0tVtGSqi3yvH28M+eg1+g5d7kQ9hLvEz5dorK3XVsH5L2jwHLQf72DzA==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ rollup: ^3.29.4 || ^4
+ typescript: ^4.5 || ^5.0
+
+ rollup-plugin-esbuild@6.2.1:
+ resolution: {integrity: sha512-jTNOMGoMRhs0JuueJrJqbW8tOwxumaWYq+V5i+PD+8ecSCVkuX27tGW7BXqDgoULQ55rO7IdNxPcnsWtshz3AA==}
+ engines: {node: '>=14.18.0'}
+ peerDependencies:
+ esbuild: '>=0.18.0'
+ rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
+
+ rollup-plugin-polyfill-node@0.13.0:
+ resolution: {integrity: sha512-FYEvpCaD5jGtyBuBFcQImEGmTxDTPbiHjJdrYIp+mFIwgXiXabxvKUK7ZT9P31ozu2Tqm9llYQMRWsfvTMTAOw==}
+ peerDependencies:
+ rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
+
+ rollup@4.45.1:
+ resolution: {integrity: sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ rrweb-cssom@0.8.0:
+ resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-buffer@5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ sass@1.89.2:
+ resolution: {integrity: sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ saxes@6.0.0:
+ resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+ engines: {node: '>=v12.22.7'}
+
+ semver@7.7.2:
+ resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ serve-handler@6.1.6:
+ resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==}
+
+ serve@14.2.4:
+ resolution: {integrity: sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
+ setimmediate@1.0.5:
+ resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ shell-quote@1.8.1:
+ resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ signal-exit@3.0.7:
+ resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ simple-git-hooks@2.13.0:
+ resolution: {integrity: sha512-N+goiLxlkHJlyaYEglFypzVNMaNplPAk5syu0+OPp/Bk6dwVoXF6FfOw2vO0Dp+JHsBaI+w6cm8TnFl2Hw6tDA==}
+ hasBin: true
+
+ slice-ansi@5.0.0:
+ resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
+ engines: {node: '>=12'}
+
+ slice-ansi@7.1.0:
+ resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
+ engines: {node: '>=18'}
+
+ smart-buffer@4.2.0:
+ resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
+ engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
+
+ socks-proxy-agent@8.0.5:
+ resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
+ engines: {node: '>= 14'}
+
+ socks@2.8.3:
+ resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
+ engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ spdx-correct@3.2.0:
+ resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
+
+ spdx-exceptions@2.5.0:
+ resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
+
+ spdx-expression-parse@3.0.1:
+ resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
+
+ spdx-license-ids@3.0.18:
+ resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==}
+
+ sprintf-js@1.1.3:
+ resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
+
+ stable-hash@0.0.5:
+ resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@3.9.0:
+ resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
+
+ streamx@2.18.0:
+ resolution: {integrity: sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==}
+
+ string-argv@0.3.2:
+ resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
+ engines: {node: '>=0.6.19'}
+
+ string-hash@1.1.3:
+ resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ string-width@7.2.0:
+ resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
+ engines: {node: '>=18'}
+
+ string_decoder@1.1.1:
+ resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ strip-final-newline@2.0.0:
+ resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
- dev: true
- /camelcase-keys/6.2.2:
- resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
- engines: {node: '>=8'}
+ strip-json-comments@2.0.1:
+ resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
+ engines: {node: '>=0.10.0'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ symbol-tree@3.2.4:
+ resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+
+ tar-fs@3.0.8:
+ resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==}
+
+ tar-stream@3.1.7:
+ resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
+
+ temp-dir@3.0.0:
+ resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==}
+ engines: {node: '>=14.16'}
+
+ tempfile@5.0.0:
+ resolution: {integrity: sha512-bX655WZI/F7EoTDw9JvQURqAXiPHi8o8+yFxPF2lWYyz1aHnmMRuXWqL6YB6GmeO0o4DIYWHLgGNi/X64T+X4Q==}
+ engines: {node: '>=14.18'}
+
+ test-exclude@7.0.1:
+ resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==}
+ engines: {node: '>=18'}
+
+ text-decoder@1.1.1:
+ resolution: {integrity: sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ tinyglobby@0.2.13:
+ resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
+ engines: {node: '>=12.0.0'}
+
+ tinypool@1.0.2:
+ resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+
+ tinyrainbow@2.0.0:
+ resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
+ engines: {node: '>=14.0.0'}
+
+ tinyspy@3.0.2:
+ resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
+ engines: {node: '>=14.0.0'}
+
+ tldts-core@6.1.86:
+ resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==}
+
+ tldts@6.1.86:
+ resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==}
+ hasBin: true
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ todomvc-app-css@2.4.3:
+ resolution: {integrity: sha512-mSnWZaKBWj9aQcFRsGguY/a8O8NR8GmecD48yU1rzwNemgZa/INLpIsxxMiToFGVth+uEKBrQ7IhWkaXZxwq5Q==}
+ engines: {node: '>=4'}
+
+ token-stream@1.0.0:
+ resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==}
+
+ tough-cookie@5.1.2:
+ resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
+ engines: {node: '>=16'}
+
+ tr46@5.1.1:
+ resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
+ engines: {node: '>=18'}
+
+ ts-api-utils@2.1.0:
+ resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-fest@2.19.0:
+ resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
+ engines: {node: '>=12.20'}
+
+ type-fest@4.24.0:
+ resolution: {integrity: sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==}
+ engines: {node: '>=16'}
+
+ typed-query-selector@2.12.0:
+ resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==}
+
+ typescript-eslint@8.32.1:
+ resolution: {integrity: sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.9.0'
+
+ typescript@5.6.3:
+ resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ uglify-js@3.19.1:
+ resolution: {integrity: sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==}
+ engines: {node: '>=0.8.0'}
+ hasBin: true
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ unicorn-magic@0.1.0:
+ resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
+ engines: {node: '>=18'}
+
+ universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+
+ unplugin-utils@0.2.4:
+ resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==}
+ engines: {node: '>=18.12.0'}
+
+ unrs-resolver@1.7.2:
+ resolution: {integrity: sha512-BBKpaylOW8KbHsu378Zky/dGh4ckT/4NW/0SHRABdqRLcQJ2dAOjDo9g97p04sWflm0kqPqpUatxReNV/dqI5A==}
+
+ update-check@1.5.4:
+ resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==}
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ validate-npm-package-license@3.0.4:
+ resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+
+ vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+
+ vite-node@3.1.4:
+ resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+
+ vite@5.4.15:
+ resolution: {integrity: sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vite@5.4.19:
+ resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vitest@3.1.4:
+ resolution: {integrity: sha512-Ta56rT7uWxCSJXlBtKgIlApJnT6e6IGmTYxYcmxjJ4ujuZDI59GUQgVDObXXJujOmPDBYXHK1qmaGtneu6TNIQ==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@types/debug': ^4.1.12
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ '@vitest/browser': 3.1.4
+ '@vitest/ui': 3.1.4
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@types/debug':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ void-elements@3.1.0:
+ resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
+ engines: {node: '>=0.10.0'}
+
+ w3c-xmlserializer@5.0.0:
+ resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
+ engines: {node: '>=18'}
+
+ webidl-conversions@7.0.0:
+ resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
+ engines: {node: '>=12'}
+
+ whatwg-encoding@3.1.1:
+ resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
+ engines: {node: '>=18'}
+
+ whatwg-mimetype@4.0.0:
+ resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
+ engines: {node: '>=18'}
+
+ whatwg-url@14.2.0:
+ resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
+ engines: {node: '>=18'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ which@5.0.0:
+ resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+ hasBin: true
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ widest-line@4.0.1:
+ resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==}
+ engines: {node: '>=12'}
+
+ with@7.0.2:
+ resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==}
+ engines: {node: '>= 10.0.0'}
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ wordwrap@1.0.0:
+ resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ wrap-ansi@9.0.0:
+ resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
+ engines: {node: '>=18'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ ws@8.18.1:
+ resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ ws@8.18.2:
+ resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ xml-name-validator@5.0.0:
+ resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
+ engines: {node: '>=18'}
+
+ xmlchars@2.2.0:
+ resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yaml@2.8.0:
+ resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
+ yauzl@2.10.0:
+ resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ zod@3.24.1:
+ resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
+
+snapshots:
+
+ '@ampproject/remapping@2.3.0':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@asamuzakjp/css-color@2.8.2':
+ dependencies:
+ '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)
+ '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)
+ '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3)
+ '@csstools/css-tokenizer': 3.0.3
+ lru-cache: 11.0.2
+
+ '@babel/code-frame@7.26.2':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.27.1
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.27.1': {}
+
+ '@babel/parser@7.28.0':
dependencies:
- camelcase: 5.3.1
- map-obj: 4.3.0
- quick-lru: 4.0.1
- dev: true
+ '@babel/types': 7.28.1
- /camelcase/4.1.0:
- resolution: {integrity: sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=}
- engines: {node: '>=4'}
- dev: true
+ '@babel/types@7.28.1':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.27.1
- /camelcase/5.3.1:
- resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
- engines: {node: '>=6'}
- dev: true
+ '@bcoe/v8-coverage@1.0.2': {}
- /camelcase/6.2.1:
- resolution: {integrity: sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==}
- engines: {node: '>=10'}
- dev: true
+ '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)':
+ dependencies:
+ '@types/semver': 7.7.0
+ semver: 7.7.2
+ optionalDependencies:
+ conventional-commits-filter: 5.0.0
+ conventional-commits-parser: 6.0.0
- /caniuse-lite/1.0.30001286:
- resolution: {integrity: sha512-zaEMRH6xg8ESMi2eQ3R4eZ5qw/hJiVsO/HlLwniIwErij0JDr9P+8V4dtx1l+kLq6j3yy8l8W4fst1lBnat5wQ==}
- dev: true
+ '@csstools/color-helpers@5.0.1': {}
- /chalk/2.4.1:
- resolution: {integrity: sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==}
- engines: {node: '>=4'}
+ '@csstools/css-calc@2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)':
dependencies:
- ansi-styles: 3.2.1
- escape-string-regexp: 1.0.5
- supports-color: 5.5.0
- dev: true
+ '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3)
+ '@csstools/css-tokenizer': 3.0.3
- /chalk/2.4.2:
- resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
- engines: {node: '>=4'}
+ '@csstools/css-color-parser@3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)':
dependencies:
- ansi-styles: 3.2.1
- escape-string-regexp: 1.0.5
- supports-color: 5.5.0
- dev: true
+ '@csstools/color-helpers': 5.0.1
+ '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)
+ '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3)
+ '@csstools/css-tokenizer': 3.0.3
- /chalk/4.1.2:
- resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
- engines: {node: '>=10'}
+ '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)':
dependencies:
- ansi-styles: 4.3.0
- supports-color: 7.2.0
- dev: true
+ '@csstools/css-tokenizer': 3.0.3
- /char-regex/1.0.2:
- resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
- engines: {node: '>=10'}
- dev: true
+ '@csstools/css-tokenizer@3.0.3': {}
- /character-parser/2.2.0:
- resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==}
+ '@emnapi/core@1.4.3':
dependencies:
- is-regex: 1.1.4
- dev: true
+ '@emnapi/wasi-threads': 1.0.2
+ tslib: 2.8.1
+ optional: true
- /chokidar/3.5.2:
- resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==}
- engines: {node: '>= 8.10.0'}
+ '@emnapi/runtime@1.4.3':
dependencies:
- anymatch: 3.1.2
- braces: 3.0.2
- glob-parent: 5.1.2
- is-binary-path: 2.1.0
- is-glob: 4.0.3
- normalize-path: 3.0.0
- readdirp: 3.6.0
- optionalDependencies:
- fsevents: 2.3.2
- dev: true
+ tslib: 2.8.1
+ optional: true
- /chownr/1.1.4:
- resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
- dev: true
+ '@emnapi/wasi-threads@1.0.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
- /ci-info/3.3.0:
- resolution: {integrity: sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==}
- dev: true
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
- /cipher-base/1.0.4:
- resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==}
- dependencies:
- inherits: 2.0.4
- safe-buffer: 5.2.1
- dev: true
+ '@esbuild/aix-ppc64@0.25.8':
+ optional: true
- /cjs-module-lexer/1.2.2:
- resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==}
- dev: true
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
- /clean-stack/2.2.0:
- resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
- engines: {node: '>=6'}
- dev: true
+ '@esbuild/android-arm64@0.25.8':
+ optional: true
- /cli-boxes/1.0.0:
- resolution: {integrity: sha1-T6kXw+WclKAEzWH47lCdplFocUM=}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@esbuild/android-arm@0.21.5':
+ optional: true
- /cli-cursor/3.1.0:
- resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
- engines: {node: '>=8'}
- dependencies:
- restore-cursor: 3.1.0
- dev: true
+ '@esbuild/android-arm@0.25.8':
+ optional: true
- /cli-truncate/2.1.0:
- resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==}
- engines: {node: '>=8'}
- dependencies:
- slice-ansi: 3.0.0
- string-width: 4.2.3
- dev: true
+ '@esbuild/android-x64@0.21.5':
+ optional: true
- /clipboardy/2.3.0:
- resolution: {integrity: sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==}
- engines: {node: '>=8'}
- dependencies:
- arch: 2.2.0
- execa: 1.0.0
- is-wsl: 2.2.0
- dev: true
+ '@esbuild/android-x64@0.25.8':
+ optional: true
- /cliui/7.0.4:
- resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
- dev: true
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
- /cliui/8.0.1:
- resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
- engines: {node: '>=12'}
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
- dev: true
+ '@esbuild/darwin-arm64@0.25.8':
+ optional: true
- /clone/0.1.19:
- resolution: {integrity: sha512-IO78I0y6JcSpEPHzK4obKdsL7E7oLdRVDVOLwr2Hkbjsb+Eoz0dxW6tef0WizoKu0gLC4oZSZuEF4U2K6w1WQw==}
- dev: true
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
- /co/4.6.0:
- resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
- engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
- dev: true
+ '@esbuild/darwin-x64@0.25.8':
+ optional: true
- /collect-v8-coverage/1.0.1:
- resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==}
- dev: true
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
- /color-convert/1.9.3:
- resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
- dependencies:
- color-name: 1.1.3
- dev: true
+ '@esbuild/freebsd-arm64@0.25.8':
+ optional: true
- /color-convert/2.0.1:
- resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
- engines: {node: '>=7.0.0'}
- dependencies:
- color-name: 1.1.4
- dev: true
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
- /color-name/1.1.3:
- resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=}
- dev: true
+ '@esbuild/freebsd-x64@0.25.8':
+ optional: true
- /color-name/1.1.4:
- resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
- dev: true
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
- /colorette/2.0.16:
- resolution: {integrity: sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==}
- dev: true
+ '@esbuild/linux-arm64@0.25.8':
+ optional: true
- /colors/1.2.5:
- resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==}
- engines: {node: '>=0.1.90'}
- dev: true
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
- /combined-stream/1.0.8:
- resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
- engines: {node: '>= 0.8'}
- dependencies:
- delayed-stream: 1.0.0
- dev: true
+ '@esbuild/linux-arm@0.25.8':
+ optional: true
- /commander/2.20.3:
- resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
- dev: true
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
- /commander/6.2.1:
- resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
- engines: {node: '>= 6'}
- dev: true
+ '@esbuild/linux-ia32@0.25.8':
+ optional: true
- /commondir/1.0.1:
- resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
- dev: true
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
- /compare-func/2.0.0:
- resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
- dependencies:
- array-ify: 1.0.0
- dot-prop: 5.3.0
- dev: true
+ '@esbuild/linux-loong64@0.25.8':
+ optional: true
- /compressible/2.0.18:
- resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
- engines: {node: '>= 0.6'}
- dependencies:
- mime-db: 1.51.0
- dev: true
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
- /compression/1.7.3:
- resolution: {integrity: sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- accepts: 1.3.7
- bytes: 3.0.0
- compressible: 2.0.18
- debug: 2.6.9
- on-headers: 1.0.2
- safe-buffer: 5.1.2
- vary: 1.1.2
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/linux-mips64el@0.25.8':
+ optional: true
- /concat-map/0.0.1:
- resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
- dev: true
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
- /concat-stream/1.6.2:
- resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
- engines: {'0': node >= 0.8}
- dependencies:
- buffer-from: 1.1.2
- inherits: 2.0.4
- readable-stream: 2.3.7
- typedarray: 0.0.6
- dev: true
+ '@esbuild/linux-ppc64@0.25.8':
+ optional: true
- /constantinople/4.0.1:
- resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==}
- dependencies:
- '@babel/parser': 7.16.4
- '@babel/types': 7.16.0
- dev: true
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
- /content-disposition/0.5.2:
- resolution: {integrity: sha1-DPaLud318r55YcOoUXjLhdunjLQ=}
- engines: {node: '>= 0.6'}
- dev: true
+ '@esbuild/linux-riscv64@0.25.8':
+ optional: true
- /conventional-changelog-angular/5.0.13:
- resolution: {integrity: sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==}
- engines: {node: '>=10'}
- dependencies:
- compare-func: 2.0.0
- q: 1.5.1
- dev: true
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
- /conventional-changelog-atom/2.0.8:
- resolution: {integrity: sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==}
- engines: {node: '>=10'}
- dependencies:
- q: 1.5.1
- dev: true
+ '@esbuild/linux-s390x@0.25.8':
+ optional: true
- /conventional-changelog-cli/2.1.1:
- resolution: {integrity: sha512-xMGQdKJ+4XFDDgfX5aK7UNFduvJMbvF5BB+g0OdVhA3rYdYyhctrIE2Al+WYdZeKTdg9YzMWF2iFPT8MupIwng==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- add-stream: 1.0.0
- conventional-changelog: 3.1.24
- lodash: 4.17.21
- meow: 8.1.2
- tempfile: 3.0.0
- dev: true
-
- /conventional-changelog-codemirror/2.0.8:
- resolution: {integrity: sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==}
- engines: {node: '>=10'}
- dependencies:
- q: 1.5.1
- dev: true
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
- /conventional-changelog-conventionalcommits/4.6.1:
- resolution: {integrity: sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==}
- engines: {node: '>=10'}
- dependencies:
- compare-func: 2.0.0
- lodash: 4.17.21
- q: 1.5.1
- dev: true
+ '@esbuild/linux-x64@0.25.8':
+ optional: true
- /conventional-changelog-core/4.2.4:
- resolution: {integrity: sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==}
- engines: {node: '>=10'}
- dependencies:
- add-stream: 1.0.0
- conventional-changelog-writer: 5.0.0
- conventional-commits-parser: 3.2.3
- dateformat: 3.0.3
- get-pkg-repo: 4.2.1
- git-raw-commits: 2.0.10
- git-remote-origin-url: 2.0.0
- git-semver-tags: 4.1.1
- lodash: 4.17.21
- normalize-package-data: 3.0.3
- q: 1.5.1
- read-pkg: 3.0.0
- read-pkg-up: 3.0.0
- through2: 4.0.2
- dev: true
-
- /conventional-changelog-ember/2.0.9:
- resolution: {integrity: sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==}
- engines: {node: '>=10'}
- dependencies:
- q: 1.5.1
- dev: true
+ '@esbuild/netbsd-arm64@0.25.8':
+ optional: true
- /conventional-changelog-eslint/3.0.9:
- resolution: {integrity: sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==}
- engines: {node: '>=10'}
- dependencies:
- q: 1.5.1
- dev: true
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
- /conventional-changelog-express/2.0.6:
- resolution: {integrity: sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==}
- engines: {node: '>=10'}
- dependencies:
- q: 1.5.1
- dev: true
+ '@esbuild/netbsd-x64@0.25.8':
+ optional: true
- /conventional-changelog-jquery/3.0.11:
- resolution: {integrity: sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==}
- engines: {node: '>=10'}
- dependencies:
- q: 1.5.1
- dev: true
+ '@esbuild/openbsd-arm64@0.25.8':
+ optional: true
- /conventional-changelog-jshint/2.0.9:
- resolution: {integrity: sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==}
- engines: {node: '>=10'}
- dependencies:
- compare-func: 2.0.0
- q: 1.5.1
- dev: true
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
- /conventional-changelog-preset-loader/2.3.4:
- resolution: {integrity: sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==}
- engines: {node: '>=10'}
- dev: true
+ '@esbuild/openbsd-x64@0.25.8':
+ optional: true
- /conventional-changelog-writer/5.0.0:
- resolution: {integrity: sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- conventional-commits-filter: 2.0.7
- dateformat: 3.0.3
- handlebars: 4.7.7
- json-stringify-safe: 5.0.1
- lodash: 4.17.21
- meow: 8.1.2
- semver: 6.3.0
- split: 1.0.1
- through2: 4.0.2
- dev: true
-
- /conventional-changelog/3.1.24:
- resolution: {integrity: sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==}
- engines: {node: '>=10'}
- dependencies:
- conventional-changelog-angular: 5.0.13
- conventional-changelog-atom: 2.0.8
- conventional-changelog-codemirror: 2.0.8
- conventional-changelog-conventionalcommits: 4.6.1
- conventional-changelog-core: 4.2.4
- conventional-changelog-ember: 2.0.9
- conventional-changelog-eslint: 3.0.9
- conventional-changelog-express: 2.0.6
- conventional-changelog-jquery: 3.0.11
- conventional-changelog-jshint: 2.0.9
- conventional-changelog-preset-loader: 2.3.4
- dev: true
-
- /conventional-commits-filter/2.0.7:
- resolution: {integrity: sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==}
- engines: {node: '>=10'}
- dependencies:
- lodash.ismatch: 4.4.0
- modify-values: 1.0.1
- dev: true
+ '@esbuild/openharmony-arm64@0.25.8':
+ optional: true
- /conventional-commits-parser/3.2.3:
- resolution: {integrity: sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- JSONStream: 1.3.5
- is-text-path: 1.0.1
- lodash: 4.17.21
- meow: 8.1.2
- split2: 3.2.2
- through2: 4.0.2
- dev: true
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
- /convert-source-map/1.8.0:
- resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
- dependencies:
- safe-buffer: 5.1.2
- dev: true
+ '@esbuild/sunos-x64@0.25.8':
+ optional: true
- /convert-source-map/2.0.0:
- resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
- dev: true
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
- /core-util-is/1.0.3:
- resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+ '@esbuild/win32-arm64@0.25.8':
+ optional: true
- /cosmiconfig/7.0.1:
- resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==}
- engines: {node: '>=10'}
- dependencies:
- '@types/parse-json': 4.0.0
- import-fresh: 3.3.0
- parse-json: 5.2.0
- path-type: 4.0.0
- yaml: 1.10.2
- dev: true
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
- /create-ecdh/4.0.4:
- resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==}
- dependencies:
- bn.js: 4.12.0
- elliptic: 6.5.4
- dev: true
+ '@esbuild/win32-ia32@0.25.8':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.25.8':
+ optional: true
- /create-hash/1.2.0:
- resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==}
+ '@eslint-community/eslint-utils@4.6.1(eslint@9.27.0)':
dependencies:
- cipher-base: 1.0.4
- inherits: 2.0.4
- md5.js: 1.3.5
- ripemd160: 2.0.2
- sha.js: 2.4.11
- dev: true
+ eslint: 9.27.0
+ eslint-visitor-keys: 3.4.3
- /create-hmac/1.1.7:
- resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==}
+ '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0)':
dependencies:
- cipher-base: 1.0.4
- create-hash: 1.2.0
- inherits: 2.0.4
- ripemd160: 2.0.2
- safe-buffer: 5.2.1
- sha.js: 2.4.11
- dev: true
+ eslint: 9.27.0
+ eslint-visitor-keys: 3.4.3
- /cross-fetch/3.1.5:
- resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
+ '@eslint-community/regexpp@4.12.1': {}
+
+ '@eslint/config-array@0.20.0':
dependencies:
- node-fetch: 2.6.7
+ '@eslint/object-schema': 2.1.6
+ debug: 4.4.0
+ minimatch: 3.1.2
transitivePeerDependencies:
- - encoding
- dev: true
-
- /cross-spawn/5.1.0:
- resolution: {integrity: sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=}
- dependencies:
- lru-cache: 4.1.5
- shebang-command: 1.2.0
- which: 1.3.1
- dev: true
-
- /cross-spawn/6.0.5:
- resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==}
- engines: {node: '>=4.8'}
- dependencies:
- nice-try: 1.0.5
- path-key: 2.0.1
- semver: 5.7.1
- shebang-command: 1.2.0
- which: 1.3.1
- dev: true
-
- /cross-spawn/7.0.3:
- resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
- engines: {node: '>= 8'}
+ - supports-color
+
+ '@eslint/config-helpers@0.2.1': {}
+
+ '@eslint/core@0.14.0':
dependencies:
- path-key: 3.1.1
- shebang-command: 2.0.0
- which: 2.0.2
- dev: true
+ '@types/json-schema': 7.0.15
- /crypto-browserify/3.12.0:
- resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==}
+ '@eslint/eslintrc@3.3.1':
dependencies:
- browserify-cipher: 1.0.1
- browserify-sign: 4.2.1
- create-ecdh: 4.0.4
- create-hash: 1.2.0
- create-hmac: 1.1.7
- diffie-hellman: 5.0.3
- inherits: 2.0.4
- pbkdf2: 3.1.2
- public-encrypt: 4.0.3
- randombytes: 2.1.0
- randomfill: 1.0.4
- dev: true
+ ajv: 6.12.6
+ debug: 4.4.0
+ espree: 10.3.0
+ globals: 14.0.0
+ ignore: 5.3.2
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
- /cssesc/3.0.0:
- resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
- engines: {node: '>=4'}
- hasBin: true
- dev: true
+ '@eslint/js@9.27.0': {}
+
+ '@eslint/object-schema@2.1.6': {}
- /cssom/0.3.8:
- resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
- dev: true
+ '@eslint/plugin-kit@0.3.1':
+ dependencies:
+ '@eslint/core': 0.14.0
+ levn: 0.4.1
- /cssom/0.5.0:
- resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==}
- dev: true
+ '@humanfs/core@0.19.1': {}
- /cssstyle/2.3.0:
- resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==}
- engines: {node: '>=8'}
+ '@humanfs/node@0.16.6':
dependencies:
- cssom: 0.3.8
- dev: true
+ '@humanfs/core': 0.19.1
+ '@humanwhocodes/retry': 0.3.1
- /csstype/2.6.19:
- resolution: {integrity: sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==}
- dev: false
+ '@humanwhocodes/module-importer@1.0.1': {}
- /csstype/3.0.10:
- resolution: {integrity: sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==}
- dev: true
+ '@humanwhocodes/retry@0.3.1': {}
- /dargs/7.0.0:
- resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
- engines: {node: '>=8'}
- dev: true
+ '@humanwhocodes/retry@0.4.2': {}
- /data-urls/3.0.2:
- resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==}
- engines: {node: '>=12'}
- dependencies:
- abab: 2.0.6
- whatwg-mimetype: 3.0.0
- whatwg-url: 11.0.0
- dev: true
+ '@hutson/parse-repository-url@5.0.0': {}
- /dateformat/3.0.3:
- resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==}
- dev: true
+ '@isaacs/balanced-match@4.0.1': {}
- /debug/2.6.9:
- resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
+ '@isaacs/brace-expansion@5.0.0':
dependencies:
- ms: 2.0.0
- dev: true
+ '@isaacs/balanced-match': 4.0.1
- /debug/4.3.3:
- resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
+ '@isaacs/cliui@8.0.2':
dependencies:
- ms: 2.1.2
- dev: true
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
- /debug/4.3.4:
- resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.1.2
- dev: true
+ '@istanbuljs/schema@0.1.3': {}
- /decamelize-keys/1.1.0:
- resolution: {integrity: sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=}
- engines: {node: '>=0.10.0'}
+ '@jridgewell/gen-mapping@0.3.5':
dependencies:
- decamelize: 1.2.0
- map-obj: 1.0.1
- dev: true
-
- /decamelize/1.2.0:
- resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
- /decimal.js/10.4.2:
- resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==}
- dev: true
+ '@jridgewell/resolve-uri@3.1.2': {}
- /dedent/0.7.0:
- resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=}
- dev: true
+ '@jridgewell/set-array@1.2.1': {}
- /deep-extend/0.6.0:
- resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
- engines: {node: '>=4.0.0'}
- dev: true
+ '@jridgewell/sourcemap-codec@1.5.0': {}
- /deep-is/0.1.4:
- resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
- dev: true
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
- /deepmerge/4.2.2:
- resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@jspm/core@2.0.1': {}
- /deferred-leveldown/0.2.0:
- resolution: {integrity: sha512-+WCbb4+ez/SZ77Sdy1iadagFiVzMB89IKOBhglgnUkVxOxRWmmFsz8UDSNWh4Rhq+3wr/vMFlYj+rdEwWUDdng==}
+ '@napi-rs/wasm-runtime@0.2.9':
dependencies:
- abstract-leveldown: 0.12.4
- dev: true
+ '@emnapi/core': 1.4.3
+ '@emnapi/runtime': 1.4.3
+ '@tybys/wasm-util': 0.9.0
+ optional: true
- /define-properties/1.1.3:
- resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==}
- engines: {node: '>= 0.4'}
+ '@nodelib/fs.scandir@2.1.5':
dependencies:
- object-keys: 1.1.1
- dev: true
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
- /delayed-stream/1.0.0:
- resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
- engines: {node: '>=0.4.0'}
- dev: true
+ '@nodelib/fs.stat@2.0.5': {}
- /des.js/1.0.1:
- resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==}
+ '@nodelib/fs.walk@1.2.8':
dependencies:
- inherits: 2.0.4
- minimalistic-assert: 1.0.1
- dev: true
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.19.1
- /detect-newline/3.1.0:
- resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
- engines: {node: '>=8'}
- dev: true
+ '@parcel/watcher-android-arm64@2.4.1':
+ optional: true
- /devtools-protocol/0.0.1056733:
- resolution: {integrity: sha512-CmTu6SQx2g3TbZzDCAV58+LTxVdKplS7xip0g5oDXpZ+isr0rv5dDP8ToyVRywzPHkCCPKgKgScEcwz4uPWDIA==}
- dev: true
+ '@parcel/watcher-darwin-arm64@2.4.1':
+ optional: true
- /diff-sequences/29.3.1:
- resolution: {integrity: sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dev: true
+ '@parcel/watcher-darwin-x64@2.4.1':
+ optional: true
- /diffie-hellman/5.0.3:
- resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
- dependencies:
- bn.js: 4.12.0
- miller-rabin: 4.0.1
- randombytes: 2.1.0
- dev: true
+ '@parcel/watcher-freebsd-x64@2.4.1':
+ optional: true
- /dir-glob/3.0.1:
- resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
- engines: {node: '>=8'}
- dependencies:
- path-type: 4.0.0
- dev: true
+ '@parcel/watcher-linux-arm-glibc@2.4.1':
+ optional: true
- /doctrine/3.0.0:
- resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
- engines: {node: '>=6.0.0'}
- dependencies:
- esutils: 2.0.3
- dev: true
+ '@parcel/watcher-linux-arm64-glibc@2.4.1':
+ optional: true
+
+ '@parcel/watcher-linux-arm64-musl@2.4.1':
+ optional: true
- /doctypes/1.1.0:
- resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==}
- dev: true
+ '@parcel/watcher-linux-x64-glibc@2.4.1':
+ optional: true
- /domexception/4.0.0:
- resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==}
- engines: {node: '>=12'}
- dependencies:
- webidl-conversions: 7.0.0
- dev: true
+ '@parcel/watcher-linux-x64-musl@2.4.1':
+ optional: true
- /dot-prop/5.3.0:
- resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
- engines: {node: '>=8'}
- dependencies:
- is-obj: 2.0.0
- dev: true
+ '@parcel/watcher-win32-arm64@2.4.1':
+ optional: true
+
+ '@parcel/watcher-win32-ia32@2.4.1':
+ optional: true
- /electron-to-chromium/1.4.16:
- resolution: {integrity: sha512-BQb7FgYwnu6haWLU63/CdVW+9xhmHls3RCQUFiV4lvw3wimEHTVcUk2hkuZo76QhR8nnDdfZE7evJIZqijwPdA==}
- dev: true
+ '@parcel/watcher-win32-x64@2.4.1':
+ optional: true
- /elliptic/6.5.4:
- resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
+ '@parcel/watcher@2.4.1':
dependencies:
- bn.js: 4.12.0
- brorand: 1.1.0
- hash.js: 1.1.7
- hmac-drbg: 1.0.1
- inherits: 2.0.4
- minimalistic-assert: 1.0.1
- minimalistic-crypto-utils: 1.0.1
- dev: true
+ detect-libc: 1.0.3
+ is-glob: 4.0.3
+ micromatch: 4.0.8
+ node-addon-api: 7.1.1
+ optionalDependencies:
+ '@parcel/watcher-android-arm64': 2.4.1
+ '@parcel/watcher-darwin-arm64': 2.4.1
+ '@parcel/watcher-darwin-x64': 2.4.1
+ '@parcel/watcher-freebsd-x64': 2.4.1
+ '@parcel/watcher-linux-arm-glibc': 2.4.1
+ '@parcel/watcher-linux-arm64-glibc': 2.4.1
+ '@parcel/watcher-linux-arm64-musl': 2.4.1
+ '@parcel/watcher-linux-x64-glibc': 2.4.1
+ '@parcel/watcher-linux-x64-musl': 2.4.1
+ '@parcel/watcher-win32-arm64': 2.4.1
+ '@parcel/watcher-win32-ia32': 2.4.1
+ '@parcel/watcher-win32-x64': 2.4.1
+ optional: true
- /emittery/0.13.1:
- resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
- engines: {node: '>=12'}
- dev: true
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
- /emoji-regex/8.0.0:
- resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
- dev: true
+ '@puppeteer/browsers@2.10.5':
+ dependencies:
+ debug: 4.4.1
+ extract-zip: 2.0.1
+ progress: 2.0.3
+ proxy-agent: 6.5.0
+ semver: 7.7.2
+ tar-fs: 3.0.8
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - supports-color
- /emojis-list/3.0.0:
- resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
- engines: {node: '>= 4'}
- dev: true
+ '@rollup/plugin-alias@5.1.1(rollup@4.45.1)':
+ optionalDependencies:
+ rollup: 4.45.1
- /end-of-stream/1.4.4:
- resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+ '@rollup/plugin-commonjs@28.0.6(rollup@4.45.1)':
dependencies:
- once: 1.4.0
- dev: true
+ '@rollup/pluginutils': 5.1.0(rollup@4.45.1)
+ commondir: 1.0.1
+ estree-walker: 2.0.2
+ fdir: 6.4.4(picomatch@4.0.2)
+ is-reference: 1.2.1
+ magic-string: 0.30.17
+ picomatch: 4.0.2
+ optionalDependencies:
+ rollup: 4.45.1
- /enquirer/2.3.6:
- resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==}
- engines: {node: '>=8.6'}
+ '@rollup/plugin-inject@5.0.5(rollup@4.45.1)':
dependencies:
- ansi-colors: 4.1.1
- dev: true
-
- /entities/4.4.0:
- resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==}
- engines: {node: '>=0.12'}
- dev: true
+ '@rollup/pluginutils': 5.1.0(rollup@4.45.1)
+ estree-walker: 2.0.2
+ magic-string: 0.30.17
+ optionalDependencies:
+ rollup: 4.45.1
- /errno/0.1.8:
- resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
- hasBin: true
+ '@rollup/plugin-json@6.1.0(rollup@4.45.1)':
dependencies:
- prr: 1.0.1
- dev: true
+ '@rollup/pluginutils': 5.1.0(rollup@4.45.1)
+ optionalDependencies:
+ rollup: 4.45.1
- /error-ex/1.3.2:
- resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+ '@rollup/plugin-node-resolve@16.0.1(rollup@4.45.1)':
dependencies:
- is-arrayish: 0.2.1
- dev: true
+ '@rollup/pluginutils': 5.1.0(rollup@4.45.1)
+ '@types/resolve': 1.20.2
+ deepmerge: 4.3.1
+ is-module: 1.0.0
+ resolve: 1.22.8
+ optionalDependencies:
+ rollup: 4.45.1
- /es-abstract/1.19.1:
- resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- es-to-primitive: 1.2.1
- function-bind: 1.1.1
- get-intrinsic: 1.1.1
- get-symbol-description: 1.0.0
- has: 1.0.3
- has-symbols: 1.0.2
- internal-slot: 1.0.3
- is-callable: 1.2.4
- is-negative-zero: 2.0.2
- is-regex: 1.1.4
- is-shared-array-buffer: 1.0.1
- is-string: 1.0.7
- is-weakref: 1.0.2
- object-inspect: 1.11.1
- object-keys: 1.1.1
- object.assign: 4.1.2
- string.prototype.trimend: 1.0.4
- string.prototype.trimstart: 1.0.4
- unbox-primitive: 1.0.1
- dev: true
-
- /es-to-primitive/1.2.1:
- resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
- engines: {node: '>= 0.4'}
+ '@rollup/plugin-replace@5.0.4(rollup@4.45.1)':
dependencies:
- is-callable: 1.2.4
- is-date-object: 1.0.5
- is-symbol: 1.0.4
- dev: true
+ '@rollup/pluginutils': 5.1.0(rollup@4.45.1)
+ magic-string: 0.30.17
+ optionalDependencies:
+ rollup: 4.45.1
- /esbuild-android-64/0.14.54:
- resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
+ '@rollup/pluginutils@5.1.0(rollup@4.45.1)':
+ dependencies:
+ '@types/estree': 1.0.7
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ optionalDependencies:
+ rollup: 4.45.1
- /esbuild-android-64/0.15.13:
- resolution: {integrity: sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [android]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-android-arm-eabi@4.45.1':
optional: true
- /esbuild-android-arm64/0.14.54:
- resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-android-arm64@4.45.1':
optional: true
- /esbuild-android-arm64/0.15.13:
- resolution: {integrity: sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-darwin-arm64@4.45.1':
optional: true
- /esbuild-darwin-64/0.14.54:
- resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-darwin-x64@4.45.1':
optional: true
- /esbuild-darwin-64/0.15.13:
- resolution: {integrity: sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-freebsd-arm64@4.45.1':
optional: true
- /esbuild-darwin-arm64/0.14.54:
- resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-freebsd-x64@4.45.1':
optional: true
- /esbuild-darwin-arm64/0.15.13:
- resolution: {integrity: sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-arm-gnueabihf@4.45.1':
optional: true
- /esbuild-freebsd-64/0.14.54:
- resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-arm-musleabihf@4.45.1':
optional: true
- /esbuild-freebsd-64/0.15.13:
- resolution: {integrity: sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-arm64-gnu@4.45.1':
optional: true
- /esbuild-freebsd-arm64/0.14.54:
- resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-arm64-musl@4.45.1':
optional: true
- /esbuild-freebsd-arm64/0.15.13:
- resolution: {integrity: sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-loongarch64-gnu@4.45.1':
optional: true
- /esbuild-linux-32/0.14.54:
- resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-powerpc64le-gnu@4.45.1':
optional: true
- /esbuild-linux-32/0.15.13:
- resolution: {integrity: sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-riscv64-gnu@4.45.1':
optional: true
- /esbuild-linux-64/0.14.54:
- resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-riscv64-musl@4.45.1':
optional: true
- /esbuild-linux-64/0.15.13:
- resolution: {integrity: sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-s390x-gnu@4.45.1':
optional: true
- /esbuild-linux-arm/0.14.54:
- resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-x64-gnu@4.45.1':
optional: true
- /esbuild-linux-arm/0.15.13:
- resolution: {integrity: sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-linux-x64-musl@4.45.1':
optional: true
- /esbuild-linux-arm64/0.14.54:
- resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-win32-arm64-msvc@4.45.1':
optional: true
- /esbuild-linux-arm64/0.15.13:
- resolution: {integrity: sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-win32-ia32-msvc@4.45.1':
optional: true
- /esbuild-linux-mips64le/0.14.54:
- resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==}
- engines: {node: '>=12'}
- cpu: [mips64el]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@rollup/rollup-win32-x64-msvc@4.45.1':
optional: true
- /esbuild-linux-mips64le/0.15.13:
- resolution: {integrity: sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==}
- engines: {node: '>=12'}
- cpu: [mips64el]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-darwin-arm64@1.13.1':
optional: true
- /esbuild-linux-ppc64le/0.14.54:
- resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-darwin-x64@1.13.1':
optional: true
- /esbuild-linux-ppc64le/0.15.13:
- resolution: {integrity: sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-linux-arm-gnueabihf@1.13.1':
optional: true
- /esbuild-linux-riscv64/0.14.54:
- resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==}
- engines: {node: '>=12'}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-linux-arm64-gnu@1.13.1':
optional: true
- /esbuild-linux-riscv64/0.15.13:
- resolution: {integrity: sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==}
- engines: {node: '>=12'}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-linux-arm64-musl@1.13.1':
optional: true
- /esbuild-linux-s390x/0.14.54:
- resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==}
- engines: {node: '>=12'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-linux-x64-gnu@1.13.1':
optional: true
- /esbuild-linux-s390x/0.15.13:
- resolution: {integrity: sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==}
- engines: {node: '>=12'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: true
+ '@swc/core-linux-x64-musl@1.13.1':
optional: true
- /esbuild-netbsd-64/0.14.54:
- resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [netbsd]
- requiresBuild: true
- dev: true
+ '@swc/core-win32-arm64-msvc@1.13.1':
optional: true
- /esbuild-netbsd-64/0.15.13:
- resolution: {integrity: sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [netbsd]
- requiresBuild: true
- dev: true
+ '@swc/core-win32-ia32-msvc@1.13.1':
optional: true
- /esbuild-openbsd-64/0.14.54:
- resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
- dev: true
+ '@swc/core-win32-x64-msvc@1.13.1':
optional: true
- /esbuild-openbsd-64/0.15.13:
- resolution: {integrity: sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
- dev: true
- optional: true
+ '@swc/core@1.13.1':
+ dependencies:
+ '@swc/counter': 0.1.3
+ '@swc/types': 0.1.23
+ optionalDependencies:
+ '@swc/core-darwin-arm64': 1.13.1
+ '@swc/core-darwin-x64': 1.13.1
+ '@swc/core-linux-arm-gnueabihf': 1.13.1
+ '@swc/core-linux-arm64-gnu': 1.13.1
+ '@swc/core-linux-arm64-musl': 1.13.1
+ '@swc/core-linux-x64-gnu': 1.13.1
+ '@swc/core-linux-x64-musl': 1.13.1
+ '@swc/core-win32-arm64-msvc': 1.13.1
+ '@swc/core-win32-ia32-msvc': 1.13.1
+ '@swc/core-win32-x64-msvc': 1.13.1
- /esbuild-sunos-64/0.14.54:
- resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [sunos]
- requiresBuild: true
- dev: true
- optional: true
+ '@swc/counter@0.1.3': {}
- /esbuild-sunos-64/0.15.13:
- resolution: {integrity: sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [sunos]
- requiresBuild: true
- dev: true
- optional: true
+ '@swc/types@0.1.23':
+ dependencies:
+ '@swc/counter': 0.1.3
- /esbuild-windows-32/0.14.54:
- resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@tootallnate/quickjs-emscripten@0.23.0': {}
- /esbuild-windows-32/0.15.13:
- resolution: {integrity: sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
+ '@tybys/wasm-util@0.9.0':
+ dependencies:
+ tslib: 2.8.1
optional: true
- /esbuild-windows-64/0.14.54:
- resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@types/estree@1.0.7': {}
- /esbuild-windows-64/0.15.13:
- resolution: {integrity: sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@types/estree@1.0.8': {}
- /esbuild-windows-arm64/0.14.54:
- resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@types/hash-sum@1.0.2': {}
- /esbuild-windows-arm64/0.15.13:
- resolution: {integrity: sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@types/json-schema@7.0.15': {}
- /esbuild/0.14.54:
- resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/linux-loong64': 0.14.54
- esbuild-android-64: 0.14.54
- esbuild-android-arm64: 0.14.54
- esbuild-darwin-64: 0.14.54
- esbuild-darwin-arm64: 0.14.54
- esbuild-freebsd-64: 0.14.54
- esbuild-freebsd-arm64: 0.14.54
- esbuild-linux-32: 0.14.54
- esbuild-linux-64: 0.14.54
- esbuild-linux-arm: 0.14.54
- esbuild-linux-arm64: 0.14.54
- esbuild-linux-mips64le: 0.14.54
- esbuild-linux-ppc64le: 0.14.54
- esbuild-linux-riscv64: 0.14.54
- esbuild-linux-s390x: 0.14.54
- esbuild-netbsd-64: 0.14.54
- esbuild-openbsd-64: 0.14.54
- esbuild-sunos-64: 0.14.54
- esbuild-windows-32: 0.14.54
- esbuild-windows-64: 0.14.54
- esbuild-windows-arm64: 0.14.54
- dev: true
-
- /esbuild/0.15.13:
- resolution: {integrity: sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/android-arm': 0.15.13
- '@esbuild/linux-loong64': 0.15.13
- esbuild-android-64: 0.15.13
- esbuild-android-arm64: 0.15.13
- esbuild-darwin-64: 0.15.13
- esbuild-darwin-arm64: 0.15.13
- esbuild-freebsd-64: 0.15.13
- esbuild-freebsd-arm64: 0.15.13
- esbuild-linux-32: 0.15.13
- esbuild-linux-64: 0.15.13
- esbuild-linux-arm: 0.15.13
- esbuild-linux-arm64: 0.15.13
- esbuild-linux-mips64le: 0.15.13
- esbuild-linux-ppc64le: 0.15.13
- esbuild-linux-riscv64: 0.15.13
- esbuild-linux-s390x: 0.15.13
- esbuild-netbsd-64: 0.15.13
- esbuild-openbsd-64: 0.15.13
- esbuild-sunos-64: 0.15.13
- esbuild-windows-32: 0.15.13
- esbuild-windows-64: 0.15.13
- esbuild-windows-arm64: 0.15.13
- dev: true
-
- /escalade/3.1.1:
- resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
- engines: {node: '>=6'}
- dev: true
+ '@types/node@22.16.5':
+ dependencies:
+ undici-types: 6.21.0
- /escape-string-regexp/1.0.5:
- resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
- engines: {node: '>=0.8.0'}
- dev: true
+ '@types/normalize-package-data@2.4.4': {}
- /escape-string-regexp/2.0.0:
- resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
- engines: {node: '>=8'}
- dev: true
+ '@types/resolve@1.20.2': {}
- /escape-string-regexp/4.0.0:
- resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
- engines: {node: '>=10'}
- dev: true
+ '@types/semver@7.7.0': {}
- /escodegen/2.0.0:
- resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==}
- engines: {node: '>=6.0'}
- hasBin: true
+ '@types/serve-handler@6.1.4':
dependencies:
- esprima: 4.0.1
- estraverse: 5.3.0
- esutils: 2.0.3
- optionator: 0.8.3
- optionalDependencies:
- source-map: 0.6.1
- dev: true
+ '@types/node': 22.16.5
- /eslint-plugin-jest/26.1.5_h6y6ce27mgasm6fmt6a3uqj6ne:
- resolution: {integrity: sha512-su89aDuljL9bTjEufTXmKUMSFe2kZUL9bi7+woq+C2ukHZordhtfPm4Vg+tdioHBaKf8v3/FXW9uV0ksqhYGFw==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- peerDependencies:
- '@typescript-eslint/eslint-plugin': ^5.0.0
- eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
- jest: '*'
- peerDependenciesMeta:
- '@typescript-eslint/eslint-plugin':
- optional: true
- jest:
- optional: true
+ '@types/trusted-types@2.0.7': {}
+
+ '@types/yauzl@2.10.3':
dependencies:
- '@typescript-eslint/utils': 5.19.0_td6yqss6ra3qoebludh4ctrhym
- eslint: 7.32.0
- jest: 29.3.1_@types+node@16.11.12
+ '@types/node': 22.16.5
+ optional: true
+
+ '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0)(typescript@5.6.3))(eslint@9.27.0)(typescript@5.6.3)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.1
+ '@typescript-eslint/parser': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ '@typescript-eslint/scope-manager': 8.32.1
+ '@typescript-eslint/type-utils': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ '@typescript-eslint/visitor-keys': 8.32.1
+ eslint: 9.27.0
+ graphemer: 1.4.0
+ ignore: 7.0.4
+ natural-compare: 1.4.0
+ ts-api-utils: 2.1.0(typescript@5.6.3)
+ typescript: 5.6.3
transitivePeerDependencies:
- supports-color
- - typescript
- dev: true
- /eslint-scope/5.1.1:
- resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
- engines: {node: '>=8.0.0'}
+ '@typescript-eslint/parser@8.32.1(eslint@9.27.0)(typescript@5.6.3)':
dependencies:
- esrecurse: 4.3.0
- estraverse: 4.3.0
- dev: true
+ '@typescript-eslint/scope-manager': 8.32.1
+ '@typescript-eslint/types': 8.32.1
+ '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.6.3)
+ '@typescript-eslint/visitor-keys': 8.32.1
+ debug: 4.4.1
+ eslint: 9.27.0
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
- /eslint-utils/2.1.0:
- resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
- engines: {node: '>=6'}
+ '@typescript-eslint/scope-manager@8.32.1':
dependencies:
- eslint-visitor-keys: 1.3.0
- dev: true
+ '@typescript-eslint/types': 8.32.1
+ '@typescript-eslint/visitor-keys': 8.32.1
- /eslint-utils/3.0.0_eslint@7.32.0:
- resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
- engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
- peerDependencies:
- eslint: '>=5'
+ '@typescript-eslint/type-utils@8.32.1(eslint@9.27.0)(typescript@5.6.3)':
dependencies:
- eslint: 7.32.0
- eslint-visitor-keys: 2.1.0
- dev: true
-
- /eslint-visitor-keys/1.3.0:
- resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
- engines: {node: '>=4'}
- dev: true
-
- /eslint-visitor-keys/2.1.0:
- resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
- engines: {node: '>=10'}
- dev: true
+ '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ debug: 4.4.1
+ eslint: 9.27.0
+ ts-api-utils: 2.1.0(typescript@5.6.3)
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
- /eslint-visitor-keys/3.3.0:
- resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- dev: true
+ '@typescript-eslint/types@8.32.1': {}
- /eslint/7.32.0:
- resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==}
- engines: {node: ^10.12.0 || >=12.0.0}
- hasBin: true
+ '@typescript-eslint/typescript-estree@8.32.1(typescript@5.6.3)':
dependencies:
- '@babel/code-frame': 7.12.11
- '@eslint/eslintrc': 0.4.3
- '@humanwhocodes/config-array': 0.5.0
- ajv: 6.12.6
- chalk: 4.1.2
- cross-spawn: 7.0.3
- debug: 4.3.3
- doctrine: 3.0.0
- enquirer: 2.3.6
- escape-string-regexp: 4.0.0
- eslint-scope: 5.1.1
- eslint-utils: 2.1.0
- eslint-visitor-keys: 2.1.0
- espree: 7.3.1
- esquery: 1.4.0
- esutils: 2.0.3
- fast-deep-equal: 3.1.3
- file-entry-cache: 6.0.1
- functional-red-black-tree: 1.0.1
- glob-parent: 5.1.2
- globals: 13.12.0
- ignore: 4.0.6
- import-fresh: 3.3.0
- imurmurhash: 0.1.4
+ '@typescript-eslint/types': 8.32.1
+ '@typescript-eslint/visitor-keys': 8.32.1
+ debug: 4.4.1
+ fast-glob: 3.3.3
is-glob: 4.0.3
- js-yaml: 3.14.1
- json-stable-stringify-without-jsonify: 1.0.1
- levn: 0.4.1
- lodash.merge: 4.6.2
- minimatch: 3.0.4
- natural-compare: 1.4.0
- optionator: 0.9.1
- progress: 2.0.3
- regexpp: 3.2.0
- semver: 7.3.5
- strip-ansi: 6.0.1
- strip-json-comments: 3.1.1
- table: 6.7.5
- text-table: 0.2.0
- v8-compile-cache: 2.3.0
+ minimatch: 9.0.5
+ semver: 7.7.2
+ ts-api-utils: 2.1.0(typescript@5.6.3)
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.32.1(eslint@9.27.0)(typescript@5.6.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0)
+ '@typescript-eslint/scope-manager': 8.32.1
+ '@typescript-eslint/types': 8.32.1
+ '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.6.3)
+ eslint: 9.27.0
+ typescript: 5.6.3
transitivePeerDependencies:
- supports-color
- dev: true
- /espree/7.3.1:
- resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
- engines: {node: ^10.12.0 || >=12.0.0}
- dependencies:
- acorn: 7.4.1
- acorn-jsx: 5.3.2_acorn@7.4.1
- eslint-visitor-keys: 1.3.0
- dev: true
+ '@typescript-eslint/visitor-keys@8.32.1':
+ dependencies:
+ '@typescript-eslint/types': 8.32.1
+ eslint-visitor-keys: 4.2.0
+
+ '@unrs/resolver-binding-darwin-arm64@1.7.2':
+ optional: true
+
+ '@unrs/resolver-binding-darwin-x64@1.7.2':
+ optional: true
+
+ '@unrs/resolver-binding-freebsd-x64@1.7.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2':
+ optional: true
- /esprima/4.0.1:
- resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
- engines: {node: '>=4'}
- hasBin: true
- dev: true
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.7.2':
+ optional: true
- /esquery/1.4.0:
- resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
- engines: {node: '>=0.10'}
- dependencies:
- estraverse: 5.3.0
- dev: true
+ '@unrs/resolver-binding-linux-arm64-gnu@1.7.2':
+ optional: true
- /esrecurse/4.3.0:
- resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
- engines: {node: '>=4.0'}
- dependencies:
- estraverse: 5.3.0
- dev: true
+ '@unrs/resolver-binding-linux-arm64-musl@1.7.2':
+ optional: true
- /estraverse/4.3.0:
- resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
- engines: {node: '>=4.0'}
- dev: true
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.7.2':
+ optional: true
- /estraverse/5.3.0:
- resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
- engines: {node: '>=4.0'}
- dev: true
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.7.2':
+ optional: true
- /estree-walker/0.5.2:
- resolution: {integrity: sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==}
- dev: true
+ '@unrs/resolver-binding-linux-riscv64-musl@1.7.2':
+ optional: true
- /estree-walker/0.6.1:
- resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
- dev: true
+ '@unrs/resolver-binding-linux-s390x-gnu@1.7.2':
+ optional: true
- /estree-walker/2.0.2:
- resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+ '@unrs/resolver-binding-linux-x64-gnu@1.7.2':
+ optional: true
- /esutils/2.0.3:
- resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@unrs/resolver-binding-linux-x64-musl@1.7.2':
+ optional: true
- /evp_bytestokey/1.0.3:
- resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==}
+ '@unrs/resolver-binding-wasm32-wasi@1.7.2':
dependencies:
- md5.js: 1.3.5
- safe-buffer: 5.2.1
- dev: true
+ '@napi-rs/wasm-runtime': 0.2.9
+ optional: true
- /execa/0.7.0:
- resolution: {integrity: sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=}
- engines: {node: '>=4'}
- dependencies:
- cross-spawn: 5.1.0
- get-stream: 3.0.0
- is-stream: 1.1.0
- npm-run-path: 2.0.2
- p-finally: 1.0.0
- signal-exit: 3.0.6
- strip-eof: 1.0.0
- dev: true
-
- /execa/1.0.0:
- resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==}
- engines: {node: '>=6'}
- dependencies:
- cross-spawn: 6.0.5
- get-stream: 4.1.0
- is-stream: 1.1.0
- npm-run-path: 2.0.2
- p-finally: 1.0.0
- signal-exit: 3.0.6
- strip-eof: 1.0.0
- dev: true
-
- /execa/4.1.0:
- resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
- engines: {node: '>=10'}
- dependencies:
- cross-spawn: 7.0.3
- get-stream: 5.2.0
- human-signals: 1.1.1
- is-stream: 2.0.1
- merge-stream: 2.0.0
- npm-run-path: 4.0.1
- onetime: 5.1.2
- signal-exit: 3.0.6
- strip-final-newline: 2.0.0
- dev: true
+ '@unrs/resolver-binding-win32-arm64-msvc@1.7.2':
+ optional: true
- /execa/5.1.1:
- resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
- engines: {node: '>=10'}
- dependencies:
- cross-spawn: 7.0.3
- get-stream: 6.0.1
- human-signals: 2.1.0
- is-stream: 2.0.1
- merge-stream: 2.0.0
- npm-run-path: 4.0.1
- onetime: 5.1.2
- signal-exit: 3.0.6
- strip-final-newline: 2.0.0
- dev: true
+ '@unrs/resolver-binding-win32-ia32-msvc@1.7.2':
+ optional: true
- /exit/0.1.2:
- resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
- engines: {node: '>= 0.8.0'}
- dev: true
+ '@unrs/resolver-binding-win32-x64-msvc@1.7.2':
+ optional: true
- /expect/29.3.1:
- resolution: {integrity: sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ '@vitejs/plugin-vue@5.2.4(vite@5.4.15(@types/node@22.16.5)(sass@1.89.2))(vue@packages+vue)':
dependencies:
- '@jest/expect-utils': 29.3.1
- jest-get-type: 29.2.0
- jest-matcher-utils: 29.3.1
- jest-message-util: 29.3.1
- jest-util: 29.3.1
- dev: true
+ vite: 5.4.15(@types/node@22.16.5)(sass@1.89.2)
+ vue: link:packages/vue
- /extract-zip/2.0.1:
- resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
- engines: {node: '>= 10.17.0'}
- hasBin: true
+ '@vitest/coverage-v8@3.1.4(vitest@3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2))':
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@bcoe/v8-coverage': 1.0.2
+ debug: 4.4.0
+ istanbul-lib-coverage: 3.2.2
+ istanbul-lib-report: 3.0.1
+ istanbul-lib-source-maps: 5.0.6
+ istanbul-reports: 3.1.7
+ magic-string: 0.30.17
+ magicast: 0.3.5
+ std-env: 3.9.0
+ test-exclude: 7.0.1
+ tinyrainbow: 2.0.0
+ vitest: 3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2)
+ transitivePeerDependencies:
+ - supports-color
+
+ '@vitest/eslint-plugin@1.2.1(eslint@9.27.0)(typescript@5.6.3)(vitest@3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2))':
dependencies:
- debug: 4.3.4
- get-stream: 5.2.0
- yauzl: 2.10.0
+ '@typescript-eslint/utils': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ eslint: 9.27.0
optionalDependencies:
- '@types/yauzl': 2.10.0
+ typescript: 5.6.3
+ vitest: 3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2)
transitivePeerDependencies:
- supports-color
- dev: true
-
- /fast-deep-equal/3.1.3:
- resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
- dev: true
- /fast-glob/3.2.7:
- resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==}
- engines: {node: '>=8'}
+ '@vitest/expect@3.1.4':
dependencies:
- '@nodelib/fs.stat': 2.0.5
- '@nodelib/fs.walk': 1.2.8
- glob-parent: 5.1.2
- merge2: 1.4.1
- micromatch: 4.0.4
- dev: true
-
- /fast-json-stable-stringify/2.1.0:
- resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
- dev: true
-
- /fast-levenshtein/2.0.6:
- resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=}
- dev: true
+ '@vitest/spy': 3.1.4
+ '@vitest/utils': 3.1.4
+ chai: 5.2.0
+ tinyrainbow: 2.0.0
- /fast-url-parser/1.1.3:
- resolution: {integrity: sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=}
+ '@vitest/mocker@3.1.4(vite@5.4.19(@types/node@22.16.5)(sass@1.89.2))':
dependencies:
- punycode: 1.4.1
- dev: true
+ '@vitest/spy': 3.1.4
+ estree-walker: 3.0.3
+ magic-string: 0.30.17
+ optionalDependencies:
+ vite: 5.4.19(@types/node@22.16.5)(sass@1.89.2)
- /fastq/1.13.0:
- resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
+ '@vitest/pretty-format@3.1.4':
dependencies:
- reusify: 1.0.4
- dev: true
+ tinyrainbow: 2.0.0
- /fb-watchman/2.0.1:
- resolution: {integrity: sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==}
+ '@vitest/runner@3.1.4':
dependencies:
- bser: 2.1.1
- dev: true
+ '@vitest/utils': 3.1.4
+ pathe: 2.0.3
- /fd-slicer/1.1.0:
- resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
+ '@vitest/snapshot@3.1.4':
dependencies:
- pend: 1.2.0
- dev: true
+ '@vitest/pretty-format': 3.1.4
+ magic-string: 0.30.17
+ pathe: 2.0.3
- /file-entry-cache/6.0.1:
- resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
- engines: {node: ^10.12.0 || >=12.0.0}
+ '@vitest/spy@3.1.4':
dependencies:
- flat-cache: 3.0.4
- dev: true
-
- /file-saver/2.0.5:
- resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
- dev: false
+ tinyspy: 3.0.2
- /fill-range/7.0.1:
- resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
- engines: {node: '>=8'}
+ '@vitest/utils@3.1.4':
dependencies:
- to-regex-range: 5.0.1
- dev: true
+ '@vitest/pretty-format': 3.1.4
+ loupe: 3.1.3
+ tinyrainbow: 2.0.0
- /find-cache-dir/3.3.2:
- resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
- engines: {node: '>=8'}
- dependencies:
- commondir: 1.0.1
- make-dir: 3.1.0
- pkg-dir: 4.2.0
- dev: true
+ '@vue/consolidate@1.0.0': {}
- /find-up/2.1.0:
- resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
- engines: {node: '>=4'}
- dependencies:
- locate-path: 2.0.0
- dev: true
+ '@vue/repl@4.6.2': {}
- /find-up/4.1.0:
- resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
- engines: {node: '>=8'}
+ '@zeit/schemas@2.36.0': {}
+
+ accepts@1.3.8:
dependencies:
- locate-path: 5.0.0
- path-exists: 4.0.0
- dev: true
+ mime-types: 2.1.35
+ negotiator: 0.6.3
- /flat-cache/3.0.4:
- resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
- engines: {node: ^10.12.0 || >=12.0.0}
+ acorn-jsx@5.3.2(acorn@8.14.0):
dependencies:
- flatted: 3.2.4
- rimraf: 3.0.2
- dev: true
+ acorn: 8.14.0
- /flatted/3.2.4:
- resolution: {integrity: sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==}
- dev: true
+ acorn@7.4.1: {}
- /foreach/2.0.6:
- resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==}
- dev: true
+ acorn@8.14.0: {}
- /form-data/4.0.0:
- resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
- engines: {node: '>= 6'}
- dependencies:
- asynckit: 0.4.0
- combined-stream: 1.0.8
- mime-types: 2.1.34
- dev: true
+ add-stream@1.0.0: {}
- /fs-constants/1.0.0:
- resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
- dev: true
+ agent-base@7.1.3: {}
- /fs-extra/10.1.0:
- resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
- engines: {node: '>=12'}
+ ajv@6.12.6:
dependencies:
- graceful-fs: 4.2.10
- jsonfile: 6.1.0
- universalify: 2.0.0
- dev: true
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
- /fs-extra/7.0.1:
- resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
- engines: {node: '>=6 <7 || >=8'}
+ ajv@8.12.0:
dependencies:
- graceful-fs: 4.2.10
- jsonfile: 4.0.0
- universalify: 0.1.2
- dev: true
+ fast-deep-equal: 3.1.3
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+ uri-js: 4.4.1
- /fs-extra/9.1.0:
- resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
- engines: {node: '>=10'}
+ ansi-align@3.0.1:
dependencies:
- at-least-node: 1.0.0
- graceful-fs: 4.2.8
- jsonfile: 6.1.0
- universalify: 2.0.0
- dev: true
+ string-width: 4.2.3
- /fs.realpath/1.0.0:
- resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
- dev: true
+ ansi-colors@4.1.3: {}
- /fsevents/2.3.2:
- resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
+ ansi-escapes@7.0.0:
+ dependencies:
+ environment: 1.1.0
- /function-bind/1.1.1:
- resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
- dev: true
+ ansi-regex@5.0.1: {}
- /functional-red-black-tree/1.0.1:
- resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=}
- dev: true
+ ansi-regex@6.0.1: {}
- /fwd-stream/1.0.4:
- resolution: {integrity: sha512-q2qaK2B38W07wfPSQDKMiKOD5Nzv2XyuvQlrmh1q0pxyHNanKHq8lwQ6n9zHucAwA5EbzRJKEgds2orn88rYTg==}
+ ansi-styles@4.3.0:
dependencies:
- readable-stream: 1.0.34
- dev: true
+ color-convert: 2.0.1
- /generic-names/2.0.1:
- resolution: {integrity: sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==}
- dependencies:
- loader-utils: 1.4.0
- dev: true
+ ansi-styles@6.2.1: {}
- /gensync/1.0.0-beta.2:
- resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
- engines: {node: '>=6.9.0'}
- dev: true
+ arch@2.2.0: {}
- /get-caller-file/2.0.5:
- resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
- engines: {node: 6.* || 8.* || >= 10.*}
- dev: true
+ arg@5.0.2: {}
- /get-intrinsic/1.1.1:
- resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==}
- dependencies:
- function-bind: 1.1.1
- has: 1.0.3
- has-symbols: 1.0.2
- dev: true
+ argparse@2.0.1: {}
- /get-own-enumerable-property-symbols/3.0.2:
- resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==}
- dev: true
+ array-ify@1.0.0: {}
- /get-package-type/0.1.0:
- resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
- engines: {node: '>=8.0.0'}
- dev: true
+ asap@2.0.6: {}
- /get-pkg-repo/4.2.1:
- resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==}
- engines: {node: '>=6.9.0'}
- hasBin: true
- dependencies:
- '@hutson/parse-repository-url': 3.0.2
- hosted-git-info: 4.0.2
- through2: 2.0.5
- yargs: 16.2.0
- dev: true
+ assert-never@1.3.0: {}
- /get-stream/3.0.0:
- resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==}
- engines: {node: '>=4'}
- dev: true
+ assertion-error@2.0.1: {}
- /get-stream/4.1.0:
- resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==}
- engines: {node: '>=6'}
+ ast-types@0.13.4:
dependencies:
- pump: 3.0.0
- dev: true
+ tslib: 2.8.1
- /get-stream/5.2.0:
- resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
- engines: {node: '>=8'}
+ b4a@1.6.6: {}
+
+ babel-walk@3.0.0-canary-5:
dependencies:
- pump: 3.0.0
- dev: true
+ '@babel/types': 7.28.1
- /get-stream/6.0.1:
- resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
- engines: {node: '>=10'}
- dev: true
+ balanced-match@1.0.2: {}
- /get-symbol-description/1.0.0:
- resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.1.1
- dev: true
+ bare-events@2.4.2:
+ optional: true
- /git-raw-commits/2.0.10:
- resolution: {integrity: sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==}
- engines: {node: '>=10'}
- hasBin: true
+ bare-fs@4.0.1:
dependencies:
- dargs: 7.0.0
- lodash: 4.17.21
- meow: 8.1.2
- split2: 3.2.2
- through2: 4.0.2
- dev: true
+ bare-events: 2.4.2
+ bare-path: 3.0.0
+ bare-stream: 2.1.3
+ optional: true
- /git-remote-origin-url/2.0.0:
- resolution: {integrity: sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=}
- engines: {node: '>=4'}
+ bare-os@3.4.0:
+ optional: true
+
+ bare-path@3.0.0:
dependencies:
- gitconfiglocal: 1.0.0
- pify: 2.3.0
- dev: true
+ bare-os: 3.4.0
+ optional: true
- /git-semver-tags/4.1.1:
- resolution: {integrity: sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==}
- engines: {node: '>=10'}
- hasBin: true
+ bare-stream@2.1.3:
dependencies:
- meow: 8.1.2
- semver: 6.3.0
- dev: true
+ streamx: 2.18.0
+ optional: true
+
+ basic-ftp@5.0.5: {}
- /gitconfiglocal/1.0.0:
- resolution: {integrity: sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=}
+ boxen@7.0.0:
dependencies:
- ini: 1.3.8
- dev: true
+ ansi-align: 3.0.1
+ camelcase: 7.0.1
+ chalk: 5.4.1
+ cli-boxes: 3.0.0
+ string-width: 5.1.2
+ type-fest: 2.19.0
+ widest-line: 4.0.1
+ wrap-ansi: 8.1.0
- /glob-parent/5.1.2:
- resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
- engines: {node: '>= 6'}
+ brace-expansion@1.1.11:
dependencies:
- is-glob: 4.0.3
- dev: true
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
- /glob/7.2.3:
- resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ brace-expansion@2.0.1:
dependencies:
- fs.realpath: 1.0.0
- inflight: 1.0.6
- inherits: 2.0.4
- minimatch: 3.1.2
- once: 1.4.0
- path-is-absolute: 1.0.1
- dev: true
+ balanced-match: 1.0.2
- /glob/8.0.3:
- resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==}
- engines: {node: '>=12'}
+ braces@3.0.3:
dependencies:
- fs.realpath: 1.0.0
- inflight: 1.0.6
- inherits: 2.0.4
- minimatch: 5.1.0
- once: 1.4.0
- dev: true
+ fill-range: 7.1.1
- /globals/11.12.0:
- resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
- engines: {node: '>=4'}
- dev: true
+ buffer-crc32@0.2.13: {}
- /globals/13.12.0:
- resolution: {integrity: sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==}
- engines: {node: '>=8'}
- dependencies:
- type-fest: 0.20.2
- dev: true
+ bytes@3.0.0: {}
- /globby/11.0.4:
- resolution: {integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==}
- engines: {node: '>=10'}
+ cac@6.7.14: {}
+
+ call-bind@1.0.7:
dependencies:
- array-union: 2.1.0
- dir-glob: 3.0.1
- fast-glob: 3.2.7
- ignore: 5.1.9
- merge2: 1.4.1
- slash: 3.0.0
- dev: true
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ set-function-length: 1.2.2
- /graceful-fs/4.2.10:
- resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
- dev: true
+ callsites@3.1.0: {}
- /graceful-fs/4.2.8:
- resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
- dev: true
+ camelcase@7.0.1: {}
- /handlebars/4.7.7:
- resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==}
- engines: {node: '>=0.4.7'}
- hasBin: true
+ chai@5.2.0:
dependencies:
- minimist: 1.2.5
- neo-async: 2.6.2
- source-map: 0.6.1
- wordwrap: 1.0.0
- optionalDependencies:
- uglify-js: 3.17.4
- dev: true
-
- /hard-rejection/2.1.0:
- resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
- engines: {node: '>=6'}
- dev: true
+ assertion-error: 2.0.1
+ check-error: 2.1.1
+ deep-eql: 5.0.2
+ loupe: 3.1.3
+ pathval: 2.0.0
- /has-bigints/1.0.1:
- resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==}
- dev: true
+ chalk-template@0.4.0:
+ dependencies:
+ chalk: 4.1.2
- /has-flag/3.0.0:
- resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=}
- engines: {node: '>=4'}
- dev: true
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
- /has-flag/4.0.0:
- resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
- engines: {node: '>=8'}
- dev: true
+ chalk@5.0.1: {}
- /has-symbols/1.0.2:
- resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==}
- engines: {node: '>= 0.4'}
- dev: true
+ chalk@5.4.1: {}
- /has-tostringtag/1.0.0:
- resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
- engines: {node: '>= 0.4'}
+ character-parser@2.2.0:
dependencies:
- has-symbols: 1.0.2
- dev: true
+ is-regex: 1.1.4
- /has/1.0.3:
- resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
- engines: {node: '>= 0.4.0'}
+ check-error@2.1.1: {}
+
+ chokidar@4.0.1:
dependencies:
- function-bind: 1.1.1
- dev: true
+ readdirp: 4.0.1
- /hash-base/3.1.0:
- resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
- engines: {node: '>=4'}
+ chromium-bidi@5.1.0(devtools-protocol@0.0.1439962):
dependencies:
- inherits: 2.0.4
- readable-stream: 3.6.0
- safe-buffer: 5.2.1
- dev: true
+ devtools-protocol: 0.0.1439962
+ mitt: 3.0.1
+ zod: 3.24.1
- /hash-sum/2.0.0:
- resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
- dev: true
+ cli-boxes@3.0.0: {}
- /hash.js/1.1.7:
- resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
+ cli-cursor@5.0.0:
dependencies:
- inherits: 2.0.4
- minimalistic-assert: 1.0.1
- dev: true
+ restore-cursor: 5.1.0
- /hmac-drbg/1.0.1:
- resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==}
+ cli-truncate@4.0.0:
dependencies:
- hash.js: 1.1.7
- minimalistic-assert: 1.0.1
- minimalistic-crypto-utils: 1.0.1
- dev: true
+ slice-ansi: 5.0.0
+ string-width: 7.2.0
- /hosted-git-info/2.8.9:
- resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
- dev: true
+ clipboardy@3.0.0:
+ dependencies:
+ arch: 2.2.0
+ execa: 5.1.1
+ is-wsl: 2.2.0
- /hosted-git-info/4.0.2:
- resolution: {integrity: sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==}
- engines: {node: '>=10'}
+ cliui@8.0.1:
dependencies:
- lru-cache: 6.0.0
- dev: true
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
- /html-encoding-sniffer/3.0.0:
- resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==}
- engines: {node: '>=12'}
+ color-convert@2.0.1:
dependencies:
- whatwg-encoding: 2.0.0
- dev: true
+ color-name: 1.1.4
- /html-escaper/2.0.2:
- resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
- dev: true
+ color-name@1.1.4: {}
- /http-proxy-agent/5.0.0:
- resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==}
- engines: {node: '>= 6'}
- dependencies:
- '@tootallnate/once': 2.0.0
- agent-base: 6.0.2
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ colorette@2.0.20: {}
- /https-proxy-agent/5.0.1:
- resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
- engines: {node: '>= 6'}
- dependencies:
- agent-base: 6.0.2
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ commander@13.1.0: {}
- /human-signals/1.1.1:
- resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
- engines: {node: '>=8.12.0'}
- dev: true
+ comment-parser@1.4.1: {}
- /human-signals/2.1.0:
- resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
- engines: {node: '>=10.17.0'}
- dev: true
+ commondir@1.0.1: {}
- /iconv-lite/0.6.3:
- resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
- engines: {node: '>=0.10.0'}
+ compare-func@2.0.0:
dependencies:
- safer-buffer: 2.1.2
- dev: true
-
- /icss-replace-symbols/1.1.0:
- resolution: {integrity: sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=}
- dev: true
+ array-ify: 1.0.0
+ dot-prop: 5.3.0
- /icss-utils/5.1.0_postcss@8.4.4:
- resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
- engines: {node: ^10 || ^12 || >= 14}
- peerDependencies:
- postcss: ^8.1.0
+ compressible@2.0.18:
dependencies:
- postcss: 8.4.4
- dev: true
+ mime-db: 1.53.0
- /idb-wrapper/1.7.2:
- resolution: {integrity: sha512-zfNREywMuf0NzDo9mVsL0yegjsirJxHpKHvWcyRozIqQy89g0a3U+oBPOCN4cc0oCiOuYgZHimzaW/R46G1Mpg==}
- dev: true
+ compression@1.7.4:
+ dependencies:
+ accepts: 1.3.8
+ bytes: 3.0.0
+ compressible: 2.0.18
+ debug: 2.6.9
+ on-headers: 1.0.2
+ safe-buffer: 5.1.2
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
- /ieee754/1.2.1:
- resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
- dev: true
+ concat-map@0.0.1: {}
- /ignore/4.0.6:
- resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
- engines: {node: '>= 4'}
- dev: true
+ constantinople@4.0.1:
+ dependencies:
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.1
- /ignore/5.1.9:
- resolution: {integrity: sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==}
- engines: {node: '>= 4'}
- dev: true
+ content-disposition@0.5.2: {}
- /immediate/3.0.6:
- resolution: {integrity: sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=}
- dev: false
+ conventional-changelog-angular@8.0.0:
+ dependencies:
+ compare-func: 2.0.0
- /immutable/4.0.0:
- resolution: {integrity: sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==}
- dev: true
+ conventional-changelog-atom@5.0.0: {}
- /import-fresh/3.3.0:
- resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
- engines: {node: '>=6'}
+ conventional-changelog-cli@5.0.0(conventional-commits-filter@5.0.0):
dependencies:
- parent-module: 1.0.1
- resolve-from: 4.0.0
- dev: true
+ add-stream: 1.0.0
+ conventional-changelog: 6.0.0(conventional-commits-filter@5.0.0)
+ meow: 13.2.0
+ tempfile: 5.0.0
+ transitivePeerDependencies:
+ - conventional-commits-filter
- /import-lazy/4.0.0:
- resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
- engines: {node: '>=8'}
- dev: true
+ conventional-changelog-codemirror@5.0.0: {}
- /import-local/3.0.3:
- resolution: {integrity: sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==}
- engines: {node: '>=8'}
- hasBin: true
+ conventional-changelog-conventionalcommits@8.0.0:
dependencies:
- pkg-dir: 4.2.0
- resolve-cwd: 3.0.0
- dev: true
+ compare-func: 2.0.0
- /imurmurhash/0.1.4:
- resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=}
- engines: {node: '>=0.8.19'}
- dev: true
+ conventional-changelog-core@8.0.0(conventional-commits-filter@5.0.0):
+ dependencies:
+ '@hutson/parse-repository-url': 5.0.0
+ add-stream: 1.0.0
+ conventional-changelog-writer: 8.0.0
+ conventional-commits-parser: 6.0.0
+ git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)
+ git-semver-tags: 8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)
+ hosted-git-info: 7.0.2
+ normalize-package-data: 6.0.2
+ read-package-up: 11.0.0
+ read-pkg: 9.0.1
+ transitivePeerDependencies:
+ - conventional-commits-filter
- /indent-string/4.0.0:
- resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
- engines: {node: '>=8'}
- dev: true
+ conventional-changelog-ember@5.0.0: {}
+
+ conventional-changelog-eslint@6.0.0: {}
- /indexof/0.0.1:
- resolution: {integrity: sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==}
- dev: true
+ conventional-changelog-express@5.0.0: {}
- /inflight/1.0.6:
- resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
+ conventional-changelog-jquery@6.0.0: {}
+
+ conventional-changelog-jshint@5.0.0:
dependencies:
- once: 1.4.0
- wrappy: 1.0.2
- dev: true
+ compare-func: 2.0.0
- /inherits/2.0.4:
- resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ conventional-changelog-preset-loader@5.0.0: {}
+
+ conventional-changelog-writer@8.0.0:
+ dependencies:
+ '@types/semver': 7.7.0
+ conventional-commits-filter: 5.0.0
+ handlebars: 4.7.8
+ meow: 13.2.0
+ semver: 7.7.2
+
+ conventional-changelog@6.0.0(conventional-commits-filter@5.0.0):
+ dependencies:
+ conventional-changelog-angular: 8.0.0
+ conventional-changelog-atom: 5.0.0
+ conventional-changelog-codemirror: 5.0.0
+ conventional-changelog-conventionalcommits: 8.0.0
+ conventional-changelog-core: 8.0.0(conventional-commits-filter@5.0.0)
+ conventional-changelog-ember: 5.0.0
+ conventional-changelog-eslint: 6.0.0
+ conventional-changelog-express: 5.0.0
+ conventional-changelog-jquery: 6.0.0
+ conventional-changelog-jshint: 5.0.0
+ conventional-changelog-preset-loader: 5.0.0
+ transitivePeerDependencies:
+ - conventional-commits-filter
- /ini/1.3.8:
- resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
- dev: true
+ conventional-commits-filter@5.0.0: {}
- /internal-slot/1.0.3:
- resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
- engines: {node: '>= 0.4'}
+ conventional-commits-parser@6.0.0:
dependencies:
- get-intrinsic: 1.1.1
- has: 1.0.3
- side-channel: 1.0.4
- dev: true
+ meow: 13.2.0
- /is-arrayish/0.2.1:
- resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
- dev: true
+ core-util-is@1.0.3: {}
- /is-bigint/1.0.4:
- resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ cosmiconfig@9.0.0(typescript@5.6.3):
dependencies:
- has-bigints: 1.0.1
- dev: true
+ env-paths: 2.2.1
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ parse-json: 5.2.0
+ optionalDependencies:
+ typescript: 5.6.3
- /is-binary-path/2.1.0:
- resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
- engines: {node: '>=8'}
+ cross-spawn@7.0.6:
dependencies:
- binary-extensions: 2.2.0
- dev: true
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
- /is-boolean-object/1.1.2:
- resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- has-tostringtag: 1.0.0
- dev: true
+ cssesc@3.0.0: {}
- /is-builtin-module/3.2.0:
- resolution: {integrity: sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==}
- engines: {node: '>=6'}
+ cssstyle@4.2.1:
dependencies:
- builtin-modules: 3.3.0
- dev: true
+ '@asamuzakjp/css-color': 2.8.2
+ rrweb-cssom: 0.8.0
- /is-callable/1.2.4:
- resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==}
- engines: {node: '>= 0.4'}
- dev: true
+ csstype@3.1.3: {}
- /is-core-module/2.10.0:
- resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
- dependencies:
- has: 1.0.3
- dev: true
+ data-uri-to-buffer@6.0.2: {}
- /is-core-module/2.8.0:
- resolution: {integrity: sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==}
+ data-urls@5.0.0:
dependencies:
- has: 1.0.3
- dev: true
+ whatwg-mimetype: 4.0.0
+ whatwg-url: 14.2.0
- /is-core-module/2.8.1:
- resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
+ debug@2.6.9:
dependencies:
- has: 1.0.3
- dev: true
+ ms: 2.0.0
- /is-date-object/1.0.5:
- resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
- engines: {node: '>= 0.4'}
+ debug@3.2.7:
dependencies:
- has-tostringtag: 1.0.0
- dev: true
+ ms: 2.1.3
- /is-docker/2.2.1:
- resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
- engines: {node: '>=8'}
- hasBin: true
- dev: true
+ debug@4.4.0:
+ dependencies:
+ ms: 2.1.3
- /is-expression/4.0.0:
- resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==}
+ debug@4.4.1:
dependencies:
- acorn: 7.4.1
- object-assign: 4.1.1
- dev: true
+ ms: 2.1.3
- /is-extglob/2.1.1:
- resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
- engines: {node: '>=0.10.0'}
- dev: true
+ decimal.js@10.5.0: {}
- /is-fullwidth-code-point/2.0.0:
- resolution: {integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=}
- engines: {node: '>=4'}
- dev: true
+ deep-eql@5.0.2: {}
- /is-fullwidth-code-point/3.0.0:
- resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
- engines: {node: '>=8'}
- dev: true
+ deep-extend@0.6.0: {}
- /is-generator-fn/2.1.0:
- resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
- engines: {node: '>=6'}
- dev: true
+ deep-is@0.1.4: {}
- /is-glob/4.0.3:
- resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
- engines: {node: '>=0.10.0'}
+ deepmerge@4.3.1: {}
+
+ define-data-property@1.1.4:
dependencies:
- is-extglob: 2.1.1
- dev: true
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ gopd: 1.0.1
- /is-module/1.0.0:
- resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
- dev: true
+ degenerator@5.0.1:
+ dependencies:
+ ast-types: 0.13.4
+ escodegen: 2.1.0
+ esprima: 4.0.1
- /is-negative-zero/2.0.2:
- resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
- engines: {node: '>= 0.4'}
- dev: true
+ detect-libc@1.0.3:
+ optional: true
- /is-number-object/1.0.6:
- resolution: {integrity: sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-tostringtag: 1.0.0
- dev: true
+ devtools-protocol@0.0.1439962: {}
- /is-number/7.0.0:
- resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
- engines: {node: '>=0.12.0'}
- dev: true
+ doctypes@1.1.0: {}
- /is-obj/1.0.1:
- resolution: {integrity: sha1-PkcprB9f3gJc19g6iW2rn09n2w8=}
- engines: {node: '>=0.10.0'}
- dev: true
+ dot-prop@5.3.0:
+ dependencies:
+ is-obj: 2.0.0
- /is-obj/2.0.0:
- resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
- engines: {node: '>=8'}
- dev: true
+ eastasianwidth@0.2.0: {}
- /is-object/0.1.2:
- resolution: {integrity: sha512-GkfZZlIZtpkFrqyAXPQSRBMsaHAw+CgoKe2HXAkjd/sfoI9+hS8PT4wg2rJxdQyUKr7N2vHJbg7/jQtE5l5vBQ==}
- dev: true
+ emoji-regex@10.3.0: {}
- /is-plain-obj/1.1.0:
- resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=}
- engines: {node: '>=0.10.0'}
- dev: true
+ emoji-regex@8.0.0: {}
- /is-potential-custom-element-name/1.0.1:
- resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
- dev: true
+ emoji-regex@9.2.2: {}
- /is-promise/2.2.2:
- resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==}
- dev: true
+ end-of-stream@1.4.4:
+ dependencies:
+ once: 1.4.0
- /is-reference/1.2.1:
- resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
+ enquirer@2.4.1:
dependencies:
- '@types/estree': 1.0.0
- dev: true
+ ansi-colors: 4.1.3
+ strip-ansi: 6.0.1
- /is-regex/1.1.4:
- resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
- engines: {node: '>= 0.4'}
+ entities@4.5.0: {}
+
+ env-paths@2.2.1: {}
+
+ environment@1.1.0: {}
+
+ error-ex@1.3.2:
dependencies:
- call-bind: 1.0.2
- has-tostringtag: 1.0.0
- dev: true
+ is-arrayish: 0.2.1
- /is-regexp/1.0.0:
- resolution: {integrity: sha1-/S2INUXEa6xaYz57mgnof6LLUGk=}
- engines: {node: '>=0.10.0'}
- dev: true
+ es-define-property@1.0.0:
+ dependencies:
+ get-intrinsic: 1.2.4
- /is-shared-array-buffer/1.0.1:
- resolution: {integrity: sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==}
- dev: true
+ es-errors@1.3.0: {}
- /is-stream/1.1.0:
- resolution: {integrity: sha1-EtSj3U5o4Lec6428hBc66A2RykQ=}
- engines: {node: '>=0.10.0'}
- dev: true
+ es-module-lexer@1.6.0: {}
- /is-stream/2.0.1:
- resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
- engines: {node: '>=8'}
- dev: true
+ es-module-lexer@1.7.0: {}
- /is-string/1.0.7:
- resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
- engines: {node: '>= 0.4'}
+ esbuild-plugin-polyfill-node@0.3.0(esbuild@0.25.8):
dependencies:
- has-tostringtag: 1.0.0
- dev: true
+ '@jspm/core': 2.0.1
+ esbuild: 0.25.8
+ import-meta-resolve: 3.1.1
- /is-symbol/1.0.4:
- resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
- engines: {node: '>= 0.4'}
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ esbuild@0.25.8:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.8
+ '@esbuild/android-arm': 0.25.8
+ '@esbuild/android-arm64': 0.25.8
+ '@esbuild/android-x64': 0.25.8
+ '@esbuild/darwin-arm64': 0.25.8
+ '@esbuild/darwin-x64': 0.25.8
+ '@esbuild/freebsd-arm64': 0.25.8
+ '@esbuild/freebsd-x64': 0.25.8
+ '@esbuild/linux-arm': 0.25.8
+ '@esbuild/linux-arm64': 0.25.8
+ '@esbuild/linux-ia32': 0.25.8
+ '@esbuild/linux-loong64': 0.25.8
+ '@esbuild/linux-mips64el': 0.25.8
+ '@esbuild/linux-ppc64': 0.25.8
+ '@esbuild/linux-riscv64': 0.25.8
+ '@esbuild/linux-s390x': 0.25.8
+ '@esbuild/linux-x64': 0.25.8
+ '@esbuild/netbsd-arm64': 0.25.8
+ '@esbuild/netbsd-x64': 0.25.8
+ '@esbuild/openbsd-arm64': 0.25.8
+ '@esbuild/openbsd-x64': 0.25.8
+ '@esbuild/openharmony-arm64': 0.25.8
+ '@esbuild/sunos-x64': 0.25.8
+ '@esbuild/win32-arm64': 0.25.8
+ '@esbuild/win32-ia32': 0.25.8
+ '@esbuild/win32-x64': 0.25.8
+
+ escalade@3.1.2: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ escodegen@2.1.0:
dependencies:
- has-symbols: 1.0.2
- dev: true
+ esprima: 4.0.1
+ estraverse: 5.3.0
+ esutils: 2.0.3
+ optionalDependencies:
+ source-map: 0.6.1
- /is-text-path/1.0.1:
- resolution: {integrity: sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=}
- engines: {node: '>=0.10.0'}
+ eslint-import-context@0.1.4(unrs-resolver@1.7.2):
dependencies:
- text-extensions: 1.9.0
- dev: true
+ get-tsconfig: 4.10.1
+ stable-hash: 0.0.5
+ optionalDependencies:
+ unrs-resolver: 1.7.2
- /is-unicode-supported/0.1.0:
- resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
- engines: {node: '>=10'}
- dev: true
+ eslint-import-resolver-node@0.3.9:
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.15.0
+ resolve: 1.22.8
+ transitivePeerDependencies:
+ - supports-color
- /is-weakref/1.0.2:
- resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ eslint-plugin-import-x@4.13.1(eslint@9.27.0)(typescript@5.6.3):
dependencies:
- call-bind: 1.0.2
- dev: true
+ '@typescript-eslint/utils': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ comment-parser: 1.4.1
+ debug: 4.4.1
+ eslint: 9.27.0
+ eslint-import-context: 0.1.4(unrs-resolver@1.7.2)
+ eslint-import-resolver-node: 0.3.9
+ is-glob: 4.0.3
+ minimatch: 10.0.1
+ semver: 7.7.2
+ stable-hash: 0.0.5
+ tslib: 2.8.1
+ unrs-resolver: 1.7.2
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
- /is-wsl/2.2.0:
- resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
- engines: {node: '>=8'}
+ eslint-scope@8.3.0:
dependencies:
- is-docker: 2.2.1
- dev: true
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint-visitor-keys@4.2.0: {}
+
+ eslint@9.27.0:
+ dependencies:
+ '@eslint-community/eslint-utils': 4.6.1(eslint@9.27.0)
+ '@eslint-community/regexpp': 4.12.1
+ '@eslint/config-array': 0.20.0
+ '@eslint/config-helpers': 0.2.1
+ '@eslint/core': 0.14.0
+ '@eslint/eslintrc': 3.3.1
+ '@eslint/js': 9.27.0
+ '@eslint/plugin-kit': 0.3.1
+ '@humanfs/node': 0.16.6
+ '@humanwhocodes/module-importer': 1.0.1
+ '@humanwhocodes/retry': 0.4.2
+ '@types/estree': 1.0.7
+ '@types/json-schema': 7.0.15
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 8.3.0
+ eslint-visitor-keys: 4.2.0
+ espree: 10.3.0
+ esquery: 1.6.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 8.0.0
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ json-stable-stringify-without-jsonify: 1.0.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.2
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ transitivePeerDependencies:
+ - supports-color
- /is/0.2.7:
- resolution: {integrity: sha512-ajQCouIvkcSnl2iRdK70Jug9mohIHVX9uKpoWnl115ov0R5mzBvRrXxrnHbsA+8AdwCwc/sfw7HXmd4I5EJBdQ==}
- dev: true
+ espree@10.3.0:
+ dependencies:
+ acorn: 8.14.0
+ acorn-jsx: 5.3.2(acorn@8.14.0)
+ eslint-visitor-keys: 4.2.0
- /isarray/0.0.1:
- resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
- dev: true
+ esprima@4.0.1: {}
- /isarray/1.0.0:
- resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=}
+ esquery@1.6.0:
+ dependencies:
+ estraverse: 5.3.0
- /isbuffer/0.0.0:
- resolution: {integrity: sha512-xU+NoHp+YtKQkaM2HsQchYn0sltxMxew0HavMfHbjnucBoTSGbw745tL+Z7QBANleWM1eEQMenEpi174mIeS4g==}
- dev: true
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
- /isexe/2.0.0:
- resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=}
- dev: true
+ estraverse@5.3.0: {}
- /istanbul-lib-coverage/3.2.0:
- resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
- engines: {node: '>=8'}
- dev: true
+ estree-walker@2.0.2: {}
- /istanbul-lib-instrument/5.1.0:
- resolution: {integrity: sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==}
- engines: {node: '>=8'}
+ estree-walker@3.0.3:
dependencies:
- '@babel/core': 7.16.0
- '@babel/parser': 7.16.4
- '@istanbuljs/schema': 0.1.3
- istanbul-lib-coverage: 3.2.0
- semver: 6.3.0
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@types/estree': 1.0.8
- /istanbul-lib-report/3.0.0:
- resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
- engines: {node: '>=8'}
+ esutils@2.0.3: {}
+
+ eventemitter3@5.0.1: {}
+
+ execa@5.1.1:
dependencies:
- istanbul-lib-coverage: 3.2.0
- make-dir: 3.1.0
- supports-color: 7.2.0
- dev: true
+ cross-spawn: 7.0.6
+ get-stream: 6.0.1
+ human-signals: 2.1.0
+ is-stream: 2.0.1
+ merge-stream: 2.0.0
+ npm-run-path: 4.0.1
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+ strip-final-newline: 2.0.0
- /istanbul-lib-source-maps/4.0.1:
- resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
- engines: {node: '>=10'}
+ expect-type@1.2.1: {}
+
+ extract-zip@2.0.1:
dependencies:
- debug: 4.3.4
- istanbul-lib-coverage: 3.2.0
- source-map: 0.6.1
+ debug: 4.4.1
+ get-stream: 5.2.0
+ yauzl: 2.10.0
+ optionalDependencies:
+ '@types/yauzl': 2.10.3
transitivePeerDependencies:
- supports-color
- dev: true
- /istanbul-reports/3.1.5:
- resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==}
- engines: {node: '>=8'}
+ fast-deep-equal@3.1.3: {}
+
+ fast-fifo@1.3.2: {}
+
+ fast-glob@3.3.3:
dependencies:
- html-escaper: 2.0.2
- istanbul-lib-report: 3.0.0
- dev: true
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
- /jest-changed-files/29.2.0:
- resolution: {integrity: sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fastq@1.19.1:
dependencies:
- execa: 5.1.1
- p-limit: 3.1.0
- dev: true
+ reusify: 1.1.0
- /jest-circus/29.3.1:
- resolution: {integrity: sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ fd-slicer@1.1.0:
dependencies:
- '@jest/environment': 29.3.1
- '@jest/expect': 29.3.1
- '@jest/test-result': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- chalk: 4.1.2
- co: 4.6.0
- dedent: 0.7.0
- is-generator-fn: 2.1.0
- jest-each: 29.3.1
- jest-matcher-utils: 29.3.1
- jest-message-util: 29.3.1
- jest-runtime: 29.3.1
- jest-snapshot: 29.3.1
- jest-util: 29.3.1
- p-limit: 3.1.0
- pretty-format: 29.3.1
- slash: 3.0.0
- stack-utils: 2.0.5
- transitivePeerDependencies:
- - supports-color
- dev: true
+ pend: 1.2.0
- /jest-cli/29.3.1_@types+node@16.11.12:
- resolution: {integrity: sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- hasBin: true
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
+ fdir@6.4.4(picomatch@4.0.2):
+ optionalDependencies:
+ picomatch: 4.0.2
+
+ file-entry-cache@8.0.0:
dependencies:
- '@jest/core': 29.3.1
- '@jest/test-result': 29.3.1
- '@jest/types': 29.3.1
- chalk: 4.1.2
- exit: 0.1.2
- graceful-fs: 4.2.10
- import-local: 3.0.3
- jest-config: 29.3.1_@types+node@16.11.12
- jest-util: 29.3.1
- jest-validate: 29.3.1
- prompts: 2.4.2
- yargs: 17.6.2
- transitivePeerDependencies:
- - '@types/node'
- - supports-color
- - ts-node
- dev: true
+ flat-cache: 4.0.1
- /jest-config/29.3.1_@types+node@16.11.12:
- resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@types/node': '*'
- ts-node: '>=9.0.0'
- peerDependenciesMeta:
- '@types/node':
- optional: true
- ts-node:
- optional: true
+ file-saver@2.0.5: {}
+
+ fill-range@7.1.1:
dependencies:
- '@babel/core': 7.16.0
- '@jest/test-sequencer': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.11.12
- babel-jest: 29.3.1_@babel+core@7.16.0
- chalk: 4.1.2
- ci-info: 3.3.0
- deepmerge: 4.2.2
- glob: 7.2.3
- graceful-fs: 4.2.10
- jest-circus: 29.3.1
- jest-environment-node: 29.3.1
- jest-get-type: 29.2.0
- jest-regex-util: 29.2.0
- jest-resolve: 29.3.1
- jest-runner: 29.3.1
- jest-util: 29.3.1
- jest-validate: 29.3.1
- micromatch: 4.0.4
- parse-json: 5.2.0
- pretty-format: 29.3.1
- slash: 3.0.0
- strip-json-comments: 3.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ to-regex-range: 5.0.1
- /jest-config/29.3.1_@types+node@16.18.2:
- resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- '@types/node': '*'
- ts-node: '>=9.0.0'
- peerDependenciesMeta:
- '@types/node':
- optional: true
- ts-node:
- optional: true
+ find-up-simple@1.0.0: {}
+
+ find-up@5.0.0:
dependencies:
- '@babel/core': 7.16.0
- '@jest/test-sequencer': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- babel-jest: 29.3.1_@babel+core@7.16.0
- chalk: 4.1.2
- ci-info: 3.3.0
- deepmerge: 4.2.2
- glob: 7.2.3
- graceful-fs: 4.2.10
- jest-circus: 29.3.1
- jest-environment-node: 29.3.1
- jest-get-type: 29.2.0
- jest-regex-util: 29.2.0
- jest-resolve: 29.3.1
- jest-runner: 29.3.1
- jest-util: 29.3.1
- jest-validate: 29.3.1
- micromatch: 4.0.4
- parse-json: 5.2.0
- pretty-format: 29.3.1
- slash: 3.0.0
- strip-json-comments: 3.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ locate-path: 6.0.0
+ path-exists: 4.0.0
- /jest-diff/29.3.1:
- resolution: {integrity: sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ flat-cache@4.0.1:
dependencies:
- chalk: 4.1.2
- diff-sequences: 29.3.1
- jest-get-type: 29.2.0
- pretty-format: 29.3.1
- dev: true
+ flatted: 3.3.1
+ keyv: 4.5.4
- /jest-docblock/29.2.0:
- resolution: {integrity: sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ flatted@3.3.1: {}
+
+ foreground-child@3.3.0:
dependencies:
- detect-newline: 3.1.0
- dev: true
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
- /jest-each/29.3.1:
- resolution: {integrity: sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ fs-extra@11.2.0:
dependencies:
- '@jest/types': 29.3.1
- chalk: 4.1.2
- jest-get-type: 29.2.0
- jest-util: 29.3.1
- pretty-format: 29.3.1
- dev: true
-
- /jest-environment-jsdom/29.3.1:
- resolution: {integrity: sha512-G46nKgiez2Gy4zvYNhayfMEAFlVHhWfncqvqS6yCd0i+a4NsSUD2WtrKSaYQrYiLQaupHXxCRi8xxVL2M9PbhA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- peerDependencies:
- canvas: ^2.5.0
- peerDependenciesMeta:
- canvas:
- optional: true
+ graceful-fs: 4.2.11
+ jsonfile: 6.1.0
+ universalify: 2.0.1
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ generic-names@4.0.0:
dependencies:
- '@jest/environment': 29.3.1
- '@jest/fake-timers': 29.3.1
- '@jest/types': 29.3.1
- '@types/jsdom': 20.0.1
- '@types/node': 16.18.2
- jest-mock: 29.3.1
- jest-util: 29.3.1
- jsdom: 20.0.2
- transitivePeerDependencies:
- - bufferutil
- - supports-color
- - utf-8-validate
- dev: true
-
- /jest-environment-node/29.3.1:
- resolution: {integrity: sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/environment': 29.3.1
- '@jest/fake-timers': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- jest-mock: 29.3.1
- jest-util: 29.3.1
- dev: true
-
- /jest-get-type/29.2.0:
- resolution: {integrity: sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dev: true
-
- /jest-haste-map/29.3.1:
- resolution: {integrity: sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/types': 29.3.1
- '@types/graceful-fs': 4.1.5
- '@types/node': 16.18.2
- anymatch: 3.1.2
- fb-watchman: 2.0.1
- graceful-fs: 4.2.10
- jest-regex-util: 29.2.0
- jest-util: 29.3.1
- jest-worker: 29.3.1
- micromatch: 4.0.4
- walker: 1.0.8
- optionalDependencies:
- fsevents: 2.3.2
- dev: true
+ loader-utils: 3.3.1
- /jest-leak-detector/29.3.1:
- resolution: {integrity: sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ get-caller-file@2.0.5: {}
+
+ get-east-asian-width@1.2.0: {}
+
+ get-intrinsic@1.2.4:
dependencies:
- jest-get-type: 29.2.0
- pretty-format: 29.3.1
- dev: true
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ hasown: 2.0.2
- /jest-matcher-utils/29.3.1:
- resolution: {integrity: sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ get-stream@5.2.0:
dependencies:
- chalk: 4.1.2
- jest-diff: 29.3.1
- jest-get-type: 29.2.0
- pretty-format: 29.3.1
- dev: true
-
- /jest-message-util/29.3.1:
- resolution: {integrity: sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@babel/code-frame': 7.18.6
- '@jest/types': 29.3.1
- '@types/stack-utils': 2.0.1
- chalk: 4.1.2
- graceful-fs: 4.2.10
- micromatch: 4.0.4
- pretty-format: 29.3.1
- slash: 3.0.0
- stack-utils: 2.0.5
- dev: true
-
- /jest-mock/29.3.1:
- resolution: {integrity: sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- jest-util: 29.3.1
- dev: true
-
- /jest-pnp-resolver/1.2.2_jest-resolve@29.3.1:
- resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
- engines: {node: '>=6'}
- peerDependencies:
- jest-resolve: '*'
- peerDependenciesMeta:
- jest-resolve:
- optional: true
+ pump: 3.0.0
+
+ get-stream@6.0.1: {}
+
+ get-tsconfig@4.10.0:
dependencies:
- jest-resolve: 29.3.1
- dev: true
+ resolve-pkg-maps: 1.0.0
- /jest-regex-util/29.2.0:
- resolution: {integrity: sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dev: true
+ get-tsconfig@4.10.1:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
- /jest-resolve-dependencies/29.3.1:
- resolution: {integrity: sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ get-uri@6.0.3:
dependencies:
- jest-regex-util: 29.2.0
- jest-snapshot: 29.3.1
+ basic-ftp: 5.0.5
+ data-uri-to-buffer: 6.0.2
+ debug: 4.4.1
+ fs-extra: 11.2.0
transitivePeerDependencies:
- supports-color
- dev: true
- /jest-resolve/29.3.1:
- resolution: {integrity: sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ git-raw-commits@5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0):
dependencies:
- chalk: 4.1.2
- graceful-fs: 4.2.10
- jest-haste-map: 29.3.1
- jest-pnp-resolver: 1.2.2_jest-resolve@29.3.1
- jest-util: 29.3.1
- jest-validate: 29.3.1
- resolve: 1.22.1
- resolve.exports: 1.1.0
- slash: 3.0.0
- dev: true
-
- /jest-runner/29.3.1:
- resolution: {integrity: sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/console': 29.3.1
- '@jest/environment': 29.3.1
- '@jest/test-result': 29.3.1
- '@jest/transform': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- chalk: 4.1.2
- emittery: 0.13.1
- graceful-fs: 4.2.10
- jest-docblock: 29.2.0
- jest-environment-node: 29.3.1
- jest-haste-map: 29.3.1
- jest-leak-detector: 29.3.1
- jest-message-util: 29.3.1
- jest-resolve: 29.3.1
- jest-runtime: 29.3.1
- jest-util: 29.3.1
- jest-watcher: 29.3.1
- jest-worker: 29.3.1
- p-limit: 3.1.0
- source-map-support: 0.5.13
- transitivePeerDependencies:
- - supports-color
- dev: true
-
- /jest-runtime/29.3.1:
- resolution: {integrity: sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/environment': 29.3.1
- '@jest/fake-timers': 29.3.1
- '@jest/globals': 29.3.1
- '@jest/source-map': 29.2.0
- '@jest/test-result': 29.3.1
- '@jest/transform': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- chalk: 4.1.2
- cjs-module-lexer: 1.2.2
- collect-v8-coverage: 1.0.1
- glob: 7.2.3
- graceful-fs: 4.2.10
- jest-haste-map: 29.3.1
- jest-message-util: 29.3.1
- jest-mock: 29.3.1
- jest-regex-util: 29.2.0
- jest-resolve: 29.3.1
- jest-snapshot: 29.3.1
- jest-util: 29.3.1
- slash: 3.0.0
- strip-bom: 4.0.0
+ '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)
+ meow: 13.2.0
transitivePeerDependencies:
- - supports-color
- dev: true
-
- /jest-snapshot/29.3.1:
- resolution: {integrity: sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@babel/core': 7.16.0
- '@babel/generator': 7.16.0
- '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.16.0
- '@babel/plugin-syntax-typescript': 7.16.0_@babel+core@7.16.0
- '@babel/traverse': 7.16.3
- '@babel/types': 7.16.0
- '@jest/expect-utils': 29.3.1
- '@jest/transform': 29.3.1
- '@jest/types': 29.3.1
- '@types/babel__traverse': 7.14.2
- '@types/prettier': 2.4.2
- babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.0
- chalk: 4.1.2
- expect: 29.3.1
- graceful-fs: 4.2.10
- jest-diff: 29.3.1
- jest-get-type: 29.2.0
- jest-haste-map: 29.3.1
- jest-matcher-utils: 29.3.1
- jest-message-util: 29.3.1
- jest-util: 29.3.1
- natural-compare: 1.4.0
- pretty-format: 29.3.1
- semver: 7.3.8
+ - conventional-commits-filter
+ - conventional-commits-parser
+
+ git-semver-tags@8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0):
+ dependencies:
+ '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)
+ meow: 13.2.0
transitivePeerDependencies:
- - supports-color
- dev: true
+ - conventional-commits-filter
+ - conventional-commits-parser
- /jest-util/29.3.1:
- resolution: {integrity: sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ glob-parent@5.1.2:
dependencies:
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- chalk: 4.1.2
- ci-info: 3.3.0
- graceful-fs: 4.2.10
- picomatch: 2.3.1
- dev: true
+ is-glob: 4.0.3
- /jest-validate/29.3.1:
- resolution: {integrity: sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ glob-parent@6.0.2:
dependencies:
- '@jest/types': 29.3.1
- camelcase: 6.2.1
- chalk: 4.1.2
- jest-get-type: 29.2.0
- leven: 3.1.0
- pretty-format: 29.3.1
- dev: true
-
- /jest-watcher/29.3.1:
- resolution: {integrity: sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/test-result': 29.3.1
- '@jest/types': 29.3.1
- '@types/node': 16.18.2
- ansi-escapes: 4.3.2
- chalk: 4.1.2
- emittery: 0.13.1
- jest-util: 29.3.1
- string-length: 4.0.2
- dev: true
+ is-glob: 4.0.3
- /jest-worker/29.3.1:
- resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ glob@10.4.5:
dependencies:
- '@types/node': 16.18.2
- jest-util: 29.3.1
- merge-stream: 2.0.0
- supports-color: 8.1.1
- dev: true
+ foreground-child: 3.3.0
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 1.11.1
- /jest/29.3.1_@types+node@16.11.12:
- resolution: {integrity: sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- hasBin: true
- peerDependencies:
- node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
- peerDependenciesMeta:
- node-notifier:
- optional: true
+ glob@11.0.0:
dependencies:
- '@jest/core': 29.3.1
- '@jest/types': 29.3.1
- import-local: 3.0.3
- jest-cli: 29.3.1_@types+node@16.11.12
- transitivePeerDependencies:
- - '@types/node'
- - supports-color
- - ts-node
- dev: true
+ foreground-child: 3.3.0
+ jackspeak: 4.0.1
+ minimatch: 10.0.3
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 2.0.0
- /jju/1.4.0:
- resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
- dev: true
+ globals@14.0.0: {}
- /js-stringify/1.0.2:
- resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==}
- dev: true
+ gopd@1.0.1:
+ dependencies:
+ get-intrinsic: 1.2.4
- /js-tokens/4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
- dev: true
+ graceful-fs@4.2.11: {}
- /js-yaml/3.14.1:
- resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
- hasBin: true
- dependencies:
- argparse: 1.0.10
- esprima: 4.0.1
- dev: true
+ graphemer@1.4.0: {}
- /jsdom/20.0.2:
- resolution: {integrity: sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==}
- engines: {node: '>=14'}
- peerDependencies:
- canvas: ^2.5.0
- peerDependenciesMeta:
- canvas:
- optional: true
+ handlebars@4.7.8:
dependencies:
- abab: 2.0.6
- acorn: 8.8.1
- acorn-globals: 7.0.1
- cssom: 0.5.0
- cssstyle: 2.3.0
- data-urls: 3.0.2
- decimal.js: 10.4.2
- domexception: 4.0.0
- escodegen: 2.0.0
- form-data: 4.0.0
- html-encoding-sniffer: 3.0.0
- http-proxy-agent: 5.0.0
- https-proxy-agent: 5.0.1
- is-potential-custom-element-name: 1.0.1
- nwsapi: 2.2.2
- parse5: 7.1.1
- saxes: 6.0.0
- symbol-tree: 3.2.4
- tough-cookie: 4.1.2
- w3c-xmlserializer: 3.0.0
- webidl-conversions: 7.0.0
- whatwg-encoding: 2.0.0
- whatwg-mimetype: 3.0.0
- whatwg-url: 11.0.0
- ws: 8.10.0
- xml-name-validator: 4.0.0
- transitivePeerDependencies:
- - bufferutil
- - supports-color
- - utf-8-validate
- dev: true
+ minimist: 1.2.8
+ neo-async: 2.6.2
+ source-map: 0.6.1
+ wordwrap: 1.0.0
+ optionalDependencies:
+ uglify-js: 3.19.1
- /jsesc/2.5.2:
- resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
- engines: {node: '>=4'}
- hasBin: true
- dev: true
+ has-flag@4.0.0: {}
- /json-parse-better-errors/1.0.2:
- resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
- dev: true
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.0
- /json-parse-even-better-errors/2.3.1:
- resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
- dev: true
+ has-proto@1.0.3: {}
- /json-schema-traverse/0.4.1:
- resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
- dev: true
+ has-symbols@1.0.3: {}
- /json-schema-traverse/1.0.0:
- resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
- dev: true
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.0.3
- /json-stable-stringify-without-jsonify/1.0.1:
- resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=}
- dev: true
+ hash-sum@2.0.0: {}
- /json-stringify-safe/5.0.1:
- resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=}
- dev: true
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
- /json5/1.0.1:
- resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==}
- hasBin: true
+ hosted-git-info@7.0.2:
dependencies:
- minimist: 1.2.5
- dev: true
+ lru-cache: 10.1.0
- /json5/2.2.0:
- resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==}
- engines: {node: '>=6'}
- hasBin: true
+ html-encoding-sniffer@4.0.0:
dependencies:
- minimist: 1.2.5
- dev: true
+ whatwg-encoding: 3.1.1
- /json5/2.2.1:
- resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
- engines: {node: '>=6'}
- hasBin: true
- dev: true
+ html-escaper@2.0.2: {}
- /jsonfile/4.0.0:
- resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
- optionalDependencies:
- graceful-fs: 4.2.10
- dev: true
+ http-proxy-agent@7.0.2:
+ dependencies:
+ agent-base: 7.1.3
+ debug: 4.4.0
+ transitivePeerDependencies:
+ - supports-color
- /jsonfile/6.1.0:
- resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+ https-proxy-agent@7.0.6:
dependencies:
- universalify: 2.0.0
- optionalDependencies:
- graceful-fs: 4.2.10
- dev: true
+ agent-base: 7.1.3
+ debug: 4.4.0
+ transitivePeerDependencies:
+ - supports-color
- /jsonparse/1.3.1:
- resolution: {integrity: sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=}
- engines: {'0': node >= 0.2.0}
- dev: true
+ human-signals@2.1.0: {}
- /jstransformer/1.0.0:
- resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==}
+ iconv-lite@0.6.3:
dependencies:
- is-promise: 2.2.2
- promise: 7.3.1
- dev: true
+ safer-buffer: 2.1.2
- /jszip/3.7.1:
- resolution: {integrity: sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==}
+ icss-utils@5.1.0(postcss@8.5.6):
dependencies:
- lie: 3.3.0
- pako: 1.0.11
- readable-stream: 2.3.7
- set-immediate-shim: 1.0.1
- dev: false
+ postcss: 8.5.6
- /kind-of/6.0.3:
- resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
- engines: {node: '>=0.10.0'}
- dev: true
+ ignore@5.3.2: {}
- /kleur/3.0.3:
- resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
- engines: {node: '>=6'}
- dev: true
+ ignore@7.0.4: {}
- /level-blobs/0.1.7:
- resolution: {integrity: sha512-n0iYYCGozLd36m/Pzm206+brIgXP8mxPZazZ6ZvgKr+8YwOZ8/PPpYC5zMUu2qFygRN8RO6WC/HH3XWMW7RMVg==}
- dependencies:
- level-peek: 1.0.6
- once: 1.4.0
- readable-stream: 1.1.14
- dev: true
-
- /level-filesystem/1.2.0:
- resolution: {integrity: sha512-PhXDuCNYpngpxp3jwMT9AYBMgOvB6zxj3DeuIywNKmZqFj2djj9XfT2XDVslfqmo0Ip79cAd3SBy3FsfOZPJ1g==}
- dependencies:
- concat-stream: 1.6.2
- errno: 0.1.8
- fwd-stream: 1.0.4
- level-blobs: 0.1.7
- level-peek: 1.0.6
- level-sublevel: 5.2.3
- octal: 1.0.0
- once: 1.4.0
- xtend: 2.2.0
- dev: true
+ immediate@3.0.6: {}
- /level-fix-range/1.0.2:
- resolution: {integrity: sha512-9llaVn6uqBiSlBP+wKiIEoBa01FwEISFgHSZiyec2S0KpyLUkGR4afW/FCZ/X8y+QJvzS0u4PGOlZDdh1/1avQ==}
- dev: true
+ immutable@5.0.2: {}
- /level-fix-range/2.0.0:
- resolution: {integrity: sha512-WrLfGWgwWbYPrHsYzJau+5+te89dUbENBg3/lsxOs4p2tYOhCHjbgXxBAj4DFqp3k/XBwitcRXoCh8RoCogASA==}
+ import-fresh@3.3.0:
dependencies:
- clone: 0.1.19
- dev: true
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ import-meta-resolve@3.1.1: {}
+
+ imurmurhash@0.1.4: {}
+
+ index-to-position@0.1.2: {}
+
+ inherits@2.0.4: {}
+
+ ini@1.3.8: {}
- /level-hooks/4.5.0:
- resolution: {integrity: sha512-fxLNny/vL/G4PnkLhWsbHnEaRi+A/k8r5EH/M77npZwYL62RHi2fV0S824z3QdpAk6VTgisJwIRywzBHLK4ZVA==}
+ ip-address@9.0.5:
dependencies:
- string-range: 1.2.2
- dev: true
+ jsbn: 1.1.0
+ sprintf-js: 1.1.3
- /level-js/2.2.4:
- resolution: {integrity: sha512-lZtjt4ZwHE00UMC1vAb271p9qzg8vKlnDeXfIesH3zL0KxhHRDjClQLGLWhyR0nK4XARnd4wc/9eD1ffd4PshQ==}
+ is-arrayish@0.2.1: {}
+
+ is-core-module@2.15.0:
dependencies:
- abstract-leveldown: 0.12.4
- idb-wrapper: 1.7.2
- isbuffer: 0.0.0
- ltgt: 2.2.1
- typedarray-to-buffer: 1.0.4
- xtend: 2.1.2
- dev: true
+ hasown: 2.0.2
+
+ is-docker@2.2.1: {}
- /level-peek/1.0.6:
- resolution: {integrity: sha512-TKEzH5TxROTjQxWMczt9sizVgnmJ4F3hotBI48xCTYvOKd/4gA/uY0XjKkhJFo6BMic8Tqjf6jFMLWeg3MAbqQ==}
+ is-expression@4.0.0:
dependencies:
- level-fix-range: 1.0.2
- dev: true
+ acorn: 7.4.1
+ object-assign: 4.1.1
- /level-sublevel/5.2.3:
- resolution: {integrity: sha512-tO8jrFp+QZYrxx/Gnmjawuh1UBiifpvKNAcm4KCogesWr1Nm2+ckARitf+Oo7xg4OHqMW76eAqQ204BoIlscjA==}
+ is-extglob@2.1.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-fullwidth-code-point@4.0.0: {}
+
+ is-fullwidth-code-point@5.0.0:
dependencies:
- level-fix-range: 2.0.0
- level-hooks: 4.5.0
- string-range: 1.2.2
- xtend: 2.0.6
- dev: true
+ get-east-asian-width: 1.2.0
- /levelup/0.18.6:
- resolution: {integrity: sha512-uB0auyRqIVXx+hrpIUtol4VAPhLRcnxcOsd2i2m6rbFIDarO5dnrupLOStYYpEcu8ZT087Z9HEuYw1wjr6RL6Q==}
+ is-glob@4.0.3:
dependencies:
- bl: 0.8.2
- deferred-leveldown: 0.2.0
- errno: 0.1.8
- prr: 0.0.0
- readable-stream: 1.0.34
- semver: 2.3.2
- xtend: 3.0.0
- dev: true
+ is-extglob: 2.1.1
- /leven/3.1.0:
- resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
- engines: {node: '>=6'}
- dev: true
+ is-module@1.0.0: {}
- /levn/0.3.0:
- resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==}
- engines: {node: '>= 0.8.0'}
+ is-number@7.0.0: {}
+
+ is-obj@2.0.0: {}
+
+ is-port-reachable@4.0.0: {}
+
+ is-potential-custom-element-name@1.0.1: {}
+
+ is-promise@2.2.2: {}
+
+ is-reference@1.2.1:
dependencies:
- prelude-ls: 1.1.2
- type-check: 0.3.2
- dev: true
+ '@types/estree': 1.0.7
- /levn/0.4.1:
- resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
- engines: {node: '>= 0.8.0'}
+ is-regex@1.1.4:
dependencies:
- prelude-ls: 1.2.1
- type-check: 0.4.0
- dev: true
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
- /lie/3.3.0:
- resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+ is-stream@2.0.1: {}
+
+ is-wsl@2.2.0:
dependencies:
- immediate: 3.0.6
- dev: false
+ is-docker: 2.2.1
- /lines-and-columns/1.2.4:
- resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
- dev: true
+ isarray@1.0.0: {}
- /lint-staged/10.5.4:
- resolution: {integrity: sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==}
- hasBin: true
+ isexe@2.0.0: {}
+
+ isexe@3.1.1: {}
+
+ istanbul-lib-coverage@3.2.2: {}
+
+ istanbul-lib-report@3.0.1:
dependencies:
- chalk: 4.1.2
- cli-truncate: 2.1.0
- commander: 6.2.1
- cosmiconfig: 7.0.1
- debug: 4.3.3
- dedent: 0.7.0
- enquirer: 2.3.6
- execa: 4.1.0
- listr2: 3.13.5_enquirer@2.3.6
- log-symbols: 4.1.0
- micromatch: 4.0.4
- normalize-path: 3.0.0
- please-upgrade-node: 3.2.0
- string-argv: 0.3.1
- stringify-object: 3.3.0
+ istanbul-lib-coverage: 3.2.2
+ make-dir: 4.0.0
+ supports-color: 7.2.0
+
+ istanbul-lib-source-maps@5.0.6:
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.25
+ debug: 4.4.0
+ istanbul-lib-coverage: 3.2.2
transitivePeerDependencies:
- supports-color
- dev: true
- /listr2/3.13.5_enquirer@2.3.6:
- resolution: {integrity: sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==}
- engines: {node: '>=10.0.0'}
- peerDependencies:
- enquirer: '>= 2.3.0 < 3'
- peerDependenciesMeta:
- enquirer:
- optional: true
+ istanbul-reports@3.1.7:
dependencies:
- cli-truncate: 2.1.0
- colorette: 2.0.16
- enquirer: 2.3.6
- log-update: 4.0.0
- p-map: 4.0.0
- rfdc: 1.3.0
- rxjs: 7.4.0
- through: 2.3.8
- wrap-ansi: 7.0.0
- dev: true
+ html-escaper: 2.0.2
+ istanbul-lib-report: 3.0.1
- /load-json-file/4.0.0:
- resolution: {integrity: sha1-L19Fq5HjMhYjT9U62rZo607AmTs=}
- engines: {node: '>=4'}
+ jackspeak@3.4.3:
dependencies:
- graceful-fs: 4.2.10
- parse-json: 4.0.0
- pify: 3.0.0
- strip-bom: 3.0.0
- dev: true
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
- /loader-utils/1.4.0:
- resolution: {integrity: sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==}
- engines: {node: '>=4.0.0'}
+ jackspeak@4.0.1:
dependencies:
- big.js: 5.2.2
- emojis-list: 3.0.0
- json5: 1.0.1
- dev: true
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
- /locate-path/2.0.0:
- resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
- engines: {node: '>=4'}
- dependencies:
- p-locate: 2.0.0
- path-exists: 3.0.0
- dev: true
+ js-stringify@1.0.2: {}
- /locate-path/5.0.0:
- resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
- engines: {node: '>=8'}
+ js-tokens@4.0.0: {}
+
+ js-yaml@4.1.0:
dependencies:
- p-locate: 4.1.0
- dev: true
+ argparse: 2.0.1
+
+ jsbn@1.1.0: {}
- /lodash.camelcase/4.3.0:
- resolution: {integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY=}
- dev: true
+ jsdom@26.1.0:
+ dependencies:
+ cssstyle: 4.2.1
+ data-urls: 5.0.0
+ decimal.js: 10.5.0
+ html-encoding-sniffer: 4.0.0
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ is-potential-custom-element-name: 1.0.1
+ nwsapi: 2.2.16
+ parse5: 7.2.1
+ rrweb-cssom: 0.8.0
+ saxes: 6.0.0
+ symbol-tree: 3.2.4
+ tough-cookie: 5.1.2
+ w3c-xmlserializer: 5.0.0
+ webidl-conversions: 7.0.0
+ whatwg-encoding: 3.1.1
+ whatwg-mimetype: 4.0.0
+ whatwg-url: 14.2.0
+ ws: 8.18.1
+ xml-name-validator: 5.0.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
- /lodash.get/4.4.2:
- resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
- dev: true
+ json-buffer@3.0.1: {}
- /lodash.isequal/4.5.0:
- resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
- dev: true
+ json-parse-even-better-errors@2.3.1: {}
- /lodash.ismatch/4.4.0:
- resolution: {integrity: sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=}
- dev: true
+ json-parse-even-better-errors@4.0.0: {}
- /lodash.memoize/4.1.2:
- resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
- dev: true
+ json-schema-traverse@0.4.1: {}
- /lodash.merge/4.6.2:
- resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
- dev: true
+ json-schema-traverse@1.0.0: {}
- /lodash.truncate/4.4.2:
- resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=}
- dev: true
+ json-stable-stringify-without-jsonify@1.0.1: {}
- /lodash/4.17.21:
- resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
- dev: true
+ jsonfile@6.1.0:
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
- /log-symbols/4.1.0:
- resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
- engines: {node: '>=10'}
+ jstransformer@1.0.0:
dependencies:
- chalk: 4.1.2
- is-unicode-supported: 0.1.0
- dev: true
+ is-promise: 2.2.2
+ promise: 7.3.1
- /log-update/4.0.0:
- resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==}
- engines: {node: '>=10'}
+ jszip@3.10.1:
dependencies:
- ansi-escapes: 4.3.2
- cli-cursor: 3.1.0
- slice-ansi: 4.0.0
- wrap-ansi: 6.2.0
- dev: true
+ lie: 3.3.0
+ pako: 1.0.11
+ readable-stream: 2.3.8
+ setimmediate: 1.0.5
- /lru-cache/4.1.5:
- resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
+ keyv@4.5.4:
dependencies:
- pseudomap: 1.0.2
- yallist: 2.1.2
- dev: true
+ json-buffer: 3.0.1
- /lru-cache/5.1.1:
- resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+ levn@0.4.1:
dependencies:
- yallist: 3.1.1
- dev: true
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
- /lru-cache/6.0.0:
- resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
- engines: {node: '>=10'}
+ lie@3.3.0:
dependencies:
- yallist: 4.0.0
- dev: true
+ immediate: 3.0.6
- /ltgt/2.2.1:
- resolution: {integrity: sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==}
- dev: true
+ lilconfig@3.1.3: {}
- /magic-string/0.22.5:
- resolution: {integrity: sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==}
- dependencies:
- vlq: 0.2.3
- dev: true
+ lines-and-columns@1.2.4: {}
- /magic-string/0.25.7:
- resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==}
+ lint-staged@16.0.0:
dependencies:
- sourcemap-codec: 1.4.8
+ chalk: 5.4.1
+ commander: 13.1.0
+ debug: 4.4.1
+ lilconfig: 3.1.3
+ listr2: 8.3.3
+ micromatch: 4.0.8
+ nano-spawn: 1.0.2
+ pidtree: 0.6.0
+ string-argv: 0.3.2
+ yaml: 2.8.0
+ transitivePeerDependencies:
+ - supports-color
- /magic-string/0.26.7:
- resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==}
- engines: {node: '>=12'}
+ listr2@8.3.3:
dependencies:
- sourcemap-codec: 1.4.8
- dev: true
+ cli-truncate: 4.0.0
+ colorette: 2.0.20
+ eventemitter3: 5.0.1
+ log-update: 6.1.0
+ rfdc: 1.4.1
+ wrap-ansi: 9.0.0
- /make-dir/3.1.0:
- resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
- engines: {node: '>=8'}
+ loader-utils@3.3.1: {}
+
+ locate-path@6.0.0:
dependencies:
- semver: 6.3.0
- dev: true
+ p-locate: 5.0.0
+
+ lodash.camelcase@4.3.0: {}
+
+ lodash.merge@4.6.2: {}
- /make-error/1.3.6:
- resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
- dev: true
+ lodash@4.17.21: {}
- /makeerror/1.0.12:
- resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
+ log-update@6.1.0:
dependencies:
- tmpl: 1.0.5
- dev: true
+ ansi-escapes: 7.0.0
+ cli-cursor: 5.0.0
+ slice-ansi: 7.1.0
+ strip-ansi: 7.1.0
+ wrap-ansi: 9.0.0
- /map-obj/1.0.1:
- resolution: {integrity: sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=}
- engines: {node: '>=0.10.0'}
- dev: true
+ loupe@3.1.3: {}
- /map-obj/4.3.0:
- resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
- engines: {node: '>=8'}
- dev: true
+ lru-cache@10.1.0: {}
- /marked/4.0.10:
- resolution: {integrity: sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==}
- engines: {node: '>= 12'}
- hasBin: true
- dev: true
+ lru-cache@10.4.3: {}
- /md5.js/1.3.5:
- resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
+ lru-cache@11.0.0: {}
+
+ lru-cache@11.0.2: {}
+
+ lru-cache@7.18.3: {}
+
+ magic-string@0.30.17:
dependencies:
- hash-base: 3.1.0
- inherits: 2.0.4
- safe-buffer: 5.2.1
- dev: true
+ '@jridgewell/sourcemap-codec': 1.5.0
- /memorystream/0.3.1:
- resolution: {integrity: sha1-htcJCzDORV1j+64S3aUaR93K+bI=}
- engines: {node: '>= 0.10.0'}
- dev: true
+ magicast@0.3.5:
+ dependencies:
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.1
+ source-map-js: 1.2.1
- /meow/8.1.2:
- resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==}
- engines: {node: '>=10'}
+ make-dir@4.0.0:
dependencies:
- '@types/minimist': 1.2.2
- camelcase-keys: 6.2.2
- decamelize-keys: 1.1.0
- hard-rejection: 2.1.0
- minimist-options: 4.1.0
- normalize-package-data: 3.0.3
- read-pkg-up: 7.0.1
- redent: 3.0.0
- trim-newlines: 3.0.1
- type-fest: 0.18.1
- yargs-parser: 20.2.9
- dev: true
-
- /merge-source-map/1.1.0:
- resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==}
+ semver: 7.7.2
+
+ markdown-table@3.0.4: {}
+
+ marked@13.0.3: {}
+
+ memorystream@0.3.1: {}
+
+ meow@13.2.0: {}
+
+ merge-source-map@1.1.0:
dependencies:
source-map: 0.6.1
- dev: true
- /merge-stream/2.0.0:
- resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
- dev: true
+ merge-stream@2.0.0: {}
- /merge2/1.4.1:
- resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
- engines: {node: '>= 8'}
- dev: true
+ merge2@1.4.1: {}
- /micromatch/4.0.4:
- resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==}
- engines: {node: '>=8.6'}
+ micromatch@4.0.8:
dependencies:
- braces: 3.0.2
- picomatch: 2.3.0
- dev: true
+ braces: 3.0.3
+ picomatch: 2.3.1
- /miller-rabin/4.0.1:
- resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==}
- hasBin: true
- dependencies:
- bn.js: 4.12.0
- brorand: 1.1.0
- dev: true
+ mime-db@1.33.0: {}
- /mime-db/1.33.0:
- resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==}
- engines: {node: '>= 0.6'}
- dev: true
+ mime-db@1.52.0: {}
- /mime-db/1.51.0:
- resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==}
- engines: {node: '>= 0.6'}
- dev: true
+ mime-db@1.53.0: {}
- /mime-types/2.1.18:
- resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==}
- engines: {node: '>= 0.6'}
+ mime-types@2.1.18:
dependencies:
mime-db: 1.33.0
- dev: true
- /mime-types/2.1.34:
- resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==}
- engines: {node: '>= 0.6'}
+ mime-types@2.1.35:
dependencies:
- mime-db: 1.51.0
- dev: true
-
- /mimic-fn/2.1.0:
- resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
- engines: {node: '>=6'}
- dev: true
+ mime-db: 1.52.0
- /min-indent/1.0.1:
- resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
- engines: {node: '>=4'}
- dev: true
+ mimic-fn@2.1.0: {}
- /minimalistic-assert/1.0.1:
- resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
- dev: true
+ mimic-function@5.0.1: {}
- /minimalistic-crypto-utils/1.0.1:
- resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==}
- dev: true
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
- /minimatch/3.0.4:
- resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==}
+ minimatch@10.0.3:
dependencies:
- brace-expansion: 1.1.11
- dev: true
+ '@isaacs/brace-expansion': 5.0.0
- /minimatch/3.1.2:
- resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
- dev: true
- /minimatch/5.1.0:
- resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==}
- engines: {node: '>=10'}
+ minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.1
- dev: true
- /minimist-options/4.1.0:
- resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
- engines: {node: '>= 6'}
- dependencies:
- arrify: 1.0.1
- is-plain-obj: 1.1.0
- kind-of: 6.0.3
- dev: true
-
- /minimist/1.2.5:
- resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
- dev: true
-
- /mkdirp-classic/0.5.3:
- resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
- dev: true
+ minimist@1.2.8: {}
- /modify-values/1.0.1:
- resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /monaco-editor/0.20.0:
- resolution: {integrity: sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ==}
- dev: false
+ minipass@7.1.2: {}
- /ms/2.0.0:
- resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
- dev: true
+ mitt@3.0.1: {}
- /ms/2.1.2:
- resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
- dev: true
+ monaco-editor@0.52.2: {}
- /nanoid/3.1.30:
- resolution: {integrity: sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
+ ms@2.0.0: {}
- /nanoid/3.3.4:
- resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
- dev: true
+ ms@2.1.3: {}
- /natural-compare/1.4.0:
- resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
- dev: true
+ nano-spawn@1.0.2: {}
- /negotiator/0.6.2:
- resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==}
- engines: {node: '>= 0.6'}
- dev: true
+ nanoid@3.3.11: {}
- /neo-async/2.6.2:
- resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
- dev: true
+ napi-postinstall@0.2.3: {}
- /nice-try/1.0.5:
- resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
- dev: true
+ natural-compare@1.4.0: {}
- /node-fetch/2.6.7:
- resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
- engines: {node: 4.x || >=6.0.0}
- peerDependencies:
- encoding: ^0.1.0
- peerDependenciesMeta:
- encoding:
- optional: true
- dependencies:
- whatwg-url: 5.0.0
- dev: true
+ negotiator@0.6.3: {}
- /node-int64/0.4.0:
- resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
- dev: true
+ neo-async@2.6.2: {}
- /node-releases/2.0.1:
- resolution: {integrity: sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==}
- dev: true
+ netmask@2.0.2: {}
- /normalize-package-data/2.5.0:
- resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
- dependencies:
- hosted-git-info: 2.8.9
- resolve: 1.22.1
- semver: 5.7.1
- validate-npm-package-license: 3.0.4
- dev: true
+ node-addon-api@7.1.1:
+ optional: true
- /normalize-package-data/3.0.3:
- resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==}
- engines: {node: '>=10'}
+ normalize-package-data@6.0.2:
dependencies:
- hosted-git-info: 4.0.2
- is-core-module: 2.8.0
- semver: 7.3.5
+ hosted-git-info: 7.0.2
+ semver: 7.7.2
validate-npm-package-license: 3.0.4
- dev: true
- /normalize-path/3.0.0:
- resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
- engines: {node: '>=0.10.0'}
- dev: true
+ npm-normalize-package-bin@4.0.0: {}
- /npm-run-all/4.1.5:
- resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==}
- engines: {node: '>= 4'}
- hasBin: true
+ npm-run-all2@7.0.2:
dependencies:
- ansi-styles: 3.2.1
- chalk: 2.4.2
- cross-spawn: 6.0.5
+ ansi-styles: 6.2.1
+ cross-spawn: 7.0.6
memorystream: 0.3.1
- minimatch: 3.0.4
- pidtree: 0.3.1
- read-pkg: 3.0.0
- shell-quote: 1.7.3
- string.prototype.padend: 3.1.3
- dev: true
-
- /npm-run-path/2.0.2:
- resolution: {integrity: sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=}
- engines: {node: '>=4'}
- dependencies:
- path-key: 2.0.1
- dev: true
+ minimatch: 9.0.5
+ pidtree: 0.6.0
+ read-package-json-fast: 4.0.0
+ shell-quote: 1.8.1
+ which: 5.0.0
- /npm-run-path/4.0.1:
- resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
- engines: {node: '>=8'}
+ npm-run-path@4.0.1:
dependencies:
path-key: 3.1.1
- dev: true
-
- /nwsapi/2.2.2:
- resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==}
- dev: true
-
- /object-assign/4.1.1:
- resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
- engines: {node: '>=0.10.0'}
- dev: true
- /object-inspect/1.11.1:
- resolution: {integrity: sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA==}
- dev: true
+ nwsapi@2.2.16: {}
- /object-keys/0.2.0:
- resolution: {integrity: sha512-XODjdR2pBh/1qrjPcbSeSgEtKbYo7LqYNq64/TPuCf7j9SfDD3i21yatKoIy39yIWNvVM59iutfQQpCv1RfFzA==}
- deprecated: Please update to the latest object-keys
- dependencies:
- foreach: 2.0.6
- indexof: 0.0.1
- is: 0.2.7
- dev: true
-
- /object-keys/0.4.0:
- resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==}
- dev: true
-
- /object-keys/1.1.1:
- resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /object.assign/4.1.2:
- resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.1.3
- has-symbols: 1.0.2
- object-keys: 1.1.1
- dev: true
-
- /octal/1.0.0:
- resolution: {integrity: sha512-nnda7W8d+A3vEIY+UrDQzzboPf1vhs4JYVhff5CDkq9QNoZY7Xrxeo/htox37j9dZf7yNHevZzqtejWgy1vCqQ==}
- dev: true
+ object-assign@4.1.1: {}
- /on-headers/1.0.2:
- resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
- engines: {node: '>= 0.8'}
- dev: true
+ on-headers@1.0.2: {}
- /once/1.4.0:
- resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
+ once@1.4.0:
dependencies:
wrappy: 1.0.2
- dev: true
- /onetime/5.1.2:
- resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
- engines: {node: '>=6'}
+ onetime@5.1.2:
dependencies:
mimic-fn: 2.1.0
- dev: true
- /optionator/0.8.3:
- resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==}
- engines: {node: '>= 0.8.0'}
+ onetime@7.0.0:
dependencies:
- deep-is: 0.1.4
- fast-levenshtein: 2.0.6
- levn: 0.3.0
- prelude-ls: 1.1.2
- type-check: 0.3.2
- word-wrap: 1.2.3
- dev: true
-
- /optionator/0.9.1:
- resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
- engines: {node: '>= 0.8.0'}
+ mimic-function: 5.0.1
+
+ optionator@0.9.4:
dependencies:
deep-is: 0.1.4
fast-levenshtein: 2.0.6
levn: 0.4.1
prelude-ls: 1.2.1
type-check: 0.4.0
- word-wrap: 1.2.3
- dev: true
-
- /p-finally/1.0.0:
- resolution: {integrity: sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=}
- engines: {node: '>=4'}
- dev: true
-
- /p-limit/1.3.0:
- resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==}
- engines: {node: '>=4'}
- dependencies:
- p-try: 1.0.0
- dev: true
-
- /p-limit/2.3.0:
- resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
- engines: {node: '>=6'}
- dependencies:
- p-try: 2.2.0
- dev: true
+ word-wrap: 1.2.5
- /p-limit/3.1.0:
- resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
- engines: {node: '>=10'}
+ p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
- dev: true
- /p-locate/2.0.0:
- resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
- engines: {node: '>=4'}
+ p-locate@5.0.0:
dependencies:
- p-limit: 1.3.0
- dev: true
+ p-limit: 3.1.0
- /p-locate/4.1.0:
- resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
- engines: {node: '>=8'}
+ pac-proxy-agent@7.1.0:
dependencies:
- p-limit: 2.3.0
- dev: true
+ '@tootallnate/quickjs-emscripten': 0.23.0
+ agent-base: 7.1.3
+ debug: 4.4.1
+ get-uri: 6.0.3
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ pac-resolver: 7.0.1
+ socks-proxy-agent: 8.0.5
+ transitivePeerDependencies:
+ - supports-color
- /p-map/4.0.0:
- resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
- engines: {node: '>=10'}
+ pac-resolver@7.0.1:
dependencies:
- aggregate-error: 3.1.0
- dev: true
-
- /p-try/1.0.0:
- resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==}
- engines: {node: '>=4'}
- dev: true
+ degenerator: 5.0.1
+ netmask: 2.0.2
- /p-try/2.2.0:
- resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
- engines: {node: '>=6'}
- dev: true
+ package-json-from-dist@1.0.0: {}
- /pako/1.0.11:
- resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
- dev: false
+ pako@1.0.11: {}
- /parent-module/1.0.1:
- resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
- engines: {node: '>=6'}
+ parent-module@1.0.1:
dependencies:
callsites: 3.1.0
- dev: true
-
- /parse-asn1/5.1.6:
- resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==}
- dependencies:
- asn1.js: 5.4.1
- browserify-aes: 1.2.0
- evp_bytestokey: 1.0.3
- pbkdf2: 3.1.2
- safe-buffer: 5.2.1
- dev: true
-
- /parse-json/4.0.0:
- resolution: {integrity: sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=}
- engines: {node: '>=4'}
- dependencies:
- error-ex: 1.3.2
- json-parse-better-errors: 1.0.2
- dev: true
- /parse-json/5.2.0:
- resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
- engines: {node: '>=8'}
+ parse-json@5.2.0:
dependencies:
- '@babel/code-frame': 7.16.0
+ '@babel/code-frame': 7.26.2
error-ex: 1.3.2
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
- dev: true
- /parse5/7.1.1:
- resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==}
+ parse-json@8.1.0:
dependencies:
- entities: 4.4.0
- dev: true
+ '@babel/code-frame': 7.26.2
+ index-to-position: 0.1.2
+ type-fest: 4.24.0
- /path-exists/3.0.0:
- resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
- engines: {node: '>=4'}
- dev: true
-
- /path-exists/4.0.0:
- resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
- engines: {node: '>=8'}
- dev: true
-
- /path-is-absolute/1.0.1:
- resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /path-is-inside/1.0.2:
- resolution: {integrity: sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=}
- dev: true
-
- /path-key/2.0.1:
- resolution: {integrity: sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=}
- engines: {node: '>=4'}
- dev: true
-
- /path-key/3.1.1:
- resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
- engines: {node: '>=8'}
- dev: true
+ parse5@7.2.1:
+ dependencies:
+ entities: 4.5.0
- /path-parse/1.0.7:
- resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- dev: true
+ path-exists@4.0.0: {}
- /path-to-regexp/2.2.1:
- resolution: {integrity: sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==}
- dev: true
+ path-is-inside@1.0.2: {}
- /path-type/3.0.0:
- resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
- engines: {node: '>=4'}
- dependencies:
- pify: 3.0.0
- dev: true
+ path-key@3.1.1: {}
- /path-type/4.0.0:
- resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
- engines: {node: '>=8'}
- dev: true
+ path-parse@1.0.7: {}
- /pbkdf2/3.1.2:
- resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
- engines: {node: '>=0.12'}
+ path-scurry@1.11.1:
dependencies:
- create-hash: 1.2.0
- create-hmac: 1.1.7
- ripemd160: 2.0.2
- safe-buffer: 5.2.1
- sha.js: 2.4.11
- dev: true
-
- /pend/1.2.0:
- resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
- dev: true
+ lru-cache: 10.4.3
+ minipass: 7.1.2
- /picocolors/1.0.0:
- resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.0
+ minipass: 7.1.2
- /picomatch/2.3.0:
- resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==}
- engines: {node: '>=8.6'}
- dev: true
+ path-to-regexp@3.3.0: {}
- /picomatch/2.3.1:
- resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
- engines: {node: '>=8.6'}
- dev: true
+ pathe@2.0.3: {}
- /pidtree/0.3.1:
- resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==}
- engines: {node: '>=0.10'}
- hasBin: true
- dev: true
+ pathval@2.0.0: {}
- /pify/2.3.0:
- resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=}
- engines: {node: '>=0.10.0'}
- dev: true
+ pend@1.2.0: {}
- /pify/3.0.0:
- resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=}
- engines: {node: '>=4'}
- dev: true
+ picocolors@1.1.1: {}
- /pirates/4.0.4:
- resolution: {integrity: sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==}
- engines: {node: '>= 6'}
- dev: true
+ picomatch@2.3.1: {}
- /pkg-dir/4.2.0:
- resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
- engines: {node: '>=8'}
- dependencies:
- find-up: 4.1.0
- dev: true
+ picomatch@4.0.2: {}
- /please-upgrade-node/3.2.0:
- resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==}
- dependencies:
- semver-compare: 1.0.0
- dev: true
+ pidtree@0.6.0: {}
- /postcss-modules-extract-imports/3.0.0_postcss@8.4.4:
- resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==}
- engines: {node: ^10 || ^12 || >= 14}
- peerDependencies:
- postcss: ^8.1.0
+ postcss-modules-extract-imports@3.1.0(postcss@8.5.6):
dependencies:
- postcss: 8.4.4
- dev: true
+ postcss: 8.5.6
- /postcss-modules-local-by-default/4.0.0_postcss@8.4.4:
- resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==}
- engines: {node: ^10 || ^12 || >= 14}
- peerDependencies:
- postcss: ^8.1.0
+ postcss-modules-local-by-default@4.0.5(postcss@8.5.6):
dependencies:
- icss-utils: 5.1.0_postcss@8.4.4
- postcss: 8.4.4
- postcss-selector-parser: 6.0.7
+ icss-utils: 5.1.0(postcss@8.5.6)
+ postcss: 8.5.6
+ postcss-selector-parser: 6.1.2
postcss-value-parser: 4.2.0
- dev: true
- /postcss-modules-scope/3.0.0_postcss@8.4.4:
- resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==}
- engines: {node: ^10 || ^12 || >= 14}
- peerDependencies:
- postcss: ^8.1.0
+ postcss-modules-scope@3.2.0(postcss@8.5.6):
dependencies:
- postcss: 8.4.4
- postcss-selector-parser: 6.0.7
- dev: true
+ postcss: 8.5.6
+ postcss-selector-parser: 6.1.2
- /postcss-modules-values/4.0.0_postcss@8.4.4:
- resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==}
- engines: {node: ^10 || ^12 || >= 14}
- peerDependencies:
- postcss: ^8.1.0
+ postcss-modules-values@4.0.0(postcss@8.5.6):
dependencies:
- icss-utils: 5.1.0_postcss@8.4.4
- postcss: 8.4.4
- dev: true
+ icss-utils: 5.1.0(postcss@8.5.6)
+ postcss: 8.5.6
- /postcss-modules/4.2.2_postcss@8.4.4:
- resolution: {integrity: sha512-/H08MGEmaalv/OU8j6bUKi/kZr2kqGF6huAW8m9UAgOLWtpFdhA14+gPBoymtqyv+D4MLsmqaF2zvIegdCxJXg==}
- peerDependencies:
- postcss: ^8.0.0
+ postcss-modules@6.0.1(postcss@8.5.6):
dependencies:
- generic-names: 2.0.1
- icss-replace-symbols: 1.1.0
+ generic-names: 4.0.0
+ icss-utils: 5.1.0(postcss@8.5.6)
lodash.camelcase: 4.3.0
- postcss: 8.4.4
- postcss-modules-extract-imports: 3.0.0_postcss@8.4.4
- postcss-modules-local-by-default: 4.0.0_postcss@8.4.4
- postcss-modules-scope: 3.0.0_postcss@8.4.4
- postcss-modules-values: 4.0.0_postcss@8.4.4
+ postcss: 8.5.6
+ postcss-modules-extract-imports: 3.1.0(postcss@8.5.6)
+ postcss-modules-local-by-default: 4.0.5(postcss@8.5.6)
+ postcss-modules-scope: 3.2.0(postcss@8.5.6)
+ postcss-modules-values: 4.0.0(postcss@8.5.6)
string-hash: 1.1.3
- dev: true
- /postcss-selector-parser/6.0.7:
- resolution: {integrity: sha512-U+b/Deoi4I/UmE6KOVPpnhS7I7AYdKbhGcat+qTQ27gycvaACvNEw11ba6RrkwVmDVRW7sigWgLj4/KbbJjeDA==}
- engines: {node: '>=4'}
+ postcss-selector-parser@6.1.2:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
- dev: true
-
- /postcss-value-parser/4.2.0:
- resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
- dev: true
-
- /postcss/8.4.16:
- resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==}
- engines: {node: ^10 || ^12 || >=14}
- dependencies:
- nanoid: 3.3.4
- picocolors: 1.0.0
- source-map-js: 1.0.2
- dev: true
- /postcss/8.4.4:
- resolution: {integrity: sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==}
- engines: {node: ^10 || ^12 || >=14}
+ postcss-selector-parser@7.1.0:
dependencies:
- nanoid: 3.1.30
- picocolors: 1.0.0
- source-map-js: 1.0.1
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
- /prelude-ls/1.1.2:
- resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
- engines: {node: '>= 0.8.0'}
- dev: true
+ postcss-value-parser@4.2.0: {}
- /prelude-ls/1.2.1:
- resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
- engines: {node: '>= 0.8.0'}
- dev: true
+ postcss@8.5.6:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
- /prettier/2.7.1:
- resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
- engines: {node: '>=10.13.0'}
- hasBin: true
- dev: true
+ prelude-ls@1.2.1: {}
- /pretty-format/29.3.1:
- resolution: {integrity: sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@jest/schemas': 29.0.0
- ansi-styles: 5.2.0
- react-is: 18.2.0
- dev: true
+ prettier@3.5.3: {}
- /process-es6/0.11.6:
- resolution: {integrity: sha512-GYBRQtL4v3wgigq10Pv58jmTbFXlIiTbSfgnNqZLY0ldUPqy1rRxDI5fCjoCpnM6TqmHQI8ydzTBXW86OYc0gA==}
- dev: true
+ pretty-bytes@6.1.1: {}
- /process-nextick-args/2.0.1:
- resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+ process-nextick-args@2.0.1: {}
- /progress/2.0.3:
- resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
- engines: {node: '>=0.4.0'}
- dev: true
+ progress@2.0.3: {}
- /promise/7.3.1:
- resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==}
+ promise@7.3.1:
dependencies:
asap: 2.0.6
- dev: true
- /prompts/2.4.2:
- resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
- engines: {node: '>= 6'}
+ proxy-agent@6.5.0:
dependencies:
- kleur: 3.0.3
- sisteransi: 1.0.5
- dev: true
-
- /proxy-from-env/1.1.0:
- resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- dev: true
-
- /prr/0.0.0:
- resolution: {integrity: sha512-LmUECmrW7RVj6mDWKjTXfKug7TFGdiz9P18HMcO4RHL+RW7MCOGNvpj5j47Rnp6ne6r4fZ2VzyUWEpKbg+tsjQ==}
- dev: true
-
- /prr/1.0.1:
- resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
- dev: true
-
- /pseudomap/1.0.2:
- resolution: {integrity: sha1-8FKijacOYYkX7wqKw0wa5aaChrM=}
- dev: true
-
- /psl/1.9.0:
- resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
- dev: true
+ agent-base: 7.1.3
+ debug: 4.4.1
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ lru-cache: 7.18.3
+ pac-proxy-agent: 7.1.0
+ proxy-from-env: 1.1.0
+ socks-proxy-agent: 8.0.5
+ transitivePeerDependencies:
+ - supports-color
- /public-encrypt/4.0.3:
- resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==}
- dependencies:
- bn.js: 4.12.0
- browserify-rsa: 4.1.0
- create-hash: 1.2.0
- parse-asn1: 5.1.6
- randombytes: 2.1.0
- safe-buffer: 5.2.1
- dev: true
+ proxy-from-env@1.1.0: {}
- /pug-attrs/3.0.0:
- resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==}
+ pug-attrs@3.0.0:
dependencies:
constantinople: 4.0.1
js-stringify: 1.0.2
pug-runtime: 3.0.1
- dev: true
- /pug-code-gen/3.0.2:
- resolution: {integrity: sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==}
+ pug-code-gen@3.0.3:
dependencies:
constantinople: 4.0.1
doctypes: 1.1.0
js-stringify: 1.0.2
pug-attrs: 3.0.0
- pug-error: 2.0.0
+ pug-error: 2.1.0
pug-runtime: 3.0.1
void-elements: 3.1.0
with: 7.0.2
- dev: true
- /pug-error/2.0.0:
- resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==}
- dev: true
+ pug-error@2.1.0: {}
- /pug-filters/4.0.0:
- resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==}
+ pug-filters@4.0.0:
dependencies:
constantinople: 4.0.1
jstransformer: 1.0.0
- pug-error: 2.0.0
+ pug-error: 2.1.0
pug-walk: 2.0.0
- resolve: 1.22.1
- dev: true
+ resolve: 1.22.8
- /pug-lexer/5.0.1:
- resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==}
+ pug-lexer@5.0.1:
dependencies:
character-parser: 2.2.0
is-expression: 4.0.0
- pug-error: 2.0.0
- dev: true
+ pug-error: 2.1.0
- /pug-linker/4.0.0:
- resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==}
+ pug-linker@4.0.0:
dependencies:
- pug-error: 2.0.0
+ pug-error: 2.1.0
pug-walk: 2.0.0
- dev: true
- /pug-load/3.0.0:
- resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==}
+ pug-load@3.0.0:
dependencies:
object-assign: 4.1.1
pug-walk: 2.0.0
- dev: true
- /pug-parser/6.0.0:
- resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==}
+ pug-parser@6.0.0:
dependencies:
- pug-error: 2.0.0
+ pug-error: 2.1.0
token-stream: 1.0.0
- dev: true
- /pug-runtime/3.0.1:
- resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==}
- dev: true
+ pug-runtime@3.0.1: {}
- /pug-strip-comments/2.0.0:
- resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==}
+ pug-strip-comments@2.0.0:
dependencies:
- pug-error: 2.0.0
- dev: true
+ pug-error: 2.1.0
- /pug-walk/2.0.0:
- resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==}
- dev: true
+ pug-walk@2.0.0: {}
- /pug/3.0.2:
- resolution: {integrity: sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==}
+ pug@3.0.3:
dependencies:
- pug-code-gen: 3.0.2
+ pug-code-gen: 3.0.3
pug-filters: 4.0.0
pug-lexer: 5.0.1
pug-linker: 4.0.0
@@ -6204,169 +5937,74 @@ packages:
pug-parser: 6.0.0
pug-runtime: 3.0.1
pug-strip-comments: 2.0.0
- dev: true
- /pump/3.0.0:
- resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
+ pump@3.0.0:
dependencies:
end-of-stream: 1.4.4
once: 1.4.0
- dev: true
- /punycode/1.4.1:
- resolution: {integrity: sha1-wNWmOycYgArY4esPpSachN1BhF4=}
- dev: true
-
- /punycode/2.1.1:
- resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
- engines: {node: '>=6'}
- dev: true
+ punycode@2.3.1: {}
- /puppeteer-core/19.2.2:
- resolution: {integrity: sha512-faojf+1pZ/tHXSr4x1q+9MVd9FrL3rpdbC0w7qN7MNClMoLuCvMbpR4vzcjoiJYgclt1n+SOPUOmHQViTw6frw==}
- engines: {node: '>=14.1.0'}
+ puppeteer-core@24.9.0:
dependencies:
- cross-fetch: 3.1.5
- debug: 4.3.4
- devtools-protocol: 0.0.1056733
- extract-zip: 2.0.1
- https-proxy-agent: 5.0.1
- proxy-from-env: 1.1.0
- rimraf: 3.0.2
- tar-fs: 2.1.1
- unbzip2-stream: 1.4.3
- ws: 8.10.0
+ '@puppeteer/browsers': 2.10.5
+ chromium-bidi: 5.1.0(devtools-protocol@0.0.1439962)
+ debug: 4.4.1
+ devtools-protocol: 0.0.1439962
+ typed-query-selector: 2.12.0
+ ws: 8.18.2
transitivePeerDependencies:
- bufferutil
- - encoding
- supports-color
- utf-8-validate
- dev: true
- /puppeteer/19.2.2:
- resolution: {integrity: sha512-m1T5Mog5qu5+dMBptWYTn6pXRdnFbydbVUCthqwbfd8/kOiMlzZBR9ywjX79LpvI1Sj+/z8+FKeIsjnMul8ZYA==}
- engines: {node: '>=14.1.0'}
- requiresBuild: true
+ puppeteer@24.9.0(typescript@5.6.3):
dependencies:
- cosmiconfig: 7.0.1
- devtools-protocol: 0.0.1056733
- https-proxy-agent: 5.0.1
- progress: 2.0.3
- proxy-from-env: 1.1.0
- puppeteer-core: 19.2.2
+ '@puppeteer/browsers': 2.10.5
+ chromium-bidi: 5.1.0(devtools-protocol@0.0.1439962)
+ cosmiconfig: 9.0.0(typescript@5.6.3)
+ devtools-protocol: 0.0.1439962
+ puppeteer-core: 24.9.0
+ typed-query-selector: 2.12.0
transitivePeerDependencies:
- bufferutil
- - encoding
- supports-color
+ - typescript
- utf-8-validate
- dev: true
-
- /q/1.5.1:
- resolution: {integrity: sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=}
- engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
- dev: true
-
- /querystringify/2.2.0:
- resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
- dev: true
-
- /queue-microtask/1.2.3:
- resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
- dev: true
-
- /quick-lru/4.0.1:
- resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
- engines: {node: '>=8'}
- dev: true
- /randombytes/2.1.0:
- resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
- dependencies:
- safe-buffer: 5.2.1
- dev: true
+ queue-microtask@1.2.3: {}
- /randomfill/1.0.4:
- resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==}
- dependencies:
- randombytes: 2.1.0
- safe-buffer: 5.2.1
- dev: true
+ queue-tick@1.0.1: {}
- /range-parser/1.2.0:
- resolution: {integrity: sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=}
- engines: {node: '>= 0.6'}
- dev: true
+ range-parser@1.2.0: {}
- /rc/1.2.8:
- resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
- hasBin: true
+ rc@1.2.8:
dependencies:
deep-extend: 0.6.0
ini: 1.3.8
- minimist: 1.2.5
+ minimist: 1.2.8
strip-json-comments: 2.0.1
- dev: true
-
- /react-is/18.2.0:
- resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
- dev: true
-
- /read-pkg-up/3.0.0:
- resolution: {integrity: sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=}
- engines: {node: '>=4'}
- dependencies:
- find-up: 2.1.0
- read-pkg: 3.0.0
- dev: true
-
- /read-pkg-up/7.0.1:
- resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
- engines: {node: '>=8'}
- dependencies:
- find-up: 4.1.0
- read-pkg: 5.2.0
- type-fest: 0.8.1
- dev: true
-
- /read-pkg/3.0.0:
- resolution: {integrity: sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=}
- engines: {node: '>=4'}
- dependencies:
- load-json-file: 4.0.0
- normalize-package-data: 2.5.0
- path-type: 3.0.0
- dev: true
- /read-pkg/5.2.0:
- resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
- engines: {node: '>=8'}
+ read-package-json-fast@4.0.0:
dependencies:
- '@types/normalize-package-data': 2.4.1
- normalize-package-data: 2.5.0
- parse-json: 5.2.0
- type-fest: 0.6.0
- dev: true
+ json-parse-even-better-errors: 4.0.0
+ npm-normalize-package-bin: 4.0.0
- /readable-stream/1.0.34:
- resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==}
+ read-package-up@11.0.0:
dependencies:
- core-util-is: 1.0.3
- inherits: 2.0.4
- isarray: 0.0.1
- string_decoder: 0.10.31
- dev: true
+ find-up-simple: 1.0.0
+ read-pkg: 9.0.1
+ type-fest: 4.24.0
- /readable-stream/1.1.14:
- resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==}
+ read-pkg@9.0.1:
dependencies:
- core-util-is: 1.0.3
- inherits: 2.0.4
- isarray: 0.0.1
- string_decoder: 0.10.31
- dev: true
+ '@types/normalize-package-data': 2.4.4
+ normalize-package-data: 6.0.2
+ parse-json: 8.1.0
+ type-fest: 4.24.0
+ unicorn-magic: 0.1.0
- /readable-stream/2.3.7:
- resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==}
+ readable-stream@2.3.8:
dependencies:
core-util-is: 1.0.3
inherits: 2.0.4
@@ -6376,1352 +6014,601 @@ packages:
string_decoder: 1.1.1
util-deprecate: 1.0.2
- /readable-stream/3.6.0:
- resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==}
- engines: {node: '>= 6'}
- dependencies:
- inherits: 2.0.4
- string_decoder: 1.3.0
- util-deprecate: 1.0.2
- dev: true
-
- /readdirp/3.6.0:
- resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
- engines: {node: '>=8.10.0'}
- dependencies:
- picomatch: 2.3.0
- dev: true
-
- /redent/3.0.0:
- resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
- engines: {node: '>=8'}
- dependencies:
- indent-string: 4.0.0
- strip-indent: 3.0.0
- dev: true
-
- /regexpp/3.2.0:
- resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
- engines: {node: '>=8'}
- dev: true
+ readdirp@4.0.1: {}
- /registry-auth-token/3.3.2:
- resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==}
+ registry-auth-token@3.3.2:
dependencies:
rc: 1.2.8
safe-buffer: 5.2.1
- dev: true
- /registry-url/3.1.0:
- resolution: {integrity: sha1-PU74cPc93h138M+aOBQyRE4XSUI=}
- engines: {node: '>=0.10.0'}
+ registry-url@3.1.0:
dependencies:
rc: 1.2.8
- dev: true
-
- /require-directory/2.1.1:
- resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /require-from-string/2.0.2:
- resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
- engines: {node: '>=0.10.0'}
- dev: true
- /requires-port/1.0.0:
- resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
- dev: true
+ require-directory@2.1.1: {}
- /resolve-cwd/3.0.0:
- resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
- engines: {node: '>=8'}
- dependencies:
- resolve-from: 5.0.0
- dev: true
-
- /resolve-from/4.0.0:
- resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
- engines: {node: '>=4'}
- dev: true
-
- /resolve-from/5.0.0:
- resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
- engines: {node: '>=8'}
- dev: true
-
- /resolve.exports/1.1.0:
- resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==}
- engines: {node: '>=10'}
- dev: true
+ require-from-string@2.0.2: {}
- /resolve/1.17.0:
- resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==}
- dependencies:
- path-parse: 1.0.7
- dev: true
+ resolve-from@4.0.0: {}
- /resolve/1.19.0:
- resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
- dependencies:
- is-core-module: 2.8.1
- path-parse: 1.0.7
- dev: true
+ resolve-pkg-maps@1.0.0: {}
- /resolve/1.22.1:
- resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
- hasBin: true
+ resolve@1.22.8:
dependencies:
- is-core-module: 2.10.0
+ is-core-module: 2.15.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
- dev: true
- /restore-cursor/3.1.0:
- resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
- engines: {node: '>=8'}
+ restore-cursor@5.1.0:
dependencies:
- onetime: 5.1.2
- signal-exit: 3.0.6
- dev: true
+ onetime: 7.0.0
+ signal-exit: 4.1.0
- /reusify/1.0.4:
- resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
- engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
- dev: true
-
- /rfdc/1.3.0:
- resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==}
- dev: true
-
- /rimraf/3.0.2:
- resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
- hasBin: true
- dependencies:
- glob: 7.2.3
- dev: true
+ reusify@1.1.0: {}
- /ripemd160/2.0.2:
- resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==}
- dependencies:
- hash-base: 3.1.0
- inherits: 2.0.4
- dev: true
+ rfdc@1.4.1: {}
- /rollup-plugin-inject/3.0.2:
- resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==}
- deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.
+ rimraf@6.0.1:
dependencies:
- estree-walker: 0.6.1
- magic-string: 0.25.7
- rollup-pluginutils: 2.8.2
- dev: true
+ glob: 11.0.0
+ package-json-from-dist: 1.0.0
- /rollup-plugin-node-builtins/2.1.2:
- resolution: {integrity: sha512-bxdnJw8jIivr2yEyt8IZSGqZkygIJOGAWypXvHXnwKAbUcN4Q/dGTx7K0oAJryC/m6aq6tKutltSeXtuogU6sw==}
+ rollup-plugin-dts@6.2.1(rollup@4.45.1)(typescript@5.6.3):
dependencies:
- browserify-fs: 1.0.0
- buffer-es6: 4.9.3
- crypto-browserify: 3.12.0
- process-es6: 0.11.6
- dev: true
+ magic-string: 0.30.17
+ rollup: 4.45.1
+ typescript: 5.6.3
+ optionalDependencies:
+ '@babel/code-frame': 7.26.2
- /rollup-plugin-node-globals/1.4.0:
- resolution: {integrity: sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g==}
+ rollup-plugin-esbuild@6.2.1(esbuild@0.25.8)(rollup@4.45.1):
dependencies:
- acorn: 5.7.4
- buffer-es6: 4.9.3
- estree-walker: 0.5.2
- magic-string: 0.22.5
- process-es6: 0.11.6
- rollup-pluginutils: 2.8.2
- dev: true
+ debug: 4.4.0
+ es-module-lexer: 1.6.0
+ esbuild: 0.25.8
+ get-tsconfig: 4.10.0
+ rollup: 4.45.1
+ unplugin-utils: 0.2.4
+ transitivePeerDependencies:
+ - supports-color
- /rollup-plugin-node-polyfills/0.2.1:
- resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==}
+ rollup-plugin-polyfill-node@0.13.0(rollup@4.45.1):
dependencies:
- rollup-plugin-inject: 3.0.2
- dev: true
+ '@rollup/plugin-inject': 5.0.5(rollup@4.45.1)
+ rollup: 4.45.1
- /rollup-plugin-polyfill-node/0.11.0_rollup@3.2.3:
- resolution: {integrity: sha512-5t+qhq4LAQKQBgbPOQJEoxxGzU5b+zLfvzpUAGy9u0MCMs8y+mrjUAv8+xrkWdxnwXQwJtjmCMnA9lCflsMzNw==}
- peerDependencies:
- rollup: ^1.20.0 || ^2.0.0 || ^3.0.0
+ rollup@4.45.1:
dependencies:
- '@rollup/plugin-inject': 5.0.2_rollup@3.2.3
- rollup: 3.2.3
- dev: true
-
- /rollup-plugin-typescript2/0.34.1_6q6ezahorvzz2ktdwmpggsjixa:
- resolution: {integrity: sha512-P4cHLtGikESmqi1CA+tdMDUv8WbQV48mzPYt77TSTOPJpERyZ9TXdDgjSDix8Fkqce6soYz3+fa4lrC93IEkcw==}
- peerDependencies:
- rollup: '>=1.26.3'
- typescript: '>=2.4.0'
- dependencies:
- '@rollup/pluginutils': 4.2.1
- find-cache-dir: 3.3.2
- fs-extra: 10.1.0
- rollup: 3.2.3
- semver: 7.3.8
- tslib: 2.4.0
- typescript: 4.8.2
- dev: true
-
- /rollup-pluginutils/2.8.2:
- resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
- dependencies:
- estree-walker: 0.6.1
- dev: true
-
- /rollup/2.77.3:
- resolution: {integrity: sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==}
- engines: {node: '>=10.0.0'}
- hasBin: true
- optionalDependencies:
- fsevents: 2.3.2
- dev: true
-
- /rollup/3.2.3:
- resolution: {integrity: sha512-qfadtkY5kl0F5e4dXVdj2D+GtOdifasXHFMiL1SMf9ADQDv5Eti6xReef9FKj+iQPR2pvtqWna57s/PjARY4fg==}
- engines: {node: '>=14.18.0', npm: '>=8.0.0'}
- hasBin: true
+ '@types/estree': 1.0.8
optionalDependencies:
- fsevents: 2.3.2
- dev: true
-
- /run-parallel/1.2.0:
- resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ '@rollup/rollup-android-arm-eabi': 4.45.1
+ '@rollup/rollup-android-arm64': 4.45.1
+ '@rollup/rollup-darwin-arm64': 4.45.1
+ '@rollup/rollup-darwin-x64': 4.45.1
+ '@rollup/rollup-freebsd-arm64': 4.45.1
+ '@rollup/rollup-freebsd-x64': 4.45.1
+ '@rollup/rollup-linux-arm-gnueabihf': 4.45.1
+ '@rollup/rollup-linux-arm-musleabihf': 4.45.1
+ '@rollup/rollup-linux-arm64-gnu': 4.45.1
+ '@rollup/rollup-linux-arm64-musl': 4.45.1
+ '@rollup/rollup-linux-loongarch64-gnu': 4.45.1
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.45.1
+ '@rollup/rollup-linux-riscv64-gnu': 4.45.1
+ '@rollup/rollup-linux-riscv64-musl': 4.45.1
+ '@rollup/rollup-linux-s390x-gnu': 4.45.1
+ '@rollup/rollup-linux-x64-gnu': 4.45.1
+ '@rollup/rollup-linux-x64-musl': 4.45.1
+ '@rollup/rollup-win32-arm64-msvc': 4.45.1
+ '@rollup/rollup-win32-ia32-msvc': 4.45.1
+ '@rollup/rollup-win32-x64-msvc': 4.45.1
+ fsevents: 2.3.3
+
+ rrweb-cssom@0.8.0: {}
+
+ run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
- dev: true
- /rxjs/7.4.0:
- resolution: {integrity: sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==}
- dependencies:
- tslib: 2.1.0
- dev: true
-
- /safe-buffer/5.1.2:
- resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+ safe-buffer@5.1.2: {}
- /safe-buffer/5.2.1:
- resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
- dev: true
+ safe-buffer@5.2.1: {}
- /safer-buffer/2.1.2:
- resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
- dev: true
+ safer-buffer@2.1.2: {}
- /sass/1.45.0:
- resolution: {integrity: sha512-ONy5bjppoohtNkFJRqdz1gscXamMzN3wQy1YH9qO2FiNpgjLhpz/IPRGg0PpCjyz/pWfCOaNEaiEGCcjOFAjqw==}
- engines: {node: '>=8.9.0'}
- hasBin: true
+ sass@1.89.2:
dependencies:
- chokidar: 3.5.2
- immutable: 4.0.0
- source-map-js: 1.0.1
- dev: true
+ chokidar: 4.0.1
+ immutable: 5.0.2
+ source-map-js: 1.2.1
+ optionalDependencies:
+ '@parcel/watcher': 2.4.1
- /saxes/6.0.0:
- resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
- engines: {node: '>=v12.22.7'}
+ saxes@6.0.0:
dependencies:
xmlchars: 2.2.0
- dev: true
-
- /semver-compare/1.0.0:
- resolution: {integrity: sha1-De4hahyUGrN+nvsXiPavxf9VN/w=}
- dev: true
-
- /semver/2.3.2:
- resolution: {integrity: sha512-abLdIKCosKfpnmhS52NCTjO4RiLspDfsn37prjzGrp9im5DPJOgh82Os92vtwGh6XdQryKI/7SREZnV+aqiXrA==}
- hasBin: true
- dev: true
- /semver/5.7.1:
- resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
- hasBin: true
- dev: true
-
- /semver/6.3.0:
- resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
- hasBin: true
- dev: true
-
- /semver/7.3.5:
- resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- lru-cache: 6.0.0
- dev: true
-
- /semver/7.3.8:
- resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- lru-cache: 6.0.0
- dev: true
+ semver@7.7.2: {}
- /serve-handler/6.1.3:
- resolution: {integrity: sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==}
+ serve-handler@6.1.6:
dependencies:
bytes: 3.0.0
content-disposition: 0.5.2
- fast-url-parser: 1.1.3
mime-types: 2.1.18
- minimatch: 3.0.4
+ minimatch: 3.1.2
path-is-inside: 1.0.2
- path-to-regexp: 2.2.1
+ path-to-regexp: 3.3.0
range-parser: 1.2.0
- dev: true
- /serve/12.0.1:
- resolution: {integrity: sha512-CQ4ikLpxg/wmNM7yivulpS6fhjRiFG6OjmP8ty3/c1SBnSk23fpKmLAV4HboTA2KrZhkUPlDfjDhnRmAjQ5Phw==}
- hasBin: true
- dependencies:
- '@zeit/schemas': 2.6.0
- ajv: 6.12.6
- arg: 2.0.0
- boxen: 1.3.0
- chalk: 2.4.1
- clipboardy: 2.3.0
- compression: 1.7.3
- serve-handler: 6.1.3
- update-check: 1.5.2
+ serve@14.2.4:
+ dependencies:
+ '@zeit/schemas': 2.36.0
+ ajv: 8.12.0
+ arg: 5.0.2
+ boxen: 7.0.0
+ chalk: 5.0.1
+ chalk-template: 0.4.0
+ clipboardy: 3.0.0
+ compression: 1.7.4
+ is-port-reachable: 4.0.0
+ serve-handler: 6.1.6
+ update-check: 1.5.4
transitivePeerDependencies:
- supports-color
- dev: true
-
- /set-immediate-shim/1.0.1:
- resolution: {integrity: sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=}
- engines: {node: '>=0.10.0'}
- dev: false
-
- /sha.js/2.4.11:
- resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==}
- hasBin: true
- dependencies:
- inherits: 2.0.4
- safe-buffer: 5.2.1
- dev: true
-
- /shebang-command/1.2.0:
- resolution: {integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=}
- engines: {node: '>=0.10.0'}
- dependencies:
- shebang-regex: 1.0.0
- dev: true
-
- /shebang-command/2.0.0:
- resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
- engines: {node: '>=8'}
- dependencies:
- shebang-regex: 3.0.0
- dev: true
-
- /shebang-regex/1.0.0:
- resolution: {integrity: sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /shebang-regex/3.0.0:
- resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
- engines: {node: '>=8'}
- dev: true
-
- /shell-quote/1.7.3:
- resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==}
- dev: true
-
- /side-channel/1.0.4:
- resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.1.1
- object-inspect: 1.11.1
- dev: true
-
- /signal-exit/3.0.6:
- resolution: {integrity: sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==}
- dev: true
-
- /signal-exit/3.0.7:
- resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
- dev: true
-
- /simple-git-hooks/2.8.1:
- resolution: {integrity: sha512-DYpcVR1AGtSfFUNzlBdHrQGPsOhuuEJ/FkmPOOlFysP60AHd3nsEpkGq/QEOdtUyT1Qhk7w9oLmFoMG+75BDog==}
- hasBin: true
- requiresBuild: true
- dev: true
-
- /sisteransi/1.0.5:
- resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
- dev: true
-
- /slash/3.0.0:
- resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
- engines: {node: '>=8'}
- dev: true
-
- /slice-ansi/3.0.0:
- resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
- engines: {node: '>=8'}
- dependencies:
- ansi-styles: 4.3.0
- astral-regex: 2.0.0
- is-fullwidth-code-point: 3.0.0
- dev: true
-
- /slice-ansi/4.0.0:
- resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
- engines: {node: '>=10'}
- dependencies:
- ansi-styles: 4.3.0
- astral-regex: 2.0.0
- is-fullwidth-code-point: 3.0.0
- dev: true
-
- /source-map-js/1.0.1:
- resolution: {integrity: sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==}
- engines: {node: '>=0.10.0'}
-
- /source-map-js/1.0.2:
- resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /source-map-support/0.5.13:
- resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==}
- dependencies:
- buffer-from: 1.1.2
- source-map: 0.6.1
- dev: true
-
- /source-map-support/0.5.21:
- resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
- dependencies:
- buffer-from: 1.1.2
- source-map: 0.6.1
- dev: true
-
- /source-map/0.5.7:
- resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /source-map/0.6.1:
- resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
- engines: {node: '>=0.10.0'}
-
- /sourcemap-codec/1.4.8:
- resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
-
- /spdx-correct/3.1.1:
- resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==}
- dependencies:
- spdx-expression-parse: 3.0.1
- spdx-license-ids: 3.0.11
- dev: true
-
- /spdx-exceptions/2.3.0:
- resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==}
- dev: true
-
- /spdx-expression-parse/3.0.1:
- resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
- dependencies:
- spdx-exceptions: 2.3.0
- spdx-license-ids: 3.0.11
- dev: true
-
- /spdx-license-ids/3.0.11:
- resolution: {integrity: sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==}
- dev: true
- /split/1.0.1:
- resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==}
+ set-function-length@1.2.2:
dependencies:
- through: 2.3.8
- dev: true
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ gopd: 1.0.1
+ has-property-descriptors: 1.0.2
- /split2/3.2.2:
- resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==}
+ setimmediate@1.0.5: {}
+
+ shebang-command@2.0.0:
dependencies:
- readable-stream: 3.6.0
- dev: true
+ shebang-regex: 3.0.0
- /sprintf-js/1.0.3:
- resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
- dev: true
+ shebang-regex@3.0.0: {}
- /stack-utils/2.0.5:
- resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==}
- engines: {node: '>=10'}
- dependencies:
- escape-string-regexp: 2.0.0
- dev: true
+ shell-quote@1.8.1: {}
- /string-argv/0.3.1:
- resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==}
- engines: {node: '>=0.6.19'}
- dev: true
+ siginfo@2.0.0: {}
- /string-hash/1.1.3:
- resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=}
- dev: true
+ signal-exit@3.0.7: {}
- /string-length/4.0.2:
- resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
- engines: {node: '>=10'}
- dependencies:
- char-regex: 1.0.2
- strip-ansi: 6.0.1
- dev: true
+ signal-exit@4.1.0: {}
- /string-range/1.2.2:
- resolution: {integrity: sha512-tYft6IFi8SjplJpxCUxyqisD3b+R2CSkomrtJYCkvuf1KuCAWgz7YXt4O0jip7efpfCemwHEzTEAO8EuOYgh3w==}
- dev: true
+ simple-git-hooks@2.13.0: {}
- /string-width/2.1.1:
- resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==}
- engines: {node: '>=4'}
+ slice-ansi@5.0.0:
dependencies:
- is-fullwidth-code-point: 2.0.0
- strip-ansi: 4.0.0
- dev: true
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
- /string-width/4.2.3:
- resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
- engines: {node: '>=8'}
+ slice-ansi@7.1.0:
dependencies:
- emoji-regex: 8.0.0
- is-fullwidth-code-point: 3.0.0
- strip-ansi: 6.0.1
- dev: true
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 5.0.0
- /string.prototype.padend/3.1.3:
- resolution: {integrity: sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.1.3
- es-abstract: 1.19.1
- dev: true
+ smart-buffer@4.2.0: {}
- /string.prototype.trimend/1.0.4:
- resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==}
+ socks-proxy-agent@8.0.5:
dependencies:
- call-bind: 1.0.2
- define-properties: 1.1.3
- dev: true
+ agent-base: 7.1.3
+ debug: 4.4.1
+ socks: 2.8.3
+ transitivePeerDependencies:
+ - supports-color
- /string.prototype.trimstart/1.0.4:
- resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==}
+ socks@2.8.3:
dependencies:
- call-bind: 1.0.2
- define-properties: 1.1.3
- dev: true
+ ip-address: 9.0.5
+ smart-buffer: 4.2.0
- /string_decoder/0.10.31:
- resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==}
- dev: true
+ source-map-js@1.2.1: {}
- /string_decoder/1.1.1:
- resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
- dependencies:
- safe-buffer: 5.1.2
+ source-map@0.6.1: {}
- /string_decoder/1.3.0:
- resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+ spdx-correct@3.2.0:
dependencies:
- safe-buffer: 5.2.1
- dev: true
+ spdx-expression-parse: 3.0.1
+ spdx-license-ids: 3.0.18
- /stringify-object/3.3.0:
- resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==}
- engines: {node: '>=4'}
- dependencies:
- get-own-enumerable-property-symbols: 3.0.2
- is-obj: 1.0.1
- is-regexp: 1.0.0
- dev: true
+ spdx-exceptions@2.5.0: {}
- /strip-ansi/4.0.0:
- resolution: {integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8=}
- engines: {node: '>=4'}
+ spdx-expression-parse@3.0.1:
dependencies:
- ansi-regex: 3.0.0
- dev: true
+ spdx-exceptions: 2.5.0
+ spdx-license-ids: 3.0.18
- /strip-ansi/6.0.1:
- resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
- engines: {node: '>=8'}
- dependencies:
- ansi-regex: 5.0.1
- dev: true
+ spdx-license-ids@3.0.18: {}
- /strip-bom/3.0.0:
- resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=}
- engines: {node: '>=4'}
- dev: true
+ sprintf-js@1.1.3: {}
- /strip-bom/4.0.0:
- resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
- engines: {node: '>=8'}
- dev: true
+ stable-hash@0.0.5: {}
- /strip-eof/1.0.0:
- resolution: {integrity: sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=}
- engines: {node: '>=0.10.0'}
- dev: true
+ stackback@0.0.2: {}
- /strip-final-newline/2.0.0:
- resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
- engines: {node: '>=6'}
- dev: true
+ std-env@3.9.0: {}
- /strip-indent/3.0.0:
- resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
- engines: {node: '>=8'}
+ streamx@2.18.0:
dependencies:
- min-indent: 1.0.1
- dev: true
+ fast-fifo: 1.3.2
+ queue-tick: 1.0.1
+ text-decoder: 1.1.1
+ optionalDependencies:
+ bare-events: 2.4.2
- /strip-json-comments/2.0.1:
- resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ string-argv@0.3.2: {}
- /strip-json-comments/3.1.1:
- resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
- engines: {node: '>=8'}
- dev: true
+ string-hash@1.1.3: {}
- /supports-color/5.5.0:
- resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
- engines: {node: '>=4'}
+ string-width@4.2.3:
dependencies:
- has-flag: 3.0.0
- dev: true
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
- /supports-color/7.2.0:
- resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
- engines: {node: '>=8'}
+ string-width@5.1.2:
dependencies:
- has-flag: 4.0.0
- dev: true
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
- /supports-color/8.1.1:
- resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
- engines: {node: '>=10'}
+ string-width@7.2.0:
dependencies:
- has-flag: 4.0.0
- dev: true
-
- /supports-preserve-symlinks-flag/1.0.0:
- resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /symbol-tree/3.2.4:
- resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
- dev: true
+ emoji-regex: 10.3.0
+ get-east-asian-width: 1.2.0
+ strip-ansi: 7.1.0
- /table/6.7.5:
- resolution: {integrity: sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==}
- engines: {node: '>=10.0.0'}
+ string_decoder@1.1.1:
dependencies:
- ajv: 8.8.2
- lodash.truncate: 4.4.2
- slice-ansi: 4.0.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
- dev: true
+ safe-buffer: 5.1.2
- /tar-fs/2.1.1:
- resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
+ strip-ansi@6.0.1:
dependencies:
- chownr: 1.1.4
- mkdirp-classic: 0.5.3
- pump: 3.0.0
- tar-stream: 2.2.0
- dev: true
+ ansi-regex: 5.0.1
- /tar-stream/2.2.0:
- resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
- engines: {node: '>=6'}
+ strip-ansi@7.1.0:
dependencies:
- bl: 4.1.0
- end-of-stream: 1.4.4
- fs-constants: 1.0.0
- inherits: 2.0.4
- readable-stream: 3.6.0
- dev: true
+ ansi-regex: 6.0.1
- /temp-dir/2.0.0:
- resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
- engines: {node: '>=8'}
- dev: true
-
- /tempfile/3.0.0:
- resolution: {integrity: sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw==}
- engines: {node: '>=8'}
- dependencies:
- temp-dir: 2.0.0
- uuid: 3.4.0
- dev: true
+ strip-final-newline@2.0.0: {}
- /term-size/1.2.0:
- resolution: {integrity: sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=}
- engines: {node: '>=4'}
- dependencies:
- execa: 0.7.0
- dev: true
+ strip-json-comments@2.0.1: {}
- /terser/5.15.1:
- resolution: {integrity: sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- '@jridgewell/source-map': 0.3.2
- acorn: 8.8.1
- commander: 2.20.3
- source-map-support: 0.5.21
- dev: true
+ strip-json-comments@3.1.1: {}
- /test-exclude/6.0.0:
- resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
- engines: {node: '>=8'}
+ supports-color@7.2.0:
dependencies:
- '@istanbuljs/schema': 0.1.3
- glob: 7.2.3
- minimatch: 3.1.2
- dev: true
-
- /text-extensions/1.9.0:
- resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==}
- engines: {node: '>=0.10'}
- dev: true
+ has-flag: 4.0.0
- /text-table/0.2.0:
- resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=}
- dev: true
+ supports-preserve-symlinks-flag@1.0.0: {}
- /through/2.3.8:
- resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
- dev: true
+ symbol-tree@3.2.4: {}
- /through2/2.0.5:
- resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
+ tar-fs@3.0.8:
dependencies:
- readable-stream: 2.3.7
- xtend: 4.0.2
- dev: true
+ pump: 3.0.0
+ tar-stream: 3.1.7
+ optionalDependencies:
+ bare-fs: 4.0.1
+ bare-path: 3.0.0
- /through2/4.0.2:
- resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
+ tar-stream@3.1.7:
dependencies:
- readable-stream: 3.6.0
- dev: true
+ b4a: 1.6.6
+ fast-fifo: 1.3.2
+ streamx: 2.18.0
- /timsort/0.3.0:
- resolution: {integrity: sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==}
- dev: true
+ temp-dir@3.0.0: {}
- /tmpl/1.0.5:
- resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
- dev: true
+ tempfile@5.0.0:
+ dependencies:
+ temp-dir: 3.0.0
- /to-fast-properties/2.0.0:
- resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=}
- engines: {node: '>=4'}
+ test-exclude@7.0.1:
+ dependencies:
+ '@istanbuljs/schema': 0.1.3
+ glob: 10.4.5
+ minimatch: 9.0.5
- /to-regex-range/5.0.1:
- resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
- engines: {node: '>=8.0'}
+ text-decoder@1.1.1:
dependencies:
- is-number: 7.0.0
- dev: true
+ b4a: 1.6.6
- /todomvc-app-css/2.4.1:
- resolution: {integrity: sha512-1mZYRG435VmqIw1WahBYhAJbyfH4HnRNI8EgF4ypK4R1RjwgBBvXd0N57ZwCa1lbHzYBraA6+dVyAg3GAPEACQ==}
- dev: true
+ tinybench@2.9.0: {}
- /token-stream/1.0.0:
- resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==}
- dev: true
+ tinyexec@0.3.2: {}
- /tough-cookie/4.1.2:
- resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==}
- engines: {node: '>=6'}
+ tinyglobby@0.2.13:
dependencies:
- psl: 1.9.0
- punycode: 2.1.1
- universalify: 0.2.0
- url-parse: 1.5.10
- dev: true
+ fdir: 6.4.4(picomatch@4.0.2)
+ picomatch: 4.0.2
- /tr46/0.0.3:
- resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
- dev: true
+ tinypool@1.0.2: {}
- /tr46/3.0.0:
- resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==}
- engines: {node: '>=12'}
- dependencies:
- punycode: 2.1.1
- dev: true
+ tinyrainbow@2.0.0: {}
- /trim-newlines/3.0.1:
- resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
- engines: {node: '>=8'}
- dev: true
+ tinyspy@3.0.2: {}
- /ts-jest/29.0.3_ok3qeoyoqhjjfsg3bzze2edrgy:
- resolution: {integrity: sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- hasBin: true
- peerDependencies:
- '@babel/core': '>=7.0.0-beta.0 <8'
- '@jest/types': ^29.0.0
- babel-jest: ^29.0.0
- esbuild: '*'
- jest: ^29.0.0
- typescript: '>=4.3'
- peerDependenciesMeta:
- '@babel/core':
- optional: true
- '@jest/types':
- optional: true
- babel-jest:
- optional: true
- esbuild:
- optional: true
+ tldts-core@6.1.86: {}
+
+ tldts@6.1.86:
dependencies:
- bs-logger: 0.2.6
- esbuild: 0.15.13
- fast-json-stable-stringify: 2.1.0
- jest: 29.3.1_@types+node@16.11.12
- jest-util: 29.3.1
- json5: 2.2.1
- lodash.memoize: 4.1.2
- make-error: 1.3.6
- semver: 7.3.8
- typescript: 4.8.2
- yargs-parser: 21.1.1
- dev: true
+ tldts-core: 6.1.86
- /tslib/1.14.1:
- resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
- dev: true
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
- /tslib/2.1.0:
- resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==}
- dev: true
+ todomvc-app-css@2.4.3: {}
- /tslib/2.4.0:
- resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
- dev: true
+ token-stream@1.0.0: {}
- /tsutils/3.21.0_typescript@4.8.2:
- resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
- engines: {node: '>= 6'}
- peerDependencies:
- typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
+ tough-cookie@5.1.2:
dependencies:
- tslib: 1.14.1
- typescript: 4.8.2
- dev: true
+ tldts: 6.1.86
- /type-check/0.3.2:
- resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==}
- engines: {node: '>= 0.8.0'}
+ tr46@5.1.1:
dependencies:
- prelude-ls: 1.1.2
- dev: true
+ punycode: 2.3.1
- /type-check/0.4.0:
- resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
- engines: {node: '>= 0.8.0'}
+ ts-api-utils@2.1.0(typescript@5.6.3):
dependencies:
- prelude-ls: 1.2.1
- dev: true
+ typescript: 5.6.3
- /type-detect/4.0.8:
- resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
- engines: {node: '>=4'}
- dev: true
+ tslib@2.8.1: {}
- /type-fest/0.18.1:
- resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==}
- engines: {node: '>=10'}
- dev: true
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
- /type-fest/0.20.2:
- resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
- engines: {node: '>=10'}
- dev: true
+ type-fest@2.19.0: {}
- /type-fest/0.21.3:
- resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
- engines: {node: '>=10'}
- dev: true
+ type-fest@4.24.0: {}
- /type-fest/0.6.0:
- resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
- engines: {node: '>=8'}
- dev: true
+ typed-query-selector@2.12.0: {}
- /type-fest/0.8.1:
- resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
- engines: {node: '>=8'}
- dev: true
+ typescript-eslint@8.32.1(eslint@9.27.0)(typescript@5.6.3):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0)(typescript@5.6.3))(eslint@9.27.0)(typescript@5.6.3)
+ '@typescript-eslint/parser': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.32.1(eslint@9.27.0)(typescript@5.6.3)
+ eslint: 9.27.0
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
- /typedarray-to-buffer/1.0.4:
- resolution: {integrity: sha512-vjMKrfSoUDN8/Vnqitw2FmstOfuJ73G6CrSEKnf11A6RmasVxHqfeBcnTb6RsL4pTMuV5Zsv9IiHRphMZyckUw==}
- dev: true
+ typescript@5.6.3: {}
- /typedarray/0.0.6:
- resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
- dev: true
+ uglify-js@3.19.1:
+ optional: true
- /typescript/4.5.5:
- resolution: {integrity: sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==}
- engines: {node: '>=4.2.0'}
- hasBin: true
- dev: true
+ undici-types@6.21.0: {}
- /typescript/4.8.2:
- resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==}
- engines: {node: '>=4.2.0'}
- hasBin: true
- dev: true
+ unicorn-magic@0.1.0: {}
- /uglify-js/3.17.4:
- resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
- engines: {node: '>=0.8.0'}
- hasBin: true
- requiresBuild: true
- dev: true
- optional: true
+ universalify@2.0.1: {}
- /unbox-primitive/1.0.1:
- resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==}
+ unplugin-utils@0.2.4:
dependencies:
- function-bind: 1.1.1
- has-bigints: 1.0.1
- has-symbols: 1.0.2
- which-boxed-primitive: 1.0.2
- dev: true
+ pathe: 2.0.3
+ picomatch: 4.0.2
- /unbzip2-stream/1.4.3:
- resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==}
+ unrs-resolver@1.7.2:
dependencies:
- buffer: 5.7.1
- through: 2.3.8
- dev: true
-
- /universalify/0.1.2:
- resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
- engines: {node: '>= 4.0.0'}
- dev: true
-
- /universalify/0.2.0:
- resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
- engines: {node: '>= 4.0.0'}
- dev: true
-
- /universalify/2.0.0:
- resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
- engines: {node: '>= 10.0.0'}
- dev: true
-
- /update-check/1.5.2:
- resolution: {integrity: sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==}
+ napi-postinstall: 0.2.3
+ optionalDependencies:
+ '@unrs/resolver-binding-darwin-arm64': 1.7.2
+ '@unrs/resolver-binding-darwin-x64': 1.7.2
+ '@unrs/resolver-binding-freebsd-x64': 1.7.2
+ '@unrs/resolver-binding-linux-arm-gnueabihf': 1.7.2
+ '@unrs/resolver-binding-linux-arm-musleabihf': 1.7.2
+ '@unrs/resolver-binding-linux-arm64-gnu': 1.7.2
+ '@unrs/resolver-binding-linux-arm64-musl': 1.7.2
+ '@unrs/resolver-binding-linux-ppc64-gnu': 1.7.2
+ '@unrs/resolver-binding-linux-riscv64-gnu': 1.7.2
+ '@unrs/resolver-binding-linux-riscv64-musl': 1.7.2
+ '@unrs/resolver-binding-linux-s390x-gnu': 1.7.2
+ '@unrs/resolver-binding-linux-x64-gnu': 1.7.2
+ '@unrs/resolver-binding-linux-x64-musl': 1.7.2
+ '@unrs/resolver-binding-wasm32-wasi': 1.7.2
+ '@unrs/resolver-binding-win32-arm64-msvc': 1.7.2
+ '@unrs/resolver-binding-win32-ia32-msvc': 1.7.2
+ '@unrs/resolver-binding-win32-x64-msvc': 1.7.2
+
+ update-check@1.5.4:
dependencies:
registry-auth-token: 3.3.2
registry-url: 3.1.0
- dev: true
- /uri-js/4.4.1:
- resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
- dependencies:
- punycode: 2.1.1
- dev: true
-
- /url-parse/1.5.10:
- resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
+ uri-js@4.4.1:
dependencies:
- querystringify: 2.2.0
- requires-port: 1.0.0
- dev: true
-
- /util-deprecate/1.0.2:
- resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
+ punycode: 2.3.1
- /uuid/3.4.0:
- resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
- deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
- hasBin: true
- dev: true
-
- /v8-compile-cache/2.3.0:
- resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
- dev: true
-
- /v8-to-istanbul/9.0.1:
- resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==}
- engines: {node: '>=10.12.0'}
- dependencies:
- '@jridgewell/trace-mapping': 0.3.17
- '@types/istanbul-lib-coverage': 2.0.3
- convert-source-map: 1.8.0
- dev: true
+ util-deprecate@1.0.2: {}
- /validate-npm-package-license/3.0.4:
- resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+ validate-npm-package-license@3.0.4:
dependencies:
- spdx-correct: 3.1.1
+ spdx-correct: 3.2.0
spdx-expression-parse: 3.0.1
- dev: true
- /validator/13.7.0:
- resolution: {integrity: sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==}
- engines: {node: '>= 0.10'}
- dev: true
+ vary@1.1.2: {}
- /vary/1.1.2:
- resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=}
- engines: {node: '>= 0.8'}
- dev: true
+ vite-node@3.1.4(@types/node@22.16.5)(sass@1.89.2):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.4.1
+ es-module-lexer: 1.7.0
+ pathe: 2.0.3
+ vite: 5.4.19(@types/node@22.16.5)(sass@1.89.2)
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - lightningcss
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
- /vite/3.0.9:
- resolution: {integrity: sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw==}
- engines: {node: ^14.18.0 || >=16.0.0}
- hasBin: true
- peerDependencies:
- less: '*'
- sass: '*'
- stylus: '*'
- terser: ^5.4.0
- peerDependenciesMeta:
- less:
- optional: true
- sass:
- optional: true
- stylus:
- optional: true
- terser:
- optional: true
+ vite@5.4.15(@types/node@22.16.5)(sass@1.89.2):
dependencies:
- esbuild: 0.14.54
- postcss: 8.4.16
- resolve: 1.22.1
- rollup: 2.77.3
+ esbuild: 0.21.5
+ postcss: 8.5.6
+ rollup: 4.45.1
optionalDependencies:
- fsevents: 2.3.2
- dev: true
+ '@types/node': 22.16.5
+ fsevents: 2.3.3
+ sass: 1.89.2
- /vite/3.0.9_terser@5.15.1:
- resolution: {integrity: sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw==}
- engines: {node: ^14.18.0 || >=16.0.0}
- hasBin: true
- peerDependencies:
- less: '*'
- sass: '*'
- stylus: '*'
- terser: ^5.4.0
- peerDependenciesMeta:
- less:
- optional: true
- sass:
- optional: true
- stylus:
- optional: true
- terser:
- optional: true
+ vite@5.4.19(@types/node@22.16.5)(sass@1.89.2):
dependencies:
- esbuild: 0.14.54
- postcss: 8.4.16
- resolve: 1.22.1
- rollup: 2.77.3
- terser: 5.15.1
+ esbuild: 0.21.5
+ postcss: 8.5.6
+ rollup: 4.45.1
optionalDependencies:
- fsevents: 2.3.2
- dev: true
-
- /vlq/0.2.3:
- resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==}
- dev: true
-
- /void-elements/3.1.0:
- resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@types/node': 22.16.5
+ fsevents: 2.3.3
+ sass: 1.89.2
+
+ vitest@3.1.4(@types/node@22.16.5)(jsdom@26.1.0)(sass@1.89.2):
+ dependencies:
+ '@vitest/expect': 3.1.4
+ '@vitest/mocker': 3.1.4(vite@5.4.19(@types/node@22.16.5)(sass@1.89.2))
+ '@vitest/pretty-format': 3.1.4
+ '@vitest/runner': 3.1.4
+ '@vitest/snapshot': 3.1.4
+ '@vitest/spy': 3.1.4
+ '@vitest/utils': 3.1.4
+ chai: 5.2.0
+ debug: 4.4.1
+ expect-type: 1.2.1
+ magic-string: 0.30.17
+ pathe: 2.0.3
+ std-env: 3.9.0
+ tinybench: 2.9.0
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.13
+ tinypool: 1.0.2
+ tinyrainbow: 2.0.0
+ vite: 5.4.19(@types/node@22.16.5)(sass@1.89.2)
+ vite-node: 3.1.4(@types/node@22.16.5)(sass@1.89.2)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 22.16.5
+ jsdom: 26.1.0
+ transitivePeerDependencies:
+ - less
+ - lightningcss
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
- /w3c-xmlserializer/3.0.0:
- resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==}
- engines: {node: '>=12'}
- dependencies:
- xml-name-validator: 4.0.0
- dev: true
+ void-elements@3.1.0: {}
- /walker/1.0.8:
- resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
+ w3c-xmlserializer@5.0.0:
dependencies:
- makeerror: 1.0.12
- dev: true
-
- /webidl-conversions/3.0.1:
- resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
- dev: true
+ xml-name-validator: 5.0.0
- /webidl-conversions/7.0.0:
- resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
- engines: {node: '>=12'}
- dev: true
+ webidl-conversions@7.0.0: {}
- /whatwg-encoding/2.0.0:
- resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
- engines: {node: '>=12'}
+ whatwg-encoding@3.1.1:
dependencies:
iconv-lite: 0.6.3
- dev: true
- /whatwg-mimetype/3.0.0:
- resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
- engines: {node: '>=12'}
- dev: true
+ whatwg-mimetype@4.0.0: {}
- /whatwg-url/11.0.0:
- resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==}
- engines: {node: '>=12'}
+ whatwg-url@14.2.0:
dependencies:
- tr46: 3.0.0
+ tr46: 5.1.1
webidl-conversions: 7.0.0
- dev: true
-
- /whatwg-url/5.0.0:
- resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
- dependencies:
- tr46: 0.0.3
- webidl-conversions: 3.0.1
- dev: true
- /which-boxed-primitive/1.0.2:
- resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ which@2.0.2:
dependencies:
- is-bigint: 1.0.4
- is-boolean-object: 1.1.2
- is-number-object: 1.0.6
- is-string: 1.0.7
- is-symbol: 1.0.4
- dev: true
+ isexe: 2.0.0
- /which/1.3.1:
- resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
- hasBin: true
+ which@5.0.0:
dependencies:
- isexe: 2.0.0
- dev: true
+ isexe: 3.1.1
- /which/2.0.2:
- resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
- engines: {node: '>= 8'}
- hasBin: true
+ why-is-node-running@2.3.0:
dependencies:
- isexe: 2.0.0
- dev: true
+ siginfo: 2.0.0
+ stackback: 0.0.2
- /widest-line/2.0.1:
- resolution: {integrity: sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==}
- engines: {node: '>=4'}
+ widest-line@4.0.1:
dependencies:
- string-width: 2.1.1
- dev: true
+ string-width: 5.1.2
- /with/7.0.2:
- resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==}
- engines: {node: '>= 10.0.0'}
+ with@7.0.2:
dependencies:
- '@babel/parser': 7.16.4
- '@babel/types': 7.16.0
- assert-never: 1.2.1
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.1
+ assert-never: 1.3.0
babel-walk: 3.0.0-canary-5
- dev: true
-
- /word-wrap/1.2.3:
- resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
- engines: {node: '>=0.10.0'}
- dev: true
- /wordwrap/1.0.0:
- resolution: {integrity: sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=}
- dev: true
+ word-wrap@1.2.5: {}
- /wrap-ansi/6.2.0:
- resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
- engines: {node: '>=8'}
- dependencies:
- ansi-styles: 4.3.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
- dev: true
+ wordwrap@1.0.0: {}
- /wrap-ansi/7.0.0:
- resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
- engines: {node: '>=10'}
+ wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
- dev: true
-
- /wrappy/1.0.2:
- resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
- dev: true
-
- /write-file-atomic/4.0.2:
- resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- imurmurhash: 0.1.4
- signal-exit: 3.0.7
- dev: true
-
- /ws/8.10.0:
- resolution: {integrity: sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==}
- engines: {node: '>=10.0.0'}
- peerDependencies:
- bufferutil: ^4.0.1
- utf-8-validate: ^5.0.2
- peerDependenciesMeta:
- bufferutil:
- optional: true
- utf-8-validate:
- optional: true
- dev: true
-
- /xml-name-validator/4.0.0:
- resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
- engines: {node: '>=12'}
- dev: true
- /xmlchars/2.2.0:
- resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
- dev: true
-
- /xtend/2.0.6:
- resolution: {integrity: sha512-fOZg4ECOlrMl+A6Msr7EIFcON1L26mb4NY5rurSkOex/TWhazOrg6eXD/B0XkuiYcYhQDWLXzQxLMVJ7LXwokg==}
- engines: {node: '>=0.4'}
+ wrap-ansi@8.1.0:
dependencies:
- is-object: 0.1.2
- object-keys: 0.2.0
- dev: true
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
- /xtend/2.1.2:
- resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==}
- engines: {node: '>=0.4'}
+ wrap-ansi@9.0.0:
dependencies:
- object-keys: 0.4.0
- dev: true
-
- /xtend/2.2.0:
- resolution: {integrity: sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw==}
- engines: {node: '>=0.4'}
- dev: true
-
- /xtend/3.0.0:
- resolution: {integrity: sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==}
- engines: {node: '>=0.4'}
- dev: true
+ ansi-styles: 6.2.1
+ string-width: 7.2.0
+ strip-ansi: 7.1.0
- /xtend/4.0.2:
- resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
- engines: {node: '>=0.4'}
- dev: true
+ wrappy@1.0.2: {}
- /y18n/5.0.8:
- resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
- engines: {node: '>=10'}
- dev: true
+ ws@8.18.1: {}
- /yallist/2.1.2:
- resolution: {integrity: sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=}
- dev: true
+ ws@8.18.2: {}
- /yallist/3.1.1:
- resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
- dev: true
+ xml-name-validator@5.0.0: {}
- /yallist/4.0.0:
- resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
- dev: true
-
- /yaml/1.10.2:
- resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
- engines: {node: '>= 6'}
- dev: true
+ xmlchars@2.2.0: {}
- /yargs-parser/20.2.9:
- resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
- engines: {node: '>=10'}
- dev: true
+ y18n@5.0.8: {}
- /yargs-parser/21.1.1:
- resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
- engines: {node: '>=12'}
- dev: true
+ yaml@2.8.0: {}
- /yargs/16.2.0:
- resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
- engines: {node: '>=10'}
- dependencies:
- cliui: 7.0.4
- escalade: 3.1.1
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- string-width: 4.2.3
- y18n: 5.0.8
- yargs-parser: 20.2.9
- dev: true
+ yargs-parser@21.1.1: {}
- /yargs/17.6.2:
- resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==}
- engines: {node: '>=12'}
+ yargs@17.7.2:
dependencies:
cliui: 8.0.1
- escalade: 3.1.1
+ escalade: 3.1.2
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
- dev: true
- /yauzl/2.10.0:
- resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
+ yauzl@2.10.0:
dependencies:
buffer-crc32: 0.2.13
fd-slicer: 1.1.0
- dev: true
- /yocto-queue/0.1.0:
- resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
- engines: {node: '>=10'}
- dev: true
+ yocto-queue@0.1.0: {}
- /z-schema/5.0.4:
- resolution: {integrity: sha512-gm/lx3hDzJNcLwseIeQVm1UcwhWIKpSB4NqH89pTBtFns4k/HDHudsICtvG05Bvw/Mv3jMyk700y5dadueLHdA==}
- engines: {node: '>=8.0.0'}
- hasBin: true
- dependencies:
- lodash.get: 4.4.2
- lodash.isequal: 4.5.0
- validator: 13.7.0
- optionalDependencies:
- commander: 2.20.3
- dev: true
+ zod@3.24.1: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 18ec407efca..3349459a15e 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,2 +1,27 @@
packages:
- 'packages/*'
+ - 'packages-private/*'
+
+catalog:
+ '@babel/parser': ^7.28.0
+ '@babel/types': ^7.28.1
+ 'estree-walker': ^2.0.2
+ 'magic-string': ^0.30.17
+ 'source-map-js': ^1.2.1
+ 'vite': ^5.4.15
+ '@vitejs/plugin-vue': ^5.2.4
+
+onlyBuiltDependencies:
+ - '@swc/core'
+ - 'esbuild'
+ - 'puppeteer'
+ - 'simple-git-hooks'
+ - 'unrs-resolver'
+
+peerDependencyRules:
+ allowedVersions:
+ 'typescript-eslint>eslint': '^9.0.0'
+ '@typescript-eslint/eslint-plugin>eslint': '^9.0.0'
+ '@typescript-eslint/parser>eslint': '^9.0.0'
+ '@typescript-eslint/type-utils>eslint': '^9.0.0'
+ '@typescript-eslint/utils>eslint': '^9.0.0'
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 00000000000..da7de554b64
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,396 @@
+// @ts-check
+import assert from 'node:assert/strict'
+import { createRequire } from 'node:module'
+import { fileURLToPath } from 'node:url'
+import fs from 'node:fs'
+import path from 'node:path'
+import replace from '@rollup/plugin-replace'
+import json from '@rollup/plugin-json'
+import pico from 'picocolors'
+import commonJS from '@rollup/plugin-commonjs'
+import polyfillNode from 'rollup-plugin-polyfill-node'
+import { nodeResolve } from '@rollup/plugin-node-resolve'
+import esbuild from 'rollup-plugin-esbuild'
+import alias from '@rollup/plugin-alias'
+import { entries } from './scripts/aliases.js'
+import { inlineEnums } from './scripts/inline-enums.js'
+import { minify as minifySwc } from '@swc/core'
+
+/**
+ * @template T
+ * @template {keyof T} K
+ * @typedef { Omit & Required> } MarkRequired
+ */
+/** @typedef {'cjs' | 'esm-bundler' | 'global' | 'global-runtime' | 'esm-browser' | 'esm-bundler-runtime' | 'esm-browser-runtime'} PackageFormat */
+/** @typedef {MarkRequired} OutputOptions */
+
+if (!process.env.TARGET) {
+ throw new Error('TARGET package must be specified via --environment flag.')
+}
+
+const require = createRequire(import.meta.url)
+const __dirname = fileURLToPath(new URL('.', import.meta.url))
+
+const masterVersion = require('./package.json').version
+const consolidatePkg = require('@vue/consolidate/package.json')
+
+const privatePackages = fs.readdirSync('packages-private')
+const pkgBase = privatePackages.includes(process.env.TARGET)
+ ? `packages-private`
+ : `packages`
+const packagesDir = path.resolve(__dirname, pkgBase)
+const packageDir = path.resolve(packagesDir, process.env.TARGET)
+
+const resolve = (/** @type {string} */ p) => path.resolve(packageDir, p)
+const pkg = require(resolve(`package.json`))
+const packageOptions = pkg.buildOptions || {}
+const name = packageOptions.filename || path.basename(packageDir)
+
+const banner = `/**
+* ${pkg.name} v${masterVersion}
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/`
+
+const [enumPlugin, enumDefines] = inlineEnums()
+
+/** @type {Record} */
+const outputConfigs = {
+ 'esm-bundler': {
+ file: resolve(`dist/${name}.esm-bundler.js`),
+ format: 'es',
+ },
+ 'esm-browser': {
+ file: resolve(`dist/${name}.esm-browser.js`),
+ format: 'es',
+ },
+ cjs: {
+ file: resolve(`dist/${name}.cjs.js`),
+ format: 'cjs',
+ },
+ global: {
+ file: resolve(`dist/${name}.global.js`),
+ format: 'iife',
+ },
+ // runtime-only builds, for main "vue" package only
+ 'esm-bundler-runtime': {
+ file: resolve(`dist/${name}.runtime.esm-bundler.js`),
+ format: 'es',
+ },
+ 'esm-browser-runtime': {
+ file: resolve(`dist/${name}.runtime.esm-browser.js`),
+ format: 'es',
+ },
+ 'global-runtime': {
+ file: resolve(`dist/${name}.runtime.global.js`),
+ format: 'iife',
+ },
+}
+
+/** @type {ReadonlyArray} */
+const defaultFormats = ['esm-bundler', 'cjs']
+/** @type {ReadonlyArray} */
+const inlineFormats = /** @type {any} */ (
+ process.env.FORMATS && process.env.FORMATS.split(',')
+)
+/** @type {ReadonlyArray} */
+const packageFormats = inlineFormats || packageOptions.formats || defaultFormats
+const packageConfigs = process.env.PROD_ONLY
+ ? []
+ : packageFormats.map(format => createConfig(format, outputConfigs[format]))
+
+if (process.env.NODE_ENV === 'production') {
+ packageFormats.forEach(format => {
+ if (packageOptions.prod === false) {
+ return
+ }
+ if (format === 'cjs') {
+ packageConfigs.push(createProductionConfig(format))
+ }
+ if (/^(global|esm-browser)(-runtime)?/.test(format)) {
+ packageConfigs.push(createMinifiedConfig(format))
+ }
+ })
+}
+
+export default packageConfigs
+
+/**
+ *
+ * @param {PackageFormat} format
+ * @param {OutputOptions} output
+ * @param {ReadonlyArray} plugins
+ * @returns {import('rollup').RollupOptions}
+ */
+function createConfig(format, output, plugins = []) {
+ if (!output) {
+ console.log(pico.yellow(`invalid format: "${format}"`))
+ process.exit(1)
+ }
+
+ const isProductionBuild =
+ process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file)
+ const isBundlerESMBuild = /esm-bundler/.test(format)
+ const isBrowserESMBuild = /esm-browser/.test(format)
+ const isServerRenderer = name === 'server-renderer'
+ const isCJSBuild = format === 'cjs'
+ const isGlobalBuild = /global/.test(format)
+ const isCompatPackage =
+ pkg.name === '@vue/compat' || pkg.name === '@vue/compat-canary'
+ const isCompatBuild = !!packageOptions.compat
+ const isBrowserBuild =
+ (isGlobalBuild || isBrowserESMBuild || isBundlerESMBuild) &&
+ !packageOptions.enableNonBrowserBranches
+
+ output.banner = banner
+
+ output.exports = isCompatPackage ? 'auto' : 'named'
+ if (isCJSBuild) {
+ output.esModule = true
+ }
+ output.sourcemap = !!process.env.SOURCE_MAP
+ output.externalLiveBindings = false
+ // https://github.com/rollup/rollup/pull/5380
+ output.reexportProtoFromExternal = false
+
+ if (isGlobalBuild) {
+ output.name = packageOptions.name
+ }
+
+ let entryFile = /runtime$/.test(format) ? `src/runtime.ts` : `src/index.ts`
+
+ // the compat build needs both default AND named exports. This will cause
+ // Rollup to complain for non-ESM targets, so we use separate entries for
+ // esm vs. non-esm builds.
+ if (isCompatPackage && (isBrowserESMBuild || isBundlerESMBuild)) {
+ entryFile = /runtime$/.test(format)
+ ? `src/esm-runtime.ts`
+ : `src/esm-index.ts`
+ }
+
+ function resolveDefine() {
+ /** @type {Record} */
+ const replacements = {
+ __COMMIT__: `"${process.env.COMMIT}"`,
+ __VERSION__: `"${masterVersion}"`,
+ // this is only used during Vue's internal tests
+ __TEST__: `false`,
+ // If the build is expected to run directly in the browser (global / esm builds)
+ __BROWSER__: String(isBrowserBuild),
+ __GLOBAL__: String(isGlobalBuild),
+ __ESM_BUNDLER__: String(isBundlerESMBuild),
+ __ESM_BROWSER__: String(isBrowserESMBuild),
+ // is targeting Node (SSR)?
+ __CJS__: String(isCJSBuild),
+ // need SSR-specific branches?
+ __SSR__: String(!isGlobalBuild),
+
+ // 2.x compat build
+ __COMPAT__: String(isCompatBuild),
+
+ // feature flags
+ __FEATURE_SUSPENSE__: `true`,
+ __FEATURE_OPTIONS_API__: isBundlerESMBuild
+ ? `__VUE_OPTIONS_API__`
+ : `true`,
+ __FEATURE_PROD_DEVTOOLS__: isBundlerESMBuild
+ ? `__VUE_PROD_DEVTOOLS__`
+ : `false`,
+ __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: isBundlerESMBuild
+ ? `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__`
+ : `false`,
+ }
+
+ if (!isBundlerESMBuild) {
+ // hard coded dev/prod builds
+ replacements.__DEV__ = String(!isProductionBuild)
+ }
+
+ // allow inline overrides like
+ //__RUNTIME_COMPILE__=true pnpm build runtime-core
+ Object.keys(replacements).forEach(key => {
+ if (key in process.env) {
+ const value = process.env[key]
+ assert(typeof value === 'string')
+ replacements[key] = value
+ }
+ })
+ return replacements
+ }
+
+ // esbuild define is a bit strict and only allows literal json or identifiers
+ // so we still need replace plugin in some cases
+ function resolveReplace() {
+ const replacements = { ...enumDefines }
+
+ if (isProductionBuild && isBrowserBuild) {
+ Object.assign(replacements, {
+ 'context.onError(': `/*@__PURE__*/ context.onError(`,
+ 'emitError(': `/*@__PURE__*/ emitError(`,
+ 'createCompilerError(': `/*@__PURE__*/ createCompilerError(`,
+ 'createDOMCompilerError(': `/*@__PURE__*/ createDOMCompilerError(`,
+ })
+ }
+
+ if (isBundlerESMBuild) {
+ Object.assign(replacements, {
+ // preserve to be handled by bundlers
+ __DEV__: `!!(process.env.NODE_ENV !== 'production')`,
+ })
+ }
+
+ // for compiler-sfc browser build inlined deps
+ if (isBrowserESMBuild) {
+ Object.assign(replacements, {
+ 'process.env': '({})',
+ 'process.platform': '""',
+ 'process.stdout': 'null',
+ })
+ }
+
+ if (Object.keys(replacements).length) {
+ return [replace({ values: replacements, preventAssignment: true })]
+ } else {
+ return []
+ }
+ }
+
+ function resolveExternal() {
+ const treeShakenDeps = [
+ 'source-map-js',
+ '@babel/parser',
+ 'estree-walker',
+ 'entities/lib/decode.js',
+ ]
+
+ if (isGlobalBuild || isBrowserESMBuild || isCompatPackage) {
+ if (!packageOptions.enableNonBrowserBranches) {
+ // normal browser builds - non-browser only imports are tree-shaken,
+ // they are only listed here to suppress warnings.
+ return treeShakenDeps
+ }
+ } else {
+ // Node / esm-bundler builds.
+ // externalize all direct deps unless it's the compat build.
+ return [
+ ...Object.keys(pkg.dependencies || {}),
+ ...Object.keys(pkg.peerDependencies || {}),
+ // for @vue/compiler-sfc / server-renderer
+ ...['path', 'url', 'stream'],
+ // somehow these throw warnings for runtime-* package builds
+ ...treeShakenDeps,
+ ]
+ }
+ }
+
+ function resolveNodePlugins() {
+ // we are bundling forked consolidate.js in compiler-sfc which dynamically
+ // requires a ton of template engines which should be ignored.
+ /** @type {ReadonlyArray} */
+ let cjsIgnores = []
+ if (
+ pkg.name === '@vue/compiler-sfc' ||
+ pkg.name === '@vue/compiler-sfc-canary'
+ ) {
+ cjsIgnores = [
+ ...Object.keys(consolidatePkg.devDependencies),
+ 'vm',
+ 'crypto',
+ 'react-dom/server',
+ 'teacup/lib/express',
+ 'arc-templates/dist/es5',
+ 'then-pug',
+ 'then-jade',
+ ]
+ }
+
+ const nodePlugins =
+ (format === 'cjs' && Object.keys(pkg.devDependencies || {}).length) ||
+ packageOptions.enableNonBrowserBranches
+ ? [
+ commonJS({
+ sourceMap: false,
+ ignore: cjsIgnores,
+ }),
+ ...(format === 'cjs' ? [] : [polyfillNode()]),
+ nodeResolve(),
+ ]
+ : []
+
+ return nodePlugins
+ }
+
+ return {
+ input: resolve(entryFile),
+ // Global and Browser ESM builds inlines everything so that they can be
+ // used alone.
+ external: resolveExternal(),
+ plugins: [
+ json({
+ namedExports: false,
+ }),
+ alias({
+ entries,
+ }),
+ enumPlugin,
+ ...resolveReplace(),
+ esbuild({
+ tsconfig: path.resolve(__dirname, 'tsconfig.json'),
+ sourceMap: output.sourcemap,
+ minify: false,
+ target: isServerRenderer || isCJSBuild ? 'es2019' : 'es2016',
+ define: resolveDefine(),
+ }),
+ ...resolveNodePlugins(),
+ ...plugins,
+ ],
+ output,
+ onwarn: (msg, warn) => {
+ if (msg.code !== 'CIRCULAR_DEPENDENCY') {
+ warn(msg)
+ }
+ },
+ treeshake: {
+ moduleSideEffects: false,
+ },
+ }
+}
+
+function createProductionConfig(/** @type {PackageFormat} */ format) {
+ return createConfig(format, {
+ file: resolve(`dist/${name}.${format}.prod.js`),
+ format: outputConfigs[format].format,
+ })
+}
+
+function createMinifiedConfig(/** @type {PackageFormat} */ format) {
+ return createConfig(
+ format,
+ {
+ file: outputConfigs[format].file.replace(/\.js$/, '.prod.js'),
+ format: outputConfigs[format].format,
+ },
+ [
+ {
+ name: 'swc-minify',
+
+ async renderChunk(contents, _, { format }) {
+ const { code } = await minifySwc(contents, {
+ module: format === 'es',
+ format: {
+ comments: false,
+ },
+ compress: {
+ ecma: 2016,
+ pure_getters: true,
+ },
+ safari10: true,
+ mangle: true,
+ })
+
+ return { code: banner + code, map: null }
+ },
+ },
+ ],
+ )
+}
diff --git a/rollup.config.mjs b/rollup.config.mjs
deleted file mode 100644
index 36f69fab07f..00000000000
--- a/rollup.config.mjs
+++ /dev/null
@@ -1,331 +0,0 @@
-// @ts-check
-import { createRequire } from 'module'
-import { fileURLToPath } from 'url'
-import path from 'path'
-import ts from 'rollup-plugin-typescript2'
-import replace from '@rollup/plugin-replace'
-import json from '@rollup/plugin-json'
-import chalk from 'chalk'
-import commonJS from '@rollup/plugin-commonjs'
-import polyfillNode from 'rollup-plugin-polyfill-node'
-import { nodeResolve } from '@rollup/plugin-node-resolve'
-import terser from '@rollup/plugin-terser'
-
-if (!process.env.TARGET) {
- throw new Error('TARGET package must be specified via --environment flag.')
-}
-
-const require = createRequire(import.meta.url)
-const __dirname = fileURLToPath(new URL('.', import.meta.url))
-
-const masterVersion = require('./package.json').version
-const consolidatePkg = require('@vue/consolidate/package.json')
-
-const packagesDir = path.resolve(__dirname, 'packages')
-const packageDir = path.resolve(packagesDir, process.env.TARGET)
-
-const resolve = p => path.resolve(packageDir, p)
-const pkg = require(resolve(`package.json`))
-const packageOptions = pkg.buildOptions || {}
-const name = packageOptions.filename || path.basename(packageDir)
-
-// ensure TS checks only once for each build
-let hasTSChecked = false
-
-const outputConfigs = {
- 'esm-bundler': {
- file: resolve(`dist/${name}.esm-bundler.js`),
- format: `es`
- },
- 'esm-browser': {
- file: resolve(`dist/${name}.esm-browser.js`),
- format: `es`
- },
- cjs: {
- file: resolve(`dist/${name}.cjs.js`),
- format: `cjs`
- },
- global: {
- file: resolve(`dist/${name}.global.js`),
- format: `iife`
- },
- // runtime-only builds, for main "vue" package only
- 'esm-bundler-runtime': {
- file: resolve(`dist/${name}.runtime.esm-bundler.js`),
- format: `es`
- },
- 'esm-browser-runtime': {
- file: resolve(`dist/${name}.runtime.esm-browser.js`),
- format: 'es'
- },
- 'global-runtime': {
- file: resolve(`dist/${name}.runtime.global.js`),
- format: 'iife'
- }
-}
-
-const defaultFormats = ['esm-bundler', 'cjs']
-const inlineFormats = process.env.FORMATS && process.env.FORMATS.split(',')
-const packageFormats = inlineFormats || packageOptions.formats || defaultFormats
-const packageConfigs = process.env.PROD_ONLY
- ? []
- : packageFormats.map(format => createConfig(format, outputConfigs[format]))
-
-if (process.env.NODE_ENV === 'production') {
- packageFormats.forEach(format => {
- if (packageOptions.prod === false) {
- return
- }
- if (format === 'cjs') {
- packageConfigs.push(createProductionConfig(format))
- }
- if (/^(global|esm-browser)(-runtime)?/.test(format)) {
- packageConfigs.push(createMinifiedConfig(format))
- }
- })
-}
-
-export default packageConfigs
-
-function createConfig(format, output, plugins = []) {
- if (!output) {
- console.log(chalk.yellow(`invalid format: "${format}"`))
- process.exit(1)
- }
-
- const isProductionBuild =
- process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file)
- const isBundlerESMBuild = /esm-bundler/.test(format)
- const isBrowserESMBuild = /esm-browser/.test(format)
- const isServerRenderer = name === 'server-renderer'
- const isNodeBuild = format === 'cjs'
- const isGlobalBuild = /global/.test(format)
- const isCompatPackage = pkg.name === '@vue/compat'
- const isCompatBuild = !!packageOptions.compat
-
- output.exports = isCompatPackage ? 'auto' : 'named'
- output.sourcemap = !!process.env.SOURCE_MAP
- output.externalLiveBindings = false
-
- if (isGlobalBuild) {
- output.name = packageOptions.name
- }
-
- const shouldEmitDeclarations =
- pkg.types && process.env.TYPES != null && !hasTSChecked
-
- const tsPlugin = ts({
- check: process.env.NODE_ENV === 'production' && !hasTSChecked,
- tsconfig: path.resolve(__dirname, 'tsconfig.json'),
- cacheRoot: path.resolve(__dirname, 'node_modules/.rts2_cache'),
- tsconfigOverride: {
- compilerOptions: {
- target: isServerRenderer || isNodeBuild ? 'es2019' : 'es2015',
- sourceMap: output.sourcemap,
- declaration: shouldEmitDeclarations,
- declarationMap: shouldEmitDeclarations
- },
- exclude: ['**/__tests__', 'test-dts']
- }
- })
- // we only need to check TS and generate declarations once for each build.
- // it also seems to run into weird issues when checking multiple times
- // during a single build.
- hasTSChecked = true
-
- let entryFile = /runtime$/.test(format) ? `src/runtime.ts` : `src/index.ts`
-
- // the compat build needs both default AND named exports. This will cause
- // Rollup to complain for non-ESM targets, so we use separate entries for
- // esm vs. non-esm builds.
- if (isCompatPackage && (isBrowserESMBuild || isBundlerESMBuild)) {
- entryFile = /runtime$/.test(format)
- ? `src/esm-runtime.ts`
- : `src/esm-index.ts`
- }
-
- let external = []
- const treeShakenDeps = ['source-map', '@babel/parser', 'estree-walker']
-
- if (isGlobalBuild || isBrowserESMBuild || isCompatPackage) {
- if (!packageOptions.enableNonBrowserBranches) {
- // normal browser builds - non-browser only imports are tree-shaken,
- // they are only listed here to suppress warnings.
- external = treeShakenDeps
- }
- } else {
- // Node / esm-bundler builds.
- // externalize all direct deps unless it's the compat build.
- external = [
- ...Object.keys(pkg.dependencies || {}),
- ...Object.keys(pkg.peerDependencies || {}),
- // for @vue/compiler-sfc / server-renderer
- ...['path', 'url', 'stream'],
- // somehow these throw warnings for runtime-* package builds
- ...treeShakenDeps
- ]
- }
-
- // we are bundling forked consolidate.js in compiler-sfc which dynamically
- // requires a ton of template engines which should be ignored.
- let cjsIgnores = []
- if (pkg.name === '@vue/compiler-sfc') {
- cjsIgnores = [
- ...Object.keys(consolidatePkg.devDependencies),
- 'vm',
- 'crypto',
- 'react-dom/server',
- 'teacup/lib/express',
- 'arc-templates/dist/es5',
- 'then-pug',
- 'then-jade'
- ]
- }
-
- const nodePlugins =
- (format === 'cjs' && Object.keys(pkg.devDependencies || {}).length) ||
- packageOptions.enableNonBrowserBranches
- ? [
- commonJS({
- sourceMap: false,
- ignore: cjsIgnores
- }),
- ...(format === 'cjs' ? [] : [polyfillNode()]),
- nodeResolve()
- ]
- : []
-
- return {
- input: resolve(entryFile),
- // Global and Browser ESM builds inlines everything so that they can be
- // used alone.
- external,
- plugins: [
- json({
- namedExports: false
- }),
- tsPlugin,
- createReplacePlugin(
- isProductionBuild,
- isBundlerESMBuild,
- isBrowserESMBuild,
- // isBrowserBuild?
- (isGlobalBuild || isBrowserESMBuild || isBundlerESMBuild) &&
- !packageOptions.enableNonBrowserBranches,
- isGlobalBuild,
- isNodeBuild,
- isCompatBuild,
- isServerRenderer
- ),
- ...nodePlugins,
- ...plugins
- ],
- output,
- onwarn: (msg, warn) => {
- if (!/Circular/.test(msg)) {
- warn(msg)
- }
- },
- treeshake: {
- moduleSideEffects: false
- }
- }
-}
-
-function createReplacePlugin(
- isProduction,
- isBundlerESMBuild,
- isBrowserESMBuild,
- isBrowserBuild,
- isGlobalBuild,
- isNodeBuild,
- isCompatBuild,
- isServerRenderer
-) {
- const replacements = {
- __COMMIT__: `"${process.env.COMMIT}"`,
- __VERSION__: `"${masterVersion}"`,
- __DEV__: isBundlerESMBuild
- ? // preserve to be handled by bundlers
- `(process.env.NODE_ENV !== 'production')`
- : // hard coded dev/prod builds
- !isProduction,
- // this is only used during Vue's internal tests
- __TEST__: false,
- // If the build is expected to run directly in the browser (global / esm builds)
- __BROWSER__: isBrowserBuild,
- __GLOBAL__: isGlobalBuild,
- __ESM_BUNDLER__: isBundlerESMBuild,
- __ESM_BROWSER__: isBrowserESMBuild,
- // is targeting Node (SSR)?
- __NODE_JS__: isNodeBuild,
- // need SSR-specific branches?
- __SSR__: isNodeBuild || isBundlerESMBuild || isServerRenderer,
-
- // for compiler-sfc browser build inlined deps
- ...(isBrowserESMBuild
- ? {
- 'process.env': '({})',
- 'process.platform': '""',
- 'process.stdout': 'null'
- }
- : {}),
-
- // 2.x compat build
- __COMPAT__: isCompatBuild,
-
- // feature flags
- __FEATURE_SUSPENSE__: true,
- __FEATURE_OPTIONS_API__: isBundlerESMBuild ? `__VUE_OPTIONS_API__` : true,
- __FEATURE_PROD_DEVTOOLS__: isBundlerESMBuild
- ? `__VUE_PROD_DEVTOOLS__`
- : false,
- ...(isProduction && isBrowserBuild
- ? {
- 'context.onError(': `/*#__PURE__*/ context.onError(`,
- 'emitError(': `/*#__PURE__*/ emitError(`,
- 'createCompilerError(': `/*#__PURE__*/ createCompilerError(`,
- 'createDOMCompilerError(': `/*#__PURE__*/ createDOMCompilerError(`
- }
- : {})
- }
- // allow inline overrides like
- //__RUNTIME_COMPILE__=true yarn build runtime-core
- Object.keys(replacements).forEach(key => {
- if (key in process.env) {
- replacements[key] = process.env[key]
- }
- })
- return replace({
- // @ts-ignore
- values: replacements,
- preventAssignment: true
- })
-}
-
-function createProductionConfig(format) {
- return createConfig(format, {
- file: resolve(`dist/${name}.${format}.prod.js`),
- format: outputConfigs[format].format
- })
-}
-
-function createMinifiedConfig(format) {
- return createConfig(
- format,
- {
- file: outputConfigs[format].file.replace(/\.js$/, '.prod.js'),
- format: outputConfigs[format].format
- },
- [
- terser({
- module: /^esm/.test(format),
- compress: {
- ecma: 2015,
- pure_getters: true
- },
- safari10: true
- })
- ]
- )
-}
diff --git a/rollup.dts.config.js b/rollup.dts.config.js
new file mode 100644
index 00000000000..d9af98f1306
--- /dev/null
+++ b/rollup.dts.config.js
@@ -0,0 +1,204 @@
+// @ts-check
+import assert from 'node:assert/strict'
+import { parse } from '@babel/parser'
+import { existsSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'
+import MagicString from 'magic-string'
+import dts from 'rollup-plugin-dts'
+
+if (!existsSync('temp/packages')) {
+ console.warn(
+ 'no temp dts files found. run `tsc -p tsconfig.build-browser.json && tsc -p tsconfig.build-node.json` first.',
+ )
+ process.exit(1)
+}
+
+const packages = readdirSync('temp/packages')
+const targets = process.env.TARGETS ? process.env.TARGETS.split(',') : null
+const targetPackages = targets
+ ? packages.filter(pkg => targets.includes(pkg))
+ : packages
+
+export default targetPackages.map(
+ /** @returns {import('rollup').RollupOptions} */
+ pkg => {
+ return {
+ input: `./temp/packages/${pkg}/src/index.d.ts`,
+ output: {
+ file: `packages/${pkg}/dist/${pkg}.d.ts`,
+ format: 'es',
+ },
+ plugins: [dts(), patchTypes(pkg), ...(pkg === 'vue' ? [copyMts()] : [])],
+ onwarn(warning, warn) {
+ // during dts rollup, everything is externalized by default
+ if (
+ warning.code === 'UNRESOLVED_IMPORT' &&
+ !warning.exporter?.startsWith('.')
+ ) {
+ return
+ }
+ warn(warning)
+ },
+ }
+ },
+)
+
+/**
+ * Patch the dts generated by rollup-plugin-dts
+ * 1. Convert all types to inline exports
+ * and remove them from the big export {} declaration
+ * otherwise it gets weird in vitepress `defineComponent` call with
+ * "the inferred type cannot be named without a reference"
+ * 2. Append custom augmentations (jsx, macros)
+ *
+ * @param {string} pkg
+ * @returns {import('rollup').Plugin}
+ */
+function patchTypes(pkg) {
+ return {
+ name: 'patch-types',
+ renderChunk(code, chunk) {
+ const s = new MagicString(code)
+ const ast = parse(code, {
+ plugins: ['typescript'],
+ sourceType: 'module',
+ })
+
+ /**
+ * @param {import('@babel/types').VariableDeclarator | import('@babel/types').TSTypeAliasDeclaration | import('@babel/types').TSInterfaceDeclaration | import('@babel/types').TSDeclareFunction | import('@babel/types').TSInterfaceDeclaration | import('@babel/types').TSEnumDeclaration | import('@babel/types').ClassDeclaration} node
+ * @param {import('@babel/types').VariableDeclaration} [parentDecl]
+ */
+ function processDeclaration(node, parentDecl) {
+ if (!node.id) {
+ return
+ }
+ assert(node.id.type === 'Identifier')
+ const name = node.id.name
+ if (name.startsWith('_')) {
+ return
+ }
+ shouldRemoveExport.add(name)
+ if (isExported.has(name)) {
+ const start = (parentDecl || node).start
+ assert(typeof start === 'number')
+ s.prependLeft(start, `export `)
+ }
+ }
+
+ const isExported = new Set()
+ const shouldRemoveExport = new Set()
+
+ // pass 0: check all exported types
+ for (const node of ast.program.body) {
+ if (node.type === 'ExportNamedDeclaration' && !node.source) {
+ for (let i = 0; i < node.specifiers.length; i++) {
+ const spec = node.specifiers[i]
+ if (spec.type === 'ExportSpecifier') {
+ isExported.add(spec.local.name)
+ }
+ }
+ }
+ }
+
+ // pass 1: add exports
+ for (const node of ast.program.body) {
+ if (node.type === 'VariableDeclaration') {
+ processDeclaration(node.declarations[0], node)
+ if (node.declarations.length > 1) {
+ assert(typeof node.start === 'number')
+ assert(typeof node.end === 'number')
+ throw new Error(
+ `unhandled declare const with more than one declarators:\n${code.slice(
+ node.start,
+ node.end,
+ )}`,
+ )
+ }
+ } else if (
+ node.type === 'TSTypeAliasDeclaration' ||
+ node.type === 'TSInterfaceDeclaration' ||
+ node.type === 'TSDeclareFunction' ||
+ node.type === 'TSEnumDeclaration' ||
+ node.type === 'ClassDeclaration'
+ ) {
+ processDeclaration(node)
+ }
+ }
+
+ // pass 2: remove exports
+ for (const node of ast.program.body) {
+ if (node.type === 'ExportNamedDeclaration' && !node.source) {
+ let removed = 0
+ for (let i = 0; i < node.specifiers.length; i++) {
+ const spec = node.specifiers[i]
+ if (
+ spec.type === 'ExportSpecifier' &&
+ shouldRemoveExport.has(spec.local.name)
+ ) {
+ assert(spec.exported.type === 'Identifier')
+ const exported = spec.exported.name
+ if (exported !== spec.local.name) {
+ // this only happens if we have something like
+ // type Foo
+ // export { Foo as Bar }
+ continue
+ }
+ const next = node.specifiers[i + 1]
+ if (next) {
+ assert(typeof spec.start === 'number')
+ assert(typeof next.start === 'number')
+ s.remove(spec.start, next.start)
+ } else {
+ // last one
+ const prev = node.specifiers[i - 1]
+ assert(typeof spec.start === 'number')
+ assert(typeof spec.end === 'number')
+ s.remove(
+ prev
+ ? (assert(typeof prev.end === 'number'), prev.end)
+ : spec.start,
+ spec.end,
+ )
+ }
+ removed++
+ }
+ }
+ if (removed === node.specifiers.length) {
+ assert(typeof node.start === 'number')
+ assert(typeof node.end === 'number')
+ s.remove(node.start, node.end)
+ }
+ }
+ }
+ code = s.toString()
+
+ // append pkg specific types
+ const additionalTypeDir = `packages/${pkg}/types`
+ if (existsSync(additionalTypeDir)) {
+ code +=
+ '\n' +
+ readdirSync(additionalTypeDir)
+ .map(file => readFileSync(`${additionalTypeDir}/${file}`, 'utf-8'))
+ .join('\n')
+ }
+ return code
+ },
+ }
+}
+
+/**
+ * According to https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#packagejson-exports-imports-and-self-referencing
+ * the only way to correct provide types for both Node ESM and CJS is to have
+ * two separate declaration files, so we need to copy vue.d.ts to vue.d.mts
+ * upon build.
+ *
+ * @returns {import('rollup').Plugin}
+ */
+function copyMts() {
+ return {
+ name: 'copy-vue-mts',
+ writeBundle(_, bundle) {
+ assert('code' in bundle['vue.d.ts'])
+ writeFileSync('packages/vue/dist/vue.d.mts', bundle['vue.d.ts'].code)
+ },
+ }
+}
diff --git a/scripts/aliases.js b/scripts/aliases.js
new file mode 100644
index 00000000000..d50498a80aa
--- /dev/null
+++ b/scripts/aliases.js
@@ -0,0 +1,37 @@
+// @ts-check
+// these aliases are shared between vitest and rollup
+import { readdirSync, statSync } from 'node:fs'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const resolveEntryForPkg = (/** @type {string} */ p) =>
+ path.resolve(
+ fileURLToPath(import.meta.url),
+ `../../packages/${p}/src/index.ts`,
+ )
+
+const dirs = readdirSync(new URL('../packages', import.meta.url))
+
+/** @type {Record} */
+const entries = {
+ vue: resolveEntryForPkg('vue'),
+ 'vue/compiler-sfc': resolveEntryForPkg('compiler-sfc'),
+ 'vue/server-renderer': resolveEntryForPkg('server-renderer'),
+ '@vue/compat': resolveEntryForPkg('vue-compat'),
+}
+
+const nonSrcPackages = ['sfc-playground', 'template-explorer', 'dts-test']
+
+for (const dir of dirs) {
+ const key = `@vue/${dir}`
+ if (
+ dir !== 'vue' &&
+ !nonSrcPackages.includes(dir) &&
+ !(key in entries) &&
+ statSync(new URL(`../packages/${dir}`, import.meta.url)).isDirectory()
+ ) {
+ entries[key] = resolveEntryForPkg(dir)
+ }
+}
+
+export { entries }
diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js
deleted file mode 100644
index f944723beba..00000000000
--- a/scripts/bootstrap.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// create package.json, README, etc. for packages that don't have them yet
-
-const args = require('minimist')(process.argv.slice(2))
-const fs = require('fs')
-const path = require('path')
-const version = require('../package.json').version
-
-const packagesDir = path.resolve(__dirname, '../packages')
-const files = fs.readdirSync(packagesDir)
-
-files.forEach(shortName => {
- if (!fs.statSync(path.join(packagesDir, shortName)).isDirectory()) {
- return
- }
-
- const name = shortName === `vue` ? shortName : `@vue/${shortName}`
- const pkgPath = path.join(packagesDir, shortName, `package.json`)
- const pkgExists = fs.existsSync(pkgPath)
- if (pkgExists) {
- const pkg = require(pkgPath)
- if (pkg.private) {
- return
- }
- }
-
- if (args.force || !pkgExists) {
- const json = {
- name,
- version,
- description: name,
- main: 'index.js',
- module: `dist/${shortName}.esm-bundler.js`,
- files: [`index.js`, `dist`],
- types: `dist/${shortName}.d.ts`,
- repository: {
- type: 'git',
- url: 'git+https://github.com/vuejs/vue.git'
- },
- keywords: ['vue'],
- author: 'Evan You',
- license: 'MIT',
- bugs: {
- url: 'https://github.com/vuejs/vue/issues'
- },
- homepage: `https://github.com/vuejs/vue/tree/dev/packages/${shortName}#readme`
- }
- fs.writeFileSync(pkgPath, JSON.stringify(json, null, 2))
- }
-
- const readmePath = path.join(packagesDir, shortName, `README.md`)
- if (args.force || !fs.existsSync(readmePath)) {
- fs.writeFileSync(readmePath, `# ${name}`)
- }
-
- const apiExtractorConfigPath = path.join(
- packagesDir,
- shortName,
- `api-extractor.json`
- )
- if (args.force || !fs.existsSync(apiExtractorConfigPath)) {
- fs.writeFileSync(
- apiExtractorConfigPath,
- `
-{
- "extends": "../../api-extractor.json",
- "mainEntryPointFilePath": "./dist/packages//src/index.d.ts",
- "dtsRollup": {
- "publicTrimmedFilePath": "./dist/.d.ts"
- }
-}
-`.trim()
- )
- }
-
- const srcDir = path.join(packagesDir, shortName, `src`)
- const indexPath = path.join(packagesDir, shortName, `src/index.ts`)
- if (args.force || !fs.existsSync(indexPath)) {
- if (!fs.existsSync(srcDir)) {
- fs.mkdirSync(srcDir)
- }
- fs.writeFileSync(indexPath, ``)
- }
-
- const nodeIndexPath = path.join(packagesDir, shortName, 'index.js')
- if (args.force || !fs.existsSync(nodeIndexPath)) {
- fs.writeFileSync(
- nodeIndexPath,
- `
-'use strict'
-
-if (process.env.NODE_ENV === 'production') {
- module.exports = require('./dist/${shortName}.cjs.prod.js')
-} else {
- module.exports = require('./dist/${shortName}.cjs.js')
-}
- `.trim() + '\n'
- )
- }
-})
diff --git a/scripts/build.js b/scripts/build.js
index efa5d7f0f40..02212a70e0c 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -1,3 +1,5 @@
+// @ts-check
+
/*
Produces production builds and stitches together d.ts files.
@@ -14,54 +16,131 @@ nr build core --formats cjs
```
*/
-const fs = require('fs-extra')
-const path = require('path')
-const chalk = require('chalk')
-const execa = require('execa')
-const { gzipSync } = require('zlib')
-const { compress } = require('brotli')
-const { targets: allTargets, fuzzyMatchTarget } = require('./utils')
-
-const args = require('minimist')(process.argv.slice(2))
-const targets = args._
-const formats = args.formats || args.f
-const devOnly = args.devOnly || args.d
-const prodOnly = !devOnly && (args.prodOnly || args.p)
-const sourceMap = args.sourcemap || args.s
-const isRelease = args.release
-const buildTypes = args.t || args.types || isRelease
-const buildAllMatching = args.all || args.a
-const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7)
+import fs from 'node:fs'
+import { parseArgs } from 'node:util'
+import path from 'node:path'
+import { brotliCompressSync, gzipSync } from 'node:zlib'
+import pico from 'picocolors'
+import { cpus } from 'node:os'
+import { targets as allTargets, exec, fuzzyMatchTarget } from './utils.js'
+import { scanEnums } from './inline-enums.js'
+import prettyBytes from 'pretty-bytes'
+import { spawnSync } from 'node:child_process'
+
+const commit = spawnSync('git', ['rev-parse', '--short=7', 'HEAD'])
+ .stdout.toString()
+ .trim()
+
+const { values, positionals: targets } = parseArgs({
+ allowPositionals: true,
+ options: {
+ formats: {
+ type: 'string',
+ short: 'f',
+ },
+ devOnly: {
+ type: 'boolean',
+ short: 'd',
+ },
+ prodOnly: {
+ type: 'boolean',
+ short: 'p',
+ },
+ withTypes: {
+ type: 'boolean',
+ short: 't',
+ },
+ sourceMap: {
+ type: 'boolean',
+ short: 's',
+ },
+ release: {
+ type: 'boolean',
+ },
+ all: {
+ type: 'boolean',
+ short: 'a',
+ },
+ size: {
+ type: 'boolean',
+ },
+ },
+})
+
+const {
+ formats,
+ all: buildAllMatching,
+ devOnly,
+ prodOnly,
+ withTypes: buildTypes,
+ sourceMap,
+ release: isRelease,
+ size: writeSize,
+} = values
+
+const sizeDir = path.resolve('temp/size')
run()
async function run() {
- if (isRelease) {
- // remove build cache for release builds to avoid outdated enum values
- await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache'))
- }
- if (!targets.length) {
- await buildAll(allTargets)
- checkAllSizes(allTargets)
- } else {
- await buildAll(fuzzyMatchTarget(targets, buildAllMatching))
- checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching))
+ if (writeSize) fs.mkdirSync(sizeDir, { recursive: true })
+ const removeCache = scanEnums()
+ try {
+ const resolvedTargets = targets.length
+ ? fuzzyMatchTarget(targets, buildAllMatching)
+ : allTargets
+ await buildAll(resolvedTargets)
+ await checkAllSizes(resolvedTargets)
+ if (buildTypes) {
+ await exec(
+ 'pnpm',
+ [
+ 'run',
+ 'build-dts',
+ ...(targets.length
+ ? ['--environment', `TARGETS:${resolvedTargets.join(',')}`]
+ : []),
+ ],
+ {
+ stdio: 'inherit',
+ },
+ )
+ }
+ } finally {
+ removeCache()
}
}
+/**
+ * Builds all the targets in parallel.
+ * @param {Array} targets - An array of targets to build.
+ * @returns {Promise} - A promise representing the build process.
+ */
async function buildAll(targets) {
- await runParallel(require('os').cpus().length, targets, build)
+ await runParallel(cpus().length, targets, build)
}
+/**
+ * Runs iterator function in parallel.
+ * @template T - The type of items in the data source
+ * @param {number} maxConcurrency - The maximum concurrency.
+ * @param {Array} source - The data source
+ * @param {(item: T) => Promise} iteratorFn - The iteratorFn
+ * @returns {Promise} - A Promise array containing all iteration results.
+ */
async function runParallel(maxConcurrency, source, iteratorFn) {
+ /**@type {Promise[]} */
const ret = []
+ /**@type {Promise[]} */
const executing = []
for (const item of source) {
- const p = Promise.resolve().then(() => iteratorFn(item, source))
+ const p = Promise.resolve().then(() => iteratorFn(item))
ret.push(p)
if (maxConcurrency <= source.length) {
- const e = p.then(() => executing.splice(executing.indexOf(e), 1))
+ const e = p.then(() => {
+ executing.splice(executing.indexOf(e), 1)
+ })
executing.push(e)
if (executing.length >= maxConcurrency) {
await Promise.race(executing)
@@ -71,9 +150,19 @@ async function runParallel(maxConcurrency, source, iteratorFn) {
return Promise.all(ret)
}
+const privatePackages = fs.readdirSync('packages-private')
+
+/**
+ * Builds the target.
+ * @param {string} target - The target to build.
+ * @returns {Promise} - A promise representing the build process.
+ */
async function build(target) {
- const pkgDir = path.resolve(`packages/${target}`)
- const pkg = require(`${pkgDir}/package.json`)
+ const pkgBase = privatePackages.includes(target)
+ ? `packages-private`
+ : `packages`
+ const pkgDir = path.resolve(`${pkgBase}/${target}`)
+ const pkg = JSON.parse(fs.readFileSync(`${pkgDir}/package.json`, 'utf-8'))
// if this is a full build (no specific targets), ignore private packages
if ((isRelease || !targets.length) && pkg.private) {
@@ -81,14 +170,15 @@ async function build(target) {
}
// if building a specific format, do not remove dist.
- if (!formats) {
- await fs.remove(`${pkgDir}/dist`)
+ if (!formats && fs.existsSync(`${pkgDir}/dist`)) {
+ fs.rmSync(`${pkgDir}/dist`, { recursive: true })
}
const env =
(pkg.buildOptions && pkg.buildOptions.env) ||
(devOnly ? 'development' : 'production')
- await execa(
+
+ await exec(
'rollup',
[
'-c',
@@ -98,94 +188,77 @@ async function build(target) {
`NODE_ENV:${env}`,
`TARGET:${target}`,
formats ? `FORMATS:${formats}` : ``,
- buildTypes ? `TYPES:true` : ``,
prodOnly ? `PROD_ONLY:true` : ``,
- sourceMap ? `SOURCE_MAP:true` : ``
+ sourceMap ? `SOURCE_MAP:true` : ``,
]
.filter(Boolean)
- .join(',')
+ .join(','),
],
- { stdio: 'inherit' }
+ { stdio: 'inherit' },
)
-
- if (buildTypes && pkg.types) {
- console.log()
- console.log(
- chalk.bold(chalk.yellow(`Rolling up type definitions for ${target}...`))
- )
-
- // build types
- const { Extractor, ExtractorConfig } = require('@microsoft/api-extractor')
-
- const extractorConfigPath = path.resolve(pkgDir, `api-extractor.json`)
- const extractorConfig =
- ExtractorConfig.loadFileAndPrepare(extractorConfigPath)
- const extractorResult = Extractor.invoke(extractorConfig, {
- localBuild: true,
- showVerboseMessages: true
- })
-
- if (extractorResult.succeeded) {
- // concat additional d.ts to rolled-up dts
- const typesDir = path.resolve(pkgDir, 'types')
- if (await fs.exists(typesDir)) {
- const dtsPath = path.resolve(pkgDir, pkg.types)
- const existing = await fs.readFile(dtsPath, 'utf-8')
- const typeFiles = await fs.readdir(typesDir)
- const toAdd = await Promise.all(
- typeFiles.map(file => {
- return fs.readFile(path.resolve(typesDir, file), 'utf-8')
- })
- )
- await fs.writeFile(dtsPath, existing + '\n' + toAdd.join('\n'))
- }
- console.log(
- chalk.bold(chalk.green(`API Extractor completed successfully.`))
- )
- } else {
- console.error(
- `API Extractor completed with ${extractorResult.errorCount} errors` +
- ` and ${extractorResult.warningCount} warnings`
- )
- process.exitCode = 1
- }
-
- await fs.remove(`${pkgDir}/dist/packages`)
- }
}
-function checkAllSizes(targets) {
+/**
+ * Checks the sizes of all targets.
+ * @param {string[]} targets - The targets to check sizes for.
+ * @returns {Promise}
+ */
+async function checkAllSizes(targets) {
if (devOnly || (formats && !formats.includes('global'))) {
return
}
console.log()
for (const target of targets) {
- checkSize(target)
+ await checkSize(target)
}
console.log()
}
-function checkSize(target) {
+/**
+ * Checks the size of a target.
+ * @param {string} target - The target to check the size for.
+ * @returns {Promise}
+ */
+async function checkSize(target) {
const pkgDir = path.resolve(`packages/${target}`)
- checkFileSize(`${pkgDir}/dist/${target}.global.prod.js`)
+ await checkFileSize(`${pkgDir}/dist/${target}.global.prod.js`)
if (!formats || formats.includes('global-runtime')) {
- checkFileSize(`${pkgDir}/dist/${target}.runtime.global.prod.js`)
+ await checkFileSize(`${pkgDir}/dist/${target}.runtime.global.prod.js`)
}
}
-function checkFileSize(filePath) {
+/**
+ * Checks the file size.
+ * @param {string} filePath - The path of the file to check the size for.
+ * @returns {Promise}
+ */
+async function checkFileSize(filePath) {
if (!fs.existsSync(filePath)) {
return
}
const file = fs.readFileSync(filePath)
- const minSize = (file.length / 1024).toFixed(2) + 'kb'
+ const fileName = path.basename(filePath)
+
const gzipped = gzipSync(file)
- const gzippedSize = (gzipped.length / 1024).toFixed(2) + 'kb'
- const compressed = compress(file)
- const compressedSize = (compressed.length / 1024).toFixed(2) + 'kb'
+ const brotli = brotliCompressSync(file)
+
console.log(
- `${chalk.gray(
- chalk.bold(path.basename(filePath))
- )} min:${minSize} / gzip:${gzippedSize} / brotli:${compressedSize}`
+ `${pico.gray(pico.bold(fileName))} min:${prettyBytes(
+ file.length,
+ )} / gzip:${prettyBytes(gzipped.length)} / brotli:${prettyBytes(
+ brotli.length,
+ )}`,
)
+
+ if (writeSize)
+ fs.writeFileSync(
+ path.resolve(sizeDir, `${fileName}.json`),
+ JSON.stringify({
+ file: fileName,
+ size: file.length,
+ gzip: gzipped.length,
+ brotli: brotli.length,
+ }),
+ 'utf-8',
+ )
}
diff --git a/scripts/dev.js b/scripts/dev.js
index 81efc5c6903..fb4d3873e8b 100644
--- a/scripts/dev.js
+++ b/scripts/dev.js
@@ -1,109 +1,162 @@
+// @ts-check
+
// Using esbuild for faster dev builds.
// We are still using Rollup for production builds because it generates
-// smaller files w/ better tree-shaking.
+// smaller files and provides better tree-shaking.
-// @ts-check
-const { build } = require('esbuild')
-const nodePolyfills = require('@esbuild-plugins/node-modules-polyfill')
-const { resolve, relative } = require('path')
-const args = require('minimist')(process.argv.slice(2))
+import esbuild from 'esbuild'
+import fs from 'node:fs'
+import { dirname, relative, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+import { createRequire } from 'node:module'
+import { parseArgs } from 'node:util'
+import { polyfillNode } from 'esbuild-plugin-polyfill-node'
+
+const require = createRequire(import.meta.url)
+const __dirname = dirname(fileURLToPath(import.meta.url))
+
+const {
+ values: { format: rawFormat, prod, inline: inlineDeps },
+ positionals,
+} = parseArgs({
+ allowPositionals: true,
+ options: {
+ format: {
+ type: 'string',
+ short: 'f',
+ default: 'global',
+ },
+ prod: {
+ type: 'boolean',
+ short: 'p',
+ default: false,
+ },
+ inline: {
+ type: 'boolean',
+ short: 'i',
+ default: false,
+ },
+ },
+})
-const target = args._[0] || 'vue'
-const format = args.f || 'global'
-const inlineDeps = args.i || args.inline
-const pkg = require(resolve(__dirname, `../packages/${target}/package.json`))
+const format = rawFormat || 'global'
+const targets = positionals.length ? positionals : ['vue']
// resolve output
const outputFormat = format.startsWith('global')
? 'iife'
: format === 'cjs'
- ? 'cjs'
- : 'esm'
+ ? 'cjs'
+ : 'esm'
const postfix = format.endsWith('-runtime')
? `runtime.${format.replace(/-runtime$/, '')}`
: format
-const outfile = resolve(
- __dirname,
- `../packages/${target}/dist/${
- target === 'vue-compat' ? `vue` : target
- }.${postfix}.js`
-)
-const relativeOutfile = relative(process.cwd(), outfile)
+const privatePackages = fs.readdirSync('packages-private')
-// resolve externals
-// TODO this logic is largely duplicated from rollup.config.js
-let external = []
-if (!inlineDeps) {
- // cjs & esm-bundler: external all deps
- if (format === 'cjs' || format.includes('esm-bundler')) {
- external = [
- ...external,
- ...Object.keys(pkg.dependencies || {}),
- ...Object.keys(pkg.peerDependencies || {}),
- // for @vue/compiler-sfc / server-renderer
- 'path',
- 'url',
- 'stream'
- ]
- }
+for (const target of targets) {
+ const pkgBase = privatePackages.includes(target)
+ ? `packages-private`
+ : `packages`
+ const pkgBasePath = `../${pkgBase}/${target}`
+ const pkg = require(`${pkgBasePath}/package.json`)
+ const outfile = resolve(
+ __dirname,
+ `${pkgBasePath}/dist/${
+ target === 'vue-compat' ? `vue` : target
+ }.${postfix}.${prod ? `prod.` : ``}js`,
+ )
+ const relativeOutfile = relative(process.cwd(), outfile)
- if (target === 'compiler-sfc') {
- const consolidateDeps = require.resolve('@vue/consolidate/package.json', {
- paths: [resolve(__dirname, `../packages/${target}/`)]
- })
- external = [
- ...external,
- ...Object.keys(require(consolidateDeps).devDependencies),
- 'fs',
- 'vm',
- 'crypto',
- 'react-dom/server',
- 'teacup/lib/express',
- 'arc-templates/dist/es5',
- 'then-pug',
- 'then-jade'
- ]
- }
-}
+ // resolve externals
+ // TODO this logic is largely duplicated from rollup.config.js
+ /** @type {string[]} */
+ let external = []
+ if (!inlineDeps) {
+ // cjs & esm-bundler: external all deps
+ if (format === 'cjs' || format.includes('esm-bundler')) {
+ external = [
+ ...external,
+ ...Object.keys(pkg.dependencies || {}),
+ ...Object.keys(pkg.peerDependencies || {}),
+ // for @vue/compiler-sfc / server-renderer
+ 'path',
+ 'url',
+ 'stream',
+ ]
+ }
-build({
- entryPoints: [resolve(__dirname, `../packages/${target}/src/index.ts`)],
- outfile,
- bundle: true,
- external,
- sourcemap: true,
- format: outputFormat,
- globalName: pkg.buildOptions?.name,
- platform: format === 'cjs' ? 'node' : 'browser',
- plugins:
- format === 'cjs' || pkg.buildOptions?.enableNonBrowserBranches
- ? [nodePolyfills.default()]
- : undefined,
- define: {
- __COMMIT__: `"dev"`,
- __VERSION__: `"${pkg.version}"`,
- __DEV__: `true`,
- __TEST__: `false`,
- __BROWSER__: String(
- format !== 'cjs' && !pkg.buildOptions?.enableNonBrowserBranches
- ),
- __GLOBAL__: String(format === 'global'),
- __ESM_BUNDLER__: String(format.includes('esm-bundler')),
- __ESM_BROWSER__: String(format.includes('esm-browser')),
- __NODE_JS__: String(format === 'cjs'),
- __SSR__: String(format === 'cjs' || format.includes('esm-bundler')),
- __COMPAT__: String(target === 'vue-compat'),
- __FEATURE_SUSPENSE__: `true`,
- __FEATURE_OPTIONS_API__: `true`,
- __FEATURE_PROD_DEVTOOLS__: `false`
- },
- watch: {
- onRebuild(error) {
- if (!error) console.log(`rebuilt: ${relativeOutfile}`)
+ if (target === 'compiler-sfc') {
+ const consolidatePkgPath = require.resolve(
+ '@vue/consolidate/package.json',
+ {
+ paths: [resolve(__dirname, `../packages/${target}/`)],
+ },
+ )
+ const consolidateDeps = Object.keys(
+ require(consolidatePkgPath).devDependencies,
+ )
+ external = [
+ ...external,
+ ...consolidateDeps,
+ 'fs',
+ 'vm',
+ 'crypto',
+ 'react-dom/server',
+ 'teacup/lib/express',
+ 'arc-templates/dist/es5',
+ 'then-pug',
+ 'then-jade',
+ ]
}
}
-}).then(() => {
- console.log(`watching: ${relativeOutfile}`)
-})
+ /** @type {Array} */
+ const plugins = [
+ {
+ name: 'log-rebuild',
+ setup(build) {
+ build.onEnd(() => {
+ console.log(`built: ${relativeOutfile}`)
+ })
+ },
+ },
+ ]
+
+ if (format !== 'cjs' && pkg.buildOptions?.enableNonBrowserBranches) {
+ plugins.push(polyfillNode())
+ }
+
+ esbuild
+ .context({
+ entryPoints: [resolve(__dirname, `${pkgBasePath}/src/index.ts`)],
+ outfile,
+ bundle: true,
+ external,
+ sourcemap: true,
+ format: outputFormat,
+ globalName: pkg.buildOptions?.name,
+ platform: format === 'cjs' ? 'node' : 'browser',
+ plugins,
+ define: {
+ __COMMIT__: `"dev"`,
+ __VERSION__: `"${pkg.version}"`,
+ __DEV__: prod ? `false` : `true`,
+ __TEST__: `false`,
+ __BROWSER__: String(
+ format !== 'cjs' && !pkg.buildOptions?.enableNonBrowserBranches,
+ ),
+ __GLOBAL__: String(format === 'global'),
+ __ESM_BUNDLER__: String(format.includes('esm-bundler')),
+ __ESM_BROWSER__: String(format.includes('esm-browser')),
+ __CJS__: String(format === 'cjs'),
+ __SSR__: String(format !== 'global'),
+ __COMPAT__: String(target === 'vue-compat'),
+ __FEATURE_SUSPENSE__: `true`,
+ __FEATURE_OPTIONS_API__: `true`,
+ __FEATURE_PROD_DEVTOOLS__: `false`,
+ __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: `true`,
+ },
+ })
+ .then(ctx => ctx.watch())
+}
diff --git a/scripts/filter-e2e.js b/scripts/filter-e2e.js
deleted file mode 100644
index d1856a389cd..00000000000
--- a/scripts/filter-e2e.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const path = require('path')
-
-const e2eTests = [
- 'vue/__tests__/Transition',
- 'vue/__tests__/TransitionGroup',
- 'vue/examples/'
-]
-
-module.exports = list => {
- return {
- filtered: list
- .filter(t => e2eTests.some(tt => t.includes(path.normalize(tt))))
- .map(test => ({ test }))
- }
-}
-
-module.exports.e2eTests = e2eTests
diff --git a/scripts/filter-unit.js b/scripts/filter-unit.js
deleted file mode 100644
index d7528079068..00000000000
--- a/scripts/filter-unit.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const { e2eTests } = require('./filter-e2e')
-
-module.exports = list => {
- return {
- filtered: list
- .filter(t => !e2eTests.some(tt => t.includes(tt)))
- .map(test => ({ test }))
- }
-}
diff --git a/scripts/inline-enums.js b/scripts/inline-enums.js
new file mode 100644
index 00000000000..b1baaa6c5c3
--- /dev/null
+++ b/scripts/inline-enums.js
@@ -0,0 +1,287 @@
+// @ts-check
+
+/**
+ * We used const enums before, but it caused some issues: #1228, so we
+ * switched to regular enums. But we still want to keep the zero-cost benefit
+ * of const enums, and minimize the impact on bundle size as much as possible.
+ *
+ * Here we pre-process all the enums in the project and turn them into
+ * global replacements, and rewrite the original declarations as object literals.
+ *
+ * This file is expected to be executed with project root as cwd.
+ */
+
+import * as assert from 'node:assert'
+import {
+ existsSync,
+ mkdirSync,
+ readFileSync,
+ rmSync,
+ writeFileSync,
+} from 'node:fs'
+import * as path from 'node:path'
+import { parse } from '@babel/parser'
+import { spawnSync } from 'node:child_process'
+import MagicString from 'magic-string'
+
+/**
+ * @typedef {{ readonly name: string, readonly value: string | number }} EnumMember
+ * @typedef {{ readonly id: string, readonly range: readonly [start: number, end: number], readonly members: ReadonlyArray}} EnumDeclaration
+ * @typedef {{ readonly declarations: { readonly [file: string] : ReadonlyArray}, readonly defines: { readonly [ id_key: `${string}.${string}`]: string } }} EnumData
+ */
+
+const ENUM_CACHE_PATH = 'temp/enum.json'
+
+/**
+ * @param {string} exp
+ * @returns {string | number}
+ */
+function evaluate(exp) {
+ return new Function(`return ${exp}`)()
+}
+
+// this is called in the build script entry once
+// so the data can be shared across concurrent Rollup processes
+export function scanEnums() {
+ /** @type {{ [file: string]: EnumDeclaration[] }} */
+ const declarations = Object.create(null)
+ /** @type {{ [id_key: `${string}.${string}`]: string; }} */
+ const defines = Object.create(null)
+
+ // 1. grep for files with exported enum
+ const { stdout } = spawnSync('git', ['grep', `export enum`])
+ const files = [
+ ...new Set(
+ stdout
+ .toString()
+ .trim()
+ .split('\n')
+ .map(line => line.split(':')[0]),
+ ),
+ ]
+
+ // 2. parse matched files to collect enum info
+ for (const relativeFile of files) {
+ const file = path.resolve(process.cwd(), relativeFile)
+ const content = readFileSync(file, 'utf-8')
+ const ast = parse(content, {
+ plugins: ['typescript'],
+ sourceType: 'module',
+ })
+
+ /** @type {Set} */
+ const enumIds = new Set()
+ for (const node of ast.program.body) {
+ if (
+ node.type === 'ExportNamedDeclaration' &&
+ node.declaration &&
+ node.declaration.type === 'TSEnumDeclaration'
+ ) {
+ const decl = node.declaration
+ const id = decl.id.name
+ if (enumIds.has(id)) {
+ throw new Error(
+ `not support declaration merging for enum ${id} in ${file}`,
+ )
+ }
+ enumIds.add(id)
+ /** @type {string | number | undefined} */
+ let lastInitialized
+ /** @type {Array} */
+ const members = []
+
+ for (let i = 0; i < decl.members.length; i++) {
+ const e = decl.members[i]
+ const key = e.id.type === 'Identifier' ? e.id.name : e.id.value
+ const fullKey = /** @type {const} */ (`${id}.${key}`)
+ const saveValue = (/** @type {string | number} */ value) => {
+ // We need allow same name enum in different file.
+ // For example: enum ErrorCodes exist in both @vue/compiler-core and @vue/runtime-core
+ // But not allow `ErrorCodes.__EXTEND_POINT__` appear in two same name enum
+ if (fullKey in defines) {
+ throw new Error(`name conflict for enum ${id} in ${file}`)
+ }
+ members.push({
+ name: key,
+ value,
+ })
+ defines[fullKey] = JSON.stringify(value)
+ }
+ const init = e.initializer
+ if (init) {
+ /** @type {string | number} */
+ let value
+ if (
+ init.type === 'StringLiteral' ||
+ init.type === 'NumericLiteral'
+ ) {
+ value = init.value
+ }
+ // e.g. 1 << 2
+ else if (init.type === 'BinaryExpression') {
+ const resolveValue = (
+ /** @type {import('@babel/types').Expression | import('@babel/types').PrivateName} */ node,
+ ) => {
+ assert.ok(typeof node.start === 'number')
+ assert.ok(typeof node.end === 'number')
+ if (
+ node.type === 'NumericLiteral' ||
+ node.type === 'StringLiteral'
+ ) {
+ return node.value
+ } else if (node.type === 'MemberExpression') {
+ const exp = /** @type {`${string}.${string}`} */ (
+ content.slice(node.start, node.end)
+ )
+ if (!(exp in defines)) {
+ throw new Error(
+ `unhandled enum initialization expression ${exp} in ${file}`,
+ )
+ }
+ return defines[exp]
+ } else {
+ throw new Error(
+ `unhandled BinaryExpression operand type ${node.type} in ${file}`,
+ )
+ }
+ }
+ const exp = `${resolveValue(init.left)}${
+ init.operator
+ }${resolveValue(init.right)}`
+ value = evaluate(exp)
+ } else if (init.type === 'UnaryExpression') {
+ if (
+ init.argument.type === 'StringLiteral' ||
+ init.argument.type === 'NumericLiteral'
+ ) {
+ const exp = `${init.operator}${init.argument.value}`
+ value = evaluate(exp)
+ } else {
+ throw new Error(
+ `unhandled UnaryExpression argument type ${init.argument.type} in ${file}`,
+ )
+ }
+ } else {
+ throw new Error(
+ `unhandled initializer type ${init.type} for ${fullKey} in ${file}`,
+ )
+ }
+ lastInitialized = value
+ saveValue(lastInitialized)
+ } else {
+ if (lastInitialized === undefined) {
+ // first initialized
+ lastInitialized = 0
+ saveValue(lastInitialized)
+ } else if (typeof lastInitialized === 'number') {
+ lastInitialized++
+ saveValue(lastInitialized)
+ } else {
+ // should not happen
+ throw new Error(`wrong enum initialization sequence in ${file}`)
+ }
+ }
+ }
+
+ if (!(file in declarations)) {
+ declarations[file] = []
+ }
+ assert.ok(typeof node.start === 'number')
+ assert.ok(typeof node.end === 'number')
+ declarations[file].push({
+ id,
+ range: [node.start, node.end],
+ members,
+ })
+ }
+ }
+ }
+
+ // 3. save cache
+ if (!existsSync('temp')) mkdirSync('temp')
+
+ /** @type {EnumData} */
+ const enumData = {
+ declarations,
+ defines,
+ }
+
+ writeFileSync(ENUM_CACHE_PATH, JSON.stringify(enumData))
+
+ return () => {
+ rmSync(ENUM_CACHE_PATH, { force: true })
+ }
+}
+
+/**
+ * @returns {[import('rollup').Plugin, Record]}
+ */
+export function inlineEnums() {
+ if (!existsSync(ENUM_CACHE_PATH)) {
+ throw new Error('enum cache needs to be initialized before creating plugin')
+ }
+ /**
+ * @type {EnumData}
+ */
+ const enumData = JSON.parse(readFileSync(ENUM_CACHE_PATH, 'utf-8'))
+
+ // 3. during transform:
+ // 3.1 files w/ enum declaration: rewrite declaration as object literal
+ // 3.2 files using enum: inject into esbuild define
+ /**
+ * @type {import('rollup').Plugin}
+ */
+ const plugin = {
+ name: 'inline-enum',
+ transform(code, id) {
+ /**
+ * @type {MagicString | undefined}
+ */
+ let s
+
+ if (id in enumData.declarations) {
+ s = s || new MagicString(code)
+ for (const declaration of enumData.declarations[id]) {
+ const {
+ range: [start, end],
+ id,
+ members,
+ } = declaration
+ s.update(
+ start,
+ end,
+ `export const ${id} = {${members
+ .flatMap(({ name, value }) => {
+ const forwardMapping =
+ JSON.stringify(name) + ': ' + JSON.stringify(value)
+ const reverseMapping =
+ JSON.stringify(value.toString()) + ': ' + JSON.stringify(name)
+
+ // see https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings
+ return typeof value === 'string'
+ ? [
+ forwardMapping,
+ // string enum members do not get a reverse mapping generated at all
+ ]
+ : [
+ forwardMapping,
+ // other enum members should support enum reverse mapping
+ reverseMapping,
+ ]
+ })
+ .join(',\n')}}`,
+ )
+ }
+ }
+
+ if (s) {
+ return {
+ code: s.toString(),
+ map: s.generateMap(),
+ }
+ }
+ },
+ }
+
+ return [plugin, enumData.defines]
+}
diff --git a/scripts/pre-dev-sfc.js b/scripts/pre-dev-sfc.js
index 7ed54dedc77..b28705f3464 100644
--- a/scripts/pre-dev-sfc.js
+++ b/scripts/pre-dev-sfc.js
@@ -1,13 +1,12 @@
-const fs = require('fs')
-const path = require('path')
+// @ts-check
+import fs from 'node:fs'
const packagesToCheck = [
'compiler-sfc',
'compiler-core',
'compiler-dom',
'compiler-ssr',
- 'reactivity-transform',
- 'shared'
+ 'shared',
]
let allFilesPresent = true
@@ -15,7 +14,7 @@ let allFilesPresent = true
for (const pkg of packagesToCheck) {
if (
!fs.existsSync(
- path.resolve(__dirname, `../packages/${pkg}/dist/${pkg}.cjs.js`)
+ new URL(`../packages/${pkg}/dist/${pkg}.cjs.js`, import.meta.url),
)
) {
allFilesPresent = false
diff --git a/scripts/preinstall.js b/scripts/preinstall.js
deleted file mode 100644
index a1269cc0a7c..00000000000
--- a/scripts/preinstall.js
+++ /dev/null
@@ -1,7 +0,0 @@
-if (!/pnpm/.test(process.env.npm_execpath || '')) {
- console.warn(
- `\u001b[33mThis repository requires using pnpm as the package manager ` +
- ` for scripts to work properly.\u001b[39m\n`
- )
- process.exit(1)
-}
diff --git a/scripts/release.js b/scripts/release.js
index b24a50371a6..cd287dfc12b 100644
--- a/scripts/release.js
+++ b/scripts/release.js
@@ -1,133 +1,329 @@
-const args = require('minimist')(process.argv.slice(2))
-const fs = require('fs')
-const path = require('path')
-const chalk = require('chalk')
-const semver = require('semver')
-const currentVersion = require('../package.json').version
-const { prompt } = require('enquirer')
-const execa = require('execa')
-
-const preId =
- args.preid ||
- (semver.prerelease(currentVersion) && semver.prerelease(currentVersion)[0])
+// @ts-check
+import fs from 'node:fs'
+import path from 'node:path'
+import pico from 'picocolors'
+import semver from 'semver'
+import enquirer from 'enquirer'
+import { createRequire } from 'node:module'
+import { fileURLToPath } from 'node:url'
+import { exec } from './utils.js'
+import { parseArgs } from 'node:util'
+
+/**
+ * @typedef {{
+ * name: string
+ * version: string
+ * dependencies?: { [dependenciesPackageName: string]: string }
+ * peerDependencies?: { [peerDependenciesPackageName: string]: string }
+ * }} Package
+ */
+
+let versionUpdated = false
+
+const { prompt } = enquirer
+const currentVersion = createRequire(import.meta.url)('../package.json').version
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
+
+const { values: args, positionals } = parseArgs({
+ allowPositionals: true,
+ options: {
+ preid: {
+ type: 'string',
+ },
+ dry: {
+ type: 'boolean',
+ },
+ tag: {
+ type: 'string',
+ },
+ canary: {
+ type: 'boolean',
+ },
+ skipBuild: {
+ type: 'boolean',
+ },
+ skipTests: {
+ type: 'boolean',
+ },
+ skipGit: {
+ type: 'boolean',
+ },
+ skipPrompts: {
+ type: 'boolean',
+ },
+ publish: {
+ type: 'boolean',
+ default: false,
+ },
+ publishOnly: {
+ type: 'boolean',
+ },
+ registry: {
+ type: 'string',
+ },
+ },
+})
+
+const preId = args.preid || semver.prerelease(currentVersion)?.[0]
const isDryRun = args.dry
-const skipTests = args.skipTests
+/** @type {boolean | undefined} */
+let skipTests = args.skipTests
const skipBuild = args.skipBuild
+const isCanary = args.canary
+const skipPrompts = args.skipPrompts || args.canary
+const skipGit = args.skipGit || args.canary
+
const packages = fs
.readdirSync(path.resolve(__dirname, '../packages'))
- .filter(p => !p.endsWith('.ts') && !p.startsWith('.'))
+ .filter(p => {
+ const pkgRoot = path.resolve(__dirname, '../packages', p)
+ if (fs.statSync(pkgRoot).isDirectory()) {
+ const pkg = JSON.parse(
+ fs.readFileSync(path.resolve(pkgRoot, 'package.json'), 'utf-8'),
+ )
+ return !pkg.private
+ }
+ })
+
+const isCorePackage = (/** @type {string} */ pkgName) => {
+ if (!pkgName) return
+
+ if (pkgName === 'vue' || pkgName === '@vue/compat') {
+ return true
+ }
+
+ return (
+ pkgName.startsWith('@vue') &&
+ packages.includes(pkgName.replace(/^@vue\//, ''))
+ )
+}
+
+const renamePackageToCanary = (/** @type {string} */ pkgName) => {
+ if (pkgName === 'vue') {
+ return '@vue/canary'
+ }
+ if (isCorePackage(pkgName)) {
+ return `${pkgName}-canary`
+ }
+
+ return pkgName
+}
+
+const keepThePackageName = (/** @type {string} */ pkgName) => pkgName
+
+/** @type {string[]} */
const skippedPackages = []
+/** @type {ReadonlyArray} */
const versionIncrements = [
'patch',
'minor',
'major',
- ...(preId ? ['prepatch', 'preminor', 'premajor', 'prerelease'] : [])
+ ...(preId
+ ? /** @type {const} */ (['prepatch', 'preminor', 'premajor', 'prerelease'])
+ : []),
]
-const inc = i => semver.inc(currentVersion, i, preId)
-const bin = name => path.resolve(__dirname, '../node_modules/.bin/' + name)
-const run = (bin, args, opts = {}) =>
- execa(bin, args, { stdio: 'inherit', ...opts })
-const dryRun = (bin, args, opts = {}) =>
- console.log(chalk.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts)
+const inc = (/** @type {import('semver').ReleaseType} */ i) =>
+ semver.inc(currentVersion, i, typeof preId === 'string' ? preId : undefined)
+const run = async (
+ /** @type {string} */ bin,
+ /** @type {ReadonlyArray} */ args,
+ /** @type {import('node:child_process').SpawnOptions} */ opts = {},
+) => exec(bin, args, { stdio: 'inherit', ...opts })
+const dryRun = async (
+ /** @type {string} */ bin,
+ /** @type {ReadonlyArray} */ args,
+ /** @type {import('node:child_process').SpawnOptions} */ opts = {},
+) => console.log(pico.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts)
const runIfNotDry = isDryRun ? dryRun : run
-const getPkgRoot = pkg => path.resolve(__dirname, '../packages/' + pkg)
-const step = msg => console.log(chalk.cyan(msg))
+const getPkgRoot = (/** @type {string} */ pkg) =>
+ path.resolve(__dirname, '../packages/' + pkg)
+const step = (/** @type {string} */ msg) => console.log(pico.cyan(msg))
async function main() {
- let targetVersion = args._[0]
+ if (!(await isInSyncWithRemote())) {
+ return
+ } else {
+ console.log(`${pico.green(`✓`)} commit is up-to-date with remote.\n`)
+ }
+
+ let targetVersion = positionals[0]
+
+ if (isCanary) {
+ // The canary version string format is `3.yyyyMMdd.0` (or `3.yyyyMMdd.0-minor.0` for minor)
+ // Use UTC date so that it's consistent across CI and maintainers' machines
+ const date = new Date()
+ const yyyy = date.getUTCFullYear()
+ const MM = (date.getUTCMonth() + 1).toString().padStart(2, '0')
+ const dd = date.getUTCDate().toString().padStart(2, '0')
+
+ const major = semver.major(currentVersion)
+ const datestamp = `${yyyy}${MM}${dd}`
+ let canaryVersion
+
+ canaryVersion = `${major}.${datestamp}.0`
+ if (args.tag && args.tag !== 'latest') {
+ canaryVersion = `${major}.${datestamp}.0-${args.tag}.0`
+ }
+
+ // check the registry to avoid version collision
+ // in case we need to publish more than one canary versions in a day
+ try {
+ const pkgName = renamePackageToCanary('vue')
+ const { stdout } = await run(
+ 'pnpm',
+ ['view', `${pkgName}@~${canaryVersion}`, 'version', '--json'],
+ { stdio: 'pipe' },
+ )
+ let versions = JSON.parse(/** @type {string} */ (stdout))
+ versions = Array.isArray(versions) ? versions : [versions]
+ const latestSameDayPatch = /** @type {string} */ (
+ semver.maxSatisfying(versions, `~${canaryVersion}`)
+ )
+
+ canaryVersion = /** @type {string} */ (
+ semver.inc(latestSameDayPatch, 'patch')
+ )
+ if (args.tag && args.tag !== 'latest') {
+ canaryVersion = /** @type {string} */ (
+ semver.inc(latestSameDayPatch, 'prerelease', args.tag)
+ )
+ }
+ } catch (/** @type {any} */ e) {
+ if (/E404/.test(e.message)) {
+ // the first patch version on that day
+ } else {
+ throw e
+ }
+ }
+
+ targetVersion = canaryVersion
+ }
if (!targetVersion) {
// no explicit version, offer suggestions
+ /** @type {{ release: string }} */
const { release } = await prompt({
type: 'select',
name: 'release',
message: 'Select release type',
- choices: versionIncrements.map(i => `${i} (${inc(i)})`).concat(['custom'])
+ choices: versionIncrements
+ .map(i => `${i} (${inc(i)})`)
+ .concat(['custom']),
})
if (release === 'custom') {
- targetVersion = (
- await prompt({
- type: 'input',
- name: 'version',
- message: 'Input custom version',
- initial: currentVersion
- })
- ).version
+ /** @type {{ version: string }} */
+ const result = await prompt({
+ type: 'input',
+ name: 'version',
+ message: 'Input custom version',
+ initial: currentVersion,
+ })
+ targetVersion = result.version
} else {
- targetVersion = release.match(/\((.*)\)/)[1]
+ targetVersion = release.match(/\((.*)\)/)?.[1] ?? ''
}
}
+ // @ts-expect-error
+ if (versionIncrements.includes(targetVersion)) {
+ // @ts-expect-error
+ targetVersion = inc(targetVersion)
+ }
+
if (!semver.valid(targetVersion)) {
throw new Error(`invalid target version: ${targetVersion}`)
}
- const { yes } = await prompt({
- type: 'confirm',
- name: 'yes',
- message: `Releasing v${targetVersion}. Confirm?`
- })
+ if (skipPrompts) {
+ step(
+ isCanary
+ ? `Releasing canary version v${targetVersion}...`
+ : `Releasing v${targetVersion}...`,
+ )
+ } else {
+ /** @type {{ yes: boolean }} */
+ const { yes: confirmRelease } = await prompt({
+ type: 'confirm',
+ name: 'yes',
+ message: `Releasing v${targetVersion}. Confirm?`,
+ })
- if (!yes) {
- return
+ if (!confirmRelease) {
+ return
+ }
}
- // run tests before release
- step('\nRunning tests...')
- if (!skipTests && !isDryRun) {
- await run(bin('jest'), ['--clearCache'])
- await run('pnpm', ['test', '--bail'])
- } else {
- console.log(`(skipped)`)
- }
+ await runTestsIfNeeded()
// update all package versions and inter-dependencies
step('\nUpdating cross dependencies...')
- updateVersions(targetVersion)
-
- // build all packages with types
- step('\nBuilding all packages...')
- if (!skipBuild && !isDryRun) {
- await run('pnpm', ['run', 'build', '--release'])
- // test generated dts files
- step('\nVerifying type declarations...')
- await run('pnpm', ['run', 'test-dts-only'])
- } else {
- console.log(`(skipped)`)
- }
+ updateVersions(
+ targetVersion,
+ isCanary ? renamePackageToCanary : keepThePackageName,
+ )
+ versionUpdated = true
// generate changelog
step('\nGenerating changelog...')
await run(`pnpm`, ['run', 'changelog'])
+ if (!skipPrompts) {
+ /** @type {{ yes: boolean }} */
+ const { yes: changelogOk } = await prompt({
+ type: 'confirm',
+ name: 'yes',
+ message: `Changelog generated. Does it look good?`,
+ })
+
+ if (!changelogOk) {
+ return
+ }
+ }
+
// update pnpm-lock.yaml
- step('\nUpdating lockfile...')
- await run(`pnpm`, ['install', '--prefer-offline'])
-
- const { stdout } = await run('git', ['diff'], { stdio: 'pipe' })
- if (stdout) {
- step('\nCommitting changes...')
- await runIfNotDry('git', ['add', '-A'])
- await runIfNotDry('git', ['commit', '-m', `release: v${targetVersion}`])
- } else {
- console.log('No changes to commit.')
+ // skipped during canary release because the package names changed and installing with `workspace:*` would fail
+ if (!isCanary) {
+ step('\nUpdating lockfile...')
+ await run(`pnpm`, ['install', '--prefer-offline'])
+ }
+
+ if (!skipGit) {
+ const { stdout } = await run('git', ['diff'], { stdio: 'pipe' })
+ if (stdout) {
+ step('\nCommitting changes...')
+ await runIfNotDry('git', ['add', '-A'])
+ await runIfNotDry('git', ['commit', '-m', `release: v${targetVersion}`])
+ } else {
+ console.log('No changes to commit.')
+ }
}
// publish packages
- step('\nPublishing packages...')
- for (const pkg of packages) {
- await publishPackage(pkg, targetVersion, runIfNotDry)
+ if (args.publish) {
+ await buildPackages()
+ await publishPackages(targetVersion)
}
// push to GitHub
- step('\nPushing to GitHub...')
- await runIfNotDry('git', ['tag', `v${targetVersion}`])
- await runIfNotDry('git', ['push', 'origin', `refs/tags/v${targetVersion}`])
- await runIfNotDry('git', ['push'])
+ if (!skipGit) {
+ step('\nPushing to GitHub...')
+ await runIfNotDry('git', ['tag', `v${targetVersion}`])
+ await runIfNotDry('git', ['push', 'origin', `refs/tags/v${targetVersion}`])
+ await runIfNotDry('git', ['push'])
+ }
+
+ if (!args.publish) {
+ console.log(
+ pico.yellow(
+ '\nRelease will be done via GitHub Actions.\n' +
+ 'Check status at https://github.com/vuejs/core/actions/workflows/release.yml',
+ ),
+ )
+ }
if (isDryRun) {
console.log(`\nDry run finished - run git diff to see package changes.`)
@@ -135,56 +331,202 @@ async function main() {
if (skippedPackages.length) {
console.log(
- chalk.yellow(
+ pico.yellow(
`The following packages are skipped and NOT published:\n- ${skippedPackages.join(
- '\n- '
- )}`
- )
+ '\n- ',
+ )}`,
+ ),
)
}
console.log()
}
-function updateVersions(version) {
+async function runTestsIfNeeded() {
+ if (!skipTests) {
+ step('Checking CI status for HEAD...')
+ let isCIPassed = await getCIResult()
+ skipTests ||= isCIPassed
+
+ if (isCIPassed) {
+ if (!skipPrompts) {
+ /** @type {{ yes: boolean }} */
+ const { yes: promptSkipTests } = await prompt({
+ type: 'confirm',
+ name: 'yes',
+ message: `CI for this commit passed. Skip local tests?`,
+ })
+ skipTests = promptSkipTests
+ } else {
+ skipTests = true
+ }
+ } else if (skipPrompts) {
+ throw new Error(
+ 'CI for the latest commit has not passed yet. ' +
+ 'Only run the release workflow after the CI has passed.',
+ )
+ }
+ }
+
+ if (!skipTests) {
+ step('\nRunning tests...')
+ if (!isDryRun) {
+ await run('pnpm', ['run', 'test', '--run'])
+ } else {
+ console.log(`Skipped (dry run)`)
+ }
+ } else {
+ step('Tests skipped.')
+ }
+}
+
+async function getCIResult() {
+ try {
+ const sha = await getSha()
+ const res = await fetch(
+ `https://api.github.com/repos/vuejs/core/actions/runs?head_sha=${sha}` +
+ `&status=success&exclude_pull_requests=true`,
+ )
+ /** @type {{ workflow_runs: ({ name: string, conclusion: string })[] }} */
+ const data = await res.json()
+ return data.workflow_runs.some(({ name, conclusion }) => {
+ return name === 'ci' && conclusion === 'success'
+ })
+ } catch {
+ console.error('Failed to get CI status for current commit.')
+ return false
+ }
+}
+
+async function isInSyncWithRemote() {
+ try {
+ const branch = await getBranch()
+ const res = await fetch(
+ `https://api.github.com/repos/vuejs/core/commits/${branch}?per_page=1`,
+ )
+ const data = await res.json()
+ if (data.sha === (await getSha())) {
+ return true
+ } else {
+ /** @type {{ yes: boolean }} */
+ const { yes } = await prompt({
+ type: 'confirm',
+ name: 'yes',
+ message: pico.red(
+ `Local HEAD is not up-to-date with remote. Are you sure you want to continue?`,
+ ),
+ })
+ return yes
+ }
+ } catch {
+ console.error(
+ pico.red('Failed to check whether local HEAD is up-to-date with remote.'),
+ )
+ return false
+ }
+}
+
+async function getSha() {
+ return (await exec('git', ['rev-parse', 'HEAD'])).stdout
+}
+
+async function getBranch() {
+ return (await exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout
+}
+
+/**
+ * @param {string} version
+ * @param {(pkgName: string) => string} getNewPackageName
+ */
+function updateVersions(version, getNewPackageName = keepThePackageName) {
// 1. update root package.json
- updatePackage(path.resolve(__dirname, '..'), version)
+ updatePackage(path.resolve(__dirname, '..'), version, getNewPackageName)
// 2. update all packages
- packages.forEach(p => updatePackage(getPkgRoot(p), version))
+ packages.forEach(p =>
+ updatePackage(getPkgRoot(p), version, getNewPackageName),
+ )
}
-function updatePackage(pkgRoot, version) {
+/**
+ * @param {string} pkgRoot
+ * @param {string} version
+ * @param {(pkgName: string) => string} getNewPackageName
+ */
+function updatePackage(pkgRoot, version, getNewPackageName) {
const pkgPath = path.resolve(pkgRoot, 'package.json')
+ /** @type {Package} */
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
+ pkg.name = getNewPackageName(pkg.name)
pkg.version = version
- updateDeps(pkg, 'dependencies', version)
- updateDeps(pkg, 'peerDependencies', version)
+ if (isCanary) {
+ updateDeps(pkg, 'dependencies', version, getNewPackageName)
+ updateDeps(pkg, 'peerDependencies', version, getNewPackageName)
+ }
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
}
-function updateDeps(pkg, depType, version) {
+/**
+ * @param {Package} pkg
+ * @param {'dependencies' | 'peerDependencies'} depType
+ * @param {string} version
+ * @param {(pkgName: string) => string} getNewPackageName
+ */
+function updateDeps(pkg, depType, version, getNewPackageName) {
const deps = pkg[depType]
if (!deps) return
Object.keys(deps).forEach(dep => {
- if (
- dep === 'vue' ||
- (dep.startsWith('@vue') && packages.includes(dep.replace(/^@vue\//, '')))
- ) {
+ if (isCorePackage(dep)) {
+ const newName = getNewPackageName(dep)
+ const newVersion = newName === dep ? version : `npm:${newName}@${version}`
console.log(
- chalk.yellow(`${pkg.name} -> ${depType} -> ${dep}@${version}`)
+ pico.yellow(`${pkg.name} -> ${depType} -> ${dep}@${newVersion}`),
)
- deps[dep] = version
+ deps[dep] = newVersion
}
})
}
-async function publishPackage(pkgName, version, runIfNotDry) {
- if (skippedPackages.includes(pkgName)) {
- return
+async function buildPackages() {
+ step('\nBuilding all packages...')
+ if (!skipBuild) {
+ await run('pnpm', ['run', 'build', '--withTypes'])
+ } else {
+ console.log(`(skipped)`)
}
- const pkgRoot = getPkgRoot(pkgName)
- const pkgPath = path.resolve(pkgRoot, 'package.json')
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
- if (pkg.private) {
+}
+
+/**
+ * @param {string} version
+ */
+async function publishPackages(version) {
+ // publish packages
+ step('\nPublishing packages...')
+
+ const additionalPublishFlags = []
+ if (isDryRun) {
+ additionalPublishFlags.push('--dry-run')
+ }
+ if (isDryRun || skipGit || process.env.CI) {
+ additionalPublishFlags.push('--no-git-checks')
+ }
+ // add provenance metadata when releasing from CI
+ // canary release commits are not pushed therefore we don't need to add provenance
+ // also skip provenance if not publishing to actual npm
+ if (process.env.CI && !isCanary && !args.registry) {
+ additionalPublishFlags.push('--provenance')
+ }
+
+ for (const pkg of packages) {
+ await publishPackage(pkg, version, additionalPublishFlags)
+ }
+}
+
+/**
+ * @param {string} pkgName
+ * @param {string} version
+ * @param {ReadonlyArray} additionalFlags
+ */
+async function publishPackage(pkgName, version, additionalFlags) {
+ if (skippedPackages.includes(pkgName)) {
return
}
@@ -201,34 +543,49 @@ async function publishPackage(pkgName, version, runIfNotDry) {
step(`Publishing ${pkgName}...`)
try {
- await runIfNotDry(
- // note: use of yarn is intentional here as we rely on its publishing
- // behavior.
- 'yarn',
+ // Don't change the package manager here as we rely on pnpm to handle
+ // workspace:* deps
+ await run(
+ 'pnpm',
[
'publish',
- '--new-version',
- version,
...(releaseTag ? ['--tag', releaseTag] : []),
'--access',
- 'public'
+ 'public',
+ ...(args.registry ? ['--registry', args.registry] : []),
+ ...additionalFlags,
],
{
- cwd: pkgRoot,
- stdio: 'pipe'
- }
+ cwd: getPkgRoot(pkgName),
+ stdio: 'pipe',
+ },
)
- console.log(chalk.green(`Successfully published ${pkgName}@${version}`))
- } catch (e) {
- if (e.stderr.match(/previously published/)) {
- console.log(chalk.red(`Skipping already published: ${pkgName}`))
+ console.log(pico.green(`Successfully published ${pkgName}@${version}`))
+ } catch (/** @type {any} */ e) {
+ if (e.message?.match(/previously published/)) {
+ console.log(pico.red(`Skipping already published: ${pkgName}`))
} else {
throw e
}
}
}
-main().catch(err => {
- updateVersions(currentVersion)
+async function publishOnly() {
+ const targetVersion = positionals[0]
+ if (targetVersion) {
+ updateVersions(targetVersion)
+ }
+ await buildPackages()
+ await publishPackages(currentVersion)
+}
+
+const fnToRun = args.publishOnly ? publishOnly : main
+
+fnToRun().catch(err => {
+ if (versionUpdated) {
+ // revert to current version on failed releases
+ updateVersions(currentVersion)
+ }
console.error(err)
+ process.exit(1)
})
diff --git a/scripts/setupJestEnv.ts b/scripts/setup-vitest.ts
similarity index 74%
rename from scripts/setupJestEnv.ts
rename to scripts/setup-vitest.ts
index bdeab74d217..08203572aff 100644
--- a/scripts/setupJestEnv.ts
+++ b/scripts/setup-vitest.ts
@@ -1,11 +1,26 @@
+import type { MockInstance } from 'vitest'
+
+declare module 'vitest' {
+ interface Assertion extends CustomMatchers {}
+ interface AsymmetricMatchersContaining extends CustomMatchers {}
+}
+
+interface CustomMatchers {
+ toHaveBeenWarned(): R
+ toHaveBeenWarnedLast(): R
+ toHaveBeenWarnedTimes(n: number): R
+}
+
+vi.stubGlobal('MathMLElement', class MathMLElement {})
+
expect.extend({
toHaveBeenWarned(received: string) {
- asserted.add(received)
const passed = warn.mock.calls.some(args => args[0].includes(received))
if (passed) {
+ asserted.add(received)
return {
pass: true,
- message: () => `expected "${received}" not to have been warned.`
+ message: () => `expected "${received}" not to have been warned.`,
}
} else {
const msgs = warn.mock.calls.map(args => args[0]).join('\n - ')
@@ -15,32 +30,31 @@ expect.extend({
`expected "${received}" to have been warned` +
(msgs.length
? `.\n\nActual messages:\n\n - ${msgs}`
- : ` but no warning was recorded.`)
+ : ` but no warning was recorded.`),
}
}
},
toHaveBeenWarnedLast(received: string) {
- asserted.add(received)
const passed =
warn.mock.calls[warn.mock.calls.length - 1][0].includes(received)
if (passed) {
+ asserted.add(received)
return {
pass: true,
- message: () => `expected "${received}" not to have been warned last.`
+ message: () => `expected "${received}" not to have been warned last.`,
}
} else {
const msgs = warn.mock.calls.map(args => args[0]).join('\n - ')
return {
pass: false,
message: () =>
- `expected "${received}" to have been warned last.\n\nActual messages:\n\n - ${msgs}`
+ `expected "${received}" to have been warned last.\n\nActual messages:\n\n - ${msgs}`,
}
}
},
toHaveBeenWarnedTimes(received: string, n: number) {
- asserted.add(received)
let found = 0
warn.mock.calls.forEach(args => {
if (args[0].includes(received)) {
@@ -49,26 +63,27 @@ expect.extend({
})
if (found === n) {
+ asserted.add(received)
return {
pass: true,
- message: () => `expected "${received}" to have been warned ${n} times.`
+ message: () => `expected "${received}" to have been warned ${n} times.`,
}
} else {
return {
pass: false,
message: () =>
- `expected "${received}" to have been warned ${n} times but got ${found}.`
+ `expected "${received}" to have been warned ${n} times but got ${found}.`,
}
}
- }
+ },
})
-let warn: jest.SpyInstance
+let warn: MockInstance
const asserted: Set = new Set()
beforeEach(() => {
asserted.clear()
- warn = jest.spyOn(console, 'warn')
+ warn = vi.spyOn(console, 'warn')
warn.mockImplementation(() => {})
})
@@ -85,8 +100,8 @@ afterEach(() => {
if (nonAssertedWarnings.length) {
throw new Error(
`test case threw unexpected warnings:\n - ${nonAssertedWarnings.join(
- '\n - '
- )}`
+ '\n - ',
+ )}`,
)
}
})
diff --git a/scripts/size-report.js b/scripts/size-report.js
new file mode 100644
index 00000000000..47b25bb8302
--- /dev/null
+++ b/scripts/size-report.js
@@ -0,0 +1,130 @@
+// @ts-check
+import path from 'node:path'
+import { markdownTable } from 'markdown-table'
+import prettyBytes from 'pretty-bytes'
+import { readdir } from 'node:fs/promises'
+import { existsSync } from 'node:fs'
+
+/**
+ * @typedef {Object} SizeResult
+ * @property {number} size
+ * @property {number} gzip
+ * @property {number} brotli
+ */
+
+/**
+ * @typedef {SizeResult & { file: string }} BundleResult
+ */
+
+/**
+ * @typedef {Record} UsageResult
+ */
+
+const currDir = path.resolve('temp/size')
+const prevDir = path.resolve('temp/size-prev')
+let output = '## Size Report\n\n'
+const sizeHeaders = ['Size', 'Gzip', 'Brotli']
+
+run()
+
+/**
+ * Runs the main process of rendering file and usage data
+ */
+async function run() {
+ await renderFiles()
+ await renderUsages()
+
+ process.stdout.write(output)
+}
+
+/**
+ * Renders file sizes and diffs between current and previous versions
+ */
+async function renderFiles() {
+ const filterFiles = files =>
+ files.filter(file => file[0] !== '_' && !file.endsWith('.txt'))
+
+ const curr = filterFiles(await readdir(currDir))
+ const prev = existsSync(prevDir) ? filterFiles(await readdir(prevDir)) : []
+ const fileList = new Set([...curr, ...prev])
+
+ const rows = []
+ for (const file of fileList) {
+ const currPath = path.resolve(currDir, file)
+ const prevPath = path.resolve(prevDir, file)
+
+ const curr = await importJSON(currPath)
+ const prev = await importJSON(prevPath)
+ const fileName = curr?.file || prev?.file || ''
+
+ if (!curr) {
+ rows.push([`~~${fileName}~~`])
+ } else {
+ rows.push([
+ fileName,
+ `${prettyBytes(curr.size)}${getDiff(curr.size, prev?.size)}`,
+ `${prettyBytes(curr.gzip)}${getDiff(curr.gzip, prev?.gzip)}`,
+ `${prettyBytes(curr.brotli)}${getDiff(curr.brotli, prev?.brotli)}`,
+ ])
+ }
+ }
+
+ output += '### Bundles\n\n'
+ output += markdownTable([['File', ...sizeHeaders], ...rows])
+ output += '\n\n'
+}
+
+/**
+ * Renders usage data comparing current and previous usage results
+ */
+async function renderUsages() {
+ const curr = await importJSON(path.resolve(currDir, '_usages.json'))
+ const prev = await importJSON(path.resolve(prevDir, '_usages.json'))
+
+ output += '\n### Usages\n\n'
+
+ const data = Object.values(curr)
+ .map(usage => {
+ const prevUsage = prev?.[usage.name]
+ const diffSize = getDiff(usage.size, prevUsage?.size)
+ const diffGzipped = getDiff(usage.gzip, prevUsage?.gzip)
+ const diffBrotli = getDiff(usage.brotli, prevUsage?.brotli)
+
+ return [
+ usage.name,
+ `${prettyBytes(usage.size)}${diffSize}`,
+ `${prettyBytes(usage.gzip)}${diffGzipped}`,
+ `${prettyBytes(usage.brotli)}${diffBrotli}`,
+ ]
+ })
+ .filter(usage => !!usage)
+
+ output += `${markdownTable([['Name', ...sizeHeaders], ...data])}\n\n`
+}
+
+/**
+ * Imports JSON data from a specified path
+ *
+ * @template T
+ * @param {string} filePath - Path to the JSON file
+ * @returns {Promise} The JSON content or undefined if the file does not exist
+ */
+async function importJSON(filePath) {
+ if (!existsSync(filePath)) return undefined
+ return (await import(filePath, { with: { type: 'json' } })).default
+}
+
+/**
+ * Calculates the difference between the current and previous sizes
+ *
+ * @param {number} curr - The current size
+ * @param {number} [prev] - The previous size
+ * @returns {string} The difference in pretty format
+ */
+function getDiff(curr, prev) {
+ if (prev === undefined) return ''
+ const diff = curr - prev
+ if (diff === 0) return ''
+ const sign = diff > 0 ? '+' : ''
+ return ` (**${sign}${prettyBytes(diff)}**)`
+}
diff --git a/scripts/usage-size.js b/scripts/usage-size.js
new file mode 100644
index 00000000000..c68e3703b91
--- /dev/null
+++ b/scripts/usage-size.js
@@ -0,0 +1,146 @@
+// @ts-check
+import { mkdir, writeFile } from 'node:fs/promises'
+import path from 'node:path'
+import { rollup } from 'rollup'
+import nodeResolve from '@rollup/plugin-node-resolve'
+import { minify } from '@swc/core'
+import replace from '@rollup/plugin-replace'
+import { brotliCompressSync, gzipSync } from 'node:zlib'
+import { parseArgs } from 'node:util'
+import pico from 'picocolors'
+import prettyBytes from 'pretty-bytes'
+
+const {
+ values: { write },
+} = parseArgs({
+ options: {
+ write: {
+ type: 'boolean',
+ default: false,
+ },
+ },
+})
+
+const sizeDir = path.resolve('temp/size')
+const entry = path.resolve('./packages/vue/dist/vue.runtime.esm-bundler.js')
+
+/**
+ * @typedef {Object} Preset
+ * @property {string} name - The name of the preset
+ * @property {string[]} imports - The imports that are part of this preset
+ * @property {Record} [replace]
+ */
+
+/** @type {Preset[]} */
+const presets = [
+ {
+ name: 'createApp (CAPI only)',
+ imports: ['createApp'],
+ replace: { __VUE_OPTIONS_API__: 'false' },
+ },
+ { name: 'createApp', imports: ['createApp'] },
+ { name: 'createSSRApp', imports: ['createSSRApp'] },
+ { name: 'defineCustomElement', imports: ['defineCustomElement'] },
+ {
+ name: 'overall',
+ imports: [
+ 'createApp',
+ 'ref',
+ 'watch',
+ 'Transition',
+ 'KeepAlive',
+ 'Suspense',
+ ],
+ },
+]
+
+main()
+
+/**
+ * Main function that initiates the bundling process for the presets
+ */
+async function main() {
+ console.log()
+ /** @type {Promise<{name: string, size: number, gzip: number, brotli: number}>[]} */
+ const tasks = []
+ for (const preset of presets) {
+ tasks.push(generateBundle(preset))
+ }
+ const results = await Promise.all(tasks)
+
+ for (const r of results) {
+ console.log(
+ `${pico.green(pico.bold(r.name))} - ` +
+ `min:${prettyBytes(r.size, { minimumFractionDigits: 3 })} / ` +
+ `gzip:${prettyBytes(r.gzip, { minimumFractionDigits: 3 })} / ` +
+ `brotli:${prettyBytes(r.brotli, { minimumFractionDigits: 3 })}`,
+ )
+ }
+
+ await mkdir(sizeDir, { recursive: true })
+ await writeFile(
+ path.resolve(sizeDir, '_usages.json'),
+ JSON.stringify(Object.fromEntries(results.map(r => [r.name, r])), null, 2),
+ 'utf-8',
+ )
+}
+
+/**
+ * Generates a bundle for a given preset
+ *
+ * @param {Preset} preset - The preset to generate the bundle for
+ * @returns {Promise<{name: string, size: number, gzip: number, brotli: number}>} - The result of the bundling process
+ */
+async function generateBundle(preset) {
+ const id = 'virtual:entry'
+ const content = `export { ${preset.imports.join(', ')} } from '${entry}'`
+
+ const result = await rollup({
+ input: id,
+ plugins: [
+ {
+ name: 'usage-size-plugin',
+ resolveId(_id) {
+ if (_id === id) return id
+ return null
+ },
+ load(_id) {
+ if (_id === id) return content
+ },
+ },
+ nodeResolve(),
+ replace({
+ 'process.env.NODE_ENV': '"production"',
+ __VUE_PROD_DEVTOOLS__: 'false',
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
+ __VUE_OPTIONS_API__: 'true',
+ preventAssignment: true,
+ ...preset.replace,
+ }),
+ ],
+ })
+
+ const generated = await result.generate({})
+ const bundled = generated.output[0].code
+ const minified = (
+ await minify(bundled, {
+ module: true,
+ toplevel: true,
+ })
+ ).code
+
+ const size = minified.length
+ const gzip = gzipSync(minified).length
+ const brotli = brotliCompressSync(minified).length
+
+ if (write) {
+ await writeFile(path.resolve(sizeDir, preset.name + '.js'), bundled)
+ }
+
+ return {
+ name: preset.name,
+ size,
+ gzip,
+ brotli,
+ }
+}
diff --git a/scripts/utils.js b/scripts/utils.js
index 480fdaf92a6..3c92bf7bafb 100644
--- a/scripts/utils.js
+++ b/scripts/utils.js
@@ -1,18 +1,35 @@
-const fs = require('fs')
-const chalk = require('chalk')
+// @ts-check
+import fs from 'node:fs'
+import pico from 'picocolors'
+import { createRequire } from 'node:module'
+import { spawn } from 'node:child_process'
-const targets = (exports.targets = fs.readdirSync('packages').filter(f => {
- if (!fs.statSync(`packages/${f}`).isDirectory()) {
- return false
- }
- const pkg = require(`../packages/${f}/package.json`)
- if (pkg.private && !pkg.buildOptions) {
- return false
- }
- return true
-}))
+const require = createRequire(import.meta.url)
+
+export const targets = fs
+ .readdirSync('packages')
+ .filter(f => {
+ if (
+ !fs.statSync(`packages/${f}`).isDirectory() ||
+ !fs.existsSync(`packages/${f}/package.json`)
+ ) {
+ return false
+ }
+ const pkg = require(`../packages/${f}/package.json`)
+ if (pkg.private && !pkg.buildOptions) {
+ return false
+ }
+ return true
+ })
+ .concat('template-explorer')
-exports.fuzzyMatchTarget = (partialTargets, includeAllMatching) => {
+/**
+ *
+ * @param {ReadonlyArray} partialTargets
+ * @param {boolean | undefined} includeAllMatching
+ */
+export function fuzzyMatchTarget(partialTargets, includeAllMatching) {
+ /** @type {Array} */
const matched = []
partialTargets.forEach(partialTarget => {
for (const target of targets) {
@@ -29,12 +46,69 @@ exports.fuzzyMatchTarget = (partialTargets, includeAllMatching) => {
} else {
console.log()
console.error(
- ` ${chalk.bgRed.white(' ERROR ')} ${chalk.red(
- `Target ${chalk.underline(partialTargets)} not found!`
- )}`
+ ` ${pico.white(pico.bgRed(' ERROR '))} ${pico.red(
+ `Target ${pico.underline(partialTargets.toString())} not found!`,
+ )}`,
)
console.log()
process.exit(1)
}
}
+
+/**
+ * @param {string} command
+ * @param {ReadonlyArray} args
+ * @param {object} [options]
+ */
+export async function exec(command, args, options) {
+ return new Promise((resolve, reject) => {
+ const _process = spawn(command, args, {
+ stdio: [
+ 'ignore', // stdin
+ 'pipe', // stdout
+ 'pipe', // stderr
+ ],
+ ...options,
+ shell: process.platform === 'win32',
+ })
+
+ /**
+ * @type {Buffer[]}
+ */
+ const stderrChunks = []
+ /**
+ * @type {Buffer[]}
+ */
+ const stdoutChunks = []
+
+ _process.stderr?.on('data', chunk => {
+ stderrChunks.push(chunk)
+ })
+
+ _process.stdout?.on('data', chunk => {
+ stdoutChunks.push(chunk)
+ })
+
+ _process.on('error', error => {
+ reject(error)
+ })
+
+ _process.on('exit', code => {
+ const ok = code === 0
+ const stderr = Buffer.concat(stderrChunks).toString().trim()
+ const stdout = Buffer.concat(stdoutChunks).toString().trim()
+
+ if (ok) {
+ const result = { ok, code, stderr, stdout }
+ resolve(result)
+ } else {
+ reject(
+ new Error(
+ `Failed to execute command: ${command} ${args.join(' ')}: ${stderr}`,
+ ),
+ )
+ }
+ })
+ })
+}
diff --git a/scripts/verify-commit.js b/scripts/verify-commit.js
new file mode 100644
index 00000000000..d37370df023
--- /dev/null
+++ b/scripts/verify-commit.js
@@ -0,0 +1,28 @@
+// @ts-check
+import pico from 'picocolors'
+import { readFileSync } from 'node:fs'
+import path from 'node:path'
+
+const msgPath = path.resolve('.git/COMMIT_EDITMSG')
+const msg = readFileSync(msgPath, 'utf-8').trim()
+
+const commitRE =
+ /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\(.+\))?: .{1,50}/
+
+if (!commitRE.test(msg)) {
+ console.log()
+ console.error(
+ ` ${pico.white(pico.bgRed(' ERROR '))} ${pico.red(
+ `invalid commit message format.`,
+ )}\n\n` +
+ pico.red(
+ ` Proper commit message format is required for automated changelog generation. Examples:\n\n`,
+ ) +
+ ` ${pico.green(`feat(compiler): add 'comments' option`)}\n` +
+ ` ${pico.green(
+ `fix(v-model): handle events on blur (close #28)`,
+ )}\n\n` +
+ pico.red(` See .github/commit-convention.md for more details.\n`),
+ )
+ process.exit(1)
+}
diff --git a/scripts/verify-treeshaking.js b/scripts/verify-treeshaking.js
new file mode 100644
index 00000000000..381fc5dda84
--- /dev/null
+++ b/scripts/verify-treeshaking.js
@@ -0,0 +1,49 @@
+// @ts-check
+import fs from 'node:fs'
+import { exec } from './utils.js'
+
+exec('pnpm', ['build', 'vue', '-f', 'global-runtime']).then(() => {
+ const errors = []
+
+ const devBuild = fs.readFileSync(
+ 'packages/vue/dist/vue.runtime.global.js',
+ 'utf-8',
+ )
+
+ if (devBuild.includes('__spreadValues')) {
+ errors.push(
+ 'dev build contains unexpected esbuild object spread helper.\n' +
+ 'This means { ...obj } syntax is used in runtime code. This should be ' +
+ 'refactored to use the `extend` helper to avoid the extra code.',
+ )
+ }
+
+ const prodBuild = fs.readFileSync(
+ 'packages/vue/dist/vue.runtime.global.prod.js',
+ 'utf-8',
+ )
+
+ if (prodBuild.includes('Vue warn')) {
+ errors.push(
+ 'prod build contains unexpected warning-related code.\n' +
+ 'This means there are calls of warn() that are not guarded by the __DEV__ condition.',
+ )
+ }
+
+ if (
+ prodBuild.includes('html,body,base') ||
+ prodBuild.includes('svg,animate,animateMotion') ||
+ prodBuild.includes('annotation,annotation-xml,maction')
+ ) {
+ errors.push(
+ 'prod build contains unexpected domTagConfig lists.\n' +
+ 'This means helpers like isHTMLTag() is used in runtime code paths when it should be compiler-only.',
+ )
+ }
+
+ if (errors.length) {
+ throw new Error(
+ `Found the following treeshaking errors:\n\n- ${errors.join('\n\n- ')}`,
+ )
+ }
+})
diff --git a/scripts/verifyCommit.mjs b/scripts/verifyCommit.mjs
deleted file mode 100644
index 81512ab920e..00000000000
--- a/scripts/verifyCommit.mjs
+++ /dev/null
@@ -1,29 +0,0 @@
-import chalk from 'chalk'
-import { readFileSync } from 'fs'
-import path from 'path'
-import { fileURLToPath } from 'url'
-
-const dirname = path.dirname(fileURLToPath(import.meta.url), '..')
-const msgPath = path.resolve(dirname, '../.git/COMMIT_EDITMSG')
-const msg = readFileSync(msgPath, 'utf-8').trim()
-
-const commitRE =
- /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\(.+\))?: .{1,50}/
-
-if (!commitRE.test(msg)) {
- console.log()
- console.error(
- ` ${chalk.bgRed.white(' ERROR ')} ${chalk.red(
- `invalid commit message format.`
- )}\n\n` +
- chalk.red(
- ` Proper commit message format is required for automated changelog generation. Examples:\n\n`
- ) +
- ` ${chalk.green(`feat(compiler): add 'comments' option`)}\n` +
- ` ${chalk.green(
- `fix(v-model): handle events on blur (close #28)`
- )}\n\n` +
- chalk.red(` See .github/commit-convention.md for more details.\n`)
- )
- process.exit(1)
-}
diff --git a/test-dts/README.md b/test-dts/README.md
deleted file mode 100644
index 966374ba5c6..00000000000
--- a/test-dts/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Test-ts
-
-Tests Typescript types to ensure the types remain as expected.
-
-## Configuration
-
-### tsconfig.json
-
-Config used to test against the package source
-
-### tsconfig.build.json
-
-Replaces the `vue` and `@vue/*` dependencies with the built Typescript to ensure the published types are correct.
diff --git a/test-dts/defineCustomElement.test-d.ts b/test-dts/defineCustomElement.test-d.ts
deleted file mode 100644
index 8e60ac1c1df..00000000000
--- a/test-dts/defineCustomElement.test-d.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { defineCustomElement, expectType, expectError } from './index'
-
-describe('inject', () => {
- // with object inject
- defineCustomElement({
- props: {
- a: String
- },
- inject: {
- foo: 'foo',
- bar: 'bar',
- },
- created() {
- expectType(this.foo)
- expectType(this.bar)
- // @ts-expect-error
- expectError(this.foobar = 1)
- }
- })
-
- // with array inject
- defineCustomElement({
- props: ['a', 'b'],
- inject: ['foo', 'bar'],
- created() {
- expectType(this.foo)
- expectType(this.bar)
- // @ts-expect-error
- expectError(this.foobar = 1)
- }
- })
-
- // with no props
- defineCustomElement({
- inject: {
- foo: {
- from: 'pbar',
- default: 'foo'
- },
- bar: {
- from: 'pfoo',
- default: 'bar'
- },
- },
- created() {
- expectType(this.foo)
- expectType(this.bar)
- // @ts-expect-error
- expectError(this.foobar = 1)
- }
- })
-
- // without inject
- defineCustomElement({
- props: ['a', 'b'],
- created() {
- // @ts-expect-error
- expectError(this.foo = 1)
- // @ts-expect-error
- expectError(this.bar = 1)
- }
- })
-})
\ No newline at end of file
diff --git a/test-dts/inject.test-d.ts b/test-dts/inject.test-d.ts
deleted file mode 100644
index 69e06f170af..00000000000
--- a/test-dts/inject.test-d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { provide, inject, InjectionKey, expectType } from './index'
-
-const key: InjectionKey