From e6f96ac75261ea3c17035b5ddda26ac74989ac07 Mon Sep 17 00:00:00 2001
From: hemengke1997 <23536175@qq.com>
Date: Thu, 14 Sep 2023 19:53:18 +0800
Subject: [PATCH] feat: export `inject-script` plugin
---
.gitignore | 3 +-
README.md | 72 ++--
__test__/basic.spec.todo.ts | 119 +++++++
__test__/basic.spec.ts | 116 -------
package.json | 2 +
playground/spa/package.json | 2 +-
playground/spa/public-typescript/index.ts | 4 +-
.../spa/public-typescript/manifest.json | 4 +-
playground/spa/public-typescript/test.ts | 2 +-
playground/spa/public/out/haha.bdaaba63.js | 1 -
playground/spa/public/out/index.cccf1b56.js | 1 -
playground/spa/public/out/test.40879d01.js | 1 -
playground/spa/src/App.tsx | 1 -
playground/spa/vite.config.ts | 82 ++---
pnpm-lock.yaml | 309 +++---------------
src/helper/AbsCacheProcessor.ts | 51 ++-
src/helper/FileCacheProcessor.ts | 27 +-
src/helper/ManifestCache.ts | 82 ++++-
src/helper/MemoryCacheProcessor.ts | 11 +-
src/helper/build.ts | 30 +-
src/helper/html.ts | 73 +++++
src/helper/processor.ts | 12 +-
src/helper/utils.ts | 7 +
src/index.ts | 110 +++++--
src/plugins/inject-script.ts | 28 ++
vitest.config.ts | 1 +
26 files changed, 591 insertions(+), 560 deletions(-)
create mode 100644 __test__/basic.spec.todo.ts
delete mode 100644 __test__/basic.spec.ts
delete mode 100644 playground/spa/public/out/haha.bdaaba63.js
delete mode 100644 playground/spa/public/out/index.cccf1b56.js
delete mode 100644 playground/spa/public/out/test.40879d01.js
create mode 100644 src/helper/html.ts
create mode 100644 src/plugins/inject-script.ts
diff --git a/.gitignore b/.gitignore
index fa49873..3185bd2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
node_modules
dist
-.idea
\ No newline at end of file
+.idea
+.Ds_store
diff --git a/README.md b/README.md
index 14b5d44..ff7e7d4 100644
--- a/README.md
+++ b/README.md
@@ -4,51 +4,63 @@
**中文** | [English](./README.md)
-**在vite的运行时或构建时打包指定目录下的typescript文件,供独立使用**
+**在vite的运行时或构建时打包指定目录下的typescript文件,供开发者独立使用**
> 如果你希望项目中所有脚本都使用typescript编写,那么你应该试试此插件
## 应用场景
-- 独立的第三方脚本,如 `sentry`,`google analytics`,百度统计等
+- 独立的第三方脚本,如 `sentry`,`google analytics`,`百度统计` 等
- 希望在页面完全加载前就执行的脚本,如 `modern-flexible` 等
- 初始化全局函数
## 功能
-- 运行时和构建时,把指定文件夹中的`typescript`文件编译为`javascript`,浏览器可直接使用
-- 输出带有`hash`的js文件,无需担心缓存
+- 运行时和构建时,把指定文件夹中的`typescript`文件编译为`javascript`,供浏览器直接使用
+- 输出带有 `hash` 的js文件,无需担心缓存
- 自定义编译选项,指定目标浏览器范围,无需担心兼容性
- 支持vite环境变量
-- 支持`HMR`
+- 支持 `HMR`
- 生产可用
-## Install
+## 安装
```bash
pnpm add vite-plugin-public-typescript -D
```
-## Preview
-
-
-
## 用法
```typescript
import { defineConfig } from 'vite'
-import { publicTypescript } from 'vite-plugin-public-typescript'
+import { publicTypescript, injectScripts } from 'vite-plugin-public-typescript'
+import manifest from './public-typescript/manifest.json'
export default defineConfig({
- plugins: [publicTypescript()],
+ plugins: [
+ publicTypescript({
+ inputDir: 'public-typescript',
+ manifestName: 'manifest',
+ hash: true,
+ outputDir: '/out',
+ destination: 'memory',
+ }),
+ injectScripts([
+ {
+ attrs: {
+ src: manifest.script,
+ },
+ injectTo: 'head',
+ },
+ ])
+ ]
})
```
### SPA
-在 `SPA` 应用中,我们可以通过 vite 的 `transformIndexHtml` hook 注入 script
-你也可以使用 [`vite-plugin-html`](https://github.com/vbenjs/vite-plugin-html),这会使得注入更加简单
+在 `SPA` 应用中,我们可以通过 `injectScripts` 插件往 `index.html` 中注入 script
完整示例请参考:[spa playground](./playground/spa/vite.config.ts)
@@ -57,30 +69,20 @@ export default defineConfig({
```typescript
import type { HtmlTagDescriptor } from 'vite'
import { defineConfig } from 'vite'
-import { publicTypescript } from 'vite-plugin-public-typescript'
-import manifest from './publicTypescript/manifest.json'
+import { publicTypescript, injectScripts } from 'vite-plugin-public-typescript'
+import manifest from './public-typescript/manifest.json'
export default defineConfig({
plugins: [
publicTypescript(),
- {
- name: 'add-script',
- async transformIndexHtml(html) {
- const tags: HtmlTagDescriptor[] = [
- {
- tag: 'script',
- attrs: {
- src: manifest.spa,
- },
- injectTo: 'head-prepend',
- },
- ]
- return {
- html,
- tags,
- }
- },
- },
+ injectScripts([
+ {
+ attrs: {
+ src: manifest.spa,
+ },
+ injectTo: 'head-prepend',
+ }
+ ])
],
})
```
@@ -109,7 +111,7 @@ export default defineConfig({
#### server.js
```js
-import manifest from './publicTypescript/custom-manifest.json' assert { type: 'json' }
+import manifest from './public-typescript/custom-manifest.json' assert { type: 'json' }
const html = template
// inject js
diff --git a/__test__/basic.spec.todo.ts b/__test__/basic.spec.todo.ts
new file mode 100644
index 0000000..34e6c3c
--- /dev/null
+++ b/__test__/basic.spec.todo.ts
@@ -0,0 +1,119 @@
+// import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
+// import mock from 'mock-fs'
+// import fs from 'fs-extra'
+// import type { ResolvedConfig, ViteDevServer } from 'vite'
+// import { createServer } from 'vite'
+// import { ManifestCache } from '../src/helper/ManifestCache'
+// import { eq, isEmptyObject } from '../src/helper/utils'
+// import { publicTypescript } from '../src'
+
+// declare module 'vitest' {
+// export interface TestContext {
+// cache: ManifestCache
+// vite: ResolvedConfig
+// viteDevServer: ViteDevServer
+// }
+// }
+
+// const manifestPath = 'manifest.json'
+
+// vi.mock('fs-extra', async () => {
+// const actual: any = await vi.importActual('fs-extra')
+// return {
+// readFileSync: vi.fn(),
+// writeFile: vi.fn(),
+// ...actual,
+// }
+// })
+
+// function initCache() {
+// const cache = new ManifestCache({ watchMode: false, write: false })
+// cache.set({
+// x: {
+// path: 'x.js',
+// _code: 'console.log("x")',
+// },
+// y: {
+// path: 'y.js',
+// _code: 'console.log("y")',
+// },
+// })
+// return cache
+// }
+
+// async function createDevServer() {
+// const server = await createServer({
+// define: { hahahaha: JSON.stringify('this is haha') },
+// plugins: [publicTypescript({ destination: 'file' })],
+// server: {
+// middlewareMode: true,
+// port: 4000,
+// host: '127.0.0.1',
+// },
+// })
+// return server
+// }
+
+// const globalServer = await createDevServer()
+
+// // beforeAll(() => {
+// // vi.spyOn(fs, 'readFileSync').mockImplementation(() => {
+// // return '{ "a": "/a.chunk.js" }'
+// // })
+// // })
+
+// beforeEach((ctx) => {
+// ctx.cache = initCache()
+// mock({
+// 'manifest.json': '{}',
+// })
+// })
+
+// beforeEach(async (ctx) => {
+// ctx.vite = globalServer.config
+// ctx.viteDevServer = globalServer
+// })
+
+// afterEach(async (ctx) => {
+// mock.restore()
+// await ctx.viteDevServer.close()
+// })
+
+// describe('manifestCache', () => {
+// test('should set cache and get cache right', ({ cache }) => {
+// expect(cache.getByKey('x')).toStrictEqual({ path: 'x.js', _code: 'console.log("x")' })
+// })
+
+// test('should remove cache', ({ cache }) => {
+// cache.remove('x')
+
+// expect(cache.getByKey('x')).toBeFalsy()
+// })
+
+// test('should get all', ({ cache }) => {
+// const v = cache.get()
+// expect(Object.keys(v).length === 2).toBe(true)
+// })
+
+// test('should set manifestPath', ({ cache }) => {
+// cache.setManifestPath(manifestPath)
+// expect(cache.getManifestPath()).toBe(manifestPath)
+// })
+
+// test('should write manifest', ({ cache }) => {
+// cache.setManifestPath(manifestPath)
+
+// {
+// const content = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
+// expect(isEmptyObject(content)).toBe(true)
+// }
+
+// cache.writeManifestJSON()
+
+// {
+// const content = fs.readFileSync(manifestPath, 'utf-8')
+// const c = initCache()
+// expect(eq(JSON.parse(content), c.extractPath(c.get()))).toBe(true)
+// }
+// })
+// })
diff --git a/__test__/basic.spec.ts b/__test__/basic.spec.ts
deleted file mode 100644
index feea24f..0000000
--- a/__test__/basic.spec.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
-import mock from 'mock-fs'
-import fs from 'fs-extra'
-import type { ResolvedConfig, ViteDevServer } from 'vite'
-import { createServer } from 'vite'
-import { ManifestCache } from '../src/helper/ManifestCache'
-import { eq, isEmptyObject } from '../src/helper/utils'
-import { publicTypescript } from '../src'
-
-declare module 'vitest' {
- export interface TestContext {
- cache: ManifestCache
- vite: ResolvedConfig
- viteDevServer: ViteDevServer
- }
-}
-
-const manifestPath = 'manifest.json'
-
-vi.mock('fs-extra', async () => {
- const actual: any = await vi.importActual('fs-extra')
- return {
- readFileSync: vi.fn(),
- writeFile: vi.fn(),
- ...actual,
- }
-})
-
-function initCache() {
- const cache = new ManifestCache()
- cache.set({
- x: {
- path: 'x.js',
- _code: 'console.log("x")',
- },
- y: {
- path: 'y.js',
- _code: 'console.log("y")',
- },
- })
- return cache
-}
-
-async function createDevServer() {
- const server = await createServer({
- define: { hahahaha: JSON.stringify('this is haha') },
- plugins: [publicTypescript()],
- server: {
- middlewareMode: true,
- },
- })
- return server
-}
-
-// beforeAll(() => {
-// vi.spyOn(fs, 'readFileSync').mockImplementation(() => {
-// return '{ "a": "/a.chunk.js" }'
-// })
-// })
-
-beforeEach((ctx) => {
- ctx.cache = initCache()
- mock({
- 'manifest.json': '{}',
- })
-})
-
-beforeEach(async (ctx) => {
- const server = await createDevServer()
- ctx.vite = server.config
- ctx.viteDevServer = server
-})
-
-afterEach((ctx) => {
- mock.restore()
- ctx.viteDevServer.close()
-})
-
-describe('manifestCache', () => {
- test('should set cache and get cache right', ({ cache }) => {
- expect(cache.getByKey('x')).toStrictEqual({ path: 'x.js', _code: 'console.log("x")' })
- })
-
- test('should remove cache', ({ cache }) => {
- cache.remove('x')
-
- expect(cache.getByKey('x')).toBeFalsy()
- })
-
- test('should get all', ({ cache }) => {
- const v = cache.get()
- expect(Object.keys(v).length === 2).toBe(true)
- })
-
- test('should set manifestPath', ({ cache }) => {
- cache.setManifestPath(manifestPath)
- expect(cache.getManifestPath()).toBe(manifestPath)
- })
-
- test('should write manifest', async ({ cache }) => {
- cache.setManifestPath(manifestPath)
-
- {
- const content = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
- expect(isEmptyObject(content)).toBe(true)
- }
-
- await cache.writeManifestJSON()
-
- {
- const content = fs.readFileSync(manifestPath, 'utf-8')
- const c = initCache()
- expect(eq(JSON.parse(content), c.extractPath(c.get()))).toBe(true)
- }
- })
-})
diff --git a/package.json b/package.json
index 7f57735..691350a 100644
--- a/package.json
+++ b/package.json
@@ -50,7 +50,9 @@
"debug": "^4.3.4",
"esbuild": "^0.19.2",
"fs-extra": "^11.1.1",
+ "magic-string": "^0.30.3",
"on-change": "^4.0.2",
+ "parse5": "^7.1.2",
"sirv": "^2.0.3",
"tiny-glob": "^0.2.9",
"watcher": "^2.3.0"
diff --git a/playground/spa/package.json b/playground/spa/package.json
index a4dcc2e..1193d94 100644
--- a/playground/spa/package.json
+++ b/playground/spa/package.json
@@ -7,6 +7,7 @@
"dev": "vite",
"debug": "cross-env DEBUG=vite-plugin-public-typescript* vite",
"build": "vite build",
+ "debug:build": "cross-env DEBUG=vite-plugin-public-typescript* vite build",
"preview": "vite preview"
},
"dependencies": {
@@ -20,7 +21,6 @@
"cross-env": "^7.0.3",
"typescript": "^4.9.5",
"vite": "4.4.9",
- "vite-plugin-html": "^3.2.0",
"vite-plugin-public-typescript": "workspace:*"
}
}
diff --git a/playground/spa/public-typescript/index.ts b/playground/spa/public-typescript/index.ts
index a4d5c8a..198ef78 100644
--- a/playground/spa/public-typescript/index.ts
+++ b/playground/spa/public-typescript/index.ts
@@ -1,3 +1 @@
-console.log(import.meta.env, 'env-')
-
-export {}
+console.log(import.meta.env)
diff --git a/playground/spa/public-typescript/manifest.json b/playground/spa/public-typescript/manifest.json
index aa8f6c5..f562564 100644
--- a/playground/spa/public-typescript/manifest.json
+++ b/playground/spa/public-typescript/manifest.json
@@ -1,5 +1,5 @@
{
"haha": "/out/haha.bdaaba63.js",
- "index": "/out/index.cccf1b56.js",
- "test": "/out/test.40879d01.js"
+ "index": "/out/index.a7db5a4b.js",
+ "test": "/out/test.e29e5748.js"
}
diff --git a/playground/spa/public-typescript/test.ts b/playground/spa/public-typescript/test.ts
index 7d71fc8..4b2e663 100644
--- a/playground/spa/public-typescript/test.ts
+++ b/playground/spa/public-typescript/test.ts
@@ -1 +1 @@
-console.log('this is a')
+console.log('test')
diff --git a/playground/spa/public/out/haha.bdaaba63.js b/playground/spa/public/out/haha.bdaaba63.js
deleted file mode 100644
index 351d836..0000000
--- a/playground/spa/public/out/haha.bdaaba63.js
+++ /dev/null
@@ -1 +0,0 @@
-(()=>{var o={hello:"world"};console.log("custom define!");console.log(o);})();
diff --git a/playground/spa/public/out/index.cccf1b56.js b/playground/spa/public/out/index.cccf1b56.js
deleted file mode 100644
index ffa0174..0000000
--- a/playground/spa/public/out/index.cccf1b56.js
+++ /dev/null
@@ -1 +0,0 @@
-(()=>{var e={VITE_HAHAH:"hahaha",BASE_URL:"/",MODE:"development",DEV:!0,PROD:!1};console.log(e,"env-");})();
diff --git a/playground/spa/public/out/test.40879d01.js b/playground/spa/public/out/test.40879d01.js
deleted file mode 100644
index 582b928..0000000
--- a/playground/spa/public/out/test.40879d01.js
+++ /dev/null
@@ -1 +0,0 @@
-(()=>{console.log("this is a");})();
diff --git a/playground/spa/src/App.tsx b/playground/spa/src/App.tsx
index 17a455c..77c4cb7 100644
--- a/playground/spa/src/App.tsx
+++ b/playground/spa/src/App.tsx
@@ -27,5 +27,4 @@ function App() {
)
}
-// eslint-disable-next-line no-restricted-syntax
export default App
diff --git a/playground/spa/vite.config.ts b/playground/spa/vite.config.ts
index 5651f87..4563463 100644
--- a/playground/spa/vite.config.ts
+++ b/playground/spa/vite.config.ts
@@ -1,35 +1,11 @@
-import type { HtmlTagDescriptor, PluginOption } from 'vite'
+import type { HtmlTagDescriptor } from 'vite'
import { defineConfig } from 'vite'
-import { publicTypescript } from 'vite-plugin-public-typescript'
+import { injectScripts, publicTypescript } from 'vite-plugin-public-typescript'
import react from '@vitejs/plugin-react'
-import { createHtmlPlugin } from 'vite-plugin-html'
import manifest from './public-typescript/manifest.json'
-function setupHtml() {
- const tags: Parameters[0] = {
- minify: false,
- inject: {
- tags: [],
- },
- }
-
- tags.inject?.tags?.push(
- ...([
- {
- tag: 'script',
- attrs: {
- src: manifest.index,
- },
- injectTo: 'head-prepend',
- },
- ] as HtmlTagDescriptor[]),
- )
- const htmlPlugin: PluginOption[] = createHtmlPlugin(tags)
- return htmlPlugin
-}
-
// https://vitejs.dev/config/
-export default defineConfig({
+export default defineConfig((env) => ({
define: {
haha: JSON.stringify('custom define!'),
app: JSON.stringify({ hello: 'world' }),
@@ -37,35 +13,47 @@ export default defineConfig({
plugins: [
react(),
{
- name: 'add-script',
- transformIndexHtml: {
- order: 'pre',
- handler(html) {
- const tags: HtmlTagDescriptor[] = [
- {
- tag: 'script',
- attrs: {
- src: manifest.test,
- },
- injectTo: 'head-prepend',
+ name: 'transform-demo',
+ async transformIndexHtml(html) {
+ const tags: HtmlTagDescriptor[] = [
+ {
+ tag: 'script',
+ attrs: {
+ 'src': manifest.test,
+ 'data-vppt': 'true',
},
- ]
+ injectTo: 'head-prepend',
+ },
+ ]
- return {
- html,
- tags,
- }
- },
+ html = html.replace('Vite + React + TS', env.command === 'build' ? 'build' : 'serve')
+
+ return {
+ html,
+ tags,
+ }
},
},
- setupHtml(),
publicTypescript({
inputDir: 'public-typescript',
manifestName: 'manifest',
hash: true,
outputDir: '/out',
- destination: 'file',
}),
+ injectScripts([
+ {
+ attrs: {
+ src: manifest.haha,
+ },
+ injectTo: 'head',
+ },
+ {
+ attrs: {
+ src: manifest.index,
+ },
+ injectTo: 'head-prepend',
+ },
+ ]),
],
clearScreen: true,
-})
+}))
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c1a4d14..72e245a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,9 +17,15 @@ importers:
fs-extra:
specifier: ^11.1.1
version: 11.1.1
+ magic-string:
+ specifier: ^0.30.3
+ version: 0.30.3
on-change:
specifier: ^4.0.2
version: 4.0.2
+ parse5:
+ specifier: ^7.1.2
+ version: 7.1.2
sirv:
specifier: ^2.0.3
version: 2.0.3
@@ -102,10 +108,7 @@ importers:
version: 4.9.5
vite:
specifier: 4.4.9
- version: 4.4.9(@types/node@20.6.0)
- vite-plugin-html:
- specifier: ^3.2.0
- version: 3.2.0(vite@4.4.9)
+ version: 4.4.9
vite-plugin-public-typescript:
specifier: workspace:*
version: link:../..
@@ -883,16 +886,8 @@ packages:
engines: {node: '>=6.0.0'}
dev: true
- /@jridgewell/source-map@0.3.5:
- resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
- dependencies:
- '@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
- dev: true
-
/@jridgewell/sourcemap-codec@1.4.15:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
- dev: true
/@jridgewell/trace-mapping@0.3.19:
resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
@@ -1151,14 +1146,6 @@ packages:
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
dev: false
- /@rollup/pluginutils@4.2.1:
- resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
- engines: {node: '>= 8.0.0'}
- dependencies:
- estree-walker: 2.0.2
- picomatch: 2.3.1
- dev: true
-
/@sigstore/bundle@1.1.0:
resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -1498,7 +1485,7 @@ packages:
'@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.17)
'@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.17)
react-refresh: 0.14.0
- vite: 4.4.9(@types/node@20.6.0)
+ vite: 4.4.9
transitivePeerDependencies:
- supports-color
dev: true
@@ -1757,10 +1744,6 @@ packages:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
dev: true
- /async@3.2.4:
- resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
- dev: true
-
/asynciterator.prototype@1.0.0:
resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==}
dependencies:
@@ -1836,10 +1819,6 @@ packages:
update-browserslist-db: 1.0.11(browserslist@4.21.10)
dev: true
- /buffer-from@1.1.2:
- resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
- dev: true
-
/builtin-modules@3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
@@ -1942,13 +1921,6 @@ packages:
engines: {node: '>=6'}
dev: true
- /camel-case@4.1.2:
- resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
- dependencies:
- pascal-case: 3.1.2
- tslib: 2.6.2
- dev: true
-
/caniuse-lite@1.0.30001534:
resolution: {integrity: sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==}
dev: true
@@ -2024,13 +1996,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /clean-css@5.3.2:
- resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==}
- engines: {node: '>= 10.0'}
- dependencies:
- source-map: 0.6.1
- dev: true
-
/clean-regexp@1.0.0:
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
engines: {node: '>=4'}
@@ -2082,20 +2047,11 @@ packages:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
dev: true
- /commander@2.20.3:
- resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
- dev: true
-
/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
dev: true
- /commander@8.3.0:
- resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
- engines: {node: '>= 12'}
- dev: true
-
/compressible@2.0.18:
resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
engines: {node: '>= 0.6'}
@@ -2122,15 +2078,6 @@ packages:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
- /connect-history-api-fallback@1.6.0:
- resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==}
- engines: {node: '>=0.8'}
- dev: true
-
- /consola@2.15.3:
- resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
- dev: true
-
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: true
@@ -2177,21 +2124,6 @@ packages:
which: 2.0.2
dev: true
- /css-select@4.3.0:
- resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
- dependencies:
- boolbase: 1.0.0
- css-what: 6.1.0
- domhandler: 4.3.1
- domutils: 2.8.0
- nth-check: 2.1.1
- dev: true
-
- /css-what@6.1.0:
- resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
- engines: {node: '>= 6'}
- dev: true
-
/cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@@ -2321,14 +2253,6 @@ packages:
esutils: 2.0.3
dev: true
- /dom-serializer@1.4.1:
- resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
- dependencies:
- domelementtype: 2.3.0
- domhandler: 4.3.1
- entities: 2.2.0
- dev: true
-
/dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies:
@@ -2341,13 +2265,6 @@ packages:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
dev: true
- /domhandler@4.3.1:
- resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
- engines: {node: '>= 4'}
- dependencies:
- domelementtype: 2.3.0
- dev: true
-
/domhandler@5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
@@ -2355,14 +2272,6 @@ packages:
domelementtype: 2.3.0
dev: true
- /domutils@2.8.0:
- resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
- dependencies:
- dom-serializer: 1.4.1
- domelementtype: 2.3.0
- domhandler: 4.3.1
- dev: true
-
/domutils@3.1.0:
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
dependencies:
@@ -2371,18 +2280,6 @@ packages:
domhandler: 5.0.3
dev: true
- /dot-case@3.0.4:
- resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
- dependencies:
- no-case: 3.0.4
- tslib: 2.6.2
- dev: true
-
- /dotenv-expand@8.0.3:
- resolution: {integrity: sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==}
- engines: {node: '>=12'}
- dev: true
-
/dotenv@16.3.1:
resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
engines: {node: '>=12'}
@@ -2396,14 +2293,6 @@ packages:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
dev: false
- /ejs@3.1.9:
- resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==}
- engines: {node: '>=0.10.0'}
- hasBin: true
- dependencies:
- jake: 10.8.7
- dev: true
-
/electron-to-chromium@1.4.519:
resolution: {integrity: sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg==}
dev: true
@@ -2429,14 +2318,9 @@ packages:
dev: true
optional: true
- /entities@2.2.0:
- resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
- dev: true
-
/entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
- dev: true
/env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
@@ -3037,10 +2921,6 @@ packages:
engines: {node: '>=4.0'}
dev: true
- /estree-walker@2.0.2:
- resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
- dev: true
-
/esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@@ -3164,12 +3044,6 @@ packages:
flat-cache: 3.1.0
dev: true
- /filelist@1.0.4:
- resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
- dependencies:
- minimatch: 5.1.6
- dev: true
-
/fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@@ -3250,15 +3124,6 @@ packages:
engines: {node: '>= 0.6'}
dev: false
- /fs-extra@10.1.0:
- resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
- engines: {node: '>=12'}
- dependencies:
- graceful-fs: 4.2.11
- jsonfile: 6.1.0
- universalify: 2.0.0
- dev: true
-
/fs-extra@11.1.1:
resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==}
engines: {node: '>=14.14'}
@@ -3529,11 +3394,6 @@ packages:
dependencies:
function-bind: 1.1.1
- /he@1.2.0:
- resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
- hasBin: true
- dev: true
-
/hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
dev: true
@@ -3545,20 +3405,6 @@ packages:
lru-cache: 7.18.3
dev: true
- /html-minifier-terser@6.1.0:
- resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==}
- engines: {node: '>=12'}
- hasBin: true
- dependencies:
- camel-case: 4.1.2
- clean-css: 5.3.2
- commander: 8.3.0
- he: 1.2.0
- param-case: 3.0.4
- relateurl: 0.2.7
- terser: 5.19.4
- dev: true
-
/htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
dependencies:
@@ -3934,17 +3780,6 @@ packages:
'@pkgjs/parseargs': 0.11.0
dev: true
- /jake@10.8.7:
- resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- async: 3.2.4
- chalk: 4.1.2
- filelist: 1.0.4
- minimatch: 3.1.2
- dev: true
-
/jiti@1.20.0:
resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==}
hasBin: true
@@ -4036,6 +3871,7 @@ packages:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.11
+ dev: false
/jsonparse@1.3.1:
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
@@ -4128,12 +3964,6 @@ packages:
get-func-name: 2.0.0
dev: true
- /lower-case@2.0.2:
- resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
- dependencies:
- tslib: 2.6.2
- dev: true
-
/lru-cache@10.0.1:
resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==}
engines: {node: 14 || >=16.14}
@@ -4162,7 +3992,6 @@ packages:
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
- dev: true
/make-fetch-happen@11.1.1:
resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==}
@@ -4282,13 +4111,6 @@ packages:
brace-expansion: 1.1.11
dev: true
- /minimatch@5.1.6:
- resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
- engines: {node: '>=10'}
- dependencies:
- brace-expansion: 2.0.1
- dev: true
-
/minimatch@9.0.3:
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -4437,13 +4259,6 @@ packages:
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
- /no-case@3.0.4:
- resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
- dependencies:
- lower-case: 2.0.2
- tslib: 2.6.2
- dev: true
-
/node-fetch-native@1.4.0:
resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==}
dev: true
@@ -4468,13 +4283,6 @@ packages:
- supports-color
dev: true
- /node-html-parser@5.4.2:
- resolution: {integrity: sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==}
- dependencies:
- css-select: 4.3.0
- he: 1.2.0
- dev: true
-
/node-releases@2.0.13:
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
dev: true
@@ -4804,13 +4612,6 @@ packages:
- supports-color
dev: true
- /param-case@3.0.4:
- resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
- dependencies:
- dot-case: 3.0.4
- tslib: 2.6.2
- dev: true
-
/parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
@@ -4839,18 +4640,17 @@ packages:
lines-and-columns: 1.2.4
dev: true
+ /parse5@7.1.2:
+ resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+ dependencies:
+ entities: 4.5.0
+ dev: false
+
/parseurl@1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
dev: false
- /pascal-case@3.1.2:
- resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
- dependencies:
- no-case: 3.0.4
- tslib: 2.6.2
- dev: true
-
/path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
@@ -4892,10 +4692,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /pathe@0.2.0:
- resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
- dev: true
-
/pathe@1.1.1:
resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
dev: true
@@ -5201,11 +4997,6 @@ packages:
jsesc: 0.5.0
dev: true
- /relateurl@0.2.7:
- resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
- engines: {node: '>= 0.10'}
- dev: true
-
/require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
@@ -5469,13 +5260,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /source-map-support@0.5.21:
- resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
- dependencies:
- buffer-from: 1.1.2
- source-map: 0.6.1
- dev: true
-
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
@@ -5712,17 +5496,6 @@ packages:
- supports-color
dev: true
- /terser@5.19.4:
- resolution: {integrity: sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- '@jridgewell/source-map': 0.3.5
- acorn: 8.10.0
- commander: 2.20.3
- source-map-support: 0.5.21
- dev: true
-
/text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
@@ -5815,10 +5588,6 @@ packages:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
- /tslib@2.6.2:
- resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
- dev: true
-
/tsup@7.2.0(typescript@5.2.2):
resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==}
engines: {node: '>=16.14'}
@@ -6014,6 +5783,7 @@ packages:
/universalify@2.0.0:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'}
+ dev: false
/unpipe@1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
@@ -6087,24 +5857,39 @@ packages:
- terser
dev: true
- /vite-plugin-html@3.2.0(vite@4.4.9):
- resolution: {integrity: sha512-2VLCeDiHmV/BqqNn5h2V+4280KRgQzCFN47cst3WiNK848klESPQnzuC3okH5XHtgwHH/6s1Ho/YV6yIO0pgoQ==}
+ /vite@4.4.9:
+ resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
peerDependencies:
- vite: '>=2.0.0'
+ '@types/node': '>= 14'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
dependencies:
- '@rollup/pluginutils': 4.2.1
- colorette: 2.0.20
- connect-history-api-fallback: 1.6.0
- consola: 2.15.3
- dotenv: 16.3.1
- dotenv-expand: 8.0.3
- ejs: 3.1.9
- fast-glob: 3.3.1
- fs-extra: 10.1.0
- html-minifier-terser: 6.1.0
- node-html-parser: 5.4.2
- pathe: 0.2.0
- vite: 4.4.9(@types/node@20.6.0)
+ esbuild: 0.18.20
+ postcss: 8.4.29
+ rollup: 3.29.1
+ optionalDependencies:
+ fsevents: 2.3.3
dev: true
/vite@4.4.9(@types/node@18.17.15):
diff --git a/src/helper/AbsCacheProcessor.ts b/src/helper/AbsCacheProcessor.ts
index 7ec10cd..af639c7 100644
--- a/src/helper/AbsCacheProcessor.ts
+++ b/src/helper/AbsCacheProcessor.ts
@@ -1,28 +1,59 @@
import { normalizePath } from 'vite'
-import type { TGlobalConfig } from './GlobalConfigBuilder'
+import createDebug from 'debug'
+import type { ManifestCache } from './ManifestCache'
+
+const debug = createDebug('vite-plugin-public-typescript:AbsCacheProcessor ===> ')
+
+export type BuildEndArgs = {
+ tsFileName: string
+ jsFileNameWithHash: string
+ code: string
+ contentHash: string
+}
export interface IDeleteFile {
- fileName: string
+ tsFileName: string
jsFileName?: string
- force?: boolean
+ silent?: boolean
}
export interface IAddFile {
code?: string
- fileName: string
+ tsFileName: string
contentHash: string
}
export abstract class AbsCacheProcessor {
+ cache: ManifestCache
abstract deleteOldJs(args: IDeleteFile): Promise
abstract addNewJs(args: IAddFile): Promise
- setCache(args: IAddFile, globalConfig: TGlobalConfig) {
- const { contentHash, code = '', fileName } = args
- const { cache, outputDir } = globalConfig
+
+ constructor(cache: ManifestCache) {
+ this.cache = cache
+ }
+
+ async onTsBuildEnd(args: BuildEndArgs) {
+ const { tsFileName, jsFileNameWithHash, code, contentHash } = args
+
+ debug('onTsBuildEnd:', args)
+
+ await this.deleteOldJs({ tsFileName, jsFileName: jsFileNameWithHash, silent: true })
+
+ await this.addNewJs({ code, tsFileName, contentHash })
+ }
+
+ setCache(
+ args: IAddFile,
+ config: {
+ outputDir: string
+ },
+ ) {
+ const { contentHash, code = '', tsFileName } = args
+ const { outputDir } = config
function getOutputPath(p: string, hash?: string) {
hash = hash ? `.${hash}` : ''
- return normalizePath(`${p}/${fileName}${hash}.js`)
+ return normalizePath(`${p}/${tsFileName}${hash}.js`)
}
let outputPath = getOutputPath(outputDir)
@@ -30,8 +61,8 @@ export abstract class AbsCacheProcessor {
outputPath = getOutputPath(outputDir, contentHash)
}
- cache.set({
- [fileName]: {
+ this.cache.set({
+ [tsFileName]: {
path: outputPath,
_code: code,
_hash: contentHash,
diff --git a/src/helper/FileCacheProcessor.ts b/src/helper/FileCacheProcessor.ts
index 19bf5eb..fe193c0 100644
--- a/src/helper/FileCacheProcessor.ts
+++ b/src/helper/FileCacheProcessor.ts
@@ -8,14 +8,19 @@ import { globalConfigBuilder } from './GlobalConfigBuilder'
import { AbsCacheProcessor } from './AbsCacheProcessor'
import type { IAddFile, IDeleteFile } from './AbsCacheProcessor'
import { writeFile } from './utils'
+import type { ManifestCache } from './ManifestCache'
const debug = createDebug('FileCacheProcessor ===> ')
// file-based processor
// the final output dir is base on `publicDir`
export class FileCacheProcessor extends AbsCacheProcessor {
+ constructor(cache: ManifestCache) {
+ super(cache)
+ }
+
async deleteOldJs(args: IDeleteFile): Promise {
- const { fileName, jsFileName = '', force = false } = args
+ const { tsFileName, jsFileName = '' } = args
const {
outputDir,
@@ -27,7 +32,7 @@ export class FileCacheProcessor extends AbsCacheProcessor {
try {
fs.ensureDirSync(path.join(publicDir, outputDir))
- oldFiles = await glob(normalizePath(path.join(publicDir, `${outputDir}/${fileName}.?(*.)js`)))
+ oldFiles = await glob(normalizePath(path.join(publicDir, `${outputDir}/${tsFileName}.?(*.)js`)))
} catch (e) {
console.error(e)
}
@@ -45,18 +50,16 @@ export class FileCacheProcessor extends AbsCacheProcessor {
continue
} // skip repeat js file
if (fs.existsSync(f)) {
- debug('deleteOldJsFile - file exists:', f, fileName)
- if (cache.getByKey(fileName) || force) {
- cache.remove(fileName)
- debug('deleteOldJsFile - cache removed:', fileName)
- fs.remove(f)
- debug('deleteOldJsFile -file removed:', f)
- }
+ debug('deleteOldJsFile - file exists:', f, tsFileName)
+ cache.remove(tsFileName)
+ debug('deleteOldJsFile - cache removed:', tsFileName)
+ fs.remove(f)
+ debug('deleteOldJsFile -file removed:', f)
}
}
- } else if (force) {
- cache.remove(fileName)
- debug('cache force removed:', fileName)
+ } else {
+ cache.remove(tsFileName)
+ debug('cache removed:', tsFileName)
}
}
diff --git a/src/helper/ManifestCache.ts b/src/helper/ManifestCache.ts
index d2f240a..98686af 100644
--- a/src/helper/ManifestCache.ts
+++ b/src/helper/ManifestCache.ts
@@ -7,8 +7,11 @@ import { eq, isEmptyObject, writeFile } from './utils'
const debug = createDebug('vite-plugin-public-typescript:ManifestCache ===> ')
+type PathOnlyCache = Record
+
export interface IManifestConstructor {
watchMode?: boolean
+ write?: boolean
onChange?: (path: string, value: ValueType, previousValue: ValueType, applyData: ApplyData) => void
}
@@ -32,17 +35,31 @@ export type TDefaultCache = {
[fileName in string]: TCacheValue
}
+const DEFAULT_OPTIONS: IManifestConstructor = {
+ watchMode: true,
+ write: true,
+}
+
export class ManifestCache {
private cache: T
private manifestPath = ''
- constructor(options?: IManifestConstructor) {
+ private inited = false
+
+ constructor(options?: IManifestConstructor) {
+ options = {
+ ...DEFAULT_OPTIONS,
+ ...options,
+ }
+
if (options?.watchMode) {
- this.cache = onChange({} as T, async (...args) => {
- options.onChange?.(...args)
- await this.writeManifestJSON()
+ this.cache = onChange({} as T, (...args) => {
debug('cache changed:', this.cache)
+ options!.onChange?.(...args)
+ if (options!.write) {
+ this.writeManifestJSON()
+ }
})
} else {
this.cache = Object.create(null)
@@ -70,10 +87,15 @@ export class ManifestCache {
return this.cache[k]
}
- remove(k: keyof T) {
- if (this.cache[k]) {
- delete this.cache[k]
+ remove(k: keyof T, opts?: { disableWatch?: boolean }) {
+ if (opts?.disableWatch) {
+ delete onChange.target(this.cache)[k]
+ } else {
+ if (this.cache[k]) {
+ delete this.cache[k]
+ }
}
+
return this
}
@@ -82,6 +104,10 @@ export class ManifestCache {
}
readManifestFromFile() {
+ if (!fs.existsSync(this.getManifestPath())) {
+ return {}
+ }
+
const cacheJson = fs.readFileSync(this.getManifestPath(), 'utf-8')
if (cacheJson) {
return JSON.parse(cacheJson)
@@ -92,6 +118,7 @@ export class ManifestCache {
setManifestPath(p: string) {
this.manifestPath = p
+ fs.ensureDirSync(path.dirname(p))
}
getManifestPath() {
@@ -100,19 +127,45 @@ export class ManifestCache {
extractPath(c: T) {
const cache = Object.assign({}, c)
- const pathOnlyCache: Record = {}
+ const pathOnlyCache: PathOnlyCache = {}
for (const key in cache) {
pathOnlyCache[key] = cache[key].path
}
return pathOnlyCache
}
- async writeManifestJSON() {
- const targetPath = this.getManifestPath()
+ recoverPath(c: PathOnlyCache) {
+ const cache = Object.assign({}, c)
+ const recoveredCache = {} as TDefaultCache
+ for (const key in cache) {
+ recoveredCache[key] = {
+ path: cache[key],
+ _code: '',
+ }
+ }
+ return recoveredCache as T
+ }
+
+ getManifestJson() {
+ return this.extractPath(this.get())
+ }
- await fs.ensureDir(path.dirname(targetPath))
+ initCacheFromFile() {
+ if (this.inited) return
+ this.inited = true
- const cacheObj = this.extractPath(this.get())
+ const parsedCache = this.readManifestFromFile()
+
+ if (!isEmptyObject(parsedCache)) {
+ const cache = this.recoverPath(parsedCache)
+ this.set(cache, { disableWatch: true })
+ }
+ }
+
+ writeManifestJSON() {
+ const targetPath = this.getManifestPath()
+
+ const cacheObj = this.getManifestJson()
const orderdCache = Object.assign({}, cacheObj)
const parsedCache = this.readManifestFromFile()
@@ -121,7 +174,10 @@ export class ManifestCache {
return
}
- debug('write manifest json:', JSON.stringify(orderdCache || {}, null, 2))
writeFile(targetPath, JSON.stringify(orderdCache || {}, null, 2))
+
+ debug('write manifest json:', JSON.stringify(orderdCache || {}, null, 2))
+
+ return orderdCache
}
}
diff --git a/src/helper/MemoryCacheProcessor.ts b/src/helper/MemoryCacheProcessor.ts
index d714140..716b62f 100644
--- a/src/helper/MemoryCacheProcessor.ts
+++ b/src/helper/MemoryCacheProcessor.ts
@@ -1,13 +1,16 @@
import { AbsCacheProcessor } from './AbsCacheProcessor'
import type { IAddFile, IDeleteFile } from './AbsCacheProcessor'
import { globalConfigBuilder } from './GlobalConfigBuilder'
+import type { ManifestCache } from './ManifestCache'
export class MemoryCacheProcessor extends AbsCacheProcessor {
- async deleteOldJs(args: IDeleteFile): Promise {
- const { fileName } = args
- const { cache } = globalConfigBuilder.get()
+ constructor(cache: ManifestCache) {
+ super(cache)
+ }
- cache.remove(fileName)
+ async deleteOldJs(args: IDeleteFile): Promise {
+ const { tsFileName, silent } = args
+ this.cache.remove(tsFileName, { disableWatch: silent })
}
async addNewJs(args: IAddFile): Promise {
diff --git a/src/helper/build.ts b/src/helper/build.ts
index 8ef903a..4e386bb 100644
--- a/src/helper/build.ts
+++ b/src/helper/build.ts
@@ -7,6 +7,7 @@ import type { VPPTPluginOptions } from '..'
import { name } from '../../package.json'
import { globalConfigBuilder } from './GlobalConfigBuilder'
import { getContentHash } from './utils'
+import type { BuildEndArgs } from './AbsCacheProcessor'
const debug = createDebug('vite-plugin-public-typescript:build ===> ')
@@ -100,25 +101,38 @@ export async function esbuildTypescript(buildOptions: IBuildOptions) {
return code
}
-export async function build(options: { filePath: string }) {
+export async function build(options: { filePath: string }, onBuildEnd?: (args: BuildEndArgs) => Promise) {
const { filePath } = options
const globalConfig = globalConfigBuilder.get()
- const fileName = path.basename(filePath, path.extname(filePath))
+ const originFileName = path.basename(filePath, path.extname(filePath))
let contentHash = ''
- let fileNameWithHash = fileName
+ let fileNameWithHash = originFileName
- const code = await esbuildTypescript({ filePath, ...globalConfig })
+ const code = (await esbuildTypescript({ filePath, ...globalConfig })) || ''
if (globalConfig.hash) {
contentHash = getContentHash(code, globalConfig.hash)
- fileNameWithHash = `${fileName}.${contentHash}`
+ fileNameWithHash = `${originFileName}.${contentHash}`
}
- await globalConfig.cacheProcessor.deleteOldJs({ fileName, jsFileName: fileNameWithHash })
+ debug('before onBuildEnd cache:', globalConfig.cache.get())
- await globalConfig.cacheProcessor.addNewJs({ code, fileName, contentHash })
+ await onBuildEnd?.({
+ tsFileName: originFileName,
+ jsFileNameWithHash: fileNameWithHash,
+ code,
+ contentHash,
+ })
- debug('cacheManifest:', globalConfig.cache.get())
+ debug('after onBuildEnd cache:', globalConfig.cache.get())
+}
+
+export async function buildAll(tsFilesGlob: string[]) {
+ const { cacheProcessor } = globalConfigBuilder.get()
+
+ for (const file of tsFilesGlob) {
+ await build({ filePath: file }, (args) => cacheProcessor.onTsBuildEnd(args))
+ }
}
diff --git a/src/helper/html.ts b/src/helper/html.ts
new file mode 100644
index 0000000..fcb3f91
--- /dev/null
+++ b/src/helper/html.ts
@@ -0,0 +1,73 @@
+import type { DefaultTreeAdapterMap, ParserError, Token } from 'parse5'
+
+export const VPPT_DATA_ATTR = 'data-vppt'
+
+export async function traverseHtml(
+ html: string,
+ filePath: string,
+ visitor: (node: DefaultTreeAdapterMap['node']) => void,
+): Promise {
+ const { parse } = await import('parse5')
+ const ast = parse(html, {
+ scriptingEnabled: false, // parse inside