diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41a5a096fb3bd2..27921e06ac8f9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@04124efe7560d15e11ea2ba96c0df2989f68f1f4 # v35.6.1 + uses: tj-actions/changed-files@9328bab880abf4acc377d77718d28c6ac167f154 # v35.7.2 with: files: | docs/** diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index ad9b8942e53712..977420800979cf 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -94,10 +94,6 @@ export default defineConfig({ pt: { label: 'Português', link: 'https://pt.vitejs.dev' }, }, - vue: { - reactivityTransform: true, - }, - themeConfig: { logo: '/logo.svg', diff --git a/docs/config/build-options.md b/docs/config/build-options.md index b9971fdb383f64..ff4dbbd50e3bbf 100644 --- a/docs/config/build-options.md +++ b/docs/config/build-options.md @@ -10,7 +10,7 @@ Browser compatibility target for the final bundle. The default value is a Vite s Another special value is `'esnext'` - which assumes native dynamic imports support and will transpile as little as possible: -- If the [`build.minify`](#build-minify) option is `'terser'`, `'esnext'` will be forced down to `'es2021'`. +- If the [`build.minify`](#build-minify) option is `'terser'` and the installed Terser version is below 5.16.0, `'esnext'` will be forced down to `'es2021'`. - In other cases, it will perform no transpilation at all. The transform is performed with esbuild and the value should be a valid [esbuild target option](https://esbuild.github.io/api/#target). Custom targets can either be an ES version (e.g. `es2015`), a browser with version (e.g. `chrome58`), or an array of multiple target strings. diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md index c66374ae1247e2..41086c8d3404df 100644 --- a/docs/guide/api-javascript.md +++ b/docs/guide/api-javascript.md @@ -198,6 +198,46 @@ import { preview } from 'vite' })() ``` +## `PreviewServer` + +```ts +interface PreviewServer extends PreviewServerForHook { + resolvedUrls: ResolvedServerUrls +} +``` + +## `PreviewServerForHook` + +```ts +interface PreviewServerForHook { + /** + * The resolved vite config object + */ + config: ResolvedConfig + /** + * A connect app instance. + * - Can be used to attach custom middlewares to the preview server. + * - Can also be used as the handler function of a custom http server + * or as a middleware in any connect-style Node.js frameworks + * + * https://github.com/senchalabs/connect#use-middleware + */ + middlewares: Connect.Server + /** + * native Node http server instance + */ + httpServer: http.Server + /** + * The resolved urls Vite prints on the CLI + */ + resolvedUrls: ResolvedServerUrls | null + /** + * Print server urls + */ + printUrls(): void +} +``` + ## `resolveConfig` **Type Signature:** diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md index 9347c84e6f10e8..d5f92bad9ad879 100644 --- a/docs/guide/api-plugin.md +++ b/docs/guide/api-plugin.md @@ -309,10 +309,11 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo ### `configurePreviewServer` -- **Type:** `(server: { middlewares: Connect.Server, httpServer: http.Server }) => (() => void) | void | Promise<(() => void) | void>` +- **Type:** `(server: PreviewServerForHook) => (() => void) | void | Promise<(() => void) | void>` - **Kind:** `async`, `sequential` +- **See also:** [PreviewServerForHook](./api-javascript#previewserverforhook) - Same as [`configureServer`](/guide/api-plugin.html#configureserver) but for the preview server. It provides the [connect](https://github.com/senchalabs/connect) server and its underlying [http server](https://nodejs.org/api/http.html). Similarly to `configureServer`, the `configurePreviewServer` hook is called before other middlewares are installed. If you want to inject a middleware **after** other middlewares, you can return a function from `configurePreviewServer`, which will be called after internal middlewares are installed: + Same as [`configureServer`](/guide/api-plugin.html#configureserver) but for the preview server. Similarly to `configureServer`, the `configurePreviewServer` hook is called before other middlewares are installed. If you want to inject a middleware **after** other middlewares, you can return a function from `configurePreviewServer`, which will be called after internal middlewares are installed: ```js const myPlugin = () => ({ diff --git a/package.json b/package.json index a2ae5066bd3c4c..0964c0a12864c9 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "ci-docs": "run-s build docs-build" }, "devDependencies": { - "@babel/types": "^7.21.2", + "@babel/types": "^7.21.3", "@microsoft/api-extractor": "^7.34.4", "@rollup/plugin-typescript": "^11.0.0", "@types/babel__core": "^7.20.0", @@ -51,26 +51,26 @@ "@types/less": "^3.0.3", "@types/micromatch": "^4.0.2", "@types/minimist": "^1.2.2", - "@types/node": "^18.14.6", + "@types/node": "^18.15.5", "@types/picomatch": "^2.3.0", - "@types/prompts": "^2.4.2", + "@types/prompts": "2.4.2", "@types/resolve": "^1.20.2", "@types/sass": "~1.43.1", "@types/semver": "^7.3.13", "@types/stylus": "^0.48.38", "@types/ws": "^8.5.4", - "@typescript-eslint/eslint-plugin": "^5.54.1", - "@typescript-eslint/parser": "^5.54.1", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "@typescript-eslint/parser": "^5.56.0", "conventional-changelog-cli": "^2.2.2", - "eslint": "^8.35.0", - "eslint-define-config": "^1.15.0", + "eslint": "^8.36.0", + "eslint-define-config": "^1.17.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-regexp": "^1.12.0", - "execa": "^7.0.0", + "eslint-plugin-regexp": "^1.13.0", + "execa": "^7.1.1", "fast-glob": "^3.2.12", - "fs-extra": "^11.1.0", - "lint-staged": "^13.1.2", + "fs-extra": "^11.1.1", + "lint-staged": "^13.2.0", "minimist": "^1.2.8", "npm-run-all": "^4.1.5", "picocolors": "^1.0.0", @@ -78,17 +78,17 @@ "prettier": "2.8.5", "prompts": "^2.4.2", "resolve": "^1.22.1", - "rimraf": "^4.1.2", - "rollup": "^3.18.0", + "rimraf": "^4.4.0", + "rollup": "^3.20.0", "semver": "^7.3.8", "simple-git-hooks": "^2.8.1", "tslib": "^2.5.0", - "tsx": "^3.12.3", + "tsx": "^3.12.6", "typescript": "^5.0.2", "unbuild": "^1.1.2", "vite": "workspace:*", - "vitepress": "^1.0.0-alpha.49", - "vitest": "^0.29.2", + "vitepress": "^1.0.0-alpha.61", + "vitest": "^0.29.7", "vue": "^3.2.47" }, "simple-git-hooks": { @@ -108,7 +108,7 @@ "eslint --cache --fix" ] }, - "packageManager": "pnpm@7.29.0", + "packageManager": "pnpm@7.30.0", "pnpm": { "overrides": { "vite": "workspace:*" @@ -127,7 +127,8 @@ }, "patchedDependencies": { "dotenv-expand@9.0.0": "patches/dotenv-expand@9.0.0.patch", - "sirv@2.0.2": "patches/sirv@2.0.2.patch" + "sirv@2.0.2": "patches/sirv@2.0.2.patch", + "chokidar@3.5.3": "patches/chokidar@3.5.3.patch" } }, "stackblitz": { diff --git a/packages/create-vite/template-lit-ts/package.json b/packages/create-vite/template-lit-ts/package.json index f03ef9ce12cae0..a564069837d479 100644 --- a/packages/create-vite/template-lit-ts/package.json +++ b/packages/create-vite/template-lit-ts/package.json @@ -3,24 +3,16 @@ "private": true, "version": "0.0.0", "type": "module", - "main": "dist/my-element.es.js", - "exports": { - ".": "./dist/my-element.es.js" - }, - "types": "types/my-element.d.ts", - "files": [ - "dist", - "types" - ], "scripts": { "dev": "vite", - "build": "tsc && vite build" + "build": "tsc && vite build", + "preview": "vite preview" }, "dependencies": { "lit": "^2.6.1" }, "devDependencies": { "typescript": "^5.0.2", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-lit-ts/tsconfig.json b/packages/create-vite/template-lit-ts/tsconfig.json index 29cdf0855ca3cb..f7c83877a73947 100644 --- a/packages/create-vite/template-lit-ts/tsconfig.json +++ b/packages/create-vite/template-lit-ts/tsconfig.json @@ -2,9 +2,7 @@ "compilerOptions": { "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], - "declaration": true, - "emitDeclarationOnly": true, - "outDir": "./types", + "noEmit": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, @@ -16,6 +14,5 @@ "useDefineForClassFields": false, "skipLibCheck": true }, - "include": ["src/**/*.ts"], - "references": [{ "path": "./tsconfig.node.json" }] + "include": ["src"] } diff --git a/packages/create-vite/template-lit-ts/tsconfig.node.json b/packages/create-vite/template-lit-ts/tsconfig.node.json deleted file mode 100644 index a535f7d4d20b7d..00000000000000 --- a/packages/create-vite/template-lit-ts/tsconfig.node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/packages/create-vite/template-lit-ts/vite.config.ts b/packages/create-vite/template-lit-ts/vite.config.ts deleted file mode 100644 index fe69491e390523..00000000000000 --- a/packages/create-vite/template-lit-ts/vite.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { defineConfig } from 'vite' - -// https://vitejs.dev/config/ -export default defineConfig({ - build: { - lib: { - entry: 'src/my-element.ts', - formats: ['es'], - }, - rollupOptions: { - external: /^lit/, - }, - }, -}) diff --git a/packages/create-vite/template-lit/package.json b/packages/create-vite/template-lit/package.json index d6dbd42d941a89..bbabef0a7ab0de 100644 --- a/packages/create-vite/template-lit/package.json +++ b/packages/create-vite/template-lit/package.json @@ -3,21 +3,15 @@ "private": true, "version": "0.0.0", "type": "module", - "main": "dist/my-element.es.js", - "exports": { - ".": "./dist/my-element.es.js" - }, - "files": [ - "dist" - ], "scripts": { "dev": "vite", - "build": "vite build" + "build": "vite build", + "preview": "vite preview" }, "dependencies": { "lit": "^2.6.1" }, "devDependencies": { - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-lit/vite.config.js b/packages/create-vite/template-lit/vite.config.js deleted file mode 100644 index 3847c1f38466f1..00000000000000 --- a/packages/create-vite/template-lit/vite.config.js +++ /dev/null @@ -1,14 +0,0 @@ -import { defineConfig } from 'vite' - -// https://vitejs.dev/config/ -export default defineConfig({ - build: { - lib: { - entry: 'src/my-element.js', - formats: ['es'], - }, - rollupOptions: { - external: /^lit/, - }, - }, -}) diff --git a/packages/create-vite/template-preact-ts/package.json b/packages/create-vite/template-preact-ts/package.json index d01991df5d2a79..6cb020637d5b92 100644 --- a/packages/create-vite/template-preact-ts/package.json +++ b/packages/create-vite/template-preact-ts/package.json @@ -9,11 +9,11 @@ "preview": "vite preview" }, "dependencies": { - "preact": "^10.13.0" + "preact": "^10.13.1" }, "devDependencies": { "@preact/preset-vite": "^2.5.0", "typescript": "^5.0.2", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-preact/package.json b/packages/create-vite/template-preact/package.json index f723768617a466..d0c6f57889eab8 100644 --- a/packages/create-vite/template-preact/package.json +++ b/packages/create-vite/template-preact/package.json @@ -9,10 +9,10 @@ "preview": "vite preview" }, "dependencies": { - "preact": "^10.13.0" + "preact": "^10.13.1" }, "devDependencies": { "@preact/preset-vite": "^2.5.0", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-react-ts/package.json b/packages/create-vite/template-react-ts/package.json index 1ae5d063c73f0d..e2abde2865cab5 100644 --- a/packages/create-vite/template-react-ts/package.json +++ b/packages/create-vite/template-react-ts/package.json @@ -17,6 +17,6 @@ "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^3.1.0", "typescript": "^5.0.2", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-react/package.json b/packages/create-vite/template-react/package.json index 19640fbd37aad6..069c2fd92e1529 100644 --- a/packages/create-vite/template-react/package.json +++ b/packages/create-vite/template-react/package.json @@ -16,6 +16,6 @@ "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^3.1.0", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-svelte-ts/package.json b/packages/create-vite/template-svelte-ts/package.json index f720373d9a20d4..2ff225ea8cce84 100644 --- a/packages/create-vite/template-svelte-ts/package.json +++ b/packages/create-vite/template-svelte-ts/package.json @@ -12,10 +12,10 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.3", "@tsconfig/svelte": "^3.0.0", - "svelte": "^3.55.1", + "svelte": "^3.57.0", "svelte-check": "^2.10.3", "tslib": "^2.5.0", "typescript": "^5.0.2", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-svelte/package.json b/packages/create-vite/template-svelte/package.json index b33e29c76a5375..b60657da9326c2 100644 --- a/packages/create-vite/template-svelte/package.json +++ b/packages/create-vite/template-svelte/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.3", - "svelte": "^3.55.1", - "vite": "^4.2.0" + "svelte": "^3.57.0", + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-vanilla-ts/package.json b/packages/create-vite/template-vanilla-ts/package.json index 27faf90d5750dc..54e3a8b4823809 100644 --- a/packages/create-vite/template-vanilla-ts/package.json +++ b/packages/create-vite/template-vanilla-ts/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "typescript": "^5.0.2", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-vanilla/package.json b/packages/create-vite/template-vanilla/package.json index 9de9447933d69f..78a6bf0c5c4df7 100644 --- a/packages/create-vite/template-vanilla/package.json +++ b/packages/create-vite/template-vanilla/package.json @@ -9,6 +9,6 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/create-vite/template-vue-ts/package.json b/packages/create-vite/template-vue-ts/package.json index 0f80a4f0630cc9..ca3a713e2d8e4f 100644 --- a/packages/create-vite/template-vue-ts/package.json +++ b/packages/create-vite/template-vue-ts/package.json @@ -14,7 +14,7 @@ "devDependencies": { "@vitejs/plugin-vue": "^4.1.0", "typescript": "^5.0.2", - "vite": "^4.2.0", + "vite": "^4.2.1", "vue-tsc": "^1.2.0" } } diff --git a/packages/create-vite/template-vue/package.json b/packages/create-vite/template-vue/package.json index 754830b42723d5..231f9af78a67a2 100644 --- a/packages/create-vite/template-vue/package.json +++ b/packages/create-vite/template-vue/package.json @@ -13,6 +13,6 @@ }, "devDependencies": { "@vitejs/plugin-vue": "^4.1.0", - "vite": "^4.2.0" + "vite": "^4.2.1" } } diff --git a/packages/plugin-legacy/package.json b/packages/plugin-legacy/package.json index 4693a1338f99fb..80ed27af7cf374 100644 --- a/packages/plugin-legacy/package.json +++ b/packages/plugin-legacy/package.json @@ -41,10 +41,10 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-legacy#readme", "dependencies": { - "@babel/core": "^7.21.0", + "@babel/core": "^7.21.3", "@babel/preset-env": "^7.20.2", "browserslist": "^4.21.5", - "core-js": "^3.29.0", + "core-js": "^3.29.1", "magic-string": "^0.30.0", "regenerator-runtime": "^0.13.11", "systemjs": "^6.14.0" diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index 1d67de9254d524..eed7071b10ab7b 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,54 @@ +## 4.3.0-beta.0 (2023-03-23) + +* perf: avoid execSync on openBrowser (#12510) ([a2af2f0](https://github.com/vitejs/vite/commit/a2af2f0)), closes [#12510](https://github.com/vitejs/vite/issues/12510) +* perf: extract regex and use Map in data-uri plugin (#12500) ([137e63d](https://github.com/vitejs/vite/commit/137e63d)), closes [#12500](https://github.com/vitejs/vite/issues/12500) +* perf: extract vite:resolve internal functions (#12522) ([6ea4be2](https://github.com/vitejs/vite/commit/6ea4be2)), closes [#12522](https://github.com/vitejs/vite/issues/12522) +* perf: improve package cache usage (#12512) ([abc2b9c](https://github.com/vitejs/vite/commit/abc2b9c)), closes [#12512](https://github.com/vitejs/vite/issues/12512) +* perf: more regex improvements (#12520) ([abf536f](https://github.com/vitejs/vite/commit/abf536f)), closes [#12520](https://github.com/vitejs/vite/issues/12520) +* perf: regex to startsWith/slice in utils (#12532) ([debc6e2](https://github.com/vitejs/vite/commit/debc6e2)), closes [#12532](https://github.com/vitejs/vite/issues/12532) +* perf: remove regex in ImportMetaURL plugins (#12502) ([1030049](https://github.com/vitejs/vite/commit/1030049)), closes [#12502](https://github.com/vitejs/vite/issues/12502) +* perf: replace endsWith with === (#12539) ([7eb52ec](https://github.com/vitejs/vite/commit/7eb52ec)), closes [#12539](https://github.com/vitejs/vite/issues/12539) +* perf: replace startsWith with === (#12531) ([9cce026](https://github.com/vitejs/vite/commit/9cce026)), closes [#12531](https://github.com/vitejs/vite/issues/12531) +* perf: reuse regex in plugins (#12518) ([da43936](https://github.com/vitejs/vite/commit/da43936)), closes [#12518](https://github.com/vitejs/vite/issues/12518) +* perf: use `safeRealpath` in `getRealpath` (#12551) ([cec2320](https://github.com/vitejs/vite/commit/cec2320)), closes [#12551](https://github.com/vitejs/vite/issues/12551) +* perf(css): improve postcss config resolve (#12484) ([58e99b6](https://github.com/vitejs/vite/commit/58e99b6)), closes [#12484](https://github.com/vitejs/vite/issues/12484) +* perf(esbuild): make tsconfck non-blocking (#12548) ([e5cdff7](https://github.com/vitejs/vite/commit/e5cdff7)), closes [#12548](https://github.com/vitejs/vite/issues/12548) +* perf(esbuild): update tsconfck to consume faster find-all implementation (#12541) ([b6ea25a](https://github.com/vitejs/vite/commit/b6ea25a)), closes [#12541](https://github.com/vitejs/vite/issues/12541) +* perf(resolve): fix browser mapping nearest package.json check (#12550) ([eac376e](https://github.com/vitejs/vite/commit/eac376e)), closes [#12550](https://github.com/vitejs/vite/issues/12550) +* perf(resolve): improve package.json resolve speed (#12441) ([1fc8c65](https://github.com/vitejs/vite/commit/1fc8c65)), closes [#12441](https://github.com/vitejs/vite/issues/12441) +* perf(resolve): refactor package.json handling for deep imports (#12461) ([596b661](https://github.com/vitejs/vite/commit/596b661)), closes [#12461](https://github.com/vitejs/vite/issues/12461) +* perf(resolve): refactor tryFsResolve and tryResolveFile (#12542) ([3f70f47](https://github.com/vitejs/vite/commit/3f70f47)) +* perf(resolve): skip absolute paths in root as url checks (#12476) ([8d2931b](https://github.com/vitejs/vite/commit/8d2931b)), closes [#12476](https://github.com/vitejs/vite/issues/12476) +* perf(resolve): support # in path only for dependencies (#12469) ([6559fc7](https://github.com/vitejs/vite/commit/6559fc7)), closes [#12469](https://github.com/vitejs/vite/issues/12469) +* fix: avoid crash because of no access permission (#12552) ([eea1682](https://github.com/vitejs/vite/commit/eea1682)), closes [#12552](https://github.com/vitejs/vite/issues/12552) +* fix: esbuild complains with extra fields (#12516) ([7be0ba5](https://github.com/vitejs/vite/commit/7be0ba5)), closes [#12516](https://github.com/vitejs/vite/issues/12516) +* fix: escape replacements in clientInjections (#12486) ([3765067](https://github.com/vitejs/vite/commit/3765067)), closes [#12486](https://github.com/vitejs/vite/issues/12486) +* fix: open browser reuse logic (#12535) ([04d14af](https://github.com/vitejs/vite/commit/04d14af)), closes [#12535](https://github.com/vitejs/vite/issues/12535) +* fix: prevent error on not set location href (#12494) ([2fb8527](https://github.com/vitejs/vite/commit/2fb8527)), closes [#12494](https://github.com/vitejs/vite/issues/12494) +* fix: simplify prettyUrl (#12488) ([ebe5aa5](https://github.com/vitejs/vite/commit/ebe5aa5)), closes [#12488](https://github.com/vitejs/vite/issues/12488) +* fix(config): add random number to temp transpiled file (#12150) ([2b2ba61](https://github.com/vitejs/vite/commit/2b2ba61)), closes [#12150](https://github.com/vitejs/vite/issues/12150) +* fix(deps): update all non-major dependencies (#12389) ([3e60b77](https://github.com/vitejs/vite/commit/3e60b77)), closes [#12389](https://github.com/vitejs/vite/issues/12389) +* fix(html): public asset urls always being treated as paths (fix #11857) (#11870) ([46d1352](https://github.com/vitejs/vite/commit/46d1352)), closes [#11857](https://github.com/vitejs/vite/issues/11857) [#11870](https://github.com/vitejs/vite/issues/11870) +* fix(ssr): hoist import statements to the top (#12274) ([33baff5](https://github.com/vitejs/vite/commit/33baff5)), closes [#12274](https://github.com/vitejs/vite/issues/12274) +* fix(ssr): hoist re-exports with imports (#12530) ([45549e4](https://github.com/vitejs/vite/commit/45549e4)), closes [#12530](https://github.com/vitejs/vite/issues/12530) +* feat: add opus filetype to assets & mime types (#12526) ([63524ba](https://github.com/vitejs/vite/commit/63524ba)), closes [#12526](https://github.com/vitejs/vite/issues/12526) +* refactor: esbuild plugin config logic (#12493) ([45b5b0f](https://github.com/vitejs/vite/commit/45b5b0f)), closes [#12493](https://github.com/vitejs/vite/issues/12493) +* chore: better error hint for data URI mime type (#12496) ([0cb9171](https://github.com/vitejs/vite/commit/0cb9171)), closes [#12496](https://github.com/vitejs/vite/issues/12496) +* chore: remove unneded async in resolveId hook (#12499) ([e6337aa](https://github.com/vitejs/vite/commit/e6337aa)), closes [#12499](https://github.com/vitejs/vite/issues/12499) +* chore: upgrade rollup 3.20.0 (#12497) ([7288a24](https://github.com/vitejs/vite/commit/7288a24)), closes [#12497](https://github.com/vitejs/vite/issues/12497) +* build: should generate Hi-res sourcemap for dev (#12501) ([1502617](https://github.com/vitejs/vite/commit/1502617)), closes [#12501](https://github.com/vitejs/vite/issues/12501) + + + +## 4.2.1 (2023-03-20) + +* fix: add `virtual:` to virtual module source map ignore (#12444) ([c4aa28f](https://github.com/vitejs/vite/commit/c4aa28f)), closes [#12444](https://github.com/vitejs/vite/issues/12444) +* fix(css): inject source content conditionally (#12449) ([3e665f6](https://github.com/vitejs/vite/commit/3e665f6)), closes [#12449](https://github.com/vitejs/vite/issues/12449) +* fix(worker): using data URLs for inline shared worker (#12014) ([79a5007](https://github.com/vitejs/vite/commit/79a5007)), closes [#12014](https://github.com/vitejs/vite/issues/12014) +* chore: changelog edits for 4.2 (#12438) ([ce047e3](https://github.com/vitejs/vite/commit/ce047e3)), closes [#12438](https://github.com/vitejs/vite/issues/12438) + + + ## 4.2.0 (2023-03-16) Vite 4.2 is out! diff --git a/packages/vite/client.d.ts b/packages/vite/client.d.ts index a7182c8fd454d9..b55e4eba33d41c 100644 --- a/packages/vite/client.d.ts +++ b/packages/vite/client.d.ts @@ -173,6 +173,11 @@ declare module '*.aac' { export default src } +declare module '*.opus' { + const src: string + export default src +} + // fonts declare module '*.woff' { const src: string diff --git a/packages/vite/package.json b/packages/vite/package.json index 31a2edc17f91cf..c0cda5f120aa97 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "4.2.0", + "version": "4.3.0-beta.0", "type": "module", "license": "MIT", "author": "Evan You", @@ -69,15 +69,15 @@ "esbuild": "^0.17.5", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.18.0" + "rollup": "^3.20.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "devDependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", "@jridgewell/trace-mapping": "^0.3.17", "@rollup/plugin-alias": "^4.0.3", "@rollup/plugin-commonjs": "^24.0.1", @@ -86,6 +86,7 @@ "@rollup/plugin-node-resolve": "15.0.1", "@rollup/plugin-typescript": "^11.0.0", "@rollup/pluginutils": "^5.0.2", + "@types/pnpapi": "^0.0.2", "acorn": "^8.8.2", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -108,7 +109,7 @@ "launch-editor-middleware": "^2.6.0", "magic-string": "^0.30.0", "micromatch": "^4.0.5", - "mlly": "^1.1.1", + "mlly": "^1.2.0", "mrmime": "^1.0.1", "okie": "^1.0.1", "open": "^8.4.2", @@ -126,11 +127,11 @@ "source-map-support": "^0.5.21", "strip-ansi": "^7.0.1", "strip-literal": "^1.0.1", - "tsconfck": "^2.1.0", + "tsconfck": "^2.1.1", "tslib": "^2.5.0", "types": "link:./types", "ufo": "^1.1.1", - "ws": "^8.12.1" + "ws": "^8.13.0" }, "peerDependencies": { "@types/node": ">= 14", diff --git a/packages/vite/rollup.config.ts b/packages/vite/rollup.config.ts index 51f40a09b72995..e241a77182c4c7 100644 --- a/packages/vite/rollup.config.ts +++ b/packages/vite/rollup.config.ts @@ -300,7 +300,7 @@ const __require = require; return { code: s.toString(), - map: s.generateMap(), + map: s.generateMap({ hires: true }), } }, } diff --git a/packages/vite/scripts/util.ts b/packages/vite/scripts/util.ts index 135c701098fc57..c742b3338e8717 100644 --- a/packages/vite/scripts/util.ts +++ b/packages/vite/scripts/util.ts @@ -17,8 +17,9 @@ export function rewriteImports( }) } +const windowsSlashRE = /\\/g export function slash(p: string): string { - return p.replace(/\\/g, '/') + return p.replace(windowsSlashRE, '/') } export function walkDir(dir: string, handleFile: (file: string) => void): void { diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index 40bb02a93c6114..ee8cd5c855d544 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -560,7 +560,7 @@ export function createHotContext(ownerPath: string): ViteHotContext { */ export function injectQuery(url: string, queryToInject: string): string { // skip urls that won't be handled by vite - if (!url.startsWith('.') && !url.startsWith('/')) { + if (url[0] !== '.' && url[0] !== '/') { return url } diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 65a88ed708230b..2ee69665c49ae7 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -5,7 +5,6 @@ import { asyncFlatten, getHash, getLocalhostAddressIfDiffersFromDNS, - getPotentialTsSrcPaths, injectQuery, isFileReadable, isWindows, @@ -137,42 +136,6 @@ describe('resolveHostname', () => { }) }) -test('ts import of file with .js extension', () => { - expect(getPotentialTsSrcPaths('test-file.js')).toEqual([ - 'test-file.ts', - 'test-file.tsx', - ]) -}) - -test('ts import of file with .jsx extension', () => { - expect(getPotentialTsSrcPaths('test-file.jsx')).toEqual(['test-file.tsx']) -}) - -test('ts import of file .mjs,.cjs extension', () => { - expect(getPotentialTsSrcPaths('test-file.cjs')).toEqual([ - 'test-file.cts', - 'test-file.ctsx', - ]) - expect(getPotentialTsSrcPaths('test-file.mjs')).toEqual([ - 'test-file.mts', - 'test-file.mtsx', - ]) -}) - -test('ts import of file with .js before extension', () => { - expect(getPotentialTsSrcPaths('test-file.js.js')).toEqual([ - 'test-file.js.ts', - 'test-file.js.tsx', - ]) -}) - -test('ts import of file with .js and query param', () => { - expect(getPotentialTsSrcPaths('test-file.js.js?lee=123')).toEqual([ - 'test-file.js.ts?lee=123', - 'test-file.js.tsx?lee=123', - ]) -}) - describe('posToNumber', () => { test('simple', () => { const actual = posToNumber('a\nb', { line: 2, column: 0 }) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 527f0e9fbac204..5f980bb130a961 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -32,7 +32,6 @@ import { copyDir, emptyDir, joinUrlSegments, - lookupFile, normalizePath, requireResolveFromRootWithFallback, } from './utils' @@ -52,8 +51,8 @@ import { initDepsOptimizer, } from './optimizer' import { loadFallbackPlugin } from './plugins/loadFallback' -import type { PackageData } from './packages' -import { watchPackageDataPlugin } from './packages' +import { findNearestPackageData, watchPackageDataPlugin } from './packages' +import type { PackageCache } from './packages' import { ensureWatchPlugin } from './plugins/ensureWatch' import { ESBUILD_MODULES_TARGET, VERSION } from './constants' import { resolveChokidarOptions } from './watch' @@ -578,7 +577,11 @@ export async function build( const format = output.format || (cjsSsrBuild ? 'cjs' : 'es') const jsExt = ssrNodeBuild || libOptions - ? resolveOutputJsExtension(format, getPkgJson(config.root)?.type) + ? resolveOutputJsExtension( + format, + findNearestPackageData(config.root, config.packageCache)?.data + .type, + ) : 'js' return { dir: outDir, @@ -595,7 +598,14 @@ export async function build( ? `[name].${jsExt}` : libOptions ? ({ name }) => - resolveLibFilename(libOptions, format, name, config.root, jsExt) + resolveLibFilename( + libOptions, + format, + name, + config.root, + jsExt, + config.packageCache, + ) : path.posix.join(options.assetsDir, `[name]-[hash].${jsExt}`), chunkFileNames: libOptions ? `[name]-[hash].${jsExt}` @@ -742,12 +752,8 @@ function prepareOutDir( } } -function getPkgJson(root: string): PackageData['data'] { - return JSON.parse(lookupFile(root, ['package.json']) || `{}`) -} - function getPkgName(name: string) { - return name?.startsWith('@') ? name.split('/')[1] : name + return name?.[0] === '@' ? name.split('/')[1] : name } type JsExt = 'js' | 'cjs' | 'mjs' @@ -769,15 +775,16 @@ export function resolveLibFilename( entryName: string, root: string, extension?: JsExt, + packageCache?: PackageCache, ): string { if (typeof libOptions.fileName === 'function') { return libOptions.fileName(format, entryName) } - const packageJson = getPkgJson(root) + const packageJson = findNearestPackageData(root, packageCache)?.data const name = libOptions.fileName || - (typeof libOptions.entry === 'string' + (packageJson && typeof libOptions.entry === 'string' ? getPkgName(packageJson.name) : entryName) @@ -786,7 +793,7 @@ export function resolveLibFilename( 'Name in package.json is required if option "build.lib.fileName" is not provided.', ) - extension ??= resolveOutputJsExtension(format, packageJson.type) + extension ??= resolveOutputJsExtension(format, packageJson?.type) if (format === 'cjs' || format === 'es') { return `${name}.${extension}` diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index fb56c92bca3ccf..19f856a040ef2b 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -1,4 +1,5 @@ import fs from 'node:fs' +import fsp from 'node:fs/promises' import path from 'node:path' import { pathToFileURL } from 'node:url' import { performance } from 'node:perf_hooks' @@ -61,6 +62,7 @@ import type { JsonOptions } from './plugins/json' import type { PluginContainer } from './server/pluginContainer' import { createPluginContainer } from './server/pluginContainer' import type { PackageCache } from './packages' +import { findNearestPackageData } from './packages' import { loadEnv, resolveEnvPrefix } from './env' import type { ResolvedSSROptions, SSROptions } from './ssr' import { resolveSSROptions } from './ssr' @@ -389,6 +391,7 @@ export async function resolveConfig( let configFileDependencies: string[] = [] let mode = inlineConfig.mode || defaultMode const isNodeEnvSet = !!process.env.NODE_ENV + const packageCache: PackageCache = new Map() // some dependencies e.g. @vue/compiler-* relies on NODE_ENV for getting // production-specific behavior, so set it early on @@ -538,12 +541,12 @@ export async function resolveConfig( ) // resolve cache directory - const pkgPath = lookupFile(resolvedRoot, [`package.json`], { pathOnly: true }) + const pkgDir = findNearestPackageData(resolvedRoot, packageCache)?.dir const cacheDir = normalizePath( config.cacheDir ? path.resolve(resolvedRoot, config.cacheDir) - : pkgPath - ? path.join(path.dirname(pkgPath), `node_modules/.vite`) + : pkgDir + ? path.join(pkgDir, `node_modules/.vite`) : path.join(resolvedRoot, `.vite`), ) @@ -680,7 +683,7 @@ export async function resolveConfig( return DEFAULT_ASSETS_RE.test(file) || assetsFilter(file) }, logger, - packageCache: new Map(), + packageCache, createResolver, optimizeDeps: { disabled: 'build', @@ -828,7 +831,7 @@ export function resolveBaseUrl( isBuild: boolean, logger: Logger, ): string { - if (base.startsWith('.')) { + if (base[0] === '.') { logger.warn( colors.yellow( colors.bold( @@ -843,7 +846,7 @@ export function resolveBaseUrl( // external URL flag const isExternal = isExternalUrl(base) // no leading slash warn - if (!isExternal && !base.startsWith('/')) { + if (!isExternal && base[0] !== '/') { logger.warn( colors.yellow( colors.bold(`(!) "base" option should start with a slash.`), @@ -855,7 +858,7 @@ export function resolveBaseUrl( if (!isBuild || !isExternal) { base = new URL(base, 'http://vitejs.dev').pathname // ensure leading slash - if (!base.startsWith('/')) { + if (base[0] !== '/') { base = '/' + base } } @@ -925,7 +928,8 @@ export async function loadConfigFromFile( // check package.json for type: "module" and set `isESM` to true try { const pkg = lookupFile(configRoot, ['package.json']) - isESM = !!pkg && JSON.parse(pkg).type === 'module' + isESM = + !!pkg && JSON.parse(fs.readFileSync(pkg, 'utf-8')).type === 'module' } catch (e) {} } @@ -1080,24 +1084,22 @@ async function loadConfigFromBundledFile( // with --experimental-loader themselves, we have to do a hack here: // write it to disk, load it with native Node ESM, then delete the file. if (isESM) { - const fileBase = `${fileName}.timestamp-${Date.now()}` + const fileBase = `${fileName}.timestamp-${Date.now()}-${Math.random() + .toString(16) + .slice(2)})}` const fileNameTmp = `${fileBase}.mjs` const fileUrl = `${pathToFileURL(fileBase)}.mjs` - fs.writeFileSync(fileNameTmp, bundledCode) + await fsp.writeFile(fileNameTmp, bundledCode) try { return (await dynamicImport(fileUrl)).default } finally { - try { - fs.unlinkSync(fileNameTmp) - } catch { - // already removed if this function is called twice simultaneously - } + fs.unlink(fileNameTmp, () => {}) // Ignore errors } } // for cjs, we can register a custom loader via `_require.extensions` else { const extension = path.extname(fileName) - const realFileName = fs.realpathSync(fileName) + const realFileName = await fsp.realpath(fileName) const loaderExt = extension in _require.extensions ? extension : '.js' const defaultLoader = _require.extensions[loaderExt]! _require.extensions[loaderExt] = (module: NodeModule, filename: string) => { diff --git a/packages/vite/src/node/constants.ts b/packages/vite/src/node/constants.ts index f2d3c161d8d84c..0f378bbdfb9f9f 100644 --- a/packages/vite/src/node/constants.ts +++ b/packages/vite/src/node/constants.ts @@ -115,6 +115,7 @@ export const KNOWN_ASSET_TYPES = [ 'wav', 'flac', 'aac', + 'opus', // fonts 'woff2?', diff --git a/packages/vite/src/node/env.ts b/packages/vite/src/node/env.ts index 338de6784497d8..374e1f049c0618 100644 --- a/packages/vite/src/node/env.ts +++ b/packages/vite/src/node/env.ts @@ -1,7 +1,8 @@ import fs from 'node:fs' +import path from 'node:path' import { parse } from 'dotenv' import { expand } from 'dotenv-expand' -import { arraify, lookupFile } from './utils' +import { arraify, tryStatSync } from './utils' import type { UserConfig } from './config' export function loadEnv( @@ -26,12 +27,10 @@ export function loadEnv( const parsed = Object.fromEntries( envFiles.flatMap((file) => { - const path = lookupFile(envDir, [file], { - pathOnly: true, - rootDir: envDir, - }) - if (!path) return [] - return Object.entries(parse(fs.readFileSync(path))) + const filePath = path.join(envDir, file) + if (!tryStatSync(filePath)?.isFile()) return [] + + return Object.entries(parse(fs.readFileSync(filePath))) }), ) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index 7af73c899cccb2..88ccd4b955cdbc 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -1,4 +1,4 @@ -import fs from 'node:fs' +import fsp from 'node:fs/promises' import path from 'node:path' import type { Server as HttpServer, @@ -124,23 +124,21 @@ export async function resolveHttpsConfig( https: boolean | HttpsServerOptions | undefined, ): Promise { if (!https) return undefined + if (!isObject(https)) return {} - const httpsOption = isObject(https) ? { ...https } : {} - - const { ca, cert, key, pfx } = httpsOption - Object.assign(httpsOption, { - ca: readFileIfExists(ca), - cert: readFileIfExists(cert), - key: readFileIfExists(key), - pfx: readFileIfExists(pfx), - }) - return httpsOption + const [ca, cert, key, pfx] = await Promise.all([ + readFileIfExists(https.ca), + readFileIfExists(https.cert), + readFileIfExists(https.key), + readFileIfExists(https.pfx), + ]) + return { ...https, ca, cert, key, pfx } } -function readFileIfExists(value?: string | Buffer | any[]) { +async function readFileIfExists(value?: string | Buffer | any[]) { if (typeof value === 'string') { try { - return fs.readFileSync(path.resolve(value)) + return fsp.readFile(path.resolve(value)) } catch (e) { return value } diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts index a0e3628484a202..cc44fe17b10524 100644 --- a/packages/vite/src/node/index.ts +++ b/packages/vite/src/node/index.ts @@ -34,6 +34,7 @@ export type { export type { PreviewOptions, PreviewServer, + PreviewServerForHook, PreviewServerHook, ResolvedPreviewOptions, } from './preview' diff --git a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts index e6378bc4e94930..e3bb4730eef1d7 100644 --- a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts +++ b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts @@ -2,8 +2,9 @@ import path from 'node:path' import type { ImportKind, Plugin } from 'esbuild' import { CSS_LANGS_RE, KNOWN_ASSET_TYPES } from '../constants' import { getDepOptimizationConfig } from '..' -import type { ResolvedConfig } from '..' +import type { PackageCache, ResolvedConfig } from '..' import { + escapeRegex, flattenId, isBuiltin, isExternalUrl, @@ -57,14 +58,24 @@ export function esbuildDepPlugin( ? externalTypes.filter((type) => !extensions?.includes('.' + type)) : externalTypes + // use separate package cache for optimizer as it caches paths around node_modules + // and it's unlikely for the core Vite process to traverse into node_modules again + const esmPackageCache: PackageCache = new Map() + const cjsPackageCache: PackageCache = new Map() + // default resolver which prefers ESM - const _resolve = config.createResolver({ asSrc: false, scan: true }) + const _resolve = config.createResolver({ + asSrc: false, + scan: true, + packageCache: esmPackageCache, + }) // cjs resolver that prefers Node const _resolveRequire = config.createResolver({ asSrc: false, isRequire: true, scan: true, + packageCache: cjsPackageCache, }) const resolve = ( @@ -116,6 +127,12 @@ export function esbuildDepPlugin( return { name: 'vite:dep-pre-bundle', setup(build) { + // clear package cache when esbuild is finished + build.onEnd(() => { + esmPackageCache.clear() + cjsPackageCache.clear() + }) + // externalize assets and commonly known non-js file types // See #8459 for more details about this require-import conversion build.onResolve( @@ -265,6 +282,8 @@ module.exports = Object.create(new Proxy({}, { } } +const matchesEntireLine = (text: string) => `^${escapeRegex(text)}$` + // esbuild doesn't transpile `require('foo')` into `import` statements if 'foo' is externalized // https://github.com/evanw/esbuild/issues/566#issuecomment-735551834 export function esbuildCjsExternalPlugin( @@ -274,9 +293,7 @@ export function esbuildCjsExternalPlugin( return { name: 'cjs-external', setup(build) { - const escape = (text: string) => - `^${text.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}$` - const filter = new RegExp(externals.map(escape).join('|')) + const filter = new RegExp(externals.map(matchesEntireLine).join('|')) build.onResolve({ filter: new RegExp(`^${nonFacadePrefix}`) }, (args) => { return { diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 62b3a9f14d7494..ab5462191e9911 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -18,15 +18,15 @@ import { getHash, isOptimizable, lookupFile, - nestedResolveFrom, normalizeId, normalizePath, - removeDir, - renameDir, - writeFile, + removeLeadingSlash, + tryStatSync, } from '../utils' import { transformWithEsbuild } from '../plugins/esbuild' import { ESBUILD_MODULES_TARGET } from '../constants' +import { resolvePackageData } from '../packages' +import type { ViteDevServer } from '../server' import { esbuildCjsExternalPlugin, esbuildDepPlugin } from './esbuildDepPlugin' import { scanImports } from './scan' export { @@ -41,6 +41,7 @@ const isDebugEnabled = _debug('vite:deps').enabled const jsExtensionRE = /\.js$/i const jsMapExtensionRE = /\.js\.map$/i +const reExportRE = /export\s+\*\s+from/ export type ExportsData = { hasImports: boolean @@ -71,6 +72,7 @@ export interface DepsOptimizer { close: () => Promise options: DepOptimizationOptions + server?: ViteDevServer } export interface DepOptimizationConfig { @@ -161,6 +163,9 @@ export interface DepOptimizationResult { * to be able to discard the result */ commit: () => Promise + /** + * @deprecated noop + */ cancel: () => void } @@ -231,7 +236,7 @@ export async function optimizeDeps( const ssr = config.command === 'build' && !!config.build.ssr - const cachedMetadata = loadCachedDepOptimizationMetadata( + const cachedMetadata = await loadCachedDepOptimizationMetadata( config, ssr, force, @@ -261,7 +266,7 @@ export async function optimizeServerSsrDeps( config: ResolvedConfig, ): Promise { const ssr = true - const cachedMetadata = loadCachedDepOptimizationMetadata( + const cachedMetadata = await loadCachedDepOptimizationMetadata( config, ssr, config.optimizeDeps.force, @@ -338,12 +343,12 @@ export function addOptimizedDepInfo( * Creates the initial dep optimization metadata, loading it from the deps cache * if it exists and pre-bundling isn't forced */ -export function loadCachedDepOptimizationMetadata( +export async function loadCachedDepOptimizationMetadata( config: ResolvedConfig, ssr: boolean, force = config.optimizeDeps.force, asCommand = false, -): DepOptimizationMetadata | undefined { +): Promise { const log = asCommand ? config.logger.info : debug // Before Vite 2.9, dependencies were cached in the root of the cacheDir @@ -359,7 +364,7 @@ export function loadCachedDepOptimizationMetadata( try { const cachedMetadataPath = path.join(depsCacheDir, '_metadata.json') cachedMetadata = parseDepsOptimizerMetadata( - fs.readFileSync(cachedMetadataPath, 'utf-8'), + await fsp.readFile(cachedMetadataPath, 'utf-8'), depsCacheDir, ) } catch (e) {} @@ -375,7 +380,7 @@ export function loadCachedDepOptimizationMetadata( } // Start with a fresh cache - fs.rmSync(depsCacheDir, { recursive: true, force: true }) + await fsp.rm(depsCacheDir, { recursive: true, force: true }) } /** @@ -471,23 +476,6 @@ export function runOptimizeDeps( } const depsCacheDir = getDepsCacheDir(resolvedConfig, ssr) - const processingCacheDir = getProcessingDepsCacheDir(resolvedConfig, ssr) - - // Create a temporal directory so we don't need to delete optimized deps - // until they have been processed. This also avoids leaving the deps cache - // directory in a corrupted state if there is an error - if (fs.existsSync(processingCacheDir)) { - emptyDir(processingCacheDir) - } else { - fs.mkdirSync(processingCacheDir, { recursive: true }) - } - - // a hint for Node.js - // all files in the cache directory should be recognized as ES modules - writeFile( - path.resolve(processingCacheDir, 'package.json'), - JSON.stringify({ type: 'module' }), - ) const metadata = initDepsOptimizerMetadata(config, ssr) @@ -502,34 +490,16 @@ export function runOptimizeDeps( const qualifiedIds = Object.keys(depsInfo) - let cleaned = false - const cleanUp = () => { - if (!cleaned) { - cleaned = true - fs.rmSync(processingCacheDir, { recursive: true, force: true }) - } - } - const createProcessingResult = () => ({ + const createEmptyProcessingResult = () => ({ metadata, - async commit() { - if (cleaned) { - throw new Error( - `Vite Internal Error: Can't commit optimizeDeps processing result, it has already been cancelled.`, - ) - } - // Write metadata file, delete `deps` folder and rename the `processing` folder to `deps` - // Processing is done, we can now replace the depsCacheDir with processingCacheDir - // Rewire the file paths from the temporal processing dir to the final deps cache dir - await removeDir(depsCacheDir) - await renameDir(processingCacheDir, depsCacheDir) - }, - cancel: cleanUp, + commit: async () => {}, + cancel: async () => {}, }) if (!qualifiedIds.length) { return { - cancel: async () => cleanUp(), - result: Promise.resolve(createProcessingResult()), + result: Promise.resolve(createEmptyProcessingResult()), + cancel: async () => {}, } } @@ -539,11 +509,11 @@ export function runOptimizeDeps( resolvedConfig, depsInfo, ssr, - processingCacheDir, + depsCacheDir, optimizerContext, ) - const result = preparedRun.then(({ context, idToExports }) => { + const runResult = preparedRun.then(({ context, idToExports }) => { function disposeContext() { return context?.dispose().catch((e) => { config.logger.error('Failed to dispose esbuild context', { error: e }) @@ -551,7 +521,7 @@ export function runOptimizeDeps( } if (!context || optimizerContext.cancelled) { disposeContext() - return createProcessingResult() + return createEmptyProcessingResult() } return context @@ -562,15 +532,11 @@ export function runOptimizeDeps( // the paths in `meta.outputs` are relative to `process.cwd()` const processingCacheDirOutputPath = path.relative( process.cwd(), - processingCacheDir, + depsCacheDir, ) for (const id in depsInfo) { - const output = esbuildOutputFromId( - meta.outputs, - id, - processingCacheDir, - ) + const output = esbuildOutputFromId(meta.outputs, id, depsCacheDir) const { exportsData, ...info } = depsInfo[id] addOptimizedDepInfo(metadata, 'optimized', { @@ -617,21 +583,64 @@ export function runOptimizeDeps( } } - const dataPath = path.join(processingCacheDir, '_metadata.json') - writeFile( - dataPath, - stringifyDepsOptimizerMetadata(metadata, depsCacheDir), + debug( + `Dependencies bundled in ${(performance.now() - start).toFixed(2)}ms`, ) - debug(`deps bundled in ${(performance.now() - start).toFixed(2)}ms`) + return { + metadata, + async commit() { + // Write this run of pre-bundled dependencies to the deps cache + + // Get a list of old files in the deps directory to delete the stale ones + const oldFilesPaths: string[] = [] + if (!fs.existsSync(depsCacheDir)) { + fs.mkdirSync(depsCacheDir, { recursive: true }) + } else { + oldFilesPaths.push( + ...(await fsp.readdir(depsCacheDir)).map((f) => + path.join(depsCacheDir, f), + ), + ) + } + + const newFilesPaths = new Set() + const files: Promise[] = [] + const write = (filePath: string, content: string) => { + newFilesPaths.add(filePath) + files.push(fsp.writeFile(filePath, content)) + } + + // a hint for Node.js + // all files in the cache directory should be recognized as ES modules + write( + path.resolve(depsCacheDir, 'package.json'), + '{\n "type": "module"\n}\n', + ) + + write( + path.join(depsCacheDir, '_metadata.json'), + stringifyDepsOptimizerMetadata(metadata, depsCacheDir), + ) + + for (const outputFile of result.outputFiles!) + write(outputFile.path, outputFile.text) + + // Clean up old files in the background + for (const filePath of oldFilesPaths) + if (!newFilesPaths.has(filePath)) fs.unlink(filePath, () => {}) // ignore errors - return createProcessingResult() + await Promise.all(files) + }, + cancel: () => {}, + } }) + .catch((e) => { if (e.errors && e.message.includes('The build was canceled')) { // esbuild logs an error when cancelling, but this is expected so // return an empty result instead - return createProcessingResult() + return createEmptyProcessingResult() } throw e }) @@ -640,18 +649,13 @@ export function runOptimizeDeps( }) }) - result.catch(() => { - cleanUp() - }) - return { async cancel() { optimizerContext.cancelled = true const { context } = await preparedRun await context?.cancel() - cleanUp() }, - result, + result: runResult, } } @@ -751,6 +755,9 @@ async function prepareEsbuildOptimizerRun( absWorkingDir: process.cwd(), entryPoints: Object.keys(flatIdDeps), bundle: true, + // Don't write to disk, we'll only write the files if the build isn't invalidated + // by newly discovered dependencies + write: false, // We can't use platform 'neutral', as esbuild has custom handling // when the platform is 'node' or 'browser' that can't be emulated // by using mainFields and conditions @@ -855,16 +862,30 @@ function createOptimizeDepsIncludeResolver( // 'foo > bar > baz' => 'foo > bar' & 'baz' const nestedRoot = id.substring(0, lastArrowIndex).trim() const nestedPath = id.substring(lastArrowIndex + 1).trim() - const basedir = nestedResolveFrom( + const basedir = nestedResolveBasedir( nestedRoot, config.root, config.resolve.preserveSymlinks, - ssr, ) return await resolve(nestedPath, basedir, undefined, ssr) } } +/** + * Continously resolve the basedir of packages separated by '>' + */ +function nestedResolveBasedir( + id: string, + basedir: string, + preserveSymlinks = false, +) { + const pkgs = id.split('>').map((pkg) => pkg.trim()) + for (const pkg of pkgs) { + basedir = resolvePackageData(pkg, basedir, preserveSymlinks)?.dir || basedir + } + return basedir +} + export function newDepOptimizationProcessing(): DepOptimizationProcessing { let resolve: () => void const promise = new Promise((_resolve) => { @@ -911,24 +932,15 @@ export function getDepsCacheDir(config: ResolvedConfig, ssr: boolean): string { return getDepsCacheDirPrefix(config) + getDepsCacheSuffix(config, ssr) } -function getProcessingDepsCacheDir(config: ResolvedConfig, ssr: boolean) { - return ( - getDepsCacheDirPrefix(config) + - getDepsCacheSuffix(config, ssr) + - '_temp_' + - getHash(Date.now().toString()) - ) -} - -export function getDepsCacheDirPrefix(config: ResolvedConfig): string { +function getDepsCacheDirPrefix(config: ResolvedConfig): string { return normalizePath(path.resolve(config.cacheDir, 'deps')) } -export function isOptimizedDepFile( - id: string, +export function createIsOptimizedDepFile( config: ResolvedConfig, -): boolean { - return id.startsWith(getDepsCacheDirPrefix(config)) +): (id: string) => boolean { + const depsCacheDirPrefix = getDepsCacheDirPrefix(config) + return (id) => id.startsWith(depsCacheDirPrefix) } export function createIsOptimizedDepUrl( @@ -942,7 +954,7 @@ export function createIsOptimizedDepUrl( const depsCacheDirPrefix = depsCacheDirRelative.startsWith('../') ? // if the cache directory is outside root, the url prefix would be something // like '/@fs/absolute/path/to/node_modules/.vite' - `/@fs/${normalizePath(depsCacheDir).replace(/^\//, '')}` + `/@fs/${removeLeadingSlash(normalizePath(depsCacheDir))}` : // if the cache directory is inside root, the url prefix would be something // like '/node_modules/.vite' `/${depsCacheDirRelative}` @@ -1098,7 +1110,7 @@ export async function extractExportsData( let parseResult: ReturnType let usedJsxLoader = false - const entryContent = fs.readFileSync(filePath, 'utf-8') + const entryContent = await fsp.readFile(filePath, 'utf-8') try { parseResult = parse(entryContent) } catch { @@ -1126,7 +1138,7 @@ export async function extractExportsData( facade, hasReExports: imports.some(({ ss, se }) => { const exp = entryContent.slice(ss, se) - return /export\s+\*\s+from/.test(exp) + return reExportRE.test(exp) }), jsxLoader: usedJsxLoader, } @@ -1176,13 +1188,10 @@ const lockfileFormats = [ { name: 'pnpm-lock.yaml', checkPatches: false }, // Included in lockfile { name: 'bun.lockb', checkPatches: true }, ] +const lockfileNames = lockfileFormats.map((l) => l.name) export function getDepHash(config: ResolvedConfig, ssr: boolean): string { - const lockfilePath = lookupFile( - config.root, - lockfileFormats.map((l) => l.name), - { pathOnly: true }, - ) + const lockfilePath = lookupFile(config.root, lockfileNames) let content = lockfilePath ? fs.readFileSync(lockfilePath, 'utf-8') : '' if (lockfilePath) { const lockfileName = path.basename(lockfilePath) @@ -1192,11 +1201,9 @@ export function getDepHash(config: ResolvedConfig, ssr: boolean): string { if (checkPatches) { // Default of https://github.com/ds300/patch-package const fullPath = path.join(path.dirname(lockfilePath), 'patches') - if (fs.existsSync(fullPath)) { - const stats = fs.statSync(fullPath) - if (stats.isDirectory()) { - content += stats.mtimeMs.toString() - } + const stat = tryStatSync(fullPath) + if (stat?.isDirectory()) { + content += stat.mtimeMs.toString() } } } @@ -1284,29 +1291,3 @@ export async function optimizedDepNeedsInterop( } return depInfo?.needsInterop } - -const MAX_TEMP_DIR_AGE_MS = 24 * 60 * 60 * 1000 -export async function cleanupDepsCacheStaleDirs( - config: ResolvedConfig, -): Promise { - try { - const cacheDir = path.resolve(config.cacheDir) - if (fs.existsSync(cacheDir)) { - const dirents = await fsp.readdir(cacheDir, { withFileTypes: true }) - for (const dirent of dirents) { - if (dirent.isDirectory() && dirent.name.includes('_temp_')) { - const tempDirPath = path.resolve(config.cacheDir, dirent.name) - const stats = await fsp.stat(tempDirPath).catch((_) => null) - if ( - stats?.mtime && - Date.now() - stats.mtime.getTime() > MAX_TEMP_DIR_AGE_MS - ) { - await removeDir(tempDirPath) - } - } - } - } - } catch (err) { - config.logger.error(err) - } -} diff --git a/packages/vite/src/node/optimizer/optimizer.ts b/packages/vite/src/node/optimizer/optimizer.ts index 629f8b9b9ccd3a..0f76e12b49c412 100644 --- a/packages/vite/src/node/optimizer/optimizer.ts +++ b/packages/vite/src/node/optimizer/optimizer.ts @@ -1,11 +1,12 @@ import colors from 'picocolors' import _debug from 'debug' import { getHash } from '../utils' -import { getDepOptimizationConfig } from '..' +import { getDepOptimizationConfig } from '../config' import type { ResolvedConfig, ViteDevServer } from '..' import { addManuallyIncludedOptimizeDeps, addOptimizedDepInfo, + createIsOptimizedDepFile, createIsOptimizedDepUrl, debuggerViteDeps as debug, depsFromOptimizedDepInfo, @@ -14,7 +15,6 @@ import { extractExportsData, getOptimizedDepPath, initDepsOptimizerMetadata, - isOptimizedDepFile, loadCachedDepOptimizationMetadata, newDepOptimizationProcessing, optimizeServerSsrDeps, @@ -99,7 +99,7 @@ async function createDepsOptimizer( const sessionTimestamp = Date.now().toString() - const cachedMetadata = loadCachedDepOptimizationMetadata(config, ssr) + const cachedMetadata = await loadCachedDepOptimizationMetadata(config, ssr) let handle: NodeJS.Timeout | undefined @@ -112,7 +112,7 @@ async function createDepsOptimizer( metadata, registerMissingImport, run: () => debouncedProcessing(0), - isOptimizedDepFile: (id: string) => isOptimizedDepFile(id, config), + isOptimizedDepFile: createIsOptimizedDepFile(config), isOptimizedDepUrl: createIsOptimizedDepUrl(config), getOptimizedDepId: (depInfo: OptimizedDepInfo) => isBuild ? depInfo.file : `${depInfo.file}?v=${depInfo.browserHash}`, @@ -122,6 +122,7 @@ async function createDepsOptimizer( ensureFirstRun, close, options: getDepOptimizationConfig(config, ssr), + server, } depsOptimizerMap.set(config, depsOptimizer) @@ -221,16 +222,6 @@ async function createDepsOptimizer( const deps = await discover.result discover = undefined - debug( - colors.green( - Object.keys(deps).length > 0 - ? `dependencies found by scanner: ${depsLogString( - Object.keys(deps), - )}` - : `no dependencies found by scanner`, - ), - ) - // Add these dependencies to the discovered list, as these are currently // used by the preAliasPlugin to support aliased and optimized deps. // This is also used by the CJS externalization heuristics in legacy mode @@ -485,13 +476,13 @@ async function createDepsOptimizer( } function fullReload() { - if (server) { + if (depsOptimizer.server) { // Cached transform results have stale imports (resolved to // old locations) so they need to be invalidated before the page is // reloaded. - server.moduleGraph.invalidateAll() + depsOptimizer.server.moduleGraph.invalidateAll() - server.ws.send({ + depsOptimizer.server.ws.send({ type: 'full-reload', path: '*', }) @@ -764,7 +755,7 @@ async function createDevSsrDepsOptimizer( const depsOptimizer = { metadata, - isOptimizedDepFile: (id: string) => isOptimizedDepFile(id, config), + isOptimizedDepFile: createIsOptimizedDepFile(config), isOptimizedDepUrl: createIsOptimizedDepUrl(config), getOptimizedDepId: (depInfo: OptimizedDepInfo) => `${depInfo.file}?v=${depInfo.browserHash}`, diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index 7929b337b8a6e4..7aa5902d23e04b 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -1,4 +1,5 @@ import fs from 'node:fs' +import fsp from 'node:fs/promises' import path from 'node:path' import { performance } from 'node:perf_hooks' import glob from 'fast-glob' @@ -17,6 +18,7 @@ import { createDebugger, dataUrlRE, externalRE, + isInNodeModules, isObject, isOptimizable, moduleListContains, @@ -32,6 +34,7 @@ import { transformGlobImport } from '../plugins/importMetaGlob' type ResolveIdOptions = Parameters[2] +const isDebug = process.env.DEBUG const debug = createDebugger('vite:deps') const htmlTypesRE = /\.(html|vue|svelte|astro|imba)$/ @@ -82,7 +85,11 @@ export function scanImports(config: ResolvedConfig): { } if (scanContext.cancelled) return - debug(`Crawling dependencies using entries:\n ${entries.join('\n ')}`) + debug( + `Crawling dependencies using entries: ${entries + .map((entry) => `\n ${colors.dim(entry)}`) + .join('')}`, + ) return prepareEsbuildScanner(config, entries, deps, missing, scanContext) }) @@ -134,10 +141,15 @@ export function scanImports(config: ResolvedConfig): { throw e }) .finally(() => { - debug( - `Scan completed in ${(performance.now() - start).toFixed(2)}ms:`, - deps, - ) + if (isDebug) { + const duration = (performance.now() - start).toFixed(2) + const depsStr = + Object.keys(orderedDependencies(deps)) + .sort() + .map((id) => `\n ${colors.cyan(id)} -> ${colors.dim(deps[id])}`) + .join('') || colors.dim('no dependencies found') + debug(`Scan completed in ${duration}ms: ${depsStr}`) + } }) return { @@ -349,7 +361,7 @@ function esbuildScanPlugin( // If we can optimize this html type, skip it so it's handled by the // bare import resolve, and recorded as optimization dep. if ( - resolved.includes('node_modules') && + isInNodeModules(resolved) && isOptimizable(resolved, config.optimizeDeps) ) return @@ -363,7 +375,7 @@ function esbuildScanPlugin( build.onLoad( { filter: htmlTypesRE, namespace: 'html' }, async ({ path }) => { - let raw = fs.readFileSync(path, 'utf-8') + let raw = await fsp.readFile(path, 'utf-8') // Avoid matching the content of the comment raw = raw.replace(commentRE, '') const isHtml = path.endsWith('.html') @@ -490,7 +502,7 @@ function esbuildScanPlugin( if (shouldExternalizeDep(resolved, id)) { return externalUnlessEntry({ path: id }) } - if (resolved.includes('node_modules') || include?.includes(id)) { + if (isInNodeModules(resolved) || include?.includes(id)) { // dependency or forced included, externalize and stop crawling if (isOptimizable(resolved, config.optimizeDeps)) { depImports[id] = resolved @@ -576,7 +588,7 @@ function esbuildScanPlugin( let ext = path.extname(id).slice(1) if (ext === 'mjs') ext = 'js' - let contents = fs.readFileSync(id, 'utf-8') + let contents = await fsp.readFile(id, 'utf-8') if (ext.endsWith('x') && config.esbuild && config.esbuild.jsxInject) { contents = config.esbuild.jsxInject + `\n` + contents } diff --git a/packages/vite/src/node/packages.ts b/packages/vite/src/node/packages.ts index 1451d18853729a..b4a0d7948240e6 100644 --- a/packages/vite/src/node/packages.ts +++ b/packages/vite/src/node/packages.ts @@ -1,13 +1,17 @@ import fs from 'node:fs' import path from 'node:path' -import { createDebugger, createFilter, resolveFrom } from './utils' +import { createRequire } from 'node:module' +import { createFilter, safeRealpathSync } from './utils' import type { ResolvedConfig } from './config' import type { Plugin } from './plugin' -const isDebug = process.env.DEBUG -const debug = createDebugger('vite:resolve-details', { - onlyWhenFocused: true, -}) +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +let pnp: typeof import('pnpapi') | undefined +if (process.versions.pnp) { + try { + pnp = createRequire(import.meta.url)('pnpapi') + } catch {} +} /** Cache for package.json resolution and package.json contents */ export type PackageCache = Map @@ -47,53 +51,116 @@ export function invalidatePackageData( } export function resolvePackageData( - id: string, + pkgName: string, basedir: string, preserveSymlinks = false, packageCache?: PackageCache, ): PackageData | null { - let pkg: PackageData | undefined - let cacheKey: string | undefined - if (packageCache) { - cacheKey = `${id}&${basedir}&${preserveSymlinks}` - if ((pkg = packageCache.get(cacheKey))) { - return pkg - } + if (pnp) { + const cacheKey = getRpdCacheKey(pkgName, basedir, preserveSymlinks) + if (packageCache?.has(cacheKey)) return packageCache.get(cacheKey)! + + const pkg = pnp.resolveToUnqualified(pkgName, basedir) + if (!pkg) return null + + const pkgData = loadPackageData(path.join(pkg, 'package.json')) + packageCache?.set(cacheKey, pkgData) + + return pkgData } - let pkgPath: string | undefined - try { - pkgPath = resolveFrom(`${id}/package.json`, basedir, preserveSymlinks) - pkg = loadPackageData(pkgPath, true, packageCache) + + const originalBasedir = basedir + while (basedir) { if (packageCache) { - packageCache.set(cacheKey!, pkg) - } - return pkg - } catch (e) { - if (e instanceof SyntaxError) { - isDebug && debug(`Parsing failed: ${pkgPath}`) - } - // Ignore error for missing package.json - else if (e.code !== 'MODULE_NOT_FOUND') { - throw e + const cached = getRpdCache( + packageCache, + pkgName, + basedir, + originalBasedir, + preserveSymlinks, + ) + if (cached) return cached } + + const pkg = path.join(basedir, 'node_modules', pkgName, 'package.json') + try { + if (fs.existsSync(pkg)) { + const pkgPath = preserveSymlinks ? pkg : safeRealpathSync(pkg) + const pkgData = loadPackageData(pkgPath) + + if (packageCache) { + setRpdCache( + packageCache, + pkgData, + pkgName, + basedir, + originalBasedir, + preserveSymlinks, + ) + } + + return pkgData + } + } catch {} + + const nextBasedir = path.dirname(basedir) + if (nextBasedir === basedir) break + basedir = nextBasedir } + return null } -export function loadPackageData( - pkgPath: string, - preserveSymlinks?: boolean, +export function findNearestPackageData( + basedir: string, packageCache?: PackageCache, -): PackageData { - if (!preserveSymlinks) { - pkgPath = fs.realpathSync.native(pkgPath) - } +): PackageData | null { + const originalBasedir = basedir + while (basedir) { + if (packageCache) { + const cached = getFnpdCache(packageCache, basedir, originalBasedir) + if (cached) return cached + } + + const pkgPath = path.join(basedir, 'package.json') + try { + if (fs.statSync(pkgPath, { throwIfNoEntry: false })?.isFile()) { + const pkgData = loadPackageData(pkgPath) + + if (packageCache) { + setFnpdCache(packageCache, pkgData, basedir, originalBasedir) + } - let cached: PackageData | undefined - if ((cached = packageCache?.get(pkgPath))) { - return cached + return pkgData + } + } catch {} + + const nextBasedir = path.dirname(basedir) + if (nextBasedir === basedir) break + basedir = nextBasedir } + return null +} + +// Finds the nearest package.json with a `name` field +export function findNearestMainPackageData( + basedir: string, + packageCache?: PackageCache, +): PackageData | null { + const nearestPackage = findNearestPackageData(basedir, packageCache) + return ( + nearestPackage && + (nearestPackage.data.name + ? nearestPackage + : findNearestMainPackageData( + path.dirname(nearestPackage.dir), + packageCache, + )) + ) +} + +export function loadPackageData(pkgPath: string): PackageData { const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) const pkgDir = path.dirname(pkgPath) const { sideEffects } = data @@ -142,7 +209,6 @@ export function loadPackageData( }, } - packageCache?.set(pkgPath, pkg) return pkg } @@ -178,3 +244,105 @@ export function watchPackageDataPlugin(config: ResolvedConfig): Plugin { }, } } + +/** + * Get cached `resolvePackageData` value based on `basedir`. When one is found, + * and we've already traversed some directories between `basedir` and `originalBasedir`, + * we cache the value for those in-between directories as well. + * + * This makes it so the fs is only read once for a shared `basedir`. + */ +function getRpdCache( + packageCache: PackageCache, + pkgName: string, + basedir: string, + originalBasedir: string, + preserveSymlinks: boolean, +) { + const cacheKey = getRpdCacheKey(pkgName, basedir, preserveSymlinks) + const pkgData = packageCache.get(cacheKey) + if (pkgData) { + traverseBetweenDirs(originalBasedir, basedir, (dir) => { + packageCache.set(getRpdCacheKey(pkgName, dir, preserveSymlinks), pkgData) + }) + return pkgData + } +} + +function setRpdCache( + packageCache: PackageCache, + pkgData: PackageData, + pkgName: string, + basedir: string, + originalBasedir: string, + preserveSymlinks: boolean, +) { + packageCache.set(getRpdCacheKey(pkgName, basedir, preserveSymlinks), pkgData) + traverseBetweenDirs(originalBasedir, basedir, (dir) => { + packageCache.set(getRpdCacheKey(pkgName, dir, preserveSymlinks), pkgData) + }) +} + +// package cache key for `resolvePackageData` +function getRpdCacheKey( + pkgName: string, + basedir: string, + preserveSymlinks: boolean, +) { + return `rpd_${pkgName}_${basedir}_${preserveSymlinks}` +} + +/** + * Get cached `findNearestPackageData` value based on `basedir`. When one is found, + * and we've already traversed some directories between `basedir` and `originalBasedir`, + * we cache the value for those in-between directories as well. + * + * This makes it so the fs is only read once for a shared `basedir`. + */ +function getFnpdCache( + packageCache: PackageCache, + basedir: string, + originalBasedir: string, +) { + const cacheKey = getFnpdCacheKey(basedir) + const pkgData = packageCache.get(cacheKey) + if (pkgData) { + traverseBetweenDirs(originalBasedir, basedir, (dir) => { + packageCache.set(getFnpdCacheKey(dir), pkgData) + }) + return pkgData + } +} + +function setFnpdCache( + packageCache: PackageCache, + pkgData: PackageData, + basedir: string, + originalBasedir: string, +) { + packageCache.set(getFnpdCacheKey(basedir), pkgData) + traverseBetweenDirs(originalBasedir, basedir, (dir) => { + packageCache.set(getFnpdCacheKey(dir), pkgData) + }) +} + +// package cache key for `findNearestPackageData` +function getFnpdCacheKey(basedir: string) { + return `fnpd_${basedir}` +} + +/** + * Traverse between `longerDir` (inclusive) and `shorterDir` (exclusive) and call `cb` for each dir. + * @param longerDir Longer dir path, e.g. `/User/foo/bar/baz` + * @param shorterDir Shorter dir path, e.g. `/User/foo` + */ +function traverseBetweenDirs( + longerDir: string, + shorterDir: string, + cb: (dir: string) => void, +) { + while (longerDir !== shorterDir) { + cb(longerDir) + longerDir = path.dirname(longerDir) + } +} diff --git a/packages/vite/src/node/plugin.ts b/packages/vite/src/node/plugin.ts index 64b702c2b1b03c..f2d73cbf1232e0 100644 --- a/packages/vite/src/node/plugin.ts +++ b/packages/vite/src/node/plugin.ts @@ -91,8 +91,9 @@ export interface Plugin extends RollupPlugin { */ configureServer?: ObjectHook /** - * Configure the preview server. The hook receives the connect server and - * its underlying http server. + * Configure the preview server. The hook receives the {@link PreviewServerForHook} + * instance. This can also be used to store a reference to the server + * for use in other hooks. * * The hooks are called before other middlewares are applied. A hook can * return a post hook that will be called after other middlewares are diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 134625c87dd078..6dcf8be3a9c1a0 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -16,7 +16,13 @@ import { } from '../build' import type { Plugin } from '../plugin' import type { ResolvedConfig } from '../config' -import { cleanUrl, getHash, joinUrlSegments, normalizePath } from '../utils' +import { + cleanUrl, + getHash, + joinUrlSegments, + normalizePath, + removeLeadingSlash, +} from '../utils' import { FS_PREFIX } from '../constants' export const assetUrlRE = /__VITE_ASSET__([a-z\d]+)__(?:\$_(.*?)__)?/g @@ -24,6 +30,7 @@ export const assetUrlRE = /__VITE_ASSET__([a-z\d]+)__(?:\$_(.*?)__)?/g const rawRE = /(?:\?|&)raw(?:&|$)/ const urlRE = /(\?|&)url(?:&|$)/ const jsSourceMapRE = /\.[cm]?js\.map$/ +const unnededFinalQueryCharRE = /[?&]$/ const assetCache = new WeakMap>() @@ -47,6 +54,8 @@ export function registerCustomMime(): void { mrmime.mimes['flac'] = 'audio/flac' // mrmime and mime-db is not released yet: https://github.com/jshttp/mime-db/commit/c9242a9b7d4bb25d7a0c9244adec74aeef08d8a1 mrmime.mimes['aac'] = 'audio/aac' + // https://wiki.xiph.org/MIME_Types_and_File_Extensions#.opus_-_audio/ogg + mrmime.mimes['opus'] = 'audio/ogg' // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types mrmime.mimes['eot'] = 'application/vnd.ms-fontobject' } @@ -148,7 +157,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { }, async load(id) { - if (id.startsWith('\0')) { + if (id[0] === '\0') { // Rollup convention, this id should be handled by the // plugin that marked it with \0 return @@ -167,7 +176,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { return } - id = id.replace(urlRE, '$1').replace(/[?&]$/, '') + id = id.replace(urlRE, '$1').replace(unnededFinalQueryCharRE, '') const url = await fileToUrl(id, config, this) return `export default ${JSON.stringify(url)}` }, @@ -212,7 +221,7 @@ export function checkPublicFile( ): string | undefined { // note if the file is in /public, the resolver would have returned it // as-is so it's not going to be a fully resolved path. - if (!publicDir || !url.startsWith('/')) { + if (!publicDir || url[0] !== '/') { return } const publicFile = path.join(publicDir, cleanUrl(url)) @@ -253,7 +262,7 @@ function fileToDevUrl(id: string, config: ResolvedConfig) { rtn = path.posix.join(FS_PREFIX, id) } const base = joinUrlSegments(config.server?.origin ?? '', config.base) - return joinUrlSegments(base, rtn.replace(/^\//, '')) + return joinUrlSegments(base, removeLeadingSlash(rtn)) } export function getPublicAssetFilename( @@ -369,9 +378,10 @@ export async function urlToBuiltUrl( if (checkPublicFile(url, config)) { return publicFileToBuiltUrl(url, config) } - const file = url.startsWith('/') - ? path.join(config.root, url) - : path.join(path.dirname(importer), url) + const file = + url[0] === '/' + ? path.join(config.root, url) + : path.join(path.dirname(importer), url) return fileToBuiltUrl( file, config, diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index 00aa1c466c406b..3f61d2ddbd0b46 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -52,7 +52,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { if (!s) s = new MagicString(code) // potential dynamic template string - if (rawUrl[0] === '`' && /\$\{/.test(rawUrl)) { + if (rawUrl[0] === '`' && rawUrl.includes('${')) { const ast = this.parse(rawUrl) const templateLiteral = (ast as any).body[0].expression if (templateLiteral.expressions.length) { @@ -72,7 +72,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { const url = rawUrl.slice(1, -1) let file: string | undefined - if (url.startsWith('.')) { + if (url[0] === '.') { file = slash(path.resolve(path.dirname(id), url)) } else { assetResolver ??= config.createResolver({ diff --git a/packages/vite/src/node/plugins/clientInjections.ts b/packages/vite/src/node/plugins/clientInjections.ts index bf46c0e42ce597..5ac79c8d14ef8e 100644 --- a/packages/vite/src/node/plugins/clientInjections.ts +++ b/packages/vite/src/node/plugins/clientInjections.ts @@ -4,6 +4,9 @@ import type { ResolvedConfig } from '../config' import { CLIENT_ENTRY, ENV_ENTRY } from '../constants' import { isObject, normalizePath, resolveHostname } from '../utils' +const process_env_NODE_ENV_RE = + /(\bglobal(This)?\.)?\bprocess\.env\.NODE_ENV\b/g + // ids in transform are normalized to unix style const normalizedClientEntry = normalizePath(CLIENT_ENTRY) const normalizedEnvEntry = normalizePath(ENV_ENTRY) @@ -13,60 +16,80 @@ const normalizedEnvEntry = normalizePath(ENV_ENTRY) * @server-only */ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { + let injectConfigValues: (code: string) => string + return { name: 'vite:client-inject', - async transform(code, id, options) { - if (id === normalizedClientEntry || id === normalizedEnvEntry) { - const resolvedServerHostname = ( - await resolveHostname(config.server.host) - ).name - const resolvedServerPort = config.server.port! - const devBase = config.base + async buildStart() { + const resolvedServerHostname = (await resolveHostname(config.server.host)) + .name + const resolvedServerPort = config.server.port! + const devBase = config.base - const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}` + const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}` + + let hmrConfig = config.server.hmr + hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined + const host = hmrConfig?.host || null + const protocol = hmrConfig?.protocol || null + const timeout = hmrConfig?.timeout || 30000 + const overlay = hmrConfig?.overlay !== false + const isHmrServerSpecified = !!hmrConfig?.server + + // hmr.clientPort -> hmr.port + // -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port + let port = hmrConfig?.clientPort || hmrConfig?.port || null + if (config.server.middlewareMode && !isHmrServerSpecified) { + port ||= 24678 + } - let hmrConfig = config.server.hmr - hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined - const host = hmrConfig?.host || null - const protocol = hmrConfig?.protocol || null - const timeout = hmrConfig?.timeout || 30000 - const overlay = hmrConfig?.overlay !== false - const isHmrServerSpecified = !!hmrConfig?.server + let directTarget = hmrConfig?.host || resolvedServerHostname + directTarget += `:${hmrConfig?.port || resolvedServerPort}` + directTarget += devBase - // hmr.clientPort -> hmr.port - // -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port - let port = hmrConfig?.clientPort || hmrConfig?.port || null - if (config.server.middlewareMode && !isHmrServerSpecified) { - port ||= 24678 - } + let hmrBase = devBase + if (hmrConfig?.path) { + hmrBase = path.posix.join(hmrBase, hmrConfig.path) + } - let directTarget = hmrConfig?.host || resolvedServerHostname - directTarget += `:${hmrConfig?.port || resolvedServerPort}` - directTarget += devBase + const serializedDefines = serializeDefine(config.define || {}) - let hmrBase = devBase - if (hmrConfig?.path) { - hmrBase = path.posix.join(hmrBase, hmrConfig.path) - } + const modeReplacement = escapeReplacement(config.mode) + const baseReplacement = escapeReplacement(devBase) + const definesReplacement = () => serializedDefines + const serverHostReplacement = escapeReplacement(serverHost) + const hmrProtocolReplacement = escapeReplacement(protocol) + const hmrHostnameReplacement = escapeReplacement(host) + const hmrPortReplacement = escapeReplacement(port) + const hmrDirectTargetReplacement = escapeReplacement(directTarget) + const hmrBaseReplacement = escapeReplacement(hmrBase) + const hmrTimeoutReplacement = escapeReplacement(timeout) + const hmrEnableOverlayReplacement = escapeReplacement(overlay) + injectConfigValues = (code: string) => { return code - .replace(`__MODE__`, JSON.stringify(config.mode)) - .replace(/__BASE__/g, JSON.stringify(devBase)) - .replace(`__DEFINES__`, serializeDefine(config.define || {})) - .replace(`__SERVER_HOST__`, JSON.stringify(serverHost)) - .replace(`__HMR_PROTOCOL__`, JSON.stringify(protocol)) - .replace(`__HMR_HOSTNAME__`, JSON.stringify(host)) - .replace(`__HMR_PORT__`, JSON.stringify(port)) - .replace(`__HMR_DIRECT_TARGET__`, JSON.stringify(directTarget)) - .replace(`__HMR_BASE__`, JSON.stringify(hmrBase)) - .replace(`__HMR_TIMEOUT__`, JSON.stringify(timeout)) - .replace(`__HMR_ENABLE_OVERLAY__`, JSON.stringify(overlay)) + .replace(`__MODE__`, modeReplacement) + .replace(/__BASE__/g, baseReplacement) + .replace(`__DEFINES__`, definesReplacement) + .replace(`__SERVER_HOST__`, serverHostReplacement) + .replace(`__HMR_PROTOCOL__`, hmrProtocolReplacement) + .replace(`__HMR_HOSTNAME__`, hmrHostnameReplacement) + .replace(`__HMR_PORT__`, hmrPortReplacement) + .replace(`__HMR_DIRECT_TARGET__`, hmrDirectTargetReplacement) + .replace(`__HMR_BASE__`, hmrBaseReplacement) + .replace(`__HMR_TIMEOUT__`, hmrTimeoutReplacement) + .replace(`__HMR_ENABLE_OVERLAY__`, hmrEnableOverlayReplacement) + } + }, + transform(code, id, options) { + if (id === normalizedClientEntry || id === normalizedEnvEntry) { + return injectConfigValues(code) } else if (!options?.ssr && code.includes('process.env.NODE_ENV')) { // replace process.env.NODE_ENV instead of defining a global // for it to avoid shimming a `process` object during dev, // avoiding inconsistencies between dev and build return code.replace( - /(\bglobal(This)?\.)?\bprocess\.env\.NODE_ENV\b/g, + process_env_NODE_ENV_RE, config.define?.['process.env.NODE_ENV'] || JSON.stringify(process.env.NODE_ENV || config.mode), ) @@ -75,6 +98,11 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { } } +function escapeReplacement(value: string | number | boolean | null) { + const jsonValue = JSON.stringify(value) + return () => jsonValue +} + function serializeDefine(define: Record): string { let res = `{` for (const key in define) { diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 9511646956ea29..1ea8cba9c510d9 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -1,4 +1,5 @@ import fs from 'node:fs' +import fsp from 'node:fs/promises' import path from 'node:path' import { createRequire } from 'node:module' import glob from 'fast-glob' @@ -166,10 +167,10 @@ export const removedPureCssFilesCache = new WeakMap< Map >() -const postcssConfigCache: Record< - string, - WeakMap -> = {} +const postcssConfigCache = new WeakMap< + ResolvedConfig, + PostCSSConfigResult | null | Promise +>() function encodePublicUrlsInCSS(config: ResolvedConfig) { return config.command === 'build' @@ -188,6 +189,9 @@ export function cssPlugin(config: ResolvedConfig): Plugin { extensions: [], }) + // warm up cache for resolved postcss config + resolvePostcssConfig(config) + return { name: 'vite:css', @@ -502,9 +506,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { const toRelative = (filename: string, importer: string) => { // relative base + extracted CSS const relativePath = path.posix.relative(cssAssetDirname!, filename) - return relativePath.startsWith('.') - ? relativePath - : './' + relativePath + return relativePath[0] === '.' ? relativePath : './' + relativePath } // replace asset url references with resolved url. @@ -803,7 +805,7 @@ async function compileCSS( const needInlineImport = code.includes('@import') const hasUrl = cssUrlRE.test(code) || cssImageSetRE.test(code) const lang = id.match(CSS_LANGS_RE)?.[1] as CssLang | undefined - const postcssConfig = await resolvePostcssConfig(config, getCssDialect(lang)) + const postcssConfig = await resolvePostcssConfig(config) // 1. plain css that needs no processing if ( @@ -884,14 +886,6 @@ async function compileCSS( // 3. postcss const postcssOptions = (postcssConfig && postcssConfig.options) || {} - // for sugarss change parser - if (lang === 'sss') { - postcssOptions.parser = loadPreprocessor( - PostCssDialectLang.sss, - config.root, - ) - } - const postcssPlugins = postcssConfig && postcssConfig.plugins ? postcssConfig.plugins.slice() : [] @@ -974,6 +968,10 @@ async function compileCSS( .default(postcssPlugins) .process(code, { ...postcssOptions, + parser: + lang === 'sss' + ? loadPreprocessor(PostCssDialectLang.sss, config.root) + : postcssOptions.parser, to: source, from: source, ...(devSourcemap @@ -1075,6 +1073,8 @@ export async function preprocessCSS( return await compileCSS(filename, code, config) } +const postcssReturnsVirtualFilesRE = /^<.+>$/ + export async function formatPostcssSourceMap( rawMap: ExistingRawSourceMap, file: string, @@ -1084,8 +1084,7 @@ export async function formatPostcssSourceMap( const sources = rawMap.sources.map((source) => { const cleanSource = cleanUrl(decodeURIComponent(source)) - // postcss returns virtual files - if (/^<.+>$/.test(cleanSource)) { + if (postcssReturnsVirtualFilesRE.test(cleanSource)) { return `\0${cleanSource}` } @@ -1139,16 +1138,10 @@ interface PostCSSConfigResult { async function resolvePostcssConfig( config: ResolvedConfig, - dialect = 'css', ): Promise { - postcssConfigCache[dialect] ??= new WeakMap< - ResolvedConfig, - PostCSSConfigResult | null - >() - - let result = postcssConfigCache[dialect].get(config) + let result = postcssConfigCache.get(config) if (result !== undefined) { - return result + return await result } // inline postcss config via vite config @@ -1164,9 +1157,7 @@ async function resolvePostcssConfig( } else { const searchPath = typeof inlineOptions === 'string' ? inlineOptions : config.root - try { - result = await postcssrc({}, searchPath) - } catch (e) { + result = postcssrc({}, searchPath).catch((e) => { if (!/No PostCSS Config found/.test(e.message)) { if (e instanceof Error) { const { name, message, stack } = e @@ -1178,11 +1169,15 @@ async function resolvePostcssConfig( throw new Error(`Failed to load PostCSS config: ${e}`) } } - result = null - } + return null + }) + // replace cached promise to result object when finished + result.then((resolved) => { + postcssConfigCache.set(config, resolved) + }) } - postcssConfigCache[dialect].set(config, result) + postcssConfigCache.set(config, result) return result } @@ -1318,7 +1313,7 @@ async function doUrlReplace( if ( isExternalUrl(rawUrl) || isDataUrl(rawUrl) || - rawUrl.startsWith('#') || + rawUrl[0] === '#' || varRE.test(rawUrl) ) { return matched @@ -1343,7 +1338,7 @@ async function doImportCSSReplace( wrap = first rawUrl = rawUrl.slice(1, -1) } - if (isExternalUrl(rawUrl) || isDataUrl(rawUrl) || rawUrl.startsWith('#')) { + if (isExternalUrl(rawUrl) || isDataUrl(rawUrl) || rawUrl[0] === '#') { return matched } @@ -1355,6 +1350,7 @@ async function minifyCSS(css: string, config: ResolvedConfig) { const { code, warnings } = await transform(css, { loader: 'css', target: config.build.cssTarget || undefined, + charset: 'utf8', ...resolveEsbuildMinifyOptions(config.esbuild || {}), }) if (warnings.length) { @@ -1543,7 +1539,7 @@ function cleanScssBugUrl(url: string) { if ( // check bug via `window` and `location` global typeof window !== 'undefined' && - typeof location !== 'undefined' + typeof location?.href === 'string' ) { const prefix = location.href.replace(/\/$/, '') return url.replace(prefix, '') @@ -1680,7 +1676,7 @@ async function rebaseUrls( return { file } } - const content = fs.readFileSync(file, 'utf-8') + const content = await fsp.readFile(file, 'utf-8') // no url() const hasUrls = cssUrlRE.test(content) // data-uri() calls @@ -1694,7 +1690,7 @@ async function rebaseUrls( let rebased const rebaseFn = (url: string) => { - if (url.startsWith('/')) return url + if (url[0] === '/') return url // ignore url's starting with variable if (url.startsWith(variablePrefix)) return url // match alias, no need to rewrite @@ -1839,7 +1835,7 @@ function createViteLessPlugin( if (result && 'contents' in result) { contents = result.contents } else { - contents = fs.readFileSync(resolved, 'utf-8') + contents = await fsp.readFile(resolved, 'utf-8') } return { filename: path.resolve(resolved), @@ -1977,7 +1973,3 @@ const preProcessors = Object.freeze({ function isPreProcessor(lang: any): lang is PreprocessLang { return lang && lang in preProcessors } - -function getCssDialect(lang: CssLang | undefined): string { - return lang === 'sss' ? 'sss' : 'css' -} diff --git a/packages/vite/src/node/plugins/dataUri.ts b/packages/vite/src/node/plugins/dataUri.ts index 8d34be298714d4..36c5c0b28b731c 100644 --- a/packages/vite/src/node/plugins/dataUri.ts +++ b/packages/vite/src/node/plugins/dataUri.ts @@ -5,59 +5,56 @@ import { URL } from 'node:url' import type { Plugin } from '../plugin' const dataUriRE = /^([^/]+\/[^;,]+)(;base64)?,([\s\S]*)$/ - -const dataUriPrefix = `/@data-uri/` +const base64RE = /base64/i +const dataUriPrefix = `\0/@data-uri/` /** * Build only, since importing from a data URI works natively. */ export function dataURIPlugin(): Plugin { - let resolved: { - [key: string]: string - } + let resolved: Map return { name: 'vite:data-uri', buildStart() { - resolved = {} + resolved = new Map() }, resolveId(id) { if (!dataUriRE.test(id)) { - return null + return } const uri = new URL(id) if (uri.protocol !== 'data:') { - return null + return } const match = uri.pathname.match(dataUriRE) if (!match) { - return null + return } const [, mime, format, data] = match if (mime !== 'text/javascript') { throw new Error( - `data URI with non-JavaScript mime type is not supported.`, + `data URI with non-JavaScript mime type is not supported. If you're using legacy JavaScript MIME types (such as 'application/javascript'), please use 'text/javascript' instead.`, ) } // decode data - const base64 = format && /base64/i.test(format.substring(1)) + const base64 = format && base64RE.test(format.substring(1)) const content = base64 ? Buffer.from(data, 'base64').toString('utf-8') : data - resolved[id] = content + resolved.set(id, content) return dataUriPrefix + id }, load(id) { if (id.startsWith(dataUriPrefix)) { - id = id.slice(dataUriPrefix.length) - return resolved[id] || null + return resolved.get(id.slice(dataUriPrefix.length)) } }, } diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts index f47a3ff97fed64..c0c37183b81aaf 100644 --- a/packages/vite/src/node/plugins/define.ts +++ b/packages/vite/src/node/plugins/define.ts @@ -1,7 +1,7 @@ import MagicString from 'magic-string' import type { ResolvedConfig } from '../config' import type { Plugin } from '../plugin' -import { transformStableResult } from '../utils' +import { escapeRegex, transformStableResult } from '../utils' import { isCSSRequest } from './css' import { isHTMLRequest } from './html' @@ -113,11 +113,7 @@ export function definePlugin(config: ResolvedConfig): Plugin { // Mustn't be preceded by a char that can be part of an identifier // or a '.' that isn't part of a spread operator '(? { - return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&') - }) - .join('|') + + replacementsKeys.map(escapeRegex).join('|') + // Mustn't be followed by a char that can be part of an identifier // or an assignment (but allow equality operators) ')(?:(?<=\\.)|(?![\\p{L}\\p{N}_$]|\\s*?=[^=]))', diff --git a/packages/vite/src/node/plugins/dynamicImportVars.ts b/packages/vite/src/node/plugins/dynamicImportVars.ts index f730fc9e093bbf..7933618d49da08 100644 --- a/packages/vite/src/node/plugins/dynamicImportVars.ts +++ b/packages/vite/src/node/plugins/dynamicImportVars.ts @@ -19,6 +19,7 @@ import { toAbsoluteGlob } from './importMetaGlob' export const dynamicImportHelperId = '\0vite/dynamic-import-helper' +const relativePathRE = /^\.{1,2}\// interface DynamicImportRequest { as?: keyof KnownAsTypeMap } @@ -122,7 +123,7 @@ export async function transformDynamicImport( await toAbsoluteGlob(rawPattern, root, importer, resolve), ) - if (!/^\.{1,2}\//.test(newRawPattern)) { + if (!relativePathRE.test(newRawPattern)) { newRawPattern = `./${newRawPattern}` } diff --git a/packages/vite/src/node/plugins/esbuild.ts b/packages/vite/src/node/plugins/esbuild.ts index 5db99c648bf4e0..fac8c44b140f67 100644 --- a/packages/vite/src/node/plugins/esbuild.ts +++ b/packages/vite/src/node/plugins/esbuild.ts @@ -9,7 +9,7 @@ import type { import { transform } from 'esbuild' import type { RawSourceMap } from '@ampproject/remapping' import type { InternalModuleFormat, SourceMap } from 'rollup' -import type { TSConfckParseOptions, TSConfckParseResult } from 'tsconfck' +import type { TSConfckParseOptions } from 'tsconfck' import { TSConfckParseError, findAll, parse } from 'tsconfck' import { cleanUrl, @@ -18,11 +18,13 @@ import { createFilter, ensureWatchedFile, generateCodeFrame, + timeFrom, } from '../utils' import type { ResolvedConfig, ViteDevServer } from '..' import type { Plugin } from '../plugin' import { searchForWorkspaceRoot } from '..' +const isDebug = process.env.DEBUG const debug = createDebugger('vite:esbuild') const INJECT_HELPERS_IIFE_RE = @@ -30,6 +32,9 @@ const INJECT_HELPERS_IIFE_RE = const INJECT_HELPERS_UMD_RE = /^(.*?)(\(function\([^)]*\)\s*\{.+?amd.+?function\([^)]*\)\s*\{.*?"use strict";)/s +const validExtensionRE = /\.\w+$/ +const jsxExtensionsRE = /\.(?:j|t)sx\b/ + let server: ViteDevServer export interface ESBuildOptions extends TransformOptions { @@ -75,7 +80,7 @@ export async function transformWithEsbuild( // if the id ends with a valid ext, use it (e.g. vue blocks) // otherwise, cleanup the query before checking the ext const ext = path - .extname(/\.\w+$/.test(filename) ? filename : cleanUrl(filename)) + .extname(validExtensionRE.test(filename) ? filename : cleanUrl(filename)) .slice(1) if (ext === 'cjs' || ext === 'mjs') { @@ -117,30 +122,39 @@ export async function transformWithEsbuild( } } - tsconfigRaw = { - ...tsconfigRaw, - compilerOptions: { - ...compilerOptionsForFile, - ...tsconfigRaw?.compilerOptions, - }, + const compilerOptions = { + ...compilerOptionsForFile, + ...tsconfigRaw?.compilerOptions, } - const { compilerOptions } = tsconfigRaw - if (compilerOptions) { - // esbuild derives `useDefineForClassFields` from `target` instead of `tsconfig.compilerOptions.target` - // https://github.com/evanw/esbuild/issues/2584 - // but we want `useDefineForClassFields` to be derived from `tsconfig.compilerOptions.target` - if (compilerOptions.useDefineForClassFields === undefined) { - const lowercaseTarget = compilerOptions.target?.toLowerCase() ?? 'es3' - if (lowercaseTarget.startsWith('es')) { - const esVersion = lowercaseTarget.slice(2) - compilerOptions.useDefineForClassFields = - esVersion === 'next' || +esVersion >= 2022 - } else { - compilerOptions.useDefineForClassFields = false - } + // esbuild derives `useDefineForClassFields` from `target` instead of `tsconfig.compilerOptions.target` + // https://github.com/evanw/esbuild/issues/2584 + // but we want `useDefineForClassFields` to be derived from `tsconfig.compilerOptions.target` + if (compilerOptions.useDefineForClassFields === undefined) { + const lowercaseTarget = compilerOptions.target?.toLowerCase() ?? 'es3' + if (lowercaseTarget.startsWith('es')) { + const esVersion = lowercaseTarget.slice(2) + compilerOptions.useDefineForClassFields = + esVersion === 'next' || +esVersion >= 2022 + } else { + compilerOptions.useDefineForClassFields = false } } + + // esbuild uses tsconfig fields when both the normal options and tsconfig was set + // but we want to prioritize the normal options + if (options) { + options.jsx && (compilerOptions.jsx = undefined) + options.jsxFactory && (compilerOptions.jsxFactory = undefined) + options.jsxFragment && (compilerOptions.jsxFragmentFactory = undefined) + options.jsxImportSource && (compilerOptions.jsxImportSource = undefined) + options.target && (compilerOptions.target = undefined) + } + + tsconfigRaw = { + ...tsconfigRaw, + compilerOptions, + } } const resolvedOptions = { @@ -152,25 +166,8 @@ export async function transformWithEsbuild( tsconfigRaw, } as ESBuildOptions - // esbuild uses tsconfig fields when both the normal options and tsconfig was set - // but we want to prioritize the normal options - if ( - options && - typeof resolvedOptions.tsconfigRaw === 'object' && - resolvedOptions.tsconfigRaw.compilerOptions - ) { - options.jsx && (resolvedOptions.tsconfigRaw.compilerOptions.jsx = undefined) - options.jsxFactory && - (resolvedOptions.tsconfigRaw.compilerOptions.jsxFactory = undefined) - options.jsxFragment && - (resolvedOptions.tsconfigRaw.compilerOptions.jsxFragmentFactory = - undefined) - options.jsxImportSource && - (resolvedOptions.tsconfigRaw.compilerOptions.jsxImportSource = undefined) - options.target && - (resolvedOptions.tsconfigRaw.compilerOptions.target = undefined) - } - + // Some projects in the ecosystem are calling this function with an ESBuildOptions + // object and esbuild throws an error for extra fields delete resolvedOptions.include delete resolvedOptions.exclude delete resolvedOptions.jsxInject @@ -209,18 +206,18 @@ export async function transformWithEsbuild( } } -export function esbuildPlugin(options: ESBuildOptions): Plugin { - const filter = createFilter( - options.include || /\.(m?ts|[jt]sx)$/, - options.exclude || /\.js$/, - ) +export function esbuildPlugin(config: ResolvedConfig): Plugin { + const options = config.esbuild as ESBuildOptions + const { jsxInject, include, exclude, ...esbuildTransformOptions } = options + + const filter = createFilter(include || /\.(m?ts|[jt]sx)$/, exclude || /\.js$/) // Remove optimization options for dev as we only need to transpile them, // and for build as the final optimization is in `buildEsbuildPlugin` const transformOptions: TransformOptions = { target: 'esnext', charset: 'utf8', - ...options, + ...esbuildTransformOptions, minify: false, minifyIdentifiers: false, minifySyntax: false, @@ -232,6 +229,8 @@ export function esbuildPlugin(options: ESBuildOptions): Plugin { keepNames: false, } + initTSConfck(config.root) + return { name: 'vite:esbuild', configureServer(_server) { @@ -241,9 +240,6 @@ export function esbuildPlugin(options: ESBuildOptions): Plugin { .on('change', reloadOnTsconfigChange) .on('unlink', reloadOnTsconfigChange) }, - async configResolved(config) { - await initTSConfck(config) - }, buildEnd() { // recycle serve to avoid preventing Node self-exit (#6815) server = null as any @@ -256,8 +252,8 @@ export function esbuildPlugin(options: ESBuildOptions): Plugin { this.warn(prettifyMessage(m, code)) }) } - if (options.jsxInject && /\.(?:j|t)sx\b/.test(id)) { - result.code = options.jsxInject + ';' + result.code + if (jsxInject && jsxExtensionsRE.test(id)) { + result.code = jsxInject + ';' + result.code } return { code: result.code, @@ -287,11 +283,10 @@ const rollupToEsbuildFormatMap: Record< } export const buildEsbuildPlugin = (config: ResolvedConfig): Plugin => { + initTSConfck(config.root) + return { name: 'vite:esbuild-transpile', - async configResolved(config) { - await initTSConfck(config) - }, async renderChunk(code, chunk, opts) { // @ts-expect-error injected by @vitejs/plugin-legacy if (opts.__vite_skip_esbuild__) { @@ -438,32 +433,51 @@ function prettifyMessage(m: Message, code: string): string { return res + `\n` } -const tsconfckParseOptions: TSConfckParseOptions = { - cache: new Map(), - tsConfigPaths: undefined, - root: undefined, - resolveWithEmptyIfConfigNotFound: true, +let tsconfckRoot: string | undefined +let tsconfckParseOptions: TSConfckParseOptions | Promise = + { resolveWithEmptyIfConfigNotFound: true } + +function initTSConfck(root: string, force = false) { + // bail if already cached + if (!force && root === tsconfckRoot) return + + const workspaceRoot = searchForWorkspaceRoot(root) + + tsconfckRoot = root + tsconfckParseOptions = initTSConfckParseOptions(workspaceRoot) + + // cached as the options value itself when promise is resolved + tsconfckParseOptions.then((options) => { + if (root === tsconfckRoot) { + tsconfckParseOptions = options + } + }) } -async function initTSConfck(config: ResolvedConfig) { - const workspaceRoot = searchForWorkspaceRoot(config.root) - debug(`init tsconfck (root: ${colors.cyan(workspaceRoot)})`) - - tsconfckParseOptions.cache!.clear() - tsconfckParseOptions.root = workspaceRoot - tsconfckParseOptions.tsConfigPaths = new Set([ - ...(await findAll(workspaceRoot, { - skip: (dir) => dir === 'node_modules' || dir === '.git', - })), - ]) - debug(`init tsconfck end`) +async function initTSConfckParseOptions(workspaceRoot: string) { + const start = isDebug ? performance.now() : 0 + + const options: TSConfckParseOptions = { + cache: new Map(), + root: workspaceRoot, + tsConfigPaths: new Set( + await findAll(workspaceRoot, { + skip: (dir) => dir === 'node_modules' || dir === '.git', + }), + ), + resolveWithEmptyIfConfigNotFound: true, + } + + isDebug && debug(timeFrom(start), 'tsconfck init', colors.dim(workspaceRoot)) + + return options } async function loadTsconfigJsonForFile( filename: string, ): Promise { try { - const result = await parse(filename, tsconfckParseOptions) + const result = await parse(filename, await tsconfckParseOptions) // tsconfig could be out of root, make sure it is watched on dev if (server && result.tsconfigFile !== 'no_tsconfig_file_found') { ensureWatchedFile(server.watcher, result.tsconfigFile, server.config.root) @@ -480,7 +494,7 @@ async function loadTsconfigJsonForFile( } } -function reloadOnTsconfigChange(changedFile: string) { +async function reloadOnTsconfigChange(changedFile: string) { // server could be closed externally after a file change is detected if (!server) return // any tsconfig.json that's added in the workspace could be closer to a code file than a previously cached one @@ -488,7 +502,7 @@ function reloadOnTsconfigChange(changedFile: string) { if ( path.basename(changedFile) === 'tsconfig.json' || (changedFile.endsWith('.json') && - tsconfckParseOptions?.cache?.has(changedFile)) + (await tsconfckParseOptions)?.cache?.has(changedFile)) ) { server.config.logger.info( `changed tsconfig file detected: ${changedFile} - Clearing cache and forcing full-reload to ensure TypeScript is compiled with updated config values.`, @@ -499,15 +513,15 @@ function reloadOnTsconfigChange(changedFile: string) { server.moduleGraph.invalidateAll() // reset tsconfck so that recompile works with up2date configs - initTSConfck(server.config).finally(() => { - // server may not be available if vite config is updated at the same time - if (server) { - // force full reload - server.ws.send({ - type: 'full-reload', - path: '*', - }) - } - }) + initTSConfck(server.config.root, true) + + // server may not be available if vite config is updated at the same time + if (server) { + // force full reload + server.ws.send({ + type: 'full-reload', + path: '*', + }) + } } } diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 9737dcb3a9e9b7..769de344b15290 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -18,8 +18,10 @@ import { getHash, isDataUrl, isExternalUrl, + isUrl, normalizePath, processSrcSet, + removeLeadingSlash, } from '../utils' import type { ResolvedConfig } from '../config' import { toOutputFilePathInHtml } from '../build' @@ -290,7 +292,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { postHooks.push(postImportMapHook()) const processedHtml = new Map() const isExcludedUrl = (url: string) => - url.startsWith('#') || + url[0] === '#' || isExternalUrl(url) || isDataUrl(url) || checkPublicFile(url, config) @@ -537,7 +539,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { if ( content !== '' && // Empty attribute !namedOutput.includes(content) && // Direct reference to named output - !namedOutput.includes(content.replace(/^\//, '')) // Allow for absolute references as named output can't be an absolute path + !namedOutput.includes(removeLeadingSlash(content)) // Allow for absolute references as named output can't be an absolute path ) { try { const url = @@ -811,11 +813,13 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { }) result = result.replace(publicAssetUrlRE, (_, fileHash) => { - return normalizePath( - toOutputPublicAssetFilePath( - getPublicAssetFilename(fileHash, config)!, - ), + const publicAssetPath = toOutputPublicAssetFilePath( + getPublicAssetFilename(fileHash, config)!, ) + + return isUrl(publicAssetPath) + ? publicAssetPath + : normalizePath(publicAssetPath) }) if (chunk && canInlineEntry) { diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index b18c9c6bc2f511..c1a7b6403502cb 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -32,6 +32,7 @@ import { isBuiltin, isDataUrl, isExternalUrl, + isInNodeModules, isJSRequest, joinUrlSegments, moduleListContains, @@ -53,11 +54,7 @@ import { shouldExternalizeForSSR, } from '../ssr/ssrExternal' import { transformRequest } from '../server/transformRequest' -import { - getDepsCacheDirPrefix, - getDepsOptimizer, - optimizedDepNeedsInterop, -} from '../optimizer' +import { getDepsOptimizer, optimizedDepNeedsInterop } from '../optimizer' import { checkPublicFile } from './asset' import { ERR_OUTDATED_OPTIMIZED_DEP, @@ -78,6 +75,13 @@ export const canSkipImportAnalysis = (id: string): boolean => const optimizedDepChunkRE = /\/chunk-[A-Z\d]{8}\.js/ const optimizedDepDynamicRE = /-[A-Z\d]{8}\.js/ +const hasImportInQueryParamsRE = /[?&]import=?\b/ + +const hasViteIgnoreRE = /\/\*\s*@vite-ignore\s*\*\// + +const cleanUpRawUrlRE = /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm +const urlIsStringRE = /^(?:'.*'|".*"|`.*`)$/ + export function isExplicitImportRequired(url: string): boolean { return !isJSRequest(cleanUrl(url)) && !isCSSRequest(url) } @@ -331,7 +335,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { ) } - const isRelative = url.startsWith('.') + const isRelative = url[0] === '.' const isSelfImport = !isRelative && cleanUrl(url) === cleanUrl(importer) // normalize all imports into resolved URLs @@ -340,7 +344,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { // in root: infer short absolute path from root url = resolved.id.slice(root.length) } else if ( - resolved.id.startsWith(getDepsCacheDirPrefix(config)) || + depsOptimizer?.isOptimizedDepFile(resolved.id) || fs.existsSync(cleanUrl(resolved.id)) ) { // an optimized deps may not yet exists in the filesystem, or @@ -357,7 +361,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { // if the resolved id is not a valid browser import specifier, // prefix it to make it valid. We will strip this before feeding it // back into the transform pipeline - if (!url.startsWith('.') && !url.startsWith('/')) { + if (url[0] !== '.' && url[0] !== '/') { url = wrapId(resolved.id) } @@ -373,7 +377,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { // query can break 3rd party plugin's extension checks. if ( (isRelative || isSelfImport) && - !/[?&]import=?\b/.test(url) && + !hasImportInQueryParamsRE.test(url) && !url.match(DEP_VERSION_RE) ) { const versionMatch = importer.match(DEP_VERSION_RE) @@ -489,7 +493,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { // warn imports to non-asset /public files if ( - specifier.startsWith('/') && + specifier[0] === '/' && !config.assetsInclude(cleanUrl(specifier)) && !specifier.endsWith('.json') && checkPublicFile(specifier, config) @@ -611,9 +615,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { staticImportedUrls.add({ url: hmrUrl, id: resolvedId }) } } else if (!importer.startsWith(clientDir)) { - if (!importer.includes('node_modules')) { + if (!isInNodeModules(importer)) { // check @vite-ignore which suppresses dynamic import warning - const hasViteIgnore = /\/\*\s*@vite-ignore\s*\*\//.test( + const hasViteIgnore = hasViteIgnoreRE.test( // complete expression inside parens source.slice(dynamicIndex + 1, end), ) @@ -637,11 +641,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { } if (!ssr) { - const url = rawUrl - .replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '') - .trim() + const url = rawUrl.replace(cleanUpRawUrlRE, '').trim() if ( - !/^(?:'.*'|".*"|`.*`)$/.test(url) || + !urlIsStringRE.test(url) || isExplicitImportRequired(url.slice(1, -1)) ) { needQueryInjectHelper = true diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts index ea79c21b13ca71..d04229dc73475f 100644 --- a/packages/vite/src/node/plugins/importAnalysisBuild.ts +++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts @@ -11,6 +11,7 @@ import { combineSourcemaps, isDataUrl, isExternalUrl, + isInNodeModules, moduleListContains, } from '../utils' import type { Plugin } from '../plugin' @@ -44,7 +45,7 @@ const optimizedDepDynamicRE = /-[A-Z\d]{8}\.js/ function toRelativePath(filename: string, importer: string) { const relPath = path.relative(path.dirname(importer), filename) - return relPath.startsWith('.') ? relPath : `./${relPath}` + return relPath[0] === '.' ? relPath : `./${relPath}` } /** @@ -185,10 +186,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { }, async transform(source, importer) { - if ( - importer.includes('node_modules') && - !dynamicImportPrefixRE.test(source) - ) { + if (isInNodeModules(importer) && !dynamicImportPrefixRE.test(source)) { return } diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index 11d495f76baecf..10fe5f9120bbd5 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -412,7 +412,7 @@ export async function transformGlobImport( ? options.query : stringifyQuery(options.query as any) - if (query && !query.startsWith('?')) query = `?${query}` + if (query && query[0] !== '?') query = `?${query}` const resolvePaths = (file: string) => { if (!dir) { @@ -425,14 +425,14 @@ export async function transformGlobImport( } let importPath = relative(dir, file) - if (!importPath.startsWith('.')) importPath = `./${importPath}` + if (importPath[0] !== '.') importPath = `./${importPath}` let filePath: string if (isRelative) { filePath = importPath } else { filePath = relative(root, file) - if (!filePath.startsWith('.')) filePath = `/${filePath}` + if (filePath[0] !== '.') filePath = `/${filePath}` } return { filePath, importPath } @@ -583,13 +583,13 @@ export async function toAbsoluteGlob( resolveId: IdResolver, ): Promise { let pre = '' - if (glob.startsWith('!')) { + if (glob[0] === '!') { pre = '!' glob = glob.slice(1) } root = globSafePath(root) const dir = importer ? globSafePath(dirname(importer)) : root - if (glob.startsWith('/')) return pre + posix.join(root, glob.slice(1)) + if (glob[0] === '/') return pre + posix.join(root, glob.slice(1)) if (glob.startsWith('./')) return pre + posix.join(dir, glob.slice(2)) if (glob.startsWith('../')) return pre + posix.join(dir, glob) if (glob.startsWith('**')) return pre + glob @@ -606,7 +606,7 @@ export async function toAbsoluteGlob( export function getCommonBase(globsResolved: string[]): null | string { const bases = globsResolved - .filter((g) => !g.startsWith('!')) + .filter((g) => g[0] !== '!') .map((glob) => { let { base } = scan(glob) // `scan('a/foo.js')` returns `base: 'a/foo.js'` @@ -632,5 +632,5 @@ export function getCommonBase(globsResolved: string[]): null | string { export function isVirtualModule(id: string): boolean { // https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention - return id.startsWith('virtual:') || id.startsWith('\0') || !id.includes('/') + return id.startsWith('virtual:') || id[0] === '\0' || !id.includes('/') } diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index 1dbd8bf90b95fc..928d2db7f3225b 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -72,7 +72,7 @@ export async function resolvePlugins( }), htmlInlineProxyPlugin(config), cssPlugin(config), - config.esbuild !== false ? esbuildPlugin(config.esbuild) : null, + config.esbuild !== false ? esbuildPlugin(config) : null, jsonPlugin( { namedExports: true, diff --git a/packages/vite/src/node/plugins/optimizedDeps.ts b/packages/vite/src/node/plugins/optimizedDeps.ts index a40cea5c5670dd..2ede063462b6cd 100644 --- a/packages/vite/src/node/plugins/optimizedDeps.ts +++ b/packages/vite/src/node/plugins/optimizedDeps.ts @@ -17,7 +17,7 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin { return { name: 'vite:optimized-deps', - async resolveId(id, source, { ssr }) { + resolveId(id, source, { ssr }) { if (getDepsOptimizer(config, ssr)?.isOptimizedDepFile(id)) { return id } @@ -89,7 +89,7 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin { } }, - async resolveId(id, importer, { ssr }) { + resolveId(id, importer, { ssr }) { if (getDepsOptimizer(config, ssr)?.isOptimizedDepFile(id)) { return id } @@ -116,31 +116,19 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin { // If all the inputs are dependencies, we aren't going to get any const info = optimizedDepInfoFromFile(depsOptimizer.metadata, file) if (info) { - try { - // This is an entry point, it may still not be bundled - await info.processing - } catch { - // If the refresh has not happened after timeout, Vite considers - // something unexpected has happened. In this case, Vite - // returns an empty response that will error. - // throwProcessingError(id) - return - } + await info.processing isDebug && debug(`load ${colors.cyan(file)}`) } else { - // TODO: error - return + throw new Error( + `Something unexpected happened while optimizing "${id}".`, + ) } // Load the file from the cache instead of waiting for other plugin // load hooks to avoid race conditions, once processing is resolved, // we are sure that the file has been properly save to disk - try { - return await fs.readFile(file, 'utf-8') - } catch (e) { - // Outdated non-entry points (CHUNK), loaded after a rerun - return '' - } + + return await fs.readFile(file, 'utf-8') }, } } diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts index 2b285723d1d80a..f3d31e14e0a733 100644 --- a/packages/vite/src/node/plugins/preAlias.ts +++ b/packages/vite/src/node/plugins/preAlias.ts @@ -11,6 +11,7 @@ import { createIsConfiguredAsSsrExternal } from '../ssr/ssrExternal' import { bareImportRE, cleanUrl, + isInNodeModules, isOptimizable, moduleListContains, } from '../utils' @@ -60,7 +61,7 @@ export function preAliasPlugin(config: ResolvedConfig): Plugin { fs.existsSync(resolvedId) && !moduleListContains(optimizeDeps.exclude, id) && path.isAbsolute(resolvedId) && - (resolvedId.includes('node_modules') || + (isInNodeModules(resolvedId) || optimizeDeps.include?.includes(id)) && isOptimizable(resolvedId, optimizeDeps) && !(isBuild && ssr && isConfiguredAsExternal(id)) && diff --git a/packages/vite/src/node/plugins/reporter.ts b/packages/vite/src/node/plugins/reporter.ts index 5b8ae593bdefea..0559e02dd5cb89 100644 --- a/packages/vite/src/node/plugins/reporter.ts +++ b/packages/vite/src/node/plugins/reporter.ts @@ -20,6 +20,8 @@ type LogEntry = { mapSize: number | null } +const COMPRESSIBLE_ASSETS_RE = /\.(?:html|json|svg|txt|xml|xhtml)$/ + export function buildReporterPlugin(config: ResolvedConfig): Plugin { const compress = promisify(gzip) const chunkLimit = config.build.chunkSizeWarningLimit @@ -144,12 +146,14 @@ export function buildReporterPlugin(config: ResolvedConfig): Plugin { } else { if (chunk.fileName.endsWith('.map')) return null const isCSS = chunk.fileName.endsWith('.css') + const isCompressible = + isCSS || COMPRESSIBLE_ASSETS_RE.test(chunk.fileName) return { name: chunk.fileName, group: isCSS ? 'CSS' : 'Assets', size: chunk.source.length, mapSize: null, // Rollup doesn't support CSS maps? - compressedSize: isCSS + compressedSize: isCompressible ? await getCompressedSize(chunk.source) : null, } diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 4cdd2043cc41b7..0d6b732e5ade2c 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -19,30 +19,35 @@ import { bareImportRE, cleanUrl, createDebugger, + deepImportRE, ensureVolumeInPath, fsPathFromId, - getPotentialTsSrcPaths, injectQuery, isBuiltin, isDataUrl, isExternalUrl, + isInNodeModules, isNonDriveRelativeAbsolutePath, isObject, isOptimizable, - isPossibleTsOutput, isTsRequest, isWindows, - lookupFile, normalizePath, resolveFrom, + safeRealpathSync, slash, + tryStatSync, } from '../utils' import { optimizedDepInfoFromFile, optimizedDepInfoFromId } from '../optimizer' import type { DepsOptimizer } from '../optimizer' import type { SSROptions } from '..' import type { PackageCache, PackageData } from '../packages' -import { loadPackageData, resolvePackageData } from '../packages' -import { isWorkerRequest } from './worker' +import { + findNearestMainPackageData, + findNearestPackageData, + loadPackageData, + resolvePackageData, +} from '../packages' const normalizedClientEntry = normalizePath(CLIENT_ENTRY) const normalizedEnvEntry = normalizePath(ENV_ENTRY) @@ -53,9 +58,10 @@ export const browserExternalId = '__vite-browser-external' // special id for packages that are optional peer deps export const optionalPeerDepId = '__vite-optional-peer-dep' -const nodeModulesInPathRE = /(?:^|\/)node_modules\// const subpathImportsPrefix = '#' +const startsWithWordCharRE = /^\w/ + const isDebug = process.env.DEBUG const debug = createDebugger('vite:resolve-details', { onlyWhenFocused: true, @@ -97,7 +103,6 @@ export interface InternalResolveOptions extends Required { asSrc?: boolean tryIndex?: boolean tryPrefix?: string - skipPackageJson?: boolean preferRelative?: boolean isRequire?: boolean // #3040 @@ -126,6 +131,13 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { const { target: ssrTarget, noExternal: ssrNoExternal } = ssrConfig ?? {} + // In unix systems, absolute paths inside root first needs to be checked as an + // absolute URL (/root/root/path-to-file) resulting in failed checks before falling + // back to checking the path as absolute. If /root/root isn't a valid path, we can + // avoid these checks. Absolute paths inside root are common in user code as many + // paths are resolved by the user. For example for an alias. + const rootInRoot = tryStatSync(path.join(root, root))?.isDirectory() ?? false + return { name: 'vite:resolve', @@ -152,53 +164,24 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { scan: resolveOpts?.scan ?? resolveOptions.scan, } - const resolveSubpathImports = (id: string, importer?: string) => { - if (!importer || !id.startsWith(subpathImportsPrefix)) return - const basedir = path.dirname(importer) - const pkgJsonPath = lookupFile(basedir, ['package.json'], { - pathOnly: true, - }) - if (!pkgJsonPath) return - - const pkgData = loadPackageData(pkgJsonPath, options.preserveSymlinks) - let importsPath = resolveExportsOrImports( - pkgData.data, - id, - options, - targetWeb, - 'imports', - ) - - if (importsPath?.startsWith('.')) { - importsPath = path.relative( - basedir, - path.join(path.dirname(pkgJsonPath), importsPath), - ) - - if (!importsPath.startsWith('.')) { - importsPath = `./${importsPath}` - } - } - - return importsPath - } - - const resolvedImports = resolveSubpathImports(id, importer) + const resolvedImports = resolveSubpathImports( + id, + importer, + options, + targetWeb, + ) if (resolvedImports) { id = resolvedImports } if (importer) { - const _importer = isWorkerRequest(importer) - ? splitFileAndPostfix(importer).file - : importer if ( - isTsRequest(_importer) || + isTsRequest(importer) || resolveOpts.custom?.depScan?.loader?.startsWith('ts') ) { options.isFromTsImporter = true } else { - const moduleLang = this.getModuleInfo(_importer)?.meta?.vite?.lang + const moduleLang = this.getModuleInfo(importer)?.meta?.vite?.lang options.isFromTsImporter = moduleLang && isTsRequest(`.${moduleLang}`) } } @@ -215,34 +198,6 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { return optimizedPath } - const ensureVersionQuery = (resolved: string): string => { - if ( - !options.isBuild && - !options.scan && - depsOptimizer && - !( - resolved === normalizedClientEntry || - resolved === normalizedEnvEntry - ) - ) { - // Ensure that direct imports of node_modules have the same version query - // as if they would have been imported through a bare import - // Use the original id to do the check as the resolved id may be the real - // file path after symlinks resolution - const isNodeModule = - nodeModulesInPathRE.test(normalizePath(id)) || - nodeModulesInPathRE.test(normalizePath(resolved)) - - if (isNodeModule && !resolved.match(DEP_VERSION_RE)) { - const versionHash = depsOptimizer.metadata.browserHash - if (versionHash && isOptimizable(resolved, depsOptimizer.options)) { - resolved = injectQuery(resolved, `v=${versionHash}`) - } - } - } - return resolved - } - // explicit fs paths that starts with /@fs/* if (asSrc && id.startsWith(FS_PREFIX)) { const fsPath = fsPathFromId(id) @@ -250,23 +205,24 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { isDebug && debug(`[@fs] ${colors.cyan(id)} -> ${colors.dim(res)}`) // always return here even if res doesn't exist since /@fs/ is explicit // if the file doesn't exist it should be a 404 - return ensureVersionQuery(res || fsPath) + return ensureVersionQuery(res || fsPath, id, options, depsOptimizer) } // URL // /foo -> /fs-root/foo - if (asSrc && id.startsWith('/')) { + if (asSrc && id[0] === '/' && (rootInRoot || !id.startsWith(root))) { const fsPath = path.resolve(root, id.slice(1)) if ((res = tryFsResolve(fsPath, options))) { isDebug && debug(`[url] ${colors.cyan(id)} -> ${colors.dim(res)}`) - return ensureVersionQuery(res) + return ensureVersionQuery(res, id, options, depsOptimizer) } } // relative if ( - id.startsWith('.') || - ((preferRelative || importer?.endsWith('.html')) && /^\w/.test(id)) + id[0] === '.' || + ((preferRelative || importer?.endsWith('.html')) && + startsWithWordCharRE.test(id)) ) { const basedir = importer ? path.dirname(importer) : process.cwd() const fsPath = path.resolve(basedir, id) @@ -298,12 +254,13 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { } if ((res = tryFsResolve(fsPath, options))) { - res = ensureVersionQuery(res) + res = ensureVersionQuery(res, id, options, depsOptimizer) isDebug && debug(`[relative] ${colors.cyan(id)} -> ${colors.dim(res)}`) - const pkg = importer != null && idToPkgMap.get(importer) + const pkg = + importer && + findNearestPackageData(path.dirname(importer), options.packageCache) if (pkg) { - idToPkgMap.set(res, pkg) return { id: res, moduleSideEffects: pkg.hasSideEffects(res), @@ -314,13 +271,13 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { } // drive relative fs paths (only windows) - if (isWindows && id.startsWith('/')) { + if (isWindows && id[0] === '/') { const basedir = importer ? path.dirname(importer) : process.cwd() const fsPath = path.resolve(basedir, id) if ((res = tryFsResolve(fsPath, options))) { isDebug && debug(`[drive-relative] ${colors.cyan(id)} -> ${colors.dim(res)}`) - return ensureVersionQuery(res) + return ensureVersionQuery(res, id, options, depsOptimizer) } } @@ -330,7 +287,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { (res = tryFsResolve(id, options)) ) { isDebug && debug(`[fs] ${colors.cyan(id)} -> ${colors.dim(res)}`) - return ensureVersionQuery(res) + return ensureVersionQuery(res, id, options, depsOptimizer) } // external @@ -451,19 +408,67 @@ export default new Proxy({}, { } } -function splitFileAndPostfix(path: string) { - let file = path - let postfix = '' +function resolveSubpathImports( + id: string, + importer: string | undefined, + options: InternalResolveOptions, + targetWeb: boolean, +) { + if (!importer || !id.startsWith(subpathImportsPrefix)) return + const basedir = path.dirname(importer) + const pkgData = findNearestPackageData(basedir, options.packageCache) + if (!pkgData) return + + let importsPath = resolveExportsOrImports( + pkgData.data, + id, + options, + targetWeb, + 'imports', + ) - let postfixIndex = path.indexOf('?') - if (postfixIndex < 0) { - postfixIndex = path.indexOf('#') + if (importsPath?.[0] === '.') { + importsPath = path.relative(basedir, path.join(pkgData.dir, importsPath)) + + if (importsPath[0] !== '.') { + importsPath = `./${importsPath}` + } } - if (postfixIndex > 0) { - file = path.slice(0, postfixIndex) - postfix = path.slice(postfixIndex) + + return importsPath +} + +function ensureVersionQuery( + resolved: string, + id: string, + options: InternalResolveOptions, + depsOptimizer?: DepsOptimizer, +): string { + if ( + !options.isBuild && + !options.scan && + depsOptimizer && + !(resolved === normalizedClientEntry || resolved === normalizedEnvEntry) + ) { + // Ensure that direct imports of node_modules have the same version query + // as if they would have been imported through a bare import + // Use the original id to do the check as the resolved id may be the real + // file path after symlinks resolution + const isNodeModule = isInNodeModules(id) || isInNodeModules(resolved) + + if (isNodeModule && !resolved.match(DEP_VERSION_RE)) { + const versionHash = depsOptimizer.metadata.browserHash + if (versionHash && isOptimizable(resolved, depsOptimizer.options)) { + resolved = injectQuery(resolved, `v=${versionHash}`) + } + } } - return { file, postfix } + return resolved +} + +function splitFileAndPostfix(path: string) { + const file = cleanUrl(path) + return { file, postfix: path.slice(file.length) } } function tryFsResolve( @@ -471,172 +476,167 @@ function tryFsResolve( options: InternalResolveOptions, tryIndex = true, targetWeb = true, + skipPackageJson = false, ): string | undefined { - const { file, postfix } = splitFileAndPostfix(fsPath) - - let res: string | undefined - - // if there is a postfix, try resolving it as a complete path first (#4703) - if ( - postfix && - (res = tryResolveFile( - fsPath, - '', - options, - false, - targetWeb, - options.tryPrefix, - options.skipPackageJson, - )) - ) { - return res - } - - if ( - (res = tryResolveFile( - file, - postfix, - options, - false, - targetWeb, - options.tryPrefix, - options.skipPackageJson, - )) - ) { - return res - } - - for (const ext of options.extensions) { - if ( - postfix && - (res = tryResolveFile( - fsPath + ext, - '', - options, - false, - targetWeb, - options.tryPrefix, - options.skipPackageJson, - false, - )) - ) { - return res - } - - if ( - (res = tryResolveFile( - file + ext, - postfix, + // Dependencies like es5-ext use `#` in their paths. We don't support `#` in user + // source code so we only need to perform the check for dependencies. + // We don't support `?` in node_modules paths, so we only need to check in this branch. + const hashIndex = fsPath.indexOf('#') + if (hashIndex >= 0 && isInNodeModules(fsPath)) { + const queryIndex = fsPath.indexOf('?') + // We only need to check foo#bar?baz and foo#bar, ignore foo?bar#baz + if (queryIndex < 0 || queryIndex > hashIndex) { + const file = queryIndex > hashIndex ? fsPath.slice(0, queryIndex) : fsPath + const res = tryCleanFsResolve( + file, options, - false, + tryIndex, targetWeb, - options.tryPrefix, - options.skipPackageJson, - false, - )) - ) { - return res + skipPackageJson, + ) + if (res) return res + fsPath.slice(file.length) } } - // if `tryIndex` false, skip as we've already tested above - if (!tryIndex) return - - if ( - postfix && - (res = tryResolveFile( - fsPath, - '', - options, - tryIndex, - targetWeb, - options.tryPrefix, - options.skipPackageJson, - )) - ) { - return res - } - - if ( - (res = tryResolveFile( - file, - postfix, - options, - tryIndex, - targetWeb, - options.tryPrefix, - options.skipPackageJson, - )) - ) { - return res - } + const { file, postfix } = splitFileAndPostfix(fsPath) + const res = tryCleanFsResolve( + file, + options, + tryIndex, + targetWeb, + skipPackageJson, + ) + if (res) return res + postfix } -function tryResolveFile( +const knownTsOutputRE = /\.(?:js|mjs|cjs|jsx)$/ +const isPossibleTsOutput = (url: string): boolean => knownTsOutputRE.test(url) + +function tryCleanFsResolve( file: string, - postfix: string, options: InternalResolveOptions, - tryIndex: boolean, - targetWeb: boolean, - tryPrefix?: string, - skipPackageJson?: boolean, - skipTsExtension?: boolean, + tryIndex = true, + targetWeb = true, + skipPackageJson = false, ): string | undefined { - let stat: fs.Stats | undefined - try { - stat = fs.statSync(file, { throwIfNoEntry: false }) - } catch { - return + const { tryPrefix, extensions, preserveSymlinks } = options + + const fileStat = tryStatSync(file) + + // Try direct match first + if (fileStat?.isFile()) return getRealPath(file, options.preserveSymlinks) + + let res: string | undefined + + // If path.dirname is a valid directory, try extensions and ts resolution logic + const possibleJsToTs = options.isFromTsImporter && isPossibleTsOutput(file) + if (possibleJsToTs || extensions.length || tryPrefix) { + const dirPath = path.dirname(file) + const dirStat = tryStatSync(dirPath) + if (dirStat?.isDirectory()) { + if (possibleJsToTs) { + // try resolve .js, .mjs, .cjs or .jsx import to typescript file + const fileExt = path.extname(file) + const fileName = file.slice(0, -fileExt.length) + if ( + (res = tryResolveRealFile( + fileName + fileExt.replace('js', 'ts'), + preserveSymlinks, + )) + ) + return res + // for .js, also try .tsx + if ( + fileExt === '.js' && + (res = tryResolveRealFile(fileName + '.tsx', preserveSymlinks)) + ) + return res + } + + if ( + (res = tryResolveRealFileWithExtensions( + file, + extensions, + preserveSymlinks, + )) + ) + return res + + if (tryPrefix) { + const prefixed = `${dirPath}/${options.tryPrefix}${path.basename(file)}` + + if ((res = tryResolveRealFile(prefixed, preserveSymlinks))) return res + + if ( + (res = tryResolveRealFileWithExtensions( + prefixed, + extensions, + preserveSymlinks, + )) + ) + return res + } + } } - if (stat) { - if (!stat.isDirectory()) { - return getRealPath(file, options.preserveSymlinks) + postfix - } else if (tryIndex) { - if (!skipPackageJson) { - const pkgPath = file + '/package.json' - try { - // path points to a node package - const pkg = loadPackageData(pkgPath, options.preserveSymlinks) - const resolved = resolvePackageEntry(file, pkg, targetWeb, options) - return resolved - } catch (e) { - if (e.code !== 'ENOENT') { - throw e + if (tryIndex && fileStat) { + // Path points to a directory, check for package.json and entry and /index file + const dirPath = file + + if (!skipPackageJson) { + let pkgPath = `${dirPath}/package.json` + try { + if (fs.existsSync(pkgPath)) { + if (!options.preserveSymlinks) { + pkgPath = safeRealpathSync(pkgPath) } + // path points to a node package + const pkg = loadPackageData(pkgPath) + return resolvePackageEntry(dirPath, pkg, targetWeb, options) } + } catch (e) { + if (e.code !== 'ENOENT') throw e } - const index = tryFsResolve(file + '/index', options) - if (index) return index + postfix } - } - // try resolve .js import to typescript file - if ( - !skipTsExtension && - options.isFromTsImporter && - isPossibleTsOutput(file) - ) { - const tsSrcPaths = getPotentialTsSrcPaths(file) - for (const srcPath of tsSrcPaths) { - const res = tryResolveFile( - srcPath, - postfix, - options, - tryIndex, - targetWeb, - tryPrefix, - skipPackageJson, - true, + if ( + (res = tryResolveRealFileWithExtensions( + `${dirPath}/index`, + extensions, + preserveSymlinks, + )) + ) + return res + + if (tryPrefix) { + if ( + (res = tryResolveRealFileWithExtensions( + `${dirPath}/${options.tryPrefix}index`, + extensions, + preserveSymlinks, + )) ) - if (res) return res + return res } - return } +} + +function tryResolveRealFile( + file: string, + preserveSymlinks: boolean, +): string | undefined { + const stat = tryStatSync(file) + if (stat?.isFile()) return getRealPath(file, preserveSymlinks) +} - if (tryPrefix) { - const prefixed = `${path.dirname(file)}/${tryPrefix}${path.basename(file)}` - return tryResolveFile(prefixed, postfix, options, tryIndex, targetWeb) +function tryResolveRealFileWithExtensions( + filePath: string, + extensions: string[], + preserveSymlinks: boolean, +): string | undefined { + for (const ext of extensions) { + const res = tryResolveRealFile(filePath + ext, preserveSymlinks) + if (res) return res } } @@ -649,8 +649,6 @@ export type InternalResolveOptionsWithOverrideConditions = overrideConditions?: string[] } -export const idToPkgMap = new Map() - export function tryNodeResolve( id: string, importer: string | null | undefined, @@ -663,32 +661,12 @@ export function tryNodeResolve( ): PartialResolvedId | undefined { const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options - const possiblePkgIds: string[] = [] - for (let prevSlashIndex = -1; ; ) { - let slashIndex = id.indexOf('/', prevSlashIndex + 1) - if (slashIndex < 0) { - slashIndex = id.length - } - - const part = id.slice(prevSlashIndex + 1, (prevSlashIndex = slashIndex)) - if (!part) { - break - } - - // Assume path parts with an extension are not package roots, except for the - // first path part (since periods are sadly allowed in package names). - // At the same time, skip the first path part if it begins with "@" - // (since "@foo/bar" should be treated as the top-level path). - if (possiblePkgIds.length ? path.extname(part) : part[0] === '@') { - continue - } - - const possiblePkgId = id.slice(0, slashIndex) - possiblePkgIds.push(possiblePkgId) - } + // check for deep import, e.g. "my-lib/foo" + const deepMatch = id.match(deepImportRE) + const pkgId = deepMatch ? deepMatch[1] || deepMatch[2] : id let basedir: string - if (dedupe?.some((id) => possiblePkgIds.includes(id))) { + if (dedupe?.includes(pkgId)) { basedir = root } else if ( importer && @@ -700,39 +678,8 @@ export function tryNodeResolve( basedir = root } - let pkg: PackageData | undefined - let pkgId: string | undefined - // nearest package.json - let nearestPkg: PackageData | undefined - - const rootPkgId = possiblePkgIds[0] - - const rootPkg = resolvePackageData( - rootPkgId, - basedir, - preserveSymlinks, - packageCache, - )! - - const nearestPkgId = [...possiblePkgIds].reverse().find((pkgId) => { - nearestPkg = resolvePackageData( - pkgId, - basedir, - preserveSymlinks, - packageCache, - )! - return nearestPkg - })! - - if (rootPkg?.data?.exports) { - pkgId = rootPkgId - pkg = rootPkg - } else { - pkgId = nearestPkgId - pkg = nearestPkg - } - - if (!pkg || !nearestPkg) { + const pkg = resolvePackageData(pkgId, basedir, preserveSymlinks, packageCache) + if (!pkg) { // if import can't be found, check if it's an optional peer dep. // if so, we can resolve to a special id that errors only when imported. if ( @@ -741,12 +688,8 @@ export function tryNodeResolve( !id.includes('\0') && bareImportRE.test(id) ) { - // find package.json with `name` as main - const mainPackageJson = lookupFile(basedir, ['package.json'], { - predicate: (content) => !!JSON.parse(content).name, - }) - if (mainPackageJson) { - const mainPkg = JSON.parse(mainPackageJson) + const mainPkg = findNearestMainPackageData(basedir, packageCache)?.data + if (mainPkg) { if ( mainPkg.peerDependencies?.[id] && mainPkg.peerDependenciesMeta?.[id]?.optional @@ -760,13 +703,8 @@ export function tryNodeResolve( return } - let resolveId = resolvePackageEntry - let unresolvedId = pkgId - const isDeepImport = unresolvedId !== id - if (isDeepImport) { - resolveId = resolveDeepImport - unresolvedId = '.' + id.slice(pkgId.length) - } + const resolveId = deepMatch ? resolveDeepImport : resolvePackageEntry + const unresolvedId = deepMatch ? '.' + id.slice(pkgId.length) : pkgId let resolved: string | undefined try { @@ -793,7 +731,7 @@ export function tryNodeResolve( return resolved } // don't external symlink packages - if (!allowLinkedExternal && !resolved.id.includes('node_modules')) { + if (!allowLinkedExternal && !isInNodeModules(resolved.id)) { return resolved } const resolvedExt = path.extname(resolved.id) @@ -807,20 +745,14 @@ export function tryNodeResolve( return resolved } let resolvedId = id - if (isDeepImport) { - if (!pkg?.data.exports && path.extname(id) !== resolvedExt) { - resolvedId = resolved.id.slice(resolved.id.indexOf(id)) - isDebug && - debug( - `[processResult] ${colors.cyan(id)} -> ${colors.dim(resolvedId)}`, - ) - } + if (deepMatch && !pkg?.data.exports && path.extname(id) !== resolvedExt) { + resolvedId = resolved.id.slice(resolved.id.indexOf(id)) + isDebug && + debug(`[processResult] ${colors.cyan(id)} -> ${colors.dim(resolvedId)}`) } return { ...resolved, id: resolvedId, external: true } } - // link id to pkg for browser field mapping check - idToPkgMap.set(resolved, pkg) if ((isBuild && !depsOptimizer) || externalize) { // Resolve package side effects for build so that rollup can better // perform tree-shaking @@ -831,12 +763,10 @@ export function tryNodeResolve( } const ext = path.extname(resolved) - const isCJS = - ext === '.cjs' || (ext === '.js' && nearestPkg.data.type !== 'module') if ( !options.ssrOptimizeCheck && - (!resolved.includes('node_modules') || // linked + (!isInNodeModules(resolved) || // linked !depsOptimizer || // resolving before listening to the server options.scan) // initial esbuild scan phase ) { @@ -858,7 +788,7 @@ export function tryNodeResolve( const skipOptimization = !isJsType || - importer?.includes('node_modules') || + (importer && isInNodeModules(importer)) || exclude?.includes(pkgId) || exclude?.includes(id) || SPECIAL_QUERY_RE.test(resolved) || @@ -867,7 +797,14 @@ export function tryNodeResolve( // The only optimized deps are the ones explicitly listed in the config. (!options.ssrOptimizeCheck && !isBuild && ssr) || // Only optimize non-external CJS deps during SSR by default - (ssr && !isCJS && !(include?.includes(pkgId) || include?.includes(id))) + (ssr && + !( + ext === '.cjs' || + (ext === '.js' && + findNearestPackageData(path.dirname(resolved), options.packageCache) + ?.data.type !== 'module') + ) && + !(include?.includes(pkgId) || include?.includes(id))) if (options.ssrOptimizeCheck) { return { @@ -1056,22 +993,29 @@ export function resolvePackageEntry( for (let entry of entryPoints) { // make sure we don't get scripts when looking for sass + let skipPackageJson = false if ( options.mainFields[0] === 'sass' && !options.extensions.includes(path.extname(entry)) ) { entry = '' - options.skipPackageJson = true - } - - // resolve object browser field in package.json - const { browser: browserField } = data - if (targetWeb && options.browserField && isObject(browserField)) { - entry = mapWithBrowserField(entry, browserField) || entry + skipPackageJson = true + } else { + // resolve object browser field in package.json + const { browser: browserField } = data + if (targetWeb && options.browserField && isObject(browserField)) { + entry = mapWithBrowserField(entry, browserField) || entry + } } const entryPointPath = path.join(dir, entry) - const resolvedEntryPoint = tryFsResolve(entryPointPath, options) + const resolvedEntryPoint = tryFsResolve( + entryPointPath, + options, + true, + true, + skipPackageJson, + ) if (resolvedEntryPoint) { isDebug && debug( @@ -1234,7 +1178,8 @@ function tryResolveBrowserMapping( ) { let res: string | undefined const pkg = - importer && (idToPkgMap.get(importer) || resolvePkg(importer, options)) + importer && + findNearestPackageData(path.dirname(importer), options.packageCache) if (pkg && isObject(pkg.data.browser)) { const mapId = isFilePath ? './' + slash(path.relative(pkg.dir, id)) : id const browserMappedPath = mapWithBrowserField(mapId, pkg.data.browser) @@ -1246,7 +1191,6 @@ function tryResolveBrowserMapping( ) { isDebug && debug(`[browser mapped] ${colors.cyan(id)} -> ${colors.dim(res)}`) - idToPkgMap.set(res, pkg) const result = { id: res, moduleSideEffects: pkg.hasSideEffects(res), @@ -1292,44 +1236,7 @@ function equalWithoutSuffix(path: string, key: string, suffix: string) { function getRealPath(resolved: string, preserveSymlinks?: boolean): string { resolved = ensureVolumeInPath(resolved) if (!preserveSymlinks && browserExternalId !== resolved) { - resolved = fs.realpathSync(resolved) + resolved = safeRealpathSync(resolved) } return normalizePath(resolved) } - -/** - * if importer was not resolved by vite's resolver previously - * (when esbuild resolved it) - * resolve importer's pkg and add to idToPkgMap - */ -function resolvePkg(importer: string, options: InternalResolveOptions) { - const { root, preserveSymlinks, packageCache } = options - - if (importer.includes('\x00')) { - return null - } - - const possiblePkgIds: string[] = [] - for (let prevSlashIndex = -1; ; ) { - const slashIndex = importer.indexOf(isWindows ? '\\' : '/', prevSlashIndex) - if (slashIndex < 0) { - break - } - - prevSlashIndex = slashIndex + 1 - - const possiblePkgId = importer.slice(0, slashIndex) - possiblePkgIds.push(possiblePkgId) - } - - let pkg: PackageData | undefined - possiblePkgIds.reverse().find((pkgId) => { - pkg = resolvePackageData(pkgId, root, preserveSymlinks, packageCache)! - return pkg - })! - - if (pkg) { - idToPkgMap.set(importer, pkg) - } - return pkg -} diff --git a/packages/vite/src/node/plugins/splitVendorChunk.ts b/packages/vite/src/node/plugins/splitVendorChunk.ts index 7202490343754a..efe0a18a2c9440 100644 --- a/packages/vite/src/node/plugins/splitVendorChunk.ts +++ b/packages/vite/src/node/plugins/splitVendorChunk.ts @@ -4,6 +4,7 @@ import type { ManualChunkMeta, OutputOptions, } from 'rollup' +import { isInNodeModules } from '../utils' import type { UserConfig } from '../../node' import type { Plugin } from '../plugin' @@ -41,7 +42,7 @@ export function splitVendorChunk( const cache = options.cache ?? new SplitVendorChunkCache() return (id, { getModuleInfo }) => { if ( - id.includes('node_modules') && + isInNodeModules(id) && !isCSSRequest(id) && staticImportedByEntry(id, getModuleInfo, cache.cache) ) { diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index 197b3feeabe0bc..7fd7e328d6c301 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -32,14 +32,6 @@ export type WorkerType = 'classic' | 'module' | 'ignore' export const WORKER_FILE_ID = 'worker_file' const workerCache = new WeakMap() -export function isWorkerRequest(id: string): boolean { - const query = parseRequest(id) - if (query && query[WORKER_FILE_ID] != null) { - return true - } - return false -} - function saveEmitWorkerAsset( config: ResolvedConfig, asset: EmittedAsset, diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts index 37ccc8a015283b..2bda9ab737e273 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -126,7 +126,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { const rawUrl = code.slice(urlStart, urlEnd) // potential dynamic template string - if (rawUrl[0] === '`' && /\$\{/.test(rawUrl)) { + if (rawUrl[0] === '`' && rawUrl.includes('${')) { this.error( `\`new URL(url, import.meta.url)\` is not supported in dynamic template string.`, urlIndex, @@ -141,7 +141,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { ) const url = rawUrl.slice(1, -1) let file: string | undefined - if (url.startsWith('.')) { + if (url[0] === '.') { file = path.resolve(path.dirname(id), url) } else { workerResolver ??= config.createResolver({ @@ -150,9 +150,10 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { preferRelative: true, }) file = await workerResolver(url, id) - file ??= url.startsWith('/') - ? slash(path.join(config.publicDir, url)) - : slash(path.resolve(path.dirname(id), url)) + file ??= + url[0] === '/' + ? slash(path.join(config.publicDir, url)) + : slash(path.resolve(path.dirname(id), url)) } let builtUrl: string diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index a9fe3d1894aed8..db827a65f5fe51 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -45,11 +45,21 @@ export function resolvePreviewOptions( } } -export interface PreviewServer { +// TODO: merge with PreviewServer in Vite 5 +export interface PreviewServerForHook { /** * The resolved vite config object */ config: ResolvedConfig + /** + * A connect app instance. + * - Can be used to attach custom middlewares to the preview server. + * - Can also be used as the handler function of a custom http server + * or as a middleware in any connect-style Node.js frameworks + * + * https://github.com/senchalabs/connect#use-middleware + */ + middlewares: Connect.Server /** * native Node http server instance */ @@ -57,19 +67,20 @@ export interface PreviewServer { /** * The resolved urls Vite prints on the CLI */ - resolvedUrls: ResolvedServerUrls + resolvedUrls: ResolvedServerUrls | null /** * Print server urls */ printUrls(): void } +export interface PreviewServer extends PreviewServerForHook { + resolvedUrls: ResolvedServerUrls +} + export type PreviewServerHook = ( this: void, - server: { - middlewares: Connect.Server - httpServer: http.Server - }, + server: PreviewServerForHook, ) => (() => void) | void | Promise<(() => void) | void> /** @@ -108,10 +119,27 @@ export async function preview( ) setClientErrorHandler(httpServer, config.logger) + const options = config.preview + const logger = config.logger + + const server: PreviewServerForHook = { + config, + middlewares: app, + httpServer, + resolvedUrls: null, + printUrls() { + if (server.resolvedUrls) { + printServerUrls(server.resolvedUrls, options.host, logger.info) + } else { + throw new Error('cannot print server URLs before server is listening.') + } + }, + } + // apply server hooks from plugins const postHooks: ((() => void) | void)[] = [] for (const hook of config.getSortedPluginHooks('configurePreviewServer')) { - postHooks.push(await hook({ middlewares: app, httpServer })) + postHooks.push(await hook(server)) } // cors @@ -153,11 +181,9 @@ export async function preview( // apply post server hooks from plugins postHooks.forEach((fn) => fn && fn()) - const options = config.preview const hostname = await resolveHostname(options.host) const port = options.port ?? DEFAULT_PREVIEW_PORT const protocol = options.https ? 'https' : 'http' - const logger = config.logger const serverPort = await httpServerStart(httpServer, { port, @@ -166,7 +192,7 @@ export async function preview( logger, }) - const resolvedUrls = await resolveServerUrls( + server.resolvedUrls = await resolveServerUrls( httpServer, config.preview, config, @@ -183,12 +209,5 @@ export async function preview( ) } - return { - config, - httpServer, - resolvedUrls, - printUrls() { - printServerUrls(resolvedUrls, options.host, logger.info) - }, - } + return server as PreviewServer } diff --git a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts index 089a45497a593e..a20fc919f7fa10 100644 --- a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts +++ b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts @@ -196,7 +196,7 @@ async function getPluginContainer( ) // @ts-expect-error This plugin requires a ViteDevServer instance. - config.plugins = config.plugins.filter((p) => !/pre-alias/.test(p.name)) + config.plugins = config.plugins.filter((p) => !p.name.includes('pre-alias')) resolveId = (id) => container.resolveId(id) const container = await createPluginContainer(config, moduleGraph) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index c0accc63e5bc71..9e693566366c5d 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -1,4 +1,4 @@ -import fs from 'node:fs' +import fsp from 'node:fs/promises' import path from 'node:path' import type { Server } from 'node:http' import colors from 'picocolors' @@ -14,6 +14,8 @@ import type { ModuleNode } from './moduleGraph' export const debugHmr = createDebugger('vite:hmr') +const whitespaceRE = /\s/ + const normalizedClientDir = normalizePath(CLIENT_DIR) export interface HmrOptions { @@ -388,7 +390,7 @@ export function lexAcceptedHmrDeps( } else if (char === '`') { prevState = state state = LexerState.inTemplateString - } else if (/\s/.test(char)) { + } else if (whitespaceRE.test(char)) { continue } else { if (state === LexerState.inCall) { @@ -473,7 +475,7 @@ export function lexAcceptedHmrExports( } export function normalizeHmrUrl(url: string): string { - if (!url.startsWith('.') && !url.startsWith('/')) { + if (url[0] !== '.' && url[0] !== '/') { url = wrapId(url) } return url @@ -492,14 +494,14 @@ function error(pos: number) { // change event and sometimes this can be too early and get an empty buffer. // Poll until the file's modified time has changed before reading again. async function readModifiedFile(file: string): Promise { - const content = fs.readFileSync(file, 'utf-8') + const content = await fsp.readFile(file, 'utf-8') if (!content) { - const mtime = fs.statSync(file).mtimeMs + const mtime = (await fsp.stat(file)).mtimeMs await new Promise((r) => { let n = 0 const poll = async () => { n++ - const newMtime = fs.statSync(file).mtimeMs + const newMtime = (await fsp.stat(file)).mtimeMs if (newMtime !== mtime || n > 10) { r(0) } else { @@ -508,7 +510,7 @@ async function readModifiedFile(file: string): Promise { } setTimeout(poll, 10) }) - return fs.readFileSync(file, 'utf-8') + return await fsp.readFile(file, 'utf-8') } else { return content } diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 4644c06f2d379d..acef17fdc7b29d 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -24,6 +24,7 @@ import type { InlineConfig, ResolvedConfig } from '../config' import { isDepsOptimizerEnabled, resolveConfig } from '../config' import { diffDnsOrderChange, + isInNodeModules, isParentDirectory, mergeConfig, normalizePath, @@ -35,7 +36,6 @@ import { cjsSsrResolveExternals } from '../ssr/ssrExternal' import { ssrFixStacktrace, ssrRewriteStacktrace } from '../ssr/ssrStacktrace' import { ssrTransform } from '../ssr/ssrTransform' import { - cleanupDepsCacheStaleDirs, getDepsOptimizer, initDepsOptimizer, initDevSsrDepsOptimizer, @@ -340,6 +340,13 @@ export async function createServer( inlineConfig: InlineConfig = {}, ): Promise { const config = await resolveConfig(inlineConfig, 'serve') + + // start optimizer in the background + let depsOptimizerReady: Promise | undefined + if (isDepsOptimizerEnabled(config, false)) { + depsOptimizerReady = initDepsOptimizer(config) + } + const { root, server: serverConfig } = config const httpsOptions = await resolveHttpsConfig(config.server.https) const { middlewareMode } = serverConfig @@ -361,7 +368,7 @@ export async function createServer( const watcher = chokidar.watch( // config file dependencies and env file might be outside of root - [root, ...config.configFileDependencies, config.envDir], + [root, ...config.configFileDependencies, path.join(config.envDir, '.env*')], resolvedWatchOptions, ) as FSWatcher @@ -656,25 +663,15 @@ export async function createServer( // error handler middlewares.use(errorMiddleware(server, middlewareMode)) - let initingServer: Promise | undefined - let serverInited = false - const initServer = async () => { - if (serverInited) { - return - } - if (initingServer) { - return initingServer - } - initingServer = (async function () { - await container.buildStart({}) - if (isDepsOptimizerEnabled(config, false)) { - // non-ssr - await initDepsOptimizer(config, server) + // when the optimizer is ready, hook server so that it can reload the page + // or invalidate the module graph when needed + if (depsOptimizerReady) { + depsOptimizerReady.then(() => { + const depsOptimizer = getDepsOptimizer(config) + if (depsOptimizer) { + depsOptimizer.server = server } - initingServer = undefined - serverInited = true - })() - return initingServer + }) } if (!middlewareMode && httpServer) { @@ -682,7 +679,7 @@ export async function createServer( const listen = httpServer.listen.bind(httpServer) httpServer.listen = (async (port: number, ...args: any[]) => { try { - await initServer() + await container.buildStart({}) } catch (e) { httpServer.emit('error', e) return @@ -690,13 +687,9 @@ export async function createServer( return listen(port, ...args) }) as any } else { - await initServer() + await container.buildStart({}) } - // Fire a clean up of stale cache dirs, in case old processes didn't - // terminate correctly. Don't await this promise - cleanupDepsCacheStaleDirs(config) - return server } @@ -772,8 +765,7 @@ export function resolveServerOptions( sourcemapIgnoreList: raw?.sourcemapIgnoreList === false ? () => false - : raw?.sourcemapIgnoreList || - ((sourcePath) => sourcePath.includes('node_modules')), + : raw?.sourcemapIgnoreList || isInNodeModules, middlewareMode: !!raw?.middlewareMode, } let allowDirs = server.fs?.allow diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index 6623b590e15ce8..a673574fd85ed2 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -1,4 +1,5 @@ import fs from 'node:fs' +import fsp from 'node:fs/promises' import path from 'node:path' import MagicString from 'magic-string' import type { SourceMapInput } from 'rollup' @@ -102,7 +103,7 @@ const processNodeUrl = ( const fullUrl = path.posix.join(devBase, url) overwriteAttrValue(s, sourceCodeLocation, fullUrl) } else if ( - url.startsWith('.') && + url[0] === '.' && originalUrl && originalUrl !== '/' && htmlPath === '/index.html' @@ -166,7 +167,7 @@ const devHtmlHook: IndexHtmlTransformHook = async ( const code = contentNode.value let map: SourceMapInput | undefined - if (!proxyModulePath.startsWith('\0')) { + if (proxyModulePath[0] !== '\0') { map = new MagicString(html) .snip( contentNode.sourceCodeLocation!.startOffset, @@ -292,7 +293,7 @@ export function indexHtmlMiddleware( const filename = getHtmlFilename(url, server) if (fs.existsSync(filename)) { try { - let html = fs.readFileSync(filename, 'utf-8') + let html = await fsp.readFile(filename, 'utf-8') html = await server.transformIndexHtml(url, html, req.originalUrl) return send(req, res, html, 'html', { headers: server.config.server.headers, diff --git a/packages/vite/src/node/server/middlewares/proxy.ts b/packages/vite/src/node/server/middlewares/proxy.ts index c668d66b83edfa..2212c7e2d7f248 100644 --- a/packages/vite/src/node/server/middlewares/proxy.ts +++ b/packages/vite/src/node/server/middlewares/proxy.ts @@ -141,7 +141,7 @@ export function proxyMiddleware( function doesProxyContextMatchUrl(context: string, url: string): boolean { return ( - (context.startsWith('^') && new RegExp(context).test(url)) || + (context[0] === '^' && new RegExp(context).test(url)) || url.startsWith(context) ) } diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 229b860dbcec56..f59961085e923f 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -14,10 +14,13 @@ import { isInternalRequest, isParentDirectory, isWindows, + removeLeadingSlash, shouldServeFile, slash, } from '../../utils' +const knownJavascriptExtensionRE = /\.[tj]sx?$/ + const sirvOptions = ({ headers, shouldServe, @@ -35,7 +38,7 @@ const sirvOptions = ({ // for the MIME type video/mp2t. In almost all cases, we can expect // these files to be TypeScript files, and for Vite to serve them with // this Content-Type. - if (/\.[tj]sx?$/.test(pathname)) { + if (knownJavascriptExtensionRE.test(pathname)) { res.setHeader('Content-Type', 'application/javascript') } if (headers) { @@ -89,7 +92,7 @@ export function serveStaticMiddleware( // also skip internal requests `/@fs/ /@vite-client` etc... const cleanedUrl = cleanUrl(req.url!) if ( - cleanedUrl.endsWith('/') || + cleanedUrl[cleanedUrl.length - 1] === '/' || path.extname(cleanedUrl) === '.html' || isInternalRequest(req.url!) ) { @@ -119,8 +122,11 @@ export function serveStaticMiddleware( } const resolvedPathname = redirectedPathname || pathname - let fileUrl = path.resolve(dir, resolvedPathname.replace(/^\//, '')) - if (resolvedPathname.endsWith('/') && !fileUrl.endsWith('/')) { + let fileUrl = path.resolve(dir, removeLeadingSlash(resolvedPathname)) + if ( + resolvedPathname[resolvedPathname.length - 1] === '/' && + fileUrl[fileUrl.length - 1] !== '/' + ) { fileUrl = fileUrl + '/' } if (!ensureServingAccess(fileUrl, server, res, next)) { diff --git a/packages/vite/src/node/server/openBrowser.ts b/packages/vite/src/node/server/openBrowser.ts index 31d27dc4172180..666a86dd4d4ef4 100644 --- a/packages/vite/src/node/server/openBrowser.ts +++ b/packages/vite/src/node/server/openBrowser.ts @@ -9,7 +9,8 @@ */ import { join } from 'node:path' -import { execSync } from 'node:child_process' +import { exec } from 'node:child_process' +import type { ExecOptions } from 'node:child_process' import open from 'open' import spawn from 'cross-spawn' import colors from 'picocolors' @@ -18,25 +19,23 @@ import { VITE_PACKAGE_DIR } from '../constants' /** * Reads the BROWSER environment variable and decides what to do with it. - * Returns true if it opened a browser or ran a node.js script, otherwise false. */ export function openBrowser( url: string, opt: string | true, logger: Logger, -): boolean { +): void { // The browser executable to open. // See https://github.com/sindresorhus/open#app for documentation. const browser = typeof opt === 'string' ? opt : process.env.BROWSER || '' if (browser.toLowerCase().endsWith('.js')) { - return executeNodeScript(browser, url, logger) + executeNodeScript(browser, url, logger) } else if (browser.toLowerCase() !== 'none') { const browserArgs = process.env.BROWSER_ARGS ? process.env.BROWSER_ARGS.split(' ') : [] - return startBrowserProcess(browser, browserArgs, url) + startBrowserProcess(browser, browserArgs, url) } - return false } function executeNodeScript(scriptPath: string, url: string, logger: Logger) { @@ -56,7 +55,6 @@ function executeNodeScript(scriptPath: string, url: string, logger: Logger) { ) } }) - return true } const supportedChromiumBrowsers = [ @@ -70,7 +68,7 @@ const supportedChromiumBrowsers = [ 'Chromium', ] -function startBrowserProcess( +async function startBrowserProcess( browser: string | undefined, browserArgs: string[], url: string, @@ -88,20 +86,19 @@ function startBrowserProcess( if (shouldTryOpenChromeWithAppleScript) { try { - const ps = execSync('ps cax').toString() + const ps = await execAsync('ps cax') const openedBrowser = preferredOSXBrowser && ps.includes(preferredOSXBrowser) ? preferredOSXBrowser : supportedChromiumBrowsers.find((b) => ps.includes(b)) if (openedBrowser) { // Try our best to reuse existing tab with AppleScript - execSync( + await execAsync( `osascript openChrome.applescript "${encodeURI( url, )}" "${openedBrowser}"`, { cwd: join(VITE_PACKAGE_DIR, 'bin'), - stdio: 'ignore', }, ) return true @@ -131,3 +128,15 @@ function startBrowserProcess( return false } } + +function execAsync(command: string, options?: ExecOptions): Promise { + return new Promise((resolve, reject) => { + exec(command, options, (error, stdout) => { + if (error) { + reject(error) + } else { + resolve(stdout.toString()) + } + }) + }) +} diff --git a/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts index ad06cafc117839..da7b79edfb4047 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts @@ -11,6 +11,9 @@ async function createDevServer() { configFile: false, root, logLevel: 'silent', + optimizeDeps: { + disabled: true, + }, }) server.pluginContainer.buildStart({}) return server diff --git a/packages/vite/src/node/ssr/__tests__/ssrStacktrace.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrStacktrace.spec.ts index eb49dbe47311a8..384fbd6a428992 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrStacktrace.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrStacktrace.spec.ts @@ -9,6 +9,9 @@ async function createDevServer() { configFile: false, root, logLevel: 'silent', + optimizeDeps: { + disabled: true, + }, }) server.pluginContainer.buildStart({}) return server diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index 91554dfd34299f..b71b6262e1f009 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -105,7 +105,9 @@ test('export * from', async () => { "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); __vite_ssr_exportAll__(__vite_ssr_import_0__); const __vite_ssr_import_1__ = await __vite_ssr_import__(\\"react\\"); - __vite_ssr_exportAll__(__vite_ssr_import_1__);" + __vite_ssr_exportAll__(__vite_ssr_import_1__); + + " `) }) @@ -130,12 +132,24 @@ test('export then import minified', async () => { `export * from 'vue';import {createApp} from 'vue';`, ), ).toMatchInlineSnapshot(` - "const __vite_ssr_import_1__ = await __vite_ssr_import__(\\"vue\\"); - __vite_ssr_exportAll__(__vite_ssr_import_1__);const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + const __vite_ssr_import_1__ = await __vite_ssr_import__(\\"vue\\"); + __vite_ssr_exportAll__(__vite_ssr_import_1__); " `) }) +test('hoist import to top', async () => { + expect( + await ssrTransformSimpleCode( + `path.resolve('server.js');import path from 'node:path';`, + ), + ).toMatchInlineSnapshot(` + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"node:path\\"); + __vite_ssr_import_0__.default.resolve('server.js');" + `) +}) + test('import.meta', async () => { expect( await ssrTransformSimpleCode(`console.log(import.meta.url)`), @@ -369,8 +383,8 @@ function c({ _ = bar() + foo() }) {} `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + const a = ({ _ = __vite_ssr_import_0__.foo() }) => {} function b({ _ = __vite_ssr_import_0__.bar() }) {} @@ -391,8 +405,8 @@ const a = () => { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + const a = () => { const { type: n = 'bar' } = {} @@ -414,8 +428,8 @@ const foo = {} `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + const foo = {} @@ -457,8 +471,8 @@ objRest() `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + function a() { @@ -507,8 +521,8 @@ const obj = { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + const bar = 'bar' @@ -539,8 +553,8 @@ class A { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + const add = __vite_ssr_import_0__.add; @@ -571,8 +585,8 @@ class A { `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); + const bar = 'bar' @@ -617,8 +631,8 @@ bbb() `, ), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); + function foobar() { @@ -662,15 +676,15 @@ test('jsx', async () => { const result = await transformWithEsbuild(code, id) expect(await ssrTransformSimpleCode(result.code, '/foo.jsx')) .toMatchInlineSnapshot(` - "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"react\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"react\\"); + const __vite_ssr_import_1__ = await __vite_ssr_import__(\\"foo\\"); - const __vite_ssr_import_1__ = await __vite_ssr_import__(\\"foo\\"); - function Bar({ Slot: Slot2 = /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_1__.Foo, null) }) { - return /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_0__.default.Fragment, null, /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(Slot2, null)); - } - " - `) + function Bar({ Slot: Slot2 = /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_1__.Foo, null) }) { + return /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(__vite_ssr_import_0__.default.Fragment, null, /* @__PURE__ */ __vite_ssr_import_0__.default.createElement(Slot2, null)); + } + " + `) }) test('continuous exports', async () => { @@ -801,8 +815,8 @@ function test() { return [foo, bar] }`), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foobar\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foobar\\"); + function test() { if (true) { @@ -828,8 +842,8 @@ function test() { return bar; }`), ).toMatchInlineSnapshot(` - " - const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foobar\\"); + "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foobar\\"); + function test() { [__vite_ssr_import_0__.foo]; diff --git a/packages/vite/src/node/ssr/ssrExternal.ts b/packages/vite/src/node/ssr/ssrExternal.ts index ce08b020d17fbf..af3349235f9d4d 100644 --- a/packages/vite/src/node/ssr/ssrExternal.ts +++ b/packages/vite/src/node/ssr/ssrExternal.ts @@ -9,11 +9,12 @@ import { createFilter, isBuiltin, isDefined, + isInNodeModules, lookupFile, normalizePath, - resolveFrom, } from '../utils' import type { Logger, ResolvedConfig } from '..' +import { resolvePackageData } from '../packages' const debug = createDebugger('vite:ssr-external') @@ -199,7 +200,7 @@ function createIsSsrExternal( return processedIds.get(id) } let external = false - if (!id.startsWith('.') && !path.isAbsolute(id)) { + if (id[0] !== '.' && !path.isAbsolute(id)) { external = isBuiltin(id) || isConfiguredAsExternal(id) } processedIds.set(id, external) @@ -216,7 +217,11 @@ function cjsSsrCollectExternals( seen: Set, logger: Logger, ) { - const rootPkgContent = lookupFile(root, ['package.json']) + const rootPkgPath = lookupFile(root, ['package.json']) + if (!rootPkgPath) { + return + } + const rootPkgContent = fs.readFileSync(rootPkgPath, 'utf-8') if (!rootPkgContent) { return } @@ -256,16 +261,16 @@ function cjsSsrCollectExternals( // which returns with '/', require.resolve returns with '\\' requireEntry = normalizePath(_require.resolve(id, { paths: [root] })) } catch (e) { - try { - // no main entry, but deep imports may be allowed - const pkgPath = resolveFrom(`${id}/package.json`, root) - if (pkgPath.includes('node_modules')) { + // no main entry, but deep imports may be allowed + const pkgDir = resolvePackageData(id, root)?.dir + if (pkgDir) { + if (isInNodeModules(pkgDir)) { ssrExternals.add(id) } else { - depsToTrace.add(path.dirname(pkgPath)) + depsToTrace.add(path.dirname(pkgDir)) } continue - } catch {} + } // resolve failed, assume include debug(`Failed to resolve entries for package "${id}"\n`, e) @@ -276,9 +281,11 @@ function cjsSsrCollectExternals( ssrExternals.add(id) } // trace the dependencies of linked packages - else if (!esmEntry.includes('node_modules')) { - const pkgPath = resolveFrom(`${id}/package.json`, root) - depsToTrace.add(path.dirname(pkgPath)) + else if (!isInNodeModules(esmEntry)) { + const pkgDir = resolvePackageData(id, root)?.dir + if (pkgDir) { + depsToTrace.add(pkgDir) + } } // has separate esm/require entry, assume require entry is cjs else if (esmEntry !== requireEntry) { @@ -288,13 +295,10 @@ function cjsSsrCollectExternals( // or are there others like SystemJS / AMD that we'd need to handle? // for now, we'll just leave this as is else if (/\.m?js$/.test(esmEntry)) { - const pkgPath = resolveFrom(`${id}/package.json`, root) - const pkgContent = fs.readFileSync(pkgPath, 'utf-8') - - if (!pkgContent) { + const pkg = resolvePackageData(id, root)?.data + if (!pkg) { continue } - const pkg = JSON.parse(pkgContent) if (pkg.type === 'module' || esmEntry.endsWith('.mjs')) { ssrExternals.add(id) @@ -340,7 +344,7 @@ export function cjsShouldExternalizeForSSR( function getNpmPackageName(importPath: string): string | null { const parts = importPath.split('/') - if (parts[0].startsWith('@')) { + if (parts[0][0] === '@') { if (!parts[1]) return null return `${parts[0]}/${parts[1]}` } else { diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index 996d4411153dc8..b7d050f6479dd4 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -94,11 +94,13 @@ async function ssrTransformScript( const idToImportMap = new Map() const declaredConst = new Set() - function defineImport(node: Node, source: string) { + function defineImport(source: string) { deps.add(source) const importId = `__vite_ssr_import_${uid++}__` - s.appendRight( - node.start, + // There will be an error if the module is called before it is imported, + // so the module import statement is hoisted to the top + s.appendLeft( + 0, `const ${importId} = await ${ssrImportKey}(${JSON.stringify(source)});\n`, ) return importId @@ -118,8 +120,8 @@ async function ssrTransformScript( // import { baz } from 'foo' --> baz -> __import_foo__.baz // import * as ok from 'foo' --> ok -> __import_foo__ if (node.type === 'ImportDeclaration') { + const importId = defineImport(node.source.value as string) s.remove(node.start, node.end) - const importId = defineImport(node, node.source.value as string) for (const spec of node.specifiers) { if (spec.type === 'ImportSpecifier') { idToImportMap.set( @@ -161,10 +163,11 @@ async function ssrTransformScript( s.remove(node.start, node.end) if (node.source) { // export { foo, bar } from './foo' - const importId = defineImport(node, node.source.value as string) + const importId = defineImport(node.source.value as string) + // hoist re-exports near the defined import so they are immediately exported for (const spec of node.specifiers) { defineExport( - node.end, + 0, spec.exported.name, `${importId}.${spec.local.name}`, ) @@ -210,11 +213,12 @@ async function ssrTransformScript( // export * from './foo' if (node.type === 'ExportAllDeclaration') { s.remove(node.start, node.end) - const importId = defineImport(node, node.source.value as string) + const importId = defineImport(node.source.value as string) + // hoist re-exports near the defined import so they are immediately exported if (node.exported) { - defineExport(node.end, node.exported.name, `${importId}`) + defineExport(0, node.exported.name, `${importId}`) } else { - s.appendLeft(node.end, `${ssrExportAllKey}(${importId});`) + s.appendLeft(0, `${ssrExportAllKey}(${importId});\n`) } } } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index c12e429c51529d..a266c8cd661d29 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -1,8 +1,8 @@ import fs from 'node:fs' import os from 'node:os' import path from 'node:path' +import { exec } from 'node:child_process' import { createHash } from 'node:crypto' -import { promisify } from 'node:util' import { URL, URLSearchParams } from 'node:url' import { builtinModules, createRequire } from 'node:module' import { promises as dns } from 'node:dns' @@ -50,8 +50,9 @@ export const createFilter = _createFilter as ( options?: { resolve?: string | false | null }, ) => (id: string | unknown) => boolean +const windowsSlashRE = /\\/g export function slash(p: string): string { - return p.replace(/\\/g, '/') + return p.replace(windowsSlashRE, '/') } /** @@ -74,15 +75,19 @@ export function unwrapId(id: string): string { : id } +const replaceSlashOrColonRE = /[/:]/g +const replaceDotRE = /\./g +const replaceNestedIdRE = /(\s*>\s*)/g +const replaceHashRE = /#/g export const flattenId = (id: string): string => id - .replace(/[/:]/g, '_') - .replace(/\./g, '__') - .replace(/(\s*>\s*)/g, '___') - .replace(/#/g, '____') + .replace(replaceSlashOrColonRE, '_') + .replace(replaceDotRE, '__') + .replace(replaceNestedIdRE, '___') + .replace(replaceHashRE, '____') export const normalizeId = (id: string): string => - id.replace(/(\s*>\s*)/g, ' > ') + id.replace(replaceNestedIdRE, ' > ') //TODO: revisit later to see if the edge case that "compiling using node v12 code to be run in node v16 in the server" is what we intend to support. const builtins = new Set([ @@ -102,8 +107,17 @@ const builtins = new Set([ 'wasi', ]) +const NODE_BUILTIN_NAMESPACE = 'node:' export function isBuiltin(id: string): boolean { - return builtins.has(id.replace(/^node:/, '')) + return builtins.has( + id.startsWith(NODE_BUILTIN_NAMESPACE) + ? id.slice(NODE_BUILTIN_NAMESPACE.length) + : id, + ) +} + +export function isInNodeModules(id: string): boolean { + return id.includes('node_modules') } export function moduleListContains( @@ -127,15 +141,9 @@ export function isOptimizable( export const bareImportRE = /^[\w@](?!.*:\/\/)/ export const deepImportRE = /^([^@][^/]*)\/|^(@[^/]+\/[^/]+)\// -export let isRunningWithYarnPnp: boolean - // TODO: use import() const _require = createRequire(import.meta.url) -try { - isRunningWithYarnPnp = Boolean(_require('pnpapi')) -} catch {} - const ssrExtensions = ['.js', '.cjs', '.json', '.node'] export function resolveFrom( @@ -149,29 +157,10 @@ export function resolveFrom( paths: [], extensions: ssr ? ssrExtensions : DEFAULT_EXTENSIONS, // necessary to work with pnpm - preserveSymlinks: preserveSymlinks || isRunningWithYarnPnp || false, + preserveSymlinks: preserveSymlinks || !!process.versions.pnp || false, }) } -/** - * like `resolveFrom` but supports resolving `>` path in `id`, - * for example: `foo > bar > baz` - */ -export function nestedResolveFrom( - id: string, - basedir: string, - preserveSymlinks = false, - ssr = false, -): string { - const pkgs = id.split('>').map((pkg) => pkg.trim()) - try { - for (const pkg of pkgs) { - basedir = resolveFrom(pkg, basedir, preserveSymlinks, ssr) - } - } catch {} - return basedir -} - // set in bin/vite.js const filter = process.env.VITE_DEBUG_FILTER @@ -217,6 +206,15 @@ function testCaseInsensitiveFS() { return fs.existsSync(CLIENT_ENTRY.replace('client.mjs', 'cLiEnT.mjs')) } +export function isUrl(path: string): boolean { + try { + new URL(path) + return true + } catch { + return false + } +} + export const isCaseInsensitiveFS = testCaseInsensitiveFS() export const isWindows = os.platform() === 'win32' @@ -231,9 +229,7 @@ export function fsPathFromId(id: string): string { const fsPath = normalizePath( id.startsWith(FS_PREFIX) ? id.slice(FS_PREFIX.length) : id, ) - return fsPath.startsWith('/') || fsPath.match(VOLUME_RE) - ? fsPath - : `/${fsPath}` + return fsPath[0] === '/' || fsPath.match(VOLUME_RE) ? fsPath : `/${fsPath}` } export function fsPathFromUrl(url: string): string { @@ -250,7 +246,7 @@ export function fsPathFromUrl(url: string): string { * @returns true if dir is a parent of file */ export function isParentDirectory(dir: string, file: string): boolean { - if (!dir.endsWith('/')) { + if (dir[dir.length - 1] !== '/') { dir = `${dir}/` } return ( @@ -264,10 +260,11 @@ export function ensureVolumeInPath(file: string): string { } export const queryRE = /\?.*$/s -export const hashRE = /#.*$/s -export const cleanUrl = (url: string): string => - url.replace(hashRE, '').replace(queryRE, '') +const postfixRE = /[?#].*$/s +export function cleanUrl(url: string): string { + return url.replace(postfixRE, '') +} export const externalRE = /^(https?:)?\/\// export const isExternalUrl = (url: string): boolean => externalRE.test(url) @@ -284,25 +281,14 @@ export const isJSRequest = (url: string): boolean => { if (knownJsSrcRE.test(url)) { return true } - if (!path.extname(url) && !url.endsWith('/')) { + if (!path.extname(url) && url[url.length - 1] !== '/') { return true } return false } -const knownTsRE = /\.(?:ts|mts|cts|tsx)$/ -const knownTsOutputRE = /\.(?:js|mjs|cjs|jsx)$/ +const knownTsRE = /\.(?:ts|mts|cts|tsx)(?:$|\?)/ export const isTsRequest = (url: string): boolean => knownTsRE.test(url) -export const isPossibleTsOutput = (url: string): boolean => - knownTsOutputRE.test(cleanUrl(url)) -export function getPotentialTsSrcPaths(filePath: string): string[] { - const [name, type, query = ''] = filePath.split(/(\.(?:[cm]?js|jsx))(\?.*)?$/) - const paths = [name + type.replace('js', 'ts') + query] - if (!type.endsWith('x')) { - paths.push(name + type.replace('js', 'tsx') + query) - } - return paths -} const importQueryRE = /(\?|&)import=?(?:&|$)/ const directRequestRE = /(\?|&)direct=?(?:&|$)/ @@ -325,10 +311,14 @@ export function removeDirectQuery(url: string): string { return url.replace(directRequestRE, '$1').replace(trailingSeparatorRE, '') } +const replacePercentageRE = /%/g export function injectQuery(url: string, queryToInject: string): string { // encode percents for consistent behavior with pathToFileURL // see #2614 for details - const resolvedUrl = new URL(url.replace(/%/g, '%25'), 'relative:///') + const resolvedUrl = new URL( + url.replace(replacePercentageRE, '%25'), + 'relative:///', + ) const { search, hash } = resolvedUrl let pathname = cleanUrl(url) pathname = isWindows ? slash(pathname) : pathname @@ -378,17 +368,7 @@ export function prettifyUrl(url: string, root: string): string { url = removeTimestampQuery(url) const isAbsoluteFile = url.startsWith(root) if (isAbsoluteFile || url.startsWith(FS_PREFIX)) { - let file = path.relative(root, isAbsoluteFile ? url : fsPathFromId(url)) - const seg = file.split('/') - const npmIndex = seg.indexOf(`node_modules`) - const isSourceMap = file.endsWith('.map') - if (npmIndex > 0) { - file = seg[npmIndex + 1] - if (file.startsWith('@')) { - file = `${file}/${seg[npmIndex + 2]}` - } - file = `npm: ${colors.dim(file)}${isSourceMap ? ` (source map)` : ``}` - } + const file = path.relative(root, isAbsoluteFile ? url : fsPathFromId(url)) return colors.dim(file) } else { return colors.dim(url) @@ -403,34 +383,27 @@ export function isDefined(value: T | undefined | null): value is T { return value != null } -interface LookupFileOptions { - pathOnly?: boolean - rootDir?: string - predicate?: (file: string) => boolean +export function tryStatSync(file: string): fs.Stats | undefined { + try { + return fs.statSync(file, { throwIfNoEntry: false }) + } catch { + // Ignore errors + } } export function lookupFile( dir: string, - formats: string[], - options?: LookupFileOptions, + fileNames: string[], ): string | undefined { - for (const format of formats) { - const fullPath = path.join(dir, format) - if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) { - const result = options?.pathOnly - ? fullPath - : fs.readFileSync(fullPath, 'utf-8') - if (!options?.predicate || options.predicate(result)) { - return result - } + while (dir) { + for (const fileName of fileNames) { + const fullPath = path.join(dir, fileName) + if (tryStatSync(fullPath)?.isFile()) return fullPath } - } - const parentDir = path.dirname(dir) - if ( - parentDir !== dir && - (!options?.rootDir || parentDir.startsWith(options?.rootDir)) - ) { - return lookupFile(parentDir, formats, options) + const parentDir = path.dirname(dir) + if (parentDir === dir) return + + dir = parentDir } } @@ -526,17 +499,6 @@ export function generateCodeFrame( return res.join('\n') } -export function writeFile( - filename: string, - content: string | Uint8Array, -): void { - const dir = path.dirname(filename) - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }) - } - fs.writeFileSync(filename, content) -} - export function isFileReadable(filename: string): boolean { try { fs.accessSync(filename, fs.constants.R_OK) @@ -605,17 +567,53 @@ export function copyDir(srcDir: string, destDir: string): void { } } -export const removeDir = isWindows - ? promisify(gracefulRemoveDir) - : function removeDirSync(dir: string) { - // when removing `.vite/deps`, if it doesn't exist, nodejs may also remove - // other directories within `.vite/`, including `.vite/deps_temp` (bug). - // workaround by checking for directory existence before removing for now. - if (fs.existsSync(dir)) { - fs.rmSync(dir, { recursive: true, force: true }) - } +// `fs.realpathSync.native` resolves differently in Windows network drive, +// causing file read errors. skip for now. +// https://github.com/nodejs/node/issues/37737 +export let safeRealpathSync = isWindows + ? windowsSafeRealPathSync + : fs.realpathSync.native + +// Based on https://github.com/larrybahr/windows-network-drive +// MIT License, Copyright (c) 2017 Larry Bahr +const windowsNetworkMap = new Map() +function windowsMappedRealpathSync(path: string) { + const realPath = fs.realpathSync.native(path) + if (realPath.startsWith('\\\\')) { + for (const [network, volume] of windowsNetworkMap) { + if (realPath.startsWith(network)) return realPath.replace(network, volume) } -export const renameDir = isWindows ? promisify(gracefulRename) : fs.renameSync + } + return realPath +} +const parseNetUseRE = /^(\w+) +(\w:) +([^ ]+)\s/ +let firstSafeRealPathSyncRun = false + +function windowsSafeRealPathSync(path: string): string { + if (!firstSafeRealPathSyncRun) { + optimizeSafeRealPathSync() + firstSafeRealPathSyncRun = true + } + return fs.realpathSync(path) +} + +function optimizeSafeRealPathSync() { + exec('net use', (error, stdout) => { + if (error) return + const lines = stdout.split('\n') + // OK Y: \\NETWORKA\Foo Microsoft Windows Network + // OK Z: \\NETWORKA\Bar Microsoft Windows Network + for (const line of lines) { + const m = line.match(parseNetUseRE) + if (m) windowsNetworkMap.set(m[3], m[2]) + } + if (windowsNetworkMap.size === 0) { + safeRealpathSync = fs.realpathSync.native + } else { + safeRealpathSync = windowsMappedRealpathSync + } + }) +} export function ensureWatchedFile( watcher: FSWatcher, @@ -687,13 +685,12 @@ export function processSrcSetSync( ) } +const cleanSrcSetRE = + /(?:url|image|gradient|cross-fade)\([^)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'/g function splitSrcSet(srcs: string) { const parts: string[] = [] // There could be a ',' inside of url(data:...), linear-gradient(...) or "data:..." - const cleanedSrcs = srcs.replace( - /(?:url|image|gradient|cross-fade)\([^)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'/g, - blankReplacer, - ) + const cleanedSrcs = srcs.replace(cleanSrcSetRE, blankReplacer) let startIndex = 0 let splitIndex: number do { @@ -706,22 +703,26 @@ function splitSrcSet(srcs: string) { return parts } +const windowsDriveRE = /^[A-Z]:/ +const replaceWindowsDriveRE = /^([A-Z]):\// +const linuxAbsolutePathRE = /^\/[^/]/ function escapeToLinuxLikePath(path: string) { - if (/^[A-Z]:/.test(path)) { - return path.replace(/^([A-Z]):\//, '/windows/$1/') + if (windowsDriveRE.test(path)) { + return path.replace(replaceWindowsDriveRE, '/windows/$1/') } - if (/^\/[^/]/.test(path)) { + if (linuxAbsolutePathRE.test(path)) { return `/linux${path}` } return path } +const revertWindowsDriveRE = /^\/windows\/([A-Z])\// function unescapeToLinuxLikePath(path: string) { if (path.startsWith('/linux/')) { return path.slice('/linux'.length) } if (path.startsWith('/windows/')) { - return path.replace(/^\/windows\/([A-Z])\//, '$1:/') + return path.replace(revertWindowsDriveRE, '$1:/') } return path } @@ -976,75 +977,6 @@ export const requireResolveFromRootWithFallback = ( return _require.resolve(id, { paths }) } -// Based on node-graceful-fs - -// The ISC License -// Copyright (c) 2011-2022 Isaac Z. Schlueter, Ben Noordhuis, and Contributors -// https://github.com/isaacs/node-graceful-fs/blob/main/LICENSE - -// On Windows, A/V software can lock the directory, causing this -// to fail with an EACCES or EPERM if the directory contains newly -// created files. The original tried for up to 60 seconds, we only -// wait for 5 seconds, as a longer time would be seen as an error - -const GRACEFUL_RENAME_TIMEOUT = 5000 -function gracefulRename( - from: string, - to: string, - cb: (error: NodeJS.ErrnoException | null) => void, -) { - const start = Date.now() - let backoff = 0 - fs.rename(from, to, function CB(er) { - if ( - er && - (er.code === 'EACCES' || er.code === 'EPERM') && - Date.now() - start < GRACEFUL_RENAME_TIMEOUT - ) { - setTimeout(function () { - fs.stat(to, function (stater, st) { - if (stater && stater.code === 'ENOENT') fs.rename(from, to, CB) - else CB(er) - }) - }, backoff) - if (backoff < 100) backoff += 10 - return - } - if (cb) cb(er) - }) -} - -const GRACEFUL_REMOVE_DIR_TIMEOUT = 5000 -function gracefulRemoveDir( - dir: string, - cb: (error: NodeJS.ErrnoException | null) => void, -) { - const start = Date.now() - let backoff = 0 - fs.rm(dir, { recursive: true }, function CB(er) { - if (er) { - if ( - (er.code === 'ENOTEMPTY' || - er.code === 'EACCES' || - er.code === 'EPERM') && - Date.now() - start < GRACEFUL_REMOVE_DIR_TIMEOUT - ) { - setTimeout(function () { - fs.rm(dir, { recursive: true }, CB) - }, backoff) - if (backoff < 100) backoff += 10 - return - } - - if (er.code === 'ENOENT') { - er = null - } - } - - if (cb) cb(er) - }) -} - export function emptyCssComments(raw: string): string { return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length)) } @@ -1148,8 +1080,8 @@ function normalizeSingleAlias({ }: Alias): Alias { if ( typeof find === 'string' && - find.endsWith('/') && - replacement.endsWith('/') + find[find.length - 1] === '/' && + replacement[replacement.length - 1] === '/' ) { find = find.slice(0, find.length - 1) replacement = replacement.slice(0, replacement.length - 1) @@ -1206,7 +1138,7 @@ const windowsDrivePathPrefixRE = /^[A-Za-z]:[/\\]/ * this function returns false for them but true for absolute paths (e.g. C:/something) */ export const isNonDriveRelativeAbsolutePath = (p: string): boolean => { - if (!isWindows) return p.startsWith('/') + if (!isWindows) return p[0] === '/' return windowsDrivePathPrefixRE.test(p) } @@ -1241,21 +1173,25 @@ export function joinUrlSegments(a: string, b: string): string { if (!a || !b) { return a || b || '' } - if (a.endsWith('/')) { + if (a[a.length - 1] === '/') { a = a.substring(0, a.length - 1) } - if (!b.startsWith('/')) { + if (b[0] !== '/') { b = '/' + b } return a + b } +export function removeLeadingSlash(str: string): string { + return str[0] === '/' ? str.slice(1) : str +} + export function stripBase(path: string, base: string): string { if (path === base) { return '/' } - const devBase = base.endsWith('/') ? base : base + '/' - return path.replace(RegExp('^' + devBase), '/') + const devBase = base[base.length - 1] === '/' ? base : base + '/' + return path.startsWith(devBase) ? path.slice(devBase.length - 1) : path } export function arrayEqual(a: any[], b: any[]): boolean { @@ -1274,3 +1210,8 @@ export function evalValue(rawValue: string): T { `) return fn() } + +const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g +export function escapeRegex(str: string): string { + return str.replace(escapeRegexRE, '\\$&') +} diff --git a/patches/chokidar@3.5.3.patch b/patches/chokidar@3.5.3.patch new file mode 100644 index 00000000000000..510fea89b1f487 --- /dev/null +++ b/patches/chokidar@3.5.3.patch @@ -0,0 +1,14 @@ +diff --git a/lib/fsevents-handler.js b/lib/fsevents-handler.js +index 0f7f2cba857e0dbe001a5597061b11a9268d1e0e..5e99d97b917f8e2616cd3deb48b7a19d8b038928 100644 +--- a/lib/fsevents-handler.js ++++ b/lib/fsevents-handler.js +@@ -303,7 +303,8 @@ _watchWithFsEvents(watchPath, realPath, transform, globFilter) { + if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; + const opts = this.fsw.options; + const watchCallback = async (fullPath, flags, info) => { +- if (this.fsw.closed) return; ++ // PATCH: bypass the callback for better perf when fullPath hit the ignored file list ++ if (this.fsw.closed || this.fsw._isIgnored(fullPath)) return; + if ( + opts.depth !== undefined && + calcDepth(fullPath, realPath) > opts.depth \ No newline at end of file diff --git a/playground/assets/__tests__/url-base/url-base-assets.spec.ts b/playground/assets/__tests__/url-base/url-base-assets.spec.ts new file mode 100644 index 00000000000000..775f8c15caddc2 --- /dev/null +++ b/playground/assets/__tests__/url-base/url-base-assets.spec.ts @@ -0,0 +1,235 @@ +import { beforeAll, describe, expect, test } from 'vitest' +import { + browserLogs, + findAssetFile, + getBg, + getColor, + isBuild, + page, + viteConfig, +} from '~utils' + +const urlAssetMatch = isBuild + ? /http:\/\/localhost:4173\/other-assets\/asset-\w{8}\.png/ + : '/nested/asset.png' + +const iconMatch = '/icon.png' + +const absoluteIconMatch = isBuild + ? /http:\/\/localhost:4173\/.*\/icon-\w{8}\.png/ + : '/nested/icon.png' + +const absolutePublicIconMatch = isBuild + ? /http:\/\/localhost:4173\/icon\.png/ + : '/icon.png' + +test('should have no 404s', () => { + browserLogs.forEach((msg) => { + expect(msg).not.toMatch('404') + }) +}) + +describe('raw references from /public', () => { + test('load raw js from /public', async () => { + expect(await page.textContent('.raw-js')).toMatch('[success]') + }) + + test('load raw css from /public', async () => { + expect(await getColor('.raw-css')).toBe('red') + }) +}) + +test('import-expression from simple script', async () => { + expect(await page.textContent('.import-expression')).toMatch( + '[success][success]', + ) +}) + +describe('asset imports from js', () => { + test('relative', async () => { + expect(await page.textContent('.asset-import-relative')).toMatch( + urlAssetMatch, + ) + }) + + test('absolute', async () => { + expect(await page.textContent('.asset-import-absolute')).toMatch( + urlAssetMatch, + ) + }) + + test('from /public', async () => { + expect(await page.textContent('.public-import')).toMatch( + absolutePublicIconMatch, + ) + }) +}) + +describe('css url() references', () => { + test('fonts', async () => { + expect( + await page.evaluate(() => document.fonts.check('700 32px Inter')), + ).toBe(true) + }) + + test('relative', async () => { + const bg = await getBg('.css-url-relative') + expect(bg).toMatch(urlAssetMatch) + }) + + test('image-set relative', async () => { + const imageSet = await getBg('.css-image-set-relative') + imageSet.split(', ').forEach((s) => { + expect(s).toMatch(urlAssetMatch) + }) + }) + + test('image-set without the url() call', async () => { + const imageSet = await getBg('.css-image-set-without-url-call') + imageSet.split(', ').forEach((s) => { + expect(s).toMatch(urlAssetMatch) + }) + }) + + test('image-set with var', async () => { + const imageSet = await getBg('.css-image-set-with-var') + imageSet.split(', ').forEach((s) => { + expect(s).toMatch(urlAssetMatch) + }) + }) + + test('image-set with mix', async () => { + const imageSet = await getBg('.css-image-set-mix-url-var') + imageSet.split(', ').forEach((s) => { + expect(s).toMatch(urlAssetMatch) + }) + }) + + test('relative in @import', async () => { + expect(await getBg('.css-url-relative-at-imported')).toMatch(urlAssetMatch) + }) + + test('absolute', async () => { + expect(await getBg('.css-url-absolute')).toMatch(urlAssetMatch) + }) + + test('from /public', async () => { + expect(await getBg('.css-url-public')).toMatch(iconMatch) + }) + + test('multiple urls on the same line', async () => { + const bg = await getBg('.css-url-same-line') + expect(bg).toMatch(urlAssetMatch) + expect(bg).toMatch(iconMatch) + }) + + test('aliased', async () => { + const bg = await getBg('.css-url-aliased') + expect(bg).toMatch(urlAssetMatch) + }) +}) + +describe.runIf(isBuild)('index.css URLs', () => { + let css: string + beforeAll(() => { + const base = viteConfig ? viteConfig?.testConfig?.baseRoute : '' + css = findAssetFile(/index.*\.css$/, base, 'other-assets') + }) + + test('use base URL for asset URL', () => { + expect(css).toMatch(urlAssetMatch) + }) + + test('preserve postfix query/hash', () => { + expect(css).toMatch('woff2?#iefix') + }) +}) + +describe('image', () => { + test('srcset', async () => { + const img = await page.$('.img-src-set') + const srcset = await img.getAttribute('srcset') + srcset.split(', ').forEach((s) => { + expect(s).toMatch( + isBuild + ? /other-assets\/asset-\w{8}\.png \dx/ + : /\.\/nested\/asset\.png \dx/, + ) + }) + }) +}) + +describe('svg fragments', () => { + // 404 is checked already, so here we just ensure the urls end with #fragment + test('img url', async () => { + const img = await page.$('.svg-frag-img') + expect(await img.getAttribute('src')).toMatch(/svg#icon-clock-view$/) + }) + + test('via css url()', async () => { + const bg = await page.evaluate( + () => getComputedStyle(document.querySelector('.icon')).backgroundImage, + ) + expect(bg).toMatch(/svg#icon-clock-view"\)$/) + }) + + test('from js import', async () => { + const img = await page.$('.svg-frag-import') + expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/) + }) +}) + +test('?raw import', async () => { + expect(await page.textContent('.raw')).toMatch('SVG') +}) + +test('?url import', async () => { + expect(await page.textContent('.url')).toMatch( + isBuild + ? /http:\/\/localhost:4173\/other-assets\/foo-\w{8}\.js/ + : '/foo.js', + ) +}) + +test('?url import on css', async () => { + const txt = await page.textContent('.url-css') + expect(txt).toMatch( + isBuild + ? /http:\/\/localhost:4173\/other-assets\/icons-\w{8}\.css/ + : '/css/icons.css', + ) +}) + +test('new URL(..., import.meta.url)', async () => { + expect(await page.textContent('.import-meta-url')).toMatch(urlAssetMatch) +}) + +test('new URL(`${dynamic}`, import.meta.url)', async () => { + const dynamic1 = await page.textContent('.dynamic-import-meta-url-1') + expect(dynamic1).toMatch(absoluteIconMatch) + const dynamic2 = await page.textContent('.dynamic-import-meta-url-2') + expect(dynamic2).toMatch(urlAssetMatch) +}) + +test('new URL(`non-existent`, import.meta.url)', async () => { + expect(await page.textContent('.non-existent-import-meta-url')).toMatch( + '/non-existent', + ) +}) + +test('inline style test', async () => { + expect(await getBg('.inline-style')).toMatch(urlAssetMatch) + expect(await getBg('.style-url-assets')).toMatch(urlAssetMatch) +}) + +test('html import word boundary', async () => { + expect(await page.textContent('.obj-import-express')).toMatch( + 'ignore object import prop', + ) + expect(await page.textContent('.string-import-express')).toMatch('no load') +}) + +test('relative path in html asset', async () => { + expect(await page.textContent('.relative-js')).toMatch('hello') + expect(await getColor('.relative-css')).toMatch('red') +}) diff --git a/playground/assets/__tests__/url-base/vite.config.js b/playground/assets/__tests__/url-base/vite.config.js new file mode 100644 index 00000000000000..4ad6a7066edad3 --- /dev/null +++ b/playground/assets/__tests__/url-base/vite.config.js @@ -0,0 +1 @@ +export { default } from '../../vite.config-url-base' diff --git a/playground/assets/package.json b/playground/assets/package.json index beec899e36bd68..47e127261142e7 100644 --- a/playground/assets/package.json +++ b/playground/assets/package.json @@ -12,6 +12,9 @@ "preview:relative-base": "vite --config ./vite.config-relative-base.js preview", "dev:runtime-base": "vite --config ./vite.config-runtime-base.js dev", "build:runtime-base": "vite --config ./vite.config-runtime-base.js build", - "preview:runtime-base": "vite --config ./vite.config-runtime-base.js preview" + "preview:runtime-base": "vite --config ./vite.config-runtime-base.js preview", + "dev:url-base": "vite --config ./vite.config-url-base.js dev", + "build:url-base": "vite --config ./vite.config-url-base.js build", + "preview:url-base": "vite --config ./vite.config-url-base.js preview" } } diff --git a/playground/assets/vite.config-url-base.js b/playground/assets/vite.config-url-base.js new file mode 100644 index 00000000000000..bed30f8d1b2e73 --- /dev/null +++ b/playground/assets/vite.config-url-base.js @@ -0,0 +1,24 @@ +import { defineConfig } from 'vite' +import baseConfig from './vite.config.js' + +export default defineConfig({ + ...baseConfig, + base: 'http://localhost:4173/', + build: { + ...baseConfig.build, + outDir: 'dist/url-base', + watch: null, + minify: false, + assetsInlineLimit: 0, + rollupOptions: { + output: { + entryFileNames: 'entries/[name].js', + chunkFileNames: 'chunks/[name]-[hash].js', + assetFileNames: 'other-assets/[name]-[hash][extname]', + }, + }, + }, + testConfig: { + baseRoute: '/url-base/', + }, +}) diff --git a/playground/backend-integration/package.json b/playground/backend-integration/package.json index 5ab044449aec4c..ed28e061d00436 100644 --- a/playground/backend-integration/package.json +++ b/playground/backend-integration/package.json @@ -9,7 +9,7 @@ "preview": "vite preview" }, "devDependencies": { - "sass": "^1.58.3", + "sass": "^1.59.3", "tailwindcss": "^3.2.7", "fast-glob": "^3.2.12" } diff --git a/playground/css-codesplit/__tests__/css-codesplit-consistent.spec.ts b/playground/css-codesplit/__tests__/css-codesplit-consistent.spec.ts new file mode 100644 index 00000000000000..4da121a652d0db --- /dev/null +++ b/playground/css-codesplit/__tests__/css-codesplit-consistent.spec.ts @@ -0,0 +1,15 @@ +import { beforeEach, describe, expect, test } from 'vitest' +import { findAssetFile, isBuild, startDefaultServe } from '~utils' + +beforeEach(async () => { + await startDefaultServe() +}) + +for (let i = 0; i < 5; i++) { + describe.runIf(isBuild)('css-codesplit build', () => { + test('should be consistent with same content', () => { + expect(findAssetFile(/style-.+\.css/)).toMatch('h2{color:#00f}') + expect(findAssetFile(/style2-.+\.css/)).toBe('') + }) + }) +} diff --git a/playground/css-codesplit/__tests__/css-codesplit.spec.ts b/playground/css-codesplit/__tests__/css-codesplit.spec.ts index e1b4f26fc6a9e3..6aae9619c5e0e9 100644 --- a/playground/css-codesplit/__tests__/css-codesplit.spec.ts +++ b/playground/css-codesplit/__tests__/css-codesplit.spec.ts @@ -30,7 +30,7 @@ test('style order should be consistent when style tag is inserted by JS', async describe.runIf(isBuild)('build', () => { test('should remove empty chunk', async () => { - expect(findAssetFile(/style.*\.js$/)).toBe('') + expect(findAssetFile(/style-.*\.js$/)).toBe('') expect(findAssetFile('main.*.js$')).toMatch(`/* empty css`) expect(findAssetFile('other.*.js$')).toMatch(`/* empty css`) expect(findAssetFile(/async.*\.js$/)).toBe('') diff --git a/playground/css-codesplit/style2.css b/playground/css-codesplit/style2.css new file mode 100644 index 00000000000000..2b4bb3671e654b --- /dev/null +++ b/playground/css-codesplit/style2.css @@ -0,0 +1,3 @@ +h2 { + color: blue; +} diff --git a/playground/css-codesplit/style2.js b/playground/css-codesplit/style2.js new file mode 100644 index 00000000000000..ab7ebb9eb632a6 --- /dev/null +++ b/playground/css-codesplit/style2.js @@ -0,0 +1 @@ +import './style2.css' diff --git a/playground/css-codesplit/vite.config.js b/playground/css-codesplit/vite.config.js index 962dbbb103192e..3e0d3ac3540be5 100644 --- a/playground/css-codesplit/vite.config.js +++ b/playground/css-codesplit/vite.config.js @@ -8,6 +8,7 @@ export default defineConfig({ input: { main: resolve(__dirname, './index.html'), other: resolve(__dirname, './other.js'), + style2: resolve(__dirname, './style2.js'), }, output: { manualChunks(id) { diff --git a/playground/css-sourcemap/package.json b/playground/css-sourcemap/package.json index f74bc2bfa7156e..828ffc153245bc 100644 --- a/playground/css-sourcemap/package.json +++ b/playground/css-sourcemap/package.json @@ -11,7 +11,7 @@ "devDependencies": { "less": "^4.1.3", "magic-string": "^0.30.0", - "sass": "^1.58.3", + "sass": "^1.59.3", "stylus": "^0.59.0", "sugarss": "^4.0.1" } diff --git a/playground/css/package.json b/playground/css/package.json index 6ae9aeec5bea05..5153cb18f69f1b 100644 --- a/playground/css/package.json +++ b/playground/css/package.json @@ -21,7 +21,7 @@ "fast-glob": "^3.2.12", "less": "^4.1.3", "postcss-nested": "^6.0.1", - "sass": "^1.58.3", + "sass": "^1.59.3", "stylus": "^0.59.0", "sugarss": "^4.0.1" } diff --git a/playground/legacy/package.json b/playground/legacy/package.json index efb5d7767de4ca..d194824d783a67 100644 --- a/playground/legacy/package.json +++ b/playground/legacy/package.json @@ -13,6 +13,6 @@ "devDependencies": { "@vitejs/plugin-legacy": "workspace:*", "express": "^4.18.2", - "terser": "^5.16.5" + "terser": "^5.16.6" } } diff --git a/playground/multiple-entrypoints/package.json b/playground/multiple-entrypoints/package.json index 0addb3ca841b01..d80deaa71cf46d 100644 --- a/playground/multiple-entrypoints/package.json +++ b/playground/multiple-entrypoints/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "fast-glob": "^3.2.12", - "sass": "^1.58.3" + "sass": "^1.59.3" } } diff --git a/playground/optimize-deps/package.json b/playground/optimize-deps/package.json index 6b7f3dc3dc4c00..acd048a654d41c 100644 --- a/playground/optimize-deps/package.json +++ b/playground/optimize-deps/package.json @@ -31,7 +31,7 @@ "@vitejs/test-added-in-entries": "file:./added-in-entries", "lodash-es": "^4.17.21", "@vitejs/test-nested-exclude": "file:./nested-exclude", - "phoenix": "^1.7.1", + "phoenix": "^1.7.2", "react": "^18.2.0", "react-dom": "^18.2.0", "@vitejs/test-resolve-linked": "workspace:0.0.0", diff --git a/playground/package.json b/playground/package.json index dd9440207f6739..8a0b3574a318a1 100644 --- a/playground/package.json +++ b/playground/package.json @@ -9,7 +9,7 @@ "convert-source-map": "^2.0.0", "css-color-names": "^1.0.1", "kill-port": "^1.6.1", - "node-fetch": "^3.3.0", + "node-fetch": "^3.3.1", "sirv": "^2.0.2" } } diff --git a/playground/preload/package.json b/playground/preload/package.json index d8a1449dcf72a1..bb2d5ce9bcf6a3 100644 --- a/playground/preload/package.json +++ b/playground/preload/package.json @@ -17,7 +17,7 @@ "preview:preload-disabled": "vite preview --config vite.config-preload-disabled.ts" }, "devDependencies": { - "terser": "^5.16.5", + "terser": "^5.16.6", "@vitejs/test-dep-a": "file:./dep-a", "@vitejs/test-dep-including-a": "file:./dep-including-a" } diff --git a/playground/resolve/index.html b/playground/resolve/index.html index 4bdfc829c20bea..3aba3224c4822c 100644 --- a/playground/resolve/index.html +++ b/playground/resolve/index.html @@ -91,6 +91,12 @@

fail

+

+ A ts module can import another ESM module using its corresponding mjs file + name with query parameters +

+

fail

+

A ts module can import another CommonJS module using its corresponding cjs file name @@ -262,6 +268,9 @@

resolve package that contains # in path

import { msgMjs as tsMjsExtensionMsg } from './ts-extension' text('.mjs-extension', tsMjsExtensionMsg) + import { msgMjs as tsMjsExtensionWithQueryMsg } from './ts-extension?query=1' + text('.mjs-extension-with-query', tsMjsExtensionWithQueryMsg) + // filename with dot import { bar } from './util/bar.util' text('.dot', bar()) diff --git a/playground/ssr/__tests__/serve.ts b/playground/ssr/__tests__/serve.ts new file mode 100644 index 00000000000000..af8c444f555235 --- /dev/null +++ b/playground/ssr/__tests__/serve.ts @@ -0,0 +1,35 @@ +// this is automatically detected by playground/vitestSetup.ts and will replace +// the default e2e test serve behavior + +import path from 'node:path' +import kill from 'kill-port' +import { hmrPorts, ports, rootDir } from '~utils' + +export const port = ports.ssr + +export async function serve(): Promise<{ close(): Promise }> { + await kill(port) + + const { createServer } = await import(path.resolve(rootDir, 'server.js')) + const { app, vite } = await createServer(rootDir, hmrPorts.ssr) + + return new Promise((resolve, reject) => { + try { + const server = app.listen(port, () => { + resolve({ + // for test teardown + async close() { + await new Promise((resolve) => { + server.close(resolve) + }) + if (vite) { + await vite.close() + } + }, + }) + }) + } catch (e) { + reject(e) + } + }) +} diff --git a/playground/ssr/__tests__/ssr.spec.ts b/playground/ssr/__tests__/ssr.spec.ts new file mode 100644 index 00000000000000..a5a7a46955d85d --- /dev/null +++ b/playground/ssr/__tests__/ssr.spec.ts @@ -0,0 +1,19 @@ +import { expect, test } from 'vitest' +import { port } from './serve' +import { page } from '~utils' + +const url = `http://localhost:${port}` + +test(`circular dependencies modules doesn't throw`, async () => { + await page.goto(`${url}/circular-dep`) + + expect(await page.textContent('.circ-dep-init')).toMatch( + 'circ-dep-init-a circ-dep-init-b', + ) +}) + +test(`deadlock doesn't happen`, async () => { + await page.goto(`${url}/forked-deadlock`) + + expect(await page.textContent('.forked-deadlock')).toMatch('rendered') +}) diff --git a/playground/ssr/index.html b/playground/ssr/index.html new file mode 100644 index 00000000000000..3ae6b11d31eb62 --- /dev/null +++ b/playground/ssr/index.html @@ -0,0 +1,12 @@ + + + + + + SSR + + +

SSR

+
+ + diff --git a/playground/ssr/package.json b/playground/ssr/package.json new file mode 100644 index 00000000000000..3011a1a067f2ef --- /dev/null +++ b/playground/ssr/package.json @@ -0,0 +1,15 @@ +{ + "name": "@vitejs/test-ssr", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "node server", + "serve": "NODE_ENV=production node server", + "debug": "node --inspect-brk server" + }, + "dependencies": {}, + "devDependencies": { + "express": "^4.18.2" + } +} diff --git a/playground/ssr/server.js b/playground/ssr/server.js new file mode 100644 index 00000000000000..b17fb9dcfd4939 --- /dev/null +++ b/playground/ssr/server.js @@ -0,0 +1,69 @@ +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import express from 'express' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const isTest = process.env.VITEST + +export async function createServer(root = process.cwd(), hmrPort) { + const resolve = (p) => path.resolve(__dirname, p) + + const app = express() + + /** + * @type {import('vite').ViteDevServer} + */ + const vite = await ( + await import('vite') + ).createServer({ + root, + logLevel: isTest ? 'error' : 'info', + server: { + middlewareMode: true, + watch: { + // During tests we edit the files too fast and sometimes chokidar + // misses change events, so enforce polling for consistency + usePolling: true, + interval: 100, + }, + hmr: { + port: hmrPort, + }, + }, + appType: 'custom', + }) + // use vite's connect instance as middleware + app.use(vite.middlewares) + + app.use('*', async (req, res, next) => { + try { + const url = req.originalUrl + + let template + template = fs.readFileSync(resolve('index.html'), 'utf-8') + template = await vite.transformIndexHtml(url, template) + const render = (await vite.ssrLoadModule('/src/app.js')).render + + const appHtml = await render(url, __dirname) + + const html = template.replace(``, appHtml) + + res.status(200).set({ 'Content-Type': 'text/html' }).end(html) + } catch (e) { + vite && vite.ssrFixStacktrace(e) + console.log(e.stack) + res.status(500).end(e.stack) + } + }) + + return { app, vite } +} + +if (!isTest) { + createServer().then(({ app }) => + app.listen(5173, () => { + console.log('http://localhost:5173') + }), + ) +} diff --git a/playground/ssr/src/app.js b/playground/ssr/src/app.js new file mode 100644 index 00000000000000..5e10dfe45937e3 --- /dev/null +++ b/playground/ssr/src/app.js @@ -0,0 +1,41 @@ +import { escapeHtml } from './utils' + +const pathRenderers = { + '/': renderRoot, + '/circular-dep': renderCircularDep, + '/forked-deadlock': renderForkedDeadlock, +} + +export async function render(url, rootDir) { + const pathname = url.replace(/#[^#]*$/, '').replace(/\?[^?]*$/, '') + const renderer = pathRenderers[pathname] + if (renderer) { + return await renderer(rootDir) + } + return '404' +} + +async function renderRoot(rootDir) { + const paths = Object.keys(pathRenderers).filter((key) => key !== '/') + return ` + + ` +} + +async function renderCircularDep(rootDir) { + const { getValueAB } = await import('./circular-dep-init/circular-dep-init') + return `
${escapeHtml(getValueAB())}
` +} + +async function renderForkedDeadlock(rootDir) { + const { commonModuleExport } = await import('./forked-deadlock/common-module') + commonModuleExport() + return `
rendered
` +} diff --git a/playground/ssr/src/circular-dep-init/README.md b/playground/ssr/src/circular-dep-init/README.md new file mode 100644 index 00000000000000..864d16ae8c495b --- /dev/null +++ b/playground/ssr/src/circular-dep-init/README.md @@ -0,0 +1 @@ +This test aim to find out wherever the modules with circular dependencies are correctly initialized diff --git a/playground/ssr/src/circular-dep-init/circular-dep-init.js b/playground/ssr/src/circular-dep-init/circular-dep-init.js new file mode 100644 index 00000000000000..8867d64ec45091 --- /dev/null +++ b/playground/ssr/src/circular-dep-init/circular-dep-init.js @@ -0,0 +1,2 @@ +export * from './module-a' +export { getValueAB } from './module-b' diff --git a/playground/ssr/src/circular-dep-init/module-a.js b/playground/ssr/src/circular-dep-init/module-a.js new file mode 100644 index 00000000000000..335b3ac26ab3b5 --- /dev/null +++ b/playground/ssr/src/circular-dep-init/module-a.js @@ -0,0 +1 @@ +export const valueA = 'circ-dep-init-a' diff --git a/playground/ssr/src/circular-dep-init/module-b.js b/playground/ssr/src/circular-dep-init/module-b.js new file mode 100644 index 00000000000000..cb16d7e9be4a30 --- /dev/null +++ b/playground/ssr/src/circular-dep-init/module-b.js @@ -0,0 +1,8 @@ +import { valueA } from './circular-dep-init' + +export const valueB = 'circ-dep-init-b' +export const valueAB = valueA.concat(` ${valueB}`) + +export function getValueAB() { + return valueAB +} diff --git a/playground/ssr/src/forked-deadlock/README.md b/playground/ssr/src/forked-deadlock/README.md new file mode 100644 index 00000000000000..798c8c429ee9e4 --- /dev/null +++ b/playground/ssr/src/forked-deadlock/README.md @@ -0,0 +1,51 @@ +This test aim to check for a particular type of circular dependency that causes tricky deadlocks, **deadlocks with forked imports stack** + +``` +A -> B means: B is imported by A and B has A in its stack +A ... B means: A is waiting for B to ssrLoadModule() + +H -> X ... Y +H -> X -> Y ... B +H -> A ... B +H -> A -> B ... X +``` + +### Forked deadlock description: + +``` +[X] is waiting for [Y] to resolve + ↑ ↳ is waiting for [A] to resolve + │ ↳ is waiting for [B] to resolve + │ ↳ is waiting for [X] to resolve + └────────────────────────────────────────────────────────────────────────┘ +``` + +This may seems a traditional deadlock, but the thing that makes this special is the import stack of each module: + +``` +[X] stack: + [H] +``` + +``` +[Y] stack: + [X] + [H] +``` + +``` +[A] stack: + [H] +``` + +``` +[B] stack: + [A] + [H] +``` + +Even if `[X]` is imported by `[B]`, `[B]` is not in `[X]`'s stack because it's imported by `[H]` in first place then it's stack is only composed by `[H]`. `[H]` **forks** the imports **stack** and this make hard to be found. + +### Fix description + +Vite, when imports `[X]`, should check whether `[X]` is already pending and if it is, it must check that, when it was imported in first place, the stack of `[X]` doesn't have any module in common with the current module; in this case `[B]` has the module `[H]` is common with `[X]` and i can assume that a deadlock is going to happen. diff --git a/playground/ssr/src/forked-deadlock/common-module.js b/playground/ssr/src/forked-deadlock/common-module.js new file mode 100644 index 00000000000000..c73a3ee4b970c8 --- /dev/null +++ b/playground/ssr/src/forked-deadlock/common-module.js @@ -0,0 +1,10 @@ +import { stuckModuleExport } from './stuck-module' +import { deadlockfuseModuleExport } from './deadlock-fuse-module' + +/** + * module H + */ +export function commonModuleExport() { + stuckModuleExport() + deadlockfuseModuleExport() +} diff --git a/playground/ssr/src/forked-deadlock/deadlock-fuse-module.js b/playground/ssr/src/forked-deadlock/deadlock-fuse-module.js new file mode 100644 index 00000000000000..4f31763ba2343f --- /dev/null +++ b/playground/ssr/src/forked-deadlock/deadlock-fuse-module.js @@ -0,0 +1,8 @@ +import { fuseStuckBridgeModuleExport } from './fuse-stuck-bridge-module' + +/** + * module A + */ +export function deadlockfuseModuleExport() { + fuseStuckBridgeModuleExport() +} diff --git a/playground/ssr/src/forked-deadlock/fuse-stuck-bridge-module.js b/playground/ssr/src/forked-deadlock/fuse-stuck-bridge-module.js new file mode 100644 index 00000000000000..211ad7c3bc9f92 --- /dev/null +++ b/playground/ssr/src/forked-deadlock/fuse-stuck-bridge-module.js @@ -0,0 +1,8 @@ +import { stuckModuleExport } from './stuck-module' + +/** + * module C + */ +export function fuseStuckBridgeModuleExport() { + stuckModuleExport() +} diff --git a/playground/ssr/src/forked-deadlock/middle-module.js b/playground/ssr/src/forked-deadlock/middle-module.js new file mode 100644 index 00000000000000..0632eedeabd7a5 --- /dev/null +++ b/playground/ssr/src/forked-deadlock/middle-module.js @@ -0,0 +1,8 @@ +import { deadlockfuseModuleExport } from './deadlock-fuse-module' + +/** + * module Y + */ +export function middleModuleExport() { + void deadlockfuseModuleExport +} diff --git a/playground/ssr/src/forked-deadlock/stuck-module.js b/playground/ssr/src/forked-deadlock/stuck-module.js new file mode 100644 index 00000000000000..50b4d28063dc70 --- /dev/null +++ b/playground/ssr/src/forked-deadlock/stuck-module.js @@ -0,0 +1,8 @@ +import { middleModuleExport } from './middle-module' + +/** + * module X + */ +export function stuckModuleExport() { + middleModuleExport() +} diff --git a/playground/ssr/src/utils.js b/playground/ssr/src/utils.js new file mode 100644 index 00000000000000..cffcfe5f7cec22 --- /dev/null +++ b/playground/ssr/src/utils.js @@ -0,0 +1,16 @@ +const escapeHtmlReplaceMap = { + '&': '&', + "'": ''', + '`': '`', + '"': '"', + '<': '<', + '>': '>', +} + +/** + * @param {string} string + * @returns {string} + */ +export function escapeHtml(string) { + return string.replace(/[&'`"<>]/g, (match) => escapeHtmlReplaceMap[match]) +} diff --git a/playground/tailwind/package.json b/playground/tailwind/package.json index 45fe4493db781a..fbf94019ede2e1 100644 --- a/playground/tailwind/package.json +++ b/playground/tailwind/package.json @@ -9,13 +9,13 @@ "preview": "vite preview" }, "dependencies": { - "autoprefixer": "^10.4.13", + "autoprefixer": "^10.4.14", "tailwindcss": "^3.2.7", "vue": "^3.2.47", "vue-router": "^4.1.6" }, "devDependencies": { - "@vitejs/plugin-vue": "^4.0.0", + "@vitejs/plugin-vue": "^4.1.0", "ts-node": "^10.9.1" } } diff --git a/playground/test-utils.ts b/playground/test-utils.ts index d2aafaff4b2aca..f791d534c0c2ad 100644 --- a/playground/test-utils.ts +++ b/playground/test-utils.ts @@ -22,21 +22,23 @@ export const ports = { lib: 9521, 'optimize-missing-deps': 9522, 'legacy/client-and-ssr': 9523, - 'ssr-deps': 9600, - 'ssr-html': 9601, - 'ssr-noexternal': 9602, - 'ssr-pug': 9603, - 'ssr-webworker': 9606, + ssr: 9600, + 'ssr-deps': 9601, + 'ssr-html': 9602, + 'ssr-noexternal': 9603, + 'ssr-pug': 9604, + 'ssr-webworker': 9605, 'css/postcss-caching': 5005, 'css/postcss-plugins-different-dir': 5006, 'css/dynamic-import': 5007, } export const hmrPorts = { 'optimize-missing-deps': 24680, - 'ssr-deps': 24681, - 'ssr-html': 24682, - 'ssr-noexternal': 24683, - 'ssr-pug': 24684, + ssr: 24681, + 'ssr-deps': 24682, + 'ssr-html': 24683, + 'ssr-noexternal': 24684, + 'ssr-pug': 24685, } const hexToNameMap: Record = {} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9c54c7ea1bcb3..d8c41e9d10d4db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,18 +6,21 @@ overrides: packageExtensionsChecksum: 2a87e01b470616d3b7def19cc0830231 patchedDependencies: - dotenv-expand@9.0.0: - hash: dccccn23nvejzy75sgiosdt2au - path: patches/dotenv-expand@9.0.0.patch + chokidar@3.5.3: + hash: dzxbf3kgof5pdmbsyih2x43sq4 + path: patches/chokidar@3.5.3.patch sirv@2.0.2: hash: hmoqtj4vy3i7wnpchga2a2mu3y path: patches/sirv@2.0.2.patch + dotenv-expand@9.0.0: + hash: dccccn23nvejzy75sgiosdt2au + path: patches/dotenv-expand@9.0.0.patch importers: .: specifiers: - '@babel/types': ^7.21.2 + '@babel/types': ^7.21.3 '@microsoft/api-extractor': ^7.34.4 '@rollup/plugin-typescript': ^11.0.0 '@types/babel__core': ^7.20.0 @@ -32,26 +35,26 @@ importers: '@types/less': ^3.0.3 '@types/micromatch': ^4.0.2 '@types/minimist': ^1.2.2 - '@types/node': ^18.14.6 + '@types/node': ^18.15.5 '@types/picomatch': ^2.3.0 - '@types/prompts': ^2.4.2 + '@types/prompts': 2.4.2 '@types/resolve': ^1.20.2 '@types/sass': ~1.43.1 '@types/semver': ^7.3.13 '@types/stylus': ^0.48.38 '@types/ws': ^8.5.4 - '@typescript-eslint/eslint-plugin': ^5.54.1 - '@typescript-eslint/parser': ^5.54.1 + '@typescript-eslint/eslint-plugin': ^5.56.0 + '@typescript-eslint/parser': ^5.56.0 conventional-changelog-cli: ^2.2.2 - eslint: ^8.35.0 - eslint-define-config: ^1.15.0 + eslint: ^8.36.0 + eslint-define-config: ^1.17.0 eslint-plugin-import: ^2.27.5 eslint-plugin-node: ^11.1.0 - eslint-plugin-regexp: ^1.12.0 - execa: ^7.0.0 + eslint-plugin-regexp: ^1.13.0 + execa: ^7.1.1 fast-glob: ^3.2.12 - fs-extra: ^11.1.0 - lint-staged: ^13.1.2 + fs-extra: ^11.1.1 + lint-staged: ^13.2.0 minimist: ^1.2.8 npm-run-all: ^4.1.5 picocolors: ^1.0.0 @@ -59,22 +62,22 @@ importers: prettier: 2.8.5 prompts: ^2.4.2 resolve: ^1.22.1 - rimraf: ^4.1.2 - rollup: ^3.18.0 + rimraf: ^4.4.0 + rollup: ^3.20.0 semver: ^7.3.8 simple-git-hooks: ^2.8.1 tslib: ^2.5.0 - tsx: ^3.12.3 + tsx: ^3.12.6 typescript: ^5.0.2 unbuild: ^1.1.2 vite: workspace:* - vitepress: ^1.0.0-alpha.49 - vitest: ^0.29.2 + vitepress: ^1.0.0-alpha.61 + vitest: ^0.29.7 vue: ^3.2.47 devDependencies: - '@babel/types': 7.21.2 - '@microsoft/api-extractor': 7.34.4_@types+node@18.14.6 - '@rollup/plugin-typescript': 11.0.0_taeyxmvmc26umlo2so2an3i7iy + '@babel/types': 7.21.3 + '@microsoft/api-extractor': 7.34.4_@types+node@18.15.5 + '@rollup/plugin-typescript': 11.0.0_7sniqkrn5rmxrmax2dmiqcv3qu '@types/babel__core': 7.20.0 '@types/babel__standalone': 7.1.4 '@types/convert-source-map': 2.0.0 @@ -87,7 +90,7 @@ importers: '@types/less': 3.0.3 '@types/micromatch': 4.0.2 '@types/minimist': 1.2.2 - '@types/node': 18.14.6 + '@types/node': 18.15.5 '@types/picomatch': 2.3.0 '@types/prompts': 2.4.2 '@types/resolve': 1.20.2 @@ -95,18 +98,18 @@ importers: '@types/semver': 7.3.13 '@types/stylus': 0.48.38 '@types/ws': 8.5.4 - '@typescript-eslint/eslint-plugin': 5.54.1_ptmzjahj2lzv7vrsfzwjsq4mpu - '@typescript-eslint/parser': 5.54.1_byynos7ffx3cepxtk6gvolkky4 + '@typescript-eslint/eslint-plugin': 5.56.0_2hcjazgfnbtq42tcc73br2vup4 + '@typescript-eslint/parser': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu conventional-changelog-cli: 2.2.2 - eslint: 8.35.0 - eslint-define-config: 1.15.0 - eslint-plugin-import: 2.27.5_uyiasnnzcqrxqkfvjklwnmwcha - eslint-plugin-node: 11.1.0_eslint@8.35.0 - eslint-plugin-regexp: 1.12.0_eslint@8.35.0 - execa: 7.0.0 + eslint: 8.36.0 + eslint-define-config: 1.17.0 + eslint-plugin-import: 2.27.5_cnkxirszkzb4o6ts7gbclno24e + eslint-plugin-node: 11.1.0_eslint@8.36.0 + eslint-plugin-regexp: 1.13.0_eslint@8.36.0 + execa: 7.1.1 fast-glob: 3.2.12 - fs-extra: 11.1.0 - lint-staged: 13.1.2 + fs-extra: 11.1.1 + lint-staged: 13.2.0 minimist: 1.2.8 npm-run-all: 4.1.5 picocolors: 1.0.0 @@ -114,17 +117,17 @@ importers: prettier: 2.8.5 prompts: 2.4.2 resolve: 1.22.1 - rimraf: 4.1.2 - rollup: 3.18.0 + rimraf: 4.4.0 + rollup: 3.20.0 semver: 7.3.8 simple-git-hooks: 2.8.1 tslib: 2.5.0 - tsx: 3.12.3 + tsx: 3.12.6 typescript: 5.0.2 unbuild: 1.1.2 vite: link:packages/vite - vitepress: 1.0.0-alpha.49 - vitest: 0.29.2 + vitepress: 1.0.0-alpha.61 + vitest: 0.29.7 vue: 3.2.47 packages/create-vite: @@ -141,21 +144,21 @@ importers: packages/plugin-legacy: specifiers: - '@babel/core': ^7.21.0 + '@babel/core': ^7.21.3 '@babel/preset-env': ^7.20.2 acorn: ^8.8.2 browserslist: ^4.21.5 - core-js: ^3.29.0 + core-js: ^3.29.1 magic-string: ^0.30.0 picocolors: ^1.0.0 regenerator-runtime: ^0.13.11 systemjs: ^6.14.0 vite: workspace:* dependencies: - '@babel/core': 7.21.0 - '@babel/preset-env': 7.20.2_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/preset-env': 7.20.2_@babel+core@7.21.3 browserslist: 4.21.5 - core-js: 3.29.0 + core-js: 3.29.1 magic-string: 0.30.0 regenerator-runtime: 0.13.11 systemjs: 6.14.0 @@ -167,8 +170,8 @@ importers: packages/vite: specifiers: '@ampproject/remapping': ^2.2.0 - '@babel/parser': ^7.21.2 - '@babel/types': ^7.21.2 + '@babel/parser': ^7.21.3 + '@babel/types': ^7.21.3 '@jridgewell/trace-mapping': ^0.3.17 '@rollup/plugin-alias': ^4.0.3 '@rollup/plugin-commonjs': ^24.0.1 @@ -177,6 +180,7 @@ importers: '@rollup/plugin-node-resolve': 15.0.1 '@rollup/plugin-typescript': ^11.0.0 '@rollup/pluginutils': ^5.0.2 + '@types/pnpapi': ^0.0.2 acorn: ^8.8.2 acorn-walk: ^8.2.0 cac: ^6.7.14 @@ -201,7 +205,7 @@ importers: launch-editor-middleware: ^2.6.0 magic-string: ^0.30.0 micromatch: ^4.0.5 - mlly: ^1.1.1 + mlly: ^1.2.0 mrmime: ^1.0.1 okie: ^1.0.1 open: ^8.4.2 @@ -215,41 +219,42 @@ importers: postcss-modules: ^6.0.0 resolve: ^1.22.1 resolve.exports: ^2.0.1 - rollup: ^3.18.0 + rollup: ^3.20.0 rollup-plugin-license: ^3.0.1 sirv: ^2.0.2 source-map-js: ^1.0.2 source-map-support: ^0.5.21 strip-ansi: ^7.0.1 strip-literal: ^1.0.1 - tsconfck: ^2.1.0 + tsconfck: ^2.1.1 tslib: ^2.5.0 types: link:./types ufo: ^1.1.1 - ws: ^8.12.1 + ws: ^8.13.0 dependencies: esbuild: 0.17.5 postcss: 8.4.21 resolve: 1.22.1 - rollup: 3.18.0 + rollup: 3.20.0 optionalDependencies: fsevents: 2.3.2 devDependencies: '@ampproject/remapping': 2.2.0 - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 '@jridgewell/trace-mapping': 0.3.17 - '@rollup/plugin-alias': 4.0.3_rollup@3.18.0 - '@rollup/plugin-commonjs': 24.0.1_rollup@3.18.0 - '@rollup/plugin-dynamic-import-vars': 2.0.3_rollup@3.18.0 - '@rollup/plugin-json': 6.0.0_rollup@3.18.0 - '@rollup/plugin-node-resolve': 15.0.1_rollup@3.18.0 - '@rollup/plugin-typescript': 11.0.0_rollup@3.18.0+tslib@2.5.0 - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/plugin-alias': 4.0.3_rollup@3.20.0 + '@rollup/plugin-commonjs': 24.0.1_rollup@3.20.0 + '@rollup/plugin-dynamic-import-vars': 2.0.3_rollup@3.20.0 + '@rollup/plugin-json': 6.0.0_rollup@3.20.0 + '@rollup/plugin-node-resolve': 15.0.1_rollup@3.20.0 + '@rollup/plugin-typescript': 11.0.0_rollup@3.20.0+tslib@2.5.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@types/pnpapi': 0.0.2 acorn: 8.8.2 acorn-walk: 8.2.0_acorn@8.8.2 cac: 6.7.14 - chokidar: 3.5.3 + chokidar: 3.5.3_dzxbf3kgof5pdmbsyih2x43sq4 connect: 3.7.0 connect-history-api-fallback: 2.0.0 convert-source-map: 2.0.0 @@ -268,7 +273,7 @@ importers: launch-editor-middleware: 2.6.0 magic-string: 0.30.0 micromatch: 4.0.5 - mlly: 1.1.1 + mlly: 1.2.0 mrmime: 1.0.1 okie: 1.0.1 open: 8.4.2 @@ -280,30 +285,30 @@ importers: postcss-load-config: 4.0.1_postcss@8.4.21 postcss-modules: 6.0.0_postcss@8.4.21 resolve.exports: 2.0.1 - rollup-plugin-license: 3.0.1_rollup@3.18.0 + rollup-plugin-license: 3.0.1_rollup@3.20.0 sirv: 2.0.2_hmoqtj4vy3i7wnpchga2a2mu3y source-map-js: 1.0.2 source-map-support: 0.5.21 strip-ansi: 7.0.1 strip-literal: 1.0.1 - tsconfck: 2.1.0 + tsconfck: 2.1.1 tslib: 2.5.0 types: link:types ufo: 1.1.1 - ws: 8.12.1 + ws: 8.13.0 playground: specifiers: convert-source-map: ^2.0.0 css-color-names: ^1.0.1 kill-port: ^1.6.1 - node-fetch: ^3.3.0 + node-fetch: ^3.3.1 sirv: ^2.0.2 devDependencies: convert-source-map: 2.0.0 css-color-names: 1.0.1 kill-port: 1.6.1 - node-fetch: 3.3.0 + node-fetch: 3.3.1 sirv: 2.0.2_hmoqtj4vy3i7wnpchga2a2mu3y playground/alias: @@ -331,11 +336,11 @@ importers: playground/backend-integration: specifiers: fast-glob: ^3.2.12 - sass: ^1.58.3 + sass: ^1.59.3 tailwindcss: ^3.2.7 devDependencies: fast-glob: 3.2.12 - sass: 1.58.3 + sass: 1.59.3 tailwindcss: 3.2.7 playground/build-old: @@ -375,7 +380,7 @@ importers: fast-glob: ^3.2.12 less: ^4.1.3 postcss-nested: ^6.0.1 - sass: ^1.58.3 + sass: ^1.59.3 stylus: ^0.59.0 sugarss: ^4.0.1 devDependencies: @@ -385,7 +390,7 @@ importers: fast-glob: 3.2.12 less: 4.1.3 postcss-nested: 6.0.1 - sass: 1.58.3 + sass: 1.59.3 stylus: 0.59.0 sugarss: 4.0.1 @@ -402,13 +407,13 @@ importers: specifiers: less: ^4.1.3 magic-string: ^0.30.0 - sass: ^1.58.3 + sass: ^1.59.3 stylus: ^0.59.0 sugarss: ^4.0.1 devDependencies: less: 4.1.3 magic-string: 0.30.0 - sass: 1.58.3 + sass: 1.59.3 stylus: 0.59.0 sugarss: 4.0.1 @@ -541,11 +546,11 @@ importers: specifiers: '@vitejs/plugin-legacy': workspace:* express: ^4.18.2 - terser: ^5.16.5 + terser: ^5.16.6 devDependencies: '@vitejs/plugin-legacy': link:../../packages/plugin-legacy express: 4.18.2 - terser: 5.16.5 + terser: 5.16.6 playground/lib: specifiers: {} @@ -556,10 +561,10 @@ importers: playground/multiple-entrypoints: specifiers: fast-glob: ^3.2.12 - sass: ^1.58.3 + sass: ^1.59.3 devDependencies: fast-glob: 3.2.12 - sass: 1.58.3 + sass: 1.59.3 playground/nested-deps: specifiers: @@ -643,7 +648,7 @@ importers: lodash: ^4.17.21 lodash-es: ^4.17.21 lodash.clonedeep: ^4.5.0 - phoenix: ^1.7.1 + phoenix: ^1.7.2 react: ^18.2.0 react-dom: ^18.2.0 url: ^0.11.0 @@ -675,7 +680,7 @@ importers: lodash: 4.17.21 lodash-es: 4.17.21 lodash.clonedeep: 4.5.0 - phoenix: 1.7.1 + phoenix: 1.7.2 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 url: 0.11.0 @@ -779,11 +784,11 @@ importers: specifiers: '@vitejs/test-dep-a': file:./dep-a '@vitejs/test-dep-including-a': file:./dep-including-a - terser: ^5.16.5 + terser: ^5.16.6 devDependencies: '@vitejs/test-dep-a': file:playground/preload/dep-a '@vitejs/test-dep-including-a': file:playground/preload/dep-including-a - terser: 5.16.5 + terser: 5.16.6 playground/preload/dep-a: specifiers: {} @@ -925,6 +930,12 @@ importers: dependencies: es5-ext: 0.10.62 + playground/ssr: + specifiers: + express: ^4.18.2 + devDependencies: + express: 4.18.2 + playground/ssr-deps: specifiers: '@vitejs/test-css-lib': file:./css-lib @@ -1117,19 +1128,19 @@ importers: playground/tailwind: specifiers: - '@vitejs/plugin-vue': ^4.0.0 - autoprefixer: ^10.4.13 + '@vitejs/plugin-vue': ^4.1.0 + autoprefixer: ^10.4.14 tailwindcss: ^3.2.7 ts-node: ^10.9.1 vue: ^3.2.47 vue-router: ^4.1.6 dependencies: - autoprefixer: 10.4.13 + autoprefixer: 10.4.14 tailwindcss: 3.2.7_ts-node@10.9.1 vue: 3.2.47 vue-router: 4.1.6_vue@3.2.47 devDependencies: - '@vitejs/plugin-vue': 4.0.0_vue@3.2.47 + '@vitejs/plugin-vue': 4.1.0_vue@3.2.47 ts-node: 10.9.1 playground/tailwind-sourcemap: @@ -1292,20 +1303,20 @@ packages: resolution: {integrity: sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==} engines: {node: '>=6.9.0'} - /@babel/core/7.21.0: - resolution: {integrity: sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==} + /@babel/core/7.21.3: + resolution: {integrity: sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.21.1 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/generator': 7.21.3 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.3 '@babel/helper-module-transforms': 7.21.2 '@babel/helpers': 7.21.0 - '@babel/parser': 7.21.2 + '@babel/parser': 7.21.3 '@babel/template': 7.20.7 - '@babel/traverse': 7.21.2 - '@babel/types': 7.21.2 + '@babel/traverse': 7.21.3 + '@babel/types': 7.21.3 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -1314,11 +1325,11 @@ packages: transitivePeerDependencies: - supports-color - /@babel/generator/7.21.1: - resolution: {integrity: sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==} + /@babel/generator/7.21.3: + resolution: {integrity: sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 '@jridgewell/gen-mapping': 0.3.2 '@jridgewell/trace-mapping': 0.3.17 jsesc: 2.5.2 @@ -1327,7 +1338,7 @@ packages: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: false /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: @@ -1335,29 +1346,29 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: false - /@babel/helper-compilation-targets/7.20.7_@babel+core@7.21.0: + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/compat-data': 7.20.10 - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.5 lru-cache: 5.1.1 semver: 6.3.0 - /@babel/helper-create-class-features-plugin/7.20.12_@babel+core@7.21.0: + /@babel/helper-create-class-features-plugin/7.20.12_@babel+core@7.21.3: resolution: {integrity: sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 @@ -1370,13 +1381,13 @@ packages: - supports-color dev: false - /@babel/helper-create-class-features-plugin/7.20.5_@babel+core@7.21.0: + /@babel/helper-create-class-features-plugin/7.20.5_@babel+core@7.21.3: resolution: {integrity: sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 @@ -1388,24 +1399,24 @@ packages: - supports-color dev: false - /@babel/helper-create-regexp-features-plugin/7.20.5_@babel+core@7.21.0: + /@babel/helper-create-regexp-features-plugin/7.20.5_@babel+core@7.21.3: resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 regexpu-core: 5.2.2 dev: false - /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.21.0: + /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.21.3: resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} peerDependencies: '@babel/core': ^7.4.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 debug: 4.3.4 lodash.debounce: 4.0.8 @@ -1423,7 +1434,7 @@ packages: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: false /@babel/helper-function-name/7.21.0: @@ -1431,26 +1442,26 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.20.7 - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 /@babel/helper-member-expression-to-functions/7.20.7: resolution: {integrity: sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: false /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 /@babel/helper-module-transforms/7.21.2: resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} @@ -1462,8 +1473,8 @@ packages: '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.20.7 - '@babel/traverse': 7.21.2 - '@babel/types': 7.21.2 + '@babel/traverse': 7.21.3 + '@babel/types': 7.21.3 transitivePeerDependencies: - supports-color @@ -1471,7 +1482,7 @@ packages: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: false /@babel/helper-plugin-utils/7.20.2: @@ -1479,17 +1490,17 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.21.0: + /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 transitivePeerDependencies: - supports-color dev: false @@ -1501,8 +1512,8 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-member-expression-to-functions': 7.20.7 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.21.2 - '@babel/types': 7.21.2 + '@babel/traverse': 7.21.3 + '@babel/types': 7.21.3 transitivePeerDependencies: - supports-color dev: false @@ -1515,8 +1526,8 @@ packages: '@babel/helper-member-expression-to-functions': 7.20.7 '@babel/helper-optimise-call-expression': 7.18.6 '@babel/template': 7.20.7 - '@babel/traverse': 7.21.2 - '@babel/types': 7.21.2 + '@babel/traverse': 7.21.3 + '@babel/types': 7.21.3 transitivePeerDependencies: - supports-color dev: false @@ -1525,20 +1536,20 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 /@babel/helper-skip-transparent-expression-wrappers/7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: false /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 /@babel/helper-string-parser/7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} @@ -1558,8 +1569,8 @@ packages: dependencies: '@babel/helper-function-name': 7.21.0 '@babel/template': 7.20.7 - '@babel/traverse': 7.21.2 - '@babel/types': 7.21.2 + '@babel/traverse': 7.21.3 + '@babel/types': 7.21.3 transitivePeerDependencies: - supports-color dev: false @@ -1569,8 +1580,8 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.20.7 - '@babel/traverse': 7.21.2 - '@babel/types': 7.21.2 + '@babel/traverse': 7.21.3 + '@babel/types': 7.21.3 transitivePeerDependencies: - supports-color @@ -1582,411 +1593,411 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser/7.21.2: - resolution: {integrity: sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==} + /@babel/parser/7.21.3: + resolution: {integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.21.0: + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.20.7_@babel+core@7.21.0: + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-async-generator-functions/7.20.7_@babel+core@7.21.0: + /@babel/plugin-proposal-async-generator-functions/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.0 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.3 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-proposal-class-static-block/7.20.7_@babel+core@7.21.0: + /@babel/plugin-proposal-class-static-block/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.21.0 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.21.3 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.21.0: + /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-logical-assignment-operators/7.20.7_@babel+core@7.21.0: + /@babel/plugin-proposal-logical-assignment-operators/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.0 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.0 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-object-rest-spread/7.20.7_@babel+core@7.21.0: + /@babel/plugin-proposal-object-rest-spread/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/compat-data': 7.20.10 - '@babel/core': 7.21.0 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-optional-chaining/7.20.7_@babel+core@7.21.0: + /@babel/plugin-proposal-optional-chaining/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.3 dev: false - /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-proposal-private-property-in-object/7.20.5_@babel+core@7.21.0: + /@babel/plugin-proposal-private-property-in-object/7.20.5_@babel+core@7.21.3: resolution: {integrity: sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.21.0 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.21.3 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.21.0: + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} engines: {node: '>=4'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.21.0: + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.21.3: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.21.0: + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.21.3: resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.21.0: + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.21.3: resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.21.0: + /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.21.3: resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.21.0: + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.21.3: resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.21.0: + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.21.3: resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.21.0: + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.21.3: resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.21.0: + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.21.3: resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.21.0: + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.21.3: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-arrow-functions/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-arrow-functions/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-async-to-generator/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-async-to-generator/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.21.0 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.21.3 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-block-scoping/7.20.14_@babel+core@7.21.0: + /@babel/plugin-transform-block-scoping/7.20.14_@babel+core@7.21.3: resolution: {integrity: sha512-sMPepQtsOs5fM1bwNvuJJHvaCfOEQfmc01FGw0ELlTpTJj5Ql/zuNRRldYhAPys4ghXdBIQJbRVYi44/7QflQQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-classes/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-classes/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.3 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 @@ -1998,121 +2009,121 @@ packages: - supports-color dev: false - /@babel/plugin-transform-computed-properties/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-computed-properties/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 '@babel/template': 7.20.7 dev: false - /@babel/plugin-transform-destructuring/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-destructuring/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.21.0: + /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.21.0: + /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.21.3: resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.21.0: + /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.3 '@babel/helper-function-name': 7.21.0 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-literals/7.18.9_@babel+core@7.21.0: + /@babel/plugin-transform-literals/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-modules-amd/7.20.11_@babel+core@7.21.0: + /@babel/plugin-transform-modules-amd/7.20.11_@babel+core@7.21.3: resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-transform-modules-commonjs/7.20.11_@babel+core@7.21.0: + /@babel/plugin-transform-modules-commonjs/7.20.11_@babel+core@7.21.3: resolution: {integrity: sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-simple-access': 7.20.2 @@ -2120,13 +2131,13 @@ packages: - supports-color dev: false - /@babel/plugin-transform-modules-systemjs/7.20.11_@babel+core@7.21.0: + /@babel/plugin-transform-modules-systemjs/7.20.11_@babel+core@7.21.3: resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 @@ -2135,262 +2146,262 @@ packages: - supports-color dev: false - /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-transform-named-capturing-groups-regex/7.20.5_@babel+core@7.21.0: + /@babel/plugin-transform-named-capturing-groups-regex/7.20.5_@babel+core@7.21.3: resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-replace-supers': 7.19.1 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-transform-parameters/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-parameters/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-regenerator/7.20.5_@babel+core@7.21.0: + /@babel/plugin-transform-regenerator/7.20.5_@babel+core@7.21.3: resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 regenerator-transform: 0.15.1 dev: false - /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-spread/7.20.7_@babel+core@7.21.0: + /@babel/plugin-transform-spread/7.20.7_@babel+core@7.21.3: resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 dev: false - /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.21.0: + /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.21.0: + /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.21.3: resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.21.0: + /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.21.3: resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.21.0: + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.21.3: resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 dev: false - /@babel/preset-env/7.20.2_@babel+core@7.21.0: + /@babel/preset-env/7.20.2_@babel+core@7.21.3: resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/compat-data': 7.20.10 - '@babel/core': 7.21.0 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.3 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-proposal-async-generator-functions': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-class-static-block': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-logical-assignment-operators': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-object-rest-spread': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-proposal-private-property-in-object': 7.20.5_@babel+core@7.21.0 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.0 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.21.0 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.21.0 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.21.0 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.0 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.0 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.0 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.21.0 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.21.0 - '@babel/plugin-transform-arrow-functions': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-async-to-generator': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-block-scoping': 7.20.14_@babel+core@7.21.0 - '@babel/plugin-transform-classes': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-computed-properties': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-destructuring': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.21.0 - '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-modules-amd': 7.20.11_@babel+core@7.21.0 - '@babel/plugin-transform-modules-commonjs': 7.20.11_@babel+core@7.21.0 - '@babel/plugin-transform-modules-systemjs': 7.20.11_@babel+core@7.21.0 - '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5_@babel+core@7.21.0 - '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-regenerator': 7.20.5_@babel+core@7.21.0 - '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-spread': 7.20.7_@babel+core@7.21.0 - '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.21.0 - '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.21.0 - '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.21.0 - '@babel/preset-modules': 0.1.5_@babel+core@7.21.0 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-proposal-async-generator-functions': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-class-static-block': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-logical-assignment-operators': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-object-rest-spread': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-proposal-private-property-in-object': 7.20.5_@babel+core@7.21.3 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.3 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.21.3 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.21.3 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.21.3 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.3 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.3 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.3 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.21.3 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.21.3 + '@babel/plugin-transform-arrow-functions': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-async-to-generator': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-block-scoping': 7.20.14_@babel+core@7.21.3 + '@babel/plugin-transform-classes': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-computed-properties': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-destructuring': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.21.3 + '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-modules-amd': 7.20.11_@babel+core@7.21.3 + '@babel/plugin-transform-modules-commonjs': 7.20.11_@babel+core@7.21.3 + '@babel/plugin-transform-modules-systemjs': 7.20.11_@babel+core@7.21.3 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5_@babel+core@7.21.3 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-regenerator': 7.20.5_@babel+core@7.21.3 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-spread': 7.20.7_@babel+core@7.21.3 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.21.3 + '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.21.3 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.21.3 + '@babel/preset-modules': 0.1.5_@babel+core@7.21.3 '@babel/types': 7.20.7 - babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.21.0 - babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.21.0 - babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.21.0 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.21.3 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.21.3 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.21.3 core-js-compat: 3.27.2 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: false - /@babel/preset-modules/0.1.5_@babel+core@7.21.0: + /@babel/preset-modules/0.1.5_@babel+core@7.21.3: resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.21.0 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.21.0 - '@babel/types': 7.21.2 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.21.3 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.21.3 + '@babel/types': 7.21.3 esutils: 2.0.3 dev: false @@ -2411,21 +2422,21 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 - /@babel/traverse/7.21.2: - resolution: {integrity: sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==} + /@babel/traverse/7.21.3: + resolution: {integrity: sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.21.1 + '@babel/generator': 7.21.3 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -2440,8 +2451,8 @@ packages: to-fast-properties: 2.0.0 dev: false - /@babel/types/7.21.2: - resolution: {integrity: sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==} + /@babel/types/7.21.3: + resolution: {integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.19.4 @@ -2931,13 +2942,28 @@ packages: dev: false optional: true - /@eslint/eslintrc/2.0.0: - resolution: {integrity: sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==} + /@eslint-community/eslint-utils/4.3.0_eslint@8.36.0: + resolution: {integrity: sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.36.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@eslint-community/regexpp/4.4.0: + resolution: {integrity: sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc/2.0.1: + resolution: {integrity: sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.4.0 + espree: 9.5.0 globals: 13.19.0 ignore: 5.2.0 import-fresh: 3.3.0 @@ -2948,8 +2974,8 @@ packages: - supports-color dev: true - /@eslint/js/8.35.0: - resolution: {integrity: sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==} + /@eslint/js/8.36.0: + resolution: {integrity: sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -3045,24 +3071,24 @@ packages: - supports-color dev: false - /@microsoft/api-extractor-model/7.26.4_@types+node@18.14.6: + /@microsoft/api-extractor-model/7.26.4_@types+node@18.15.5: resolution: {integrity: sha512-PDCgCzXDo+SLY5bsfl4bS7hxaeEtnXj7XtuzEE+BtALp7B5mK/NrS2kHWU69pohgsRmEALycQdaQPXoyT2i5MQ==} dependencies: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.1 - '@rushstack/node-core-library': 3.55.2_@types+node@18.14.6 + '@rushstack/node-core-library': 3.55.2_@types+node@18.15.5 transitivePeerDependencies: - '@types/node' dev: true - /@microsoft/api-extractor/7.34.4_@types+node@18.14.6: + /@microsoft/api-extractor/7.34.4_@types+node@18.15.5: resolution: {integrity: sha512-HOdcci2nT40ejhwPC3Xja9G+WSJmWhCUKKryRfQYsmE9cD+pxmBaKBKCbuS9jUcl6bLLb4Gz+h7xEN5r0QiXnQ==} hasBin: true dependencies: - '@microsoft/api-extractor-model': 7.26.4_@types+node@18.14.6 + '@microsoft/api-extractor-model': 7.26.4_@types+node@18.15.5 '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.1 - '@rushstack/node-core-library': 3.55.2_@types+node@18.14.6 + '@rushstack/node-core-library': 3.55.2_@types+node@18.15.5 '@rushstack/rig-package': 0.3.18 '@rushstack/ts-command-line': 4.13.2 colors: 1.2.5 @@ -3151,7 +3177,7 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true - /@rollup/plugin-alias/4.0.3_rollup@3.18.0: + /@rollup/plugin-alias/4.0.3_rollup@3.20.0: resolution: {integrity: sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3160,11 +3186,11 @@ packages: rollup: optional: true dependencies: - rollup: 3.18.0 + rollup: 3.20.0 slash: 4.0.0 dev: true - /@rollup/plugin-commonjs/24.0.1_rollup@3.18.0: + /@rollup/plugin-commonjs/24.0.1_rollup@3.20.0: resolution: {integrity: sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3173,16 +3199,16 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.0.3 is-reference: 1.2.1 magic-string: 0.27.0 - rollup: 3.18.0 + rollup: 3.20.0 dev: true - /@rollup/plugin-dynamic-import-vars/2.0.3_rollup@3.18.0: + /@rollup/plugin-dynamic-import-vars/2.0.3_rollup@3.20.0: resolution: {integrity: sha512-0zQV0TDDewilU+7ZLmwc0u44SkeRxSxMdINBuX5isrQGJ6EdTjVL1TcnOZ9In99byaSGAQnHmSFw+6hm0E/jrw==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3191,14 +3217,14 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 estree-walker: 2.0.2 fast-glob: 3.2.12 magic-string: 0.27.0 - rollup: 3.18.0 + rollup: 3.20.0 dev: true - /@rollup/plugin-json/6.0.0_rollup@3.18.0: + /@rollup/plugin-json/6.0.0_rollup@3.20.0: resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3207,11 +3233,11 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 - rollup: 3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + rollup: 3.20.0 dev: true - /@rollup/plugin-node-resolve/15.0.1_rollup@3.18.0: + /@rollup/plugin-node-resolve/15.0.1_rollup@3.20.0: resolution: {integrity: sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3220,16 +3246,16 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 '@types/resolve': 1.20.2 deepmerge: 4.2.2 is-builtin-module: 3.2.0 is-module: 1.0.0 resolve: 1.22.1 - rollup: 3.18.0 + rollup: 3.20.0 dev: true - /@rollup/plugin-replace/5.0.2_rollup@3.18.0: + /@rollup/plugin-replace/5.0.2_rollup@3.20.0: resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3238,12 +3264,12 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 magic-string: 0.27.0 - rollup: 3.18.0 + rollup: 3.20.0 dev: true - /@rollup/plugin-typescript/11.0.0_rollup@3.18.0+tslib@2.5.0: + /@rollup/plugin-typescript/11.0.0_7sniqkrn5rmxrmax2dmiqcv3qu: resolution: {integrity: sha512-goPyCWBiimk1iJgSTgsehFD5OOFHiAknrRJjqFCudcW8JtWiBlK284Xnn4flqMqg6YAjVG/EE+3aVzrL5qNSzQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3256,13 +3282,14 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 resolve: 1.22.1 - rollup: 3.18.0 + rollup: 3.20.0 tslib: 2.5.0 + typescript: 5.0.2 dev: true - /@rollup/plugin-typescript/11.0.0_taeyxmvmc26umlo2so2an3i7iy: + /@rollup/plugin-typescript/11.0.0_rollup@3.20.0+tslib@2.5.0: resolution: {integrity: sha512-goPyCWBiimk1iJgSTgsehFD5OOFHiAknrRJjqFCudcW8JtWiBlK284Xnn4flqMqg6YAjVG/EE+3aVzrL5qNSzQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3275,14 +3302,13 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 resolve: 1.22.1 - rollup: 3.18.0 + rollup: 3.20.0 tslib: 2.5.0 - typescript: 5.0.2 dev: true - /@rollup/pluginutils/5.0.2_rollup@3.18.0: + /@rollup/pluginutils/5.0.2_rollup@3.20.0: resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3294,10 +3320,10 @@ packages: '@types/estree': 1.0.0 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.18.0 + rollup: 3.20.0 dev: true - /@rushstack/node-core-library/3.55.2_@types+node@18.14.6: + /@rushstack/node-core-library/3.55.2_@types+node@18.15.5: resolution: {integrity: sha512-SaLe/x/Q/uBVdNFK5V1xXvsVps0y7h1sN7aSJllQyFbugyOaxhNRF25bwEDnicARNEjJw0pk0lYnJQ9Kr6ev0A==} peerDependencies: '@types/node': '*' @@ -3305,7 +3331,7 @@ packages: '@types/node': optional: true dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 colors: 1.2.5 fs-extra: 7.0.1 import-lazy: 4.0.0 @@ -3354,8 +3380,8 @@ packages: /@types/babel__core/7.20.0: resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} dependencies: - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.17.1 @@ -3364,13 +3390,13 @@ packages: /@types/babel__generator/7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: true /@types/babel__standalone/7.1.4: resolution: {integrity: sha512-HijIDmcNl3Wmo0guqjYkQvMzyRCM6zMCkYcdG8f+2X7mPBNa9ikSeaQlWs2Yg18KN1klOJzyupX5BPOf+7ahaw==} dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 transitivePeerDependencies: - supports-color dev: true @@ -3378,14 +3404,14 @@ packages: /@types/babel__template/7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 dev: true /@types/babel__traverse/7.17.1: resolution: {integrity: sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: true /@types/braces/3.0.1: @@ -3409,7 +3435,7 @@ packages: /@types/cross-spawn/6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true /@types/debug/4.1.7: @@ -3425,14 +3451,14 @@ packages: /@types/etag/1.8.1: resolution: {integrity: sha512-bsKkeSqN7HYyYntFRAmzcwx/dKW4Wa+KVMTInANlI72PWLQmOpZu96j0OqHZGArW4VQwCmJPteQlXaUDeOB0WQ==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true /@types/fs-extra/11.0.1: resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} dependencies: '@types/jsonfile': 6.1.1 - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true /@types/json-schema/7.0.11: @@ -3450,7 +3476,7 @@ packages: /@types/jsonfile/6.1.1: resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true /@types/less/3.0.3: @@ -3479,8 +3505,8 @@ packages: resolution: {integrity: sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==} dev: true - /@types/node/18.14.6: - resolution: {integrity: sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA==} + /@types/node/18.15.5: + resolution: {integrity: sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==} dev: true /@types/normalize-package-data/2.4.1: @@ -3491,10 +3517,14 @@ packages: resolution: {integrity: sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g==} dev: true + /@types/pnpapi/0.0.2: + resolution: {integrity: sha512-2lqsQt1iXkiTqwuzw2SS50iduoPZNpV/ou4/vJD443C0weF63Gqd3ErGS811CBNMzLO64zVJ+tiyh+4yimdYkg==} + dev: true + /@types/prompts/2.4.2: resolution: {integrity: sha512-TwNx7qsjvRIUv/BCx583tqF5IINEVjCNqg9ofKHRlSoUHE62WBHrem4B1HGXcIrG511v29d1kJ9a/t2Esz7MIg==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 kleur: 3.0.3 dev: true @@ -3505,7 +3535,7 @@ packages: /@types/sass/1.43.1: resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true /@types/semver/7.3.13: @@ -3519,7 +3549,7 @@ packages: /@types/stylus/0.48.38: resolution: {integrity: sha512-B5otJekvD6XM8iTrnO6e2twoTY2tKL9VkL/57/2Lo4tv3EatbCaufdi68VVtn/h4yjO+HVvYEyrNQd0Lzj6riw==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true /@types/web-bluetooth/0.0.16: @@ -3529,11 +3559,11 @@ packages: /@types/ws/8.5.4: resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} dependencies: - '@types/node': 18.14.6 + '@types/node': 18.15.5 dev: true - /@typescript-eslint/eslint-plugin/5.54.1_ptmzjahj2lzv7vrsfzwjsq4mpu: - resolution: {integrity: sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew==} + /@typescript-eslint/eslint-plugin/5.56.0_2hcjazgfnbtq42tcc73br2vup4: + resolution: {integrity: sha512-ZNW37Ccl3oMZkzxrYDUX4o7cnuPgU+YrcaYXzsRtLB16I1FR5SHMqga3zGsaSliZADCWo2v8qHWqAYIj8nWCCg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -3543,16 +3573,16 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.54.1_byynos7ffx3cepxtk6gvolkky4 - '@typescript-eslint/scope-manager': 5.54.1 - '@typescript-eslint/type-utils': 5.54.1_byynos7ffx3cepxtk6gvolkky4 - '@typescript-eslint/utils': 5.54.1_byynos7ffx3cepxtk6gvolkky4 + '@eslint-community/regexpp': 4.4.0 + '@typescript-eslint/parser': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu + '@typescript-eslint/scope-manager': 5.56.0 + '@typescript-eslint/type-utils': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu + '@typescript-eslint/utils': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu debug: 4.3.4 - eslint: 8.35.0 + eslint: 8.36.0 grapheme-splitter: 1.0.4 ignore: 5.2.0 natural-compare-lite: 1.4.0 - regexpp: 3.2.0 semver: 7.3.8 tsutils: 3.21.0_typescript@5.0.2 typescript: 5.0.2 @@ -3560,8 +3590,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.54.1_byynos7ffx3cepxtk6gvolkky4: - resolution: {integrity: sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg==} + /@typescript-eslint/parser/5.56.0_j4766f7ecgqbon3u7zlxn5zszu: + resolution: {integrity: sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3570,26 +3600,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.54.1 - '@typescript-eslint/types': 5.54.1 - '@typescript-eslint/typescript-estree': 5.54.1_typescript@5.0.2 + '@typescript-eslint/scope-manager': 5.56.0 + '@typescript-eslint/types': 5.56.0 + '@typescript-eslint/typescript-estree': 5.56.0_typescript@5.0.2 debug: 4.3.4 - eslint: 8.35.0 + eslint: 8.36.0 typescript: 5.0.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.54.1: - resolution: {integrity: sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg==} + /@typescript-eslint/scope-manager/5.56.0: + resolution: {integrity: sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.54.1 - '@typescript-eslint/visitor-keys': 5.54.1 + '@typescript-eslint/types': 5.56.0 + '@typescript-eslint/visitor-keys': 5.56.0 dev: true - /@typescript-eslint/type-utils/5.54.1_byynos7ffx3cepxtk6gvolkky4: - resolution: {integrity: sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g==} + /@typescript-eslint/type-utils/5.56.0_j4766f7ecgqbon3u7zlxn5zszu: + resolution: {integrity: sha512-8WxgOgJjWRy6m4xg9KoSHPzBNZeQbGlQOH7l2QEhQID/+YseaFxg5J/DLwWSsi9Axj4e/cCiKx7PVzOq38tY4A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -3598,23 +3628,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.54.1_typescript@5.0.2 - '@typescript-eslint/utils': 5.54.1_byynos7ffx3cepxtk6gvolkky4 + '@typescript-eslint/typescript-estree': 5.56.0_typescript@5.0.2 + '@typescript-eslint/utils': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu debug: 4.3.4 - eslint: 8.35.0 + eslint: 8.36.0 tsutils: 3.21.0_typescript@5.0.2 typescript: 5.0.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.54.1: - resolution: {integrity: sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw==} + /@typescript-eslint/types/5.56.0: + resolution: {integrity: sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.54.1_typescript@5.0.2: - resolution: {integrity: sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg==} + /@typescript-eslint/typescript-estree/5.56.0_typescript@5.0.2: + resolution: {integrity: sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -3622,8 +3652,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.54.1 - '@typescript-eslint/visitor-keys': 5.54.1 + '@typescript-eslint/types': 5.56.0 + '@typescript-eslint/visitor-keys': 5.56.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -3634,36 +3664,36 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.54.1_byynos7ffx3cepxtk6gvolkky4: - resolution: {integrity: sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ==} + /@typescript-eslint/utils/5.56.0_j4766f7ecgqbon3u7zlxn5zszu: + resolution: {integrity: sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: + '@eslint-community/eslint-utils': 4.3.0_eslint@8.36.0 '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.54.1 - '@typescript-eslint/types': 5.54.1 - '@typescript-eslint/typescript-estree': 5.54.1_typescript@5.0.2 - eslint: 8.35.0 + '@typescript-eslint/scope-manager': 5.56.0 + '@typescript-eslint/types': 5.56.0 + '@typescript-eslint/typescript-estree': 5.56.0_typescript@5.0.2 + eslint: 8.36.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.35.0 semver: 7.3.8 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.54.1: - resolution: {integrity: sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg==} + /@typescript-eslint/visitor-keys/5.56.0: + resolution: {integrity: sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.54.1 + '@typescript-eslint/types': 5.56.0 eslint-visitor-keys: 3.3.0 dev: true - /@vitejs/plugin-vue/4.0.0_5qyuox3n3rizckhh25uzvv7zgq: - resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==} + /@vitejs/plugin-vue/4.1.0_5qyuox3n3rizckhh25uzvv7zgq: + resolution: {integrity: sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.0.0 @@ -3673,8 +3703,8 @@ packages: vue: 3.2.47 dev: true - /@vitejs/plugin-vue/4.0.0_vue@3.2.47: - resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==} + /@vitejs/plugin-vue/4.1.0_vue@3.2.47: + resolution: {integrity: sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.0.0 @@ -3683,42 +3713,41 @@ packages: vue: 3.2.47 dev: true - /@vitest/expect/0.29.2: - resolution: {integrity: sha512-wjrdHB2ANTch3XKRhjWZN0UueFocH0cQbi2tR5Jtq60Nb3YOSmakjdAvUa2JFBu/o8Vjhj5cYbcMXkZxn1NzmA==} + /@vitest/expect/0.29.7: + resolution: {integrity: sha512-UtG0tW0DP6b3N8aw7PHmweKDsvPv4wjGvrVZW7OSxaFg76ShtVdMiMcUkZJgCE8QWUmhwaM0aQhbbVLo4F4pkA==} dependencies: - '@vitest/spy': 0.29.2 - '@vitest/utils': 0.29.2 + '@vitest/spy': 0.29.7 + '@vitest/utils': 0.29.7 chai: 4.3.7 dev: true - /@vitest/runner/0.29.2: - resolution: {integrity: sha512-A1P65f5+6ru36AyHWORhuQBJrOOcmDuhzl5RsaMNFe2jEkoj0faEszQS4CtPU/LxUYVIazlUtZTY0OEZmyZBnA==} + /@vitest/runner/0.29.7: + resolution: {integrity: sha512-Yt0+csM945+odOx4rjZSjibQfl2ymxqVsmYz6sO2fiO5RGPYDFCo60JF6tLL9pz4G/kjY4irUxadeB1XT+H1jg==} dependencies: - '@vitest/utils': 0.29.2 + '@vitest/utils': 0.29.7 p-limit: 4.0.0 pathe: 1.1.0 dev: true - /@vitest/spy/0.29.2: - resolution: {integrity: sha512-Hc44ft5kaAytlGL2PyFwdAsufjbdOvHklwjNy/gy/saRbg9Kfkxfh+PklLm1H2Ib/p586RkQeNFKYuJInUssyw==} + /@vitest/spy/0.29.7: + resolution: {integrity: sha512-IalL0iO6A6Xz8hthR8sctk6ZS//zVBX48EiNwQguYACdgdei9ZhwMaBFV70mpmeYAFCRAm+DpoFHM5470Im78A==} dependencies: tinyspy: 1.0.2 dev: true - /@vitest/utils/0.29.2: - resolution: {integrity: sha512-F14/Uc+vCdclStS2KEoXJlOLAEyqRhnw0gM27iXw9bMTcyKRPJrQ+rlC6XZ125GIPvvKYMPpVxNhiou6PsEeYQ==} + /@vitest/utils/0.29.7: + resolution: {integrity: sha512-vNgGadp2eE5XKCXtZXL5UyNEDn68npSct75OC9AlELenSK0DiV1Mb9tfkwJHKjRb69iek+e79iipoJx8+s3SdA==} dependencies: cli-truncate: 3.1.0 diff: 5.1.0 loupe: 2.3.6 - picocolors: 1.0.0 pretty-format: 27.5.1 dev: true /@vue/compiler-core/3.2.47: resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==} dependencies: - '@babel/parser': 7.21.2 + '@babel/parser': 7.21.3 '@vue/shared': 3.2.47 estree-walker: 2.0.2 source-map: 0.6.1 @@ -3732,7 +3761,7 @@ packages: /@vue/compiler-sfc/3.2.47: resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==} dependencies: - '@babel/parser': 7.21.2 + '@babel/parser': 7.21.3 '@vue/compiler-core': 3.2.47 '@vue/compiler-dom': 3.2.47 '@vue/compiler-ssr': 3.2.47 @@ -3764,7 +3793,7 @@ packages: /@vue/reactivity-transform/3.2.47: resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==} dependencies: - '@babel/parser': 7.21.2 + '@babel/parser': 7.21.3 '@vue/compiler-core': 3.2.47 '@vue/shared': 3.2.47 estree-walker: 2.0.2 @@ -4098,15 +4127,15 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /autoprefixer/10.4.13: - resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} + /autoprefixer/10.4.14: + resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: browserslist: 4.21.5 - caniuse-lite: 1.0.30001427 + caniuse-lite: 1.0.30001468 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -4128,38 +4157,38 @@ packages: - debug dev: false - /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.21.0: + /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.21.3: resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/compat-data': 7.20.10 - '@babel/core': 7.21.0 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.3 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: false - /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.21.0: + /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.21.3: resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.3 core-js-compat: 3.27.2 transitivePeerDependencies: - supports-color dev: false - /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.21.0: + /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.21.3: resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.0 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + '@babel/core': 7.21.3 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.3 transitivePeerDependencies: - supports-color dev: false @@ -4168,7 +4197,7 @@ packages: resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} engines: {node: '>= 10.0.0'} dependencies: - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 dev: true /balanced-match/1.0.2: @@ -4304,13 +4333,13 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite/1.0.30001427: - resolution: {integrity: sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==} - dev: false - /caniuse-lite/1.0.30001457: resolution: {integrity: sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==} + /caniuse-lite/1.0.30001468: + resolution: {integrity: sha512-zgAo8D5kbOyUcRAgSmgyuvBkjrGk5CGYG5TYgFdpQv+ywcyEpo1LOWoG8YmoflGnh+V+UsNuKYedsoYs0hzV5A==} + dev: false + /chai/4.3.7: resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} engines: {node: '>=4'} @@ -4355,7 +4384,7 @@ packages: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true - /chokidar/3.5.3: + /chokidar/3.5.3_dzxbf3kgof5pdmbsyih2x43sq4: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} dependencies: @@ -4368,6 +4397,7 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.2 + patched: true /chownr/2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} @@ -4481,6 +4511,11 @@ packages: delayed-stream: 1.0.0 dev: false + /commander/10.0.0: + resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} + engines: {node: '>=14'} + dev: true + /commander/2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} requiresBuild: true @@ -4491,11 +4526,6 @@ packages: engines: {node: '>= 10'} dev: true - /commander/9.4.1: - resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} - engines: {node: ^12.20.0 || >=14} - dev: true - /comment-parser/1.3.1: resolution: {integrity: sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==} engines: {node: '>= 12.0.0'} @@ -4557,8 +4587,8 @@ packages: /constantinople/4.0.1: resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} dependencies: - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 dev: true /content-disposition/0.5.4: @@ -4760,8 +4790,8 @@ packages: browserslist: 4.21.5 dev: false - /core-js/3.29.0: - resolution: {integrity: sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==} + /core-js/3.29.1: + resolution: {integrity: sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==} requiresBuild: true dev: false @@ -5104,7 +5134,7 @@ packages: is-string: 1.0.7 is-typed-array: 1.1.10 is-weakref: 1.0.2 - object-inspect: 1.12.2 + object-inspect: 1.12.3 object-keys: 1.1.1 object.assign: 4.1.4 regexp.prototype.flags: 1.4.3 @@ -5455,8 +5485,8 @@ packages: engines: {node: '>=10'} dev: true - /eslint-define-config/1.15.0: - resolution: {integrity: sha512-p6K61L6HrnDNRF2HzUsTdGaGPohO0TmSX/oQ0ttBhfApWHMyDcX+FCqSziCDywSf0U0bxe4e2HOfYho1nGHTLw==} + /eslint-define-config/1.17.0: + resolution: {integrity: sha512-J1sweMoWsLcokaiAlfOCC4yMoHbvC/kDAxorm5TkUcD74w+kauMIyjKLM3dOadNxVKOjDiYN1Tu2x9N+4EUuuQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13', pnpm: '>= 7.0.0'} dev: true @@ -5470,7 +5500,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_spn4godk7g7ml4zhqabnc6rdgi: + /eslint-module-utils/2.7.4_tf7h2azriypc3gaglz256o6pea: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -5491,26 +5521,26 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.54.1_byynos7ffx3cepxtk6gvolkky4 + '@typescript-eslint/parser': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu debug: 3.2.7 - eslint: 8.35.0 + eslint: 8.36.0 eslint-import-resolver-node: 0.3.7 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-es/3.0.1_eslint@8.35.0: + /eslint-plugin-es/3.0.1_eslint@8.36.0: resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.35.0 + eslint: 8.36.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-import/2.27.5_uyiasnnzcqrxqkfvjklwnmwcha: + /eslint-plugin-import/2.27.5_cnkxirszkzb4o6ts7gbclno24e: resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: @@ -5520,15 +5550,15 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.54.1_byynos7ffx3cepxtk6gvolkky4 + '@typescript-eslint/parser': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.35.0 + eslint: 8.36.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4_spn4godk7g7ml4zhqabnc6rdgi + eslint-module-utils: 2.7.4_tf7h2azriypc3gaglz256o6pea has: 1.0.3 is-core-module: 2.11.0 is-glob: 4.0.3 @@ -5543,14 +5573,14 @@ packages: - supports-color dev: true - /eslint-plugin-node/11.1.0_eslint@8.35.0: + /eslint-plugin-node/11.1.0_eslint@8.36.0: resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=5.16.0' dependencies: - eslint: 8.35.0 - eslint-plugin-es: 3.0.1_eslint@8.35.0 + eslint: 8.36.0 + eslint-plugin-es: 3.0.1_eslint@8.36.0 eslint-utils: 2.1.0 ignore: 5.2.0 minimatch: 3.1.2 @@ -5558,20 +5588,20 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-regexp/1.12.0_eslint@8.35.0: - resolution: {integrity: sha512-A1lnzOqHC22Ve8PZJgcw5pDHk5Sxp7J/pY86u027lVEGpUwe7dhZVVsy3SCm/cN438Zts8e9c09KGIVK4IixuA==} + /eslint-plugin-regexp/1.13.0_eslint@8.36.0: + resolution: {integrity: sha512-MAyx+n+gmkuK2kWPHoSITi+r8eEK9oCYEx4yrKwpePSzklsdEm5afDHVAjl7VEY0OZ/2iEi9jsxJwPpcgFbt+A==} engines: {node: ^12 || >=14} peerDependencies: eslint: '>=6.0.0' dependencies: + '@eslint-community/eslint-utils': 4.3.0_eslint@8.36.0 + '@eslint-community/regexpp': 4.4.0 comment-parser: 1.3.1 - eslint: 8.35.0 - eslint-utils: 3.0.0_eslint@8.35.0 + eslint: 8.36.0 grapheme-splitter: 1.0.4 jsdoctypeparser: 9.0.0 refa: 0.9.1 regexp-ast-analysis: 0.5.1 - regexpp: 3.2.0 scslre: 0.1.6 dev: true @@ -5598,38 +5628,25 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.35.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 8.35.0 - eslint-visitor-keys: 2.1.0 - dev: true - /eslint-visitor-keys/1.3.0: resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} engines: {node: '>=4'} dev: true - /eslint-visitor-keys/2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - dev: true - /eslint-visitor-keys/3.3.0: resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.35.0: - resolution: {integrity: sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==} + /eslint/8.36.0: + resolution: {integrity: sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 2.0.0 - '@eslint/js': 8.35.0 + '@eslint-community/eslint-utils': 4.3.0_eslint@8.36.0 + '@eslint-community/regexpp': 4.4.0 + '@eslint/eslintrc': 2.0.1 + '@eslint/js': 8.36.0 '@humanwhocodes/config-array': 0.11.8 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -5640,9 +5657,8 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.35.0 eslint-visitor-keys: 3.3.0 - espree: 9.4.0 + espree: 9.5.0 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -5664,7 +5680,6 @@ packages: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.1 - regexpp: 3.2.0 strip-ansi: 6.0.1 strip-json-comments: 3.1.1 text-table: 0.2.0 @@ -5672,8 +5687,8 @@ packages: - supports-color dev: true - /espree/9.4.0: - resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==} + /espree/9.5.0: + resolution: {integrity: sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.8.2 @@ -5731,23 +5746,8 @@ packages: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: true - /execa/6.1.0: - resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 3.0.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - dev: true - - /execa/7.0.0: - resolution: {integrity: sha512-tQbH0pH/8LHTnwTrsKWideqi6rFB/QNUawEwrn+WHyz7PX1Tuz2u7wfTvbaNBdP5JD5LVWxNo8/A8CHNZ3bV6g==} + /execa/7.1.1: + resolution: {integrity: sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==} engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} dependencies: cross-spawn: 7.0.3 @@ -5980,8 +5980,8 @@ packages: resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} engines: {node: '>= 0.6'} - /fs-extra/11.1.0: - resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} + /fs-extra/11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} dependencies: graceful-fs: 4.2.10 @@ -6173,6 +6173,16 @@ packages: once: 1.4.0 dev: true + /glob/9.3.1: + resolution: {integrity: sha512-qERvJb7IGsnkx6YYmaaGvDpf77c951hICMdWaFXyH3PlVob8sbPJJyJX0kWkiCWyXUzoy9UOTNjGg0RbD8bYIw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + fs.realpath: 1.0.0 + minimatch: 7.4.2 + minipass: 4.2.5 + path-scurry: 1.6.1 + dev: true + /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -6356,11 +6366,6 @@ packages: - supports-color dev: false - /human-signals/3.0.1: - resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==} - engines: {node: '>=12.20.0'} - dev: true - /human-signals/4.3.0: resolution: {integrity: sha512-zyzVyMjpGBX2+6cDVZeFPCdtOtdsxOeseRhB9tkQ6xXmGUNrcnBzdEKPy3VPNYz+4gy1oukVOXcrJCunSyc6QQ==} engines: {node: '>=14.18.0'} @@ -6887,35 +6892,39 @@ packages: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} + /lilconfig/2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + /lines-and-columns/1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /lint-staged/13.1.2: - resolution: {integrity: sha512-K9b4FPbWkpnupvK3WXZLbgu9pchUJ6N7TtVZjbaPsoizkqFUDkUReUL25xdrCljJs7uLUF3tZ7nVPeo/6lp+6w==} + /lint-staged/13.2.0: + resolution: {integrity: sha512-GbyK5iWinax5Dfw5obm2g2ccUiZXNGtAS4mCbJ0Lv4rq6iEtfBSjOYdcbOtAIFtM114t0vdpViDDetjVTSd8Vw==} engines: {node: ^14.13.1 || >=16.0.0} hasBin: true dependencies: + chalk: 5.2.0 cli-truncate: 3.1.0 - colorette: 2.0.19 - commander: 9.4.1 + commander: 10.0.0 debug: 4.3.4 - execa: 6.1.0 - lilconfig: 2.0.6 - listr2: 5.0.5 + execa: 7.1.1 + lilconfig: 2.1.0 + listr2: 5.0.8 micromatch: 4.0.5 normalize-path: 3.0.0 - object-inspect: 1.12.2 + object-inspect: 1.12.3 pidtree: 0.6.0 string-argv: 0.3.1 - yaml: 2.1.3 + yaml: 2.2.1 transitivePeerDependencies: - enquirer - supports-color dev: true - /listr2/5.0.5: - resolution: {integrity: sha512-DpBel6fczu7oQKTXMekeprc0o3XDgGMkD7JNYyX+X0xbwK+xgrx9dcyKoXKqpLSUvAWfmoePS7kavniOcq3r4w==} + /listr2/5.0.8: + resolution: {integrity: sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==} engines: {node: ^14.13.1 || >=16.0.0} peerDependencies: enquirer: '>= 2.3.0 < 3' @@ -6928,7 +6937,7 @@ packages: log-update: 4.0.0 p-map: 4.0.0 rfdc: 1.3.0 - rxjs: 7.5.7 + rxjs: 7.8.0 through: 2.3.8 wrap-ansi: 7.0.0 dev: true @@ -7056,6 +7065,11 @@ packages: dependencies: yallist: 4.0.0 + /lru-cache/7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: true + /magic-string/0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: @@ -7216,7 +7230,7 @@ packages: '@iarna/toml': 2.2.5 '@mrbbot/node-fetch': 4.6.0 '@peculiar/webcrypto': 1.3.3 - chokidar: 3.5.3 + chokidar: 3.5.3_dzxbf3kgof5pdmbsyih2x43sq4 cjstoesm: 1.1.4_typescript@4.6.4 dotenv: 8.6.0 env-paths: 2.2.1 @@ -7258,6 +7272,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch/7.4.2: + resolution: {integrity: sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist-options/4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -7277,6 +7298,11 @@ packages: yallist: 4.0.0 dev: false + /minipass/4.2.5: + resolution: {integrity: sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==} + engines: {node: '>=8'} + dev: true + /minizlib/2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -7304,7 +7330,7 @@ packages: dependencies: defu: 6.1.2 esbuild: 0.17.10 - fs-extra: 11.1.0 + fs-extra: 11.1.1 globby: 13.1.3 jiti: 1.17.1 mri: 1.2.0 @@ -7312,12 +7338,12 @@ packages: typescript: 4.9.5 dev: true - /mlly/1.1.1: - resolution: {integrity: sha512-Jnlh4W/aI4GySPo6+DyTN17Q75KKbLTyFK8BrGhjNP4rxuUjbRWhE6gHg3bs33URWAF44FRm7gdQA348i3XxRw==} + /mlly/1.2.0: + resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==} dependencies: acorn: 8.8.2 pathe: 1.1.0 - pkg-types: 1.0.1 + pkg-types: 1.0.2 ufo: 1.1.1 dev: true @@ -7341,7 +7367,7 @@ packages: dev: true /ms/2.0.0: - resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -7427,8 +7453,8 @@ packages: whatwg-url: 5.0.0 dev: false - /node-fetch/3.3.0: - resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==} + /node-fetch/3.3.1: + resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: data-uri-to-buffer: 4.0.0 @@ -7524,8 +7550,8 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - /object-inspect/1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + /object-inspect/1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} /object-keys/1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -7762,6 +7788,14 @@ packages: /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + /path-scurry/1.6.1: + resolution: {integrity: sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==} + engines: {node: '>=14'} + dependencies: + lru-cache: 7.18.3 + minipass: 4.2.5 + dev: true + /path-to-regexp/0.1.7: resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} @@ -7793,8 +7827,8 @@ packages: is-reference: 3.0.0 dev: true - /phoenix/1.7.1: - resolution: {integrity: sha512-DORpAOHp8XdQDs6WT2yD65fhUQXhzrD+CTZCKqWQ9g0G/fyM8EKsSDhtOwl54Nr2DDBu8JARMR97OfLYCiKAoQ==} + /phoenix/1.7.2: + resolution: {integrity: sha512-jwWDOsUNEQZkLNSwzfLJ6AMFUkyZ+ILU+NkBBtoAK020QPpV/dYEQHGMQoFScj89MFjJlLdkE1W97i8S+4FdGg==} dev: false /picocolors/1.0.0: @@ -7831,19 +7865,11 @@ packages: dev: true optional: true - /pkg-types/1.0.1: - resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==} - dependencies: - jsonc-parser: 3.2.0 - mlly: 1.1.1 - pathe: 1.1.0 - dev: true - /pkg-types/1.0.2: resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==} dependencies: jsonc-parser: 3.2.0 - mlly: 1.1.1 + mlly: 1.2.0 pathe: 1.1.0 dev: true @@ -7906,7 +7932,7 @@ packages: ts-node: optional: true dependencies: - lilconfig: 2.0.6 + lilconfig: 2.1.0 postcss: 8.4.21 ts-node: 10.9.1 yaml: 1.10.2 @@ -7924,7 +7950,7 @@ packages: ts-node: optional: true dependencies: - lilconfig: 2.0.6 + lilconfig: 2.1.0 postcss: 8.4.21 yaml: 1.10.2 @@ -8510,13 +8536,15 @@ packages: dependencies: glob: 7.2.0 - /rimraf/4.1.2: - resolution: {integrity: sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==} + /rimraf/4.4.0: + resolution: {integrity: sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==} engines: {node: '>=14'} hasBin: true + dependencies: + glob: 9.3.1 dev: true - /rollup-plugin-dts/5.3.0_fn2onl6nbsljlgjr3jlzr6w7we: + /rollup-plugin-dts/5.3.0_pn5zetjg24cqcolt42iry5qj6a: resolution: {integrity: sha512-8FXp0ZkyZj1iU5klkIJYLjIq/YZSwBoERu33QBDxm/1yw5UU4txrEtcmMkrq+ZiKu3Q4qvPCNqc3ovX6rjqzbQ==} engines: {node: '>=v14'} peerDependencies: @@ -8524,13 +8552,13 @@ packages: typescript: ^4.1 || ^5.0 dependencies: magic-string: 0.30.0 - rollup: 3.18.0 + rollup: 3.20.0 typescript: 4.9.5 optionalDependencies: '@babel/code-frame': 7.18.6 dev: true - /rollup-plugin-license/3.0.1_rollup@3.18.0: + /rollup-plugin-license/3.0.1_rollup@3.20.0: resolution: {integrity: sha512-/lec6Y94Y3wMfTDeYTO/jSXII0GQ/XkDZCiqkMKxyU5D5nGPaxr/2JNYvAgYsoCYuOLGOanKDPjCCQiTT96p7A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -8543,13 +8571,13 @@ packages: mkdirp: 1.0.4 moment: 2.29.3 package-name-regex: 2.0.6 - rollup: 3.18.0 + rollup: 3.20.0 spdx-expression-validate: 2.0.0 spdx-satisfies: 5.0.1 dev: true - /rollup/3.18.0: - resolution: {integrity: sha512-J8C6VfEBjkvYPESMQYxKHxNOh4A5a3FlP+0BETGo34HEcE4eTlgCrO2+eWzlu2a/sHs2QUkZco+wscH7jhhgWg==} + /rollup/3.20.0: + resolution: {integrity: sha512-YsIfrk80NqUDrxrjWPXUa7PWvAfegZEXHuPsEZg58fGCdjL1I9C1i/NaG+L+27kxxwkrG/QEDEQc8s/ynXWWGQ==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -8560,8 +8588,8 @@ packages: dependencies: queue-microtask: 1.2.3 - /rxjs/7.5.7: - resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} + /rxjs/7.8.0: + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} dependencies: tslib: 2.5.0 dev: true @@ -8590,12 +8618,12 @@ packages: truncate-utf8-bytes: 1.0.2 dev: true - /sass/1.58.3: - resolution: {integrity: sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==} + /sass/1.59.3: + resolution: {integrity: sha512-QCq98N3hX1jfTCoUAsF3eyGuXLsY7BCnCEg9qAact94Yc21npG2/mVOqoDvE0fCbWDqiM4WlcJQla0gWG2YlxQ==} engines: {node: '>=12.0.0'} hasBin: true dependencies: - chokidar: 3.5.3 + chokidar: 3.5.3_dzxbf3kgof5pdmbsyih2x43sq4 immutable: 4.0.0 source-map-js: 1.0.2 dev: true @@ -8737,7 +8765,7 @@ packages: dependencies: call-bind: 1.0.2 get-intrinsic: 1.1.3 - object-inspect: 1.12.2 + object-inspect: 1.12.3 /siginfo/2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -9073,7 +9101,7 @@ packages: hasBin: true dependencies: arg: 5.0.2 - chokidar: 3.5.3 + chokidar: 3.5.3_dzxbf3kgof5pdmbsyih2x43sq4 color-name: 1.1.4 detective: 5.2.1 didyoumean: 1.2.2 @@ -9104,7 +9132,7 @@ packages: hasBin: true dependencies: arg: 5.0.2 - chokidar: 3.5.3 + chokidar: 3.5.3_dzxbf3kgof5pdmbsyih2x43sq4 color-name: 1.1.4 detective: 5.2.1 didyoumean: 1.2.2 @@ -9155,8 +9183,8 @@ packages: uuid: 3.4.0 dev: true - /terser/5.16.5: - resolution: {integrity: sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==} + /terser/5.16.6: + resolution: {integrity: sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -9200,8 +9228,8 @@ packages: resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==} dev: true - /tinypool/0.3.1: - resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} + /tinypool/0.4.0: + resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==} engines: {node: '>=14.0.0'} dev: true @@ -9283,8 +9311,8 @@ packages: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - /tsconfck/2.1.0: - resolution: {integrity: sha512-lztI9ohwclQHISVWrM/hlcgsRpphsii94DV9AQtAw2XJSVNiv+3ppdEsrL5J+xc5oTeHXe1qDqlOAGw8VSa9+Q==} + /tsconfck/2.1.1: + resolution: {integrity: sha512-ZPCkJBKASZBmBUNqGHmRhdhM8pJYDdOXp4nRgj/O0JwUwsMq50lCDRQP/M5GBNAA0elPrq4gAeu4dkaVCuKWww==} engines: {node: ^14.13.1 || ^16 || >=18} hasBin: true peerDependencies: @@ -9321,8 +9349,8 @@ packages: typescript: 5.0.2 dev: true - /tsx/3.12.3: - resolution: {integrity: sha512-Wc5BFH1xccYTXaQob+lEcimkcb/Pq+0en2s+ruiX0VEIC80nV7/0s7XRahx8NnsoCnpCVUPz8wrqVSPi760LkA==} + /tsx/3.12.6: + resolution: {integrity: sha512-q93WgS3lBdHlPgS0h1i+87Pt6n9K/qULIMNYZo07nSeu2z5QE2CellcAZfofVXBo2tQg9av2ZcRMQ2S2i5oadQ==} hasBin: true dependencies: '@esbuild-kit/cjs-loader': 2.4.2 @@ -9459,12 +9487,12 @@ packages: resolution: {integrity: sha512-EK5LeABThyn5KbX0eo5c7xKRQhnHVxKN8/e5Y+YQEf4ZobJB6OZ766756wbVqzIY/G/MvAfLbc6EwFPdSNnlpA==} hasBin: true dependencies: - '@rollup/plugin-alias': 4.0.3_rollup@3.18.0 - '@rollup/plugin-commonjs': 24.0.1_rollup@3.18.0 - '@rollup/plugin-json': 6.0.0_rollup@3.18.0 - '@rollup/plugin-node-resolve': 15.0.1_rollup@3.18.0 - '@rollup/plugin-replace': 5.0.2_rollup@3.18.0 - '@rollup/pluginutils': 5.0.2_rollup@3.18.0 + '@rollup/plugin-alias': 4.0.3_rollup@3.20.0 + '@rollup/plugin-commonjs': 24.0.1_rollup@3.20.0 + '@rollup/plugin-json': 6.0.0_rollup@3.20.0 + '@rollup/plugin-node-resolve': 15.0.1_rollup@3.20.0 + '@rollup/plugin-replace': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.0 chalk: 5.2.0 consola: 2.15.3 defu: 6.1.2 @@ -9474,13 +9502,13 @@ packages: jiti: 1.17.1 magic-string: 0.29.0 mkdist: 1.1.1_typescript@4.9.5 - mlly: 1.1.1 + mlly: 1.2.0 mri: 1.2.0 pathe: 1.1.0 pkg-types: 1.0.2 pretty-bytes: 6.1.0 - rollup: 3.18.0 - rollup-plugin-dts: 5.3.0_fn2onl6nbsljlgjr3jlzr6w7we + rollup: 3.20.0 + rollup-plugin-dts: 5.3.0_pn5zetjg24cqcolt42iry5qj6a scule: 1.0.0 typescript: 4.9.5 untyped: 1.2.2 @@ -9523,15 +9551,15 @@ packages: dev: true /unpipe/1.0.0: - resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=} + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} /untyped/1.2.2: resolution: {integrity: sha512-EANYd5L6AdpgfldlgMcmvOOnj092nWhy0ybhc7uhEH12ipytDYz89EOegBQKj8qWL3u1wgYnmFjADhsuCJs5Aw==} dependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.21.3 '@babel/standalone': 7.20.14 - '@babel/types': 7.21.2 + '@babel/types': 7.21.3 scule: 1.0.0 transitivePeerDependencies: - supports-color @@ -9595,14 +9623,14 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - /vite-node/0.29.2: - resolution: {integrity: sha512-5oe1z6wzI3gkvc4yOBbDBbgpiWiApvuN4P55E8OI131JGrSuo4X3SOZrNmZYo4R8Zkze/dhi572blX0zc+6SdA==} + /vite-node/0.29.7: + resolution: {integrity: sha512-PakCZLvz37yFfUPWBnLa1OYHPCGm5v4pmRrTcFN4V/N/T3I6tyP3z07S//9w+DdeL7vVd0VSeyMZuAh+449ZWw==} engines: {node: '>=v14.16.0'} hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 - mlly: 1.1.1 + mlly: 1.2.0 pathe: 1.1.0 picocolors: 1.0.0 vite: link:packages/vite @@ -9610,13 +9638,13 @@ packages: - supports-color dev: true - /vitepress/1.0.0-alpha.49: - resolution: {integrity: sha512-3nUZJow4qL8NHRWYatqqVj45AJDxWst/TuOj+IbQRhxesEswa+Fpwayj9/FxzRzBl665fuiG5y+QeVhOeUm0OA==} + /vitepress/1.0.0-alpha.61: + resolution: {integrity: sha512-NvzERVS3/TU9YkYcaiK7yNSe0zY9UcSV58tx3mxbvVLCuwRykzO4OWbl6vQT6Ut6YGuZU1y3Z5WcSS+fHfaxJA==} hasBin: true dependencies: '@docsearch/css': 3.3.3 '@docsearch/js': 3.3.3 - '@vitejs/plugin-vue': 4.0.0_5qyuox3n3rizckhh25uzvv7zgq + '@vitejs/plugin-vue': 4.1.0_5qyuox3n3rizckhh25uzvv7zgq '@vue/devtools-api': 6.5.0 '@vueuse/core': 9.13.0_vue@3.2.47 body-scroll-lock: 4.0.0-beta.0 @@ -9631,8 +9659,8 @@ packages: - react-dom dev: true - /vitest/0.29.2: - resolution: {integrity: sha512-ydK9IGbAvoY8wkg29DQ4ivcVviCaUi3ivuPKfZEVddMTenFHUfB8EEDXQV8+RasEk1ACFLgMUqAaDuQ/Nk+mQA==} + /vitest/0.29.7: + resolution: {integrity: sha512-aWinOSOu4jwTuZHkb+cCyrqQ116Q9TXaJrNKTHudKBknIpR0VplzeaOUuDF9jeZcrbtQKZQt6yrtd+eakbaxHg==} engines: {node: '>=v14.16.0'} hasBin: true peerDependencies: @@ -9641,6 +9669,8 @@ packages: '@vitest/ui': '*' happy-dom: '*' jsdom: '*' + safaridriver: '*' + webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -9652,14 +9682,18 @@ packages: optional: true jsdom: optional: true + safaridriver: + optional: true + webdriverio: + optional: true dependencies: '@types/chai': 4.3.4 '@types/chai-subset': 1.3.3 - '@types/node': 18.14.6 - '@vitest/expect': 0.29.2 - '@vitest/runner': 0.29.2 - '@vitest/spy': 0.29.2 - '@vitest/utils': 0.29.2 + '@types/node': 18.15.5 + '@vitest/expect': 0.29.7 + '@vitest/runner': 0.29.7 + '@vitest/spy': 0.29.7 + '@vitest/utils': 0.29.7 acorn: 8.8.2 acorn-walk: 8.2.0_acorn@8.8.2 cac: 6.7.14 @@ -9672,10 +9706,10 @@ packages: std-env: 3.3.1 strip-literal: 1.0.1 tinybench: 2.3.1 - tinypool: 0.3.1 + tinypool: 0.4.0 tinyspy: 1.0.2 vite: link:packages/vite - vite-node: 0.29.2 + vite-node: 0.29.7 why-is-node-running: 2.2.2 transitivePeerDependencies: - supports-color @@ -9832,8 +9866,8 @@ packages: resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} engines: {node: '>= 10.0.0'} dependencies: - '@babel/parser': 7.21.2 - '@babel/types': 7.21.2 + '@babel/parser': 7.21.3 + '@babel/types': 7.21.3 assert-never: 1.2.1 babel-walk: 3.0.0-canary-5 dev: true @@ -9881,8 +9915,8 @@ packages: optional: true dev: true - /ws/8.12.1: - resolution: {integrity: sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==} + /ws/8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -9918,8 +9952,8 @@ packages: engines: {node: '>= 14'} dev: true - /yaml/2.1.3: - resolution: {integrity: sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==} + /yaml/2.2.1: + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} engines: {node: '>= 14'} dev: true diff --git a/vitest.config.ts b/vitest.config.ts index f86aad8dd8b15b..5249f8894dc190 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,6 +9,8 @@ export default defineConfig({ './playground-temp/**/*.*', ], testTimeout: 20000, + // node14 segfaults often with threads + threads: !process.versions.node.startsWith('14'), }, esbuild: { target: 'node14',