├── .github
└── workflows
│ ├── codeql-analysis.yml
│ ├── npm-publish.yml
│ ├── publish-test.yml
│ └── test.js.yml
├── .gitignore
├── .npmrc
├── LICENSE
├── README.md
├── README_ZH.md
├── demo
├── demo1
│ ├── demo.vue
│ ├── demo1.html
│ └── demo1.ts
├── demo2
│ ├── demo.ts
│ ├── demo.vue
│ ├── demo2.html
│ └── route
│ │ └── route1.vue
├── demoIndex1.html
├── demoIndex2.html
├── partials
│ └── test.ejs
└── template.html
├── demo3.html
├── demo4.html
├── package.json
├── pnpm-lock.yaml
├── src
├── history-api
│ ├── historyApiFallbackPlugin.ts
│ └── types.ts
├── html
│ ├── Base.ts
│ ├── Build.ts
│ ├── Serve.ts
│ ├── VirtualHtmlPlugin.ts
│ └── types.ts
└── index.ts
├── test
├── __snapshots__
│ ├── pages.test.ts.snap
│ └── template.test.ts.snap
├── demo
│ ├── demo1
│ │ ├── demo1.html
│ │ └── demo1.ts
│ └── template
│ │ ├── demo1.html
│ │ ├── demo2.html
│ │ ├── demo3.html
│ │ └── test.ejs
├── pages.test.ts
└── template.test.ts
├── tsconfig.json
├── tsup.config.ts
├── vite.config.ts
└── vitestSetup.ts
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ main ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ main ]
20 | schedule:
21 | - cron: '22 3 * * 2'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v2
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v1
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v1
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 https://git.io/JvXDl
60 |
61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62 | # and modify them (or add more) to build your code if your project
63 | # uses a compiled language
64 |
65 | #- run: |
66 | # make bootstrap
67 | # make release
68 |
69 | - name: Perform CodeQL Analysis
70 | uses: github/codeql-action/analyze@v1
71 |
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3 |
4 | name: Node.js Package
5 |
6 | on:
7 | release:
8 | types: [created]
9 |
10 | jobs:
11 | publish-npm:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: pnpm/action-setup@v4.0.0
16 | with:
17 | version: 9.12.1
18 | - uses: actions/setup-node@v4.0.4
19 | with:
20 | node-version: 22.9.0
21 | registry-url: https://registry.npmjs.org/
22 | cache: 'pnpm'
23 | - run: npm install corepack -g
24 | - run: corepack enable
25 | - run: corepack install -g pnpm@9.12.1
26 | - run: pnpm install
27 | - run: npx playwright install
28 | - run: npm publish
29 | env:
30 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
31 |
--------------------------------------------------------------------------------
/.github/workflows/publish-test.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3 |
4 | name: Publish npm package
5 |
6 | on:
7 | workflow_dispatch:
8 |
9 | jobs:
10 | publish-npm:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: pnpm/action-setup@v4.0.0
15 | with:
16 | version: 9.12.1
17 | - uses: actions/setup-node@v4.0.4
18 | with:
19 | node-version: 22.9.0
20 | registry-url: https://registry.npmjs.org/
21 | cache: 'pnpm'
22 | - run: npm install corepack -g
23 | - run: corepack enable
24 | - run: corepack install -g pnpm@9.12.1
25 | - run: pnpm install
26 | - run: npx playwright install
27 | - run: npm publish
28 | env:
29 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
30 |
--------------------------------------------------------------------------------
/.github/workflows/test.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3 |
4 | name: Test commit
5 |
6 | on:
7 | push:
8 | branches: [ "main" ]
9 | pull_request:
10 | branches: [ "main" ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [18.18.0]
20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21 |
22 | steps:
23 | - uses: actions/checkout@v3
24 | - uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
25 | with:
26 | version: 7.16.0
27 | - name: Use Node.js ${{ matrix.node-version }}
28 | uses: actions/setup-node@v3
29 | with:
30 | node-version: ${{ matrix.node-version }}
31 | cache: 'pnpm'
32 | - run: pnpm i
33 | - run: npx playwright install
34 | - run: pnpm test
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | dist-ssr
5 | *.local
6 | .idea
7 | vite.config.js
8 | vite.config.js.map
9 | vite.config.d.ts
10 | *.d.ts
11 | *.js
12 | *.map
13 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmjs.org
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 windson1806
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vite-plugin-virtual-html
2 |
3 | [中文文档](./README_ZH.md)
4 |
5 | ## Motivation
6 |
7 | vite's [MPA](https://vitejs.dev/guide/build.html#multi-page-app) unlike `@vue/cli`'s `pages` option have a configuration
8 | in dev mode.
9 |
10 | vite's html file need to place in project's root to have same behavior in dev and production mode, it makes your
11 | project's root dir looks chaotic.
12 |
13 | And if you follow vite's MPA, put other file in other directory, unlike `index.html`, you need useless middle directory(
14 | Ex. from vite's MPA doc `http://localhost:3000/nested/nested.html`) to located it.
15 |
16 | so, i write this plugin to make vite's MPA more configurable and in dev mode or production has same behavior.
17 |
18 | this plugin use vite's `configureServer` Hook to intercept html request and response the html content requested from
19 | browser.
20 |
21 | ## update
22 |
23 | 1. `1.1.9` add `urlTransformer`function to support developer edit url
24 | 1. `1.0.2` add `connect-history-api-fallback` support
25 | 1. `0.4.0` add a new option to `pages`,just need an js file,plugin will auto generate a html file which include the
26 | entry js
27 | 1. `0.3.0` change the behavior of `defaultRender`, if in project, it has `ejs` as dependency, it will return html code
28 | which rendered by `ejs`, otherwise it will return html code directly as old version do
29 | 1. `0.2.9` add a new option `injectCode` to add some code before/after tag in html file
30 | 2. `0.2.8` add a new option `extraGlobPattern` to customize `fast-glob`'s pattern. Default pattern
31 | is `['**/*.html', '!node_modules/**/*.html', '!.**/*.html']`, attention: if your config has problems, such as you
32 | didn't ignore `dist`, when build,it will occur
33 | error: `new Error('[vite]: Rollup failed to resolve import "${id}" from "${importer}".\n'`
34 | 3. `0.2.6` `pages` now correctly identify multi-level directories
35 | 4. `0.2.3` `pages` options now can set to true to allow all html in project.
36 | 5. `0.2.1` now works fine with `@vitejs/plugin-react`.
37 | 6. `0.2.0` has reworked, so config have a little change
38 | 1. plugin does not require your html exists, but you must provide a template file(as html)
39 | 2. `page`'s config renamed to `template`
40 | 3. each `page` can have a independent `render` function
41 | 4. add a global config `data`, its' config will be covered by `page`'s `data`
42 | 5. all you `pages`' will be treat as template file
43 |
44 | ## features
45 |
46 | + allow you put your html file anywhere in your project(like `@vue/cli`'s `pages`)
47 | + when you run in dev,it will intercept html requests,and response with the html content which you set in `pages`.
48 | + when you run build, it will copy files(reading config from `pages` options) under dist's sub-folder to dist
49 | folder, and then delete the rest html file.
50 | + auto config `build.rollupOptions.input` from pages
51 | + if your html do not have a module script import. plugin will try to add a js/ts script import using the html file's
52 | name.
53 |
54 | ## Usage
55 |
56 | `yarn add vite-plugin-virtual-html --dev # npm install vite-plugin-virtual-html -D`
57 |
58 | Add it to `vite.config.js`
59 |
60 | ``` js
61 | // vite.config.js
62 | const virtualHtml = require('vite-plugin-virtual-html')
63 |
64 | const pages = {
65 | index: '/src/index/index.html',
66 | login: '/src/login/login.html',
67 | }
68 |
69 | module.exports = {
70 | plugins: [virtualHtml({
71 | pages,
72 | indexPage: 'login'
73 | })],
74 | }
75 | ```
76 |
77 | ## Configuration
78 |
79 | ### pages
80 |
81 | config your project's all html/template file's path
82 |
83 | it will be used for:
84 |
85 | + dev mode, it will intercept your html request, and response with html file in this config
86 | + build mode, inject into `build.rollupOptions.input`
87 | + when you build, plugin will copy all your config pages to project ROOT, and when build finished, the copied HTML file
88 | will auto remove from project ROOT.
89 | + if you want to use template system,you can send a object which contains `template` and `data` to render it. By
90 | default, it will return the html content in your HTML/template file, when you define a render function, it(html
91 | template) will rendered by your custom render function.
92 |
93 | ```
94 | // all config
95 | {
96 | // 1. directly input html/template path
97 | login1: '/src/index/index.html',
98 | // 2. a object with template
99 | login2: {
100 | template: '/src/login/login.html', // if there is no data prop, the login.html must only contain HTML content
101 | },
102 | // 3. a object with template and data, maybe with render
103 | login3: {
104 | template: '/src/login1/login1.html',
105 | data: {
106 | users: ['a', 'b', 'c']
107 | },
108 | // each page can have independent render function
109 | // render(template, data){
110 | // return template
111 | // }
112 | },
113 | // 4. config a js file path to auto-generate a html file
114 | login4: {
115 | entry: '/src/login/login.js', // MUST
116 | title: 'login4',// optional, default: ''
117 | body: '
' // optional, default: ''
118 | }
119 | }
120 | ```
121 |
122 | **notice:**
123 |
124 | 1. if your html page contains any template content(such as `<$= users.join(" | "); $>`), you **must** contain `template`
125 | and `data`.
126 | 2. The `pages` options' `key` is the real HTML file after build
127 | 3. The `pages` options' `key` and `value`/ `template` file's name can different.
128 | 4. for example 1, you can access `login1.html` when `dev` mode, and it will generate a `login1.html` when build.
129 | 5. when `pages` set to `true`, the `template.html` will only generate **ONLY ONE** `html` file
130 | 6. when use `entry` config, plugin will auto generate a html file like this project's `demo4.html`, according
131 | your `entry`/`title`/`body` config, it will has a little difference
132 |
133 | ### indexPage
134 |
135 | config the index page
136 |
137 | Ex. when you open `http://localhost:3000`, your project's root dir has no `index.html` file, then browser will
138 | show `404`.
139 |
140 | now, if you set this, plugin will intercept `/` request, and response with page you set.
141 |
142 | Like this:
143 | when you set `indexPage` to `login`,then you access `http://localhost:3000` in browser, it will show the `/login.html`
144 | page.
145 |
146 | it equals to access `http://localhost:3000/login.html`.
147 |
148 | ### render
149 |
150 | from `0.1.0` , you can use `render` function to render html template.
151 | i have just test in `ejs`, but i think other template system will(maybe) work correctly.
152 |
153 | **notice:**
154 |
155 | 1. `0.3.0` or later,if your html code/template use `ejs` template, you **MUST** install `ejs`
156 |
157 | ### extraGlobPattern
158 |
159 | Customize `fast-glob`'s pattern
160 | When set this options, it will replace default `fast-glob` pattern, it's default value
161 | is `['**/*.html', '!node_modules/**/*.html', '!.**/*.html']`
162 |
163 | ### injectCode
164 |
165 | [options](./src/html/types.ts#28)
166 |
167 | In html file, put `replacement`before/after `find`
168 |
169 | ### urlTransformer
170 |
171 | Allow plugin's user to fully customize the `url`, this is a function which has two param:(`resolvedUrl`,`req`)
172 |
173 | First param: `resolvedUrl` is a `string`, it means the plugin handles from `req` param.
174 |
175 | Second param : `req`, is a `http.IncommingMessage`
176 |
177 | This function must return a `string`
178 |
179 | ## NOTICE
180 |
181 | 1. if you use same `template` file for multiple page, please make sure the page's key is different.
182 | 2. please DO NOT use this plugin when you build a library(you can use this in dev NOT in build)
183 |
184 | ## Thanks
185 |
186 | 
187 |
--------------------------------------------------------------------------------
/README_ZH.md:
--------------------------------------------------------------------------------
1 | # vite-plugin-virtual-html
2 |
3 | ## 简介
4 |
5 | `Vite`的[多页面应用](https://cn.vitejs.dev/guide/build.html#multi-page-app)需要将`html`文件放到项目根目录或通过从根目录起的路径访问。
6 |
7 | 这会导致在开发和构建过程的`html`文件访问不一致.例如在开发时,你需要访问`/nested/a.html`,但是在构建后,你需要访问的时`/a.html`
8 |
9 | 所以,为了解决这个问题,需要在开发时对`html`请求进行拦截并返回相应的`html`内容
10 |
11 | 这个插件使用了以下的钩子:
12 |
13 | - 开发过程
14 | - `config`: 将下面的3个钩子注入到插件中
15 | - `configureServer`: 拦截并响应`html`请求, 处理`connect-history-api-fallback`的请求
16 | - `load`: 加载并处理`html`代码
17 | - `transform`: 在`html`文件中注入一些可配置的代码等
18 | - 构建过程
19 | - `config`: 将下面的3个钩子注入到插件中,并将`html`文件复制到项目根目录
20 | - `load`: 加载并处理`html`代码
21 | - `transform`: 在`html`文件中注入一些可配置的代码等
22 | - `closeBundle`: 移除在`config`中复制的`html`文件
23 |
24 | ## 更新信息
25 |
26 |
27 | ## 功能
28 | + 允许你将`html`文件放置到项目的任意位置(与`@vue/cli`的`pages`配置相同)
29 | + 当`dev`开发时,拦截`html`请求,然后将配置的相应的`html`文件内容返回给浏览器
30 | + 当`build`项目时,将配置的`html`文件复制到`dist`目录下,同时删除其他`html`文件及其目录
31 | + 自动配置`build.rollupOptions.input`
32 | + 如果你的`html`文件没有配置入口文件,则将会在`html`文件附近寻找与`html`文件同名的`js/ts`文件,并将其添加到`html`的文件内容中
33 |
34 | ## 使用方法
35 |
36 | `pnpm install vite-plugin-virtual-html -D`
37 |
38 | 在`vite.config.ts`中配置插件
39 |
40 | ``` typescript
41 | // vite.config.ts
42 | const virtualHtml from 'vite-plugin-virtual-html'
43 |
44 | const pages = {
45 | index: '/src/index/index.html',
46 | login: '/src/login/login.html',
47 | }
48 |
49 | module.exports = {
50 | plugins: [
51 | virtualHtml({
52 | pages,
53 | })
54 | ],
55 | }
56 | ```
57 |
58 | **插件使用事项:**
59 |
60 | - 一定不要再编译库时使用这个插件!!!
61 |
62 | ## 配置
63 |
64 | ### pages
65 |
66 | 配置项目的html文件路径
67 |
68 | `pages`可配置为[Pages](./src/html/types.ts#33)对象或`true`
69 |
70 | 当配置为`true`时,会根据`extraGlobPattern`的配置自动读取项目中的`html`文件路径并生成`pages`对象
71 |
72 | **注意:**
73 |
74 | - `entry`与`template`目前不能同时使用
75 |
76 |
77 | ### extraGlobPattern
78 |
79 | 仅`pages`为`true`时可用,默认值为
80 | ```
81 | '**/*.html',
82 | '!node_modules/**/*.html',
83 | '!.**/*.html'
84 | ```
85 |
86 | ### indexPage
87 |
88 | 指定当访问`index`或`/`页面时应当返回`pages`中的哪一个`html`文件的内容
89 |
90 | ### render, data
91 |
92 | 自定义全局模版渲染函数及渲染时使用的数据
93 |
94 | **注意:**
95 |
96 | - 目前我只测试了`ejs`,其他模版系统应该也可以正常工作
97 |
98 | ### injectCode
99 |
100 | 将配置的`replacement`放到`find`前面或后面
101 |
102 | ### rewrites
103 |
104 | 处理`connect-history-api-fallback`的重写请求
105 |
106 | ### urlTransformer
107 |
108 | 完全由开发者自定义处理`dev-server`拦截到的url,传入的参数为(`resolvedUrl`,`req`)
109 |
110 | 其中,第一个参数是插件初步处理的`url`字符串, 第二个参数是一个`req`对象(`http.IncomingMessage`)
111 |
112 | 返回值为一个新的`url`字符串
113 |
--------------------------------------------------------------------------------
/demo/demo1/demo.vue:
--------------------------------------------------------------------------------
1 |
2 | demo1
3 |
4 |
5 |
13 |
--------------------------------------------------------------------------------
/demo/demo1/demo1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo
6 |
7 |
8 |
9 |
10 | <%= users.join(" | "); %>
11 | <%= include('/demo/partials/test') %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/demo/demo1/demo1.ts:
--------------------------------------------------------------------------------
1 | import {createApp} from 'vue'
2 | import demo from './demo.vue'
3 |
4 | createApp(demo).mount('#app')
5 |
--------------------------------------------------------------------------------
/demo/demo2/demo.ts:
--------------------------------------------------------------------------------
1 | import {createApp} from 'vue'
2 | import {createRouter,createWebHashHistory} from 'vue-router'
3 | import demo from './demo.vue'
4 |
5 | const router = createRouter({
6 | history: createWebHashHistory(),
7 | routes: [
8 | {
9 | path: '/',
10 | component: demo
11 | },
12 | {
13 | path: '/route1',
14 | component: ()=>import('./route/route1.vue')
15 | }
16 | ]
17 | })
18 | const app = createApp({})
19 | app.use(router)
20 | app.mount('#app')
21 |
--------------------------------------------------------------------------------
/demo/demo2/demo.vue:
--------------------------------------------------------------------------------
1 |
2 | demo2
3 |
4 |
5 |
13 |
--------------------------------------------------------------------------------
/demo/demo2/demo2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo
6 |
7 |
8 |
9 |
10 |
Hello App!
11 |
12 |
13 |
14 |
15 | Go to Home
16 | Go to About
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/demo2/route/route1.vue:
--------------------------------------------------------------------------------
1 |
2 | route1
3 |
4 |
5 |
15 |
16 |
--------------------------------------------------------------------------------
/demo/demoIndex1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demo
7 |
8 |
9 |
10 |
11 | demoIndex1
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/demo/demoIndex2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demo
7 |
8 |
9 |
10 |
11 | demoIndex2
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/demo/partials/test.ejs:
--------------------------------------------------------------------------------
1 | I am a test partial
--------------------------------------------------------------------------------
/demo/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 | <%- script; %>
7 |
8 |
9 | fdf
10 |
11 |
12 |
--------------------------------------------------------------------------------
/demo3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo
6 |
7 |
8 |
9 |
10 |
Hello App!
11 |
12 |
13 |
14 |
15 | Go to Home
16 | Go to About
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | login4
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vite-plugin-virtual-html",
3 | "version": "1.2.6",
4 | "description": "Vite plugin to load html anywhere",
5 | "type": "module",
6 | "main": "./dist/index.cjs",
7 | "module": "./dist/index.js",
8 | "types": "./dist/index.d.ts",
9 | "exports": {
10 | ".": {
11 | "import": "./dist/index.js"
12 | }
13 | },
14 | "scripts": {
15 | "build": "tsup && npm publish && git clean -f",
16 | "test:build": "vite build",
17 | "test:dev": "vite",
18 | "test": "vitest"
19 | },
20 | "files": [
21 | "dist"
22 | ],
23 | "keywords": [
24 | "vite-plugin",
25 | "virtual-html"
26 | ],
27 | "author": "windson",
28 | "license": "MIT",
29 | "repository": {
30 | "type": "git",
31 | "url": "git+https://github.com/Windson1806/vite-plugin-virtual-html.git"
32 | },
33 | "bugs": {
34 | "url": "https://github.com/Windson1806/vite-plugin-virtual-html/issues"
35 | },
36 | "homepage": "https://github.com/Windson1806/vite-plugin-virtual-html/",
37 | "devDependencies": {
38 | "@types/connect-history-api-fallback": "^1.5.4",
39 | "@types/debug": "^4.1.12",
40 | "@types/ejs": "^3.1.5",
41 | "@types/node": "^22.12.0",
42 | "@vitejs/plugin-vue": "^5.2.1",
43 | "@vue/compiler-sfc": "^3.5.13",
44 | "playwright-chromium": "^1.50.0",
45 | "tsup": "^8.3.6",
46 | "typescript": "^5.7.3",
47 | "vite-plugin-inspect": "^10.1.0",
48 | "vitest": "^3.0.4",
49 | "vue": "^3.5.13",
50 | "vue-router": "^4.5.0"
51 | },
52 | "dependencies": {
53 | "connect-history-api-fallback": "^2.0.0",
54 | "debug": "^4.3.7",
55 | "ejs": "^3.1.10",
56 | "fast-glob": "^3.3.3",
57 | "magic-string": "^0.30.11",
58 | "vite": "^6.0.11"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | connect-history-api-fallback:
12 | specifier: ^2.0.0
13 | version: 2.0.0
14 | debug:
15 | specifier: ^4.3.7
16 | version: 4.4.0
17 | ejs:
18 | specifier: ^3.1.10
19 | version: 3.1.10
20 | fast-glob:
21 | specifier: ^3.3.3
22 | version: 3.3.3
23 | magic-string:
24 | specifier: ^0.30.11
25 | version: 0.30.17
26 | vite:
27 | specifier: ^6.0.11
28 | version: 6.0.11(@types/node@22.12.0)
29 | devDependencies:
30 | '@types/connect-history-api-fallback':
31 | specifier: ^1.5.4
32 | version: 1.5.4
33 | '@types/debug':
34 | specifier: ^4.1.12
35 | version: 4.1.12
36 | '@types/ejs':
37 | specifier: ^3.1.5
38 | version: 3.1.5
39 | '@types/node':
40 | specifier: ^22.12.0
41 | version: 22.12.0
42 | '@vitejs/plugin-vue':
43 | specifier: ^5.2.1
44 | version: 5.2.1(vite@6.0.11(@types/node@22.12.0))(vue@3.5.13(typescript@5.7.3))
45 | '@vue/compiler-sfc':
46 | specifier: ^3.5.13
47 | version: 3.5.13
48 | playwright-chromium:
49 | specifier: ^1.50.0
50 | version: 1.50.0
51 | tsup:
52 | specifier: ^8.3.6
53 | version: 8.3.6(postcss@8.4.49)(typescript@5.7.3)
54 | typescript:
55 | specifier: ^5.7.3
56 | version: 5.7.3
57 | vite-plugin-inspect:
58 | specifier: ^10.1.0
59 | version: 10.1.0(vite@6.0.11(@types/node@22.12.0))
60 | vitest:
61 | specifier: ^3.0.4
62 | version: 3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)
63 | vue:
64 | specifier: ^3.5.13
65 | version: 3.5.13(typescript@5.7.3)
66 | vue-router:
67 | specifier: ^4.5.0
68 | version: 4.5.0(vue@3.5.13(typescript@5.7.3))
69 |
70 | packages:
71 |
72 | '@babel/helper-string-parser@7.25.9':
73 | resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
74 | engines: {node: '>=6.9.0'}
75 |
76 | '@babel/helper-validator-identifier@7.25.9':
77 | resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
78 | engines: {node: '>=6.9.0'}
79 |
80 | '@babel/parser@7.26.5':
81 | resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==}
82 | engines: {node: '>=6.0.0'}
83 | hasBin: true
84 |
85 | '@babel/types@7.26.5':
86 | resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==}
87 | engines: {node: '>=6.9.0'}
88 |
89 | '@esbuild/aix-ppc64@0.24.2':
90 | resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
91 | engines: {node: '>=18'}
92 | cpu: [ppc64]
93 | os: [aix]
94 |
95 | '@esbuild/android-arm64@0.24.2':
96 | resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
97 | engines: {node: '>=18'}
98 | cpu: [arm64]
99 | os: [android]
100 |
101 | '@esbuild/android-arm@0.24.2':
102 | resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
103 | engines: {node: '>=18'}
104 | cpu: [arm]
105 | os: [android]
106 |
107 | '@esbuild/android-x64@0.24.2':
108 | resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
109 | engines: {node: '>=18'}
110 | cpu: [x64]
111 | os: [android]
112 |
113 | '@esbuild/darwin-arm64@0.24.2':
114 | resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
115 | engines: {node: '>=18'}
116 | cpu: [arm64]
117 | os: [darwin]
118 |
119 | '@esbuild/darwin-x64@0.24.2':
120 | resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
121 | engines: {node: '>=18'}
122 | cpu: [x64]
123 | os: [darwin]
124 |
125 | '@esbuild/freebsd-arm64@0.24.2':
126 | resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
127 | engines: {node: '>=18'}
128 | cpu: [arm64]
129 | os: [freebsd]
130 |
131 | '@esbuild/freebsd-x64@0.24.2':
132 | resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
133 | engines: {node: '>=18'}
134 | cpu: [x64]
135 | os: [freebsd]
136 |
137 | '@esbuild/linux-arm64@0.24.2':
138 | resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
139 | engines: {node: '>=18'}
140 | cpu: [arm64]
141 | os: [linux]
142 |
143 | '@esbuild/linux-arm@0.24.2':
144 | resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
145 | engines: {node: '>=18'}
146 | cpu: [arm]
147 | os: [linux]
148 |
149 | '@esbuild/linux-ia32@0.24.2':
150 | resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
151 | engines: {node: '>=18'}
152 | cpu: [ia32]
153 | os: [linux]
154 |
155 | '@esbuild/linux-loong64@0.24.2':
156 | resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
157 | engines: {node: '>=18'}
158 | cpu: [loong64]
159 | os: [linux]
160 |
161 | '@esbuild/linux-mips64el@0.24.2':
162 | resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
163 | engines: {node: '>=18'}
164 | cpu: [mips64el]
165 | os: [linux]
166 |
167 | '@esbuild/linux-ppc64@0.24.2':
168 | resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
169 | engines: {node: '>=18'}
170 | cpu: [ppc64]
171 | os: [linux]
172 |
173 | '@esbuild/linux-riscv64@0.24.2':
174 | resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
175 | engines: {node: '>=18'}
176 | cpu: [riscv64]
177 | os: [linux]
178 |
179 | '@esbuild/linux-s390x@0.24.2':
180 | resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
181 | engines: {node: '>=18'}
182 | cpu: [s390x]
183 | os: [linux]
184 |
185 | '@esbuild/linux-x64@0.24.2':
186 | resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
187 | engines: {node: '>=18'}
188 | cpu: [x64]
189 | os: [linux]
190 |
191 | '@esbuild/netbsd-arm64@0.24.2':
192 | resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
193 | engines: {node: '>=18'}
194 | cpu: [arm64]
195 | os: [netbsd]
196 |
197 | '@esbuild/netbsd-x64@0.24.2':
198 | resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
199 | engines: {node: '>=18'}
200 | cpu: [x64]
201 | os: [netbsd]
202 |
203 | '@esbuild/openbsd-arm64@0.24.2':
204 | resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
205 | engines: {node: '>=18'}
206 | cpu: [arm64]
207 | os: [openbsd]
208 |
209 | '@esbuild/openbsd-x64@0.24.2':
210 | resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
211 | engines: {node: '>=18'}
212 | cpu: [x64]
213 | os: [openbsd]
214 |
215 | '@esbuild/sunos-x64@0.24.2':
216 | resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
217 | engines: {node: '>=18'}
218 | cpu: [x64]
219 | os: [sunos]
220 |
221 | '@esbuild/win32-arm64@0.24.2':
222 | resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
223 | engines: {node: '>=18'}
224 | cpu: [arm64]
225 | os: [win32]
226 |
227 | '@esbuild/win32-ia32@0.24.2':
228 | resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
229 | engines: {node: '>=18'}
230 | cpu: [ia32]
231 | os: [win32]
232 |
233 | '@esbuild/win32-x64@0.24.2':
234 | resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
235 | engines: {node: '>=18'}
236 | cpu: [x64]
237 | os: [win32]
238 |
239 | '@isaacs/cliui@8.0.2':
240 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
241 | engines: {node: '>=12'}
242 |
243 | '@jridgewell/gen-mapping@0.3.8':
244 | resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
245 | engines: {node: '>=6.0.0'}
246 |
247 | '@jridgewell/resolve-uri@3.1.2':
248 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
249 | engines: {node: '>=6.0.0'}
250 |
251 | '@jridgewell/set-array@1.2.1':
252 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
253 | engines: {node: '>=6.0.0'}
254 |
255 | '@jridgewell/sourcemap-codec@1.5.0':
256 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
257 |
258 | '@jridgewell/trace-mapping@0.3.25':
259 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
260 |
261 | '@nodelib/fs.scandir@2.1.5':
262 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
263 | engines: {node: '>= 8'}
264 |
265 | '@nodelib/fs.stat@2.0.5':
266 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
267 | engines: {node: '>= 8'}
268 |
269 | '@nodelib/fs.walk@1.2.8':
270 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
271 | engines: {node: '>= 8'}
272 |
273 | '@pkgjs/parseargs@0.11.0':
274 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
275 | engines: {node: '>=14'}
276 |
277 | '@polka/url@1.0.0-next.24':
278 | resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==}
279 |
280 | '@rollup/rollup-android-arm-eabi@4.30.1':
281 | resolution: {integrity: sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==}
282 | cpu: [arm]
283 | os: [android]
284 |
285 | '@rollup/rollup-android-arm64@4.30.1':
286 | resolution: {integrity: sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==}
287 | cpu: [arm64]
288 | os: [android]
289 |
290 | '@rollup/rollup-darwin-arm64@4.30.1':
291 | resolution: {integrity: sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==}
292 | cpu: [arm64]
293 | os: [darwin]
294 |
295 | '@rollup/rollup-darwin-x64@4.30.1':
296 | resolution: {integrity: sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==}
297 | cpu: [x64]
298 | os: [darwin]
299 |
300 | '@rollup/rollup-freebsd-arm64@4.30.1':
301 | resolution: {integrity: sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==}
302 | cpu: [arm64]
303 | os: [freebsd]
304 |
305 | '@rollup/rollup-freebsd-x64@4.30.1':
306 | resolution: {integrity: sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==}
307 | cpu: [x64]
308 | os: [freebsd]
309 |
310 | '@rollup/rollup-linux-arm-gnueabihf@4.30.1':
311 | resolution: {integrity: sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==}
312 | cpu: [arm]
313 | os: [linux]
314 |
315 | '@rollup/rollup-linux-arm-musleabihf@4.30.1':
316 | resolution: {integrity: sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==}
317 | cpu: [arm]
318 | os: [linux]
319 |
320 | '@rollup/rollup-linux-arm64-gnu@4.30.1':
321 | resolution: {integrity: sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==}
322 | cpu: [arm64]
323 | os: [linux]
324 |
325 | '@rollup/rollup-linux-arm64-musl@4.30.1':
326 | resolution: {integrity: sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==}
327 | cpu: [arm64]
328 | os: [linux]
329 |
330 | '@rollup/rollup-linux-loongarch64-gnu@4.30.1':
331 | resolution: {integrity: sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==}
332 | cpu: [loong64]
333 | os: [linux]
334 |
335 | '@rollup/rollup-linux-powerpc64le-gnu@4.30.1':
336 | resolution: {integrity: sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==}
337 | cpu: [ppc64]
338 | os: [linux]
339 |
340 | '@rollup/rollup-linux-riscv64-gnu@4.30.1':
341 | resolution: {integrity: sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==}
342 | cpu: [riscv64]
343 | os: [linux]
344 |
345 | '@rollup/rollup-linux-s390x-gnu@4.30.1':
346 | resolution: {integrity: sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==}
347 | cpu: [s390x]
348 | os: [linux]
349 |
350 | '@rollup/rollup-linux-x64-gnu@4.30.1':
351 | resolution: {integrity: sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==}
352 | cpu: [x64]
353 | os: [linux]
354 |
355 | '@rollup/rollup-linux-x64-musl@4.30.1':
356 | resolution: {integrity: sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==}
357 | cpu: [x64]
358 | os: [linux]
359 |
360 | '@rollup/rollup-win32-arm64-msvc@4.30.1':
361 | resolution: {integrity: sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==}
362 | cpu: [arm64]
363 | os: [win32]
364 |
365 | '@rollup/rollup-win32-ia32-msvc@4.30.1':
366 | resolution: {integrity: sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==}
367 | cpu: [ia32]
368 | os: [win32]
369 |
370 | '@rollup/rollup-win32-x64-msvc@4.30.1':
371 | resolution: {integrity: sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==}
372 | cpu: [x64]
373 | os: [win32]
374 |
375 | '@types/connect-history-api-fallback@1.5.4':
376 | resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==}
377 |
378 | '@types/debug@4.1.12':
379 | resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
380 |
381 | '@types/ejs@3.1.5':
382 | resolution: {integrity: sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==}
383 |
384 | '@types/estree@1.0.6':
385 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
386 |
387 | '@types/express-serve-static-core@4.17.33':
388 | resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==}
389 |
390 | '@types/ms@0.7.31':
391 | resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
392 |
393 | '@types/node@22.12.0':
394 | resolution: {integrity: sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==}
395 |
396 | '@types/qs@6.9.7':
397 | resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
398 |
399 | '@types/range-parser@1.2.4':
400 | resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
401 |
402 | '@vitejs/plugin-vue@5.2.1':
403 | resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
404 | engines: {node: ^18.0.0 || >=20.0.0}
405 | peerDependencies:
406 | vite: ^5.0.0 || ^6.0.0
407 | vue: ^3.2.25
408 |
409 | '@vitest/expect@3.0.4':
410 | resolution: {integrity: sha512-Nm5kJmYw6P2BxhJPkO3eKKhGYKRsnqJqf+r0yOGRKpEP+bSCBDsjXgiu1/5QFrnPMEgzfC38ZEjvCFgaNBC0Eg==}
411 |
412 | '@vitest/mocker@3.0.4':
413 | resolution: {integrity: sha512-gEef35vKafJlfQbnyOXZ0Gcr9IBUsMTyTLXsEQwuyYAerpHqvXhzdBnDFuHLpFqth3F7b6BaFr4qV/Cs1ULx5A==}
414 | peerDependencies:
415 | msw: ^2.4.9
416 | vite: ^5.0.0 || ^6.0.0
417 | peerDependenciesMeta:
418 | msw:
419 | optional: true
420 | vite:
421 | optional: true
422 |
423 | '@vitest/pretty-format@3.0.4':
424 | resolution: {integrity: sha512-ts0fba+dEhK2aC9PFuZ9LTpULHpY/nd6jhAQ5IMU7Gaj7crPCTdCFfgvXxruRBLFS+MLraicCuFXxISEq8C93g==}
425 |
426 | '@vitest/runner@3.0.4':
427 | resolution: {integrity: sha512-dKHzTQ7n9sExAcWH/0sh1elVgwc7OJ2lMOBrAm73J7AH6Pf9T12Zh3lNE1TETZaqrWFXtLlx3NVrLRb5hCK+iw==}
428 |
429 | '@vitest/snapshot@3.0.4':
430 | resolution: {integrity: sha512-+p5knMLwIk7lTQkM3NonZ9zBewzVp9EVkVpvNta0/PlFWpiqLaRcF4+33L1it3uRUCh0BGLOaXPPGEjNKfWb4w==}
431 |
432 | '@vitest/spy@3.0.4':
433 | resolution: {integrity: sha512-sXIMF0oauYyUy2hN49VFTYodzEAu744MmGcPR3ZBsPM20G+1/cSW/n1U+3Yu/zHxX2bIDe1oJASOkml+osTU6Q==}
434 |
435 | '@vitest/utils@3.0.4':
436 | resolution: {integrity: sha512-8BqC1ksYsHtbWH+DfpOAKrFw3jl3Uf9J7yeFh85Pz52IWuh1hBBtyfEbRNNZNjl8H8A5yMLH9/t+k7HIKzQcZQ==}
437 |
438 | '@vue/compiler-core@3.5.13':
439 | resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
440 |
441 | '@vue/compiler-dom@3.5.13':
442 | resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==}
443 |
444 | '@vue/compiler-sfc@3.5.13':
445 | resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==}
446 |
447 | '@vue/compiler-ssr@3.5.13':
448 | resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==}
449 |
450 | '@vue/devtools-api@6.6.4':
451 | resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
452 |
453 | '@vue/reactivity@3.5.13':
454 | resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==}
455 |
456 | '@vue/runtime-core@3.5.13':
457 | resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==}
458 |
459 | '@vue/runtime-dom@3.5.13':
460 | resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==}
461 |
462 | '@vue/server-renderer@3.5.13':
463 | resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==}
464 | peerDependencies:
465 | vue: 3.5.13
466 |
467 | '@vue/shared@3.5.13':
468 | resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
469 |
470 | ansi-regex@5.0.1:
471 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
472 | engines: {node: '>=8'}
473 |
474 | ansi-regex@6.1.0:
475 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
476 | engines: {node: '>=12'}
477 |
478 | ansi-styles@4.3.0:
479 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
480 | engines: {node: '>=8'}
481 |
482 | ansi-styles@6.2.1:
483 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
484 | engines: {node: '>=12'}
485 |
486 | any-promise@1.3.0:
487 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
488 |
489 | assertion-error@2.0.1:
490 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
491 | engines: {node: '>=12'}
492 |
493 | async@3.2.4:
494 | resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
495 |
496 | balanced-match@1.0.2:
497 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
498 |
499 | brace-expansion@1.1.11:
500 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
501 |
502 | brace-expansion@2.0.1:
503 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
504 |
505 | braces@3.0.3:
506 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
507 | engines: {node: '>=8'}
508 |
509 | bundle-name@4.1.0:
510 | resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
511 | engines: {node: '>=18'}
512 |
513 | bundle-require@5.1.0:
514 | resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
515 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
516 | peerDependencies:
517 | esbuild: '>=0.18'
518 |
519 | cac@6.7.14:
520 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
521 | engines: {node: '>=8'}
522 |
523 | chai@5.1.2:
524 | resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==}
525 | engines: {node: '>=12'}
526 |
527 | chalk@4.1.2:
528 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
529 | engines: {node: '>=10'}
530 |
531 | check-error@2.1.1:
532 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
533 | engines: {node: '>= 16'}
534 |
535 | chokidar@4.0.3:
536 | resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
537 | engines: {node: '>= 14.16.0'}
538 |
539 | color-convert@2.0.1:
540 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
541 | engines: {node: '>=7.0.0'}
542 |
543 | color-name@1.1.4:
544 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
545 |
546 | commander@4.1.1:
547 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
548 | engines: {node: '>= 6'}
549 |
550 | concat-map@0.0.1:
551 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
552 |
553 | connect-history-api-fallback@2.0.0:
554 | resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==}
555 | engines: {node: '>=0.8'}
556 |
557 | consola@3.4.0:
558 | resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==}
559 | engines: {node: ^14.18.0 || >=16.10.0}
560 |
561 | cross-spawn@7.0.3:
562 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
563 | engines: {node: '>= 8'}
564 |
565 | csstype@3.1.3:
566 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
567 |
568 | debug@4.4.0:
569 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
570 | engines: {node: '>=6.0'}
571 | peerDependencies:
572 | supports-color: '*'
573 | peerDependenciesMeta:
574 | supports-color:
575 | optional: true
576 |
577 | deep-eql@5.0.2:
578 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
579 | engines: {node: '>=6'}
580 |
581 | default-browser-id@5.0.0:
582 | resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==}
583 | engines: {node: '>=18'}
584 |
585 | default-browser@5.2.1:
586 | resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==}
587 | engines: {node: '>=18'}
588 |
589 | define-lazy-prop@3.0.0:
590 | resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
591 | engines: {node: '>=12'}
592 |
593 | eastasianwidth@0.2.0:
594 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
595 |
596 | ejs@3.1.10:
597 | resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
598 | engines: {node: '>=0.10.0'}
599 | hasBin: true
600 |
601 | emoji-regex@8.0.0:
602 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
603 |
604 | emoji-regex@9.2.2:
605 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
606 |
607 | entities@4.5.0:
608 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
609 | engines: {node: '>=0.12'}
610 |
611 | error-stack-parser-es@1.0.5:
612 | resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
613 |
614 | es-module-lexer@1.6.0:
615 | resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
616 |
617 | esbuild@0.24.2:
618 | resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
619 | engines: {node: '>=18'}
620 | hasBin: true
621 |
622 | estree-walker@2.0.2:
623 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
624 |
625 | estree-walker@3.0.3:
626 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
627 |
628 | expect-type@1.1.0:
629 | resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==}
630 | engines: {node: '>=12.0.0'}
631 |
632 | fast-glob@3.3.3:
633 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
634 | engines: {node: '>=8.6.0'}
635 |
636 | fastq@1.13.0:
637 | resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
638 |
639 | fdir@6.4.3:
640 | resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==}
641 | peerDependencies:
642 | picomatch: ^3 || ^4
643 | peerDependenciesMeta:
644 | picomatch:
645 | optional: true
646 |
647 | filelist@1.0.4:
648 | resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
649 |
650 | fill-range@7.1.1:
651 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
652 | engines: {node: '>=8'}
653 |
654 | foreground-child@3.3.0:
655 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
656 | engines: {node: '>=14'}
657 |
658 | fsevents@2.3.3:
659 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
660 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
661 | os: [darwin]
662 |
663 | glob-parent@5.1.2:
664 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
665 | engines: {node: '>= 6'}
666 |
667 | glob@10.4.5:
668 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
669 | hasBin: true
670 |
671 | has-flag@4.0.0:
672 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
673 | engines: {node: '>=8'}
674 |
675 | is-docker@3.0.0:
676 | resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
677 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
678 | hasBin: true
679 |
680 | is-extglob@2.1.1:
681 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
682 | engines: {node: '>=0.10.0'}
683 |
684 | is-fullwidth-code-point@3.0.0:
685 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
686 | engines: {node: '>=8'}
687 |
688 | is-glob@4.0.3:
689 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
690 | engines: {node: '>=0.10.0'}
691 |
692 | is-inside-container@1.0.0:
693 | resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
694 | engines: {node: '>=14.16'}
695 | hasBin: true
696 |
697 | is-number@7.0.0:
698 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
699 | engines: {node: '>=0.12.0'}
700 |
701 | is-wsl@3.1.0:
702 | resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
703 | engines: {node: '>=16'}
704 |
705 | isexe@2.0.0:
706 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
707 |
708 | jackspeak@3.4.3:
709 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
710 |
711 | jake@10.8.5:
712 | resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==}
713 | engines: {node: '>=10'}
714 | hasBin: true
715 |
716 | joycon@3.1.1:
717 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
718 | engines: {node: '>=10'}
719 |
720 | lilconfig@3.1.3:
721 | resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
722 | engines: {node: '>=14'}
723 |
724 | lines-and-columns@1.2.4:
725 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
726 |
727 | load-tsconfig@0.2.3:
728 | resolution: {integrity: sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ==}
729 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
730 |
731 | lodash.sortby@4.7.0:
732 | resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
733 |
734 | loupe@3.1.3:
735 | resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
736 |
737 | lru-cache@10.4.3:
738 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
739 |
740 | magic-string@0.30.17:
741 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
742 |
743 | merge2@1.4.1:
744 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
745 | engines: {node: '>= 8'}
746 |
747 | micromatch@4.0.8:
748 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
749 | engines: {node: '>=8.6'}
750 |
751 | minimatch@3.1.2:
752 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
753 |
754 | minimatch@5.1.1:
755 | resolution: {integrity: sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==}
756 | engines: {node: '>=10'}
757 |
758 | minimatch@9.0.5:
759 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
760 | engines: {node: '>=16 || 14 >=14.17'}
761 |
762 | minipass@7.1.2:
763 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
764 | engines: {node: '>=16 || 14 >=14.17'}
765 |
766 | mrmime@2.0.0:
767 | resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
768 | engines: {node: '>=10'}
769 |
770 | ms@2.1.3:
771 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
772 |
773 | mz@2.7.0:
774 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
775 |
776 | nanoid@3.3.7:
777 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
778 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
779 | hasBin: true
780 |
781 | object-assign@4.1.1:
782 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
783 | engines: {node: '>=0.10.0'}
784 |
785 | open@10.1.0:
786 | resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==}
787 | engines: {node: '>=18'}
788 |
789 | package-json-from-dist@1.0.1:
790 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
791 |
792 | path-key@3.1.1:
793 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
794 | engines: {node: '>=8'}
795 |
796 | path-scurry@1.11.1:
797 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
798 | engines: {node: '>=16 || 14 >=14.18'}
799 |
800 | pathe@2.0.2:
801 | resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==}
802 |
803 | pathval@2.0.0:
804 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
805 | engines: {node: '>= 14.16'}
806 |
807 | picocolors@1.1.1:
808 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
809 |
810 | picomatch@2.3.1:
811 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
812 | engines: {node: '>=8.6'}
813 |
814 | picomatch@4.0.2:
815 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
816 | engines: {node: '>=12'}
817 |
818 | pirates@4.0.5:
819 | resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
820 | engines: {node: '>= 6'}
821 |
822 | playwright-chromium@1.50.0:
823 | resolution: {integrity: sha512-gyI1ATjSCn0kCHCV8lGS65h0tRSlJvdlwgvXwY5EyUHW+YLPnOtnMaCiNmHgrcVK8ofsXWq3alaUfnmirNzBlA==}
824 | engines: {node: '>=18'}
825 | hasBin: true
826 |
827 | playwright-core@1.50.0:
828 | resolution: {integrity: sha512-CXkSSlr4JaZs2tZHI40DsZUN/NIwgaUPsyLuOAaIZp2CyF2sN5MM5NJsyB188lFSSozFxQ5fPT4qM+f0tH/6wQ==}
829 | engines: {node: '>=18'}
830 | hasBin: true
831 |
832 | postcss-load-config@6.0.1:
833 | resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
834 | engines: {node: '>= 18'}
835 | peerDependencies:
836 | jiti: '>=1.21.0'
837 | postcss: '>=8.0.9'
838 | tsx: ^4.8.1
839 | yaml: ^2.4.2
840 | peerDependenciesMeta:
841 | jiti:
842 | optional: true
843 | postcss:
844 | optional: true
845 | tsx:
846 | optional: true
847 | yaml:
848 | optional: true
849 |
850 | postcss@8.4.49:
851 | resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
852 | engines: {node: ^10 || ^12 || >=14}
853 |
854 | punycode@2.1.1:
855 | resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
856 | engines: {node: '>=6'}
857 |
858 | queue-microtask@1.2.3:
859 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
860 |
861 | readdirp@4.1.1:
862 | resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==}
863 | engines: {node: '>= 14.18.0'}
864 |
865 | resolve-from@5.0.0:
866 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
867 | engines: {node: '>=8'}
868 |
869 | reusify@1.0.4:
870 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
871 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
872 |
873 | rollup@4.30.1:
874 | resolution: {integrity: sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==}
875 | engines: {node: '>=18.0.0', npm: '>=8.0.0'}
876 | hasBin: true
877 |
878 | run-applescript@7.0.0:
879 | resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==}
880 | engines: {node: '>=18'}
881 |
882 | run-parallel@1.2.0:
883 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
884 |
885 | shebang-command@2.0.0:
886 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
887 | engines: {node: '>=8'}
888 |
889 | shebang-regex@3.0.0:
890 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
891 | engines: {node: '>=8'}
892 |
893 | siginfo@2.0.0:
894 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
895 |
896 | signal-exit@4.1.0:
897 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
898 | engines: {node: '>=14'}
899 |
900 | sirv@3.0.0:
901 | resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==}
902 | engines: {node: '>=18'}
903 |
904 | source-map-js@1.2.1:
905 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
906 | engines: {node: '>=0.10.0'}
907 |
908 | source-map@0.8.0-beta.0:
909 | resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
910 | engines: {node: '>= 8'}
911 |
912 | stackback@0.0.2:
913 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
914 |
915 | std-env@3.8.0:
916 | resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
917 |
918 | string-width@4.2.3:
919 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
920 | engines: {node: '>=8'}
921 |
922 | string-width@5.1.2:
923 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
924 | engines: {node: '>=12'}
925 |
926 | strip-ansi@6.0.1:
927 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
928 | engines: {node: '>=8'}
929 |
930 | strip-ansi@7.1.0:
931 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
932 | engines: {node: '>=12'}
933 |
934 | sucrase@3.35.0:
935 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
936 | engines: {node: '>=16 || 14 >=14.17'}
937 | hasBin: true
938 |
939 | supports-color@7.2.0:
940 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
941 | engines: {node: '>=8'}
942 |
943 | thenify-all@1.6.0:
944 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
945 | engines: {node: '>=0.8'}
946 |
947 | thenify@3.3.1:
948 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
949 |
950 | tinybench@2.9.0:
951 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
952 |
953 | tinyexec@0.3.2:
954 | resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
955 |
956 | tinyglobby@0.2.10:
957 | resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==}
958 | engines: {node: '>=12.0.0'}
959 |
960 | tinypool@1.0.2:
961 | resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
962 | engines: {node: ^18.0.0 || >=20.0.0}
963 |
964 | tinyrainbow@2.0.0:
965 | resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
966 | engines: {node: '>=14.0.0'}
967 |
968 | tinyspy@3.0.2:
969 | resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
970 | engines: {node: '>=14.0.0'}
971 |
972 | to-regex-range@5.0.1:
973 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
974 | engines: {node: '>=8.0'}
975 |
976 | totalist@3.0.0:
977 | resolution: {integrity: sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==}
978 | engines: {node: '>=6'}
979 |
980 | tr46@1.0.1:
981 | resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
982 |
983 | tree-kill@1.2.2:
984 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
985 | hasBin: true
986 |
987 | ts-interface-checker@0.1.13:
988 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
989 |
990 | tsup@8.3.6:
991 | resolution: {integrity: sha512-XkVtlDV/58S9Ye0JxUUTcrQk4S+EqlOHKzg6Roa62rdjL1nGWNUstG0xgI4vanHdfIpjP448J8vlN0oK6XOJ5g==}
992 | engines: {node: '>=18'}
993 | hasBin: true
994 | peerDependencies:
995 | '@microsoft/api-extractor': ^7.36.0
996 | '@swc/core': ^1
997 | postcss: ^8.4.12
998 | typescript: '>=4.5.0'
999 | peerDependenciesMeta:
1000 | '@microsoft/api-extractor':
1001 | optional: true
1002 | '@swc/core':
1003 | optional: true
1004 | postcss:
1005 | optional: true
1006 | typescript:
1007 | optional: true
1008 |
1009 | typescript@5.7.3:
1010 | resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
1011 | engines: {node: '>=14.17'}
1012 | hasBin: true
1013 |
1014 | undici-types@6.20.0:
1015 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
1016 |
1017 | vite-node@3.0.4:
1018 | resolution: {integrity: sha512-7JZKEzcYV2Nx3u6rlvN8qdo3QV7Fxyt6hx+CCKz9fbWxdX5IvUOmTWEAxMrWxaiSf7CKGLJQ5rFu8prb/jBjOA==}
1019 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1020 | hasBin: true
1021 |
1022 | vite-plugin-inspect@10.1.0:
1023 | resolution: {integrity: sha512-solJQhkZULyR7Qq2CRGbO/8ijNPTwmxxLDMx3FkMzGQAuVqKrgqmV2cw/u8SXBsKDHgSMykipW+78MBMZz3O0g==}
1024 | engines: {node: '>=14'}
1025 | peerDependencies:
1026 | '@nuxt/kit': '*'
1027 | vite: ^6.0.0
1028 | peerDependenciesMeta:
1029 | '@nuxt/kit':
1030 | optional: true
1031 |
1032 | vite@6.0.11:
1033 | resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
1034 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1035 | hasBin: true
1036 | peerDependencies:
1037 | '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
1038 | jiti: '>=1.21.0'
1039 | less: '*'
1040 | lightningcss: ^1.21.0
1041 | sass: '*'
1042 | sass-embedded: '*'
1043 | stylus: '*'
1044 | sugarss: '*'
1045 | terser: ^5.16.0
1046 | tsx: ^4.8.1
1047 | yaml: ^2.4.2
1048 | peerDependenciesMeta:
1049 | '@types/node':
1050 | optional: true
1051 | jiti:
1052 | optional: true
1053 | less:
1054 | optional: true
1055 | lightningcss:
1056 | optional: true
1057 | sass:
1058 | optional: true
1059 | sass-embedded:
1060 | optional: true
1061 | stylus:
1062 | optional: true
1063 | sugarss:
1064 | optional: true
1065 | terser:
1066 | optional: true
1067 | tsx:
1068 | optional: true
1069 | yaml:
1070 | optional: true
1071 |
1072 | vitest@3.0.4:
1073 | resolution: {integrity: sha512-6XG8oTKy2gnJIFTHP6LD7ExFeNLxiTkK3CfMvT7IfR8IN+BYICCf0lXUQmX7i7JoxUP8QmeP4mTnWXgflu4yjw==}
1074 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1075 | hasBin: true
1076 | peerDependencies:
1077 | '@edge-runtime/vm': '*'
1078 | '@types/debug': ^4.1.12
1079 | '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
1080 | '@vitest/browser': 3.0.4
1081 | '@vitest/ui': 3.0.4
1082 | happy-dom: '*'
1083 | jsdom: '*'
1084 | peerDependenciesMeta:
1085 | '@edge-runtime/vm':
1086 | optional: true
1087 | '@types/debug':
1088 | optional: true
1089 | '@types/node':
1090 | optional: true
1091 | '@vitest/browser':
1092 | optional: true
1093 | '@vitest/ui':
1094 | optional: true
1095 | happy-dom:
1096 | optional: true
1097 | jsdom:
1098 | optional: true
1099 |
1100 | vue-router@4.5.0:
1101 | resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==}
1102 | peerDependencies:
1103 | vue: ^3.2.0
1104 |
1105 | vue@3.5.13:
1106 | resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==}
1107 | peerDependencies:
1108 | typescript: '*'
1109 | peerDependenciesMeta:
1110 | typescript:
1111 | optional: true
1112 |
1113 | webidl-conversions@4.0.2:
1114 | resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
1115 |
1116 | whatwg-url@7.1.0:
1117 | resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
1118 |
1119 | which@2.0.2:
1120 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1121 | engines: {node: '>= 8'}
1122 | hasBin: true
1123 |
1124 | why-is-node-running@2.3.0:
1125 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
1126 | engines: {node: '>=8'}
1127 | hasBin: true
1128 |
1129 | wrap-ansi@7.0.0:
1130 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1131 | engines: {node: '>=10'}
1132 |
1133 | wrap-ansi@8.1.0:
1134 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
1135 | engines: {node: '>=12'}
1136 |
1137 | snapshots:
1138 |
1139 | '@babel/helper-string-parser@7.25.9': {}
1140 |
1141 | '@babel/helper-validator-identifier@7.25.9': {}
1142 |
1143 | '@babel/parser@7.26.5':
1144 | dependencies:
1145 | '@babel/types': 7.26.5
1146 |
1147 | '@babel/types@7.26.5':
1148 | dependencies:
1149 | '@babel/helper-string-parser': 7.25.9
1150 | '@babel/helper-validator-identifier': 7.25.9
1151 |
1152 | '@esbuild/aix-ppc64@0.24.2':
1153 | optional: true
1154 |
1155 | '@esbuild/android-arm64@0.24.2':
1156 | optional: true
1157 |
1158 | '@esbuild/android-arm@0.24.2':
1159 | optional: true
1160 |
1161 | '@esbuild/android-x64@0.24.2':
1162 | optional: true
1163 |
1164 | '@esbuild/darwin-arm64@0.24.2':
1165 | optional: true
1166 |
1167 | '@esbuild/darwin-x64@0.24.2':
1168 | optional: true
1169 |
1170 | '@esbuild/freebsd-arm64@0.24.2':
1171 | optional: true
1172 |
1173 | '@esbuild/freebsd-x64@0.24.2':
1174 | optional: true
1175 |
1176 | '@esbuild/linux-arm64@0.24.2':
1177 | optional: true
1178 |
1179 | '@esbuild/linux-arm@0.24.2':
1180 | optional: true
1181 |
1182 | '@esbuild/linux-ia32@0.24.2':
1183 | optional: true
1184 |
1185 | '@esbuild/linux-loong64@0.24.2':
1186 | optional: true
1187 |
1188 | '@esbuild/linux-mips64el@0.24.2':
1189 | optional: true
1190 |
1191 | '@esbuild/linux-ppc64@0.24.2':
1192 | optional: true
1193 |
1194 | '@esbuild/linux-riscv64@0.24.2':
1195 | optional: true
1196 |
1197 | '@esbuild/linux-s390x@0.24.2':
1198 | optional: true
1199 |
1200 | '@esbuild/linux-x64@0.24.2':
1201 | optional: true
1202 |
1203 | '@esbuild/netbsd-arm64@0.24.2':
1204 | optional: true
1205 |
1206 | '@esbuild/netbsd-x64@0.24.2':
1207 | optional: true
1208 |
1209 | '@esbuild/openbsd-arm64@0.24.2':
1210 | optional: true
1211 |
1212 | '@esbuild/openbsd-x64@0.24.2':
1213 | optional: true
1214 |
1215 | '@esbuild/sunos-x64@0.24.2':
1216 | optional: true
1217 |
1218 | '@esbuild/win32-arm64@0.24.2':
1219 | optional: true
1220 |
1221 | '@esbuild/win32-ia32@0.24.2':
1222 | optional: true
1223 |
1224 | '@esbuild/win32-x64@0.24.2':
1225 | optional: true
1226 |
1227 | '@isaacs/cliui@8.0.2':
1228 | dependencies:
1229 | string-width: 5.1.2
1230 | string-width-cjs: string-width@4.2.3
1231 | strip-ansi: 7.1.0
1232 | strip-ansi-cjs: strip-ansi@6.0.1
1233 | wrap-ansi: 8.1.0
1234 | wrap-ansi-cjs: wrap-ansi@7.0.0
1235 |
1236 | '@jridgewell/gen-mapping@0.3.8':
1237 | dependencies:
1238 | '@jridgewell/set-array': 1.2.1
1239 | '@jridgewell/sourcemap-codec': 1.5.0
1240 | '@jridgewell/trace-mapping': 0.3.25
1241 |
1242 | '@jridgewell/resolve-uri@3.1.2': {}
1243 |
1244 | '@jridgewell/set-array@1.2.1': {}
1245 |
1246 | '@jridgewell/sourcemap-codec@1.5.0': {}
1247 |
1248 | '@jridgewell/trace-mapping@0.3.25':
1249 | dependencies:
1250 | '@jridgewell/resolve-uri': 3.1.2
1251 | '@jridgewell/sourcemap-codec': 1.5.0
1252 |
1253 | '@nodelib/fs.scandir@2.1.5':
1254 | dependencies:
1255 | '@nodelib/fs.stat': 2.0.5
1256 | run-parallel: 1.2.0
1257 |
1258 | '@nodelib/fs.stat@2.0.5': {}
1259 |
1260 | '@nodelib/fs.walk@1.2.8':
1261 | dependencies:
1262 | '@nodelib/fs.scandir': 2.1.5
1263 | fastq: 1.13.0
1264 |
1265 | '@pkgjs/parseargs@0.11.0':
1266 | optional: true
1267 |
1268 | '@polka/url@1.0.0-next.24': {}
1269 |
1270 | '@rollup/rollup-android-arm-eabi@4.30.1':
1271 | optional: true
1272 |
1273 | '@rollup/rollup-android-arm64@4.30.1':
1274 | optional: true
1275 |
1276 | '@rollup/rollup-darwin-arm64@4.30.1':
1277 | optional: true
1278 |
1279 | '@rollup/rollup-darwin-x64@4.30.1':
1280 | optional: true
1281 |
1282 | '@rollup/rollup-freebsd-arm64@4.30.1':
1283 | optional: true
1284 |
1285 | '@rollup/rollup-freebsd-x64@4.30.1':
1286 | optional: true
1287 |
1288 | '@rollup/rollup-linux-arm-gnueabihf@4.30.1':
1289 | optional: true
1290 |
1291 | '@rollup/rollup-linux-arm-musleabihf@4.30.1':
1292 | optional: true
1293 |
1294 | '@rollup/rollup-linux-arm64-gnu@4.30.1':
1295 | optional: true
1296 |
1297 | '@rollup/rollup-linux-arm64-musl@4.30.1':
1298 | optional: true
1299 |
1300 | '@rollup/rollup-linux-loongarch64-gnu@4.30.1':
1301 | optional: true
1302 |
1303 | '@rollup/rollup-linux-powerpc64le-gnu@4.30.1':
1304 | optional: true
1305 |
1306 | '@rollup/rollup-linux-riscv64-gnu@4.30.1':
1307 | optional: true
1308 |
1309 | '@rollup/rollup-linux-s390x-gnu@4.30.1':
1310 | optional: true
1311 |
1312 | '@rollup/rollup-linux-x64-gnu@4.30.1':
1313 | optional: true
1314 |
1315 | '@rollup/rollup-linux-x64-musl@4.30.1':
1316 | optional: true
1317 |
1318 | '@rollup/rollup-win32-arm64-msvc@4.30.1':
1319 | optional: true
1320 |
1321 | '@rollup/rollup-win32-ia32-msvc@4.30.1':
1322 | optional: true
1323 |
1324 | '@rollup/rollup-win32-x64-msvc@4.30.1':
1325 | optional: true
1326 |
1327 | '@types/connect-history-api-fallback@1.5.4':
1328 | dependencies:
1329 | '@types/express-serve-static-core': 4.17.33
1330 | '@types/node': 22.12.0
1331 |
1332 | '@types/debug@4.1.12':
1333 | dependencies:
1334 | '@types/ms': 0.7.31
1335 |
1336 | '@types/ejs@3.1.5': {}
1337 |
1338 | '@types/estree@1.0.6': {}
1339 |
1340 | '@types/express-serve-static-core@4.17.33':
1341 | dependencies:
1342 | '@types/node': 22.12.0
1343 | '@types/qs': 6.9.7
1344 | '@types/range-parser': 1.2.4
1345 |
1346 | '@types/ms@0.7.31': {}
1347 |
1348 | '@types/node@22.12.0':
1349 | dependencies:
1350 | undici-types: 6.20.0
1351 |
1352 | '@types/qs@6.9.7': {}
1353 |
1354 | '@types/range-parser@1.2.4': {}
1355 |
1356 | '@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.12.0))(vue@3.5.13(typescript@5.7.3))':
1357 | dependencies:
1358 | vite: 6.0.11(@types/node@22.12.0)
1359 | vue: 3.5.13(typescript@5.7.3)
1360 |
1361 | '@vitest/expect@3.0.4':
1362 | dependencies:
1363 | '@vitest/spy': 3.0.4
1364 | '@vitest/utils': 3.0.4
1365 | chai: 5.1.2
1366 | tinyrainbow: 2.0.0
1367 |
1368 | '@vitest/mocker@3.0.4(vite@6.0.11(@types/node@22.12.0))':
1369 | dependencies:
1370 | '@vitest/spy': 3.0.4
1371 | estree-walker: 3.0.3
1372 | magic-string: 0.30.17
1373 | optionalDependencies:
1374 | vite: 6.0.11(@types/node@22.12.0)
1375 |
1376 | '@vitest/pretty-format@3.0.4':
1377 | dependencies:
1378 | tinyrainbow: 2.0.0
1379 |
1380 | '@vitest/runner@3.0.4':
1381 | dependencies:
1382 | '@vitest/utils': 3.0.4
1383 | pathe: 2.0.2
1384 |
1385 | '@vitest/snapshot@3.0.4':
1386 | dependencies:
1387 | '@vitest/pretty-format': 3.0.4
1388 | magic-string: 0.30.17
1389 | pathe: 2.0.2
1390 |
1391 | '@vitest/spy@3.0.4':
1392 | dependencies:
1393 | tinyspy: 3.0.2
1394 |
1395 | '@vitest/utils@3.0.4':
1396 | dependencies:
1397 | '@vitest/pretty-format': 3.0.4
1398 | loupe: 3.1.3
1399 | tinyrainbow: 2.0.0
1400 |
1401 | '@vue/compiler-core@3.5.13':
1402 | dependencies:
1403 | '@babel/parser': 7.26.5
1404 | '@vue/shared': 3.5.13
1405 | entities: 4.5.0
1406 | estree-walker: 2.0.2
1407 | source-map-js: 1.2.1
1408 |
1409 | '@vue/compiler-dom@3.5.13':
1410 | dependencies:
1411 | '@vue/compiler-core': 3.5.13
1412 | '@vue/shared': 3.5.13
1413 |
1414 | '@vue/compiler-sfc@3.5.13':
1415 | dependencies:
1416 | '@babel/parser': 7.26.5
1417 | '@vue/compiler-core': 3.5.13
1418 | '@vue/compiler-dom': 3.5.13
1419 | '@vue/compiler-ssr': 3.5.13
1420 | '@vue/shared': 3.5.13
1421 | estree-walker: 2.0.2
1422 | magic-string: 0.30.17
1423 | postcss: 8.4.49
1424 | source-map-js: 1.2.1
1425 |
1426 | '@vue/compiler-ssr@3.5.13':
1427 | dependencies:
1428 | '@vue/compiler-dom': 3.5.13
1429 | '@vue/shared': 3.5.13
1430 |
1431 | '@vue/devtools-api@6.6.4': {}
1432 |
1433 | '@vue/reactivity@3.5.13':
1434 | dependencies:
1435 | '@vue/shared': 3.5.13
1436 |
1437 | '@vue/runtime-core@3.5.13':
1438 | dependencies:
1439 | '@vue/reactivity': 3.5.13
1440 | '@vue/shared': 3.5.13
1441 |
1442 | '@vue/runtime-dom@3.5.13':
1443 | dependencies:
1444 | '@vue/reactivity': 3.5.13
1445 | '@vue/runtime-core': 3.5.13
1446 | '@vue/shared': 3.5.13
1447 | csstype: 3.1.3
1448 |
1449 | '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.7.3))':
1450 | dependencies:
1451 | '@vue/compiler-ssr': 3.5.13
1452 | '@vue/shared': 3.5.13
1453 | vue: 3.5.13(typescript@5.7.3)
1454 |
1455 | '@vue/shared@3.5.13': {}
1456 |
1457 | ansi-regex@5.0.1: {}
1458 |
1459 | ansi-regex@6.1.0: {}
1460 |
1461 | ansi-styles@4.3.0:
1462 | dependencies:
1463 | color-convert: 2.0.1
1464 |
1465 | ansi-styles@6.2.1: {}
1466 |
1467 | any-promise@1.3.0: {}
1468 |
1469 | assertion-error@2.0.1: {}
1470 |
1471 | async@3.2.4: {}
1472 |
1473 | balanced-match@1.0.2: {}
1474 |
1475 | brace-expansion@1.1.11:
1476 | dependencies:
1477 | balanced-match: 1.0.2
1478 | concat-map: 0.0.1
1479 |
1480 | brace-expansion@2.0.1:
1481 | dependencies:
1482 | balanced-match: 1.0.2
1483 |
1484 | braces@3.0.3:
1485 | dependencies:
1486 | fill-range: 7.1.1
1487 |
1488 | bundle-name@4.1.0:
1489 | dependencies:
1490 | run-applescript: 7.0.0
1491 |
1492 | bundle-require@5.1.0(esbuild@0.24.2):
1493 | dependencies:
1494 | esbuild: 0.24.2
1495 | load-tsconfig: 0.2.3
1496 |
1497 | cac@6.7.14: {}
1498 |
1499 | chai@5.1.2:
1500 | dependencies:
1501 | assertion-error: 2.0.1
1502 | check-error: 2.1.1
1503 | deep-eql: 5.0.2
1504 | loupe: 3.1.3
1505 | pathval: 2.0.0
1506 |
1507 | chalk@4.1.2:
1508 | dependencies:
1509 | ansi-styles: 4.3.0
1510 | supports-color: 7.2.0
1511 |
1512 | check-error@2.1.1: {}
1513 |
1514 | chokidar@4.0.3:
1515 | dependencies:
1516 | readdirp: 4.1.1
1517 |
1518 | color-convert@2.0.1:
1519 | dependencies:
1520 | color-name: 1.1.4
1521 |
1522 | color-name@1.1.4: {}
1523 |
1524 | commander@4.1.1: {}
1525 |
1526 | concat-map@0.0.1: {}
1527 |
1528 | connect-history-api-fallback@2.0.0: {}
1529 |
1530 | consola@3.4.0: {}
1531 |
1532 | cross-spawn@7.0.3:
1533 | dependencies:
1534 | path-key: 3.1.1
1535 | shebang-command: 2.0.0
1536 | which: 2.0.2
1537 |
1538 | csstype@3.1.3: {}
1539 |
1540 | debug@4.4.0:
1541 | dependencies:
1542 | ms: 2.1.3
1543 |
1544 | deep-eql@5.0.2: {}
1545 |
1546 | default-browser-id@5.0.0: {}
1547 |
1548 | default-browser@5.2.1:
1549 | dependencies:
1550 | bundle-name: 4.1.0
1551 | default-browser-id: 5.0.0
1552 |
1553 | define-lazy-prop@3.0.0: {}
1554 |
1555 | eastasianwidth@0.2.0: {}
1556 |
1557 | ejs@3.1.10:
1558 | dependencies:
1559 | jake: 10.8.5
1560 |
1561 | emoji-regex@8.0.0: {}
1562 |
1563 | emoji-regex@9.2.2: {}
1564 |
1565 | entities@4.5.0: {}
1566 |
1567 | error-stack-parser-es@1.0.5: {}
1568 |
1569 | es-module-lexer@1.6.0: {}
1570 |
1571 | esbuild@0.24.2:
1572 | optionalDependencies:
1573 | '@esbuild/aix-ppc64': 0.24.2
1574 | '@esbuild/android-arm': 0.24.2
1575 | '@esbuild/android-arm64': 0.24.2
1576 | '@esbuild/android-x64': 0.24.2
1577 | '@esbuild/darwin-arm64': 0.24.2
1578 | '@esbuild/darwin-x64': 0.24.2
1579 | '@esbuild/freebsd-arm64': 0.24.2
1580 | '@esbuild/freebsd-x64': 0.24.2
1581 | '@esbuild/linux-arm': 0.24.2
1582 | '@esbuild/linux-arm64': 0.24.2
1583 | '@esbuild/linux-ia32': 0.24.2
1584 | '@esbuild/linux-loong64': 0.24.2
1585 | '@esbuild/linux-mips64el': 0.24.2
1586 | '@esbuild/linux-ppc64': 0.24.2
1587 | '@esbuild/linux-riscv64': 0.24.2
1588 | '@esbuild/linux-s390x': 0.24.2
1589 | '@esbuild/linux-x64': 0.24.2
1590 | '@esbuild/netbsd-arm64': 0.24.2
1591 | '@esbuild/netbsd-x64': 0.24.2
1592 | '@esbuild/openbsd-arm64': 0.24.2
1593 | '@esbuild/openbsd-x64': 0.24.2
1594 | '@esbuild/sunos-x64': 0.24.2
1595 | '@esbuild/win32-arm64': 0.24.2
1596 | '@esbuild/win32-ia32': 0.24.2
1597 | '@esbuild/win32-x64': 0.24.2
1598 |
1599 | estree-walker@2.0.2: {}
1600 |
1601 | estree-walker@3.0.3:
1602 | dependencies:
1603 | '@types/estree': 1.0.6
1604 |
1605 | expect-type@1.1.0: {}
1606 |
1607 | fast-glob@3.3.3:
1608 | dependencies:
1609 | '@nodelib/fs.stat': 2.0.5
1610 | '@nodelib/fs.walk': 1.2.8
1611 | glob-parent: 5.1.2
1612 | merge2: 1.4.1
1613 | micromatch: 4.0.8
1614 |
1615 | fastq@1.13.0:
1616 | dependencies:
1617 | reusify: 1.0.4
1618 |
1619 | fdir@6.4.3(picomatch@4.0.2):
1620 | optionalDependencies:
1621 | picomatch: 4.0.2
1622 |
1623 | filelist@1.0.4:
1624 | dependencies:
1625 | minimatch: 5.1.1
1626 |
1627 | fill-range@7.1.1:
1628 | dependencies:
1629 | to-regex-range: 5.0.1
1630 |
1631 | foreground-child@3.3.0:
1632 | dependencies:
1633 | cross-spawn: 7.0.3
1634 | signal-exit: 4.1.0
1635 |
1636 | fsevents@2.3.3:
1637 | optional: true
1638 |
1639 | glob-parent@5.1.2:
1640 | dependencies:
1641 | is-glob: 4.0.3
1642 |
1643 | glob@10.4.5:
1644 | dependencies:
1645 | foreground-child: 3.3.0
1646 | jackspeak: 3.4.3
1647 | minimatch: 9.0.5
1648 | minipass: 7.1.2
1649 | package-json-from-dist: 1.0.1
1650 | path-scurry: 1.11.1
1651 |
1652 | has-flag@4.0.0: {}
1653 |
1654 | is-docker@3.0.0: {}
1655 |
1656 | is-extglob@2.1.1: {}
1657 |
1658 | is-fullwidth-code-point@3.0.0: {}
1659 |
1660 | is-glob@4.0.3:
1661 | dependencies:
1662 | is-extglob: 2.1.1
1663 |
1664 | is-inside-container@1.0.0:
1665 | dependencies:
1666 | is-docker: 3.0.0
1667 |
1668 | is-number@7.0.0: {}
1669 |
1670 | is-wsl@3.1.0:
1671 | dependencies:
1672 | is-inside-container: 1.0.0
1673 |
1674 | isexe@2.0.0: {}
1675 |
1676 | jackspeak@3.4.3:
1677 | dependencies:
1678 | '@isaacs/cliui': 8.0.2
1679 | optionalDependencies:
1680 | '@pkgjs/parseargs': 0.11.0
1681 |
1682 | jake@10.8.5:
1683 | dependencies:
1684 | async: 3.2.4
1685 | chalk: 4.1.2
1686 | filelist: 1.0.4
1687 | minimatch: 3.1.2
1688 |
1689 | joycon@3.1.1: {}
1690 |
1691 | lilconfig@3.1.3: {}
1692 |
1693 | lines-and-columns@1.2.4: {}
1694 |
1695 | load-tsconfig@0.2.3: {}
1696 |
1697 | lodash.sortby@4.7.0: {}
1698 |
1699 | loupe@3.1.3: {}
1700 |
1701 | lru-cache@10.4.3: {}
1702 |
1703 | magic-string@0.30.17:
1704 | dependencies:
1705 | '@jridgewell/sourcemap-codec': 1.5.0
1706 |
1707 | merge2@1.4.1: {}
1708 |
1709 | micromatch@4.0.8:
1710 | dependencies:
1711 | braces: 3.0.3
1712 | picomatch: 2.3.1
1713 |
1714 | minimatch@3.1.2:
1715 | dependencies:
1716 | brace-expansion: 1.1.11
1717 |
1718 | minimatch@5.1.1:
1719 | dependencies:
1720 | brace-expansion: 2.0.1
1721 |
1722 | minimatch@9.0.5:
1723 | dependencies:
1724 | brace-expansion: 2.0.1
1725 |
1726 | minipass@7.1.2: {}
1727 |
1728 | mrmime@2.0.0: {}
1729 |
1730 | ms@2.1.3: {}
1731 |
1732 | mz@2.7.0:
1733 | dependencies:
1734 | any-promise: 1.3.0
1735 | object-assign: 4.1.1
1736 | thenify-all: 1.6.0
1737 |
1738 | nanoid@3.3.7: {}
1739 |
1740 | object-assign@4.1.1: {}
1741 |
1742 | open@10.1.0:
1743 | dependencies:
1744 | default-browser: 5.2.1
1745 | define-lazy-prop: 3.0.0
1746 | is-inside-container: 1.0.0
1747 | is-wsl: 3.1.0
1748 |
1749 | package-json-from-dist@1.0.1: {}
1750 |
1751 | path-key@3.1.1: {}
1752 |
1753 | path-scurry@1.11.1:
1754 | dependencies:
1755 | lru-cache: 10.4.3
1756 | minipass: 7.1.2
1757 |
1758 | pathe@2.0.2: {}
1759 |
1760 | pathval@2.0.0: {}
1761 |
1762 | picocolors@1.1.1: {}
1763 |
1764 | picomatch@2.3.1: {}
1765 |
1766 | picomatch@4.0.2: {}
1767 |
1768 | pirates@4.0.5: {}
1769 |
1770 | playwright-chromium@1.50.0:
1771 | dependencies:
1772 | playwright-core: 1.50.0
1773 |
1774 | playwright-core@1.50.0: {}
1775 |
1776 | postcss-load-config@6.0.1(postcss@8.4.49):
1777 | dependencies:
1778 | lilconfig: 3.1.3
1779 | optionalDependencies:
1780 | postcss: 8.4.49
1781 |
1782 | postcss@8.4.49:
1783 | dependencies:
1784 | nanoid: 3.3.7
1785 | picocolors: 1.1.1
1786 | source-map-js: 1.2.1
1787 |
1788 | punycode@2.1.1: {}
1789 |
1790 | queue-microtask@1.2.3: {}
1791 |
1792 | readdirp@4.1.1: {}
1793 |
1794 | resolve-from@5.0.0: {}
1795 |
1796 | reusify@1.0.4: {}
1797 |
1798 | rollup@4.30.1:
1799 | dependencies:
1800 | '@types/estree': 1.0.6
1801 | optionalDependencies:
1802 | '@rollup/rollup-android-arm-eabi': 4.30.1
1803 | '@rollup/rollup-android-arm64': 4.30.1
1804 | '@rollup/rollup-darwin-arm64': 4.30.1
1805 | '@rollup/rollup-darwin-x64': 4.30.1
1806 | '@rollup/rollup-freebsd-arm64': 4.30.1
1807 | '@rollup/rollup-freebsd-x64': 4.30.1
1808 | '@rollup/rollup-linux-arm-gnueabihf': 4.30.1
1809 | '@rollup/rollup-linux-arm-musleabihf': 4.30.1
1810 | '@rollup/rollup-linux-arm64-gnu': 4.30.1
1811 | '@rollup/rollup-linux-arm64-musl': 4.30.1
1812 | '@rollup/rollup-linux-loongarch64-gnu': 4.30.1
1813 | '@rollup/rollup-linux-powerpc64le-gnu': 4.30.1
1814 | '@rollup/rollup-linux-riscv64-gnu': 4.30.1
1815 | '@rollup/rollup-linux-s390x-gnu': 4.30.1
1816 | '@rollup/rollup-linux-x64-gnu': 4.30.1
1817 | '@rollup/rollup-linux-x64-musl': 4.30.1
1818 | '@rollup/rollup-win32-arm64-msvc': 4.30.1
1819 | '@rollup/rollup-win32-ia32-msvc': 4.30.1
1820 | '@rollup/rollup-win32-x64-msvc': 4.30.1
1821 | fsevents: 2.3.3
1822 |
1823 | run-applescript@7.0.0: {}
1824 |
1825 | run-parallel@1.2.0:
1826 | dependencies:
1827 | queue-microtask: 1.2.3
1828 |
1829 | shebang-command@2.0.0:
1830 | dependencies:
1831 | shebang-regex: 3.0.0
1832 |
1833 | shebang-regex@3.0.0: {}
1834 |
1835 | siginfo@2.0.0: {}
1836 |
1837 | signal-exit@4.1.0: {}
1838 |
1839 | sirv@3.0.0:
1840 | dependencies:
1841 | '@polka/url': 1.0.0-next.24
1842 | mrmime: 2.0.0
1843 | totalist: 3.0.0
1844 |
1845 | source-map-js@1.2.1: {}
1846 |
1847 | source-map@0.8.0-beta.0:
1848 | dependencies:
1849 | whatwg-url: 7.1.0
1850 |
1851 | stackback@0.0.2: {}
1852 |
1853 | std-env@3.8.0: {}
1854 |
1855 | string-width@4.2.3:
1856 | dependencies:
1857 | emoji-regex: 8.0.0
1858 | is-fullwidth-code-point: 3.0.0
1859 | strip-ansi: 6.0.1
1860 |
1861 | string-width@5.1.2:
1862 | dependencies:
1863 | eastasianwidth: 0.2.0
1864 | emoji-regex: 9.2.2
1865 | strip-ansi: 7.1.0
1866 |
1867 | strip-ansi@6.0.1:
1868 | dependencies:
1869 | ansi-regex: 5.0.1
1870 |
1871 | strip-ansi@7.1.0:
1872 | dependencies:
1873 | ansi-regex: 6.1.0
1874 |
1875 | sucrase@3.35.0:
1876 | dependencies:
1877 | '@jridgewell/gen-mapping': 0.3.8
1878 | commander: 4.1.1
1879 | glob: 10.4.5
1880 | lines-and-columns: 1.2.4
1881 | mz: 2.7.0
1882 | pirates: 4.0.5
1883 | ts-interface-checker: 0.1.13
1884 |
1885 | supports-color@7.2.0:
1886 | dependencies:
1887 | has-flag: 4.0.0
1888 |
1889 | thenify-all@1.6.0:
1890 | dependencies:
1891 | thenify: 3.3.1
1892 |
1893 | thenify@3.3.1:
1894 | dependencies:
1895 | any-promise: 1.3.0
1896 |
1897 | tinybench@2.9.0: {}
1898 |
1899 | tinyexec@0.3.2: {}
1900 |
1901 | tinyglobby@0.2.10:
1902 | dependencies:
1903 | fdir: 6.4.3(picomatch@4.0.2)
1904 | picomatch: 4.0.2
1905 |
1906 | tinypool@1.0.2: {}
1907 |
1908 | tinyrainbow@2.0.0: {}
1909 |
1910 | tinyspy@3.0.2: {}
1911 |
1912 | to-regex-range@5.0.1:
1913 | dependencies:
1914 | is-number: 7.0.0
1915 |
1916 | totalist@3.0.0: {}
1917 |
1918 | tr46@1.0.1:
1919 | dependencies:
1920 | punycode: 2.1.1
1921 |
1922 | tree-kill@1.2.2: {}
1923 |
1924 | ts-interface-checker@0.1.13: {}
1925 |
1926 | tsup@8.3.6(postcss@8.4.49)(typescript@5.7.3):
1927 | dependencies:
1928 | bundle-require: 5.1.0(esbuild@0.24.2)
1929 | cac: 6.7.14
1930 | chokidar: 4.0.3
1931 | consola: 3.4.0
1932 | debug: 4.4.0
1933 | esbuild: 0.24.2
1934 | joycon: 3.1.1
1935 | picocolors: 1.1.1
1936 | postcss-load-config: 6.0.1(postcss@8.4.49)
1937 | resolve-from: 5.0.0
1938 | rollup: 4.30.1
1939 | source-map: 0.8.0-beta.0
1940 | sucrase: 3.35.0
1941 | tinyexec: 0.3.2
1942 | tinyglobby: 0.2.10
1943 | tree-kill: 1.2.2
1944 | optionalDependencies:
1945 | postcss: 8.4.49
1946 | typescript: 5.7.3
1947 | transitivePeerDependencies:
1948 | - jiti
1949 | - supports-color
1950 | - tsx
1951 | - yaml
1952 |
1953 | typescript@5.7.3: {}
1954 |
1955 | undici-types@6.20.0: {}
1956 |
1957 | vite-node@3.0.4(@types/node@22.12.0):
1958 | dependencies:
1959 | cac: 6.7.14
1960 | debug: 4.4.0
1961 | es-module-lexer: 1.6.0
1962 | pathe: 2.0.2
1963 | vite: 6.0.11(@types/node@22.12.0)
1964 | transitivePeerDependencies:
1965 | - '@types/node'
1966 | - jiti
1967 | - less
1968 | - lightningcss
1969 | - sass
1970 | - sass-embedded
1971 | - stylus
1972 | - sugarss
1973 | - supports-color
1974 | - terser
1975 | - tsx
1976 | - yaml
1977 |
1978 | vite-plugin-inspect@10.1.0(vite@6.0.11(@types/node@22.12.0)):
1979 | dependencies:
1980 | debug: 4.4.0
1981 | error-stack-parser-es: 1.0.5
1982 | open: 10.1.0
1983 | picocolors: 1.1.1
1984 | sirv: 3.0.0
1985 | vite: 6.0.11(@types/node@22.12.0)
1986 | transitivePeerDependencies:
1987 | - supports-color
1988 |
1989 | vite@6.0.11(@types/node@22.12.0):
1990 | dependencies:
1991 | esbuild: 0.24.2
1992 | postcss: 8.4.49
1993 | rollup: 4.30.1
1994 | optionalDependencies:
1995 | '@types/node': 22.12.0
1996 | fsevents: 2.3.3
1997 |
1998 | vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.12.0):
1999 | dependencies:
2000 | '@vitest/expect': 3.0.4
2001 | '@vitest/mocker': 3.0.4(vite@6.0.11(@types/node@22.12.0))
2002 | '@vitest/pretty-format': 3.0.4
2003 | '@vitest/runner': 3.0.4
2004 | '@vitest/snapshot': 3.0.4
2005 | '@vitest/spy': 3.0.4
2006 | '@vitest/utils': 3.0.4
2007 | chai: 5.1.2
2008 | debug: 4.4.0
2009 | expect-type: 1.1.0
2010 | magic-string: 0.30.17
2011 | pathe: 2.0.2
2012 | std-env: 3.8.0
2013 | tinybench: 2.9.0
2014 | tinyexec: 0.3.2
2015 | tinypool: 1.0.2
2016 | tinyrainbow: 2.0.0
2017 | vite: 6.0.11(@types/node@22.12.0)
2018 | vite-node: 3.0.4(@types/node@22.12.0)
2019 | why-is-node-running: 2.3.0
2020 | optionalDependencies:
2021 | '@types/debug': 4.1.12
2022 | '@types/node': 22.12.0
2023 | transitivePeerDependencies:
2024 | - jiti
2025 | - less
2026 | - lightningcss
2027 | - msw
2028 | - sass
2029 | - sass-embedded
2030 | - stylus
2031 | - sugarss
2032 | - supports-color
2033 | - terser
2034 | - tsx
2035 | - yaml
2036 |
2037 | vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)):
2038 | dependencies:
2039 | '@vue/devtools-api': 6.6.4
2040 | vue: 3.5.13(typescript@5.7.3)
2041 |
2042 | vue@3.5.13(typescript@5.7.3):
2043 | dependencies:
2044 | '@vue/compiler-dom': 3.5.13
2045 | '@vue/compiler-sfc': 3.5.13
2046 | '@vue/runtime-dom': 3.5.13
2047 | '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.7.3))
2048 | '@vue/shared': 3.5.13
2049 | optionalDependencies:
2050 | typescript: 5.7.3
2051 |
2052 | webidl-conversions@4.0.2: {}
2053 |
2054 | whatwg-url@7.1.0:
2055 | dependencies:
2056 | lodash.sortby: 4.7.0
2057 | tr46: 1.0.1
2058 | webidl-conversions: 4.0.2
2059 |
2060 | which@2.0.2:
2061 | dependencies:
2062 | isexe: 2.0.0
2063 |
2064 | why-is-node-running@2.3.0:
2065 | dependencies:
2066 | siginfo: 2.0.0
2067 | stackback: 0.0.2
2068 |
2069 | wrap-ansi@7.0.0:
2070 | dependencies:
2071 | ansi-styles: 4.3.0
2072 | string-width: 4.2.3
2073 | strip-ansi: 6.0.1
2074 |
2075 | wrap-ansi@8.1.0:
2076 | dependencies:
2077 | ansi-styles: 6.2.1
2078 | string-width: 5.1.2
2079 | strip-ansi: 7.1.0
2080 |
--------------------------------------------------------------------------------
/src/history-api/historyApiFallbackPlugin.ts:
--------------------------------------------------------------------------------
1 | import type { Connect, Plugin, ViteDevServer } from 'vite'
2 | import history from 'connect-history-api-fallback'
3 | import type { HistoryApiOptions, HistoryRewrites } from './types'
4 |
5 | // noinspection JSUnusedGlobalSymbols
6 | export const historyApiFallbackPlugin = (historyApiOptions: HistoryApiOptions): Plugin => {
7 | const {
8 | rewrites,
9 | usePreview
10 | } = historyApiOptions
11 | const configureServerHookName = usePreview ? 'configurePreviewServer' : 'configureServer'
12 | return {
13 | name: 'vite-plugin-virtual-html:history',
14 | [configureServerHookName](server: ViteDevServer) {
15 | if (rewrites) {
16 | buildHistoryApiFallback(server, rewrites)
17 | }
18 | },
19 | }
20 | }
21 |
22 | /**
23 | * build a server
24 | * @param server
25 | * @param rewrites
26 | */
27 | export function buildHistoryApiFallback(server: ViteDevServer, rewrites: Array) {
28 | server.middlewares.use(history({
29 | disableDotRule: undefined,
30 | htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
31 | rewrites: rewrites,
32 | }) as Connect.NextHandleFunction)
33 | }
34 |
--------------------------------------------------------------------------------
/src/history-api/types.ts:
--------------------------------------------------------------------------------
1 | import type {Rewrite} from 'connect-history-api-fallback'
2 | export type HistoryRewrites = Rewrite
3 |
4 | export type HistoryApiOptions = {
5 | /**
6 | * option to connect-history-api-fallback's rewrites
7 | */
8 | rewrites?: Array
9 | usePreview?: boolean
10 | }
11 |
--------------------------------------------------------------------------------
/src/html/Base.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | HtmlPluginOptions,
3 | InjectCode,
4 | PageObject,
5 | VirtualHtmlTemplateData,
6 | } from "./types";
7 | import {
8 | Pages,
9 | POS,
10 | VirtualHtmlPage,
11 | VirtualHtmlTemplateRender,
12 | VirtualPageOptions,
13 | } from "./types";
14 | import { createFilter, normalizePath, type UserConfig } from "vite";
15 | import * as path from "path";
16 | import * as fs from "fs";
17 | import glob from "fast-glob";
18 | import debug from "debug";
19 | import { createRequire } from "node:module";
20 | import MagicString from "magic-string";
21 |
22 | const _require =
23 | import.meta.url !== undefined ? createRequire(import.meta.url) : require;
24 |
25 | const fsp = fs.promises;
26 | const DEFAULT_GLOB_PATTERN = [
27 | "**/*.html",
28 | "!node_modules/**/*.html",
29 | "!.**/*.html",
30 | ];
31 |
32 | const VIRTUAL_HTML_CONTENT = new MagicString(`
33 |
34 |
35 |
36 |
37 | #TITLE#
38 |
39 |
40 |
41 | #BODY#
42 |
43 |
44 | `);
45 | export const DEFAULT_INJECTCODE_ALL = "*";
46 |
47 | export class Base {
48 | _config?: UserConfig;
49 |
50 | _pages: Pages;
51 |
52 | _indexPage: string;
53 |
54 | _globalRender: VirtualHtmlTemplateRender;
55 |
56 | _globalData: Record;
57 |
58 | _injectCode: Record;
59 |
60 | cwd = normalizePath(process.cwd());
61 | logger = debug("vite-plugin-virtual-html");
62 | _filter: (id: string | unknown) => boolean;
63 |
64 | constructor(virtualHtmlOptions: HtmlPluginOptions) {
65 | const {
66 | pages: pagesObj,
67 | indexPage = "index",
68 | render = this.defaultRender,
69 | data = {},
70 | extraGlobPattern = [],
71 | injectCode = {},
72 | cwd = normalizePath(process.cwd())
73 | } = virtualHtmlOptions;
74 | if (pagesObj === true || pagesObj === undefined) {
75 | this._pages = this.findAllHtmlInProject(extraGlobPattern);
76 | } else {
77 | this._pages = pagesObj;
78 | }
79 | this._indexPage = indexPage;
80 | this._globalData = data;
81 | this._globalRender = render;
82 | this._injectCode = injectCode;
83 | this._filter = createFilter(/\.html|\/$/);
84 | this.cwd = cwd
85 | }
86 |
87 | /**
88 | * load html file
89 | * @param args
90 | */
91 | _load = async (...args: [string, unknown]) => {
92 | const [id] = args;
93 | if (this._filter(id)) {
94 | let newId = this.getHtmlName(id, this._config?.root);
95 | const maybeIndexName1 = (newId + "/").replace("//", "/");
96 | const maybeIndexName2 = (newId + "/index").replace("//", "/");
97 | const maybeIndexName3 = newId.replace("index", "").replace("//", "/");
98 |
99 | const pageOption: VirtualHtmlPage | VirtualPageOptions =
100 | this._pages[newId] ||
101 | this._pages[maybeIndexName1] ||
102 | this._pages[maybeIndexName2] ||
103 | this._pages[maybeIndexName3];
104 | if (pageOption !== undefined) {
105 | // string
106 | if (typeof pageOption === "string") {
107 | const page = await this.generatePageOptions(
108 | pageOption,
109 | this._globalData,
110 | this._globalRender
111 | );
112 | // generate html template
113 | return await this.readHtml(page);
114 | }
115 | // PageObject
116 | if ("template" in pageOption) {
117 | const page = await this.generatePageOptions(
118 | pageOption,
119 | this._globalData,
120 | this._globalRender
121 | );
122 | // generate html template
123 | return await this.readHtml(page);
124 | }
125 | // VirtualPageOptions
126 | if ("entry" in pageOption) {
127 | return await this.generateVirtualPage(pageOption);
128 | }
129 | }
130 | }
131 | return undefined;
132 | };
133 |
134 | /**
135 | * transform code to inject some code into original code
136 | * @param args
137 | */
138 | _transform = async (
139 | ...args: [string, string, unknown]
140 | ): Promise => {
141 | const [code, id] = args;
142 | if (this._filter(id)) {
143 | const ids = id.split("/");
144 | const key = ids[ids.length - 1];
145 | let _code = code;
146 | if (DEFAULT_INJECTCODE_ALL in this._injectCode) {
147 | _code = this.generateInjectCode(
148 | this._injectCode[DEFAULT_INJECTCODE_ALL],
149 | _code
150 | );
151 | }
152 | if (key in this._injectCode) {
153 | _code = this.generateInjectCode(this._injectCode[key], _code);
154 | }
155 | return _code;
156 | }
157 | return null;
158 | };
159 |
160 | /**
161 | * get html file's name
162 | * @param id
163 | * @param root
164 | */
165 | getHtmlName = (id: string, root?: string) => {
166 | const _root = (root ?? "").replace(this.cwd, "");
167 | const _id = id.replace(this.cwd, "");
168 | const result = _id
169 | .replace(".html", "")
170 | .replace(_root !== "" ? this.addTrailingSlash(_root) : "", "");
171 | return result.startsWith("/") ? result.substring(1, result.length) : result;
172 | };
173 |
174 | /**
175 | * add trailing slash on path
176 | * @param {string} path
177 | * @returns {string}
178 | */
179 | addTrailingSlash = (path: string): string => {
180 | const _path = normalizePath(path.replace(this.cwd, ""));
181 | return _path.endsWith("/") ? _path : `${_path}/`;
182 | };
183 |
184 | /**
185 | * generate URL
186 | * @param url
187 | */
188 | generateUrl = (url?: string): string => {
189 | if (!url) {
190 | return "/";
191 | }
192 | // url with parameters
193 | if (url.indexOf("?") > 0) {
194 | return url.split("?")[0];
195 | }
196 | return url;
197 | };
198 |
199 | /**
200 | * read HTML file from disk and generate code from template system(with render function)
201 | * @param template
202 | * @param data
203 | * @param render
204 | */
205 | readHtml = async ({
206 | template = "",
207 | data = {},
208 | render = this.defaultRender,
209 | }: PageObject) => {
210 | const templatePath = path.resolve(this.cwd, `.${template}`);
211 | if (!fs.existsSync(templatePath)) {
212 | this.logger("[vite-plugin-virtual-html]: template file must exist!");
213 | return "";
214 | }
215 | return await this.renderTemplate(templatePath, render, data);
216 | };
217 |
218 | /**
219 | * render template
220 | * @param templatePath
221 | * @param render
222 | * @param data
223 | */
224 | renderTemplate = async (
225 | templatePath: string,
226 | render: VirtualHtmlTemplateRender,
227 | data: VirtualHtmlTemplateData
228 | ) => {
229 | const code = await this.readTemplate(templatePath);
230 | return render(
231 | code,
232 | data,
233 | templatePath.substring(templatePath.lastIndexOf(path.sep) + 1)
234 | );
235 | };
236 |
237 | /**
238 | * read html file's content to render with render function
239 | * @param templatePath
240 | */
241 | readTemplate = async (templatePath: string): Promise => {
242 | const result = await fsp.readFile(templatePath);
243 | return result.toString();
244 | };
245 |
246 | /**
247 | * generate page option from string/object to object
248 | * @param page
249 | * @param globalData
250 | * @param globalRender
251 | */
252 | generatePageOptions = async (
253 | page: PageObject | string,
254 | globalData: Record,
255 | globalRender: VirtualHtmlTemplateRender
256 | ): Promise => {
257 | if (typeof page === "string") {
258 | return {
259 | template: page,
260 | data: {
261 | ...globalData,
262 | },
263 | render: globalRender,
264 | };
265 | }
266 | const { data = {}, render, template } = page;
267 | return {
268 | template: template,
269 | data: {
270 | ...globalData,
271 | ...data,
272 | },
273 | render: render ?? globalRender ?? this.defaultRender,
274 | };
275 | };
276 |
277 | /**
278 | * directly use find\replacement / replacement\find to replace find
279 | * @param {pos, find, replacement}
280 | * @param code
281 | */
282 | generateInjectCode = (
283 | { pos, find, replacement }: InjectCode,
284 | code: string
285 | ): string => {
286 | if (pos === POS.after) {
287 | return code.replace(find, `${find}\n${replacement}`);
288 | }
289 | if (pos === POS.before) {
290 | return code.replace(find, `\n${replacement}\n${find}`);
291 | }
292 | return code;
293 | };
294 |
295 | /**
296 | * generate page from virtual page
297 | * @param vPages
298 | */
299 | generateVirtualPage = async (vPages: VirtualPageOptions): Promise => {
300 | const { entry, title = "", body = '' } = vPages;
301 | return VIRTUAL_HTML_CONTENT.replace("#ENTRY#", entry)
302 | .replace("#TITLE#", title)
303 | .replace("#BODY#", body)
304 | .toString();
305 | };
306 |
307 | /**
308 | * find all html file in project and return it as Pages
309 | */
310 | findAllHtmlInProject = (extraGlobPattern: Array = []): Pages => {
311 | const pages: Pages = {};
312 | let realPattern: Array = [];
313 | if (extraGlobPattern.length === 0) {
314 | realPattern = DEFAULT_GLOB_PATTERN;
315 | } else {
316 | const set: Set = new Set();
317 | DEFAULT_GLOB_PATTERN.forEach((dg) => set.add(dg));
318 | extraGlobPattern.forEach((dg) => set.add(dg));
319 | for (let key of set.keys()) {
320 | realPattern.push(key);
321 | }
322 | }
323 | const files = glob.sync(realPattern);
324 | files.forEach((file) => {
325 | const filePathArr = file.split("/");
326 | pages[
327 | filePathArr[filePathArr.length - 1].replace(".html", "")
328 | ] = `/${file}`;
329 | });
330 | return pages;
331 | };
332 |
333 | defaultRender: VirtualHtmlTemplateRender = (
334 | template: string,
335 | data: Record
336 | ) => {
337 | try {
338 | const resolved = _require.resolve("ejs");
339 | return _require(resolved).render(template, data, {
340 | delimiter: "%",
341 | root: process.cwd(),
342 | });
343 | } catch (e) {
344 | //
345 | }
346 | return template;
347 | };
348 | }
349 |
--------------------------------------------------------------------------------
/src/html/Build.ts:
--------------------------------------------------------------------------------
1 | import type { HtmlPluginOptions } from './types'
2 | import { VirtualHtmlPage, VirtualPageOptions } from './types'
3 | import type { UserConfig } from 'vite'
4 | import { normalizePath } from 'vite'
5 | import { Base } from './Base'
6 | import fs, { promises as fsp } from 'fs'
7 | import path from 'path'
8 |
9 | export class Build extends Base {
10 |
11 | _needRemove: Array = []
12 | _distDir!: string
13 |
14 | constructor(virtualHtmlOptions: HtmlPluginOptions) {
15 | super(virtualHtmlOptions)
16 | }
17 |
18 | /**
19 | * check html file's parent directory
20 | * @param html
21 | * @param needRemove
22 | */
23 | async checkVirtualPath(html: string, needRemove: Array, root: string) {
24 | const cwd = normalizePath(path.resolve(this.cwd, root))
25 | const pathArr = html.split('/')
26 | const fileName = pathArr[pathArr.length - 1]
27 | const middlePath = html.replace(fileName, '').replace(cwd, '')
28 | const firstPath = middlePath.split('/')[1]
29 | if (!fs.existsSync(middlePath)) {
30 | needRemove.push(normalizePath(path.resolve(cwd, `./${firstPath}`)))
31 | await fsp.mkdir(path.resolve(cwd, `./${middlePath}`), {
32 | recursive: true
33 | })
34 | }
35 | }
36 |
37 | async _buildConfig(config: UserConfig,) {
38 | this._config = config
39 | const pagesKey = Object.keys(this._pages)
40 | for (let i = 0; i < pagesKey.length; i++) {
41 | const key = pagesKey[i]
42 | const pageOption = this._pages[key]
43 | const vHtml = normalizePath(path.resolve(this.cwd, `./${config.root ? this.addTrailingSlash(config.root) : ''}${this.htmlNameAddIndex(key)}.html`))
44 | if (!fs.existsSync(vHtml)) {
45 | this._needRemove.push(vHtml)
46 | await this.checkVirtualPath(vHtml, this._needRemove, config.root ?? '')
47 | if (typeof pageOption === 'string' || 'template' in pageOption) {
48 | const genPageOption = await this.generatePageOptions(pageOption, this._globalData, this._globalRender)
49 | await fsp.copyFile(path.resolve(this.cwd, `.${genPageOption.template}`), vHtml)
50 | }
51 | if (typeof pageOption !== 'string' && 'entry' in pageOption) {
52 | await fsp.writeFile(path.resolve(this.cwd, vHtml), await this.generateVirtualPage(pageOption))
53 | }
54 | }
55 | }
56 | this.logger('[vite-plugin-virtual-html]: This plugin cannot use in library mode!')
57 | // get custom distDir config,if it is undefined use default config 'dist'
58 | this._distDir = config.build?.outDir ?? 'dist'
59 | // inject build.rollupOptions.input from pages directly.
60 | config.build = {
61 | ...config.build,
62 | rollupOptions: {
63 | ...config.build?.rollupOptions,
64 | input: {
65 | ...(config.build?.rollupOptions?.input as object),
66 | ...this.extractHtmlPath(this._pages),
67 | },
68 | },
69 | }
70 | }
71 |
72 | _closeBundle() {
73 | // remove files should not be under project root
74 | for (let vHtml of this._needRemove) {
75 | if (fs.existsSync(vHtml)) {
76 | fsp.rm(vHtml, {
77 | recursive: true,
78 | }).catch(() => {
79 | // ignore this warning
80 | })
81 | }
82 | }
83 | }
84 |
85 | /**
86 | * use pages' key as html name
87 | * @param pages
88 | */
89 | extractHtmlPath(pages: {
90 | [p: string]: VirtualHtmlPage | VirtualPageOptions
91 | }) {
92 | const newPages: {
93 | [key: string]: string
94 | } = {}
95 | Object.keys(pages).forEach(key => {
96 | newPages[key] = `/${this.htmlNameAddIndex(key)}.html`
97 | })
98 | return newPages
99 | }
100 |
101 | htmlNameAddIndex(htmlName: string): string {
102 | return htmlName.endsWith('/') ? htmlName + 'index' : htmlName
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/html/Serve.ts:
--------------------------------------------------------------------------------
1 | import type { HtmlPluginOptions, UrlTransformerFunction } from './types'
2 | import { Base } from './Base'
3 | import { buildHistoryApiFallback } from '../history-api/historyApiFallbackPlugin'
4 | import type { ViteDevServer } from 'vite'
5 | import { normalizePath, createFilter, } from 'vite'
6 | import type { HistoryApiOptions, HistoryRewrites } from '../history-api/types'
7 |
8 | const HTML_INCLUDE = [/\.html$/,/\/$/]
9 | const HTML_FILTER = createFilter(HTML_INCLUDE)
10 |
11 | export class Serve extends Base {
12 | _rewrites?: Array
13 |
14 | _urlTransformer?: UrlTransformerFunction
15 |
16 | constructor(virtualHtmlOptions: HtmlPluginOptions & HistoryApiOptions) {
17 | super(virtualHtmlOptions)
18 | this._rewrites = virtualHtmlOptions.rewrites
19 | this._urlTransformer = virtualHtmlOptions.urlTransformer
20 | }
21 |
22 | _configureServer = (server: ViteDevServer) => {
23 | if (this._rewrites) {
24 | buildHistoryApiFallback(server, this._rewrites)
25 | }
26 | // other html handled after vite's inner middlewares.
27 | return () => {
28 | server.middlewares.use(async (req, res, next) => {
29 | const originalUrl = req.originalUrl
30 | const reqUrl = req.url
31 | let url = decodeURI(this.generateUrl(originalUrl?.endsWith('/') ? originalUrl : reqUrl))
32 | // allow user customize url transformer
33 | if (this._urlTransformer) {
34 | url = this._urlTransformer(url, req)
35 | }
36 | // if request is not html , directly return next()
37 | if (!HTML_FILTER(url) && url !== '/') {
38 | return next()
39 | }
40 | // request / means client requests an index page
41 | // load it with indexPage config
42 | let htmlCode: string|undefined
43 | if (url === '/' || url === '/index.html') {
44 | url = `/${this._indexPage}.html`
45 | }
46 | // load specify html file code
47 | // @ts-ignore
48 | htmlCode = await this._load(normalizePath(url))
49 | if (htmlCode === undefined) {
50 | res.statusCode = 404
51 | res.end()
52 | return next()
53 | }
54 | // @ts-ignore
55 | const transformResult = await this._transform(htmlCode, url)
56 | if (transformResult === null) {
57 | return next()
58 | }
59 | res.end(await server.transformIndexHtml(url, transformResult))
60 | next()
61 | })
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/html/VirtualHtmlPlugin.ts:
--------------------------------------------------------------------------------
1 | import type { HtmlPluginOptions } from "./types";
2 | import type { ConfigEnv, Plugin, UserConfig } from "vite";
3 | import type { HistoryApiOptions } from "../history-api/types";
4 | import { Serve } from "./Serve";
5 | import { Build } from "./Build";
6 |
7 | export const VirtualHtmlPlugin = (
8 | virtualHtmlOptions: HtmlPluginOptions & HistoryApiOptions
9 | ): Plugin => {
10 | let _htmlOptions = virtualHtmlOptions;
11 | let _config: UserConfig;
12 | let _instance: Serve | Build | null = null;
13 | return {
14 | name: "vite-plugin-virtual-html",
15 | async config(config: UserConfig, { command }: ConfigEnv) {
16 | _config = config;
17 | if (command === "serve") {
18 | if (_htmlOptions.useCustom??true) {
19 | config.appType = "custom";
20 | }
21 | _instance = new Serve(_htmlOptions);
22 | } else if (command === "build") {
23 | _instance = new Build(_htmlOptions);
24 | await _instance._buildConfig.call(_instance, config);
25 | }
26 | },
27 | configureServer(server) {
28 | if ((_instance as Serve)._configureServer) {
29 | return (_instance as Serve)._configureServer(server);
30 | }
31 | },
32 | async load(...args) {
33 | if (_instance?._load) {
34 | return await _instance._load(...args);
35 | }
36 | },
37 | async transform(...args) {
38 | if (_instance?._transform) {
39 | return await _instance._transform(...args);
40 | }
41 | },
42 | closeBundle() {
43 | if ((_instance as Build)._closeBundle) {
44 | return (_instance as Build)._closeBundle();
45 | }
46 | },
47 | };
48 | };
49 |
--------------------------------------------------------------------------------
/src/html/types.ts:
--------------------------------------------------------------------------------
1 | import { type IncomingMessage } from 'http'
2 |
3 | export type PageObject = {
4 | template: string,
5 | data?: VirtualHtmlTemplateData,
6 | render?: VirtualHtmlTemplateRender,
7 | }
8 | /**
9 | * describe a page
10 | */
11 | export type VirtualHtmlPage = string | PageObject | VirtualPageOptions
12 | /**
13 | * html template render
14 | */
15 | export type VirtualHtmlTemplateRender = (template: string, data: Record, htmlName?: string) => string
16 |
17 | export type VirtualHtmlTemplateData = Record
18 |
19 | export type Pages = {
20 | [key: string]: VirtualHtmlPage
21 | }
22 |
23 | export type VirtualPageOptions = {
24 | entry: string,
25 | title?: string,
26 | body?: string,
27 | }
28 |
29 | export type UrlTransformerFunction = (resolvedUrl: string, req: IncomingMessage) => string
30 |
31 | /**
32 | * plugin config options
33 | */
34 | export type HtmlPluginOptions = {
35 | /**
36 | * config html-entries' path
37 | * if it is true, plugin will use glob to find all the html page in project to generate a json like {a: /src/a/a.html,}
38 | */
39 | pages?: Pages | true,
40 | /**
41 | * transform url to another url by user.
42 | * This is ONLY apply in dev mode.
43 | * @param url
44 | */
45 | urlTransformer?: UrlTransformerFunction
46 | /**
47 | * define the index page,to replace default index.html
48 | * this page will trigger `transformIndexHtml` hook.
49 | */
50 | indexPage?: string,
51 | /**
52 | * use for template. as global inject data
53 | */
54 | data?: Record
55 | /**
56 | * function to render template
57 | */
58 | render?: VirtualHtmlTemplateRender
59 | /**
60 | * when pages set to true, customize fast-glob's pattern
61 | * default value is ['**\\*.html', '!node_modules\\**\\*.html', '!.**\\*.html']
62 | */
63 | extraGlobPattern?: Array
64 | /**
65 | * inject code to html
66 | * key: html name, can be *
67 | */
68 | injectCode?: Record
69 | /**
70 | * is set appType to custom?
71 | */
72 | useCustom?: boolean
73 | cwd?: string
74 | }
75 |
76 | /**
77 | * inject code to tag's before or after
78 | */
79 | export enum POS {
80 | before, after
81 | }
82 |
83 | /**
84 | * inject code config
85 | */
86 | export type InjectCode = {
87 | pos: POS,
88 | find: string,
89 | replacement: string,
90 | }
91 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { Plugin, } from 'vite'
2 | import type { HtmlPluginOptions, } from './html/types'
3 | import { VirtualHtmlPlugin } from './html/VirtualHtmlPlugin'
4 | import type { HistoryApiOptions } from './history-api/types'
5 |
6 | export default (virtualHtmlOptions: HtmlPluginOptions & HistoryApiOptions): Plugin => {
7 | return VirtualHtmlPlugin(virtualHtmlOptions)
8 | }
9 |
10 | export {
11 | VirtualHtmlPlugin,
12 | }
13 |
14 | export * from './html/Build'
15 |
16 | export * from './html/Serve'
17 |
18 | export * from './history-api/historyApiFallbackPlugin'
19 |
20 | export * from './html/types'
21 |
22 | export * from './history-api/types'
23 |
--------------------------------------------------------------------------------
/test/__snapshots__/pages.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`html_with_entry_and_template_config 1`] = `
4 | "
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | "
16 | `;
17 |
18 | exports[`html_with_entry_and_template_config 2`] = `
19 | "
20 |
21 |
22 |
23 | Demo
24 |
25 |
26 |
27 |
28 |
29 |
30 | "
31 | `;
32 |
33 | exports[`html_with_entry_config 1`] = `
34 | "
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | "
46 | `;
47 |
48 | exports[`html_with_inject_code_all_page 1`] = `
49 | "
50 |
51 |
52 |
53 | Demo
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | "
63 | `;
64 |
65 | exports[`html_with_inject_code_all_page 2`] = `
66 | "
67 |
68 |
69 |
70 | Demo
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | "
80 | `;
81 |
82 | exports[`html_with_inject_code_demo1 1`] = `
83 | "
84 |
85 |
86 |
87 | Demo
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | "
97 | `;
98 |
99 | exports[`html_with_template_config1 1`] = `
100 | "
101 |
102 |
103 |
104 | Demo
105 |
106 |
107 |
108 |
109 |
110 |
111 | "
112 | `;
113 |
114 | exports[`html_with_template_config2 1`] = `
115 | "
116 |
117 |
118 |
119 | Demo
120 |
121 |
122 |
123 |
124 |
125 |
126 | "
127 | `;
128 |
129 | exports[`index 1`] = `
130 | "
131 |
132 |
133 |
134 | Demo
135 |
136 |
137 |
138 |
139 |
140 |
141 | "
142 | `;
143 |
144 | exports[`index 2`] = `
145 | "
146 |
147 |
148 |
149 | Demo
150 |
151 |
152 |
153 |
154 |
155 |
156 | "
157 | `;
158 |
159 | exports[`index with context 1 1`] = `
160 | "
161 |
162 |
163 |
164 | Demo
165 |
166 |
167 |
168 |
169 |
170 |
171 | "
172 | `;
173 |
174 | exports[`index with context 1 2`] = `
175 | "
176 |
177 |
178 |
179 | Demo
180 |
181 |
182 |
183 |
184 |
185 |
186 | "
187 | `;
188 |
189 | exports[`index_with_sub_folder1 1`] = `
190 | "
191 |
192 |
193 |
194 | Demo
195 |
196 |
197 |
198 |
199 |
200 |
201 | "
202 | `;
203 |
204 | exports[`index_with_sub_folder1 2`] = `
205 | "
206 |
207 |
208 |
209 | Demo
210 |
211 |
212 |
213 |
214 |
215 |
216 | "
217 | `;
218 |
219 | exports[`index_with_sub_folder2 1`] = `
220 | "
221 |
222 |
223 |
224 | Demo
225 |
226 |
227 |
228 |
229 |
230 |
231 | "
232 | `;
233 |
234 | exports[`index_with_sub_folder2 2`] = `
235 | "
236 |
237 |
238 |
239 | Demo
240 |
241 |
242 |
243 |
244 |
245 |
246 | "
247 | `;
248 |
--------------------------------------------------------------------------------
/test/__snapshots__/template.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`template_ejs 1`] = `
4 | "
5 |
6 |
7 |
8 | Demo1
9 |
10 |
11 |
12 |
13 | a | b | c
14 |
15 |
16 | "
17 | `;
18 |
19 | exports[`template_ejs 2`] = `
20 | "
21 |
22 |
23 |
24 | Demo2
25 |
26 |
27 |
28 |
29 | a | b | c
30 | <p>I am a test partial</p>
31 |
32 |
33 | "
34 | `;
35 |
36 | exports[`template_ejs 3`] = `
37 | "
38 |
39 |
40 |
41 | Demo3
42 | <script type="module" src="/test/demo/demo1/demo1.ts"></script>
43 |
44 |
45 |
46 |
47 |
48 | "
49 | `;
50 |
--------------------------------------------------------------------------------
/test/demo/demo1/demo1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/demo/demo1/demo1.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windsonR/vite-plugin-virtual-html/ec47c600e819cbb8ebcad1a45722d186399ac9ac/test/demo/demo1/demo1.ts
--------------------------------------------------------------------------------
/test/demo/template/demo1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo1
6 |
7 |
8 |
9 |
10 | <%= users.join(" | "); %>
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/demo/template/demo2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo2
6 |
7 |
8 |
9 |
10 | <%= users.join(" | "); %>
11 | <%= include('/test/demo/template/test') %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/demo/template/demo3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo3
6 | <%= script; %>
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/demo/template/test.ejs:
--------------------------------------------------------------------------------
1 | I am a test partial
--------------------------------------------------------------------------------
/test/pages.test.ts:
--------------------------------------------------------------------------------
1 | // noinspection DuplicatedCode
2 |
3 | import {expect, test} from 'vitest'
4 | import VirtualHtml, { POS } from '../src'
5 | import {createServer,} from 'vite'
6 | import {page} from '../vitestSetup'
7 |
8 | test('index', async () => {
9 | const server = await createServer({
10 | configFile: false,
11 | plugins: [
12 | VirtualHtml({
13 | pages: {
14 | demo1: '/test/demo/demo1/demo1.html',
15 | },
16 | indexPage: 'demo1',
17 | })
18 | ]
19 | })
20 | await server.listen()
21 | await page.goto(`http://localhost:${server.config.server.port}/`)
22 | const index = await page.content()
23 | expect(index).toMatchSnapshot()
24 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
25 | const demo1 = await page.content()
26 | expect(demo1).toMatchSnapshot()
27 | expect(index).toBe(demo1)
28 | await server.close()
29 | })
30 |
31 | test('index with context 1', async () => {
32 | const context = '/demo/'
33 | const server = await createServer({
34 | base: context,
35 | configFile: false,
36 | plugins: [
37 | VirtualHtml({
38 | pages: {
39 | demo1: '/test/demo/demo1/demo1.html',
40 | },
41 | indexPage: 'demo1',
42 | urlTransformer(url){
43 | return url.replace(context, '/')
44 | }
45 | })
46 | ]
47 | })
48 | await server.listen()
49 | await page.goto(`http://localhost:${server.config.server.port}${context}`)
50 | const index = await page.content()
51 | expect(index).toMatchSnapshot()
52 | await page.goto(`http://localhost:${server.config.server.port}${context}demo1.html`)
53 | const demo1 = await page.content()
54 | expect(demo1).toMatchSnapshot()
55 | expect(index).toBe(demo1)
56 | await server.close()
57 | })
58 |
59 | test('index_with_sub_folder1', async () => {
60 | const server = await createServer({
61 | configFile: false,
62 | plugins: [
63 | VirtualHtml({
64 | pages: {
65 | // should access with localhost/demo1/ or localhost/demo1/index.html
66 | 'demo1/index': '/test/demo/demo1/demo1.html',
67 | },
68 | })
69 | ]
70 | })
71 | await server.listen()
72 | await page.goto(`http://localhost:${server.config.server.port}/demo1/`)
73 | const index = await page.content()
74 | expect(index).toMatchSnapshot()
75 | await page.goto(`http://localhost:${server.config.server.port}/demo1/index.html`)
76 | const demo1 = await page.content()
77 | expect(demo1).toMatchSnapshot()
78 | expect(index).toBe(demo1)
79 | await server.close()
80 | })
81 |
82 | test('index_with_sub_folder2', async () => {
83 | const server = await createServer({
84 | configFile: false,
85 | plugins: [
86 | VirtualHtml({
87 | pages: {
88 | // should access with localhost/demo1/ or localhost/demo1/index.html
89 | 'demo1/': '/test/demo/demo1/demo1.html',
90 | },
91 | })
92 | ]
93 | })
94 | await server.listen()
95 | await page.goto(`http://localhost:${server.config.server.port}/demo1/`)
96 | const index = await page.content()
97 | expect(index).toMatchSnapshot()
98 | await page.goto(`http://localhost:${server.config.server.port}/demo1/index.html`)
99 | const demo1 = await page.content()
100 | expect(demo1).toMatchSnapshot()
101 | expect(index).toBe(demo1)
102 | await server.close()
103 | })
104 |
105 | test('html_with_template_config1', async () => {
106 | const server = await createServer({
107 | configFile: false,
108 | plugins: [
109 | VirtualHtml({
110 | pages: {
111 | demo1: '/test/demo/demo1/demo1.html',
112 | },
113 | })
114 | ]
115 | })
116 | await server.listen()
117 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
118 | expect(await page.content()).toMatchSnapshot()
119 | await server.close()
120 | })
121 |
122 | test('html_with_template_config2', async () => {
123 | const server = await createServer({
124 | configFile: false,
125 | // root: path.resolve(__dirname, './'),
126 | plugins: [
127 | VirtualHtml({
128 | pages: {
129 | demo1: {
130 | template: '/test/demo/demo1/demo1.html'
131 | },
132 | },
133 | })
134 | ]
135 | })
136 | await server.listen()
137 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
138 | expect(await page.content()).toMatchSnapshot()
139 | await server.close()
140 | })
141 |
142 | test('html_with_entry_config', async () => {
143 | const server = await createServer({
144 | configFile: false,
145 | plugins: [
146 | VirtualHtml({
147 | pages: {
148 | demo1: {
149 | entry: '/test/demo/demo1/demo1.ts'
150 | },
151 | },
152 | })
153 | ]
154 | })
155 | await server.listen()
156 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
157 | expect(await page.content()).toMatchSnapshot()
158 | await server.close()
159 | })
160 |
161 | test('html_with_entry_and_template_config', async () => {
162 |
163 | const server = await createServer({
164 | configFile: false,
165 | plugins: [
166 | VirtualHtml({
167 | pages: {
168 | demo1: {
169 | entry: '/test/demo/demo1/demo1.ts'
170 | },
171 | demo2: {
172 | template: '/test/demo/demo1/demo1.html',
173 | }
174 | },
175 | })
176 | ]
177 | })
178 | await server.listen()
179 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
180 | expect(await page.content()).toMatchSnapshot()
181 | await page.goto(`http://localhost:${server.config.server.port}/demo2.html`)
182 | expect(await page.content()).toMatchSnapshot()
183 | await server.close()
184 | })
185 |
186 | test('html_with_inject_code_demo1', async () => {
187 | const server = await createServer({
188 | configFile: false,
189 | plugins: [
190 | VirtualHtml({
191 | pages: {
192 | demo1: '/test/demo/demo1/demo1.html',
193 | },
194 | injectCode: {
195 | 'demo1.html': {
196 | pos: POS.before,
197 | find: '',
198 | replacement: '',
199 | }
200 | }
201 | })
202 | ]
203 | })
204 | await server.listen()
205 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
206 | expect(await page.content()).toMatchSnapshot()
207 | await server.close()
208 | })
209 |
210 | test('html_with_inject_code_all_page', async () => {
211 | const server = await createServer({
212 | configFile: false,
213 | plugins: [
214 | VirtualHtml({
215 | pages: {
216 | demo1: '/test/demo/demo1/demo1.html',
217 | demo2: {
218 | template: '/test/demo/demo1/demo1.html',
219 | }
220 | },
221 | injectCode: {
222 | '*': {
223 | pos: POS.before,
224 | find: '',
225 | replacement: '',
226 | }
227 | }
228 | })
229 | ]
230 | })
231 | await server.listen()
232 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
233 | expect(await page.content()).toMatchSnapshot()
234 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
235 | expect(await page.content()).toMatchSnapshot()
236 | await server.close()
237 | })
238 |
--------------------------------------------------------------------------------
/test/template.test.ts:
--------------------------------------------------------------------------------
1 | // noinspection DuplicatedCode
2 |
3 | import {expect, test} from 'vitest'
4 | import VirtualHtml from '../src'
5 | import {createServer,} from 'vite'
6 | import {page} from '../vitestSetup'
7 |
8 | test('template_ejs', async () => {
9 | const server = await createServer({
10 | configFile: false,
11 | plugins: [
12 | VirtualHtml({
13 | pages: {
14 | demo1: {
15 | template: '/test/demo/template/demo1.html',
16 | data: {
17 | users: ['a', 'b', 'c']
18 | }
19 | },
20 | demo2: {
21 | template: '/test/demo/template/demo2.html',
22 | data: {
23 | users: ['a', 'b', 'c']
24 | }
25 | },
26 | demo3: {
27 | template: '/test/demo/template/demo3.html',
28 | data: {
29 | script: ''
30 | }
31 | },
32 | },
33 | })
34 | ]
35 | })
36 | await server.listen()
37 | await page.goto(`http://localhost:${server.config.server.port}/demo1.html`)
38 | expect(await page.content()).toMatchSnapshot()
39 | await page.goto(`http://localhost:${server.config.server.port}/demo2.html`)
40 | expect(await page.content()).toMatchSnapshot()
41 | await page.goto(`http://localhost:${server.config.server.port}/demo3.html`)
42 | expect(await page.content()).toMatchSnapshot()
43 | await server.close()
44 | })
45 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "module": "ES2020",
5 | "moduleResolution": "node",
6 | "strict": true,
7 | "jsx": "preserve",
8 | "sourceMap": true,
9 | "resolveJsonModule": true,
10 | "esModuleInterop": true,
11 | "lib": [
12 | "esnext",
13 | "dom"
14 | ],
15 | "types": [
16 | "vite/client"
17 | ],
18 | "declaration": true,
19 | "skipLibCheck": true
20 | },
21 | "include": [
22 | "src/**/*.ts"
23 | ],
24 | "exclude": [
25 | "vite.config.ts"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'tsup'
2 |
3 | export const tsup = defineConfig({
4 | entry: [
5 | 'src/index.ts',
6 | ],
7 | format: ['esm'],
8 | dts: true,
9 | splitting: false,
10 | clean: true,
11 | shims: false,
12 | minify: false,
13 | sourcemap: true,
14 | })
15 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import {defineConfig} from 'vite'
2 | import VirtualHtml from './src'
3 | import Vue from '@vitejs/plugin-vue'
4 | import Inspect from 'vite-plugin-inspect'
5 | // @ts-ignore
6 | import ejs from 'ejs'
7 | import {POS} from './src/html/types';
8 |
9 | export default defineConfig({
10 | resolve: {
11 | alias: {
12 | 'vue': 'vue/dist/vue.esm-bundler.js'
13 | }
14 | },
15 | plugins: [
16 | Inspect(),
17 | Vue(),
18 | VirtualHtml({
19 | pages: {
20 | // demo1 is the html name you access in browser
21 | demo1: {
22 | template: '/demo/demo1/demo1.html',
23 | data: {
24 | users: ['a','b','c']
25 | }
26 | },
27 | 'demo1/index': '/demo/demoIndex1.html',
28 | 'demo2/': '/demo/demoIndex2.html',
29 | demo2: '/demo/demo2/demo2.html',
30 | demo3: {
31 | template: '/demo/demo3.html'
32 | },
33 | demo4: {
34 | template: '/demo/template.html',
35 | data: {
36 | script: ''
37 | }
38 | },
39 | 'demo1/demo2/demo5': { // multi-level directories, the last (demo5) will be the html name
40 | template: '/demo/template.html',
41 | data: {
42 | script: ''
43 | }
44 | },
45 | demo6: {
46 | entry: '/demo/demo1/demo1.ts',
47 | },
48 | demo7: {
49 | entry: '/demo/demo1/demo1.ts',
50 | title: 'demo7',
51 | body: ''
52 | },
53 | },
54 | data: {
55 | users: ['a', 'b', 'c'],
56 | script: ''
57 | },
58 | indexPage: 'demo1',
59 | // global render, from 0.3.0 it (this demo code) will auto configure in plugin, and you MUST install 'ejs' in your project to use it.
60 | // render(template,data){
61 | // return ejs.render(template, data, {delimiter: '%', root: process.cwd()})
62 | // },
63 | // pages: true, // when pages set to true, plugin will use extraGlobPattern to glob html file
64 | // extraGlobPattern: [
65 | // '**/*.html',
66 | // '!node_modules/**/*.html',
67 | // '!.**/*.html',
68 | // '!dist/**/*.html'
69 | // ],
70 | injectCode: {
71 | 'demo1.html': {
72 | pos: POS.after,
73 | find: '',
74 | replacement: ''
75 | },
76 | '*': {
77 | pos: POS.after,
78 | find: '',
79 | replacement: ''
80 | },
81 | },
82 | // rewrites: [
83 | // {
84 | // from: /.*/g,
85 | // to: ''
86 | // }
87 | // ]
88 | }),
89 | ],
90 | optimizeDeps: {
91 | force: true
92 | }
93 | })
94 |
--------------------------------------------------------------------------------
/vitestSetup.ts:
--------------------------------------------------------------------------------
1 | import {beforeAll} from 'vitest'
2 | import { chromium, Page } from 'playwright-chromium'
3 |
4 | export let page: Page = undefined!
5 | beforeAll(async ()=>{
6 | const browser = await chromium.launch()
7 | const context = await browser.newContext()
8 | page = await context.newPage()
9 | page.once('load', () => console.log('Page loaded!'));
10 | })
11 |
--------------------------------------------------------------------------------