diff --git a/.changeset/angry-avocados-live.md b/.changeset/angry-avocados-live.md new file mode 100644 index 0000000000000..c48db59488f2c --- /dev/null +++ b/.changeset/angry-avocados-live.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Prevent Partytown from hijacking history APIs diff --git a/.changeset/brave-taxis-arrive.md b/.changeset/brave-taxis-arrive.md deleted file mode 100644 index 3d2a5bd172edb..0000000000000 --- a/.changeset/brave-taxis-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Adds a warning if `astro add` fetches a package but returns a non-404 status diff --git a/.changeset/lorem-ipsum-dolor b/.changeset/lorem-ipsum-dolor new file mode 100644 index 0000000000000..15182e8f6cd5b --- /dev/null +++ b/.changeset/lorem-ipsum-dolor @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes static builds when `config.outDir` is located outside of the astro project diff --git a/.changeset/quick-toes-peel.md b/.changeset/quick-toes-peel.md deleted file mode 100644 index 25d5c13c7130b..0000000000000 --- a/.changeset/quick-toes-peel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Add a new property `Astro.currentLocale`, available when `i18n` is enabled. diff --git a/.changeset/selfish-parents-leave.md b/.changeset/selfish-parents-leave.md new file mode 100644 index 0000000000000..206fa08e12844 --- /dev/null +++ b/.changeset/selfish-parents-leave.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Improves the error message when a middleware doesn't return a `Response` diff --git a/.changeset/thirty-hats-bathe.md b/.changeset/thirty-hats-bathe.md new file mode 100644 index 0000000000000..1ec2b932af389 --- /dev/null +++ b/.changeset/thirty-hats-bathe.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Correctly merge headers from the original response when an error page is rendered diff --git a/.devcontainer/with-vite-plugin-pwa/devcontainer.json b/.devcontainer/with-vite-plugin-pwa/devcontainer.json deleted file mode 100644 index d716cded01b64..0000000000000 --- a/.devcontainer/with-vite-plugin-pwa/devcontainer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "Vite PWA", - "build": { - "dockerfile": "../examples.Dockerfile" - }, - - "workspaceFolder": "/workspaces/astro/examples/with-vite-plugin-pwa", - - "portsAttributes": { - "4321": { - "label": "Application", - "onAutoForward": "openPreview" - } - }, - - "forwardPorts": [4321], - - "postCreateCommand": "pnpm install && cd /workspaces/astro && pnpm run build", - - "waitFor": "postCreateCommand", - - "postAttachCommand": { - "Server": "pnpm start --host" - }, - - "customizations": { - "codespaces": { - "openFiles": ["src/pages/index.astro"] - }, - "vscode": { - "extensions": ["astro-build.astro-vscode", "esbenp.prettier-vscode"] - } - } -} diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e6085ac647f67..95f00b4762897 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -58,6 +58,16 @@ module.exports = { '@typescript-eslint/unbound-method': 'off', '@typescript-eslint/no-explicit-any': 'off', + // Enforce separate type imports for type-only imports to avoid bundling unneeded code + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + fixStyle: 'separate-type-imports', + disallowTypeAnnotations: false, + }, + ], + // These rules enabled by the preset configs don't work well for us '@typescript-eslint/await-thenable': 'off', 'prefer-const': 'off', diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index feecf12a5aac5..30fd8867bcbad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,7 @@ on: - main - "1-legacy" - "2-legacy" + - "3-legacy" - next defaults: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47c9aa6b2a9f0..05a07e125484e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,8 +2,7 @@ We welcome contributions of any size and skill level. As an open source project, we believe in giving back to our contributors and are happy to help with guidance on PRs, technical writing, and turning any feature idea into a reality. -> **Tip for new contributors:** -> Take a look at [https://github.com/firstcontributions/first-contributions](https://github.com/firstcontributions/first-contributions) for helpful information on contributing +> [!Tip] > **For new contributors:** Take a look at [https://github.com/firstcontributions/first-contributions](https://github.com/firstcontributions/first-contributions) for helpful information on contributing ## Quick Guide @@ -46,7 +45,8 @@ To get started, create a codespace for this repository by clicking this 👇 Your new codespace will open in a web-based version of Visual Studio Code. All development dependencies will be preinstalled, and the tests will run automatically ensuring you've got a green base from which to start working. -**Note**: Dev containers is now an open spec which is supported by [GitHub Codespaces](https://github.com/codespaces) and [other supporting tools](https://containers.dev/supporting). +> [!Note] +> Dev containers is now an open spec which is supported by [GitHub Codespaces](https://github.com/codespaces) and [other supporting tools](https://containers.dev/supporting). ### Development @@ -187,7 +187,7 @@ Understanding in which environment code runs, and at which stage in the process, Active Astro development happens on the [`main`](https://github.com/withastro/astro/tree/main) branch. `main` always reflects the latest code. -> **Note:** +> [!Note] > During certain periods, we put `main` into a [**prerelease**](https://github.com/changesets/changesets/blob/main/docs/prereleases.md#prereleases) state. Read more about [Releasing Astro](#releasing-astro). ### `latest` @@ -198,7 +198,8 @@ By default, `create-astro` and [astro.new](https://astro.new) point to this bran ## Releasing Astro -_Note: Only [core maintainers (L3+)](https://github.com/withastro/.github/blob/main/GOVERNANCE.md#level-3-l3---core) can release new versions of Astro._ +> [!Note] +> Only [core maintainers (L3+)](https://github.com/withastro/.github/blob/main/GOVERNANCE.md#level-3-l3---core) can release new versions of Astro. The repo is set up with automatic releases, using the changeset GitHub action & bot. @@ -247,7 +248,7 @@ If you have gotten permission from the core contributors, you can enter into pre - Run: `pnpm exec changeset pre enter next` in the project root - Create a new PR from the changes created by this command - Review, approve, and more the PR to enter prerelease mode. -- If successful, The "Version Packages" PR (if one exists) will now say "Version Packages (next)". +- If successful, The "[ci] release" PR (if one exists) will now say "[ci] release (next)". ### Exiting prerelease mode @@ -256,7 +257,7 @@ Exiting prerelease mode should happen once an experimental release is ready to g - Run: `pnpm exec changeset pre exit` in the project root - Create a new PR from the changes created by this command. - Review, approve, and more the PR to enter prerelease mode. -- If successful, The "Version Packages (next)" PR (if one exists) will now say "Version Packages". +- If successful, The "[ci] release (next)" PR (if one exists) will now say "[ci] release". ### Releasing `astro@latest` while in prerelease mode diff --git a/LICENSE b/LICENSE index 1f0bcaa7dcefc..b3cd0c0f0e01d 100644 --- a/LICENSE +++ b/LICENSE @@ -20,7 +20,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - """ This license applies to parts of the `packages/create-astro` and `packages/astro` subdirectories originating from the https://github.com/sveltejs/kit repository: @@ -33,7 +32,6 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ - """ This license applies to parts of the `packages/create-astro` and `packages/astro` subdirectories originating from the https://github.com/vitejs/vite repository: diff --git a/README.md b/README.md index b608a3026a105..dc246b3d145f5 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,14 @@

+
+ +![Build Status](https://github.com/withastro/astro/actions/workflows/ci.yml/badge.svg) +[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/withastro/astro/blob/main/LICENSE) +[![npm version](https://badge.fury.io/js/astro.svg)](https://badge.fury.io/js/astro) + +
+ ## Install The **recommended** way to install the latest version of Astro is by running the command below: @@ -60,7 +68,6 @@ Join us on [Discord](https://astro.build/chat) to meet other maintainers. We'll | [@astrojs/tailwind](packages/integrations/tailwind) | [![astro version](https://img.shields.io/npm/v/@astrojs/tailwind.svg?label=%20)](packages/integrations/tailwind/CHANGELOG.md) | | [@astrojs/alpinejs](packages/integrations/alpinejs) | [![astro version](https://img.shields.io/npm/v/@astrojs/alpinejs.svg?label=%20)](packages/integrations/alpinejs/CHANGELOG.md) | | [@astrojs/mdx](packages/integrations/mdx) | [![astro version](https://img.shields.io/npm/v/@astrojs/mdx.svg?label=%20)](packages/integrations/mdx/CHANGELOG.md) | -| [@astrojs/prefetch](packages/integrations/prefetch) | [![astro version](https://img.shields.io/npm/v/@astrojs/prefetch.svg?label=%20)](packages/integrations/prefetch/CHANGELOG.md) | [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6178/badge)](https://bestpractices.coreinfrastructure.org/projects/6178) diff --git a/benchmark/packages/timer/package.json b/benchmark/packages/timer/package.json index 8ac03985492ef..a4a3b8df1b81c 100644 --- a/benchmark/packages/timer/package.json +++ b/benchmark/packages/timer/package.json @@ -29,7 +29,7 @@ "astro": "workspace:*" }, "devDependencies": { - "@types/server-destroy": "^1.0.1", + "@types/server-destroy": "^1.0.3", "astro": "workspace:*", "astro-scripts": "workspace:*" } diff --git a/benchmark/packages/timer/src/index.ts b/benchmark/packages/timer/src/index.ts index 49edcb5e86a5e..2ea41af6624d0 100644 --- a/benchmark/packages/timer/src/index.ts +++ b/benchmark/packages/timer/src/index.ts @@ -6,6 +6,7 @@ export function getAdapter(): AstroAdapter { serverEntrypoint: '@benchmark/timer/server.js', previewEntrypoint: '@benchmark/timer/preview.js', exports: ['handler'], + supportedAstroFeatures: {}, }; } diff --git a/examples/basics/package.json b/examples/basics/package.json index 1be44bed6e74d..33bb8dbfeb6b9 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.5.5" + "astro": "^4.0.5" } } diff --git a/examples/blog/package.json b/examples/blog/package.json index afee1f0281c66..0887b798078e4 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^1.1.5", - "@astrojs/rss": "^3.0.0", + "@astrojs/mdx": "^2.0.1", + "@astrojs/rss": "^4.0.1", "@astrojs/sitemap": "^3.0.3", - "astro": "^3.5.5" + "astro": "^4.0.5" } } diff --git a/examples/blog/src/content/config.ts b/examples/blog/src/content/config.ts index f0419223e7635..667a31cc73912 100644 --- a/examples/blog/src/content/config.ts +++ b/examples/blog/src/content/config.ts @@ -1,6 +1,7 @@ import { defineCollection, z } from 'astro:content'; const blog = defineCollection({ + type: 'content', // Type-check frontmatter using a schema schema: z.object({ title: z.string(), diff --git a/examples/component/package.json b/examples/component/package.json index 2c781217268ba..3365f94cfac7a 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^3.5.5" + "astro": "^4.0.5" }, "peerDependencies": { "astro": "^3.0.0" diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index 88c5f32295e46..9b649f82af342 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -12,8 +12,8 @@ }, "dependencies": { "@astrojs/alpinejs": "^0.3.1", - "@types/alpinejs": "^3.7.2", - "alpinejs": "^3.12.3", - "astro": "^3.5.5" + "@types/alpinejs": "^3.13.5", + "alpinejs": "^3.13.3", + "astro": "^4.0.5" } } diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index 97f9a4dcb29c9..478c491b88c60 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/lit": "^3.0.3", + "@astrojs/lit": "^4.0.0", "@webcomponents/template-shadowroot": "^0.2.1", - "astro": "^3.5.5", + "astro": "^4.0.5", "lit": "^2.8.0" } } diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index af251b7d8796c..361459ccf6338 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -12,16 +12,16 @@ }, "dependencies": { "@astrojs/preact": "^3.0.1", - "@astrojs/react": "^3.0.5", + "@astrojs/react": "^3.0.7", "@astrojs/solid-js": "^3.0.2", - "@astrojs/svelte": "^4.0.4", - "@astrojs/vue": "^3.0.4", - "astro": "^3.5.5", - "preact": "^10.17.1", + "@astrojs/svelte": "^5.0.1", + "@astrojs/vue": "^4.0.3", + "astro": "^4.0.5", + "preact": "^10.19.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index c8059410c45ec..311005c85883c 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -13,7 +13,7 @@ "dependencies": { "@astrojs/preact": "^3.0.1", "@preact/signals": "^1.2.1", - "astro": "^3.5.5", - "preact": "^10.17.1" + "astro": "^4.0.5", + "preact": "^10.19.2" } } diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index 79b09fc45d4c9..208a234bdeb1b 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -11,10 +11,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/react": "^3.0.5", - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", - "astro": "^3.5.5", + "@astrojs/react": "^3.0.7", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "astro": "^4.0.5", "react": "^18.2.0", "react-dom": "^18.2.0" } diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index 8b1a9a3157f06..7c6a3826962b7 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/solid-js": "^3.0.2", - "astro": "^3.5.5", - "solid-js": "^1.7.11" + "astro": "^4.0.5", + "solid-js": "^1.8.5" } } diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 3badefefbdd66..2a3322bd6b44c 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "@astrojs/svelte": "^4.0.4", - "astro": "^3.5.5", - "svelte": "^4.2.0" + "@astrojs/svelte": "^5.0.1", + "astro": "^4.0.5", + "svelte": "^4.2.5" } } diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index 99a6b678f005b..90d2e02d4064e 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "@astrojs/vue": "^3.0.4", - "astro": "^3.5.5", - "vue": "^3.3.4" + "@astrojs/vue": "^4.0.3", + "astro": "^4.0.5", + "vue": "^3.3.8" } } diff --git a/examples/framework-vue/src/components/Counter.vue b/examples/framework-vue/src/components/Counter.vue index 5ce5352b88e6e..11f2bf1b5051f 100644 --- a/examples/framework-vue/src/components/Counter.vue +++ b/examples/framework-vue/src/components/Counter.vue @@ -1,31 +1,22 @@ + + - - - diff --git a/examples/with-vite-plugin-pwa/src/env.d.ts b/examples/with-vite-plugin-pwa/src/env.d.ts deleted file mode 100644 index f964fe0cffd88..0000000000000 --- a/examples/with-vite-plugin-pwa/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/examples/with-vite-plugin-pwa/src/index.ts b/examples/with-vite-plugin-pwa/src/index.ts deleted file mode 100644 index 2595fe3a89037..0000000000000 --- a/examples/with-vite-plugin-pwa/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { registerSW } from 'virtual:pwa-register'; - -const updateSW = registerSW({ - onNeedRefresh() {}, - onOfflineReady() { - console.log('Offline ready'); - }, -}); - -updateSW(); diff --git a/examples/with-vite-plugin-pwa/src/pages/index.astro b/examples/with-vite-plugin-pwa/src/pages/index.astro deleted file mode 100644 index 19956b3d24c7b..0000000000000 --- a/examples/with-vite-plugin-pwa/src/pages/index.astro +++ /dev/null @@ -1,18 +0,0 @@ ---- - ---- - - - - - - - - Welcome to Astro - - - -

Welcome to Astro

- - - diff --git a/examples/with-vite-plugin-pwa/src/vite-env.d.ts b/examples/with-vite-plugin-pwa/src/vite-env.d.ts deleted file mode 100644 index 1a947fad00738..0000000000000 --- a/examples/with-vite-plugin-pwa/src/vite-env.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare module 'virtual:pwa-register' { - export type RegisterSWOptions = { - immediate?: boolean; - onNeedRefresh?: () => void; - onOfflineReady?: () => void; - onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void; - onRegisterError?: (error: any) => void; - }; - - export function registerSW(options?: RegisterSWOptions): (reloadPage?: boolean) => Promise; -} diff --git a/examples/with-vite-plugin-pwa/tsconfig.json b/examples/with-vite-plugin-pwa/tsconfig.json deleted file mode 100644 index d78f81ec4e8e9..0000000000000 --- a/examples/with-vite-plugin-pwa/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "astro/tsconfigs/base" -} diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json index 5259966bb9e71..965d0dc123217 100644 --- a/examples/with-vitest/package.json +++ b/examples/with-vitest/package.json @@ -12,7 +12,7 @@ "test": "vitest" }, "dependencies": { - "astro": "^3.5.5", + "astro": "^4.0.5", "vitest": "^0.34.2" } } diff --git a/package.json b/package.json index 8bf7dc459cb98..ad073d17d5137 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "build:examples": "turbo run build --filter=\"@example/*\"", "dev": "turbo run dev --concurrency=40 --parallel --filter=astro --filter=create-astro --filter=\"@astrojs/*\" --filter=\"@benchmark/*\"", "format": "pnpm run format:code", - "format:ci": "pnpm run format:imports && pnpm run format:code", + "format:ci": "pnpm run format:code", "format:code": "prettier -w \"**/*\" --ignore-unknown --cache", "format:imports": "organize-imports-cli ./packages/*/tsconfig.json ./packages/*/*/tsconfig.json", "test": "turbo run test --concurrency=1 --filter=astro --filter=create-astro --filter=\"@astrojs/*\"", @@ -44,14 +44,51 @@ "pnpm": ">=8.6.12" }, "packageManager": "pnpm@8.6.12", + "dependencies": { + "astro-benchmark": "workspace:*" + }, + "devDependencies": { + "@astrojs/check": "^0.3.1", + "@changesets/changelog-github": "^0.4.8", + "@changesets/cli": "^2.26.2", + "@types/node": "^18.17.8", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "esbuild": "^0.19.6", + "eslint": "^8.54.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-prettier": "^5.0.0", + "only-allow": "^1.1.1", + "organize-imports-cli": "^0.10.0", + "prettier": "^3.1.0", + "prettier-plugin-astro": "^0.12.2", + "tiny-glob": "^0.2.9", + "turbo": "^1.10.12", + "typescript": "~5.2.2" + }, "pnpm": { "packageExtensions": { + "vite-svg-loader": { + "peerDependenciesMeta": { + "vue": { + "optional": true + } + } + }, "svelte2tsx": { "peerDependenciesMeta": { "typescript": { "optional": true } } + }, + "rehype-pretty-code": { + "peerDependenciesMeta": { + "shiki": { + "optional": true + } + } } }, "overrides": { @@ -66,34 +103,14 @@ "vite", "react", "react-dom", - "@types/react" + "@types/react", + "tslib", + "quill-delta", + "rxjs" ], "allowAny": [ "astro" ] } - }, - "dependencies": { - "astro-benchmark": "workspace:*" - }, - "devDependencies": { - "@astrojs/check": "^0.1.0", - "@changesets/changelog-github": "^0.4.8", - "@changesets/cli": "^2.26.2", - "@types/node": "^18.17.8", - "@typescript-eslint/eslint-plugin": "^6.4.1", - "@typescript-eslint/parser": "^6.4.1", - "esbuild": "^0.19.2", - "eslint": "^8.47.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-prettier": "^5.0.0", - "only-allow": "^1.1.1", - "organize-imports-cli": "^0.10.0", - "prettier": "^3.0.3", - "prettier-plugin-astro": "^0.12.0", - "tiny-glob": "^0.2.9", - "turbo": "^1.10.12", - "typescript": "~5.1.6" } } diff --git a/packages/astro-prism/package.json b/packages/astro-prism/package.json index eae841073a2df..d62e819a8253b 100644 --- a/packages/astro-prism/package.json +++ b/packages/astro-prism/package.json @@ -35,7 +35,7 @@ "prismjs": "^1.29.0" }, "devDependencies": { - "@types/prismjs": "1.26.0", + "@types/prismjs": "1.26.3", "astro-scripts": "workspace:*" }, "engines": { diff --git a/packages/astro-rss/CHANGELOG.md b/packages/astro-rss/CHANGELOG.md index 26e9c95d73c2f..df205874890d1 100644 --- a/packages/astro-rss/CHANGELOG.md +++ b/packages/astro-rss/CHANGELOG.md @@ -1,5 +1,23 @@ # @astrojs/rss +## 4.0.1 + +### Patch Changes + +- [#9299](https://github.com/withastro/astro/pull/9299) [`edfae50e6`](https://github.com/withastro/astro/commit/edfae50e6ea494f49c6d4fbf4bd4481870f994b1) Thanks [@cdvillard](https://github.com/cdvillard)! - Improves the `@astrojs/rss` error message thrown when the object passed to the `items` property is missing any of the three required keys or if one of those keys is mistyped. + +## 4.0.0 + +### Major Changes + +- [#9168](https://github.com/withastro/astro/pull/9168) [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17) Thanks [@bluwy](https://github.com/bluwy)! - Removes the deprecated (in v3.0) `drafts` option as the feature is deprecated in Astro 3.0 + +## 4.0.0-beta.0 + +### Major Changes + +- [#9168](https://github.com/withastro/astro/pull/9168) [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17) Thanks [@bluwy](https://github.com/bluwy)! - Removes the `drafts` option as the feature is deprecated in Astro 3.0 + ## 3.0.0 ### Major Changes diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index 268f58f26690f..c8485b02e3e8e 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -28,7 +28,7 @@ Start by [adding a `site` to your project's `astro.config` for link generation]( import rss from '@astrojs/rss'; import { getCollection } from 'astro:content'; -export async function get(context) { +export async function GET(context) { const posts = await getCollection('blog'); return rss({ title: 'Buzz’s Blog', @@ -55,7 +55,7 @@ Read **[Astro's RSS docs][astro-rss]** for more on using content collections, an The `rss` default export offers a number of configuration options. Here's a quick reference: ```js -export function get(context) { +export function GET(context) { return rss({ // `` field in output xml title: 'Buzz’s Blog', @@ -98,7 +98,7 @@ The base URL to use when generating RSS item links. We recommend using the [endp ```ts import rss from '@astrojs/rss'; -export const get = (context) => +export const GET = (context) => rss({ site: context.site, // ... @@ -113,14 +113,6 @@ A list of formatted RSS feed items. See [Astro's RSS items documentation](https: When providing a formatted RSS item list, see the [`RSSFeedItem` type reference](#rssfeeditem). -### drafts - -Type: `boolean (optional)` - -**Deprecated**: Manually filter `items` instead. - -Set `drafts: true` to include [draft posts](https://docs.astro.build/en/guides/markdown-content/#draft-pages) in the feed output. By default, this option is `false` and draft posts are not included. - ### stylesheet Type: `string (optional)` @@ -136,7 +128,7 @@ A string of valid XML to be injected between your feed's `<description>` and `<i ```js import rss from '@astrojs/rss'; -export const get = () => rss({ +export const GET = () => rss({ ... customData: '<language>en-us</language>', }); @@ -181,7 +173,7 @@ By default, the library will add trailing slashes to the emitted URLs. To preven ```js import rss from '@astrojs/rss'; -export const get = () => +export const GET = () => rss({ trailingSlash: false, }); @@ -361,7 +353,7 @@ This function assumes, but does not verify, you are globbing for items inside `s // src/pages/rss.xml.js import rss, { pagesGlobToRssItems } from '@astrojs/rss'; -export async function get(context) { +export async function GET(context) { return rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', @@ -379,7 +371,7 @@ As `rss()` returns a `Response`, you can also use `getRssString()` to get the RS // src/pages/rss.xml.js import { getRssString } from '@astrojs/rss'; -export async function get(context) { +export async function GET(context) { const rssString = await getRssString({ title: 'Buzz’s Blog', ... diff --git a/packages/astro-rss/package.json b/packages/astro-rss/package.json index c200e6c5942a4..c262452daf0b6 100644 --- a/packages/astro-rss/package.json +++ b/packages/astro-rss/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/rss", "description": "Add RSS feeds to your Astro projects", - "version": "3.0.0", + "version": "4.0.1", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -27,9 +27,9 @@ "test": "mocha --exit --timeout 20000" }, "devDependencies": { - "@types/chai": "^4.3.5", - "@types/chai-as-promised": "^7.1.5", - "@types/mocha": "^10.0.1", + "@types/chai": "^4.3.10", + "@types/chai-as-promised": "^7.1.8", + "@types/mocha": "^10.0.4", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", diff --git a/packages/astro-rss/src/index.ts b/packages/astro-rss/src/index.ts index a611afc1637dd..c8cf19d6022e9 100644 --- a/packages/astro-rss/src/index.ts +++ b/packages/astro-rss/src/index.ts @@ -27,11 +27,6 @@ export type RSSOptions = { stylesheet?: z.infer<typeof rssOptionsValidator>['stylesheet']; /** Specify custom data in opening of file */ customData?: z.infer<typeof rssOptionsValidator>['customData']; - /** - * Whether to include drafts or not - * @deprecated Deprecated since version 3.0. Use content collections instead. - */ - drafts?: z.infer<typeof rssOptionsValidator>['drafts']; trailingSlash?: z.infer<typeof rssOptionsValidator>['trailingSlash']; }; @@ -48,11 +43,6 @@ export type RSSFeedItem = { description?: z.infer<typeof rssSchema>['description']; /** Append some other XML-valid data to this item */ customData?: z.infer<typeof rssSchema>['customData']; - /** - * Whether draft or not - * @deprecated Deprecated since version 3.0. Use content collections instead. - */ - draft?: z.infer<typeof rssSchema>['draft']; /** Categories or tags related to the item */ categories?: z.infer<typeof rssSchema>['categories']; /** The item author's email address */ @@ -92,7 +82,6 @@ const rssOptionsValidator = z.object({ return items; }), xmlns: z.record(z.string()).optional(), - drafts: z.boolean().default(false), stylesheet: z.union([z.string(), z.boolean()]).optional(), customData: z.string().optional(), trailingSlash: z.boolean().default(true), @@ -120,9 +109,21 @@ async function validateRssOptions(rssOptions: RSSOptions) { const formattedError = new Error( [ `[RSS] Invalid or missing options:`, - ...parsedResult.error.errors.map( - (zodError) => `${zodError.message} (${zodError.path.join('.')})` - ), + ...parsedResult.error.errors.map((zodError) => { + const path = zodError.path.join('.'); + const message = `${zodError.message} (${path})`; + const code = zodError.code; + + if (path === 'items' && code === 'invalid_union') { + return [ + message, + `The \`items\` property requires properly typed \`title\`, \`pubDate\`, and \`link\` keys.`, + `Check your collection's schema, and visit https://docs.astro.build/en/guides/rss/#generating-items for more info.`, + ].join('\n'); + } + + return message; + }), ].join('\n') ); throw formattedError; @@ -159,10 +160,7 @@ export function pagesGlobToRssItems(items: GlobResult): Promise<ValidatedRSSFeed /** Generate RSS 2.0 feed */ async function generateRSS(rssOptions: ValidatedRSSOptions): Promise<string> { - const { site } = rssOptions; - const items = rssOptions.drafts - ? rssOptions.items - : rssOptions.items.filter((item) => !item.draft); + const { items, site } = rssOptions; const xmlOptions = { ignoreAttributes: false, diff --git a/packages/astro-rss/src/schema.ts b/packages/astro-rss/src/schema.ts index eb15ecd584095..98aa35f812123 100644 --- a/packages/astro-rss/src/schema.ts +++ b/packages/astro-rss/src/schema.ts @@ -8,7 +8,6 @@ export const rssSchema = z.object({ .refine((value) => !isNaN(value.getTime())), description: z.string().optional(), customData: z.string().optional(), - draft: z.boolean().optional(), categories: z.array(z.string()).optional(), author: z.string().optional(), commentsUrl: z.string().optional(), diff --git a/packages/astro-rss/test/rss.test.js b/packages/astro-rss/test/rss.test.js index 5dfb48b32adf3..e6f68a272f5fb 100644 --- a/packages/astro-rss/test/rss.test.js +++ b/packages/astro-rss/test/rss.test.js @@ -1,18 +1,18 @@ -import rss, { getRssString } from '../dist/index.js'; -import { rssSchema } from '../dist/schema.js'; import chai from 'chai'; import chaiPromises from 'chai-as-promised'; import chaiXml from 'chai-xml'; +import rss, { getRssString } from '../dist/index.js'; +import { rssSchema } from '../dist/schema.js'; import { - title, description, - site, phpFeedItem, phpFeedItemWithContent, phpFeedItemWithCustomData, + site, + title, web1FeedItem, - web1FeedItemWithContent, web1FeedItemWithAllData, + web1FeedItemWithContent, } from './test-utils.js'; chai.use(chaiPromises); @@ -156,36 +156,12 @@ describe('getRssString', () => { chai.expect(str).to.contain(customData); }); - it('should filter out entries marked as `draft`', async () => { - const str = await getRssString({ - title, - description, - items: [phpFeedItem, { ...web1FeedItem, draft: true }], - site, - }); - - chai.expect(str).xml.to.equal(validXmlWithoutWeb1FeedResult); - }); - - it('should respect drafts option', async () => { - const str = await getRssString({ - title, - description, - items: [phpFeedItem, { ...web1FeedItem, draft: true }], - site, - drafts: true, - }); - - chai.expect(str).xml.to.equal(validXmlResult); - }); - it('should not append trailing slash to URLs with the given option', async () => { const str = await getRssString({ title, description, - items: [phpFeedItem, { ...web1FeedItem, draft: true }], + items: [phpFeedItem], site, - drafts: true, trailingSlash: false, }); diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index a3061833944f2..fa073b5d58caf 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,638 @@ # astro +## 4.0.5 + +### Patch Changes + +- [#9423](https://github.com/withastro/astro/pull/9423) [`bda1d294f`](https://github.com/withastro/astro/commit/bda1d294f2d50f31abfc9a32b5272fc9ac080e83) Thanks [@matthewp](https://github.com/matthewp)! - Error when getImage is passed an undefined src + +- [#9424](https://github.com/withastro/astro/pull/9424) [`e1a5a2d36`](https://github.com/withastro/astro/commit/e1a5a2d36ac3637f5c94a27b69128a121541bae8) Thanks [@matthewp](https://github.com/matthewp)! - Prevents dev server from crashing on unhandled rejections, and adds a helpful error message + +- [#9404](https://github.com/withastro/astro/pull/9404) [`8aa17a64b`](https://github.com/withastro/astro/commit/8aa17a64b46b8eaabfd1375fd6550ff93727aa81) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fixed some newer HTML attributes not being included in our type definitions + +- [#9414](https://github.com/withastro/astro/pull/9414) [`bebf38c0c`](https://github.com/withastro/astro/commit/bebf38c0cb539de04007f5e721bf459300b895a1) Thanks [@Skn0tt](https://github.com/Skn0tt)! - Adds the feature name to logs about feature deprecation / experimental status. + +- [#9418](https://github.com/withastro/astro/pull/9418) [`2c168af67`](https://github.com/withastro/astro/commit/2c168af6745f5357e76ec323787595ef06d5fd73) Thanks [@alexnguyennz](https://github.com/alexnguyennz)! - Fix broken link in CI instructions + +- [#9407](https://github.com/withastro/astro/pull/9407) [`546d92c86`](https://github.com/withastro/astro/commit/546d92c862d08c69751039511a12c92ae38184c2) Thanks [@matthewp](https://github.com/matthewp)! - Allows file URLs as import specifiers + +## 4.0.4 + +### Patch Changes + +- [#9380](https://github.com/withastro/astro/pull/9380) [`ea0918259`](https://github.com/withastro/astro/commit/ea0918259964947523827bac6abe88ad3841dbb9) Thanks [@ematipico](https://github.com/ematipico)! - Correctly handle the rendering of i18n routes when `output: "hybrid"` is set + +- [#9374](https://github.com/withastro/astro/pull/9374) [`65ddb0271`](https://github.com/withastro/astro/commit/65ddb027111514d41481f7455c0f0f03f8f608a8) Thanks [@bluwy](https://github.com/bluwy)! - Fixes an issue where prerendered route paths that end with `.mjs` were removed from the final build + +- [#9375](https://github.com/withastro/astro/pull/9375) [`26f7023d6`](https://github.com/withastro/astro/commit/26f7023d6928de75c363df0fa759a6255cb73ef3) Thanks [@bluwy](https://github.com/bluwy)! - Prettifies generated route names injected by integrations + +- [#9387](https://github.com/withastro/astro/pull/9387) [`a7c75b333`](https://github.com/withastro/astro/commit/a7c75b3339e6b1562d0d16ab6ef482840c51df68) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Fixes an edge case with `astro add` that could install a prerelease instead of a stable release version. + + **Prior to this change** + `astro add svelte` installs `svelte@5.0.0-next.22` + + **After this change** + `astro add svelte` installs `svelte@4.2.8` + +- Updated dependencies [[`270c6cc27`](https://github.com/withastro/astro/commit/270c6cc27f20995883fcdabbff9b56d7f041f9e4)]: + - @astrojs/markdown-remark@4.0.1 + +## 4.0.3 + +### Patch Changes + +- [#9342](https://github.com/withastro/astro/pull/9342) [`eb942942d`](https://github.com/withastro/astro/commit/eb942942d67508c07d7efaa859a7840f7c0223da) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix missing `is:inline` type for the `<slot />` element + +- [#9343](https://github.com/withastro/astro/pull/9343) [`ab0281aee`](https://github.com/withastro/astro/commit/ab0281aee419e58c6079ca393987fe1ff0541dd5) Thanks [@martrapp](https://github.com/martrapp)! - Adds source file properties to HTML elements only if devToolbar is enabled + +- [#9336](https://github.com/withastro/astro/pull/9336) [`c76901065`](https://github.com/withastro/astro/commit/c76901065545f6a8d3de3e44d1c8ee5456a8a77a) Thanks [@FredKSchott](https://github.com/FredKSchott)! - dev: fix issue where 404 and 500 responses were logged as 200 + +- [#9339](https://github.com/withastro/astro/pull/9339) [`0bb3d5322`](https://github.com/withastro/astro/commit/0bb3d532219fb90fc08bfb472fc981fab6543d16) Thanks [@morinokami](https://github.com/morinokami)! - Fixed the log message to correctly display 'enabled' and 'disabled' when toggling 'Disable notifications' in the Toolbar. + +## 4.0.2 + +### Patch Changes + +- [#9331](https://github.com/withastro/astro/pull/9331) [`cfb20550d`](https://github.com/withastro/astro/commit/cfb20550d346a33e76e23453d5dcd084e5065c4d) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Updates an internal dependency ([`vitefu`](https://github.com/svitejs/vitefu)) to avoid a common `peerDependency` warning + +- [#9327](https://github.com/withastro/astro/pull/9327) [`3878a91be`](https://github.com/withastro/astro/commit/3878a91be4879988c7235f433e50a6dc82e32288) Thanks [@doseofted](https://github.com/doseofted)! - Fixes an edge case for `<form method="dialog">` when using View Transitions. Forms with `method="dialog"` no longer require an additional `data-astro-reload` attribute. + +## 4.0.1 + +### Patch Changes + +- [#9315](https://github.com/withastro/astro/pull/9315) [`631e5d01b`](https://github.com/withastro/astro/commit/631e5d01b00efee6970466c38201cb0e67ec74cf) Thanks [@ematipico](https://github.com/ematipico)! - Fixes an issue where logs that weren't grouped together by route when building the app. + +## 4.0.0 + +### Major Changes + +- [#9138](https://github.com/withastro/astro/pull/9138) [`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3) Thanks [@bluwy](https://github.com/bluwy)! - Updates the unified, remark, and rehype dependencies to latest. Make sure to update your custom remark and rehype plugins as well to be compatible with the latest versions. + + **Potentially breaking change:** The default value of `markdown.remarkRehype.footnoteBackLabel` is changed from `"Back to content"` to `"Back to reference 1"`. See the `mdast-util-to-hast` [commit](https://github.com/syntax-tree/mdast-util-to-hast/commit/56c88e45690be138fad9f0bf367b939d09816863) for more information. + +- [#9181](https://github.com/withastro/astro/pull/9181) [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e) Thanks [@bluwy](https://github.com/bluwy)! - Removes support for returning simple objects from endpoints (deprecated since Astro 3.0). You should return a `Response` instead. + + `ResponseWithEncoding` is also removed. You can refactor the code to return a response with an array buffer instead, which is encoding agnostic. + + The types for middlewares have also been revised. To type a middleware function, you should now use `MiddlewareHandler` instead of `MiddlewareResponseHandler`. If you used `defineMiddleware()` to type the function, no changes are needed. + +- [#9263](https://github.com/withastro/astro/pull/9263) [`3cbd8ea75`](https://github.com/withastro/astro/commit/3cbd8ea7534910e3beae396dcfa93ce87dcdd91f) Thanks [@bluwy](https://github.com/bluwy)! - Removes additional deprecated APIs: + + - The Astro preview server now returns a 404 status instead of a 301 redirect when requesting assets from the public directory without a base. + - Removes special handling when referencing the `astro/client-image` type. You should use the `astro/client` type instead. + - Removes deprecated built-in `rss` support in `getStaticPaths`. You should use `@astrojs/rss` instead. + - Removes deprecated `Astro.request.params` support. You should use `Astro.params` instead. + +- [#9271](https://github.com/withastro/astro/pull/9271) [`47604bd5b`](https://github.com/withastro/astro/commit/47604bd5b5bb2ea63922b657bac104c010575c20) Thanks [@matthewp](https://github.com/matthewp)! - Renames Dev Overlay to Dev Toolbar + + The previously named experimental Dev Overlay is now known as the Astro Dev Toolbar. Overlay plugins have been renamed as Toolbar Apps. All APIs have been updated to reflect this name change. + + To not break existing APIs, aliases for the Toolbar-based names have been created. The previous API names will continue to function but will be deprecated in the future. All documentation has been updated to reflect Toolbar-based names. + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +- [#9225](https://github.com/withastro/astro/pull/9225) [`c421a3d17`](https://github.com/withastro/astro/commit/c421a3d17911aeda29b5204f6d568ae87e329eaf) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Removes the opt-in `handleForms` property for `<ViewTransitions />`. Form submissions are now handled by default and this property is no longer necessary. This default behavior can be disabled by setting `data-astro-reload` on relevant `<form />` elements. + +- [#9196](https://github.com/withastro/astro/pull/9196) [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6) Thanks [@bluwy](https://github.com/bluwy)! - Removes support for Shiki custom language's `path` property. The language JSON file should be imported and passed to the option instead. + + ```diff + // astro.config.js + + import customLang from './custom.tmLanguage.json' + + export default defineConfig({ + markdown: { + shikiConfig: { + langs: [ + - { path: './custom.tmLanguage.json' }, + + customLang, + ], + }, + }, + }) + ``` + +- [#9199](https://github.com/withastro/astro/pull/9199) [`49aa215a0`](https://github.com/withastro/astro/commit/49aa215a01ee1c4805316c85bb0aea6cfbc25a31) Thanks [@lilnasy](https://github.com/lilnasy)! - This change only affects maintainers of third-party adapters. In the Integration API, the `app.render()` method of the `App` class has been simplified. + + Instead of two optional arguments, it now takes a single optional argument that is an object with two optional properties: `routeData` and `locals`. + + ```diff + app.render(request) + + - app.render(request, routeData) + + app.render(request, { routeData }) + + - app.render(request, routeData, locals) + + app.render(request, { routeData, locals }) + + - app.render(request, undefined, locals) + + app.render(request, { locals }) + ``` + + The current signature is deprecated but will continue to function until next major version. + +- [#9212](https://github.com/withastro/astro/pull/9212) [`c0383ea0c`](https://github.com/withastro/astro/commit/c0383ea0c102cb62b7235823c706a090ba08715f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Removes deprecated `app.match()` option, `matchNotFound` + +- [#9168](https://github.com/withastro/astro/pull/9168) [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17) Thanks [@bluwy](https://github.com/bluwy)! - Removes deprecated features from Astro 3.0 + + - Adapters are now required to pass `supportedAstroFeatures` to specify a list of features they support. + - The `build.split` and `build.excludeMiddleware` options are removed. Use `functionPerRoute` and `edgeMiddleware` from adapters instead. + - The `markdown.drafts` option and draft feature is removed. Use content collections instead. + - Lowercase endpoint names are no longer supported. Use uppercase endpoint names instead. + - `getHeaders()` exported from markdown files is removed. Use `getHeadings()` instead. + +### Minor Changes + +- [#9105](https://github.com/withastro/astro/pull/9105) [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Update CLI logging experience + +- [#9200](https://github.com/withastro/astro/pull/9200) [`b4b851f5a`](https://github.com/withastro/astro/commit/b4b851f5a46b32ee531db5dc39ccd2aa7af7bcfd) Thanks [@ematipico](https://github.com/ematipico)! - Adds a new way to configure the `i18n.locales` array. + + Developers can now assign a custom URL path prefix that can span multiple language codes: + + ```js + // astro.config.mjs + export default defineConfig({ + experimental: { + i18n: { + defaultLocale: 'english', + locales: ['de', { path: 'english', codes: ['en', 'en-US'] }, 'fr'], + }, + }, + }); + ``` + + With the above configuration, the URL prefix of the default locale will be `/english/`. When computing `Astro.preferredLocale`, Astro will use the `codes`. + +- [#9115](https://github.com/withastro/astro/pull/9115) [`3b77889b4`](https://github.com/withastro/astro/commit/3b77889b47750ed6e17c7858780dc4aae9201b58) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Adds the `astro preferences` command to manage user preferences. User preferences are specific to individual Astro users, unlike the `astro.config.mjs` file which changes behavior for everyone working on a project. + + User preferences are scoped to the current project by default, stored in a local `.astro/settings.json` file. Using the `--global` flag, user preferences can also be applied to every Astro project on the current machine. Global user preferences are stored in an operating system-specific location. + + ```sh + # Disable the dev overlay for the current user in the current project + npm run astro preferences disable devOverlay + # Disable the dev overlay for the current user in all Astro projects on this machine + npm run astro preferences --global disable devOverlay + + # Check if the dev overlay is enabled for the current user + npm run astro preferences list devOverlay + ``` + +- [#9139](https://github.com/withastro/astro/pull/9139) [`459b26436`](https://github.com/withastro/astro/commit/459b2643666db08dbd29a100ce3d8697b451d3fe) Thanks [@bluwy](https://github.com/bluwy)! - Reworks Vite's logger to use Astro's logger to correctly log HMR messages + +- [#9279](https://github.com/withastro/astro/pull/9279) [`6a9669b81`](https://github.com/withastro/astro/commit/6a9669b810ddfcae6c537165a438190ea1e7a4bc) Thanks [@martrapp](https://github.com/martrapp)! - Improves consistency between navigations with and without `<ViewTransitions>`. See [#9279](https://github.com/withastro/astro/pull/9279) for more details. + +- [#9161](https://github.com/withastro/astro/pull/9161) [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299) Thanks [@bluwy](https://github.com/bluwy)! - Renames the `entryPoint` property of the `injectRoute` integrations API to `entrypoint` for consistency. A warning will be shown prompting you to update your code when using the old name. + +- [#9129](https://github.com/withastro/astro/pull/9129) [`8bfc20511`](https://github.com/withastro/astro/commit/8bfc20511918d675202cdc100d4efab293e5cbac) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Update error log formatting + +### Patch Changes + +- [#9118](https://github.com/withastro/astro/pull/9118) [`000e8f465`](https://github.com/withastro/astro/commit/000e8f4654cae9982e21e0a858366c4844139db6) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Redesign Dev Overlay main screen to show more information, such as the coolest integrations, your current Astro version and more. + +- [#9118](https://github.com/withastro/astro/pull/9118) [`000e8f465`](https://github.com/withastro/astro/commit/000e8f4654cae9982e21e0a858366c4844139db6) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fixes an issue where links with the same pathname as the current page, but different search params, were not prefetched. + +- [#9275](https://github.com/withastro/astro/pull/9275) [`0968cb1a3`](https://github.com/withastro/astro/commit/0968cb1a373b1101a649035d2ea2210d3d6412dc) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where html annotations relevant only to the dev server were included in the production build. + +- [#9252](https://github.com/withastro/astro/pull/9252) [`7b74ec4ba`](https://github.com/withastro/astro/commit/7b74ec4ba48e363a19d20e322212d0d264927f1b) Thanks [@ematipico](https://github.com/ematipico)! - Consistently emit fallback routes in the correct folders, and emit routes that consider `trailingSlash` + +- [#9222](https://github.com/withastro/astro/pull/9222) [`279e3c1b3`](https://github.com/withastro/astro/commit/279e3c1b3d06e7b48f01c0ef8285c3719ac74ace) Thanks [@matthewp](https://github.com/matthewp)! - Ensure the dev-overlay-window is anchored to the bottom + +- [#9292](https://github.com/withastro/astro/pull/9292) [`5428b3da0`](https://github.com/withastro/astro/commit/5428b3da08493d933981c4646d5d132fb31f0d25) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improves display for `astro preferences list` command + +- [#9235](https://github.com/withastro/astro/pull/9235) [`9c2342c32`](https://github.com/withastro/astro/commit/9c2342c327a13d2f7d1eb387b743e81f431b9813) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix SVG icons not showing properly in the extended dropdown menu of the dev overlay + +- [#9218](https://github.com/withastro/astro/pull/9218) [`f4401c8c1`](https://github.com/withastro/astro/commit/f4401c8c1fa203431b4e7b2e89381a91b4ef1ac6) Thanks [@matthewp](https://github.com/matthewp)! - Improve high contrast mode with the Dev Overlay + +- [#9254](https://github.com/withastro/astro/pull/9254) [`b750a161e`](https://github.com/withastro/astro/commit/b750a161e0e059de9cf814ce271d5891e4e97cbe) Thanks [@matthewp](https://github.com/matthewp)! - Improve highlight/tooltip positioning when in fixed positions + +- [#9230](https://github.com/withastro/astro/pull/9230) [`60cfa49e4`](https://github.com/withastro/astro/commit/60cfa49e445c926288612a6b1a30113ab988011c) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Update the look and feel of the dev overlay + +- [#9248](https://github.com/withastro/astro/pull/9248) [`43ddb5217`](https://github.com/withastro/astro/commit/43ddb5217691dc4112d8d98ae07511a8be6d4b94) Thanks [@martrapp](https://github.com/martrapp)! - Adds properties of the submit button (name, value) to the form data of a view transition + +- [#9170](https://github.com/withastro/astro/pull/9170) [`8a228fce0`](https://github.com/withastro/astro/commit/8a228fce0114daeea2100e50ddc5cf2ea0a03b5d) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Adds new accessibility audits to the Dev Toolbar's built-in Audits app. + + The audits Astro performs are non-exhaustive and only capable of detecting a handful of common accessibility issues. Please take care to perform a thorough, **manual** audit of your site to ensure compliance with the [Web Content Accessibility Guidelines (WCAG) international standard](https://www.w3.org/WAI/standards-guidelines/wcag/) _before_ publishing your site. + + 🧡 Huge thanks to the [Svelte](https://github.com/sveltejs/svelte) team for providing the basis of these accessibility audits! + +- [#9149](https://github.com/withastro/astro/pull/9149) [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c) Thanks [@bluwy](https://github.com/bluwy)! - Removes vendored Vite's `importMeta.d.ts` file in favour of Vite 5's new `vite/types/import-meta.d.ts` export + +- [#9295](https://github.com/withastro/astro/pull/9295) [`3d2dbb0e5`](https://github.com/withastro/astro/commit/3d2dbb0e5d2bf67b38ff8533d4dd938c94433812) Thanks [@matthewp](https://github.com/matthewp)! - Remove aria-query package + + This is another CJS-only package that breaks usage. + +- [#9274](https://github.com/withastro/astro/pull/9274) [`feaba2c7f`](https://github.com/withastro/astro/commit/feaba2c7fc0a48d3af7dd98e6b750ec1e8274e33) Thanks [@TheOtterlord](https://github.com/TheOtterlord)! - Fix routing prefixes when `prefixDefaultLocale` is `true` + +- [#9273](https://github.com/withastro/astro/pull/9273) [`9887f2412`](https://github.com/withastro/astro/commit/9887f241241f800e2907afe7079db070f3bfcfab) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Exports type for Dev Toolbar App under correct name + +- [#9150](https://github.com/withastro/astro/pull/9150) [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6) Thanks [@bluwy](https://github.com/bluwy)! - Refactors virtual modules exports. This should not break your project unless you import Astro's internal modules, including: + + - `astro/middleware/namespace` + - `astro/transitions` + - `astro/transitions/router` + - `astro/transitions/events` + - `astro/transitions/types` + - `astro/prefetch` + - `astro/i18n` + +- [#9227](https://github.com/withastro/astro/pull/9227) [`4b8a42406`](https://github.com/withastro/astro/commit/4b8a42406bbdcc68604ea4ecc2a926721fbc4d52) Thanks [@matthewp](https://github.com/matthewp)! - Ensure overlay x-ray z-index is higher than the island + +- [#9255](https://github.com/withastro/astro/pull/9255) [`9ea3e0b94`](https://github.com/withastro/astro/commit/9ea3e0b94f7c4813c52bffd78043f90fd87dffda) Thanks [@matthewp](https://github.com/matthewp)! - Adds instructions on how to hide the dev overlay + +- [#9293](https://github.com/withastro/astro/pull/9293) [`cf5fa4376`](https://github.com/withastro/astro/commit/cf5fa437627ca6978ae3ff33c7894f278dfe75cd) Thanks [@matthewp](https://github.com/matthewp)! - Removes the 'a11y-role-has-required-aria-props' audit rule + + This audit rule depends on a CommonJS module. To prevent blocking the 4.0 release the rule is being removed temporarily. + +- [#9214](https://github.com/withastro/astro/pull/9214) [`4fe523b00`](https://github.com/withastro/astro/commit/4fe523b0064b323ee46b2574339d96ea8bdb7b2d) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fixes a number of small user experience bugs with the dev overlay + +- [#9013](https://github.com/withastro/astro/pull/9013) [`ff8eadb95`](https://github.com/withastro/astro/commit/ff8eadb95d34833baaf3ec7575bf4f293eae97da) Thanks [@bayssmekanique](https://github.com/bayssmekanique)! - Returns the updated config in the integration `astro:config:setup` hook's `updateConfig()` API + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`addb57c8e`](https://github.com/withastro/astro/commit/addb57c8e80b7b67ec61224666f3a1db5c44410c), [`c7953645e`](https://github.com/withastro/astro/commit/c7953645eeaaf9e87c6db4494b0023d2c1878ff0)]: + - @astrojs/markdown-remark@4.0.0 + +## 4.0.0-beta.7 + +### Patch Changes + +- [#9295](https://github.com/withastro/astro/pull/9295) [`3d2dbb0e5`](https://github.com/withastro/astro/commit/3d2dbb0e5d2bf67b38ff8533d4dd938c94433812) Thanks [@matthewp](https://github.com/matthewp)! - Remove aria-query package + + This is another CJS-only package that breaks usage. + +## 4.0.0-beta.6 + +### Patch Changes + +- [#9275](https://github.com/withastro/astro/pull/9275) [`0968cb1a3`](https://github.com/withastro/astro/commit/0968cb1a373b1101a649035d2ea2210d3d6412dc) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where html annotations relevant only to the dev server were included in the production build. + +- [#9292](https://github.com/withastro/astro/pull/9292) [`5428b3da0`](https://github.com/withastro/astro/commit/5428b3da08493d933981c4646d5d132fb31f0d25) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improves display for `astro preferences list` command + +- [#9293](https://github.com/withastro/astro/pull/9293) [`cf5fa4376`](https://github.com/withastro/astro/commit/cf5fa437627ca6978ae3ff33c7894f278dfe75cd) Thanks [@matthewp](https://github.com/matthewp)! - Removes the 'a11y-role-has-required-aria-props' audit rule + + This audit rule depends on a CommonJS module. To prevent blocking the 4.0 release the rule is being removed temporarily. + +## 4.0.0-beta.5 + +### Minor Changes + +- [#9279](https://github.com/withastro/astro/pull/9279) [`6a9669b81`](https://github.com/withastro/astro/commit/6a9669b810ddfcae6c537165a438190ea1e7a4bc) Thanks [@martrapp](https://github.com/martrapp)! - Improves consistency between navigations with and without `<ViewTransitions>`. See [#9279](https://github.com/withastro/astro/pull/9279) for more details. + +### Patch Changes + +- [#9170](https://github.com/withastro/astro/pull/9170) [`8a228fce0`](https://github.com/withastro/astro/commit/8a228fce0114daeea2100e50ddc5cf2ea0a03b5d) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Adds new accessibility audits to the Dev Toolbar's built-in Audits app. + + The audits Astro performs are non-exhaustive and only capable of detecting a handful of common accessibility issues. Please take care to perform a thorough, **manual** audit of your site to ensure compliance with the [Web Content Accessibility Guidelines (WCAG) international standard](https://www.w3.org/WAI/standards-guidelines/wcag/) _before_ publishing your site. + + 🧡 Huge thanks to the [Svelte](https://github.com/sveltejs/svelte) team for providing the basis of these accessibility audits! + +- [#9274](https://github.com/withastro/astro/pull/9274) [`feaba2c7f`](https://github.com/withastro/astro/commit/feaba2c7fc0a48d3af7dd98e6b750ec1e8274e33) Thanks [@TheOtterlord](https://github.com/TheOtterlord)! - Fix routing prefixes when `prefixDefaultLocale` is `true` + +- [#9273](https://github.com/withastro/astro/pull/9273) [`9887f2412`](https://github.com/withastro/astro/commit/9887f241241f800e2907afe7079db070f3bfcfab) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Exports type for Dev Toolbar App under correct name + +## 4.0.0-beta.4 + +### Major Changes + +- [#9271](https://github.com/withastro/astro/pull/9271) [`47604bd5b`](https://github.com/withastro/astro/commit/47604bd5b5bb2ea63922b657bac104c010575c20) Thanks [@matthewp](https://github.com/matthewp)! - Renames Dev Overlay to Dev Toolbar + + The previously named experimental Dev Overlay is now known as the Astro Dev Toolbar. Plugins have been renamed as Toolbar Apps. This updates our references to reflect. + + To not break existing APIs, aliases for the Toolbar-based names have been created. The previous API names will continue to function but will be deprecated in the future. All documentation has been updated to reflect Toolbar-based names. + +## 4.0.0-beta.3 + +### Major Changes + +- [#9263](https://github.com/withastro/astro/pull/9263) [`3cbd8ea75`](https://github.com/withastro/astro/commit/3cbd8ea7534910e3beae396dcfa93ce87dcdd91f) Thanks [@bluwy](https://github.com/bluwy)! - Removes additional deprecated APIs: + + - The Astro preview server now returns a 404 status instead of a 301 redirect when requesting assets from the public directory without a base. + - Removes special handling when referencing the `astro/client-image` type. You should use the `astro/client` type instead. + - Removes deprecated built-in `rss` support in `getStaticPaths`. You should use `@astrojs/rss` instead. + - Removes deprecated `Astro.request.params` support. You should use `Astro.params` instead. + +### Minor Changes + +- [#9200](https://github.com/withastro/astro/pull/9200) [`b4b851f5a`](https://github.com/withastro/astro/commit/b4b851f5a46b32ee531db5dc39ccd2aa7af7bcfd) Thanks [@ematipico](https://github.com/ematipico)! - Adds a new way to configure the `i18n.locales` array. + + Developers can now assign a custom URL path prefix that can span multiple language codes: + + ```js + // astro.config.mjs + export default defineConfig({ + experimental: { + i18n: { + defaultLocale: 'english', + locales: ['de', { path: 'english', codes: ['en', 'en-US'] }, 'fr'], + routingStrategy: 'prefix-always', + }, + }, + }); + ``` + + With the above configuration, the URL prefix of the default locale will be `/english/`. When computing `Astro.preferredLocale`, Astro will use the `codes`. + +- [#9139](https://github.com/withastro/astro/pull/9139) [`459b26436`](https://github.com/withastro/astro/commit/459b2643666db08dbd29a100ce3d8697b451d3fe) Thanks [@bluwy](https://github.com/bluwy)! - Reworks Vite's logger to use Astro's logger to correctly log HMR messages + +### Patch Changes + +- [#9252](https://github.com/withastro/astro/pull/9252) [`7b74ec4ba`](https://github.com/withastro/astro/commit/7b74ec4ba48e363a19d20e322212d0d264927f1b) Thanks [@ematipico](https://github.com/ematipico)! - Consistently emit fallback routes in the correct folders, and emit routes that + consider `trailingSlash` + +- [#9235](https://github.com/withastro/astro/pull/9235) [`9c2342c32`](https://github.com/withastro/astro/commit/9c2342c327a13d2f7d1eb387b743e81f431b9813) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix SVG icons not showing properly in the extended dropdown menu of the dev overlay + +- [#9254](https://github.com/withastro/astro/pull/9254) [`b750a161e`](https://github.com/withastro/astro/commit/b750a161e0e059de9cf814ce271d5891e4e97cbe) Thanks [@matthewp](https://github.com/matthewp)! - Improve highlight/tooltip positioning when in fixed positions + +- [#9230](https://github.com/withastro/astro/pull/9230) [`60cfa49e4`](https://github.com/withastro/astro/commit/60cfa49e445c926288612a6b1a30113ab988011c) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Update the look and feel of the dev overlay + +- [#9248](https://github.com/withastro/astro/pull/9248) [`43ddb5217`](https://github.com/withastro/astro/commit/43ddb5217691dc4112d8d98ae07511a8be6d4b94) Thanks [@martrapp](https://github.com/martrapp)! - Adds properties of the submit button (name, value) to the form data of a view transition + +- [#9255](https://github.com/withastro/astro/pull/9255) [`9ea3e0b94`](https://github.com/withastro/astro/commit/9ea3e0b94f7c4813c52bffd78043f90fd87dffda) Thanks [@matthewp](https://github.com/matthewp)! - Adds instructions on how to hide the dev overlay + +- [#9013](https://github.com/withastro/astro/pull/9013) [`ff8eadb95`](https://github.com/withastro/astro/commit/ff8eadb95d34833baaf3ec7575bf4f293eae97da) Thanks [@bayssmekanique](https://github.com/bayssmekanique)! - Returns the updated config in the integration `astro:config:setup` hook's `updateConfig()` API + +## 4.0.0-beta.2 + +### Major Changes + +- [#9225](https://github.com/withastro/astro/pull/9225) [`c421a3d17`](https://github.com/withastro/astro/commit/c421a3d17911aeda29b5204f6d568ae87e329eaf) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Removes the opt-in `handleForms` property for `<ViewTransitions />`. Form submissions are now handled by default and can be disabled by setting `data-astro-reload` on relevant `<form />` elements. + +- [#9199](https://github.com/withastro/astro/pull/9199) [`49aa215a0`](https://github.com/withastro/astro/commit/49aa215a01ee1c4805316c85bb0aea6cfbc25a31) Thanks [@lilnasy](https://github.com/lilnasy)! - This change only affects maintainers of third-party adapters. In the Integration API, the `app.render()` method of the `App` class has been simplified. + + Instead of two optional arguments, it now takes a single optional argument that is an object with two optional properties: `routeData` and `locals`. + + ```diff + app.render(request) + + - app.render(request, routeData) + + app.render(request, { routeData }) + + - app.render(request, routeData, locals) + + app.render(request, { routeData, locals }) + + - app.render(request, undefined, locals) + + app.render(request, { locals }) + ``` + + The current signature is deprecated but will continue to function until next major version. + +- [#9212](https://github.com/withastro/astro/pull/9212) [`c0383ea0c`](https://github.com/withastro/astro/commit/c0383ea0c102cb62b7235823c706a090ba08715f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Removes deprecated `app.match()` option, `matchNotFound` + +### Minor Changes + +- [#9115](https://github.com/withastro/astro/pull/9115) [`3b77889b4`](https://github.com/withastro/astro/commit/3b77889b47750ed6e17c7858780dc4aae9201b58) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Adds the `astro preferences` command to manage user preferences. User preferences are specific to individual Astro users, unlike the `astro.config.mjs` file which changes behavior for everyone working on a project. + + User preferences are scoped to the current project by default, stored in a local `.astro/settings.json` file. Using the `--global` flag, user preferences can also be applied to every Astro project on the current machine. Global user preferences are stored in an operating system-specific location. + + ```sh + # Disable the dev overlay for the current user in the current project + npm run astro preferences disable devOverlay + # Disable the dev overlay for the current user in all Astro projects on this machine + npm run astro preferences --global disable devOverlay + + # Check if the dev overlay is enabled for the current user + npm run astro preferences list devOverlay + ``` + +- [#9129](https://github.com/withastro/astro/pull/9129) [`8bfc20511`](https://github.com/withastro/astro/commit/8bfc20511918d675202cdc100d4efab293e5cbac) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Update error log formatting + +### Patch Changes + +- [#9222](https://github.com/withastro/astro/pull/9222) [`279e3c1b3`](https://github.com/withastro/astro/commit/279e3c1b3d06e7b48f01c0ef8285c3719ac74ace) Thanks [@matthewp](https://github.com/matthewp)! - Ensure the dev-overlay-window is anchored to the bottom + +- [#9218](https://github.com/withastro/astro/pull/9218) [`f4401c8c1`](https://github.com/withastro/astro/commit/f4401c8c1fa203431b4e7b2e89381a91b4ef1ac6) Thanks [@matthewp](https://github.com/matthewp)! - Improve high contrast mode with the Dev Overlay + +- [#9227](https://github.com/withastro/astro/pull/9227) [`4b8a42406`](https://github.com/withastro/astro/commit/4b8a42406bbdcc68604ea4ecc2a926721fbc4d52) Thanks [@matthewp](https://github.com/matthewp)! - Ensure overlay x-ray z-index is higher than the island + +- [#9214](https://github.com/withastro/astro/pull/9214) [`4fe523b00`](https://github.com/withastro/astro/commit/4fe523b0064b323ee46b2574339d96ea8bdb7b2d) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fixes a number of small user experience bugs with the dev overlay + +## 4.0.0-beta.1 + +### Patch Changes + +- [#9118](https://github.com/withastro/astro/pull/9118) [`000e8f465`](https://github.com/withastro/astro/commit/000e8f4654cae9982e21e0a858366c4844139db6) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Redesign Dev Overlay main screen to show more information, such as the coolest integrations, your current Astro version and more. + +- [#9118](https://github.com/withastro/astro/pull/9118) [`000e8f465`](https://github.com/withastro/astro/commit/000e8f4654cae9982e21e0a858366c4844139db6) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fixes an issue where links with the same pathname as the current page, but different search params, were not prefetched. + +## 4.0.0-beta.0 + +### Major Changes + +- [#9138](https://github.com/withastro/astro/pull/9138) [`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3) Thanks [@bluwy](https://github.com/bluwy)! - Updates the unified, remark, and rehype dependencies to latest. Make sure to update your custom remark and rehype plugins as well to be compatible with the latest versions. + + **Potentially breaking change:** The default value of `markdown.remarkRehype.footnoteBackLabel` is changed from `"Back to content"` to `"Back to reference 1"`. See the `mdast-util-to-hast` [commit](https://github.com/syntax-tree/mdast-util-to-hast/commit/56c88e45690be138fad9f0bf367b939d09816863) for more information. + +- [#9181](https://github.com/withastro/astro/pull/9181) [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e) Thanks [@bluwy](https://github.com/bluwy)! - Removes support for returning simple objects from endpoints (deprecated since Astro 3.0). You should return a `Response` instead. + + `ResponseWithEncoding` is also removed. You can refactor the code to return a response with an array buffer instead, which is encoding agnostic. + + The types for middlewares have also been revised. To type a middleware function, you should now use `MiddlewareHandler` instead of `MiddlewareResponseHandler`. If you used `defineMiddleware()` to type the function, no changes are needed. + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +- [#9196](https://github.com/withastro/astro/pull/9196) [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6) Thanks [@bluwy](https://github.com/bluwy)! - Removes support for Shiki custom language's `path` property. The language JSON file should be imported and passed to the option instead. + + ```diff + // astro.config.js + + import customLang from './custom.tmLanguage.json' + + export default defineConfig({ + markdown: { + shikiConfig: { + langs: [ + - { path: './custom.tmLanguage.json' }, + + customLang, + ], + }, + }, + }) + ``` + +- [#9168](https://github.com/withastro/astro/pull/9168) [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17) Thanks [@bluwy](https://github.com/bluwy)! - Removes deprecated features from Astro 3.0 + + - Adapters are now required to pass `supportedAstroFeatures` to specify a list of features they support. + - The `build.split` and `build.excludeMiddleware` options are removed. Use `functionPerRoute` and `edgeMiddleware` from adapters instead. + - The `markdown.drafts` option and draft feature is removed. Use content collections instead. + - Lowercase endpoint names are no longer supported. Use uppercase endpoint names instead. + - `getHeaders()` exported from markdown files is removed. Use `getHeadings()` instead. + +### Minor Changes + +- [#9105](https://github.com/withastro/astro/pull/9105) [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Update CLI logging experience + +- [#9161](https://github.com/withastro/astro/pull/9161) [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299) Thanks [@bluwy](https://github.com/bluwy)! - Renames the `entryPoint` property of the `injectRoute` integrations API to `entrypoint` for consistency. A warning will be shown prompting you to update your code when using the old name. + +### Patch Changes + +- [#9149](https://github.com/withastro/astro/pull/9149) [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c) Thanks [@bluwy](https://github.com/bluwy)! - Removes vendored Vite's `importMeta.d.ts` file in favour of Vite 5's new `vite/types/import-meta.d.ts` export + +- [#9150](https://github.com/withastro/astro/pull/9150) [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6) Thanks [@bluwy](https://github.com/bluwy)! - Refactors virtual modules exports. This should not break your project unless you import Astro's internal modules, including: + + - `astro/middleware/namespace` + - `astro/transitions` + - `astro/transitions/router` + - `astro/transitions/events` + - `astro/transitions/types` + - `astro/prefetch` + - `astro/i18n` + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`addb57c8e`](https://github.com/withastro/astro/commit/addb57c8e80b7b67ec61224666f3a1db5c44410c), [`c7953645e`](https://github.com/withastro/astro/commit/c7953645eeaaf9e87c6db4494b0023d2c1878ff0)]: + - @astrojs/markdown-remark@4.0.0-beta.0 + +## 3.6.4 + +### Patch Changes + +- [#9226](https://github.com/withastro/astro/pull/9226) [`8f8a40e93`](https://github.com/withastro/astro/commit/8f8a40e93d6a0774ba84a6f5db8c42cd81db005e) Thanks [@outofambit](https://github.com/outofambit)! - Fix i18n fallback routing with routing strategy of always-prefix + +- [#9179](https://github.com/withastro/astro/pull/9179) [`3f28336d9`](https://github.com/withastro/astro/commit/3f28336d9a52d7e4364d455ee3128d14d10a078a) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where the presence of a slot in a page led to an error. + +- [#9219](https://github.com/withastro/astro/pull/9219) [`067a65f5b`](https://github.com/withastro/astro/commit/067a65f5b4d163bf1944cf47e6bf891f0b93553f) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Fix edge case where `<style>` updates inside of `.astro` files would ocassionally fail to update without reloading the page. + +- [#9236](https://github.com/withastro/astro/pull/9236) [`27d3e86e4`](https://github.com/withastro/astro/commit/27d3e86e4c8d04101113ab7a53477f26a4fb0619) Thanks [@ematipico](https://github.com/ematipico)! - The configuration `i18n.routingStrategy` has been replaced with an object called `routing`. + + ```diff + export default defineConfig({ + experimental: { + i18n: { + - routingStrategy: "prefix-always", + + routing: { + + prefixDefaultLocale: true, + + } + } + } + }) + ``` + + ```diff + export default defineConfig({ + experimental: { + i18n: { + - routingStrategy: "prefix-other-locales", + + routing: { + + prefixDefaultLocale: false, + + } + } + } + }) + ``` + +## 3.6.3 + +### Patch Changes + +- [#9193](https://github.com/withastro/astro/pull/9193) [`0dc99c9a2`](https://github.com/withastro/astro/commit/0dc99c9a28fcb6b46db49eefac6afa415875edcb) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Prevents the Code component from crashing if the lang isn't supported by falling back to `plaintext`. + +## 3.6.2 + +### Patch Changes + +- [#9189](https://github.com/withastro/astro/pull/9189) [`d90714fc3`](https://github.com/withastro/astro/commit/d90714fc3dd7c3eab0a6b29319b0b666bb04b678) Thanks [@SpencerWhitehead7](https://github.com/SpencerWhitehead7)! - Fixes an issue where links with the same pathname as the current page, but different search params, were not prefetched. + +## 3.6.4 + +### Patch Changes + +- [#9226](https://github.com/withastro/astro/pull/9226) [`8f8a40e93`](https://github.com/withastro/astro/commit/8f8a40e93d6a0774ba84a6f5db8c42cd81db005e) Thanks [@outofambit](https://github.com/outofambit)! - Fix i18n fallback routing with routing strategy of always-prefix + +- [#9179](https://github.com/withastro/astro/pull/9179) [`3f28336d9`](https://github.com/withastro/astro/commit/3f28336d9a52d7e4364d455ee3128d14d10a078a) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where the presence of a slot in a page led to an error. + +- [#9219](https://github.com/withastro/astro/pull/9219) [`067a65f5b`](https://github.com/withastro/astro/commit/067a65f5b4d163bf1944cf47e6bf891f0b93553f) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Fix edge case where `<style>` updates inside of `.astro` files would ocassionally fail to update without reloading the page. + +- [#9236](https://github.com/withastro/astro/pull/9236) [`27d3e86e4`](https://github.com/withastro/astro/commit/27d3e86e4c8d04101113ab7a53477f26a4fb0619) Thanks [@ematipico](https://github.com/ematipico)! - The configuration `i18n.routingStrategy` has been replaced with an object called `routing`. + + ```diff + export default defineConfig({ + experimental: { + i18n: { + - routingStrategy: "prefix-always", + + routing: { + + prefixDefaultLocale: true, + + } + } + } + }) + ``` + + ```diff + export default defineConfig({ + experimental: { + i18n: { + - routingStrategy: "prefix-other-locales", + + routing: { + + prefixDefaultLocale: false, + + } + } + } + }) + ``` + +## 3.6.3 + +### Patch Changes + +- [#9193](https://github.com/withastro/astro/pull/9193) [`0dc99c9a2`](https://github.com/withastro/astro/commit/0dc99c9a28fcb6b46db49eefac6afa415875edcb) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Prevents the Code component from crashing if the lang isn't supported by falling back to `plaintext`. + +## 3.6.2 + +### Patch Changes + +- [#9189](https://github.com/withastro/astro/pull/9189) [`d90714fc3`](https://github.com/withastro/astro/commit/d90714fc3dd7c3eab0a6b29319b0b666bb04b678) Thanks [@SpencerWhitehead7](https://github.com/SpencerWhitehead7)! - Fixes an issue where links with the same pathname as the current page, but different search params, were not prefetched. + +## 3.6.1 + +### Patch Changes + +- [#9173](https://github.com/withastro/astro/pull/9173) [`04fdc1c61`](https://github.com/withastro/astro/commit/04fdc1c613171409ed1a2bd887326e26cdb8b5ef) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where having a middleware prevented the SSR app from being deployed on Netlify. + +- [#9186](https://github.com/withastro/astro/pull/9186) [`607542c7c`](https://github.com/withastro/astro/commit/607542c7cf9fe9813c06f1d96615d6c793262d22) Thanks [@martrapp](https://github.com/martrapp)! - Fixes a view transition issue on webKit browsers that prevented scrolling to #fragments + +## 3.6.0 + +### Minor Changes + +- [#9090](https://github.com/withastro/astro/pull/9090) [`c87223c21`](https://github.com/withastro/astro/commit/c87223c21ab5d515fb8f04ee10be5c0ca51e0b29) Thanks [@martrapp](https://github.com/martrapp)! - Take full control over the behavior of view transitions! + + Three new events now complement the existing `astro:after-swap` and `astro:page-load` events: + + ```javascript + 'astro:before-preparation'; // Control how the DOM and other resources of the target page are loaded + 'astro:after-preparation'; // Last changes before taking off? Remove that loading indicator? Here you go! + 'astro:before-swap'; // Control how the DOM is updated to match the new page + ``` + + The `astro:before-*` events allow you to change properties and strategies of the view transition implementation. + The `astro:after-*` events are notifications that a phase is complete. + Head over to docs to see [the full view transitions lifecycle](https://docs.astro.build/en/guides/view-transitions/#lifecycle-events) including these new events! + +- [#9092](https://github.com/withastro/astro/pull/9092) [`0ea4bd47e`](https://github.com/withastro/astro/commit/0ea4bd47e0d7cc98c43568a55aa87da772bd2e0a) Thanks [@smitbarmase](https://github.com/smitbarmase)! - Changes the fallback prefetch behavior on slow connections and when data saver mode is enabled. Instead of disabling prefetch entirely, the `tap` strategy will be used. + +- [#9166](https://github.com/withastro/astro/pull/9166) [`cba6cf32d`](https://github.com/withastro/astro/commit/cba6cf32d9bf1f5c3268808f185a4824d6fbd7f4) Thanks [@matthewp](https://github.com/matthewp)! - The Picture component is no longer experimental + + The `<Picture />` component, part of `astro:assets`, has exited experimental status and is now recommended for use. There are no code changes to the component, and no upgrade to your project is necessary. + + This is only a change in documentation/recommendation. If you were waiting to use the `<Picture />` component until it had exited the experimental stage, wait no more! + +- [#9092](https://github.com/withastro/astro/pull/9092) [`0ea4bd47e`](https://github.com/withastro/astro/commit/0ea4bd47e0d7cc98c43568a55aa87da772bd2e0a) Thanks [@smitbarmase](https://github.com/smitbarmase)! - Adds a `ignoreSlowConnection` option to the `prefetch()` API to prefetch even on data saver mode or slow connection. + +## 3.5.7 + +### Patch Changes + +- [#9157](https://github.com/withastro/astro/pull/9157) [`7ff8d62bf`](https://github.com/withastro/astro/commit/7ff8d62bf861694067491ff17d01b1b0f6809d6b) Thanks [@ematipico](https://github.com/ematipico)! - Revert fix around fallback system, which broken injected styles + +## 3.5.6 + +### Patch Changes + +- [#9121](https://github.com/withastro/astro/pull/9121) [`f4efd1c80`](https://github.com/withastro/astro/commit/f4efd1c808476c7e60fe00fcfb86276cf14fee79) Thanks [@peng](https://github.com/peng)! - Adds a warning if `astro add` fetches a package but returns a non-404 status + +- [#9142](https://github.com/withastro/astro/pull/9142) [`7d55cf68d`](https://github.com/withastro/astro/commit/7d55cf68d89cb46bfb89a109b09af61be8431c89) Thanks [@ematipico](https://github.com/ematipico)! - Consistely emit fallback routes in the correct folders. + +- [#9119](https://github.com/withastro/astro/pull/9119) [`306781795`](https://github.com/withastro/astro/commit/306781795d5f4b755bbdf650a937f1f3c00030bd) Thanks [@ematipico](https://github.com/ematipico)! - Fix a flaw in the i18n fallback logic, where the routes didn't preserve their metadata, such as hoisted scripts + +- [#9140](https://github.com/withastro/astro/pull/9140) [`7742fd7dc`](https://github.com/withastro/astro/commit/7742fd7dc26533c6f7cd497b00b72de935c57628) Thanks [@martrapp](https://github.com/martrapp)! - View Transitions: handle clicks on SVGAElements and image maps" + +- [#9101](https://github.com/withastro/astro/pull/9101) [`e3dce215a`](https://github.com/withastro/astro/commit/e3dce215a5ea06bcff1b21027e5613e6518c69d4) Thanks [@ematipico](https://github.com/ematipico)! - Add a new property `Astro.currentLocale`, available when `i18n` is enabled. + ## 3.5.5 ### Patch Changes diff --git a/packages/astro/astro-jsx.d.ts b/packages/astro/astro-jsx.d.ts index 3e8a868892827..46202644a6a50 100644 --- a/packages/astro/astro-jsx.d.ts +++ b/packages/astro/astro-jsx.d.ts @@ -36,6 +36,7 @@ declare namespace astroHTML.JSX { AstroDefineVarsAttribute; type AstroStyleAttributes = import('./dist/@types/astro.js').AstroStyleAttributes & AstroDefineVarsAttribute; + type AstroSlotAttributes = import('./dist/@types/astro.js').AstroSlotAttributes; // This is an unfortunate use of `any`, but unfortunately we can't make a type that works for every framework // without importing every single framework's types (which comes with its own set of problems). @@ -516,7 +517,8 @@ declare namespace astroHTML.JSX { | 'search' | 'send' | undefined - | null; + | null; + exportparts?: string | undefined | null; hidden?: boolean | string | undefined | null; id?: string | undefined | null; inert?: boolean | string | undefined | null; @@ -532,18 +534,23 @@ declare namespace astroHTML.JSX { | undefined | null; is?: string | undefined | null; + + // Microdata API itemid?: string | undefined | null; itemprop?: string | undefined | null; itemref?: string | undefined | null; itemscope?: boolean | string | undefined | null; itemtype?: string | undefined | null; + lang?: string | undefined | null; + part?: string | undefined | null; + popover?: boolean | string | undefined | null; slot?: string | undefined | null; spellcheck?: 'true' | 'false' | boolean | undefined | null; style?: string | StyleObject | undefined | null; tabindex?: number | string | undefined | null; title?: string | undefined | null; - translate?: 'yes' | 'no' | undefined | null; + translate?: 'yes' | 'no' | '' | undefined | null; // <command>, <menuitem> radiogroup?: string | undefined | null; @@ -1415,7 +1422,7 @@ declare namespace astroHTML.JSX { ruby: HTMLAttributes; s: HTMLAttributes; samp: HTMLAttributes; - slot: SlotHTMLAttributes; + slot: SlotHTMLAttributes & AstroSlotAttributes; script: ScriptHTMLAttributes & AstroScriptAttributes; section: HTMLAttributes; select: SelectHTMLAttributes; diff --git a/packages/astro/astro.js b/packages/astro/astro.js index e067b9dd9b551..059024621a286 100755 --- a/packages/astro/astro.js +++ b/packages/astro/astro.js @@ -67,7 +67,7 @@ Please upgrade Node.js to a supported version: "${engines}"\n`); console.log( `${ci.name} CI Environment Detected!\nAdditional steps may be needed to set your Node.js version:` ); - console.log(`Documentation: https://docs.astro.build/guides/deploy`); + console.log(`Documentation: https://docs.astro.build/en/guides/deploy/`); if (CI_INSTRUCTIONS[platform]) { console.log(`${ci.name} Documentation: ${CI_INSTRUCTIONS[platform]}`); } diff --git a/packages/astro/client.d.ts b/packages/astro/client.d.ts index f2af4a88c0a1c..3b30d77008861 100644 --- a/packages/astro/client.d.ts +++ b/packages/astro/client.d.ts @@ -1,4 +1,4 @@ -/// <reference path="./import-meta.d.ts" /> +/// <reference types="vite/types/import-meta.d.ts" /> // eslint-disable-next-line @typescript-eslint/no-namespace declare namespace App { @@ -106,33 +106,55 @@ declare module '*.avif' { } declare module 'astro:transitions' { - type TransitionModule = typeof import('./dist/transitions/index.js'); + type TransitionModule = typeof import('./dist/virtual-modules/transitions.js'); export const slide: TransitionModule['slide']; export const fade: TransitionModule['fade']; + export const createAnimationScope: TransitionModule['createAnimationScope']; type ViewTransitionsModule = typeof import('./components/ViewTransitions.astro'); export const ViewTransitions: ViewTransitionsModule['default']; } declare module 'astro:transitions/client' { - type TransitionRouterModule = typeof import('./dist/transitions/router.js'); - export const supportsViewTransitions: TransitionRouterModule['supportsViewTransitions']; - export const transitionEnabledOnThisPage: TransitionRouterModule['transitionEnabledOnThisPage']; + type TransitionRouterModule = typeof import('./dist/virtual-modules/transitions-router.js'); export const navigate: TransitionRouterModule['navigate']; - export type Options = import('./dist/transitions/router.js').Options; + + type TransitionUtilModule = typeof import('./dist/virtual-modules/transitions-util.js'); + export const supportsViewTransitions: TransitionUtilModule['supportsViewTransitions']; + export const getFallback: TransitionUtilModule['getFallback']; + export const transitionEnabledOnThisPage: TransitionUtilModule['transitionEnabledOnThisPage']; + + export type Fallback = import('./dist/virtual-modules/transitions-types.js').Fallback; + export type Direction = import('./dist/virtual-modules/transitions-types.ts').Direction; + export type NavigationTypeString = + import('./dist/virtual-modules/transitions-types.js').NavigationTypeString; + export type Options = import('./dist/virtual-modules/transitions-types.js').Options; + + type EventModule = typeof import('./dist/virtual-modules/transitions-events.js'); + export const TRANSITION_BEFORE_PREPARATION: EventModule['TRANSITION_BEFORE_PREPARATION']; + export const TRANSITION_AFTER_PREPARATION: EventModule['TRANSITION_AFTER_PREPARATION']; + export const TRANSITION_BEFORE_SWAP: EventModule['TRANSITION_BEFORE_SWAP']; + export const TRANSITION_AFTER_SWAP: EventModule['TRANSITION_AFTER_SWAP']; + export const TRANSITION_PAGE_LOAD: EventModule['TRANSITION_PAGE_LOAD']; + export type TransitionBeforePreparationEvent = + import('./dist/virtual-modules/transitions-events.js').TransitionBeforePreparationEvent; + export type TransitionBeforeSwapEvent = + import('./dist/virtual-modules/transitions-events.js').TransitionBeforeSwapEvent; + export const isTransitionBeforePreparationEvent: EventModule['isTransitionBeforePreparationEvent']; + export const isTransitionBeforeSwapEvent: EventModule['isTransitionBeforeSwapEvent']; } declare module 'astro:prefetch' { - export { prefetch, PrefetchOptions } from 'astro/prefetch'; + export { prefetch, PrefetchOptions } from 'astro/virtual-modules/prefetch.js'; } declare module 'astro:i18n' { - export type GetLocaleOptions = import('./dist/i18n/index.js').GetLocaleOptions; + export type GetLocaleOptions = import('./dist/virtual-modules/i18n.js').GetLocaleOptions; /** * @param {string} locale A locale * @param {string} [path=""] An optional path to add after the `locale`. - * @param {import('./dist/i18n/index.js').GetLocaleOptions} options Customise the generated path + * @param {import('./dist/virtual-modules/i18n.js').GetLocaleOptions} options Customise the generated path * @return {string} * * Returns a _relative_ path with passed locale. @@ -161,7 +183,7 @@ declare module 'astro:i18n' { * * @param {string} locale A locale * @param {string} [path=""] An optional path to add after the `locale`. - * @param {import('./dist/i18n/index.js').GetLocaleOptions} options Customise the generated path + * @param {import('./dist/virtual-modules/i18n.js').GetLocaleOptions} options Customise the generated path * @return {string} * * Returns an absolute path with the passed locale. The behaviour is subject to change based on `site` configuration. @@ -191,7 +213,7 @@ declare module 'astro:i18n' { /** * @param {string} [path=""] An optional path to add after the `locale`. - * @param {import('./dist/i18n/index.js').GetLocaleOptions} options Customise the generated path + * @param {import('./dist/virtual-modules/i18n.js').GetLocaleOptions} options Customise the generated path * @return {string[]} * * Works like `getRelativeLocaleUrl` but it emits the relative URLs for ALL locales: @@ -199,16 +221,79 @@ declare module 'astro:i18n' { export const getRelativeLocaleUrlList: (path?: string, options?: GetLocaleOptions) => string[]; /** * @param {string} [path=""] An optional path to add after the `locale`. - * @param {import('./dist/i18n/index.js').GetLocaleOptions} options Customise the generated path + * @param {import('./dist/virtual-modules/i18n.js').GetLocaleOptions} options Customise the generated path * @return {string[]} * * Works like `getAbsoluteLocaleUrl` but it emits the absolute URLs for ALL locales: */ export const getAbsoluteLocaleUrlList: (path?: string, options?: GetLocaleOptions) => string[]; + + /** + * A function that return the `path` associated to a locale (defined as code). It's particularly useful in case you decide + * to use locales that are broken down in paths and codes. + * + * @param {string} code The code of the locale + * @returns {string} The path associated to the locale + * + * ## Example + * + * ```js + * // astro.config.mjs + * + * export default defineConfig({ + * i18n: { + * locales: [ + * { codes: ["it", "it-VT"], path: "italiano" }, + * "es" + * ] + * } + * }) + * ``` + * + * ```js + * import { getPathByLocale } from "astro:i18n"; + * getPathByLocale("it"); // returns "italiano" + * getPathByLocale("it-VT"); // returns "italiano" + * getPathByLocale("es"); // returns "es" + * ``` + */ + export const getPathByLocale: (code: string) => string; + + /** + * A function that returns the preferred locale given a certain path. This is particularly useful if you configure a locale using + * `path` and `codes`. When you define multiple `code`, this function will return the first code of the array. + * + * Astro will treat the first code as the one that the user prefers. + * + * @param {string} path The path that maps to a locale + * @returns {string} The path associated to the locale + * + * ## Example + * + * ```js + * // astro.config.mjs + * + * export default defineConfig({ + * i18n: { + * locales: [ + * { codes: ["it-VT", "it"], path: "italiano" }, + * "es" + * ] + * } + * }) + * ``` + * + * ```js + * import { getLocaleByPath } from "astro:i18n"; + * getLocaleByPath("italiano"); // returns "it-VT" because that's the first code configured + * getLocaleByPath("es"); // returns "es" + * ``` + */ + export const getLocaleByPath: (path: string) => string; } declare module 'astro:middleware' { - export * from 'astro/middleware/namespace'; + export * from 'astro/virtual-modules/middleware.js'; } declare module 'astro:components' { @@ -221,8 +306,6 @@ interface ExportedMarkdownModuleEntities { file: MD['file']; url: MD['url']; getHeadings: MD['getHeadings']; - /** @deprecated Renamed to `getHeadings()` */ - getHeaders: () => void; Content: MD['Content']; rawContent: MD['rawContent']; compiledContent: MD['compiledContent']; diff --git a/packages/astro/components/Code.astro b/packages/astro/components/Code.astro index 506a3ed3c0d19..44d81b7144f10 100644 --- a/packages/astro/components/Code.astro +++ b/packages/astro/components/Code.astro @@ -1,7 +1,4 @@ --- -import path from 'node:path'; -import fs from 'node:fs'; -import { fileURLToPath } from 'node:url'; import type { BuiltinLanguage, BuiltinTheme, @@ -10,6 +7,7 @@ import type { ThemeRegistration, ThemeRegistrationRaw, } from 'shikiji'; +import { bundledLanguages } from 'shikiji/langs'; import { getCachedHighlighter } from '../dist/core/shiki.js'; interface Props { @@ -64,23 +62,6 @@ const { // shiki -> shikiji compat if (typeof lang === 'object') { - // shikiji does not support `path` - // https://github.com/shikijs/shiki/blob/facb6ff37996129626f8066a5dccb4608e45f649/packages/shiki/src/loader.ts#L98 - const langPath = (lang as any).path; - if (langPath) { - // shiki resolves path from within its package directory :shrug: - const astroRoot = fileURLToPath(new URL('../', import.meta.url)); - const normalizedPath = path.isAbsolute(langPath) ? langPath : path.resolve(astroRoot, langPath); - try { - const content = fs.readFileSync(normalizedPath, 'utf-8'); - const parsed = JSON.parse(content); - Object.assign(lang, parsed); - } catch (e) { - throw new Error(`Unable to find language file at ${normalizedPath}`, { - cause: e, - }); - } - } // `id` renamed to `name` (always override) if ((lang as any).id) { lang.name = (lang as any).id; @@ -92,7 +73,13 @@ if (typeof lang === 'object') { } const highlighter = await getCachedHighlighter({ - langs: [lang], + langs: [ + typeof lang === 'string' + ? Object.keys(bundledLanguages).includes(lang) + ? lang + : 'plaintext' + : lang, + ], theme, experimentalThemes, wrap, diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro index 089d8d8e554e8..310f1865a92cb 100644 --- a/packages/astro/components/ViewTransitions.astro +++ b/packages/astro/components/ViewTransitions.astro @@ -3,10 +3,14 @@ type Fallback = 'none' | 'animate' | 'swap'; export interface Props { fallback?: Fallback; + /** @deprecated handleForms is enabled by default in Astro 4.0 + * + * Set `data-astro-reload` on your form to opt-out of the default behavior. + */ handleForms?: boolean; } -const { fallback = 'animate', handleForms } = Astro.props; +const { fallback = 'animate' } = Astro.props; --- <style is:global> @@ -25,14 +29,14 @@ const { fallback = 'animate', handleForms } = Astro.props; </style> <meta name="astro-view-transitions-enabled" content="true" /> <meta name="astro-view-transitions-fallback" content={fallback} /> -{handleForms ? <meta name="astro-view-transitions-forms" content="true" /> : ''} <script> import type { Options } from 'astro:transitions/client'; import { supportsViewTransitions, navigate } from 'astro:transitions/client'; - // NOTE: import from `astro/prefetch` as `astro:prefetch` requires the `prefetch` config to be enabled - import { init } from 'astro/prefetch'; + // NOTE: import from `astro/virtual-modules/prefetch.js` as `astro:prefetch` requires the `prefetch` config to be enabled + // @ts-ignore + import { init } from 'astro/virtual-modules/prefetch.js'; - export type Fallback = 'none' | 'animate' | 'swap'; + type Fallback = 'none' | 'animate' | 'swap'; function getFallback(): Fallback { const el = document.querySelector('[name="astro-view-transitions-fallback"]'); @@ -42,27 +46,34 @@ const { fallback = 'animate', handleForms } = Astro.props; return 'animate'; } - function isReloadEl(el: HTMLElement): boolean { + function isReloadEl(el: HTMLElement | SVGAElement): boolean { return el.dataset.astroReload !== undefined; } if (supportsViewTransitions || getFallback() !== 'none') { document.addEventListener('click', (ev) => { let link = ev.target; - if (link instanceof Element && link.tagName !== 'A') { - link = link.closest('a'); + if (link instanceof Element) { + link = link.closest('a, area'); } + if ( + !(link instanceof HTMLAnchorElement) && + !(link instanceof SVGAElement) && + !(link instanceof HTMLAreaElement) + ) + return; // This check verifies that the click is happening on an anchor // that is going to another page within the same origin. Basically it determines // same-origin navigation, but omits special key combos for new tabs, etc. + const linkTarget = link instanceof HTMLElement ? link.target : link.target.baseVal; + const href = link instanceof HTMLElement ? link.href : link.href.baseVal; + const origin = new URL(href, location.href).origin; if ( - !link || - !(link instanceof HTMLAnchorElement) || isReloadEl(link) || link.hasAttribute('download') || !link.href || - (link.target && link.target !== '_self') || - link.origin !== location.origin || + (linkTarget && linkTarget !== '_self') || + origin !== location.origin || ev.button !== 0 || // left clicks only ev.metaKey || // new tab (mac) ev.ctrlKey || // new tab (windows) @@ -75,38 +86,43 @@ const { fallback = 'animate', handleForms } = Astro.props; return; } ev.preventDefault(); - navigate(link.href, { + navigate(href, { history: link.dataset.astroHistory === 'replace' ? 'replace' : 'auto', + sourceElement: link, }); }); - if (document.querySelector('[name="astro-view-transitions-forms"]')) { - document.addEventListener('submit', (ev) => { - let el = ev.target as HTMLElement; - if (el.tagName !== 'FORM' || isReloadEl(el)) { - return; - } + document.addEventListener('submit', (ev) => { + let el = ev.target as HTMLElement; + if (el.tagName !== 'FORM' || isReloadEl(el)) { + return; + } + const form = el as HTMLFormElement; + const submitter = ev.submitter; + const formData = new FormData(form, submitter); + // Use the form action, if defined, otherwise fallback to current path. + let action = submitter?.getAttribute('formaction') ?? form.action ?? location.pathname; + const method = submitter?.getAttribute('formmethod') ?? form.method; + + // the "dialog" method is a special keyword used within <dialog> elements + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-method + if (method === 'dialog') { + return; + } - const form = el as HTMLFormElement; - const submitter = ev.submitter; - const formData = new FormData(form); - // Use the form action, if defined, otherwise fallback to current path. - let action = submitter?.getAttribute('formaction') ?? form.action ?? location.pathname; - const method = submitter?.getAttribute('formmethod') ?? form.method; + const options: Options = { sourceElement: submitter ?? form }; + if (method === 'get') { + const params = new URLSearchParams(formData as any); + const url = new URL(action); + url.search = params.toString(); + action = url.toString(); + } else { + options.formData = formData; + } - const options: Options = {}; - if (method === 'get') { - const params = new URLSearchParams(formData as any); - const url = new URL(action); - url.search = params.toString(); - action = url.toString(); - } else { - options.formData = formData; - } - ev.preventDefault(); - navigate(action, options); - }); - } + ev.preventDefault(); + navigate(action, options); + }); // @ts-expect-error injected by vite-plugin-transitions for treeshaking if (!__PREFETCH_DISABLED__) { diff --git a/packages/astro/e2e/astro-envs.test.js b/packages/astro/e2e/astro-envs.test.js index 50cff6e895579..cf8a1d304259d 100644 --- a/packages/astro/e2e/astro-envs.test.js +++ b/packages/astro/e2e/astro-envs.test.js @@ -1,7 +1,12 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/astro-envs/' }); +const test = testFactory({ + root: './fixtures/astro-envs/', + devToolbar: { + enabled: false, + }, +}); let devServer; diff --git a/packages/astro/e2e/css.test.js b/packages/astro/e2e/css.test.js index 3e0486d0f3691..fff197a39246d 100644 --- a/packages/astro/e2e/css.test.js +++ b/packages/astro/e2e/css.test.js @@ -3,6 +3,9 @@ import { testFactory } from './test-utils.js'; const test = testFactory({ root: './fixtures/css/', + devToolbar: { + enabled: false, + }, }); let devServer; diff --git a/packages/astro/e2e/dev-overlay.test.js b/packages/astro/e2e/dev-overlay.test.js index 1a358487cb27b..b61a3e10e7568 100644 --- a/packages/astro/e2e/dev-overlay.test.js +++ b/packages/astro/e2e/dev-overlay.test.js @@ -19,14 +19,14 @@ test.describe('Dev Overlay', () => { test('dev overlay exists in the page', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); - const devOVerlay = page.locator('astro-dev-overlay'); - await expect(devOVerlay).toHaveCount(1); + const devToolbar = page.locator('astro-dev-toolbar'); + await expect(devToolbar).toHaveCount(1); }); test('shows plugin name on hover', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); - const overlay = page.locator('astro-dev-overlay'); + const overlay = page.locator('astro-dev-toolbar'); const pluginButton = overlay.locator('button[data-plugin-id="astro"]'); const pluginButtonTooltip = pluginButton.locator('.item-tooltip'); await pluginButton.hover(); @@ -37,14 +37,14 @@ test.describe('Dev Overlay', () => { test('can open Astro plugin', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); - const overlay = page.locator('astro-dev-overlay'); + const overlay = page.locator('astro-dev-toolbar'); const pluginButton = overlay.locator('button[data-plugin-id="astro"]'); await pluginButton.click(); const astroPluginCanvas = overlay.locator( - 'astro-dev-overlay-plugin-canvas[data-plugin-id="astro"]' + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro"]' ); - const astroWindow = astroPluginCanvas.locator('astro-dev-overlay-window'); + const astroWindow = astroPluginCanvas.locator('astro-dev-toolbar-window'); await expect(astroWindow).toHaveCount(1); await expect(astroWindow).toBeVisible(); @@ -56,18 +56,18 @@ test.describe('Dev Overlay', () => { test('xray shows highlights and tooltips', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); - const overlay = page.locator('astro-dev-overlay'); + const overlay = page.locator('astro-dev-toolbar'); const pluginButton = overlay.locator('button[data-plugin-id="astro:xray"]'); await pluginButton.click(); const xrayCanvas = overlay.locator( - 'astro-dev-overlay-plugin-canvas[data-plugin-id="astro:xray"]' + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:xray"]' ); - const xrayHighlight = xrayCanvas.locator('astro-dev-overlay-highlight'); + const xrayHighlight = xrayCanvas.locator('astro-dev-toolbar-highlight'); await expect(xrayHighlight).toBeVisible(); await xrayHighlight.hover(); - const xrayHighlightTooltip = xrayHighlight.locator('astro-dev-overlay-tooltip'); + const xrayHighlightTooltip = xrayHighlight.locator('astro-dev-toolbar-tooltip'); await expect(xrayHighlightTooltip).toBeVisible(); // Toggle plugin off @@ -76,21 +76,41 @@ test.describe('Dev Overlay', () => { await expect(xrayHighlightTooltip).not.toBeVisible(); }); + test('xray shows no islands message when there are none', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/xray-no-islands')); + + const overlay = page.locator('astro-dev-toolbar'); + const pluginButton = overlay.locator('button[data-plugin-id="astro:xray"]'); + await pluginButton.click(); + + const xrayCanvas = overlay.locator( + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:xray"]' + ); + const auditHighlight = xrayCanvas.locator('astro-dev-toolbar-highlight'); + await expect(auditHighlight).not.toBeVisible(); + + const xrayWindow = xrayCanvas.locator('astro-dev-toolbar-window'); + await expect(xrayWindow).toHaveCount(1); + await expect(xrayWindow).toBeVisible(); + + await expect(xrayWindow.locator('astro-dev-toolbar-icon[icon=lightbulb]')).toBeVisible(); + }); + test('audit shows higlights and tooltips', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); - const overlay = page.locator('astro-dev-overlay'); + const overlay = page.locator('astro-dev-toolbar'); const pluginButton = overlay.locator('button[data-plugin-id="astro:audit"]'); await pluginButton.click(); const auditCanvas = overlay.locator( - 'astro-dev-overlay-plugin-canvas[data-plugin-id="astro:audit"]' + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:audit"]' ); - const auditHighlight = auditCanvas.locator('astro-dev-overlay-highlight'); + const auditHighlight = auditCanvas.locator('astro-dev-toolbar-highlight'); await expect(auditHighlight).toBeVisible(); await auditHighlight.hover(); - const auditHighlightTooltip = auditHighlight.locator('astro-dev-overlay-tooltip'); + const auditHighlightTooltip = auditHighlight.locator('astro-dev-toolbar-tooltip'); await expect(auditHighlightTooltip).toBeVisible(); // Toggle plugin off @@ -99,17 +119,37 @@ test.describe('Dev Overlay', () => { await expect(auditHighlightTooltip).not.toBeVisible(); }); + test('audit shows no issues message when there are no issues', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/audit-no-warning')); + + const overlay = page.locator('astro-dev-toolbar'); + const pluginButton = overlay.locator('button[data-plugin-id="astro:audit"]'); + await pluginButton.click(); + + const auditCanvas = overlay.locator( + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:audit"]' + ); + const auditHighlight = auditCanvas.locator('astro-dev-toolbar-highlight'); + await expect(auditHighlight).not.toBeVisible(); + + const auditWindow = auditCanvas.locator('astro-dev-toolbar-window'); + await expect(auditWindow).toHaveCount(1); + await expect(auditWindow).toBeVisible(); + + await expect(auditWindow.locator('astro-dev-toolbar-icon[icon=check-circle]')).toBeVisible(); + }); + test('can open Settings plugin', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); - const overlay = page.locator('astro-dev-overlay'); + const overlay = page.locator('astro-dev-toolbar'); const pluginButton = overlay.locator('button[data-plugin-id="astro:settings"]'); await pluginButton.click(); const settingsPluginCanvas = overlay.locator( - 'astro-dev-overlay-plugin-canvas[data-plugin-id="astro:settings"]' + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:settings"]' ); - const settingsWindow = settingsPluginCanvas.locator('astro-dev-overlay-window'); + const settingsWindow = settingsPluginCanvas.locator('astro-dev-toolbar-window'); await expect(settingsWindow).toHaveCount(1); await expect(settingsWindow).toBeVisible(); @@ -117,4 +157,50 @@ test.describe('Dev Overlay', () => { await pluginButton.click(); await expect(settingsWindow).not.toBeVisible(); }); + + test('Opening a plugin closes the currently opened plugin', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + + const overlay = page.locator('astro-dev-toolbar'); + let pluginButton = overlay.locator('button[data-plugin-id="astro:settings"]'); + await pluginButton.click(); + + const settingsPluginCanvas = overlay.locator( + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:settings"]' + ); + const settingsWindow = settingsPluginCanvas.locator('astro-dev-toolbar-window'); + await expect(settingsWindow).toHaveCount(1); + await expect(settingsWindow).toBeVisible(); + + // Click the astro plugin + pluginButton = overlay.locator('button[data-plugin-id="astro"]'); + await pluginButton.click(); + + const astroPluginCanvas = overlay.locator( + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro"]' + ); + const astroWindow = astroPluginCanvas.locator('astro-dev-toolbar-window'); + await expect(astroWindow).toHaveCount(1); + await expect(astroWindow).toBeVisible(); + + await expect(settingsWindow).not.toBeVisible(); + }); + + test('Settings plugin contains message on disabling the overlay', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + + const overlay = page.locator('astro-dev-toolbar'); + let pluginButton = overlay.locator('button[data-plugin-id="astro:settings"]'); + await pluginButton.click(); + + const settingsPluginCanvas = overlay.locator( + 'astro-dev-toolbar-plugin-canvas[data-plugin-id="astro:settings"]' + ); + const settingsWindow = settingsPluginCanvas.locator('astro-dev-toolbar-window'); + await expect(settingsWindow).toHaveCount(1); + await expect(settingsWindow).toBeVisible(); + + const hideOverlay = settingsWindow.getByRole('heading', { name: 'Hide toolbar' }); + await expect(hideOverlay).toBeVisible(); + }); }); diff --git a/packages/astro/e2e/fixtures/astro-component/astro.config.mjs b/packages/astro/e2e/fixtures/astro-component/astro.config.mjs index 44371fc32b633..58b3ebc4bf9c2 100644 --- a/packages/astro/e2e/fixtures/astro-component/astro.config.mjs +++ b/packages/astro/e2e/fixtures/astro-component/astro.config.mjs @@ -3,5 +3,8 @@ import preact from '@astrojs/preact' // https://astro.build/config export default defineConfig({ - integrations: [preact()] + integrations: [preact()], + devToolbar: { + enabled: false, + } }); diff --git a/packages/astro/e2e/fixtures/astro-component/package.json b/packages/astro/e2e/fixtures/astro-component/package.json index b7cc8fbc132f5..b02f5b90c89f2 100644 --- a/packages/astro/e2e/fixtures/astro-component/package.json +++ b/packages/astro/e2e/fixtures/astro-component/package.json @@ -6,6 +6,6 @@ "@astrojs/preact": "workspace:*", "@e2e/astro-linked-lib": "link:../_deps/astro-linked-lib", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/astro-envs/astro.config.mjs b/packages/astro/e2e/fixtures/astro-envs/astro.config.mjs index 1fee9eb36b573..48d49eccd2042 100644 --- a/packages/astro/e2e/fixtures/astro-envs/astro.config.mjs +++ b/packages/astro/e2e/fixtures/astro-envs/astro.config.mjs @@ -5,5 +5,8 @@ import vue from '@astrojs/vue'; export default defineConfig({ site: 'http://example.com', base: '/blog', + devToolbar: { + enabled: false, + }, integrations: [vue()], }); diff --git a/packages/astro/e2e/fixtures/astro-envs/package.json b/packages/astro/e2e/fixtures/astro-envs/package.json index 2fa703b969de7..ac0cd9afa5b3f 100644 --- a/packages/astro/e2e/fixtures/astro-envs/package.json +++ b/packages/astro/e2e/fixtures/astro-envs/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/client-only/package.json b/packages/astro/e2e/fixtures/client-only/package.json index f71e9936ca5ee..938d67392533f 100644 --- a/packages/astro/e2e/fixtures/client-only/package.json +++ b/packages/astro/e2e/fixtures/client-only/package.json @@ -11,11 +11,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/dev-overlay/astro.config.mjs b/packages/astro/e2e/fixtures/dev-overlay/astro.config.mjs index 380a501ac44b8..d24b4cc9a2605 100644 --- a/packages/astro/e2e/fixtures/dev-overlay/astro.config.mjs +++ b/packages/astro/e2e/fixtures/dev-overlay/astro.config.mjs @@ -2,7 +2,4 @@ import preact from '@astrojs/preact'; export default { integrations: [preact()], - experimental: { - devOverlay: true - } }; diff --git a/packages/astro/e2e/fixtures/dev-overlay/package.json b/packages/astro/e2e/fixtures/dev-overlay/package.json index 707aa8718b0d6..6cd05404d6a2a 100644 --- a/packages/astro/e2e/fixtures/dev-overlay/package.json +++ b/packages/astro/e2e/fixtures/dev-overlay/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/dev-overlay/src/pages/audit-no-warning.astro b/packages/astro/e2e/fixtures/dev-overlay/src/pages/audit-no-warning.astro new file mode 100644 index 0000000000000..9d0c2858777bb --- /dev/null +++ b/packages/astro/e2e/fixtures/dev-overlay/src/pages/audit-no-warning.astro @@ -0,0 +1,5 @@ +--- + +--- + +<img src="https://astro.build/assets/press/astro-logo-dark.svg" alt="Astro logo" /> diff --git a/packages/astro/e2e/fixtures/dev-overlay/src/pages/xray-no-islands.astro b/packages/astro/e2e/fixtures/dev-overlay/src/pages/xray-no-islands.astro new file mode 100644 index 0000000000000..f408d45cb0500 --- /dev/null +++ b/packages/astro/e2e/fixtures/dev-overlay/src/pages/xray-no-islands.astro @@ -0,0 +1,5 @@ +--- + +--- + +<div>no islands on this page</div> diff --git a/packages/astro/e2e/fixtures/error-cyclic/package.json b/packages/astro/e2e/fixtures/error-cyclic/package.json index b4a9ed29ca353..f63c95a376d8f 100644 --- a/packages/astro/e2e/fixtures/error-cyclic/package.json +++ b/packages/astro/e2e/fixtures/error-cyclic/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/error-sass/package.json b/packages/astro/e2e/fixtures/error-sass/package.json index 6c89910db6c4a..7f92d3b5ac66a 100644 --- a/packages/astro/e2e/fixtures/error-sass/package.json +++ b/packages/astro/e2e/fixtures/error-sass/package.json @@ -4,6 +4,6 @@ "private": true, "dependencies": { "astro": "workspace:*", - "sass": "^1.66.1" + "sass": "^1.69.5" } } diff --git a/packages/astro/e2e/fixtures/errors/package.json b/packages/astro/e2e/fixtures/errors/package.json index 67ce0a5355f4d..7d93b835492ab 100644 --- a/packages/astro/e2e/fixtures/errors/package.json +++ b/packages/astro/e2e/fixtures/errors/package.json @@ -9,12 +9,12 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "sass": "^1.66.1", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "sass": "^1.69.5", + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/hmr/package.json b/packages/astro/e2e/fixtures/hmr/package.json index f5aa414601d81..6e102c9976fdf 100644 --- a/packages/astro/e2e/fixtures/hmr/package.json +++ b/packages/astro/e2e/fixtures/hmr/package.json @@ -4,6 +4,6 @@ "private": true, "devDependencies": { "astro": "workspace:*", - "sass": "^1.66.1" + "sass": "^1.69.5" } } diff --git a/packages/astro/e2e/fixtures/hydration-race/package.json b/packages/astro/e2e/fixtures/hydration-race/package.json index 8db4efa2934dc..580c6721dab1a 100644 --- a/packages/astro/e2e/fixtures/hydration-race/package.json +++ b/packages/astro/e2e/fixtures/hydration-race/package.json @@ -9,6 +9,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/lit-component/astro.config.mjs b/packages/astro/e2e/fixtures/lit-component/astro.config.mjs index 1eab8f9ab8beb..8df6f42a1165b 100644 --- a/packages/astro/e2e/fixtures/lit-component/astro.config.mjs +++ b/packages/astro/e2e/fixtures/lit-component/astro.config.mjs @@ -4,4 +4,7 @@ import lit from '@astrojs/lit'; // https://astro.build/config export default defineConfig({ integrations: [lit()], + devToolbar: { + enabled: false, + } }); diff --git a/packages/astro/e2e/fixtures/lit-component/package.json b/packages/astro/e2e/fixtures/lit-component/package.json index c221e81c97d09..ca278c082afa9 100644 --- a/packages/astro/e2e/fixtures/lit-component/package.json +++ b/packages/astro/e2e/fixtures/lit-component/package.json @@ -6,6 +6,6 @@ "@astrojs/lit": "workspace:*", "@webcomponents/template-shadowroot": "^0.2.1", "astro": "workspace:*", - "lit": "^2.8.0" + "lit": "^3.1.0" } } diff --git a/packages/astro/e2e/fixtures/multiple-frameworks/package.json b/packages/astro/e2e/fixtures/multiple-frameworks/package.json index 1edb9df993efd..4666b1593e5b4 100644 --- a/packages/astro/e2e/fixtures/multiple-frameworks/package.json +++ b/packages/astro/e2e/fixtures/multiple-frameworks/package.json @@ -14,11 +14,11 @@ "dependencies": { "@webcomponents/template-shadowroot": "^0.2.1", "lit": "^2.8.0", - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/namespaced-component/package.json b/packages/astro/e2e/fixtures/namespaced-component/package.json index 596cb5d2b3a16..a64e3b52a023d 100644 --- a/packages/astro/e2e/fixtures/namespaced-component/package.json +++ b/packages/astro/e2e/fixtures/namespaced-component/package.json @@ -8,6 +8,6 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/nested-in-preact/package.json b/packages/astro/e2e/fixtures/nested-in-preact/package.json index c626314bd4eb7..fcbbd1e2bdbc5 100644 --- a/packages/astro/e2e/fixtures/nested-in-preact/package.json +++ b/packages/astro/e2e/fixtures/nested-in-preact/package.json @@ -11,11 +11,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/nested-in-react/package.json b/packages/astro/e2e/fixtures/nested-in-react/package.json index 88690f1406365..18463a7736929 100644 --- a/packages/astro/e2e/fixtures/nested-in-react/package.json +++ b/packages/astro/e2e/fixtures/nested-in-react/package.json @@ -11,11 +11,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/nested-in-solid/package.json b/packages/astro/e2e/fixtures/nested-in-solid/package.json index 47ba1334d23ef..4c9f03262ab78 100644 --- a/packages/astro/e2e/fixtures/nested-in-solid/package.json +++ b/packages/astro/e2e/fixtures/nested-in-solid/package.json @@ -11,11 +11,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/nested-in-svelte/package.json b/packages/astro/e2e/fixtures/nested-in-svelte/package.json index 91b88bbb8430b..a3adbea06b764 100644 --- a/packages/astro/e2e/fixtures/nested-in-svelte/package.json +++ b/packages/astro/e2e/fixtures/nested-in-svelte/package.json @@ -11,11 +11,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/nested-in-vue/package.json b/packages/astro/e2e/fixtures/nested-in-vue/package.json index 3cab15f47c3ac..2555b7a2908d0 100644 --- a/packages/astro/e2e/fixtures/nested-in-vue/package.json +++ b/packages/astro/e2e/fixtures/nested-in-vue/package.json @@ -11,11 +11,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/nested-recursive/package.json b/packages/astro/e2e/fixtures/nested-recursive/package.json index a1dfa3a097aba..a6b11a389129f 100644 --- a/packages/astro/e2e/fixtures/nested-recursive/package.json +++ b/packages/astro/e2e/fixtures/nested-recursive/package.json @@ -11,12 +11,12 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" }, "scripts": { "dev": "astro dev" diff --git a/packages/astro/e2e/fixtures/preact-compat-component/package.json b/packages/astro/e2e/fixtures/preact-compat-component/package.json index 72fdbdf3a6ef1..38b4fc3a8d097 100644 --- a/packages/astro/e2e/fixtures/preact-compat-component/package.json +++ b/packages/astro/e2e/fixtures/preact-compat-component/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/preact-component/package.json b/packages/astro/e2e/fixtures/preact-component/package.json index 264c1d99bfa04..4e2cd6fe225a2 100644 --- a/packages/astro/e2e/fixtures/preact-component/package.json +++ b/packages/astro/e2e/fixtures/preact-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/e2e/fixtures/prefetch/astro.config.mjs b/packages/astro/e2e/fixtures/prefetch/astro.config.mjs index bec1677fd8a79..a29c83f4250c1 100644 --- a/packages/astro/e2e/fixtures/prefetch/astro.config.mjs +++ b/packages/astro/e2e/fixtures/prefetch/astro.config.mjs @@ -2,5 +2,8 @@ import { defineConfig } from 'astro/config'; // https://astro.build/config export default defineConfig({ + devToolbar: { + enabled: false, + }, prefetch: true }); diff --git a/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro b/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro index e61bc1c6c33ef..88ce196ae22fc 100644 --- a/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro @@ -9,6 +9,8 @@ <br> <a id="prefetch-false" href="/prefetch-false" data-astro-prefetch="false">false</a> <br> + <a id="prefetch-search-param" href="?search-param=true" data-astro-prefetch="hover">search param</a> + <br> <a id="prefetch-tap" href="/prefetch-tap" data-astro-prefetch="tap">tap</a> <br> <a id="prefetch-hover" href="/prefetch-hover" data-astro-prefetch="hover">hover</a> diff --git a/packages/astro/e2e/fixtures/solid-circular/package.json b/packages/astro/e2e/fixtures/solid-circular/package.json index e32dccbdb22e8..a40b083c3d2bb 100644 --- a/packages/astro/e2e/fixtures/solid-circular/package.json +++ b/packages/astro/e2e/fixtures/solid-circular/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*" }, "devDependencies": { - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/e2e/fixtures/solid-component/package.json b/packages/astro/e2e/fixtures/solid-component/package.json index d4ef4de6ea6f7..634693c79321c 100644 --- a/packages/astro/e2e/fixtures/solid-component/package.json +++ b/packages/astro/e2e/fixtures/solid-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/solid-js": "workspace:*", "astro": "workspace:*", - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/e2e/fixtures/solid-recurse/package.json b/packages/astro/e2e/fixtures/solid-recurse/package.json index 6f999c6a35d73..96d93df74a5d0 100644 --- a/packages/astro/e2e/fixtures/solid-recurse/package.json +++ b/packages/astro/e2e/fixtures/solid-recurse/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*" }, "devDependencies": { - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/e2e/fixtures/svelte-component/package.json b/packages/astro/e2e/fixtures/svelte-component/package.json index c6fe3c8e892d7..b721b8ccbdaa9 100644 --- a/packages/astro/e2e/fixtures/svelte-component/package.json +++ b/packages/astro/e2e/fixtures/svelte-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/e2e/fixtures/tailwindcss/astro.config.mjs b/packages/astro/e2e/fixtures/tailwindcss/astro.config.mjs index 011b1a8b99c35..aa1ca234a34be 100644 --- a/packages/astro/e2e/fixtures/tailwindcss/astro.config.mjs +++ b/packages/astro/e2e/fixtures/tailwindcss/astro.config.mjs @@ -9,6 +9,9 @@ export default defineConfig({ configFile: fileURLToPath(new URL('./tailwind.config.js', import.meta.url)), }), ], + devToolbar: { + enabled: false, + }, vite: { build: { assetsInlineLimit: 0, diff --git a/packages/astro/e2e/fixtures/tailwindcss/package.json b/packages/astro/e2e/fixtures/tailwindcss/package.json index ddac263a55adc..d755b95163343 100644 --- a/packages/astro/e2e/fixtures/tailwindcss/package.json +++ b/packages/astro/e2e/fixtures/tailwindcss/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*", "autoprefixer": "^10.4.15", "postcss": "^8.4.28", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.3.5" } } diff --git a/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs b/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs index f4450f67285d8..4b682d215785f 100644 --- a/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs +++ b/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs @@ -13,6 +13,9 @@ export default defineConfig({ '/redirect-two': '/two', '/redirect-external': 'http://example.com/', }, + devToolbar: { + enabled: false, + }, vite: { build: { assetsInlineLimit: 0, diff --git a/packages/astro/e2e/fixtures/view-transitions/package.json b/packages/astro/e2e/fixtures/view-transitions/package.json index b53b5fcad4a68..327393ccda6eb 100644 --- a/packages/astro/e2e/fixtures/view-transitions/package.json +++ b/packages/astro/e2e/fixtures/view-transitions/package.json @@ -3,14 +3,14 @@ "version": "0.0.0", "private": true, "dependencies": { - "astro": "workspace:*", "@astrojs/node": "workspace:*", "@astrojs/react": "workspace:*", - "@astrojs/vue": "workspace:*", "@astrojs/svelte": "workspace:*", - "svelte": "^4.2.0", - "vue": "^3.3.4", + "@astrojs/vue": "workspace:*", + "astro": "workspace:*", "react": "^18.1.0", - "react-dom": "^18.1.0" + "react-dom": "^18.1.0", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/dialog.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/dialog.astro new file mode 100644 index 0000000000000..07d4b0f00b393 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/dialog.astro @@ -0,0 +1,16 @@ +--- +import { ViewTransitions } from "astro:transitions"; +--- +<html> + <head> + <ViewTransitions /> + </head> + <body> + <button id="open" onclick="modal.showModal()">Open Modal</button> + <dialog id="modal"> + <form method="dialog"> + <button id="close">Close</button> + </form> + </dialog> + </body> +</html> diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/form-four.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/form-four.astro new file mode 100644 index 0000000000000..7a62fbe47ba0b --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/form-four.astro @@ -0,0 +1,20 @@ +--- +import { ViewTransitions } from 'astro:transitions'; +--- + +<html> + <head> + <ViewTransitions handleForms/> + <meta charset="UTF-8" /> + </head> + <body> + <h2>Voting Form</h2> + {Astro.url.search} + <h3>This form does neither have a `method`, nor an `action`, nor an `input` defined</h3> + <form> + <button name="stars" value="1">⭐</button> + <button id="three" name="stars" value="3">⭐⭐⭐</button> + <button name="stars" value="5">⭐⭐⭐⭐⭐</button> + </form> + </body> +</html> diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/long-page.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/long-page.astro index ebe918c680aff..aa7c8b5e59c7f 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/long-page.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/long-page.astro @@ -51,3 +51,9 @@ import Layout from '../components/Layout.astro'; Libero id faucibus nisl tincidunt eget nullam non. Faucibus a pellentesque sit amet porttitor eget dolor. Posuere urna nec tincidunt praesent semper feugiat nibh sed. Suspendisse ultrices gravida dictum fusce. Porttitor eget dolor morbi non arcu. Neque egestas congue quisque egestas diam in. Suscipit tellus mauris a diam maecenas sed enim ut sem. Luctus accumsan tortor posuere ac. Tortor posuere ac ut consequat semper viverra. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla. Senectus et netus et malesuada fames ac turpis egestas. Sed libero enim sed faucibus turpis in eu mi bibendum. Sollicitudin tempor id eu nisl nunc mi. </article> </Layout> +<script is:inline> + // let playwright know when navigate() is done + document.addEventListener('astro:before-swap', (e) => { + e.viewTransition.ready.then(()=>console.log("ready")) + }); +</script> diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/non-html-anchor.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/non-html-anchor.astro new file mode 100644 index 0000000000000..8d5ea8d46c769 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/non-html-anchor.astro @@ -0,0 +1,22 @@ +--- +import Layout from '../components/Layout.astro'; +--- +<Layout> +<h1>SVGA and Image Map links</h1> + +<svg viewBox="0 0 160 40" xmlns="http://www.w3.org/2000/svg"> + <a href="/two" id="svga"> + <text x="10" y="25" id="insidesvga">text within a svga</text> + </a> +</svg> + + +<map name="map"> + <area shape="default" href="/two" alt="logo" id="area"/> +</map> +<img id="logo" usemap="#map" src="/logo.svg" alt="logo" /> +<style> + body { + background: #888; + } +</style> diff --git a/packages/astro/e2e/fixtures/vue-component/package.json b/packages/astro/e2e/fixtures/vue-component/package.json index 81e7997830e35..091f3643558ce 100644 --- a/packages/astro/e2e/fixtures/vue-component/package.json +++ b/packages/astro/e2e/fixtures/vue-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/astro/e2e/hmr.test.js b/packages/astro/e2e/hmr.test.js index 091aa716d6897..5e7e232af96fa 100644 --- a/packages/astro/e2e/hmr.test.js +++ b/packages/astro/e2e/hmr.test.js @@ -3,6 +3,9 @@ import { testFactory } from './test-utils.js'; const test = testFactory({ root: './fixtures/hmr/', + devToolbar: { + enabled: false, + }, }); let devServer; diff --git a/packages/astro/e2e/prefetch.test.js b/packages/astro/e2e/prefetch.test.js index dc29bde33f07f..a19c87680ecac 100644 --- a/packages/astro/e2e/prefetch.test.js +++ b/packages/astro/e2e/prefetch.test.js @@ -16,7 +16,8 @@ test.describe('Prefetch (default)', () => { test.beforeEach(async ({ page }) => { page.on('request', (req) => { - reqUrls.push(new URL(req.url()).pathname); + const urlObj = new URL(req.url()); + reqUrls.push(urlObj.pathname + urlObj.search); }); }); @@ -38,6 +39,16 @@ test.describe('Prefetch (default)', () => { expect(reqUrls).not.toContainEqual('/prefetch-false'); }); + test('Link with search param should prefetch', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + expect(reqUrls).not.toContainEqual('/?search-param=true'); + await Promise.all([ + page.waitForEvent('request'), // wait prefetch request + page.locator('#prefetch-search-param').hover(), + ]); + expect(reqUrls).toContainEqual('/?search-param=true'); + }); + test('data-astro-prefetch="tap" should prefetch on tap', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); expect(reqUrls).not.toContainEqual('/prefetch-tap'); @@ -102,7 +113,8 @@ test.describe("Prefetch (prefetchAll: true, defaultStrategy: 'tap')", () => { test.beforeEach(async ({ page }) => { page.on('request', (req) => { - reqUrls.push(new URL(req.url()).pathname); + const urlObj = new URL(req.url()); + reqUrls.push(urlObj.pathname + urlObj.search); }); }); @@ -129,6 +141,16 @@ test.describe("Prefetch (prefetchAll: true, defaultStrategy: 'tap')", () => { expect(reqUrls).not.toContainEqual('/prefetch-false'); }); + test('Link with search param should prefetch', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + expect(reqUrls).not.toContainEqual('/?search-param=true'); + await Promise.all([ + page.waitForEvent('request'), // wait prefetch request + page.locator('#prefetch-search-param').hover(), + ]); + expect(reqUrls).toContainEqual('/?search-param=true'); + }); + test('data-astro-prefetch="tap" should prefetch on tap', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); expect(reqUrls).not.toContainEqual('/prefetch-tap'); diff --git a/packages/astro/e2e/react-component.test.js b/packages/astro/e2e/react-component.test.js index b19a071d664a1..361ee8d69a2a4 100644 --- a/packages/astro/e2e/react-component.test.js +++ b/packages/astro/e2e/react-component.test.js @@ -46,7 +46,6 @@ test.describe('React client id generation', () => { const hydratedId1 = await components.nth(2).getAttribute('id'); const clientOnlyId0 = await components.nth(3).getAttribute('id'); const clientOnlyId1 = await components.nth(4).getAttribute('id'); - console.log('ho ho', staticId, hydratedId0, hydratedId1, clientOnlyId0, clientOnlyId1); expect(staticId).not.toEqual(hydratedId0); expect(hydratedId0).not.toEqual(hydratedId1); expect(hydratedId1).not.toEqual(clientOnlyId0); diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 20ea8adbc302f..222c9dfdf2aa4 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -394,7 +394,10 @@ test.describe('View Transitions', () => { await expect(locator).toBeInViewport(); // Scroll back to top + // back returns immediately, but we need to wait for navigate() to complete + const waitForReady = page.waitForEvent('console'); await page.goBack(); + await waitForReady; locator = page.locator('#longpage'); await expect(locator).toBeInViewport(); @@ -1016,4 +1019,76 @@ test.describe('View Transitions', () => { const result = page.locator('#three-result'); await expect(result, 'should have content').toHaveText('Got: Testing'); }); + + test('click on an svg anchor should trigger navigation', async ({ page, astro }) => { + const loads = []; + page.addListener('load', (p) => { + loads.push(p.title()); + }); + + await page.goto(astro.resolveUrl('/non-html-anchor')); + let locator = page.locator('#insidesvga'); + await expect(locator, 'should have attribute').toHaveAttribute('x', '10'); + await page.click('#svga'); + const p = page.locator('#two'); + await expect(p, 'should have content').toHaveText('Page 2'); + expect(loads.length, 'There should only be 1 page load').toEqual(1); + }); + + test('click inside an svg anchor should trigger navigation', async ({ page, astro }) => { + const loads = []; + page.addListener('load', (p) => { + loads.push(p.title()); + }); + await page.goto(astro.resolveUrl('/non-html-anchor')); + let locator = page.locator('#insidesvga'); + await expect(locator, 'should have content').toHaveText('text within a svga'); + await page.click('#insidesvga'); + const p = page.locator('#two'); + await expect(p, 'should have content').toHaveText('Page 2'); + expect(loads.length, 'There should only be 1 page load').toEqual(1); + }); + + test('click on an area in an image map should trigger navigation', async ({ page, astro }) => { + const loads = []; + page.addListener('load', (p) => { + loads.push(p.title()); + }); + await page.goto(astro.resolveUrl('/non-html-anchor')); + let locator = page.locator('#area'); + await expect(locator, 'should have attribute').toHaveAttribute('shape', 'default'); + await page.click('#logo'); + const p = page.locator('#two'); + await expect(p, 'should have content').toHaveText('Page 2'); + expect(loads.length, 'There should only be 1 page load').toEqual(1); + }); + + test('Submitter with a name property is included in form data', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/form-four')); + + let locator = page.locator('h2'); + await expect(locator, 'should have content').toHaveText('Voting Form'); + + // Submit the form + const expected = page.url() + '?stars=3'; + await page.click('#three'); + await expect(page).toHaveURL(expected); + }); + + test('Dialog using form with method of "dialog" should not trigger navigation', async ({ + page, + astro, + }) => { + await page.goto(astro.resolveUrl('/dialog')); + + let requests = []; + page.on('request', (request) => requests.push(`${request.method()} ${request.url()}`)); + + await page.click('#open'); + await expect(page.locator('dialog')).toHaveAttribute('open'); + await page.click('#close'); + await expect(page.locator('dialog')).not.toHaveAttribute('open'); + + expect(requests).toHaveLength(0); + }); }); diff --git a/packages/astro/import-meta.d.ts b/packages/astro/import-meta.d.ts deleted file mode 100644 index 23d951cf2db18..0000000000000 --- a/packages/astro/import-meta.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -// File vendored from Vite itself, as a workaround to https://github.com/vitejs/vite/issues/13309 until Vite 5 comes out - -// This file is an augmentation to the built-in ImportMeta interface -// Thus cannot contain any top-level imports -// <https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation> - -/* eslint-disable @typescript-eslint/consistent-type-imports */ - -interface ImportMeta { - url: string; - - readonly hot?: import('vite/types/hot').ViteHotContext; - - readonly env: ImportMetaEnv; - - glob: import('vite/types/importGlob').ImportGlobFunction; - /** - * @deprecated Use `import.meta.glob('*', { eager: true })` instead - */ - globEager: import('vite/types/importGlob').ImportGlobEagerFunction; -} - -interface ImportMetaEnv { - [key: string]: any; - BASE_URL: string; - MODE: string; - DEV: boolean; - PROD: boolean; - SSR: boolean; -} diff --git a/packages/astro/package.json b/packages/astro/package.json index 1cb40861cddba..37338f066e44d 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "3.5.5", + "version": "4.0.5", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", @@ -22,10 +22,7 @@ "./dist/core/app/*" ], "middleware": [ - "./dist/core/middleware/index.d.ts" - ], - "middleware/namespace": [ - "./dist/core/middleware/namespace.d.ts" + "./dist/virtual-modules/middleware.d.ts" ] } }, @@ -73,14 +70,7 @@ "types": "./dist/core/middleware/index.d.ts", "default": "./dist/core/middleware/index.js" }, - "./middleware/namespace": { - "types": "./dist/core/middleware/namespace.d.ts", - "default": "./dist/core/middleware/namespace.js" - }, - "./transitions": "./dist/transitions/index.js", - "./transitions/router": "./dist/transitions/router.js", - "./prefetch": "./dist/prefetch/index.js", - "./i18n": "./dist/i18n/index.js" + "./virtual-modules/*": "./dist/virtual-modules/*" }, "imports": { "#astro/*": "./dist/*.js" @@ -122,33 +112,36 @@ "test:e2e:match": "playwright test -g" }, "dependencies": { - "@astrojs/compiler": "^2.3.0", + "@astrojs/compiler": "^2.3.2", "@astrojs/internal-helpers": "workspace:*", "@astrojs/markdown-remark": "workspace:*", "@astrojs/telemetry": "workspace:*", - "@babel/core": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/parser": "^7.22.10", + "@babel/core": "^7.23.3", + "@babel/generator": "^7.23.3", + "@babel/parser": "^7.23.3", "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "@types/babel__core": "^7.20.1", - "acorn": "^8.10.0", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "@types/babel__core": "^7.20.4", + "acorn": "^8.11.2", "boxen": "^7.1.1", "chokidar": "^3.5.3", - "ci-info": "^3.8.0", + "ci-info": "^4.0.0", "clsx": "^2.0.0", "common-ancestor-path": "^1.0.1", - "cookie": "^0.5.0", + "cookie": "^0.6.0", "debug": "^4.3.4", - "deterministic-object-hash": "^1.3.1", + "deterministic-object-hash": "^2.0.1", "devalue": "^4.3.2", "diff": "^5.1.0", - "es-module-lexer": "^1.3.0", - "esbuild": "^0.19.2", + "dlv": "^1.1.3", + "dset": "^3.1.3", + "es-module-lexer": "^1.4.1", + "esbuild": "^0.19.6", "estree-walker": "^3.0.3", "execa": "^8.0.1", - "fast-glob": "^3.3.1", + "fast-glob": "^3.3.2", + "flattie": "^1.1.0", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "html-escaper": "^3.0.3", @@ -156,27 +149,27 @@ "js-yaml": "^4.1.0", "kleur": "^4.1.4", "magic-string": "^0.30.3", - "mdast-util-to-hast": "12.3.0", + "mdast-util-to-hast": "13.0.2", "mime": "^3.0.0", "ora": "^7.0.1", - "p-limit": "^4.0.0", + "p-limit": "^5.0.0", "p-queue": "^7.4.1", "path-to-regexp": "^6.2.1", "preferred-pm": "^3.1.2", "probe-image-size": "^7.2.3", "prompts": "^2.4.2", - "rehype": "^12.0.1", + "rehype": "^13.0.1", "resolve": "^1.22.4", "semver": "^7.5.4", "server-destroy": "^1.0.1", - "shikiji": "^0.6.8", - "string-width": "^6.1.0", + "shikiji": "^0.6.13", + "string-width": "^7.0.0", "strip-ansi": "^7.1.0", "tsconfck": "^3.0.0", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7", - "vite": "^4.4.9", - "vitefu": "^0.2.4", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1", + "vite": "^5.0.0", + "vitefu": "^0.2.5", "which-pm": "^2.1.1", "yargs-parser": "^21.1.1", "zod": "^3.22.4" @@ -185,31 +178,33 @@ "sharp": "^0.32.5" }, "devDependencies": { - "@astrojs/check": "^0.1.0", - "@playwright/test": "1.40.0-alpha-nov-13-2023", - "@types/babel__generator": "^7.6.4", - "@types/babel__traverse": "^7.20.1", - "@types/chai": "^4.3.5", - "@types/common-ancestor-path": "^1.0.0", - "@types/connect": "^3.4.35", - "@types/cookie": "^0.5.1", - "@types/debug": "^4.1.8", - "@types/diff": "^5.0.3", - "@types/dom-view-transitions": "^1.0.1", - "@types/estree": "^1.0.1", - "@types/hast": "^2.3.5", - "@types/html-escaper": "^3.0.0", - "@types/http-cache-semantics": "^4.0.1", - "@types/js-yaml": "^4.0.5", - "@types/mime": "^3.0.1", - "@types/mocha": "^10.0.1", - "@types/probe-image-size": "^7.2.0", - "@types/prompts": "^2.4.4", - "@types/resolve": "^1.20.2", - "@types/send": "^0.17.1", - "@types/server-destroy": "^1.0.1", - "@types/unist": "^2.0.7", - "@types/yargs-parser": "^21.0.0", + "@astrojs/check": "^0.3.1", + "@playwright/test": "1.40.0", + "@types/babel__generator": "^7.6.7", + "@types/babel__traverse": "^7.20.4", + "@types/chai": "^4.3.10", + "@types/common-ancestor-path": "^1.0.2", + "@types/connect": "^3.4.38", + "@types/cookie": "^0.5.4", + "@types/debug": "^4.1.12", + "@types/diff": "^5.0.8", + "@types/dlv": "^1.1.4", + "@types/dom-view-transitions": "^1.0.4", + "@types/estree": "^1.0.5", + "@types/hast": "^3.0.3", + "@types/html-escaper": "^3.0.2", + "@types/http-cache-semantics": "^4.0.4", + "@types/js-yaml": "^4.0.9", + "@types/mime": "^3.0.4", + "@types/mocha": "^10.0.4", + "@types/probe-image-size": "^7.2.3", + "@types/prompts": "^2.4.8", + "@types/resolve": "^1.20.5", + "@types/semver": "^7.5.2", + "@types/send": "^0.17.4", + "@types/server-destroy": "^1.0.3", + "@types/unist": "^3.0.2", + "@types/yargs-parser": "^21.0.3", "astro-scripts": "workspace:*", "chai": "^4.3.7", "cheerio": "1.0.0-rc.12", @@ -218,14 +213,14 @@ "mocha": "^10.2.0", "node-mocks-http": "^1.13.0", "parse-srcset": "^1.0.2", - "rehype-autolink-headings": "^6.1.1", - "rehype-slug": "^5.0.1", + "rehype-autolink-headings": "^7.1.0", + "rehype-slug": "^6.0.0", "rehype-toc": "^3.0.2", "remark-code-titles": "^0.1.2", - "rollup": "^3.28.1", - "sass": "^1.66.1", + "rollup": "^4.5.0", + "sass": "^1.69.5", "srcset-parse": "^1.1.0", - "unified": "^10.1.2" + "unified": "^11.0.4" }, "engines": { "node": ">=18.14.1", diff --git a/packages/astro/performance/content-benchmark.mjs b/packages/astro/performance/content-benchmark.mjs index 14f9b598e3b39..c2d1d69184def 100644 --- a/packages/astro/performance/content-benchmark.mjs +++ b/packages/astro/performance/content-benchmark.mjs @@ -44,14 +44,14 @@ async function benchmark({ fixtures, templates, numPosts }) { const test = Array.isArray(flags.test) ? flags.test : typeof flags.test === 'string' - ? [flags.test] - : ['simple', 'with-astro-components', 'with-react-components']; + ? [flags.test] + : ['simple', 'with-astro-components', 'with-react-components']; const formats = Array.isArray(flags.format) ? flags.format : typeof flags.format === 'string' - ? [flags.format] - : ['md', 'mdx', 'mdoc']; + ? [flags.format] + : ['md', 'mdx', 'mdoc']; const numPosts = flags.numPosts || 1000; diff --git a/packages/astro/performance/fixtures/md/package.json b/packages/astro/performance/fixtures/md/package.json index ff7b1dec0df6c..4dea64d76530c 100644 --- a/packages/astro/performance/fixtures/md/package.json +++ b/packages/astro/performance/fixtures/md/package.json @@ -16,8 +16,8 @@ "dependencies": { "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "astro": "workspace:*", "react": "^18.0.0", "react-dom": "^18.0.0" diff --git a/packages/astro/performance/fixtures/mdoc/package.json b/packages/astro/performance/fixtures/mdoc/package.json index 351ef15e49488..a25e69c971b25 100644 --- a/packages/astro/performance/fixtures/mdoc/package.json +++ b/packages/astro/performance/fixtures/mdoc/package.json @@ -17,8 +17,8 @@ "@astrojs/markdoc": "workspace:*", "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "astro": "workspace:*", "react": "^18.0.0", "react-dom": "^18.0.0" diff --git a/packages/astro/performance/fixtures/mdx/package.json b/packages/astro/performance/fixtures/mdx/package.json index c2d4e368a8727..2144dc2258199 100644 --- a/packages/astro/performance/fixtures/mdx/package.json +++ b/packages/astro/performance/fixtures/mdx/package.json @@ -17,8 +17,8 @@ "@astrojs/mdx": "workspace:*", "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "astro": "workspace:*", "react": "^18.0.0", "react-dom": "^18.0.0" diff --git a/packages/astro/performance/package.json b/packages/astro/performance/package.json index e09f291736c20..25bfad16b4af8 100644 --- a/packages/astro/performance/package.json +++ b/packages/astro/performance/package.json @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "devDependencies": { - "@types/yargs-parser": "^21.0.0", + "@types/yargs-parser": "^21.0.3", "cross-env": "^7.0.3", "kleur": "^4.1.5", "npm-run-all": "^4.1.5", diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 6477f738396ca..fa8c33920ac03 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -19,16 +19,22 @@ import type { AstroConfigType } from '../core/config/index.js'; import type { AstroTimer } from '../core/config/timer.js'; import type { TSConfig } from '../core/config/tsconfig.js'; import type { AstroCookies } from '../core/cookies/index.js'; -import type { ResponseWithEncoding } from '../core/endpoint/index.js'; import type { AstroIntegrationLogger, Logger, LoggerLevel } from '../core/logger/core.js'; +import type { AstroPreferences } from '../preferences/index.js'; import type { AstroDevOverlay, DevOverlayCanvas } from '../runtime/client/dev-overlay/overlay.js'; -import type { DevOverlayHighlight } from '../runtime/client/dev-overlay/ui-library/highlight.js'; import type { Icon } from '../runtime/client/dev-overlay/ui-library/icons.js'; -import type { DevOverlayToggle } from '../runtime/client/dev-overlay/ui-library/toggle.js'; -import type { DevOverlayTooltip } from '../runtime/client/dev-overlay/ui-library/tooltip.js'; -import type { DevOverlayWindow } from '../runtime/client/dev-overlay/ui-library/window.js'; +import type { + DevOverlayBadge, + DevOverlayButton, + DevOverlayCard, + DevOverlayHighlight, + DevOverlayIcon, + DevOverlayToggle, + DevOverlayTooltip, + DevOverlayWindow, +} from '../runtime/client/dev-overlay/ui-library/index.js'; import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server/index.js'; -import type { OmitIndexSignature, Simplify } from '../type-utils.js'; +import type { DeepPartial, OmitIndexSignature, Simplify } from '../type-utils.js'; import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js'; export { type AstroIntegrationLogger }; @@ -126,6 +132,10 @@ export interface AstroScriptAttributes { 'is:inline'?: boolean; } +export interface AstroSlotAttributes { + 'is:inline'?: boolean; +} + export interface AstroComponentMetadata { displayName: string; hydrate?: 'load' | 'idle' | 'visible' | 'media' | 'only'; @@ -143,7 +153,6 @@ export interface CLIFlags { host?: string | boolean; port?: number; config?: string; - drafts?: boolean; open?: boolean; } @@ -886,33 +895,6 @@ export interface AstroUserConfig { * ``` */ inlineStylesheets?: 'always' | 'auto' | 'never'; - - /** - * @docs - * @name build.split - * @type {boolean} - * @default `false` - * @deprecated Deprecated since version 3.0. - * @description - * The build config option `build.split` has been replaced by the adapter configuration option [`functionPerRoute`](/en/reference/adapter-reference/#functionperroute). - * - * Please see your [SSR adapter's documentation](/en/guides/integrations-guide/#official-integrations) for using `functionPerRoute` to define how your SSR code is bundled. - * - */ - split?: boolean; - - /** - * @docs - * @name build.excludeMiddleware - * @type {boolean} - * @default `false` - * @deprecated Deprecated since version 3.0. - * @description - * The build config option `build.excludeMiddleware` has been replaced by the adapter configuration option [`edgeMiddleware`](/en/reference/adapter-reference/#edgemiddleware). - * - * Please see your [SSR adapter's documentation](/en/guides/integrations-guide/#official-integrations) for using `edgeMiddleware` to define whether or not any SSR middleware code will be bundled when built. - */ - excludeMiddleware?: boolean; }; /** @@ -1180,31 +1162,28 @@ export interface AstroUserConfig { /** * @docs * @kind heading - * @name Markdown Options + * @name Dev Toolbar Options */ - markdown?: { + devToolbar?: { /** * @docs - * @name markdown.drafts + * @name devToolbar.enabled * @type {boolean} - * @default `false` - * @deprecated Deprecated since version 3.0. Use content collections instead. + * @default `true` * @description - * Control whether Markdown draft pages should be included in the build. - * - * A Markdown page is considered a draft if it includes `draft: true` in its frontmatter. Draft pages are always included & visible during development (`astro dev`) but by default they will not be included in your final build. + * Whether to enable the Astro Dev Toolbar. This toolbar allows you to inspect your page islands, see helpful audits on performance and accessibility, and more. * - * ```js - * { - * markdown: { - * // Example: Include all drafts in your final build - * drafts: true, - * } - * } - * ``` + * This option is scoped to the entire project, to only disable the toolbar for yourself, run `npm run astro preferences disable devToolbar`. To disable the toolbar for all your Astro projects, run `npm run astro preferences disable devToolbar --global`. */ - drafts?: boolean; + enabled: boolean; + }; + /** + * @docs + * @kind heading + * @name Markdown Options + */ + markdown?: { /** * @docs * @name markdown.shikiConfig @@ -1317,7 +1296,7 @@ export interface AstroUserConfig { * { * markdown: { * // Example: Translate the footnotes text to another language, here are the default English values - * remarkRehype: { footnoteLabel: "Footnotes", footnoteBackLabel: "Back to content"}, + * remarkRehype: { footnoteLabel: "Footnotes", footnoteBackLabel: "Back to reference 1"}, * }, * }; * ``` @@ -1382,6 +1361,119 @@ export interface AstroUserConfig { */ vite?: ViteUserConfig; + /** + * @docs + * @kind heading + * @name i18n + * @type {object} + * @version 3.5.0 + * @type {object} + * @description + * + * Configures i18n routing and allows you to specify some customization options. + * + * See our guide for more information on [internationalization in Astro](/en/guides/internationalization/) + */ + i18n?: { + /** + * @docs + * @name i18n.defaultLocale + * @type {string} + * @version 3.5.0 + * @description + * + * The default locale of your website/application. This is a required field. + * + * No particular language format or syntax is enforced, but we suggest using lower-case and hyphens as needed (e.g. "es", "pt-br") for greatest compatibility. + */ + defaultLocale: string; + /** + * @docs + * @name i18n.locales + * @type {Locales} + * @version 3.5.0 + * @description + * + * A list of all locales supported by the website, including the `defaultLocale`. This is a required field. + * + * Languages can be listed either as individual codes (e.g. `['en', 'es', 'pt-br']`) or mapped to a shared `path` of codes (e.g. `{ path: "english", codes: ["en", "en-US"]}`). These codes will be used to determine the URL structure of your deployed site. + * + * No particular language code format or syntax is enforced, but your project folders containing your content files must match exactly the `locales` items in the list. In the case of multiple `codes` pointing to a custom URL path prefix, store your content files in a folder with the same name as the `path` configured. + */ + locales: Locales; + + /** + * @docs + * @name i18n.fallback + * @type {Record<string, string>} + * @version 3.5.0 + * @description + * + * The fallback strategy when navigating to pages that do not exist (e.g. a translated page has not been created). + * + * Use this object to declare a fallback `locale` route for each language you support. If no fallback is specified, then unavailable pages will return a 404. + * + * ##### Example + * + * The following example configures your content fallback strategy to redirect unavailable pages in `/pt-br/` to their `es` version, and unavailable pages in `/fr/` to their `en` version. Unavailable `/es/` pages will return a 404. + * + * ```js + * export default defineConfig({ + * i18n: { + * defaultLocale: "en", + * locales: ["en", "fr", "pt-br", "es"], + * fallback: { + * pt: "es", + * fr: "en" + * } + * } + * }) + * ``` + */ + fallback?: Record<string, string>; + + /** + * @docs + * @name i18n.routing + * @type {Routing} + * @version 3.7.0 + * @description + * + * Controls the routing strategy to determine your site URLs. Set this based on your folder/URL path configuration for your default language. + */ + routing?: { + /** + * @docs + * @name i18n.routing.prefixDefaultLocale + * @kind h4 + * @type {boolean} + * @default `false` + * @version 3.7.0 + * @description + * + * When `false`, only non-default languages will display a language prefix. + * The `defaultLocale` will not show a language prefix and content files do not exist in a localized folder. + * URLs will be of the form `example.com/[locale]/content/` for all non-default languages, but `example.com/content/` for the default locale. + * + * When `true`, all URLs will display a language prefix. + * URLs will be of the form `example.com/[locale]/content/` for every route, including the default language. + * Localized folders are used for every language, including the default. + */ + prefixDefaultLocale: boolean; + + /** + * @name i18n.routing.strategy + * @type {"pathname"} + * @default `"pathname"` + * @version 3.7.0 + * @description + * + * - `"pathanme": The strategy is applied to the pathname of the URLs + */ + strategy: 'pathname'; + }; + }; + /** * @docs * @kind heading @@ -1424,119 +1516,6 @@ export interface AstroUserConfig { */ optimizeHoistedScript?: boolean; - /** - * @docs - * @name experimental.devOverlay - * @type {boolean} - * @default `false` - * @version 3.4.0 - * @description - * Enable a dev overlay in development mode. This overlay allows you to inspect your page islands, see helpful audits on performance and accessibility, and more. - * - * ```js - * { - * experimental: { - * devOverlay: true, - * }, - * } - * ``` - */ - devOverlay?: boolean; - - /** - * @docs - * @name experimental.i18n - * @type {object} - * @version 3.5.0 - * @type {object} - * @description - * - * Configures experimental i18n routing and allows you to specify some customization options. - * - * See our guide for more information on [internationalization in Astro](/en/guides/internationalization/) - */ - i18n?: { - /** - * @docs - * @kind h4 - * @name experimental.i18n.defaultLocale - * @type {string} - * @version 3.5.0 - * @description - * - * The default locale of your website/application. This is a required field. - * - * No particular language format or syntax is enforced, but we suggest using lower-case and hyphens as needed (e.g. "es", "pt-br") for greatest compatibility. - */ - defaultLocale: string; - /** - * @docs - * @kind h4 - * @name experimental.i18n.locales - * @type {string[]} - * @version 3.5.0 - * @description - * - * A list of all locales supported by the website (e.g. `['en', 'es', 'pt-br']`). This list should also include the `defaultLocale`. This is a required field. - * - * No particular language format or syntax is enforced, but your folder structure must match exactly the locales in the list. - */ - locales: string[]; - - /** - * @docs - * @kind h4 - * @name experimental.i18n.fallback - * @type {Record<string, string>} - * @version 3.5.0 - * @description - * - * The fallback strategy when navigating to pages that do not exist (e.g. a translated page has not been created). - * - * Use this object to declare a fallback `locale` route for each language you support. If no fallback is specified, then unavailable pages will return a 404. - * - * ##### Example - * - * The following example configures your content fallback strategy to redirect unavailable pages in `/pt-br/` to their `es` version, and unavailable pages in `/fr/` to their `en` version. Unavailable `/es/` pages will return a 404. - * - * ```js - * export default defineConfig({ - * experimental: { - * i18n: { - * defaultLocale: "en", - * locales: ["en", "fr", "pt-br", "es"], - * fallback: { - * pt: "es", - * fr: "en" - * } - * } - * } - * }) - * ``` - */ - fallback?: Record<string, string>; - - /** - * @docs - * @kind h4 - * @name experimental.i18n.routingStrategy - * @type {'prefix-always' | 'prefix-other-locales'} - * @default 'prefix-other-locales' - * @version 3.5.0 - * @description - * - * Controls the routing strategy to determine your site URLs. Set this based on your folder/URL path configuration for your default language: - * - * - `prefix-other-locales`(default): Only non-default languages will display a language prefix. - * The `defaultLocale` will not show a language prefix and content files do not exist in a localized folder. - * URLs will be of the form `example.com/[locale]/content/` for all non-default languages, but `example.com/content/` for the default locale. - * - `prefix-always`: All URLs will display a language prefix. - * URLs will be of the form `example.com/[locale]/content/` for every route, including the default language. - * Localized folders are used for every language, including the default. - * - */ - routingStrategy?: 'prefix-always' | 'prefix-other-locales'; - }; /** * @docs * @name experimental.contentCollectionCache @@ -1578,7 +1557,7 @@ export type InjectedScriptStage = 'before-hydration' | 'head-inline' | 'page' | export interface InjectedRoute { pattern: string; - entryPoint: string; + entrypoint: string; prerender?: boolean; } @@ -1714,6 +1693,7 @@ export interface AstroAdapterFeatures { export interface AstroSettings { config: AstroConfig; adapter: AstroAdapter | undefined; + preferences: AstroPreferences; injectedRoutes: InjectedRoute[]; resolvedInjectedRoutes: ResolvedInjectedRoute[]; pageExtensions: string[]; @@ -1728,7 +1708,7 @@ export interface AstroSettings { * Map of directive name (e.g. `load`) to the directive script code */ clientDirectives: Map<string, string>; - devOverlayPlugins: string[]; + devToolbarApps: string[]; middlewares: { pre: string[]; post: string[] }; tsConfig: TSConfig | undefined; tsConfigPath: string | undefined; @@ -1749,10 +1729,6 @@ export interface ComponentInstance { css?: string[]; partial?: boolean; prerender?: boolean; - /** - * Only used for logging if deprecated drafts feature is used - */ - frontmatter?: Record<string, any>; getStaticPaths?: (options: GetStaticPathsOptions) => GetStaticPathsResult; } @@ -1809,13 +1785,9 @@ export type GetHydrateCallback = () => Promise<() => void | Promise<void>>; * getStaticPaths() options * * [Astro Reference](https://docs.astro.build/en/reference/api-reference/#getstaticpaths) - */ export interface GetStaticPathsOptions { + */ +export interface GetStaticPathsOptions { paginate: PaginateFunction; - /** - * The RSS helper has been removed from getStaticPaths! Try the new @astrojs/rss package instead. - * @see https://docs.astro.build/en/guides/rss/ - */ - rss(): never; } export type GetStaticPathsItem = { @@ -2044,6 +2016,8 @@ export interface AstroInternationalizationFeature { detectBrowserLanguage?: SupportsKind; } +export type Locales = (string | { codes: string[]; path: string })[]; + export interface AstroAdapter { name: string; serverEntrypoint?: string; @@ -2056,11 +2030,9 @@ export interface AstroAdapter { * * If the adapter is not able to handle certain configurations, Astro will throw an error. */ - supportedAstroFeatures?: AstroFeatureMap; + supportedAstroFeatures: AstroFeatureMap; } -type Body = string; - export type ValidRedirectStatus = 300 | 301 | 302 | 303 | 304 | 307 | 308; // Shared types between `Astro` global and API context object @@ -2145,7 +2117,7 @@ export interface APIContext< * ]; * } * - * export async function get({ params }) { + * export async function GET({ params }) { * return { * body: `Hello user ${params.id}!`, * } @@ -2168,7 +2140,7 @@ export interface APIContext< * ]; * } * - * export function get({ props }) { + * export function GET({ props }) { * return { * body: `Hello ${props.name}!`, * } @@ -2184,7 +2156,7 @@ export interface APIContext< * Example usage: * ```ts * // src/pages/secret.ts - * export function get({ redirect }) { + * export function GET({ redirect }) { * return redirect('/login'); * } * ``` @@ -2217,10 +2189,9 @@ export interface APIContext< * ``` */ locals: App.Locals; - ResponseWithEncoding: typeof ResponseWithEncoding; /** - * Available only when `experimental.i18n` enabled and in SSR. + * Available only when `i18n` configured and in SSR. * * It represents the preferred locale of the user. It's computed by checking the supported locales in `i18n.locales` * and locales supported by the users's browser via the header `Accept-Language` @@ -2233,7 +2204,7 @@ export interface APIContext< preferredLocale: string | undefined; /** - * Available only when `experimental.i18n` enabled and in SSR. + * Available only when `i18n` configured and in SSR. * * It represents the list of the preferred locales that are supported by the application. The list is sorted via [quality value]. * @@ -2253,22 +2224,18 @@ export interface APIContext< currentLocale: string | undefined; } -export type EndpointOutput = - | { - body: Body; - encoding?: BufferEncoding; - } - | { - body: Uint8Array; - encoding: 'binary'; - }; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type Routing = { + prefixDefaultLocale: boolean; + strategy: 'pathname'; +}; export type APIRoute<Props extends Record<string, any> = Record<string, any>> = ( context: APIContext<Props> -) => EndpointOutput | Response | Promise<EndpointOutput | Response>; +) => Response | Promise<Response>; export interface EndpointHandler { - [method: string]: APIRoute | ((params: Params, request: Request) => EndpointOutput | Response); + [method: string]: APIRoute | ((params: Params, request: Request) => Response); } export type Props = Record<string, unknown>; @@ -2311,13 +2278,17 @@ export interface AstroIntegration { config: AstroConfig; command: 'dev' | 'build' | 'preview'; isRestart: boolean; - updateConfig: (newConfig: Record<string, any>) => void; + updateConfig: (newConfig: DeepPartial<AstroConfig>) => AstroConfig; addRenderer: (renderer: AstroRenderer) => void; addWatchFile: (path: URL | string) => void; injectScript: (stage: InjectedScriptStage, content: string) => void; injectRoute: (injectRoute: InjectedRoute) => void; addClientDirective: (directive: ClientDirectiveConfig) => void; + /** + * @deprecated Use `addDevToolbarApp` instead. + */ addDevOverlayPlugin: (entrypoint: string) => void; + addDevToolbarApp: (entrypoint: string) => void; addMiddleware: (mid: AstroIntegrationMiddleware) => void; logger: AstroIntegrationLogger; // TODO: Add support for `injectElement()` for full HTML element injection, not just scripts. @@ -2373,20 +2344,16 @@ export interface AstroIntegration { }; } -export type MiddlewareNext<R> = () => Promise<R>; -export type MiddlewareHandler<R> = ( +export type MiddlewareNext = () => Promise<Response>; +export type MiddlewareHandler = ( context: APIContext, - next: MiddlewareNext<R> -) => Promise<R> | R | Promise<void> | void; - -export type MiddlewareResponseHandler = MiddlewareHandler<Response>; -export type MiddlewareEndpointHandler = MiddlewareHandler<Response | EndpointOutput>; -export type MiddlewareNextResponse = MiddlewareNext<Response>; + next: MiddlewareNext +) => Promise<Response> | Response | Promise<void> | void; // NOTE: when updating this file with other functions, // remember to update `plugin-page.ts` too, to add that function as a no-op function. -export type AstroMiddlewareInstance<R> = { - onRequest?: MiddlewareHandler<R>; +export type AstroMiddlewareInstance = { + onRequest?: MiddlewareHandler; }; export type AstroIntegrationMiddleware = { @@ -2434,16 +2401,21 @@ export interface RouteData { prerender: boolean; redirect?: RedirectConfig; redirectRoute?: RouteData; + fallbackRoutes: RouteData[]; } export type RedirectRouteData = RouteData & { redirect: string; }; -export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern' | 'redirectRoute'> & { +export type SerializedRouteData = Omit< + RouteData, + 'generate' | 'pattern' | 'redirectRoute' | 'fallbackRoutes' +> & { generate: undefined; pattern: string; redirectRoute: SerializedRouteData | undefined; + fallbackRoutes: SerializedRouteData[]; _meta: { trailingSlash: AstroConfig['trailingSlash']; }; @@ -2567,7 +2539,7 @@ export interface ClientDirectiveConfig { entrypoint: string; } -export interface DevOverlayPlugin { +export interface DevToolbarApp { id: string; name: string; icon: Icon; @@ -2575,20 +2547,40 @@ export interface DevOverlayPlugin { beforeTogglingOff?(canvas: ShadowRoot): boolean | Promise<boolean>; } +export type DevOverlayPlugin = DevToolbarApp; + export type DevOverlayMetadata = Window & typeof globalThis & { __astro_dev_overlay__: { root: string; + version: string; + debugInfo: string; }; }; declare global { interface HTMLElementTagNameMap { + 'astro-dev-toolbar': AstroDevOverlay; + 'astro-dev-toolbar-window': DevOverlayWindow; + 'astro-dev-toolbar-plugin-canvas': DevOverlayCanvas; + 'astro-dev-toolbar-tooltip': DevOverlayTooltip; + 'astro-dev-toolbar-highlight': DevOverlayHighlight; + 'astro-dev-toolbar-toggle': DevOverlayToggle; + 'astro-dev-toolbar-badge': DevOverlayBadge; + 'astro-dev-toolbar-button': DevOverlayButton; + 'astro-dev-toolbar-icon': DevOverlayIcon; + 'astro-dev-toolbar-card': DevOverlayCard; + + // Deprecated names 'astro-dev-overlay': AstroDevOverlay; 'astro-dev-overlay-window': DevOverlayWindow; 'astro-dev-overlay-plugin-canvas': DevOverlayCanvas; 'astro-dev-overlay-tooltip': DevOverlayTooltip; 'astro-dev-overlay-highlight': DevOverlayHighlight; 'astro-dev-overlay-toggle': DevOverlayToggle; + 'astro-dev-overlay-badge': DevOverlayBadge; + 'astro-dev-overlay-button': DevOverlayButton; + 'astro-dev-overlay-icon': DevOverlayIcon; + 'astro-dev-overlay-card': DevOverlayCard; } } diff --git a/packages/astro/src/assets/build/generate.ts b/packages/astro/src/assets/build/generate.ts index be637c26da7ad..1c55a93b98749 100644 --- a/packages/astro/src/assets/build/generate.ts +++ b/packages/astro/src/assets/build/generate.ts @@ -1,7 +1,7 @@ import { dim, green } from 'kleur/colors'; import fs, { readFileSync } from 'node:fs'; import { basename, join } from 'node:path/posix'; -import PQueue from 'p-queue'; +import type PQueue from 'p-queue'; import type { AstroConfig } from '../../@types/astro.js'; import type { BuildPipeline } from '../../core/build/buildPipeline.js'; import { getOutDirWithinCwd } from '../../core/build/common.js'; @@ -58,7 +58,7 @@ export async function prepareAssetsGenerationEnv( await fs.promises.mkdir(assetsCacheDir, { recursive: true }); } catch (err) { logger.warn( - 'astro:assets', + null, `An error was encountered while creating the cache directory. Proceeding without caching. Error: ${err}` ); useCache = false; @@ -231,7 +231,7 @@ export async function generateImagesForPath( } } catch (e) { env.logger.warn( - 'astro:assets', + null, `An error was encountered while creating the cache directory. Proceeding without caching. Error: ${e}` ); } finally { diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index 46319ed3bc4c6..06dad68524691 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -19,7 +19,7 @@ export function injectImageEndpoint(settings: AstroSettings, mode: 'dev' | 'buil settings.injectedRoutes.push({ pattern: '/_image', - entryPoint: endpointEntrypoint, + entrypoint: endpointEntrypoint, prerender: false, }); @@ -79,6 +79,16 @@ export async function getImage( message: AstroErrorData.ExpectedImageOptions.message(JSON.stringify(options)), }); } + if (typeof options.src === 'undefined') { + throw new AstroError({ + ...AstroErrorData.ExpectedImage, + message: AstroErrorData.ExpectedImage.message( + options.src, + 'undefined', + JSON.stringify(options) + ), + }); + } const service = await getConfiguredImageService(); diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index 80c0e10ff760b..76323ca0b7894 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -5,6 +5,7 @@ import { bold, cyan, dim, green, magenta, red, yellow } from 'kleur/colors'; import fsMod, { existsSync, promises as fs } from 'node:fs'; import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; +import maxSatisfying from 'semver/ranges/max-satisfying.js'; import ora from 'ora'; import preferredPM from 'preferred-pm'; import prompts from 'prompts'; @@ -610,15 +611,7 @@ async function getInstallIntegrationsCommand({ logger.debug('add', `package manager: ${JSON.stringify(pm)}`); if (!pm) return null; - let dependencies = integrations - .map<[string, string | null][]>((i) => [[i.packageName, null], ...i.dependencies]) - .flat(1) - .filter((dep, i, arr) => arr.findIndex((d) => d[0] === dep[0]) === i) - .map(([name, version]) => - version === null ? name : `${name}@${version.split(/\s*\|\|\s*/).pop()}` - ) - .sort(); - + const dependencies = await convertIntegrationsToInstallSpecifiers(integrations); switch (pm.name) { case 'npm': return { pm: 'npm', command: 'install', flags: [], dependencies }; @@ -633,6 +626,35 @@ async function getInstallIntegrationsCommand({ } } +async function convertIntegrationsToInstallSpecifiers( + integrations: IntegrationInfo[] +): Promise<string[]> { + const ranges: Record<string, string> = {}; + for (let { packageName, dependencies } of integrations) { + ranges[packageName] = '*'; + for (const [name, range] of dependencies) { + ranges[name] = range; + } + } + return Promise.all( + Object.entries(ranges).map(([name, range]) => resolveRangeToInstallSpecifier(name, range)) + ); +} + +/** + * Resolves package with a given range to a STABLE version + * peerDependencies might specify a compatible prerelease, + * but `astro add` should only ever install stable releases + */ +async function resolveRangeToInstallSpecifier(name: string, range: string): Promise<string> { + const versions = await fetchPackageVersions(name); + if (versions instanceof Error) return name; + // Filter out any prerelease versions + const stableVersions = versions.filter((v) => !v.includes('-')); + const maxStable = maxSatisfying(stableVersions, range); + return `${name}@^${maxStable}`; +} + // Allow forwarding of standard `npm install` flags // See https://docs.npmjs.com/cli/v8/commands/npm-install#description const INHERITED_FLAGS = new Set<string>([ @@ -725,7 +747,7 @@ async function fetchPackageJson( scope: string | undefined, name: string, tag: string -): Promise<object | Error> { +): Promise<Record<string, any> | Error> { const packageName = `${scope ? `${scope}/` : ''}${name}`; const registry = await getRegistry(); const res = await fetch(`${registry}/${packageName}/${tag}`); @@ -739,6 +761,21 @@ async function fetchPackageJson( } } +async function fetchPackageVersions(packageName: string): Promise<string[] | Error> { + const registry = await getRegistry(); + const res = await fetch(`${registry}/${packageName}`, { + headers: { accept: 'application/vnd.npm.install-v1+json' }, + }); + if (res.status >= 200 && res.status < 300) { + return await res.json().then((data) => Object.keys(data.versions)); + } else if (res.status === 404) { + // 404 means the package doesn't exist, so we don't need an error message here + return new Error(); + } else { + return new Error(`Failed to fetch ${registry}/${packageName} - GET ${res.status}`); + } +} + export async function validateIntegrations(integrations: string[]): Promise<IntegrationInfo[]> { const spinner = ora('Resolving packages...').start(); try { diff --git a/packages/astro/src/cli/build/index.ts b/packages/astro/src/cli/build/index.ts index 1a7d5aa520481..15ff584317d93 100644 --- a/packages/astro/src/cli/build/index.ts +++ b/packages/astro/src/cli/build/index.ts @@ -14,7 +14,6 @@ export async function build({ flags }: BuildOptions) { usage: '[...flags]', tables: { Flags: [ - ['--drafts', `Include Markdown draft pages in the build.`], ['--outDir <directory>', `Specify the output directory for the build.`], ['--help (-h)', 'See all available flags.'], ], diff --git a/packages/astro/src/cli/flags.ts b/packages/astro/src/cli/flags.ts index c97f1801acf1d..c384d98671b86 100644 --- a/packages/astro/src/cli/flags.ts +++ b/packages/astro/src/cli/flags.ts @@ -15,9 +15,6 @@ export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig { site: typeof flags.site === 'string' ? flags.site : undefined, base: typeof flags.base === 'string' ? flags.base : undefined, outDir: typeof flags.outDir === 'string' ? flags.outDir : undefined, - markdown: { - drafts: typeof flags.drafts === 'boolean' ? flags.drafts : undefined, - }, server: { port: typeof flags.port === 'number' ? flags.port : undefined, host: diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts index 0421258a51ae4..7ca4d21a9a7bd 100644 --- a/packages/astro/src/cli/index.ts +++ b/packages/astro/src/cli/index.ts @@ -14,6 +14,7 @@ type CLICommand = | 'sync' | 'check' | 'info' + | 'preferences' | 'telemetry'; /** Display --help flag */ @@ -33,6 +34,7 @@ async function printAstroHelp() { ['info', 'List info about your current Astro setup.'], ['preview', 'Preview your build locally.'], ['sync', 'Generate content collection types.'], + ['preferences', 'Configure user preferences.'], ['telemetry', 'Configure telemetry settings.'], ], 'Global Flags': [ @@ -64,6 +66,7 @@ function resolveCommand(flags: yargs.Arguments): CLICommand { 'add', 'sync', 'telemetry', + 'preferences', 'dev', 'build', 'preview', @@ -114,6 +117,12 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { const exitCode = await sync({ flags }); return process.exit(exitCode); } + case 'preferences': { + const { preferences } = await import('./preferences/index.js'); + const [subcommand, key, value] = flags._.slice(3).map((v) => v.toString()); + const exitCode = await preferences(subcommand, key, value, { flags }); + return process.exit(exitCode); + } } // In verbose/debug mode, we log the debug logs asap before any potential errors could appear @@ -177,7 +186,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { /** The primary CLI action */ export async function cli(args: string[]) { - const flags = yargs(args); + const flags = yargs(args, { boolean: ['global'], alias: { g: 'global' } }); const cmd = resolveCommand(flags); try { await runCommand(cmd, flags); diff --git a/packages/astro/src/cli/info/index.ts b/packages/astro/src/cli/info/index.ts index 46e7d3c6978c7..c6586b28d2a4d 100644 --- a/packages/astro/src/cli/info/index.ts +++ b/packages/astro/src/cli/info/index.ts @@ -4,6 +4,7 @@ import { execSync } from 'node:child_process'; import { arch, platform } from 'node:os'; import prompts from 'prompts'; import type yargs from 'yargs-parser'; +import type { AstroConfig, AstroUserConfig } from '../../@types/astro.js'; import { resolveConfig } from '../../core/config/index.js'; import { ASTRO_VERSION } from '../../core/constants.js'; import { flagsToAstroInlineConfig } from '../flags.js'; @@ -12,7 +13,13 @@ interface InfoOptions { flags: yargs.Arguments; } -export async function printInfo({ flags }: InfoOptions) { +export async function getInfoOutput({ + userConfig, + print, +}: { + userConfig: AstroUserConfig | AstroConfig; + print: boolean; +}): Promise<string> { const rows: Array<[string, string | string[]]> = [ ['Astro', `v${ASTRO_VERSION}`], ['Node', process.version], @@ -20,9 +27,7 @@ export async function printInfo({ flags }: InfoOptions) { ['Package Manager', getPackageManager()], ]; - const inlineConfig = flagsToAstroInlineConfig(flags); try { - const { userConfig } = await resolveConfig(inlineConfig, 'info'); rows.push(['Output', userConfig.output ?? 'static']); rows.push(['Adapter', userConfig.adapter?.name ?? 'none']); const integrations = (userConfig?.integrations ?? []) @@ -35,10 +40,17 @@ export async function printInfo({ flags }: InfoOptions) { let output = ''; for (const [label, value] of rows) { - output += printRow(label, value); + output += printRow(label, value, print); } - await copyToClipboard(output.trim()); + return output.trim(); +} + +export async function printInfo({ flags }: InfoOptions) { + const { userConfig } = await resolveConfig(flagsToAstroInlineConfig(flags), 'info'); + const output = await getInfoOutput({ userConfig, print: true }); + + await copyToClipboard(output); } async function copyToClipboard(text: string) { @@ -105,7 +117,7 @@ function getPackageManager() { } const MAX_PADDING = 25; -function printRow(label: string, value: string | string[]) { +function printRow(label: string, value: string | string[], print: boolean) { const padding = MAX_PADDING - label.length; const [first, ...rest] = Array.isArray(value) ? value : [value]; let plaintext = `${label}${' '.repeat(padding)}${first}`; @@ -117,6 +129,8 @@ function printRow(label: string, value: string | string[]) { } } plaintext += '\n'; - console.log(richtext); + if (print) { + console.log(richtext); + } return plaintext; } diff --git a/packages/astro/src/cli/install-package.ts b/packages/astro/src/cli/install-package.ts index 689f81e3e8791..667037a0cb3de 100644 --- a/packages/astro/src/cli/install-package.ts +++ b/packages/astro/src/cli/install-package.ts @@ -26,7 +26,7 @@ export async function getPackage<T>( packageImport = await import(packageName); } catch (e) { logger.info( - '', + null, `To continue, Astro requires the following dependency to be installed: ${bold(packageName)}.` ); const result = await installPackage([packageName, ...otherDeps], options, logger); diff --git a/packages/astro/src/cli/preferences/index.ts b/packages/astro/src/cli/preferences/index.ts new file mode 100644 index 0000000000000..4fd29cdfea144 --- /dev/null +++ b/packages/astro/src/cli/preferences/index.ts @@ -0,0 +1,340 @@ +/* eslint-disable no-console */ +import type yargs from 'yargs-parser'; +import type { AstroSettings } from '../../@types/astro.js'; + +import { bgGreen, black, bold, dim } from 'kleur/colors'; +import { fileURLToPath } from 'node:url'; + +import dlv from 'dlv'; +import { resolveConfig } from '../../core/config/config.js'; +import { createSettings } from '../../core/config/settings.js'; +import * as msg from '../../core/messages.js'; +import { DEFAULT_PREFERENCES } from '../../preferences/defaults.js'; +import { + coerce, + isValidKey, + type PreferenceKey, + type PreferenceLocation, +} from '../../preferences/index.js'; +import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js'; +// @ts-expect-error flattie types are mispackaged +import { flattie } from 'flattie'; +import { formatWithOptions } from 'node:util'; +import { collectErrorMetadata } from '../../core/errors/dev/utils.js'; + +interface PreferencesOptions { + flags: yargs.Arguments; +} + +const PREFERENCES_SUBCOMMANDS = [ + 'get', + 'set', + 'enable', + 'disable', + 'delete', + 'reset', + 'list', +] as const; +export type Subcommand = (typeof PREFERENCES_SUBCOMMANDS)[number]; + +function isValidSubcommand(subcommand: string): subcommand is Subcommand { + return PREFERENCES_SUBCOMMANDS.includes(subcommand as Subcommand); +} + +export async function preferences( + subcommand: string, + key: string, + value: string | undefined, + { flags }: PreferencesOptions +): Promise<number> { + if (!isValidSubcommand(subcommand) || flags?.help || flags?.h) { + msg.printHelp({ + commandName: 'astro preferences', + usage: '[command]', + tables: { + Commands: [ + ['list', 'Pretty print all current preferences'], + ['list --json', 'Log all current preferences as a JSON object'], + ['get [key]', 'Log current preference value'], + ['set [key] [value]', 'Update preference value'], + ['reset [key]', 'Reset preference value to default'], + ['enable [key]', 'Set a boolean preference to true'], + ['disable [key]', 'Set a boolean preference to false'], + ], + Flags: [ + [ + '--global', + 'Scope command to global preferences (all Astro projects) rather than the current project', + ], + ], + }, + }); + return 0; + } + + const inlineConfig = flagsToAstroInlineConfig(flags); + const logger = createLoggerFromFlags(flags); + const { astroConfig } = await resolveConfig(inlineConfig ?? {}, 'dev'); + const settings = await createSettings(astroConfig, fileURLToPath(astroConfig.root)); + const opts: SubcommandOptions = { + location: flags.global ? 'global' : undefined, + json: flags.json, + }; + + if (subcommand === 'list') { + return listPreferences(settings, opts); + } + + if (subcommand === 'enable' || subcommand === 'disable') { + key = `${key}.enabled` as PreferenceKey; + } + + if (!isValidKey(key)) { + logger.error('preferences', `Unknown preference "${key}"\n`); + return 1; + } + + if (subcommand === 'set' && value === undefined) { + const type = typeof dlv(DEFAULT_PREFERENCES, key); + console.error( + msg.formatErrorMessage( + collectErrorMetadata(new Error(`Please provide a ${type} value for "${key}"`)), + true + ) + ); + return 1; + } + + switch (subcommand) { + case 'get': + return getPreference(settings, key, opts); + case 'set': + return setPreference(settings, key, value, opts); + case 'reset': + case 'delete': + return resetPreference(settings, key, opts); + case 'enable': + return enablePreference(settings, key, opts); + case 'disable': + return disablePreference(settings, key, opts); + } +} + +interface SubcommandOptions { + location?: 'global' | 'project'; + json?: boolean; +} + +// Default `location` to "project" to avoid reading default preferencesa +async function getPreference( + settings: AstroSettings, + key: PreferenceKey, + { location = 'project' }: SubcommandOptions +) { + try { + let value = await settings.preferences.get(key, { location }); + if (value && typeof value === 'object' && !Array.isArray(value)) { + if (Object.keys(value).length === 0) { + value = dlv(DEFAULT_PREFERENCES, key); + console.log(msg.preferenceDefaultIntro(key)); + } + prettyPrint({ [key]: value }); + return 0; + } + if (value === undefined) { + const defaultValue = await settings.preferences.get(key); + console.log(msg.preferenceDefault(key, defaultValue)); + return 0; + } + console.log(msg.preferenceGet(key, value)); + return 0; + } catch {} + return 1; +} + +async function setPreference( + settings: AstroSettings, + key: PreferenceKey, + value: unknown, + { location }: SubcommandOptions +) { + try { + const defaultType = typeof dlv(DEFAULT_PREFERENCES, key); + if (typeof coerce(key, value) !== defaultType) { + throw new Error(`${key} expects a "${defaultType}" value!`); + } + + await settings.preferences.set(key, coerce(key, value), { location }); + console.log(msg.preferenceSet(key, value)); + return 0; + } catch (e) { + if (e instanceof Error) { + console.error(msg.formatErrorMessage(collectErrorMetadata(e), true)); + return 1; + } + throw e; + } +} + +async function enablePreference( + settings: AstroSettings, + key: PreferenceKey, + { location }: SubcommandOptions +) { + try { + await settings.preferences.set(key, true, { location }); + console.log(msg.preferenceEnabled(key.replace('.enabled', ''))); + return 0; + } catch {} + return 1; +} + +async function disablePreference( + settings: AstroSettings, + key: PreferenceKey, + { location }: SubcommandOptions +) { + try { + await settings.preferences.set(key, false, { location }); + console.log(msg.preferenceDisabled(key.replace('.enabled', ''))); + return 0; + } catch {} + return 1; +} + +async function resetPreference( + settings: AstroSettings, + key: PreferenceKey, + { location }: SubcommandOptions +) { + try { + await settings.preferences.set(key, undefined as any, { location }); + console.log(msg.preferenceReset(key)); + return 0; + } catch {} + return 1; +} + +async function listPreferences(settings: AstroSettings, { location, json }: SubcommandOptions) { + if (json) { + const resolved = await settings.preferences.getAll(); + console.log(JSON.stringify(resolved, null, 2)); + return 0; + } + const { global, project, defaults } = await settings.preferences.list({ location }); + const flatProject = flattie(project); + const flatGlobal = flattie(global); + const flatUser = Object.assign({}, flatGlobal, flatProject); + for (let key of Object.keys(flatUser)) { + if (!isValidKey(key)) { + delete flatUser[key]; + continue; + } + } + + const flatDefault = flattie(defaults); + const userKeys = Object.keys(flatUser); + + if (userKeys.length > 0) { + const badge = bgGreen(black(` Your Preferences `)); + const table = formatTable(flatUser, ['Preference', 'Value']); + + console.log(['', badge, table].join('\n')); + } else { + const badge = bgGreen(black(` Your Preferences `)); + const message = dim('No preferences set'); + console.log(['', badge, '', message].join('\n')); + } + const flatUnset = Object.assign({}, flatDefault); + for (const key of userKeys) { + delete flatUnset[key]; + } + const unsetKeys = Object.keys(flatUnset); + + if (unsetKeys.length > 0) { + const badge = bgGreen(black(` Default Preferences `)); + const table = formatTable(flatUnset, ['Preference', 'Value']); + + console.log(['', badge, table].join('\n')); + } else { + const badge = bgGreen(black(` Default Preferences `)); + const message = dim('All preferences have been set'); + console.log(['', badge, '', message].join('\n')); + } + + return 0; +} + +function prettyPrint(value: Record<string, string | number | boolean>) { + const flattened = flattie(value); + const table = formatTable(flattened, ['Preference', 'Value']); + console.log(table); +} + +const chars = { + h: '─', + hThick: '━', + hThickCross: '┿', + v: '│', + vRight: '├', + vRightThick: '┝', + vLeft: '┤', + vLeftThick: '┥', + hTop: '┴', + hBottom: '┬', + topLeft: '╭', + topRight: '╮', + bottomLeft: '╰', + bottomRight: '╯', +}; + +function formatTable( + object: Record<string, string | number | boolean>, + columnLabels: [string, string] +) { + const [colA, colB] = columnLabels; + const colALength = [colA, ...Object.keys(object)].reduce(longest, 0) + 3; + const colBLength = [colB, ...Object.values(object)].reduce(longest, 0) + 3; + function formatRow( + i: number, + a: string, + b: string | number | boolean, + style: (value: string | number | boolean) => string = (v) => v.toString() + ): string { + return `${dim(chars.v)} ${style(a)} ${space(colALength - a.length - 2)} ${dim(chars.v)} ${style( + b + )} ${space(colBLength - b.toString().length - 3)} ${dim(chars.v)}`; + } + const top = dim( + `${chars.topLeft}${chars.h.repeat(colALength + 1)}${chars.hBottom}${chars.h.repeat( + colBLength + )}${chars.topRight}` + ); + const bottom = dim( + `${chars.bottomLeft}${chars.h.repeat(colALength + 1)}${chars.hTop}${chars.h.repeat( + colBLength + )}${chars.bottomRight}` + ); + const divider = dim( + `${chars.vRightThick}${chars.hThick.repeat(colALength + 1)}${ + chars.hThickCross + }${chars.hThick.repeat(colBLength)}${chars.vLeftThick}` + ); + const rows: string[] = [top, formatRow(-1, colA, colB, bold), divider]; + let i = 0; + for (const [key, value] of Object.entries(object)) { + rows.push(formatRow(i, key, value, (v) => formatWithOptions({ colors: true }, v))); + i++; + } + rows.push(bottom); + return rows.join('\n'); +} + +function space(len: number) { + return ' '.repeat(len); +} + +const longest = (a: number, b: string | number | boolean) => { + const { length: len } = b.toString(); + return a > len ? a : len; +}; diff --git a/packages/astro/src/cli/telemetry/index.ts b/packages/astro/src/cli/telemetry/index.ts index fd664fcc94414..277b1cab67216 100644 --- a/packages/astro/src/cli/telemetry/index.ts +++ b/packages/astro/src/cli/telemetry/index.ts @@ -1,23 +1,23 @@ /* eslint-disable no-console */ -import whichPm from 'which-pm'; import type yargs from 'yargs-parser'; import * as msg from '../../core/messages.js'; import { telemetry } from '../../events/index.js'; +import { createLoggerFromFlags } from '../flags.js'; interface TelemetryOptions { flags: yargs.Arguments; } export async function notify() { - const packageManager = (await whichPm(process.cwd()))?.name ?? 'npm'; await telemetry.notify(() => { - console.log(msg.telemetryNotice(packageManager) + '\n'); + console.log(msg.telemetryNotice() + '\n'); return true; }); } export async function update(subcommand: string, { flags }: TelemetryOptions) { const isValid = ['enable', 'disable', 'reset'].includes(subcommand); + const logger = createLoggerFromFlags(flags); if (flags.help || flags.h || !isValid) { msg.printHelp({ @@ -37,17 +37,17 @@ export async function update(subcommand: string, { flags }: TelemetryOptions) { switch (subcommand) { case 'enable': { telemetry.setEnabled(true); - console.log(msg.telemetryEnabled()); + logger.info('SKIP_FORMAT', msg.telemetryEnabled()); return; } case 'disable': { telemetry.setEnabled(false); - console.log(msg.telemetryDisabled()); + logger.info('SKIP_FORMAT', msg.telemetryDisabled()); return; } case 'reset': { telemetry.clear(); - console.log(msg.telemetryReset()); + logger.info('SKIP_FORMAT', msg.telemetryReset()); return; } } diff --git a/packages/astro/src/cli/throw-and-exit.ts b/packages/astro/src/cli/throw-and-exit.ts index 3196092d2cc6e..1a8916ede9c59 100644 --- a/packages/astro/src/cli/throw-and-exit.ts +++ b/packages/astro/src/cli/throw-and-exit.ts @@ -20,7 +20,7 @@ export async function throwAndExit(cmd: string, err: unknown) { const errorWithMetadata = collectErrorMetadata(createSafeError(err)); telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true })); - errorMessage = formatErrorMessage(errorWithMetadata); + errorMessage = formatErrorMessage(errorWithMetadata, true); // Timeout the error reporter (very short) because the user is waiting. // NOTE(fks): It is better that we miss some events vs. holding too long. diff --git a/packages/astro/src/content/server-listeners.ts b/packages/astro/src/content/server-listeners.ts index 699d5f2710dd1..3ff3148cbdfc8 100644 --- a/packages/astro/src/content/server-listeners.ts +++ b/packages/astro/src/content/server-listeners.ts @@ -1,4 +1,4 @@ -import { bold, cyan } from 'kleur/colors'; +import { bold, cyan, underline } from 'kleur/colors'; import type fsMod from 'node:fs'; import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; @@ -26,7 +26,7 @@ export async function attachContentServerListeners({ const contentPaths = getContentPaths(settings.config, fs); if (fs.existsSync(contentPaths.contentDir)) { - logger.info( + logger.debug( 'content', `Watching ${cyan( contentPaths.contentDir.href.replace(settings.config.root.href, '') @@ -39,7 +39,7 @@ export async function attachContentServerListeners({ viteServer.watcher.on('addDir', contentDirListener); async function contentDirListener(dir: string) { if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) { - logger.info('content', `Content dir found. Watching for changes`); + logger.debug('content', `Content directory found. Watching for changes`); await attachListeners(); viteServer.watcher.removeListener('addDir', contentDirListener); } @@ -55,7 +55,7 @@ export async function attachContentServerListeners({ contentConfigObserver: globalContentConfigObserver, }); await contentGenerator.init(); - logger.info('content', 'Types generated'); + logger.debug('content', 'Types generated'); viteServer.watcher.on('add', (entry) => { contentGenerator.queueEvent({ name: 'add', entry }); @@ -90,9 +90,9 @@ function warnAllowJsIsFalse({ 'true' )} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold( contentConfigFileName - )} file. -See ${bold('https://www.typescriptlang.org/tsconfig#allowJs')} for more information. - ` + )} file. See ${underline( + cyan('https://www.typescriptlang.org/tsconfig#allowJs') + )} for more information.` ); } diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts index b50c597fdf5e7..dc9c1ecc76edd 100644 --- a/packages/astro/src/content/types-generator.ts +++ b/packages/astro/src/content/types-generator.ts @@ -1,5 +1,5 @@ import glob from 'fast-glob'; -import { cyan } from 'kleur/colors'; +import { bold, cyan } from 'kleur/colors'; import type fsMod from 'node:fs'; import * as path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; @@ -56,13 +56,6 @@ type CreateContentGeneratorParams = { fs: typeof fsMod; }; -type EventOpts = { logLevel: 'info' | 'warn' }; - -type EventWithOptions = { - type: ContentEvent; - opts: EventOpts | undefined; -}; - class UnsupportedFileTypeError extends Error {} export async function createContentTypesGenerator({ @@ -78,7 +71,7 @@ export async function createContentTypesGenerator({ const contentEntryExts = [...contentEntryConfigByExt.keys()]; const dataEntryExts = getDataEntryExts(settings); - let events: EventWithOptions[] = []; + let events: ContentEvent[] = []; let debounceTimeout: NodeJS.Timeout | undefined; const typeTemplateContent = await fs.promises.readFile(contentPaths.typesTemplate, 'utf-8'); @@ -90,10 +83,7 @@ export async function createContentTypesGenerator({ return { typesGenerated: false, reason: 'no-content-dir' }; } - events.push({ - type: { name: 'add', entry: contentPaths.config.url }, - opts: { logLevel: 'warn' }, - }); + events.push({ name: 'add', entry: contentPaths.config.url }); const globResult = await glob('**', { cwd: fileURLToPath(contentPaths.contentDir), @@ -110,12 +100,9 @@ export async function createContentTypesGenerator({ const entryURL = pathToFileURL(fullPath); if (entryURL.href.startsWith(contentPaths.config.url.href)) continue; if (entry.dirent.isFile()) { - events.push({ - type: { name: 'add', entry: entryURL }, - opts: { logLevel: 'warn' }, - }); + events.push({ name: 'add', entry: entryURL }); } else if (entry.dirent.isDirectory()) { - events.push({ type: { name: 'addDir', entry: entryURL }, opts: { logLevel: 'warn' } }); + events.push({ name: 'addDir', entry: entryURL }); } } await runEvents(); @@ -123,11 +110,8 @@ export async function createContentTypesGenerator({ } async function handleEvent( - event: ContentEvent, - opts?: EventOpts + event: ContentEvent ): Promise<{ shouldGenerateTypes: boolean; error?: Error }> { - const logLevel = opts?.logLevel ?? 'info'; - if (event.name === 'addDir' || event.name === 'unlinkDir') { const collection = normalizePath( path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry)) @@ -140,9 +124,7 @@ export async function createContentTypesGenerator({ switch (event.name) { case 'addDir': collectionEntryMap[JSON.stringify(collection)] = { type: 'unknown', entries: {} }; - if (logLevel === 'info') { - logger.info('content', `${cyan(collection)} collection added`); - } + logger.debug('content', `${cyan(collection)} collection added`); break; case 'unlinkDir': if (collectionKey in collectionEntryMap) { @@ -186,16 +168,14 @@ export async function createContentTypesGenerator({ const collection = getEntryCollectionName({ entry, contentDir }); if (collection === undefined) { - if (['info', 'warn'].includes(logLevel)) { - logger.warn( - 'content', - `${cyan( - normalizePath( - path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry)) - ) - )} must be nested in a collection directory. Skipping.` - ); - } + logger.warn( + 'content', + `${bold( + normalizePath( + path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry)) + ) + )} must live in a ${bold('content/...')} collection subdirectory.` + ); return { shouldGenerateTypes: false }; } @@ -308,22 +288,19 @@ export async function createContentTypesGenerator({ } } - function queueEvent(rawEvent: RawContentEvent, opts?: EventOpts) { + function queueEvent(rawEvent: RawContentEvent) { const event = { - type: { - entry: pathToFileURL(rawEvent.entry), - name: rawEvent.name, - }, - opts, + entry: pathToFileURL(rawEvent.entry), + name: rawEvent.name, }; - if (!event.type.entry.pathname.startsWith(contentPaths.contentDir.pathname)) return; + if (!event.entry.pathname.startsWith(contentPaths.contentDir.pathname)) return; events.push(event); debounceTimeout && clearTimeout(debounceTimeout); const runEventsSafe = async () => { try { - await runEvents(opts); + await runEvents(); } catch { // Prevent frontmatter errors from crashing the server. The errors // are still reported on page reflects as desired. @@ -333,30 +310,25 @@ export async function createContentTypesGenerator({ debounceTimeout = setTimeout(runEventsSafe, 50 /* debounce to batch chokidar events */); } - async function runEvents(opts?: EventOpts) { - const logLevel = opts?.logLevel ?? 'info'; + async function runEvents() { const eventResponses = []; for (const event of events) { - const response = await handleEvent(event.type, event.opts); + const response = await handleEvent(event); eventResponses.push(response); } events = []; - let unsupportedFiles = []; for (const response of eventResponses) { if (response.error instanceof UnsupportedFileTypeError) { - unsupportedFiles.push(response.error.message); + logger.warn( + 'content', + `Unsupported file type ${bold( + response.error.message + )} found. Prefix filename with an underscore (\`_\`) to ignore.` + ); } } - if (unsupportedFiles.length > 0 && ['info', 'warn'].includes(logLevel)) { - logger.warn( - 'content', - `Unsupported file types found. Prefix with an underscore (\`_\`) to ignore:\n- ${unsupportedFiles.join( - '\n' - )}` - ); - } const observable = contentConfigObserver.get(); if (eventResponses.some((r) => r.shouldGenerateTypes)) { await writeContentFiles({ @@ -369,7 +341,7 @@ export async function createContentTypesGenerator({ viteServer, }); invalidateVirtualMod(viteServer); - if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) { + if (observable.status === 'loaded') { warnNonexistentCollections({ logger, contentConfig: observable.config, @@ -475,6 +447,7 @@ async function writeContentFiles({ let configPathRelativeToCacheDir = normalizePath( path.relative(contentPaths.cacheDir.pathname, contentPaths.config.url.pathname) ); + if (!isRelativePath(configPathRelativeToCacheDir)) configPathRelativeToCacheDir = './' + configPathRelativeToCacheDir; @@ -514,9 +487,9 @@ function warnNonexistentCollections({ if (!collectionEntryMap[JSON.stringify(configuredCollection)]) { logger.warn( 'content', - `The ${JSON.stringify( - configuredCollection - )} collection does not have an associated folder in your \`content\` directory. Make sure the folder exists, or check your content config for typos.` + `The ${bold(configuredCollection)} collection is defined but no ${bold( + 'content/' + configuredCollection + )} folder exists in the content directory. Create a new folder for the collection, or check your content configuration file for typos.` ); } } diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index a941d7f487480..4e446bf9cf280 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -1,7 +1,6 @@ import type { EndpointHandler, ManifestData, - MiddlewareEndpointHandler, RouteData, SSRElement, SSRManifest, @@ -36,9 +35,11 @@ const responseSentSymbol = Symbol.for('astro.responseSent'); const STATUS_CODES = new Set([404, 500]); -export interface MatchOptions { - matchNotFound?: boolean | undefined; +export interface RenderOptions { + routeData?: RouteData; + locals?: object; } + export interface RenderErrorOptions { routeData?: RouteData; response?: Response; @@ -63,6 +64,7 @@ export class App { #baseWithoutTrailingSlash: string; #pipeline: SSRRoutePipeline; #adapterLogger: AstroIntegrationLogger; + #renderOptionsDeprecationWarningShown = false; constructor(manifest: SSRManifest, streaming = true) { this.#manifest = manifest; @@ -127,7 +129,14 @@ export class App { } return pathname; } - match(request: Request, _opts: MatchOptions = {}): RouteData | undefined { + + #getPathnameFromRequest(request: Request): string { + const url = new URL(request.url); + const pathname = prependForwardSlash(this.removeBase(url.pathname)); + return pathname; + } + + match(request: Request): RouteData | undefined { const url = new URL(request.url); // ignore requests matching public assets if (this.#manifest.assets.has(url.pathname)) return undefined; @@ -138,7 +147,38 @@ export class App { return routeData; } - async render(request: Request, routeData?: RouteData, locals?: object): Promise<Response> { + async render(request: Request, options?: RenderOptions): Promise<Response>; + /** + * @deprecated Instead of passing `RouteData` and locals individually, pass an object with `routeData` and `locals` properties. + * See https://github.com/withastro/astro/pull/9199 for more information. + */ + async render(request: Request, routeData?: RouteData, locals?: object): Promise<Response>; + async render( + request: Request, + routeDataOrOptions?: RouteData | RenderOptions, + maybeLocals?: object + ): Promise<Response> { + let routeData: RouteData | undefined; + let locals: object | undefined; + + if ( + routeDataOrOptions && + ('routeData' in routeDataOrOptions || 'locals' in routeDataOrOptions) + ) { + if ('routeData' in routeDataOrOptions) { + routeData = routeDataOrOptions.routeData; + } + if ('locals' in routeDataOrOptions) { + locals = routeDataOrOptions.locals; + } + } else { + routeData = routeDataOrOptions as RouteData | undefined; + locals = maybeLocals; + if (routeDataOrOptions || locals) { + this.#logRenderOptionsDeprecationWarning(); + } + } + // Handle requests with duplicate slashes gracefully by cloning with a cleaned-up request URL if (request.url !== collapseDuplicateSlashes(request.url)) { request = new Request(collapseDuplicateSlashes(request.url), request); @@ -149,9 +189,9 @@ export class App { if (!routeData) { return this.#renderError(request, { status: 404 }); } - Reflect.set(request, clientLocalsSymbol, locals ?? {}); - const defaultStatus = this.#getDefaultStatusCode(routeData.route); + const pathname = this.#getPathnameFromRequest(request); + const defaultStatus = this.#getDefaultStatusCode(routeData, pathname); const mod = await this.#getModuleForRoute(routeData); const pageModule = (await mod.page()) as any; @@ -173,16 +213,14 @@ export class App { ); if (i18nMiddleware) { if (mod.onRequest) { - this.#pipeline.setMiddlewareFunction( - sequence(i18nMiddleware, mod.onRequest as MiddlewareEndpointHandler) - ); + this.#pipeline.setMiddlewareFunction(sequence(i18nMiddleware, mod.onRequest)); } else { this.#pipeline.setMiddlewareFunction(i18nMiddleware); } this.#pipeline.onBeforeRenderRoute(i18nPipelineHook); } else { if (mod.onRequest) { - this.#pipeline.setMiddlewareFunction(mod.onRequest as MiddlewareEndpointHandler); + this.#pipeline.setMiddlewareFunction(mod.onRequest); } } response = await this.#pipeline.renderRoute(renderContext, pageModule); @@ -190,7 +228,7 @@ export class App { if (err instanceof EndpointNotFoundError) { return this.#renderError(request, { status: 404, response: err.originalResponse }); } else { - this.#logger.error('ssr', err.stack || err.message || String(err)); + this.#logger.error(null, err.stack || err.message || String(err)); return this.#renderError(request, { status: 500 }); } } @@ -208,6 +246,15 @@ export class App { return response; } + #logRenderOptionsDeprecationWarning() { + if (this.#renderOptionsDeprecationWarningShown) return; + this.#logger.warn( + 'deprecated', + `The adapter ${this.#manifest.adapterName} is using a deprecated signature of the 'app.render()' method. From Astro 4.0, locals and routeData are provided as properties on an optional object to this method. Using the old signature will cause an error in Astro 5.0. See https://github.com/withastro/astro/pull/9199 for more information.` + ); + this.#renderOptionsDeprecationWarningShown = true; + } + setCookieHeaders(response: Response) { return getSetCookiesFromResponse(response); } @@ -235,7 +282,7 @@ export class App { env: this.#pipeline.env, mod: handler as any, locales: this.#manifest.i18n?.locales, - routingStrategy: this.#manifest.i18n?.routingStrategy, + routing: this.#manifest.i18n?.routing, defaultLocale: this.#manifest.i18n?.defaultLocale, }); } else { @@ -272,7 +319,7 @@ export class App { mod, env: this.#pipeline.env, locales: this.#manifest.i18n?.locales, - routingStrategy: this.#manifest.i18n?.routingStrategy, + routing: this.#manifest.i18n?.routing, defaultLocale: this.#manifest.i18n?.defaultLocale, }); } @@ -315,7 +362,7 @@ export class App { ); const page = (await mod.page()) as any; if (skipMiddleware === false && mod.onRequest) { - this.#pipeline.setMiddlewareFunction(mod.onRequest as MiddlewareEndpointHandler); + this.#pipeline.setMiddlewareFunction(mod.onRequest); } if (skipMiddleware) { // make sure middleware set by other requests is cleared out @@ -340,8 +387,12 @@ export class App { return response; } - #mergeResponses(newResponse: Response, oldResponse?: Response, override?: { status: 404 | 500 }) { - if (!oldResponse) { + #mergeResponses( + newResponse: Response, + originalResponse?: Response, + override?: { status: 404 | 500 } + ) { + if (!originalResponse) { if (override !== undefined) { return new Response(newResponse.body, { status: override.status, @@ -352,26 +403,43 @@ export class App { return newResponse; } - const { statusText, headers } = oldResponse; - // If the new response did not have a meaningful status, an override may have been provided // If the original status was 200 (default), override it with the new status (probably 404 or 500) // Otherwise, the user set a specific status while rendering and we should respect that one const status = override?.status ? override.status - : oldResponse.status === 200 - ? newResponse.status - : oldResponse.status; + : originalResponse.status === 200 + ? newResponse.status + : originalResponse.status; + try { + // this function could throw an error... + originalResponse.headers.delete('Content-type'); + } catch {} return new Response(newResponse.body, { status, - statusText: status === 200 ? newResponse.statusText : statusText, - headers: new Headers(Array.from(headers)), + statusText: status === 200 ? newResponse.statusText : originalResponse.statusText, + // If you're looking at here for possible bugs, it means that it's not a bug. + // With the middleware, users can meddle with headers, and we should pass to the 404/500. + // If users see something weird, it's because they are setting some headers they should not. + // + // Although, we don't want it to replace the content-type, because the error page must return `text/html` + headers: new Headers([ + ...Array.from(newResponse.headers), + ...Array.from(originalResponse.headers), + ]), }); } - #getDefaultStatusCode(route: string): number { - route = removeTrailingForwardSlash(route); + #getDefaultStatusCode(routeData: RouteData, pathname: string): number { + if (!routeData.pattern.exec(pathname)) { + for (const fallbackRoute of routeData.fallbackRoutes) { + if (fallbackRoute.pattern.test(pathname)) { + return 302; + } + } + } + const route = removeTrailingForwardSlash(routeData.route); if (route.endsWith('/404')) return 404; if (route.endsWith('/500')) return 500; return 200; diff --git a/packages/astro/src/core/app/node.ts b/packages/astro/src/core/app/node.ts index 1df931eca22e6..f5ea38cc18d2b 100644 --- a/packages/astro/src/core/app/node.ts +++ b/packages/astro/src/core/app/node.ts @@ -1,11 +1,12 @@ import type { RouteData } from '../../@types/astro.js'; +import type { RenderOptions } from './index.js'; import type { SerializedSSRManifest, SSRManifest } from './types.js'; import * as fs from 'node:fs'; import { IncomingMessage } from 'node:http'; import { TLSSocket } from 'node:tls'; import { deserializeManifest } from './common.js'; -import { App, type MatchOptions } from './index.js'; +import { App } from './index.js'; export { apply as applyPolyfills } from '../polyfill.js'; const clientAddressSymbol = Symbol.for('astro.clientAddress'); @@ -108,19 +109,34 @@ class NodeIncomingMessage extends IncomingMessage { } export class NodeApp extends App { - match(req: NodeIncomingMessage | Request, opts: MatchOptions = {}) { + match(req: NodeIncomingMessage | Request) { if (!(req instanceof Request)) { req = createRequestFromNodeRequest(req, { emptyBody: true, }); } - return super.match(req, opts); + return super.match(req); } - render(req: NodeIncomingMessage | Request, routeData?: RouteData, locals?: object) { + render(request: NodeIncomingMessage | Request, options?: RenderOptions): Promise<Response>; + /** + * @deprecated Instead of passing `RouteData` and locals individually, pass an object with `routeData` and `locals` properties. + * See https://github.com/withastro/astro/pull/9199 for more information. + */ + render( + request: NodeIncomingMessage | Request, + routeData?: RouteData, + locals?: object + ): Promise<Response>; + render( + req: NodeIncomingMessage | Request, + routeDataOrOptions?: RouteData | RenderOptions, + maybeLocals?: object + ) { if (!(req instanceof Request)) { req = createRequestFromNodeRequest(req); } - return super.render(req, routeData, locals); + // @ts-expect-error The call would have succeeded against the implementation, but implementation signatures of overloads are not externally visible. + return super.render(req, routeDataOrOptions, maybeLocals); } } diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts index 9f9d80f445117..ab4a4fc2cdf7f 100644 --- a/packages/astro/src/core/app/types.ts +++ b/packages/astro/src/core/app/types.ts @@ -1,4 +1,5 @@ import type { + Locales, RouteData, SerializedRouteData, SSRComponentMetadata, @@ -55,8 +56,8 @@ export type SSRManifest = { export type SSRManifestI18n = { fallback?: Record<string, string>; - routingStrategy?: 'prefix-always' | 'prefix-other-locales'; - locales: string[]; + routing?: 'prefix-always' | 'prefix-other-locales'; + locales: Locales; defaultLocale: string; }; diff --git a/packages/astro/src/core/build/buildPipeline.ts b/packages/astro/src/core/build/buildPipeline.ts index fc315ff7dba24..166e42a2f8cb2 100644 --- a/packages/astro/src/core/build/buildPipeline.ts +++ b/packages/astro/src/core/build/buildPipeline.ts @@ -2,13 +2,16 @@ import type { AstroConfig, AstroSettings, SSRLoadedRenderer } from '../../@types import { getOutputDirectory, isServerLikeOutput } from '../../prerender/utils.js'; import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js'; import type { SSRManifest } from '../app/types.js'; -import { Logger } from '../logger/core.js'; +import type { Logger } from '../logger/core.js'; import { Pipeline } from '../pipeline.js'; import { routeIsFallback, routeIsRedirect } from '../redirects/helpers.js'; import { createEnvironment } from '../render/index.js'; import { createAssetLink } from '../render/ssr-element.js'; import type { BuildInternals } from './internal.js'; -import { ASTRO_PAGE_RESOLVED_MODULE_ID } from './plugins/plugin-pages.js'; +import { + ASTRO_PAGE_RESOLVED_MODULE_ID, + getVirtualModulePageNameFromPath, +} from './plugins/plugin-pages.js'; import { RESOLVED_SPLIT_MODULE_ID } from './plugins/plugin-ssr.js'; import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { PageBuildData, StaticBuildOptions } from './types.js'; @@ -142,15 +145,15 @@ export class BuildPipeline extends Pipeline { retrieveRoutesToGenerate(): Map<PageBuildData, string> { const pages = new Map<PageBuildData, string>(); - for (const [entryPoint, filePath] of this.#internals.entrySpecifierToBundleMap) { + for (const [entrypoint, filePath] of this.#internals.entrySpecifierToBundleMap) { // virtual pages can be emitted with different prefixes: // - the classic way are pages emitted with prefix ASTRO_PAGE_RESOLVED_MODULE_ID -> plugin-pages // - pages emitted using `build.split`, in this case pages are emitted with prefix RESOLVED_SPLIT_MODULE_ID if ( - entryPoint.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || - entryPoint.includes(RESOLVED_SPLIT_MODULE_ID) + entrypoint.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || + entrypoint.includes(RESOLVED_SPLIT_MODULE_ID) ) { - const [, pageName] = entryPoint.split(':'); + const [, pageName] = entrypoint.split(':'); const pageData = this.#internals.pagesByComponent.get( `${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, '.')}` ); @@ -164,16 +167,26 @@ export class BuildPipeline extends Pipeline { } } - for (const [path, pageDataList] of this.#internals.pagesByComponents.entries()) { - for (const pageData of pageDataList) { - if (routeIsRedirect(pageData.route)) { - pages.set(pageData, path); - } else if ( - routeIsFallback(pageData.route) && - (i18nHasFallback(this.getConfig()) || - (routeIsFallback(pageData.route) && pageData.route.route === '/')) - ) { - pages.set(pageData, path); + for (const [path, pageData] of this.#internals.pagesByComponent.entries()) { + if (routeIsRedirect(pageData.route)) { + pages.set(pageData, path); + } else if ( + routeIsFallback(pageData.route) && + (i18nHasFallback(this.getConfig()) || + (routeIsFallback(pageData.route) && pageData.route.route === '/')) + ) { + // The original component is transformed during the first build, so we have to retrieve + // the actual `.mjs` that was created. + // During the build, we transform the names of our pages with some weird name, and those weird names become the keys of a map. + // The values of the map are the actual `.mjs` files that are generated during the build + + // Here, we take the component path and transform it in the virtual module name + const moduleSpecifier = getVirtualModulePageNameFromPath(path); + // We retrieve the original JS module + const filePath = this.#internals.entrySpecifierToBundleMap.get(moduleSpecifier); + if (filePath) { + // it exists, added it to pages to render, using the file path that we jus retrieved + pages.set(pageData, filePath); } } } diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 20854f779b0e2..486fac9fbcf03 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -1,16 +1,13 @@ -import * as colors from 'kleur/colors'; -import { bgGreen, black, cyan, dim, green, magenta } from 'kleur/colors'; +import { bgGreen, black, blue, bold, dim, green, magenta, red } from 'kleur/colors'; import fs from 'node:fs'; import os from 'node:os'; import { fileURLToPath } from 'node:url'; import PQueue from 'p-queue'; import type { OutputAsset, OutputChunk } from 'rollup'; -import type { BufferEncoding } from 'vfile'; import type { AstroSettings, ComponentInstance, GetStaticPathsItem, - MiddlewareEndpointHandler, RouteData, RouteType, SSRError, @@ -113,16 +110,6 @@ async function getEntryForFallbackRoute( return RedirectSinglePageBuiltModule; } -function shouldSkipDraft(pageModule: ComponentInstance, settings: AstroSettings): boolean { - return ( - // Drafts are disabled - !settings.config.markdown.drafts && - // This is a draft post - 'frontmatter' in pageModule && - (pageModule as any).frontmatter?.draft === true - ); -} - // Gives back a facadeId that is relative to the root. // ie, src/pages/index.astro instead of /Users/name..../src/pages/index.astro export function rootRelativeFacadeId(facadeId: string, settings: AstroSettings): string { @@ -149,7 +136,7 @@ export function chunkIsPage( } export async function generatePages(opts: StaticBuildOptions, internals: BuildInternals) { - const timer = performance.now(); + const generatePagesTimer = performance.now(); const ssr = isServerLikeOutput(opts.settings.config); let manifest: SSRManifest; if (ssr) { @@ -179,7 +166,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn } const verb = ssr ? 'prerendering' : 'generating'; - logger.info(null, `\n${bgGreen(black(` ${verb} static routes `))}`); + logger.info('SKIP_FORMAT', `\n${bgGreen(black(` ${verb} static routes `))}`); const builtPaths = new Set<string>(); const pagesToGenerate = pipeline.retrieveRoutesToGenerate(); if (ssr) { @@ -187,11 +174,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn if (pageData.route.prerender) { const ssrEntryURLPage = createEntryURL(filePath, outFolder); const ssrEntryPage = await import(ssrEntryURLPage.toString()); - if ( - // TODO: remove in Astro 4.0 - opts.settings.config.build.split || - opts.settings.adapter?.adapterFeatures?.functionPerRoute - ) { + if (opts.settings.adapter?.adapterFeatures?.functionPerRoute) { // forcing to use undefined, so we fail in an expected way if the module is not even there. const ssrEntry = ssrEntryPage?.pageModule; if (ssrEntry) { @@ -223,12 +206,14 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn } } } - - logger.info(null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`)); + logger.info( + null, + green(`✓ Completed in ${getTimeStat(generatePagesTimer, performance.now())}.\n`) + ); const staticImageList = getStaticImageList(); if (staticImageList.size) { - logger.info(null, `\n${bgGreen(black(` generating optimized images `))}`); + logger.info('SKIP_FORMAT', `${bgGreen(black(` generating optimized images `))}`); const totalCount = Array.from(staticImageList.values()) .map((x) => x.transforms.size) @@ -244,7 +229,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn await queue.onIdle(); const assetsTimeEnd = performance.now(); - logger.info(null, dim(`Completed in ${getTimeStat(assetsTimer, assetsTimeEnd)}.\n`)); + logger.info(null, green(`✓ Completed in ${getTimeStat(assetsTimer, assetsTimeEnd)}.\n`)); delete globalThis?.astroAsset?.addStaticImage; } @@ -261,37 +246,36 @@ async function generatePage( builtPaths: Set<string>, pipeline: BuildPipeline ) { - let timeStart = performance.now(); + // prepare information we need const logger = pipeline.getLogger(); const config = pipeline.getConfig(); + const pageModulePromise = ssrEntry.page; + const onRequest = ssrEntry.onRequest; const pageInfo = getPageDataByComponent(pipeline.getInternals(), pageData.route.component); - // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. - const linkIds: [] = []; - const scripts = pageInfo?.hoistedScript ?? null; + // Calculate information of the page, like scripts, links and styles const styles = pageData.styles .sort(cssOrder) .map(({ sheet }) => sheet) .reduce(mergeInlineCss, []); - - const pageModulePromise = ssrEntry.page; - const onRequest = ssrEntry.onRequest; + // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. + const linkIds: [] = []; + const scripts = pageInfo?.hoistedScript ?? null; + // prepare the middleware const i18nMiddleware = createI18nMiddleware( pipeline.getManifest().i18n, pipeline.getManifest().base, pipeline.getManifest().trailingSlash ); - if (config.experimental.i18n && i18nMiddleware) { + if (config.i18n && i18nMiddleware) { if (onRequest) { - pipeline.setMiddlewareFunction( - sequence(i18nMiddleware, onRequest as MiddlewareEndpointHandler) - ); + pipeline.setMiddlewareFunction(sequence(i18nMiddleware, onRequest)); } else { pipeline.setMiddlewareFunction(i18nMiddleware); } pipeline.onBeforeRenderRoute(i18nPipelineHook); } else if (onRequest) { - pipeline.setMiddlewareFunction(onRequest as MiddlewareEndpointHandler); + pipeline.setMiddlewareFunction(onRequest); } if (!pageModulePromise) { throw new Error( @@ -299,16 +283,6 @@ async function generatePage( ); } const pageModule = await pageModulePromise(); - if (shouldSkipDraft(pageModule, pipeline.getSettings())) { - logger.info(null, `${magenta('⚠️')} Skipping draft ${pageData.route.component}`); - // TODO: Remove in Astro 4.0 - logger.warn( - 'astro', - `The drafts feature is deprecated. You should migrate to content collections instead. See https://docs.astro.build/en/guides/content-collections/#filtering-collection-queries for more information.` - ); - return; - } - const generationOptions: Readonly<GeneratePathOptions> = { pageData, linkIds, @@ -316,38 +290,41 @@ async function generatePage( styles, mod: pageModule, }; - - const icon = - pageData.route.type === 'page' || - pageData.route.type === 'redirect' || - pageData.route.type === 'fallback' - ? green('▶') - : magenta('λ'); - if (isRelativePath(pageData.route.component)) { - logger.info(null, `${icon} ${pageData.route.route}`); - } else { - logger.info(null, `${icon} ${pageData.route.component}`); + // Now we explode the routes. A route render itself, and it can render its fallbacks (i18n routing) + for (const route of eachRouteInRouteData(pageData)) { + const icon = + route.type === 'page' || route.type === 'redirect' || route.type === 'fallback' + ? green('▶') + : magenta('λ'); + logger.info(null, `${icon} ${getPrettyRouteName(route)}`); + // Get paths for the route, calling getStaticPaths if needed. + const paths = await getPathsForRoute(route, pageModule, pipeline, builtPaths); + let timeStart = performance.now(); + let prevTimeEnd = timeStart; + for (let i = 0; i < paths.length; i++) { + const path = paths[i]; + pipeline.getEnvironment().logger.debug('build', `Generating: ${path}`); + await generatePath(path, pipeline, generationOptions, route); + const timeEnd = performance.now(); + const timeChange = getTimeStat(prevTimeEnd, timeEnd); + const timeIncrease = `(+${timeChange})`; + const filePath = getOutputFilename(pipeline.getConfig(), path, pageData.route.type); + const lineIcon = i === paths.length - 1 ? '└─' : '├─'; + logger.info(null, ` ${blue(lineIcon)} ${dim(filePath)} ${dim(timeIncrease)}`); + prevTimeEnd = timeEnd; + } } +} - // Get paths for the route, calling getStaticPaths if needed. - const paths = await getPathsForRoute(pageData, pageModule, pipeline, builtPaths); - - let prevTimeEnd = timeStart; - for (let i = 0; i < paths.length; i++) { - const path = paths[i]; - await generatePath(path, generationOptions, pipeline); - const timeEnd = performance.now(); - const timeChange = getTimeStat(prevTimeEnd, timeEnd); - const timeIncrease = `(+${timeChange})`; - const filePath = getOutputFilename(pipeline.getConfig(), path, pageData.route.type); - const lineIcon = i === paths.length - 1 ? '└─' : '├─'; - logger.info(null, ` ${cyan(lineIcon)} ${dim(filePath)} ${dim(timeIncrease)}`); - prevTimeEnd = timeEnd; +function* eachRouteInRouteData(data: PageBuildData) { + yield data.route; + for (const fallbackRoute of data.route.fallbackRoutes) { + yield fallbackRoute; } } async function getPathsForRoute( - pageData: PageBuildData, + route: RouteData, mod: ComponentInstance, pipeline: BuildPipeline, builtPaths: Set<string> @@ -355,11 +332,16 @@ async function getPathsForRoute( const opts = pipeline.getStaticBuildOptions(); const logger = pipeline.getLogger(); let paths: Array<string> = []; - if (pageData.route.pathname) { - paths.push(pageData.route.pathname); - builtPaths.add(pageData.route.pathname); + if (route.pathname) { + paths.push(route.pathname); + builtPaths.add(route.pathname); + for (const virtualRoute of route.fallbackRoutes) { + if (virtualRoute.pathname) { + paths.push(virtualRoute.pathname); + builtPaths.add(virtualRoute.pathname); + } + } } else { - const route = pageData.route; const staticPaths = await callGetStaticPaths({ mod, route, @@ -367,16 +349,14 @@ async function getPathsForRoute( logger, ssr: isServerLikeOutput(opts.settings.config), }).catch((err) => { - logger.debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`); + logger.debug('build', `├── ${bold(red('✗'))} ${route.component}`); throw err; }); const label = staticPaths.length === 1 ? 'page' : 'pages'; logger.debug( 'build', - `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta( - `[${staticPaths.length} ${label}]` - )}` + `├── ${bold(green('✔'))} ${route.component} → ${magenta(`[${staticPaths.length} ${label}]`)}` ); paths = staticPaths @@ -490,18 +470,24 @@ function getUrlForPath( return url; } -async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeline: BuildPipeline) { - const manifest = pipeline.getManifest(); +interface GeneratePathOptions { + pageData: PageBuildData; + linkIds: string[]; + scripts: { type: 'inline' | 'external'; value: string } | null; + styles: StylesheetAsset[]; + mod: ComponentInstance; +} +async function generatePath( + pathname: string, + pipeline: BuildPipeline, + gopts: GeneratePathOptions, + route: RouteData +) { const { mod, scripts: hoistedScripts, styles: _styles, pageData } = gopts; - - // This adds the page name to the array so it can be shown as part of stats. - if (pageData.route.type === 'page') { - addPageName(pathname, pipeline.getStaticBuildOptions()); - } - + const manifest = pipeline.getManifest(); + const logger = pipeline.getLogger(); pipeline.getEnvironment().logger.debug('build', `Generating: ${pathname}`); - // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. const links = new Set<never>(); const scripts = createModuleScriptsSet( hoistedScripts ? [hoistedScripts] : [], @@ -532,13 +518,18 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli } } + // This adds the page name to the array so it can be shown as part of stats. + if (route.type === 'page') { + addPageName(pathname, pipeline.getStaticBuildOptions()); + } + const ssr = isServerLikeOutput(pipeline.getConfig()); const url = getUrlForPath( pathname, pipeline.getConfig().base, pipeline.getStaticBuildOptions().origin, pipeline.getConfig().build.format, - pageData.route.type + route.type ); const request = createRequest({ @@ -547,7 +538,8 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli logger: pipeline.getLogger(), ssr, }); - const i18n = pipeline.getConfig().experimental.i18n; + const i18n = pipeline.getConfig().i18n; + const renderContext = await createRenderContext({ pathname, request, @@ -555,23 +547,22 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli scripts, styles, links, - route: pageData.route, + route, env: pipeline.getEnvironment(), mod, locales: i18n?.locales, - routingStrategy: i18n?.routingStrategy, + routing: i18n?.routing, defaultLocale: i18n?.defaultLocale, }); let body: string | Uint8Array; - let encoding: BufferEncoding | undefined; let response: Response; try { response = await pipeline.renderRoute(renderContext, mod); } catch (err) { if (!AstroError.is(err) && !(err as SSRError).id && typeof err === 'object') { - (err as SSRError).id = pageData.component; + (err as SSRError).id = route.component; } throw err; } @@ -600,22 +591,33 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli body = body.replaceAll('\n', ''); } // A dynamic redirect, set the location so that integrations know about it. - if (pageData.route.type !== 'redirect') { - pageData.route.redirect = location.toString(); + if (route.type !== 'redirect') { + route.redirect = location.toString(); } } else { // If there's no body, do nothing if (!response.body) return; body = Buffer.from(await response.arrayBuffer()); - encoding = (response.headers.get('X-Astro-Encoding') as BufferEncoding | null) ?? 'utf-8'; } - const outFolder = getOutFolder(pipeline.getConfig(), pathname, pageData.route.type); - const outFile = getOutFile(pipeline.getConfig(), outFolder, pathname, pageData.route.type); - pageData.route.distURL = outFile; + const outFolder = getOutFolder(pipeline.getConfig(), pathname, route.type); + const outFile = getOutFile(pipeline.getConfig(), outFolder, pathname, route.type); + route.distURL = outFile; await fs.promises.mkdir(outFolder, { recursive: true }); - await fs.promises.writeFile(outFile, body, encoding); + await fs.promises.writeFile(outFile, body); +} + +function getPrettyRouteName(route: RouteData): string { + if (isRelativePath(route.component)) { + return route.route; + } else if (route.component.includes('node_modules/')) { + // For routes from node_modules (usually injected by integrations), + // prettify it by only grabbing the part after the last `node_modules/` + return route.component.match(/.*node_modules\/(.+)/)?.[1] ?? route.component; + } else { + return route.component; + } } /** @@ -631,12 +633,12 @@ export function createBuildManifest( renderers: SSRLoadedRenderer[] ): SSRManifest { let i18nManifest: SSRManifestI18n | undefined = undefined; - if (settings.config.experimental.i18n) { + if (settings.config.i18n) { i18nManifest = { - fallback: settings.config.experimental.i18n.fallback, - routingStrategy: settings.config.experimental.i18n.routingStrategy, - defaultLocale: settings.config.experimental.i18n.defaultLocale, - locales: settings.config.experimental.i18n.locales, + fallback: settings.config.i18n.fallback, + routing: settings.config.i18n.routing, + defaultLocale: settings.config.i18n.defaultLocale, + locales: settings.config.i18n.locales, }; } return { diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index f096b8f767e96..551e686dc472c 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -1,4 +1,4 @@ -import * as colors from 'kleur/colors'; +import { blue, bold, green } from 'kleur/colors'; import fs from 'node:fs'; import { performance } from 'node:perf_hooks'; import { fileURLToPath } from 'node:url'; @@ -24,7 +24,8 @@ import { resolveConfig } from '../config/config.js'; import { createNodeLogger } from '../config/logging.js'; import { createSettings } from '../config/settings.js'; import { createVite } from '../create-vite.js'; -import { Logger, levels, timerMessage } from '../logger/core.js'; +import type { Logger } from '../logger/core.js'; +import { levels, timerMessage } from '../logger/core.js'; import { apply as applyPolyfill } from '../polyfill.js'; import { RouteCache } from '../render/route-cache.js'; import { createRouteManifest } from '../routing/index.js'; @@ -69,8 +70,9 @@ export default async function build( if (astroConfig.experimental.contentCollectionCache && options.force) { const contentCacheDir = new URL('./content/', astroConfig.cacheDir); if (fs.existsSync(contentCacheDir)) { - logger.warn('content', 'clearing cache'); + logger.debug('content', 'clearing content cache'); await fs.promises.rm(contentCacheDir, { force: true, recursive: true }); + logger.warn('content', 'content cache cleared (force)'); } } @@ -157,9 +159,10 @@ class AstroBuilder { await runHookBuildStart({ config: this.settings.config, logging: this.logger }); this.validateConfig(); - this.logger.info('build', `output target: ${colors.green(this.settings.config.output)}`); + this.logger.info('build', `output: ${blue('"' + this.settings.config.output + '"')}`); + this.logger.info('build', `directory: ${blue(fileURLToPath(this.settings.config.outDir))}`); if (this.settings.adapter) { - this.logger.info('build', `deploy adapter: ${colors.green(this.settings.adapter.name)}`); + this.logger.info('build', `adapter: ${green(this.settings.adapter.name)}`); } this.logger.info('build', 'Collecting build info...'); this.timer.loadStart = performance.now(); @@ -179,7 +182,7 @@ class AstroBuilder { this.timer.buildStart = performance.now(); this.logger.info( 'build', - colors.dim(`Completed in ${getTimeStat(this.timer.init, performance.now())}.`) + green(`✓ Completed in ${getTimeStat(this.timer.init, performance.now())}.`) ); const opts: StaticBuildOptions = { @@ -195,8 +198,8 @@ class AstroBuilder { viteConfig, }; - const { internals } = await viteBuild(opts); - await staticBuild(opts, internals); + const { internals, ssrOutputChunkNames } = await viteBuild(opts); + await staticBuild(opts, internals, ssrOutputChunkNames); // Write any additionally generated assets to disk. this.timer.assetsStart = performance.now(); @@ -251,31 +254,6 @@ class AstroBuilder { `the outDir cannot be the root folder. Please build to a folder such as dist.` ); } - - if (config.build.split === true) { - if (config.output === 'static') { - this.logger.warn( - 'configuration', - 'The option `build.split` won\'t take effect, because `output` is not `"server"` or `"hybrid"`.' - ); - } - this.logger.warn( - 'configuration', - 'The option `build.split` is deprecated. Use the adapter options.' - ); - } - if (config.build.excludeMiddleware === true) { - if (config.output === 'static') { - this.logger.warn( - 'configuration', - 'The option `build.excludeMiddleware` won\'t take effect, because `output` is not `"server"` or `"hybrid"`.' - ); - } - this.logger.warn( - 'configuration', - 'The option `build.excludeMiddleware` is deprecated. Use the adapter options.' - ); - } } /** Stats */ @@ -294,12 +272,12 @@ class AstroBuilder { let messages: string[] = []; if (buildMode === 'static') { - messages = [`${pageCount} page(s) built in`, colors.bold(total)]; + messages = [`${pageCount} page(s) built in`, bold(total)]; } else { - messages = ['Server built in', colors.bold(total)]; + messages = ['Server built in', bold(total)]; } logger.info('build', messages.join(' ')); - logger.info('build', `${colors.bold('Complete!')}`); + logger.info('build', `${bold('Complete!')}`); } } diff --git a/packages/astro/src/core/build/internal.ts b/packages/astro/src/core/build/internal.ts index 1dc38e73566b4..34e76ab1df1bc 100644 --- a/packages/astro/src/core/build/internal.ts +++ b/packages/astro/src/core/build/internal.ts @@ -2,7 +2,6 @@ import type { Rollup } from 'vite'; import type { RouteData, SSRResult } from '../../@types/astro.js'; import type { PageOptions } from '../../vite-plugin-astro/types.js'; import { prependForwardSlash, removeFileExtension } from '../path.js'; -import { routeIsFallback } from '../redirects/helpers.js'; import { viteID } from '../util.js'; import { ASTRO_PAGE_RESOLVED_MODULE_ID, @@ -38,16 +37,9 @@ export interface BuildInternals { /** * A map for page-specific information. - * // TODO: Remove in Astro 4.0 - * @deprecated */ pagesByComponent: Map<string, PageBuildData>; - /** - * TODO: Use this in Astro 4.0 - */ - pagesByComponents: Map<string, PageBuildData[]>; - /** * A map for page-specific output. */ @@ -126,7 +118,6 @@ export function createBuildInternals(): BuildInternals { entrySpecifierToBundleMap: new Map<string, string>(), pageToBundleMap: new Map<string, string>(), pagesByComponent: new Map(), - pagesByComponents: new Map(), pageOptionsByPage: new Map(), pagesByViteID: new Map(), pagesByClientOnly: new Map(), @@ -152,16 +143,7 @@ export function trackPageData( componentURL: URL ): void { pageData.moduleSpecifier = componentModuleId; - if (!routeIsFallback(pageData.route)) { - internals.pagesByComponent.set(component, pageData); - } - const list = internals.pagesByComponents.get(component); - if (list) { - list.push(pageData); - internals.pagesByComponents.set(component, list); - } else { - internals.pagesByComponents.set(component, [pageData]); - } + internals.pagesByComponent.set(component, pageData); internals.pagesByViteID.set(viteID(componentURL), pageData); } @@ -258,25 +240,23 @@ export function* eachPageData(internals: BuildInternals) { } export function* eachPageFromAllPages(allPages: AllPagesData): Generator<[string, PageBuildData]> { - for (const [path, list] of Object.entries(allPages)) { - for (const pageData of list) { - yield [path, pageData]; - } + for (const [path, pageData] of Object.entries(allPages)) { + yield [path, pageData]; } } export function* eachPageDataFromEntryPoint( internals: BuildInternals ): Generator<[PageBuildData, string]> { - for (const [entryPoint, filePath] of internals.entrySpecifierToBundleMap) { + for (const [entrypoint, filePath] of internals.entrySpecifierToBundleMap) { // virtual pages can be emitted with different prefixes: // - the classic way are pages emitted with prefix ASTRO_PAGE_RESOLVED_MODULE_ID -> plugin-pages // - pages emitted using `build.split`, in this case pages are emitted with prefix RESOLVED_SPLIT_MODULE_ID if ( - entryPoint.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || - entryPoint.includes(RESOLVED_SPLIT_MODULE_ID) + entrypoint.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || + entrypoint.includes(RESOLVED_SPLIT_MODULE_ID) ) { - const [, pageName] = entryPoint.split(':'); + const [, pageName] = entrypoint.split(':'); const pageData = internals.pagesByComponent.get( `${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, '.')}` ); diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts index 7292cb4e8f94f..89eca3ffc5efd 100644 --- a/packages/astro/src/core/build/page-data.ts +++ b/packages/astro/src/core/build/page-data.ts @@ -47,29 +47,16 @@ export async function collectPagesData( clearInterval(routeCollectionLogTimeout); }, 10000); builtPaths.add(route.pathname); - if (allPages[route.component]) { - allPages[route.component].push({ - component: route.component, - route, - moduleSpecifier: '', - styles: [], - propagatedStyles: new Map(), - propagatedScripts: new Map(), - hoistedScript: undefined, - }); - } else { - allPages[route.component] = [ - { - component: route.component, - route, - moduleSpecifier: '', - styles: [], - propagatedStyles: new Map(), - propagatedScripts: new Map(), - hoistedScript: undefined, - }, - ]; - } + + allPages[route.component] = { + component: route.component, + route, + moduleSpecifier: '', + styles: [], + propagatedStyles: new Map(), + propagatedScripts: new Map(), + hoistedScript: undefined, + }; clearInterval(routeCollectionLogTimeout); if (settings.config.output === 'static') { @@ -84,29 +71,16 @@ export async function collectPagesData( continue; } // dynamic route: - if (allPages[route.component]) { - allPages[route.component].push({ - component: route.component, - route, - moduleSpecifier: '', - styles: [], - propagatedStyles: new Map(), - propagatedScripts: new Map(), - hoistedScript: undefined, - }); - } else { - allPages[route.component] = [ - { - component: route.component, - route, - moduleSpecifier: '', - styles: [], - propagatedStyles: new Map(), - propagatedScripts: new Map(), - hoistedScript: undefined, - }, - ]; - } + + allPages[route.component] = { + component: route.component, + route, + moduleSpecifier: '', + styles: [], + propagatedStyles: new Map(), + propagatedScripts: new Map(), + hoistedScript: undefined, + }; } clearInterval(dataCollectionLogTimeout); diff --git a/packages/astro/src/core/build/plugin.ts b/packages/astro/src/core/build/plugin.ts index c611c5186ed54..68474b0576b76 100644 --- a/packages/astro/src/core/build/plugin.ts +++ b/packages/astro/src/core/build/plugin.ts @@ -1,4 +1,4 @@ -import type { Plugin as VitePlugin } from 'vite'; +import type { Plugin as VitePlugin, Rollup } from 'vite'; import type { BuildInternals } from './internal.js'; import type { StaticBuildOptions, ViteBuildReturn } from './types.js'; @@ -68,7 +68,7 @@ export function createPluginContainer(options: StaticBuildOptions, internals: Bu }; }, - async runPostHook(ssrReturn: ViteBuildReturn, clientReturn: ViteBuildReturn | null) { + async runPostHook(ssrOutputs: Rollup.RollupOutput[], clientOutputs: Rollup.RollupOutput[]) { const mutations = new Map< string, { @@ -76,20 +76,6 @@ export function createPluginContainer(options: StaticBuildOptions, internals: Bu code: string; } >(); - const ssrOutputs: RollupOutputArray = []; - const clientOutputs: RollupOutputArray = []; - - if (Array.isArray(ssrReturn)) { - ssrOutputs.push(...ssrReturn); - } else if ('output' in ssrReturn) { - ssrOutputs.push(ssrReturn); - } - - if (Array.isArray(clientReturn)) { - clientOutputs.push(...clientReturn); - } else if (clientReturn && 'output' in clientReturn) { - clientOutputs.push(clientReturn); - } const mutate: MutateChunk = (chunk, targets, newCode) => { chunk.code = newCode; diff --git a/packages/astro/src/core/build/plugins/index.ts b/packages/astro/src/core/build/plugins/index.ts index 879f72210f92c..9c1f9b5500806 100644 --- a/packages/astro/src/core/build/plugins/index.ts +++ b/packages/astro/src/core/build/plugins/index.ts @@ -1,7 +1,6 @@ import { astroConfigBuildPlugin } from '../../../content/vite-plugin-content-assets.js'; import { astroHeadBuildPlugin } from '../../../vite-plugin-head/index.js'; import type { AstroBuildPluginContainer } from '../plugin.js'; -import { pluginAliasResolve } from './plugin-alias-resolve.js'; import { pluginAnalyzer } from './plugin-analyzer.js'; import { pluginChunks } from './plugin-chunks.js'; import { pluginComponentEntry } from './plugin-component-entry.js'; @@ -18,7 +17,6 @@ import { pluginSSR, pluginSSRSplit } from './plugin-ssr.js'; export function registerAllPlugins({ internals, options, register }: AstroBuildPluginContainer) { register(pluginComponentEntry(internals)); - register(pluginAliasResolve(internals)); register(pluginAnalyzer(options, internals)); register(pluginInternals(internals)); register(pluginManifest(options, internals)); diff --git a/packages/astro/src/core/build/plugins/plugin-alias-resolve.ts b/packages/astro/src/core/build/plugins/plugin-alias-resolve.ts deleted file mode 100644 index 6fb09acf8c437..0000000000000 --- a/packages/astro/src/core/build/plugins/plugin-alias-resolve.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { Alias, Plugin as VitePlugin } from 'vite'; -import type { BuildInternals } from '../internal.js'; -import type { AstroBuildPlugin } from '../plugin.js'; - -/** - * `@rollup/plugin-alias` doesn't resolve aliases in Rollup input by default. This plugin fixes it - * with a partial fork of it's resolve function. https://github.com/rollup/plugins/blob/master/packages/alias/src/index.ts - * When https://github.com/rollup/plugins/pull/1402 is merged, we can remove this plugin. - */ -export function vitePluginAliasResolve(internals: BuildInternals): VitePlugin { - let aliases: Alias[]; - - return { - name: '@astro/plugin-alias-resolve', - enforce: 'pre', - configResolved(config) { - aliases = config.resolve.alias; - }, - async resolveId(id, importer, opts) { - if ( - !importer && - (internals.discoveredHydratedComponents.has(id) || - internals.discoveredClientOnlyComponents.has(id)) - ) { - const matchedEntry = aliases.find((entry) => matches(entry.find, id)); - if (!matchedEntry) { - return null; - } - - const updatedId = id.replace(matchedEntry.find, matchedEntry.replacement); - - return this.resolve(updatedId, importer, Object.assign({ skipSelf: true }, opts)).then( - (resolved) => resolved || { id: updatedId } - ); - } - }, - }; -} - -function matches(pattern: string | RegExp, importee: string) { - if (pattern instanceof RegExp) { - return pattern.test(importee); - } - if (importee.length < pattern.length) { - return false; - } - if (importee === pattern) { - return true; - } - return importee.startsWith(pattern + '/'); -} - -export function pluginAliasResolve(internals: BuildInternals): AstroBuildPlugin { - return { - targets: ['client'], - hooks: { - 'build:before': () => { - return { - vitePlugin: vitePluginAliasResolve(internals), - }; - }, - }, - }; -} diff --git a/packages/astro/src/core/build/plugins/plugin-css.ts b/packages/astro/src/core/build/plugins/plugin-css.ts index f8611898f0a06..318a1fee545ea 100644 --- a/packages/astro/src/core/build/plugins/plugin-css.ts +++ b/packages/astro/src/core/build/plugins/plugin-css.ts @@ -223,8 +223,8 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] { inlineConfig === 'always' ? true : inlineConfig === 'never' - ? false - : assetSize <= assetsInlineLimit; + ? false + : assetSize <= assetsInlineLimit; // there should be a single js object for each stylesheet, // allowing the single reference to be shared and checked for duplicates diff --git a/packages/astro/src/core/build/plugins/plugin-manifest.ts b/packages/astro/src/core/build/plugins/plugin-manifest.ts index 83065ecacbe42..1a313b6bbdb40 100644 --- a/packages/astro/src/core/build/plugins/plugin-manifest.ts +++ b/packages/astro/src/core/build/plugins/plugin-manifest.ts @@ -98,8 +98,6 @@ export function pluginManifest( const manifest = await createManifest(options, internals); const shouldPassMiddlewareEntryPoint = - // TODO: remove in Astro 4.0 - options.settings.config.build.excludeMiddleware || options.settings.adapter?.adapterFeatures?.edgeMiddleware; await runHookBuildSsr({ config: options.settings.config, @@ -242,12 +240,12 @@ function buildManifest( entryModules[BEFORE_HYDRATION_SCRIPT_ID] = ''; } let i18nManifest: SSRManifestI18n | undefined = undefined; - if (settings.config.experimental.i18n) { + if (settings.config.i18n) { i18nManifest = { - fallback: settings.config.experimental.i18n.fallback, - routingStrategy: settings.config.experimental.i18n.routingStrategy, - locales: settings.config.experimental.i18n.locales, - defaultLocale: settings.config.experimental.i18n.defaultLocale, + fallback: settings.config.i18n.fallback, + routing: settings.config.i18n.routing, + locales: settings.config.i18n.locales, + defaultLocale: settings.config.i18n.defaultLocale, }; } diff --git a/packages/astro/src/core/build/plugins/plugin-pages.ts b/packages/astro/src/core/build/plugins/plugin-pages.ts index 2a348f18fece2..fee94071ee25b 100644 --- a/packages/astro/src/core/build/plugins/plugin-pages.ts +++ b/packages/astro/src/core/build/plugins/plugin-pages.ts @@ -92,10 +92,6 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V } export function shouldBundleMiddleware(settings: AstroSettings) { - // TODO: Remove in Astro 4.0 - if (settings.config.build.excludeMiddleware === true) { - return false; - } if (settings.adapter?.adapterFeatures?.edgeMiddleware === true) { return false; } diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index fd892c9b63c74..6a6dd224af4fd 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -102,10 +102,7 @@ export function pluginSSR( hooks: { 'build:before': () => { let vitePlugin = - ssr && - // TODO: Remove in Astro 4.0 - options.settings.config.build.split === false && - functionPerRouteEnabled === false + ssr && functionPerRouteEnabled === false ? vitePluginSSR(internals, options.settings.adapter!, options) : undefined; @@ -119,7 +116,7 @@ export function pluginSSR( return; } - if (options.settings.config.build.split || functionPerRouteEnabled) { + if (functionPerRouteEnabled) { return; } @@ -146,7 +143,7 @@ function vitePluginSSRSplit( name: '@astrojs/vite-plugin-astro-ssr-split', enforce: 'post', options(opts) { - if (options.settings.config.build.split || functionPerRouteEnabled) { + if (functionPerRouteEnabled) { const inputs = new Set<string>(); for (const [path, pageData] of eachPageFromAllPages(options.allPages)) { @@ -223,7 +220,7 @@ export function pluginSSRSplit( hooks: { 'build:before': () => { let vitePlugin = - ssr && (options.settings.config.build.split || functionPerRouteEnabled) + ssr && functionPerRouteEnabled ? vitePluginSSRSplit(internals, options.settings.adapter!, options) : undefined; @@ -240,7 +237,7 @@ function generateSSRCode(config: AstroConfig, adapter: AstroAdapter) { const imports: string[] = []; const contents: string[] = []; let pageMap; - if (config.build.split || isFunctionPerRouteEnabled(adapter)) { + if (isFunctionPerRouteEnabled(adapter)) { pageMap = 'pageModule'; } else { pageMap = 'pageMap'; diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 81dcdb4a00b01..cd642aca0ed10 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -1,7 +1,7 @@ import { teardown } from '@astrojs/compiler'; import * as eslexer from 'es-module-lexer'; import glob from 'fast-glob'; -import { bgGreen, bgMagenta, black, dim } from 'kleur/colors'; +import { bgGreen, bgMagenta, black, green } from 'kleur/colors'; import fs from 'node:fs'; import path, { extname } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; @@ -33,7 +33,7 @@ import { RESOLVED_RENDERERS_MODULE_ID } from './plugins/plugin-renderers.js'; import { RESOLVED_SPLIT_MODULE_ID, RESOLVED_SSR_VIRTUAL_MODULE_ID } from './plugins/plugin-ssr.js'; import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { StaticBuildOptions } from './types.js'; -import { encodeName, getTimeStat } from './util.js'; +import { encodeName, getTimeStat, viteBuildReturnToRollupOutputs } from './util.js'; export async function viteBuild(opts: StaticBuildOptions) { const { allPages, settings } = opts; @@ -51,17 +51,15 @@ export async function viteBuild(opts: StaticBuildOptions) { // Build internals needed by the CSS plugin const internals = createBuildInternals(); - for (const [component, pageDataList] of Object.entries(allPages)) { - for (const pageData of pageDataList) { - const astroModuleURL = new URL('./' + component, settings.config.root); - const astroModuleId = prependForwardSlash(component); + for (const [component, pageData] of Object.entries(allPages)) { + const astroModuleURL = new URL('./' + component, settings.config.root); + const astroModuleId = prependForwardSlash(component); - // Track the page data in internals - trackPageData(internals, component, pageData, astroModuleId, astroModuleURL); + // Track the page data in internals + trackPageData(internals, component, pageData, astroModuleId, astroModuleURL); - if (!routeIsRedirect(pageData.route)) { - pageInput.add(astroModuleId); - } + if (!routeIsRedirect(pageData.route)) { + pageInput.add(astroModuleId); } } @@ -80,7 +78,8 @@ export async function viteBuild(opts: StaticBuildOptions) { const ssrTime = performance.now(); opts.logger.info('build', `Building ${settings.config.output} entrypoints...`); const ssrOutput = await ssrBuild(opts, internals, pageInput, container); - opts.logger.info('build', dim(`Completed in ${getTimeStat(ssrTime, performance.now())}.`)); + opts.logger.info('build', green(`✓ Completed in ${getTimeStat(ssrTime, performance.now())}.`)); + settings.timer.end('SSR build'); settings.timer.start('Client build'); @@ -104,7 +103,9 @@ export async function viteBuild(opts: StaticBuildOptions) { // Run client build first, so the assets can be fed into the SSR rendered version. const clientOutput = await clientBuild(opts, internals, clientInput, container); - await runPostBuildHooks(container, ssrOutput, clientOutput); + const ssrOutputs = viteBuildReturnToRollupOutputs(ssrOutput); + const clientOutputs = viteBuildReturnToRollupOutputs(clientOutput ?? []); + await runPostBuildHooks(container, ssrOutputs, clientOutputs); settings.timer.end('Client build'); @@ -114,23 +115,38 @@ export async function viteBuild(opts: StaticBuildOptions) { teardown(); } - return { internals }; + // For static builds, the SSR output output won't be needed anymore after page generation. + // We keep track of the names here so we only remove these specific files when finished. + const ssrOutputChunkNames: string[] = []; + for (const output of ssrOutputs) { + for (const chunk of output.output) { + if (chunk.type === 'chunk') { + ssrOutputChunkNames.push(chunk.fileName); + } + } + } + + return { internals, ssrOutputChunkNames }; } -export async function staticBuild(opts: StaticBuildOptions, internals: BuildInternals) { +export async function staticBuild( + opts: StaticBuildOptions, + internals: BuildInternals, + ssrOutputChunkNames: string[] +) { const { settings } = opts; switch (true) { case settings.config.output === 'static': { settings.timer.start('Static generate'); await generatePages(opts, internals); - await cleanServerOutput(opts); + await cleanServerOutput(opts, ssrOutputChunkNames); settings.timer.end('Static generate'); return; } case isServerLikeOutput(settings.config): { settings.timer.start('Server generate'); await generatePages(opts, internals); - await cleanStaticOutput(opts, internals); + await cleanStaticOutput(opts, internals, ssrOutputChunkNames); opts.logger.info(null, `\n${bgMagenta(black(' finalizing server assets '))}\n`); await ssrMoveAssets(opts); settings.timer.end('Server generate'); @@ -149,17 +165,14 @@ async function ssrBuild( const { allPages, settings, viteConfig } = opts; const ssr = isServerLikeOutput(settings.config); const out = getOutputDirectory(settings.config); - const routes = Object.values(allPages) - .flat() - .map((pageData) => pageData.route); + const routes = Object.values(allPages).flatMap((pageData) => pageData.route); const isContentCache = !ssr && settings.config.experimental.contentCollectionCache; const { lastVitePlugins, vitePlugins } = await container.runBeforeHook('server', input); const viteBuildConfig: vite.InlineConfig = { ...viteConfig, mode: viteConfig.mode || 'production', - // Check using `settings...` as `viteConfig` always defaults to `warn` by Astro - logLevel: settings.config.vite.logLevel ?? 'error', + logLevel: viteConfig.logLevel ?? 'error', build: { target: 'esnext', // Vite defaults cssMinify to false in SSR by default, but we want to minify it @@ -272,7 +285,6 @@ async function clientBuild( container: AstroBuildPluginContainer ) { const { settings, viteConfig } = opts; - const timer = performance.now(); const ssr = isServerLikeOutput(settings.config); const out = ssr ? settings.config.build.client : getOutDirWithinCwd(settings.config.outDir); @@ -287,13 +299,11 @@ async function clientBuild( } const { lastVitePlugins, vitePlugins } = await container.runBeforeHook('client', input); - opts.logger.info(null, `\n${bgGreen(black(' building client '))}`); + opts.logger.info('SKIP_FORMAT', `\n${bgGreen(black(' building client (vite) '))}`); const viteBuildConfig: vite.InlineConfig = { ...viteConfig, mode: viteConfig.mode || 'production', - // Check using `settings...` as `viteConfig` always defaults to `warn` by Astro - logLevel: settings.config.vite.logLevel ?? 'info', build: { target: 'esnext', ...viteConfig.build, @@ -326,16 +336,15 @@ async function clientBuild( }); const buildResult = await vite.build(viteBuildConfig); - opts.logger.info(null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`)); return buildResult; } async function runPostBuildHooks( container: AstroBuildPluginContainer, - ssrReturn: Awaited<ReturnType<typeof ssrBuild>>, - clientReturn: Awaited<ReturnType<typeof clientBuild>> + ssrOutputs: vite.Rollup.RollupOutput[], + clientOutputs: vite.Rollup.RollupOutput[] ) { - const mutations = await container.runPostHook(ssrReturn, clientReturn); + const mutations = await container.runPostHook(ssrOutputs, clientOutputs); const config = container.options.settings.config; const build = container.options.settings.config.build; for (const [fileName, mutation] of mutations) { @@ -343,7 +352,7 @@ async function runPostBuildHooks( ? mutation.targets.includes('server') ? build.server : build.client - : config.outDir; + : getOutDirWithinCwd(config.outDir); const fullPath = path.join(fileURLToPath(root), fileName); const fileURL = pathToFileURL(fullPath); await fs.promises.mkdir(new URL('./', fileURL), { recursive: true }); @@ -355,7 +364,11 @@ async function runPostBuildHooks( * For each statically prerendered page, replace their SSR file with a noop. * This allows us to run the SSR build only once, but still remove dependencies for statically rendered routes. */ -async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInternals) { +async function cleanStaticOutput( + opts: StaticBuildOptions, + internals: BuildInternals, + ssrOutputChunkNames: string[] +) { const allStaticFiles = new Set(); for (const pageData of eachPageData(internals)) { if (pageData.route.prerender) { @@ -369,10 +382,8 @@ async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInter const out = ssr ? opts.settings.config.build.server : getOutDirWithinCwd(opts.settings.config.outDir); - // The SSR output is all .mjs files, the client output is not. - const files = await glob('**/*.mjs', { - cwd: fileURLToPath(out), - }); + // The SSR output chunks for Astro are all .mjs files + const files = ssrOutputChunkNames.filter((f) => f.endsWith('.mjs')); if (files.length) { await eslexer.init; @@ -402,14 +413,10 @@ async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInter } } -async function cleanServerOutput(opts: StaticBuildOptions) { +async function cleanServerOutput(opts: StaticBuildOptions, ssrOutputChunkNames: string[]) { const out = getOutDirWithinCwd(opts.settings.config.outDir); - // The SSR output is all .mjs files, the client output is not. - const files = await glob('**/*.mjs', { - cwd: fileURLToPath(out), - // Important! Also cleanup dotfiles like `node_modules/.pnpm/**` - dot: true, - }); + // The SSR output chunks for Astro are all .mjs files + const files = ssrOutputChunkNames.filter((f) => f.endsWith('.mjs')); if (files.length) { // Remove all the SSR generated .mjs files await Promise.all( diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts index 00d6ce0461bff..0722a293dcad5 100644 --- a/packages/astro/src/core/build/types.ts +++ b/packages/astro/src/core/build/types.ts @@ -30,7 +30,8 @@ export interface PageBuildData { hoistedScript: { type: 'inline' | 'external'; value: string } | undefined; styles: Array<{ depth: number; order: number; sheet: StylesheetAsset }>; } -export type AllPagesData = Record<ComponentPath, PageBuildData[]>; + +export type AllPagesData = Record<ComponentPath, PageBuildData>; /** Options for the static build */ export interface StaticBuildOptions { @@ -53,7 +54,7 @@ export interface SinglePageBuiltModule { /** * The `onRequest` hook exported by the middleware */ - onRequest?: MiddlewareHandler<unknown>; + onRequest?: MiddlewareHandler; renderers: SSRLoadedRenderer[]; } diff --git a/packages/astro/src/core/build/util.ts b/packages/astro/src/core/build/util.ts index e46a0713a0b42..fde296a6d246c 100644 --- a/packages/astro/src/core/build/util.ts +++ b/packages/astro/src/core/build/util.ts @@ -1,8 +1,10 @@ +import type { Rollup } from 'vite'; import type { AstroConfig } from '../../@types/astro.js'; +import type { ViteBuildReturn } from './types.js'; export function getTimeStat(timeStart: number, timeEnd: number) { const buildTime = timeEnd - timeStart; - return buildTime < 750 ? `${Math.round(buildTime)}ms` : `${(buildTime / 1000).toFixed(2)}s`; + return buildTime < 1000 ? `${Math.round(buildTime)}ms` : `${(buildTime / 1000).toFixed(2)}s`; } /** @@ -29,9 +31,9 @@ export function shouldAppendForwardSlash( } export function i18nHasFallback(config: AstroConfig): boolean { - if (config.experimental.i18n && config.experimental.i18n.fallback) { + if (config.i18n && config.i18n.fallback) { // we have some fallback and the control is not none - return Object.keys(config.experimental.i18n.fallback).length > 0; + return Object.keys(config.i18n.fallback).length > 0; } return false; @@ -52,3 +54,15 @@ export function encodeName(name: string): string { return name; } + +export function viteBuildReturnToRollupOutputs( + viteBuildReturn: ViteBuildReturn +): Rollup.RollupOutput[] { + const result: Rollup.RollupOutput[] = []; + if (Array.isArray(viteBuildReturn)) { + result.push(...viteBuildReturn); + } else if ('output' in viteBuildReturn) { + result.push(viteBuildReturn); + } + return result; +} diff --git a/packages/astro/src/core/compile/compile.ts b/packages/astro/src/core/compile/compile.ts index f270e123eba94..97625f021a551 100644 --- a/packages/astro/src/core/compile/compile.ts +++ b/packages/astro/src/core/compile/compile.ts @@ -5,14 +5,17 @@ import type { AstroConfig } from '../../@types/astro.js'; import { transform } from '@astrojs/compiler'; import { fileURLToPath } from 'node:url'; import { normalizePath } from 'vite'; -import { AggregateError, AstroError, CompilerError } from '../errors/errors.js'; +import type { AstroError } from '../errors/errors.js'; +import { AggregateError, CompilerError } from '../errors/errors.js'; import { AstroErrorData } from '../errors/index.js'; import { resolvePath } from '../util.js'; import { createStylePreprocessor } from './style.js'; +import type { AstroPreferences } from '../../preferences/index.js'; export interface CompileProps { astroConfig: AstroConfig; viteConfig: ResolvedConfig; + preferences: AstroPreferences; filename: string; source: string; } @@ -25,6 +28,7 @@ export interface CompileResult extends TransformResult { export async function compile({ astroConfig, viteConfig, + preferences, filename, source, }: CompileProps): Promise<CompileResult> { @@ -46,7 +50,11 @@ export async function compile({ scopedStyleStrategy: astroConfig.scopedStyleStrategy, resultScopedSlot: true, transitionsAnimationURL: 'astro/components/viewtransitions.css', - annotateSourceFile: !viteConfig.isProduction && astroConfig.experimental.devOverlay, + annotateSourceFile: + viteConfig.command === 'serve' && + astroConfig.devToolbar && + astroConfig.devToolbar.enabled && + (await preferences.get('devToolbar.enabled')), preprocessStyle: createStylePreprocessor({ filename, viteConfig, diff --git a/packages/astro/src/core/config/config.ts b/packages/astro/src/core/config/config.ts index 53acb6924fcbc..82bb872b15939 100644 --- a/packages/astro/src/core/config/config.ts +++ b/packages/astro/src/core/config/config.ts @@ -67,7 +67,6 @@ export function resolveFlags(flags: Partial<Flags>): CLIFlags { config: typeof flags.config === 'string' ? flags.config : undefined, host: typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined, - drafts: typeof flags.drafts === 'boolean' ? flags.drafts : undefined, }; } diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts index eaa11786a5c9a..08910720a13ee 100644 --- a/packages/astro/src/core/config/schema.ts +++ b/packages/astro/src/core/config/schema.ts @@ -8,10 +8,9 @@ import { markdownConfigDefaults } from '@astrojs/markdown-remark'; import { bundledThemes, type BuiltinTheme } from 'shikiji'; import type { AstroUserConfig, ViteUserConfig } from '../../@types/astro.js'; -import fs from 'node:fs'; import type { OutgoingHttpHeaders } from 'node:http'; import path from 'node:path'; -import { fileURLToPath, pathToFileURL } from 'node:url'; +import { pathToFileURL } from 'node:url'; import { z } from 'zod'; import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from '../path.js'; @@ -38,12 +37,13 @@ const ASTRO_CONFIG_DEFAULTS = { serverEntry: 'entry.mjs', redirects: true, inlineStylesheets: 'auto', - split: false, - excludeMiddleware: false, }, image: { service: { entrypoint: 'astro/assets/services/sharp', config: {} }, }, + devToolbar: { + enabled: true, + }, compressHTML: true, server: { host: false, @@ -51,20 +51,18 @@ const ASTRO_CONFIG_DEFAULTS = { open: false, }, integrations: [], - markdown: { - drafts: false, - ...markdownConfigDefaults, - }, + markdown: markdownConfigDefaults, vite: {}, legacy: {}, redirects: {}, experimental: { optimizeHoistedScript: false, - devOverlay: false, contentCollectionCache: false, }, } satisfies AstroUserConfig & { server: { open: boolean } }; +type RoutingStrategies = 'prefix-always' | 'prefix-other-locales'; + export const AstroConfigSchema = z.object({ root: z .string() @@ -139,20 +137,6 @@ export const AstroConfigSchema = z.object({ .enum(['always', 'auto', 'never']) .optional() .default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets), - - /** - * @deprecated - * Use the adapter feature instead - */ - split: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.split), - /** - * @deprecated - * Use the adapter feature instead - */ - excludeMiddleware: z - .boolean() - .optional() - .default(ASTRO_CONFIG_DEFAULTS.build.excludeMiddleware), }) .default({}), server: z.preprocess( @@ -243,9 +227,13 @@ export const AstroConfigSchema = z.object({ .default([]), }) .default(ASTRO_CONFIG_DEFAULTS.image), + devToolbar: z + .object({ + enabled: z.boolean().default(ASTRO_CONFIG_DEFAULTS.devToolbar.enabled), + }) + .default(ASTRO_CONFIG_DEFAULTS.devToolbar), markdown: z .object({ - drafts: z.boolean().default(false), syntaxHighlight: z .union([z.literal('shiki'), z.literal('prism'), z.literal(false)]) .default(ASTRO_CONFIG_DEFAULTS.markdown.syntaxHighlight), @@ -258,25 +246,6 @@ export const AstroConfigSchema = z.object({ for (const lang of langs) { // shiki -> shikiji compat if (typeof lang === 'object') { - // shikiji does not support `path` - // https://github.com/shikijs/shiki/blob/facb6ff37996129626f8066a5dccb4608e45f649/packages/shiki/src/loader.ts#L98 - const langPath = (lang as any).path; - if (langPath) { - // shiki resolves path from within its package directory :shrug: - const astroRoot = fileURLToPath(new URL('../../../', import.meta.url)); - const normalizedPath = path.isAbsolute(langPath) - ? langPath - : path.resolve(astroRoot, langPath); - try { - const content = fs.readFileSync(normalizedPath, 'utf-8'); - const parsed = JSON.parse(content); - Object.assign(lang, parsed); - } catch (e) { - throw new Error(`Unable to find language file at ${normalizedPath}`, { - cause: e, - }); - } - } // `id` renamed to `name` (always override) if ((lang as any).id) { lang.name = (lang as any).id; @@ -333,62 +302,90 @@ export const AstroConfigSchema = z.object({ vite: z .custom<ViteUserConfig>((data) => data instanceof Object && !Array.isArray(data)) .default(ASTRO_CONFIG_DEFAULTS.vite), - experimental: z - .object({ - optimizeHoistedScript: z - .boolean() - .optional() - .default(ASTRO_CONFIG_DEFAULTS.experimental.optimizeHoistedScript), - devOverlay: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.devOverlay), - i18n: z.optional( - z + i18n: z.optional( + z + .object({ + defaultLocale: z.string(), + locales: z.array( + z.union([ + z.string(), + z.object({ + path: z.string(), + codes: z.string().array().nonempty(), + }), + ]) + ), + fallback: z.record(z.string(), z.string()).optional(), + routing: z .object({ - defaultLocale: z.string(), - locales: z.string().array(), - fallback: z.record(z.string(), z.string()).optional(), - // TODO: properly add default when the feature goes of experimental - routingStrategy: z - .enum(['prefix-always', 'prefix-other-locales']) - .optional() - .default('prefix-other-locales'), + prefixDefaultLocale: z.boolean().default(false), + strategy: z.enum(['pathname']).default('pathname'), }) - .optional() - .superRefine((i18n, ctx) => { - if (i18n) { - const { defaultLocale, locales, fallback } = i18n; - if (!locales.includes(defaultLocale)) { + .default({}) + .transform((routing) => { + let strategy: RoutingStrategies; + switch (routing.strategy) { + case 'pathname': { + if (routing.prefixDefaultLocale === true) { + strategy = 'prefix-always'; + } else { + strategy = 'prefix-other-locales'; + } + } + } + return strategy; + }), + }) + .optional() + .superRefine((i18n, ctx) => { + if (i18n) { + const { defaultLocale, locales: _locales, fallback } = i18n; + const locales = _locales.map((locale) => { + if (typeof locale === 'string') { + return locale; + } else { + return locale.path; + } + }); + if (!locales.includes(defaultLocale)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `The default locale \`${defaultLocale}\` is not present in the \`i18n.locales\` array.`, + }); + } + if (fallback) { + for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) { + if (!locales.includes(fallbackFrom)) { ctx.addIssue({ code: z.ZodIssueCode.custom, - message: `The default locale \`${defaultLocale}\` is not present in the \`i18n.locales\` array.`, + message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`, }); } - if (fallback) { - for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) { - if (!locales.includes(fallbackFrom)) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`, - }); - } - if (fallbackFrom === defaultLocale) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `You can't use the default locale as a key. The default locale can only be used as value.`, - }); - } + if (fallbackFrom === defaultLocale) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `You can't use the default locale as a key. The default locale can only be used as value.`, + }); + } - if (!locales.includes(fallbackTo)) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`, - }); - } - } + if (!locales.includes(fallbackTo)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`, + }); } } - }) - ), + } + } + }) + ), + experimental: z + .object({ + optimizeHoistedScript: z + .boolean() + .optional() + .default(ASTRO_CONFIG_DEFAULTS.experimental.optimizeHoistedScript), contentCollectionCache: z .boolean() .optional() @@ -452,12 +449,6 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: string) { .enum(['always', 'auto', 'never']) .optional() .default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets), - - split: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.split), - excludeMiddleware: z - .boolean() - .optional() - .default(ASTRO_CONFIG_DEFAULTS.build.excludeMiddleware), }) .optional() .default({}), diff --git a/packages/astro/src/core/config/settings.ts b/packages/astro/src/core/config/settings.ts index fca392c976723..ef92d6e7d9be7 100644 --- a/packages/astro/src/core/config/settings.ts +++ b/packages/astro/src/core/config/settings.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { AstroConfig, AstroSettings } from '../../@types/astro.js'; import { getContentPaths } from '../../content/index.js'; +import createPreferences from '../../preferences/index.js'; import { markdownContentEntryType } from '../../vite-plugin-markdown/content-entry-type.js'; import { getDefaultClientDirectives } from '../client-directive/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; @@ -13,8 +14,10 @@ import { loadTSConfig } from './tsconfig.js'; export function createBaseSettings(config: AstroConfig): AstroSettings { const { contentDir } = getContentPaths(config); + const preferences = createPreferences(config); return { config, + preferences, tsConfig: undefined, tsConfigPath: undefined, adapter: undefined, @@ -99,7 +102,7 @@ export function createBaseSettings(config: AstroConfig): AstroSettings { clientDirectives: getDefaultClientDirectives(), middlewares: { pre: [], post: [] }, watchFiles: [], - devOverlayPlugins: [], + devToolbarApps: [], timer: new AstroTimer(), }; } diff --git a/packages/astro/src/core/config/tsconfig.ts b/packages/astro/src/core/config/tsconfig.ts index db4b1392ff2aa..3375be9c8b878 100644 --- a/packages/astro/src/core/config/tsconfig.ts +++ b/packages/astro/src/core/config/tsconfig.ts @@ -162,14 +162,14 @@ export type StripEnums<T extends Record<string, any>> = { [K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string - ? T[K] - : T[K] extends object - ? T[K] - : T[K] extends Array<any> - ? T[K] - : T[K] extends undefined - ? undefined - : any; + ? T[K] + : T[K] extends object + ? T[K] + : T[K] extends Array<any> + ? T[K] + : T[K] extends undefined + ? undefined + : any; }; export interface TSConfig { diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index de644372996c7..a3edff3b917cb 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -1,10 +1,8 @@ -import type { AstroSettings } from '../@types/astro.js'; -import type { Logger } from './logger/core.js'; - import nodeFs from 'node:fs'; import { fileURLToPath } from 'node:url'; import * as vite from 'vite'; import { crawlFrameworkPkgs } from 'vitefu'; +import type { AstroSettings } from '../@types/astro.js'; import astroAssetsPlugin from '../assets/vite-plugin-assets.js'; import { astroContentAssetPropagationPlugin, @@ -31,8 +29,11 @@ import astroScannerPlugin from '../vite-plugin-scanner/index.js'; import astroScriptsPlugin from '../vite-plugin-scripts/index.js'; import astroScriptsPageSSRPlugin from '../vite-plugin-scripts/page-ssr.js'; import { vitePluginSSRManifest } from '../vite-plugin-ssr-manifest/index.js'; +import type { Logger } from './logger/core.js'; +import { createViteLogger } from './logger/vite.js'; import { vitePluginMiddleware } from './middleware/vite-plugin.js'; import { joinPaths } from './path.js'; +import vitePluginFileURL from '../vite-plugin-fileurl/index.js'; interface CreateViteOptions { settings: AstroSettings; @@ -108,7 +109,7 @@ export async function createVite( configFile: false, cacheDir: fileURLToPath(new URL('./node_modules/.vite/', settings.config.root)), // using local caches allows Astro to be used in monorepos, etc. clearScreen: false, // we want to control the output, not Vite - logLevel: 'warn', // log warnings and errors only + customLogger: createViteLogger(logger, settings.config.vite.logLevel), appType: 'custom', optimizeDeps: { entries: ['src/**/*'], @@ -141,7 +142,8 @@ export async function createVite( astroPrefetch({ settings }), astroTransitions({ settings }), astroDevOverlay({ settings, logger }), - !!settings.config.experimental.i18n && astroInternationalization({ settings }), + vitePluginFileURL({}), + !!settings.config.i18n && astroInternationalization({ settings }), ], publicDir: fileURLToPath(settings.config.publicDir), root: fileURLToPath(settings.config.root), @@ -180,7 +182,7 @@ export async function createVite( }, { find: 'astro:middleware', - replacement: 'astro/middleware/namespace', + replacement: 'astro/virtual-modules/middleware.js', }, { find: 'astro:components', diff --git a/packages/astro/src/core/dev/dev.ts b/packages/astro/src/core/dev/dev.ts index 02ba9d872ffcf..c0c1b9b8ea642 100644 --- a/packages/astro/src/core/dev/dev.ts +++ b/packages/astro/src/core/dev/dev.ts @@ -1,8 +1,9 @@ +import { green } from 'kleur/colors'; +import type * as vite from 'vite'; import fs from 'node:fs'; import type http from 'node:http'; import type { AddressInfo } from 'node:net'; import { performance } from 'perf_hooks'; -import type * as vite from 'vite'; import type { AstroInlineConfig } from '../../@types/astro.js'; import { attachContentServerListeners } from '../../content/index.js'; import { telemetry } from '../../events/index.js'; @@ -33,9 +34,8 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS // Start listening to the port const devServerAddressInfo = await startContainer(restart.container); - logger.info( - null, + 'SKIP_FORMAT', msg.serverStart({ startupTime: performance.now() - devStart, resolvedUrls: restart.container.viteServer.resolvedUrls || { local: [], network: [] }, @@ -46,14 +46,16 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS const currentVersion = process.env.PACKAGE_VERSION ?? '0.0.0'; if (currentVersion.includes('-')) { - logger.warn(null, msg.prerelease({ currentVersion })); + logger.warn('SKIP_FORMAT', msg.prerelease({ currentVersion })); } if (restart.container.viteServer.config.server?.fs?.strict === false) { - logger.warn(null, msg.fsStrictWarning()); + logger.warn('SKIP_FORMAT', msg.fsStrictWarning()); } await attachContentServerListeners(restart.container); + logger.info(null, green('watching for file changes...')); + return { address: devServerAddressInfo, get watcher() { diff --git a/packages/astro/src/core/dev/restart.ts b/packages/astro/src/core/dev/restart.ts index f03db39cf957d..3d77ef0c0cc56 100644 --- a/packages/astro/src/core/dev/restart.ts +++ b/packages/astro/src/core/dev/restart.ts @@ -1,4 +1,4 @@ -import nodeFs from 'node:fs'; +import type nodeFs from 'node:fs'; import { fileURLToPath } from 'node:url'; import * as vite from 'vite'; import type { AstroInlineConfig, AstroSettings } from '../../@types/astro.js'; @@ -29,6 +29,9 @@ async function createRestartedContainer( return newContainer; } +const configRE = new RegExp(`.*astro\.config\.((mjs)|(cjs)|(js)|(ts))$`); +const preferencesRE = new RegExp(`.*\.astro\/settings\.json$`); + export function shouldRestartContainer( { settings, inlineConfig, restartInFlight }: Container, changedFile: string @@ -43,9 +46,9 @@ export function shouldRestartContainer( } // Otherwise, watch for any astro.config.* file changes in project root else { - const exp = new RegExp(`.*astro\.config\.((mjs)|(cjs)|(js)|(ts))$`); const normalizedChangedFile = vite.normalizePath(changedFile); - shouldRestart = exp.test(normalizedChangedFile); + shouldRestart = + configRE.test(normalizedChangedFile) || preferencesRE.test(normalizedChangedFile); } if (!shouldRestart && settings.watchFiles.length > 0) { @@ -71,7 +74,10 @@ export async function restartContainer(container: Container): Promise<Container const error = createSafeError(_err); // Print all error messages except ZodErrors from AstroConfig as the pre-logged error is sufficient if (!isAstroConfigZodError(_err)) { - logger.error('config', formatErrorMessage(collectErrorMetadata(error)) + '\n'); + logger.error( + 'config', + formatErrorMessage(collectErrorMetadata(error), logger.level() === 'debug') + '\n' + ); } // Inform connected clients of the config error container.viteServer.ws.send({ @@ -82,7 +88,7 @@ export async function restartContainer(container: Container): Promise<Container }, }); container.restartInFlight = false; - logger.error('astro', 'Continuing with previous valid configuration\n'); + logger.error(null, 'Continuing with previous valid configuration\n'); return error; } } @@ -121,8 +127,8 @@ export async function createContainerWithAutomaticRestart({ }, }; - async function handleServerRestart(logMsg: string) { - logger.info('astro', logMsg + '\n'); + async function handleServerRestart(logMsg = '') { + logger.info(null, (logMsg + ' Restarting...').trim()); const container = restart.container; const result = await restartContainer(container); if (result instanceof Error) { @@ -150,13 +156,13 @@ export async function createContainerWithAutomaticRestart({ // Set up watches function addWatches() { const watcher = restart.container.viteServer.watcher; - watcher.on('change', handleChangeRestart('Configuration updated. Restarting...')); - watcher.on('unlink', handleChangeRestart('Configuration removed. Restarting...')); - watcher.on('add', handleChangeRestart('Configuration added. Restarting...')); + watcher.on('change', handleChangeRestart('Configuration file updated.')); + watcher.on('unlink', handleChangeRestart('Configuration file removed.')); + watcher.on('add', handleChangeRestart('Configuration file added.')); // Restart the Astro dev server instead of Vite's when the API is called by plugins. // Ignore the `forceOptimize` parameter for now. - restart.container.viteServer.restart = () => handleServerRestart('Restarting...'); + restart.container.viteServer.restart = () => handleServerRestart(); } addWatches(); return restart; diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 80af2358d13be..c04c9b2b50212 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -1,9 +1,7 @@ -import mime from 'mime'; import type { APIContext, EndpointHandler, - EndpointOutput, - MiddlewareEndpointHandler, + Locales, MiddlewareHandler, Params, } from '../../@types/astro.js'; @@ -19,8 +17,6 @@ import { } from '../render/context.js'; import { type Environment, type RenderContext } from '../render/index.js'; -const encoder = new TextEncoder(); - const clientAddressSymbol = Symbol.for('astro.clientAddress'); const clientLocalsSymbol = Symbol.for('astro.locals'); @@ -30,7 +26,7 @@ type CreateAPIContext = { site?: string; props: Record<string, any>; adapterName?: string; - locales: string[] | undefined; + locales: Locales | undefined; routingStrategy: 'prefix-always' | 'prefix-other-locales' | undefined; defaultLocale: string | undefined; }; @@ -69,7 +65,6 @@ export function createAPIContext({ }, }); }, - ResponseWithEncoding, get preferredLocale(): string | undefined { if (preferredLocale) { return preferredLocale; @@ -143,36 +138,11 @@ export function createAPIContext({ return context; } -type ResponseParameters = ConstructorParameters<typeof Response>; - -export class ResponseWithEncoding extends Response { - constructor(body: ResponseParameters[0], init: ResponseParameters[1], encoding?: BufferEncoding) { - // If a body string is given, try to encode it to preserve the behaviour as simple objects. - // We don't do the full handling as simple objects so users can control how headers are set instead. - if (typeof body === 'string') { - // In NodeJS, we can use Buffer.from which supports all BufferEncoding - if (typeof Buffer !== 'undefined' && Buffer.from) { - body = Buffer.from(body, encoding); - } - // In non-NodeJS, use the web-standard TextEncoder for utf-8 strings - else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') { - body = encoder.encode(body); - } - } - - super(body, init); - - if (encoding) { - this.headers.set('X-Astro-Encoding', encoding); - } - } -} - -export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>( +export async function callEndpoint( mod: EndpointHandler, env: Environment, ctx: RenderContext, - onRequest: MiddlewareHandler<MiddlewareResult> | undefined + onRequest: MiddlewareHandler | undefined ): Promise<Response> { const context = createAPIContext({ request: ctx.request, @@ -180,114 +150,20 @@ export async function callEndpoint<MiddlewareResult = Response | EndpointOutput> props: ctx.props, site: env.site, adapterName: env.adapterName, - routingStrategy: ctx.routingStrategy, + routingStrategy: ctx.routing, defaultLocale: ctx.defaultLocale, locales: ctx.locales, }); let response; if (onRequest) { - response = await callMiddleware<Response | EndpointOutput>( - env.logger, - onRequest as MiddlewareEndpointHandler, - context, - async () => { - return await renderEndpoint(mod, context, env.ssr, env.logger); - } - ); + response = await callMiddleware(onRequest, context, async () => { + return await renderEndpoint(mod, context, env.ssr, env.logger); + }); } else { response = await renderEndpoint(mod, context, env.ssr, env.logger); } - const isEndpointSSR = env.ssr && !ctx.route?.prerender; - - if (response instanceof Response) { - if (isEndpointSSR && response.headers.get('X-Astro-Encoding')) { - env.logger.warn( - 'ssr', - '`ResponseWithEncoding` is ignored in SSR. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.' - ); - } - attachCookiesToResponse(response, context.cookies); - return response; - } - - // The endpoint returned a simple object, convert it to a Response - - // TODO: Remove in Astro 4.0 - env.logger.warn( - 'astro', - `${ctx.route.component} returns a simple object which is deprecated. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.` - ); - - if (isEndpointSSR) { - if (response.hasOwnProperty('headers')) { - env.logger.warn( - 'ssr', - 'Setting headers is not supported when returning an object. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.' - ); - } - - if (response.encoding) { - env.logger.warn( - 'ssr', - '`encoding` is ignored in SSR. To return a charset other than UTF-8, please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.' - ); - } - } - - let body: BodyInit; - const headers = new Headers(); - - // Try to get the MIME type for this route - const pathname = ctx.route - ? // Try the static route `pathname` - ctx.route.pathname ?? - // Dynamic routes don't include `pathname`, so synthesize a path for these (e.g. 'src/pages/[slug].svg') - ctx.route.segments.map((s) => s.map((p) => p.content).join('')).join('/') - : // Fallback to pathname of the request - ctx.pathname; - const mimeType = mime.getType(pathname) || 'text/plain'; - headers.set('Content-Type', `${mimeType};charset=utf-8`); - - // Save encoding to X-Astro-Encoding to be used later during SSG with `fs.writeFile`. - // It won't work in SSR and is already warned above. - if (response.encoding) { - headers.set('X-Astro-Encoding', response.encoding); - } - - // For Uint8Array (binary), it can passed to Response directly - if (response.body instanceof Uint8Array) { - body = response.body; - headers.set('Content-Length', body.byteLength.toString()); - } - // In NodeJS, we can use Buffer.from which supports all BufferEncoding - else if (typeof Buffer !== 'undefined' && Buffer.from) { - body = Buffer.from(response.body, response.encoding); - headers.set('Content-Length', body.byteLength.toString()); - } - // In non-NodeJS, use the web-standard TextEncoder for utf-8 strings only - // to calculate the content length - else if ( - response.encoding == null || - response.encoding === 'utf8' || - response.encoding === 'utf-8' - ) { - body = encoder.encode(response.body); - headers.set('Content-Length', body.byteLength.toString()); - } - // Fallback pass it to Response directly. It will mainly rely on X-Astro-Encoding - // to be further processed in SSG. - else { - body = response.body; - // NOTE: Can't calculate the content length as we can't encode to figure out the real length. - // But also because we don't need the length for SSG as it's only being written to disk. - } - - response = new Response(body, { - status: 200, - headers, - }); attachCookiesToResponse(response, context.cookies); return response; } diff --git a/packages/astro/src/core/errors/dev/vite.ts b/packages/astro/src/core/errors/dev/vite.ts index b3e49234d6033..7d67806f8fa4f 100644 --- a/packages/astro/src/core/errors/dev/vite.ts +++ b/packages/astro/src/core/errors/dev/vite.ts @@ -83,7 +83,6 @@ export function enhanceViteSSRError({ if (globPattern) { safeError.message = InvalidGlob.message(globPattern); safeError.name = 'InvalidGlob'; - safeError.hint = InvalidGlob.hint; safeError.title = InvalidGlob.title; const line = lns.findIndex((ln) => ln.includes(globPattern)); diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index ec84888d4cc9c..047bb533721ce 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -292,6 +292,7 @@ export const InvalidGetStaticPathsReturn = { /** * @docs + * @deprecated Deprecated since Astro 4.0. The RSS helper no longer exists with an error fallback. * @see * - [RSS Guide](https://docs.astro.build/en/guides/rss/) * @description @@ -490,9 +491,10 @@ export const PageNumberParamNotFound = { */ export const ImageMissingAlt = { name: 'ImageMissingAlt', - title: 'Missing alt property.', - message: 'The alt property is required.', - hint: "The `alt` property is important for the purpose of accessibility, without it users using screen readers or other assistive technologies won't be able to understand what your image is supposed to represent. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-alt for more information.", + title: 'Image missing required "alt" property.', + message: + 'Image missing "alt" property. "alt" text is required to describe important images on the page.', + hint: 'Use an empty string ("") for decorative images.', } satisfies ErrorData; /** * @docs @@ -731,8 +733,9 @@ export const ResponseSentError = { */ export const MiddlewareNoDataOrNextCalled = { name: 'MiddlewareNoDataOrNextCalled', - title: "The middleware didn't return a response or call `next`.", - message: 'The middleware needs to either return a `Response` object or call the `next` function.', + title: "The middleware didn't return a `Response`.", + message: + 'Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function.', } satisfies ErrorData; /** @@ -1275,10 +1278,8 @@ export const UnsupportedConfigTransformError = { export const MissingLocale = { name: 'MissingLocaleError', title: 'The provided locale does not exist.', - message: (locale: string, locales: string[]) => { - return `The locale \`${locale}\` does not exist in the configured locales. Available locales: ${locales.join( - ', ' - )}.`; + message: (locale: string) => { + return `The locale/path \`${locale}\` does not exist in the configured \`i18n.locales\`.`; }, } satisfies ErrorData; @@ -1292,3 +1293,12 @@ export const CantRenderPage = { // Generic catch-all - Only use this in extreme cases, like if there was a cosmic ray bit flip export const UnknownError = { name: 'UnknownError', title: 'Unknown Error.' } satisfies ErrorData; + +export const UnhandledRejection = { + name: 'UnhandledRejection', + title: 'Unhandled rejection', + message: (stack: string) => { + return `Astro detected an unhandled rejection. Here's the stack trace:\n${stack}`; + }, + hint: 'Make sure your promises all have an `await` or a `.catch()` handler.', +}; diff --git a/packages/astro/src/core/errors/utils.ts b/packages/astro/src/core/errors/utils.ts index 300787dd32032..ef0a10b4f6ded 100644 --- a/packages/astro/src/core/errors/utils.ts +++ b/packages/astro/src/core/errors/utils.ts @@ -93,9 +93,8 @@ export function createSafeError(err: any): Error { } else { const error = new Error(JSON.stringify(err)); - ( - error as SSRError - ).hint = `To get as much information as possible from your errors, make sure to throw Error objects instead of \`${typeof err}\`. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error for more information.`; + (error as SSRError).hint = + `To get as much information as possible from your errors, make sure to throw Error objects instead of \`${typeof err}\`. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error for more information.`; return error; } diff --git a/packages/astro/src/core/logger/console.ts b/packages/astro/src/core/logger/console.ts index f39f6b74d2332..d55318d4ccac3 100644 --- a/packages/astro/src/core/logger/console.ts +++ b/packages/astro/src/core/logger/console.ts @@ -1,10 +1,6 @@ -import { bold, cyan, dim, red, reset, yellow } from 'kleur/colors'; -import type { LogMessage } from './core.js'; -import { dateTimeFormat, levels } from './core.js'; +import { getEventPrefix, levels, type LogMessage, type LogWritable } from './core.js'; -let lastMessage: string; -let lastMessageCount = 1; -export const consoleLogDestination = { +export const consoleLogDestination: LogWritable<LogMessage> = { write(event: LogMessage) { // eslint-disable-next-line no-console let dest = console.error; @@ -12,37 +8,11 @@ export const consoleLogDestination = { // eslint-disable-next-line no-console dest = console.log; } - - function getPrefix() { - let prefix = ''; - let type = event.label; - if (type) { - // hide timestamp when type is undefined - prefix += dim(dateTimeFormat.format(new Date()) + ' '); - if (event.level === 'info') { - type = bold(cyan(`[${type}]`)); - } else if (event.level === 'warn') { - type = bold(yellow(`[${type}]`)); - } else if (event.level === 'error') { - type = bold(red(`[${type}]`)); - } - - prefix += `${type} `; - } - return reset(prefix); - } - - let message = event.message; - // For repeat messages, only update the message counter - if (message === lastMessage) { - lastMessageCount++; - message = `${message} ${yellow(`(x${lastMessageCount})`)}`; + if (event.label === 'SKIP_FORMAT') { + dest(event.message); } else { - lastMessage = message; - lastMessageCount = 1; + dest(getEventPrefix(event) + ' ' + event.message); } - const outMessage = getPrefix() + message; - dest(outMessage); return true; }, }; diff --git a/packages/astro/src/core/logger/core.ts b/packages/astro/src/core/logger/core.ts index 11804dd01ab71..db571d8f14da4 100644 --- a/packages/astro/src/core/logger/core.ts +++ b/packages/astro/src/core/logger/core.ts @@ -1,12 +1,36 @@ -import { dim } from 'kleur/colors'; +import { blue, bold, dim, red, yellow } from 'kleur/colors'; import stringWidth from 'string-width'; -interface LogWritable<T> { +export interface LogWritable<T> { write: (chunk: T) => boolean; } export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; // same as Pino +/** + * Defined logger labels. Add more as needed, but keep them high-level & reusable, + * rather than specific to a single command, function, use, etc. The label will be + * shown in the log message to the user, so it should be relevant. + */ +export type LoggerLabel = + | 'add' + | 'build' + | 'check' + | 'config' + | 'content' + | 'deprecated' + | 'markdown' + | 'router' + | 'types' + | 'vite' + | 'watch' + | 'middleware' + | 'preferences' + | 'redirects' + // SKIP_FORMAT: A special label that tells the logger not to apply any formatting. + // Useful for messages that are already formatted, like the server start message. + | 'SKIP_FORMAT'; + export interface LogOptions { dest: LogWritable<LogMessage>; level: LoggerLevel; @@ -25,6 +49,7 @@ export const dateTimeFormat = new Intl.DateTimeFormat([], { hour: '2-digit', minute: '2-digit', second: '2-digit', + hour12: false, }); export interface LogMessage { @@ -52,13 +77,17 @@ export function log(opts: LogOptions, level: LoggerLevel, label: string | null, }; // test if this level is enabled or not - if (levels[logLevel] > levels[level]) { + if (!isLogLevelEnabled(logLevel, level)) { return; // do nothing } dest.write(event); } +export function isLogLevelEnabled(configuredLogLevel: LoggerLevel, level: LoggerLevel) { + return levels[configuredLogLevel] <= levels[level]; +} + /** Emit a user-facing message. Useful for UI and other console messages. */ export function info(opts: LogOptions, label: string | null, message: string) { return log(opts, 'info', label, message); @@ -98,6 +127,35 @@ function padStr(str: string, len: number) { return str + spaces; } +/** + * Get the prefix for a log message. + * This includes the timestamp, log level, and label all properly formatted + * with colors. This is shared across different loggers, so it's defined here. + */ +export function getEventPrefix({ level, label }: LogMessage) { + const timestamp = `${dateTimeFormat.format(new Date())}`; + const prefix = []; + if (level === 'error' || level === 'warn') { + prefix.push(bold(timestamp)); + prefix.push(`[${level.toUpperCase()}]`); + } else { + prefix.push(timestamp); + } + if (label) { + prefix.push(`[${label}]`); + } + if (level === 'error') { + return red(prefix.join(' ')); + } + if (level === 'warn') { + return yellow(prefix.join(' ')); + } + if (prefix.length === 1) { + return dim(prefix[0]); + } + return dim(prefix[0]) + ' ' + blue(prefix.splice(1).join(' ')); +} + export let defaultLogLevel: LoggerLevel; if (typeof process !== 'undefined') { // This could be a shimmed environment so we don't know that `process` is the full @@ -133,16 +191,16 @@ export class Logger { this.options = options; } - info(label: string | null, message: string) { + info(label: LoggerLabel | null, message: string) { info(this.options, label, message); } - warn(label: string | null, message: string) { + warn(label: LoggerLabel | null, message: string) { warn(this.options, label, message); } - error(label: string | null, message: string) { + error(label: LoggerLabel | null, message: string) { error(this.options, label, message); } - debug(label: string | null, ...messages: any[]) { + debug(label: LoggerLabel, ...messages: any[]) { debug(label, ...messages); } diff --git a/packages/astro/src/core/logger/node.ts b/packages/astro/src/core/logger/node.ts index 57aa59ed02d40..2c75968d2f85f 100644 --- a/packages/astro/src/core/logger/node.ts +++ b/packages/astro/src/core/logger/node.ts @@ -1,113 +1,35 @@ import debugPackage from 'debug'; -import { bold, cyan, dim, red, reset, yellow } from 'kleur/colors'; -import * as readline from 'node:readline'; -import { Writable } from 'node:stream'; -import stringWidth from 'string-width'; -import { dateTimeFormat, error, info, warn } from './core.js'; +import type { Writable } from 'node:stream'; +import { getEventPrefix, levels, type LogMessage, type LogWritable } from './core.js'; type ConsoleStream = Writable & { fd: 1 | 2; }; -let lastMessage: string; -let lastMessageCount = 1; -export const nodeLogDestination = new Writable({ - objectMode: true, - write(event: LogMessage, _, callback) { +export const nodeLogDestination: LogWritable<LogMessage> = { + write(event: LogMessage) { let dest: ConsoleStream = process.stderr; if (levels[event.level] < levels['error']) { dest = process.stdout; } - - function getPrefix() { - let prefix = ''; - let label = event.label; - if (label) { - // hide timestamp when type is undefined - prefix += dim(dateTimeFormat.format(new Date()) + ' '); - if (event.level === 'info') { - label = bold(cyan(`[${label}]`)); - } else if (event.level === 'warn') { - label = bold(yellow(`[${label}]`)); - } else if (event.level === 'error') { - label = bold(red(`[${label}]`)); - } - - prefix += `${label} `; - } - return reset(prefix); - } - - // console.log({msg: event.message, args: event.args}); - let message = event.message; - // For repeat messages, only update the message counter - if (message === lastMessage) { - lastMessageCount++; - if (levels[event.level] < levels['error']) { - let lines = 1; - let len = stringWidth(`${getPrefix()}${message}`); - let cols = (dest as unknown as typeof process.stdout).columns; - if (len > cols) { - lines = Math.ceil(len / cols); - } - for (let i = 0; i < lines; i++) { - readline.clearLine(dest, 0); - readline.cursorTo(dest, 0); - readline.moveCursor(dest, 0, -1); - } - } - message = `${message} ${yellow(`(x${lastMessageCount})`)}`; + if (event.label === 'SKIP_FORMAT') { + dest.write(event.message + '\n'); } else { - lastMessage = message; - lastMessageCount = 1; + dest.write(getEventPrefix(event) + ' ' + event.message + '\n'); } - - dest.write(getPrefix()); - dest.write(message); - dest.write('\n'); - callback(); + return true; }, -}); - -interface LogWritable<T> { - write: (chunk: T) => boolean; -} - -export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; // same as Pino -export type LoggerEvent = 'info' | 'warn' | 'error'; - -export interface LogOptions { - dest?: LogWritable<LogMessage>; - level?: LoggerLevel; -} - -export const nodeLogOptions: Required<LogOptions> = { - dest: nodeLogDestination, - level: 'info', -}; - -export interface LogMessage { - label: string | null; - level: LoggerLevel; - message: string; -} - -export const levels: Record<LoggerLevel, number> = { - debug: 20, - info: 30, - warn: 40, - error: 50, - silent: 90, }; const debuggers: Record<string, debugPackage.Debugger['log']> = {}; + /** * Emit a message only shown in debug mode. * Astro (along with many of its dependencies) uses the `debug` package for debug logging. * You can enable these logs with the `DEBUG=astro:*` environment variable. * More info https://github.com/debug-js/debug#environment-variables */ -export function debug(type: string, ...messages: Array<any>) { +function debug(type: string, ...messages: Array<any>) { const namespace = `astro:${type}`; debuggers[namespace] = debuggers[namespace] || debugPackage(namespace); return debuggers[namespace](...messages); @@ -116,16 +38,9 @@ export function debug(type: string, ...messages: Array<any>) { // This is gross, but necessary since we are depending on globals. (globalThis as any)._astroGlobalDebug = debug; -// A default logger for when too lazy to pass LogOptions around. -export const logger = { - info: info.bind(null, nodeLogOptions), - warn: warn.bind(null, nodeLogOptions), - error: error.bind(null, nodeLogOptions), -}; - export function enableVerboseLogging() { - debugPackage.enable('*,-babel'); - debug('cli', '--verbose flag enabled! Enabling: DEBUG="*,-babel"'); + debugPackage.enable('astro:*,vite:*'); + debug('cli', '--verbose flag enabled! Enabling: DEBUG="astro:*,vite:*"'); debug( 'cli', 'Tip: Set the DEBUG env variable directly for more control. Example: "DEBUG=astro:*,vite:* astro build".' diff --git a/packages/astro/src/core/logger/vite.ts b/packages/astro/src/core/logger/vite.ts new file mode 100644 index 0000000000000..ac48369a36939 --- /dev/null +++ b/packages/astro/src/core/logger/vite.ts @@ -0,0 +1,97 @@ +import { fileURLToPath } from 'url'; +import stripAnsi from 'strip-ansi'; +import type { Logger as ViteLogger, Rollup, LogLevel } from 'vite'; +import { isAstroError } from '../errors/errors.js'; +import { isLogLevelEnabled, type Logger as AstroLogger } from './core.js'; + +const PKG_PREFIX = fileURLToPath(new URL('../../../', import.meta.url)); +const E2E_PREFIX = fileURLToPath(new URL('../../../e2e', import.meta.url)); +export function isAstroSrcFile(id: string | null) { + return id?.startsWith(PKG_PREFIX) && !id.startsWith(E2E_PREFIX); +} + +// capture "page reload some/Component.vue (additional info)" messages +const vitePageReloadMsg = /page reload (.*)( \(.*\))?/; +// capture "hmr update some/Component.vue" messages +const viteHmrUpdateMsg = /hmr update (.*)/; +// capture "vite v5.0.0 building SSR bundle for production..." and "vite v5.0.0 building for production..." messages +const viteBuildMsg = /vite.*building.*for production/; + +export function createViteLogger( + astroLogger: AstroLogger, + viteLogLevel: LogLevel = 'info' +): ViteLogger { + const warnedMessages = new Set<string>(); + const loggedErrors = new WeakSet<Error | Rollup.RollupError>(); + + const logger: ViteLogger = { + hasWarned: false, + info(msg) { + if (!isLogLevelEnabled(viteLogLevel, 'info')) return; + + const stripped = stripAnsi(msg); + let m; + // Rewrite HMR page reload message + if ((m = vitePageReloadMsg.exec(stripped))) { + if (isAstroSrcFile(m[1])) return; + const extra = m[2] ?? ''; + astroLogger.info('watch', m[1] + extra); + } + // Rewrite HMR update message + else if ((m = viteHmrUpdateMsg.exec(stripped))) { + if (isAstroSrcFile(m[1])) return; + astroLogger.info('watch', m[1]); + } + // Don't log Vite build messages + else if (viteBuildMsg.test(stripped)) { + // noop + } + // Fallback + else { + astroLogger.info('vite', msg); + } + }, + warn(msg) { + if (!isLogLevelEnabled(viteLogLevel, 'warn')) return; + + logger.hasWarned = true; + astroLogger.warn('vite', msg); + }, + warnOnce(msg) { + if (!isLogLevelEnabled(viteLogLevel, 'warn')) return; + + if (warnedMessages.has(msg)) return; + logger.hasWarned = true; + astroLogger.warn('vite', msg); + warnedMessages.add(msg); + }, + error(msg, opts) { + if (!isLogLevelEnabled(viteLogLevel, 'error')) return; + + logger.hasWarned = true; + + const err = opts?.error; + if (err) loggedErrors.add(err); + // Astro errors are already logged by us, skip logging + if (err && isAstroError(err)) return; + // SSR module and pre-transform errors are always handled by us, + // send to debug logs + if ( + msg.includes('Error when evaluating SSR module') || + msg.includes('Pre-transform error:') + ) { + astroLogger.debug('vite', msg); + return; + } + + astroLogger.error('vite', msg); + }, + // Don't allow clear screen + clearScreen: () => {}, + hasErrorLogged(error) { + return loggedErrors.has(error); + }, + }; + + return logger; +} diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts index 758f5e5813c46..b105e985cb052 100644 --- a/packages/astro/src/core/messages.ts +++ b/packages/astro/src/core/messages.ts @@ -5,6 +5,7 @@ import { bgWhite, bgYellow, black, + blue, bold, cyan, dim, @@ -22,36 +23,29 @@ import { CompilerError, type ErrorWithMetadata, } from './errors/index.js'; -import { emoji, padMultilineString } from './util.js'; - -const PREFIX_PADDING = 6; +import { padMultilineString } from './util.js'; /** Display */ export function req({ url, + method, statusCode, reqTime, }: { url: string; statusCode: number; + method?: string; reqTime?: number; }): string { - let color = dim; - if (statusCode >= 500) color = red; - else if (statusCode >= 400) color = yellow; - else if (statusCode >= 300) color = dim; - else if (statusCode >= 200) color = green; - return `${bold(color(`${statusCode}`.padStart(PREFIX_PADDING)))} ${url.padStart(40)} ${ - reqTime ? dim(Math.round(reqTime) + 'ms') : '' - }`.trim(); -} - -export function reload({ file }: { file: string }): string { - return `${green('reload'.padStart(PREFIX_PADDING))} ${file}`; -} - -export function hmr({ file, style = false }: { file: string; style?: boolean }): string { - return `${green('update'.padStart(PREFIX_PADDING))} ${file}${style ? ` ${dim('style')}` : ''}`; + const color = statusCode >= 500 ? red : statusCode >= 300 ? yellow : blue; + return ( + color(`[${statusCode}]`) + + ` ` + + (method && method !== 'GET' ? color(method) + ' ' : '') + + url + + ` ` + + (reqTime ? dim(Math.round(reqTime) + 'ms') : '') + ); } /** Display server host and startup time */ @@ -60,13 +54,11 @@ export function serverStart({ resolvedUrls, host, base, - isRestart = false, }: { startupTime: number; resolvedUrls: ResolvedServerUrls; host: string | boolean; base: string; - isRestart?: boolean; }): string { // PACKAGE_VERSION is injected at build-time const version = process.env.PACKAGE_VERSION ?? '0.0.0'; @@ -75,10 +67,10 @@ export function serverStart({ const emptyPrefix = ' '.repeat(11); const localUrlMessages = resolvedUrls.local.map((url, i) => { - return `${i === 0 ? localPrefix : emptyPrefix}${bold(cyan(new URL(url).origin + base))}`; + return `${i === 0 ? localPrefix : emptyPrefix}${cyan(new URL(url).origin + base)}`; }); const networkUrlMessages = resolvedUrls.network.map((url, i) => { - return `${i === 0 ? networkPrefix : emptyPrefix}${bold(cyan(new URL(url).origin + base))}`; + return `${i === 0 ? networkPrefix : emptyPrefix}${cyan(new URL(url).origin + base)}`; }); if (networkUrlMessages.length === 0) { @@ -91,58 +83,88 @@ export function serverStart({ } const messages = [ - `${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim( - `${isRestart ? 're' : ''}started in ${Math.round(startupTime)}ms` - )}`, + '', + `${bgGreen(bold(` astro `))} ${green(`v${version}`)} ${dim(`ready in`)} ${Math.round( + startupTime + )} ${dim('ms')}`, '', ...localUrlMessages, ...networkUrlMessages, '', ]; - return messages - .filter((msg) => typeof msg === 'string') - .map((msg) => ` ${msg}`) - .join('\n'); + return messages.filter((msg) => typeof msg === 'string').join('\n'); } -export function telemetryNotice(packageManager = 'npm') { - const headline = `${cyan('◆')} Astro collects completely anonymous usage data.`; - const why = dim(' This optional program helps shape our roadmap.'); - const disable = dim(` Run \`${packageManager} run astro telemetry disable\` to opt-out.`); - const details = ` Details: ${underline('https://astro.build/telemetry')}`; - return [headline, why, disable, details].map((v) => ' ' + v).join('\n'); +export function telemetryNotice() { + const headline = blue(`▶ Astro collects anonymous usage data.`); + const why = ' This information helps us improve Astro.'; + const disable = ` Run "astro telemetry disable" to opt-out.`; + const details = ` ${cyan(underline('https://astro.build/telemetry'))}`; + return [headline, why, disable, details].join('\n'); } export function telemetryEnabled() { - return `${green('◉')} Anonymous telemetry is now ${bgGreen(black(' enabled '))}\n ${dim( - 'Thank you for improving Astro!' + return [ + green('▶ Anonymous telemetry ') + bgGreen(' enabled '), + ` Thank you for helping us improve Astro!`, + ``, + ].join('\n'); +} + +export function preferenceEnabled(name: string) { + return `${green('◉')} ${name} is now ${bgGreen(black(' enabled '))}\n`; +} + +export function preferenceSet(name: string, value: any) { + return `${green('◉')} ${name} has been set to ${bgGreen(black(` ${JSON.stringify(value)} `))}\n`; +} + +export function preferenceGet(name: string, value: any) { + return `${green('◉')} ${name} is set to ${bgGreen(black(` ${JSON.stringify(value)} `))}\n`; +} + +export function preferenceDefaultIntro(name: string) { + return `${yellow('◯')} ${name} has not been set. It defaults to\n`; +} + +export function preferenceDefault(name: string, value: any) { + return `${yellow('◯')} ${name} has not been set. It defaults to ${bgYellow( + black(` ${JSON.stringify(value)} `) )}\n`; } +export function preferenceDisabled(name: string) { + return `${yellow('◯')} ${name} is now ${bgYellow(black(' disabled '))}\n`; +} + +export function preferenceReset(name: string) { + return `${cyan('◆')} ${name} has been ${bgCyan(black(' reset '))}\n`; +} + export function telemetryDisabled() { - return `${yellow('◯')} Anonymous telemetry is now ${bgYellow(black(' disabled '))}\n ${dim( - "We won't ever record your usage data." - )}\n`; + return [ + green('▶ Anonymous telemetry ') + bgGreen(' disabled '), + ` Astro is no longer collecting anonymous usage data.`, + ``, + ].join('\n'); } export function telemetryReset() { - return `${cyan('◆')} Anonymous telemetry has been ${bgCyan(black(' reset '))}\n ${dim( - 'You may be prompted again.' - )}\n`; + return [green('▶ Anonymous telemetry preferences reset.'), ``].join('\n'); } export function fsStrictWarning() { - return yellow( - '⚠️ Serving with vite.server.fs.strict: false. Note that all files on your machine will be accessible to anyone on your network!' - ); + const title = yellow('▶ ' + `${bold('vite.server.fs.strict')} has been disabled!`); + const subtitle = ` Files on your machine are likely accessible on your network.`; + return `${title}\n${subtitle}\n`; } export function prerelease({ currentVersion }: { currentVersion: string }) { - const tag = currentVersion.split('-').slice(1).join('-').replace(/\..*$/, ''); + const tag = currentVersion.split('-').slice(1).join('-').replace(/\..*$/, '') || 'unknown'; const badge = bgYellow(black(` ${tag} `)); - const headline = yellow(`▶ This is a ${badge} prerelease build`); - const warning = ` Feedback? ${underline('https://astro.build/issues')}`; - return [headline, warning, ''].map((msg) => ` ${msg}`).join('\n'); + const title = yellow('▶ ' + `This is a ${badge} prerelease build!`); + const subtitle = ` Report issues here: ${cyan(underline('https://astro.build/issues'))}`; + return `${title}\n${subtitle}\n`; } export function success(message: string, tip?: string) { @@ -196,58 +218,81 @@ export function formatConfigErrorMessage(err: ZodError) { )}`; } -export function formatErrorMessage(err: ErrorWithMetadata, args: string[] = []): string { +// a regex to match the first line of a stack trace +const STACK_LINE_REGEXP = /^\s+at /g; +const IRRELEVANT_STACK_REGEXP = /(node_modules|astro[\/\\]dist)/g; +function formatErrorStackTrace( + err: Error | ErrorWithMetadata, + showFullStacktrace: boolean +): string { + const stackLines = (err.stack || '').split('\n').filter((line) => STACK_LINE_REGEXP.test(line)); + // If full details are required, just return the entire stack trace. + if (showFullStacktrace) { + return stackLines.join('\n'); + } + // Grab every string from the user's codebase, exit when you hit node_modules or astro/dist + const irrelevantStackIndex = stackLines.findIndex((line) => IRRELEVANT_STACK_REGEXP.test(line)); + if (irrelevantStackIndex <= 0) { + const errorId = (err as ErrorWithMetadata).id; + const errorLoc = (err as ErrorWithMetadata).loc; + if (errorId || errorLoc?.file) { + const prettyLocation = ` at ${errorId ?? errorLoc?.file}${ + errorLoc?.line && errorLoc.column ? `:${errorLoc.line}:${errorLoc.column}` : '' + }`; + return ( + prettyLocation + '\n [...] See full stack trace in the browser, or rerun with --verbose.' + ); + } else { + return stackLines.join('\n'); + } + } + // If the error occurred inside of a dependency, grab the entire stack. + // Otherwise, only grab the part of the stack that is relevant to the user's codebase. + return ( + stackLines.splice(0, irrelevantStackIndex).join('\n') + + '\n [...] See full stack trace in the browser, or rerun with --verbose.' + ); +} + +export function formatErrorMessage(err: ErrorWithMetadata, showFullStacktrace: boolean): string { const isOurError = AstroError.is(err) || CompilerError.is(err) || AstroUserError.is(err); + let message = ''; + if (isOurError) { + message += red(`[${err.name}]`) + ' ' + renderErrorMarkdown(err.message, 'cli'); + } else { + message += err.message; + } + const output = [message]; - args.push( - `${bgRed(black(` error `))}${red( - padMultilineString(isOurError ? renderErrorMarkdown(err.message, 'cli') : err.message) - )}` - ); if (err.hint) { - args.push(` ${bold('Hint:')}`); - args.push( - yellow(padMultilineString(isOurError ? renderErrorMarkdown(err.hint, 'cli') : err.hint, 4)) - ); + output.push(` ${bold('Hint:')}`); + output.push(yellow(padMultilineString(renderErrorMarkdown(err.hint, 'cli'), 4))); } + const docsLink = getDocsForError(err); if (docsLink) { - args.push(` ${bold('Error reference:')}`); - args.push(` ${underline(docsLink)}`); + output.push(` ${bold('Error reference:')}`); + output.push(` ${cyan(underline(docsLink))}`); } - if (err.id || err.loc?.file) { - args.push(` ${bold('File:')}`); - args.push( - red( - ` ${err.id ?? err.loc?.file}${ - err.loc?.line && err.loc.column ? `:${err.loc.line}:${err.loc.column}` : '' - }` - ) - ); - } - if (err.frame) { - args.push(` ${bold('Code:')}`); - args.push(red(padMultilineString(err.frame.trim(), 4))); - } - if (args.length === 1 && err.stack) { - args.push(dim(err.stack)); - } else if (err.stack) { - args.push(` ${bold('Stacktrace:')}`); - args.push(dim(err.stack)); - args.push(``); + + if (err.stack) { + output.push(` ${bold('Stack trace:')}`); + output.push(dim(formatErrorStackTrace(err, showFullStacktrace))); } if (err.cause) { - args.push(` ${bold('Cause:')}`); + output.push(` ${bold('Caused by:')}`); + let causeMessage = ' '; if (err.cause instanceof Error) { - args.push(dim(err.cause.stack ?? err.cause.toString())); + causeMessage += + err.cause.message + '\n' + formatErrorStackTrace(err.cause, showFullStacktrace); } else { - args.push(JSON.stringify(err.cause)); + causeMessage += JSON.stringify(err.cause); } - - args.push(``); + output.push(dim(causeMessage)); } - return args.join('\n'); + + return output.join('\n'); } export function printHelp({ diff --git a/packages/astro/src/core/middleware/callMiddleware.ts b/packages/astro/src/core/middleware/callMiddleware.ts index 40513c152ff2a..4d79cd566364a 100644 --- a/packages/astro/src/core/middleware/callMiddleware.ts +++ b/packages/astro/src/core/middleware/callMiddleware.ts @@ -1,13 +1,6 @@ -import { bold } from 'kleur/colors'; -import type { - APIContext, - EndpointOutput, - MiddlewareHandler, - MiddlewareNext, -} from '../../@types/astro.js'; +import type { APIContext, MiddlewareHandler, MiddlewareNext } from '../../@types/astro.js'; import { attachCookiesToResponse, responseHasCookies } from '../cookies/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Environment } from '../render/index.js'; /** * Utility function that is in charge of calling the middleware. @@ -43,15 +36,14 @@ import type { Environment } from '../render/index.js'; * @param apiContext The API context * @param responseFunction A callback function that should return a promise with the response */ -export async function callMiddleware<R>( - logger: Environment['logger'], - onRequest: MiddlewareHandler<R>, +export async function callMiddleware( + onRequest: MiddlewareHandler, apiContext: APIContext, - responseFunction: () => Promise<R> -): Promise<Response | R> { + responseFunction: () => Promise<Response> +): Promise<Response> { let nextCalled = false; - let responseFunctionPromise: Promise<R> | undefined = undefined; - const next: MiddlewareNext<R> = async () => { + let responseFunctionPromise: Promise<Response> | undefined = undefined; + const next: MiddlewareNext = async () => { nextCalled = true; responseFunctionPromise = responseFunction(); return responseFunctionPromise; @@ -60,14 +52,6 @@ export async function callMiddleware<R>( let middlewarePromise = onRequest(apiContext, next); return await Promise.resolve(middlewarePromise).then(async (value) => { - if (isEndpointOutput(value)) { - logger.warn( - 'middleware', - 'Using simple endpoints can cause unexpected issues in the chain of middleware functions.' + - `\nIt's strongly suggested to use full ${bold('Response')} objects.` - ); - } - // first we check if `next` was called if (nextCalled) { /** @@ -83,7 +67,7 @@ export async function callMiddleware<R>( if (value instanceof Response === false) { throw new AstroError(AstroErrorData.MiddlewareNotAResponse); } - return ensureCookiesAttached(apiContext, value as Response); + return ensureCookiesAttached(apiContext, value); } else { /** * Here we handle the case where `next` was called and returned nothing. @@ -106,7 +90,7 @@ export async function callMiddleware<R>( throw new AstroError(AstroErrorData.MiddlewareNotAResponse); } else { // Middleware did not call resolve and returned a value - return ensureCookiesAttached(apiContext, value as Response); + return ensureCookiesAttached(apiContext, value); } }); } @@ -117,11 +101,3 @@ function ensureCookiesAttached(apiContext: APIContext, response: Response): Resp } return response; } - -function isEndpointOutput(endpointResult: any): endpointResult is EndpointOutput { - return ( - !(endpointResult instanceof Response) && - typeof endpointResult === 'object' && - typeof endpointResult.body === 'string' - ); -} diff --git a/packages/astro/src/core/middleware/index.ts b/packages/astro/src/core/middleware/index.ts index c02761351d3cf..ffaafb3e56b2c 100644 --- a/packages/astro/src/core/middleware/index.ts +++ b/packages/astro/src/core/middleware/index.ts @@ -1,8 +1,8 @@ -import type { MiddlewareEndpointHandler, Params } from '../../@types/astro.js'; +import type { MiddlewareHandler, Params } from '../../@types/astro.js'; import { createAPIContext } from '../endpoint/index.js'; import { sequence } from './sequence.js'; -function defineMiddleware(fn: MiddlewareEndpointHandler) { +function defineMiddleware(fn: MiddlewareHandler) { return fn; } diff --git a/packages/astro/src/core/middleware/namespace.ts b/packages/astro/src/core/middleware/namespace.ts deleted file mode 100644 index 55a84f66620c1..0000000000000 --- a/packages/astro/src/core/middleware/namespace.ts +++ /dev/null @@ -1 +0,0 @@ -export { defineMiddleware, sequence } from './index.js'; diff --git a/packages/astro/src/core/middleware/sequence.ts b/packages/astro/src/core/middleware/sequence.ts index d20641ee31691..9a68963945ecf 100644 --- a/packages/astro/src/core/middleware/sequence.ts +++ b/packages/astro/src/core/middleware/sequence.ts @@ -1,4 +1,4 @@ -import type { APIContext, MiddlewareEndpointHandler } from '../../@types/astro.js'; +import type { APIContext, MiddlewareHandler } from '../../@types/astro.js'; import { defineMiddleware } from './index.js'; // From SvelteKit: https://github.com/sveltejs/kit/blob/master/packages/kit/src/exports/hooks/sequence.js @@ -6,11 +6,11 @@ import { defineMiddleware } from './index.js'; * * It accepts one or more middleware handlers and makes sure that they are run in sequence. */ -export function sequence(...handlers: MiddlewareEndpointHandler[]): MiddlewareEndpointHandler { +export function sequence(...handlers: MiddlewareHandler[]): MiddlewareHandler { const filtered = handlers.filter((h) => !!h); const length = filtered.length; if (!length) { - const handler: MiddlewareEndpointHandler = defineMiddleware((context, next) => { + const handler: MiddlewareHandler = defineMiddleware((context, next) => { return next(); }); return handler; diff --git a/packages/astro/src/core/middleware/vite-plugin.ts b/packages/astro/src/core/middleware/vite-plugin.ts index 0447134910f0c..918c7c9526c59 100644 --- a/packages/astro/src/core/middleware/vite-plugin.ts +++ b/packages/astro/src/core/middleware/vite-plugin.ts @@ -7,7 +7,7 @@ import type { BuildInternals } from '../build/internal.js'; import type { StaticBuildOptions } from '../build/types.js'; import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../constants.js'; -export const MIDDLEWARE_MODULE_ID = '@astro-middleware'; +export const MIDDLEWARE_MODULE_ID = '\0astro-internal:middleware'; const EMPTY_MIDDLEWARE = '\0empty-middleware'; export function vitePluginMiddleware({ settings }: { settings: AstroSettings }): VitePlugin { diff --git a/packages/astro/src/core/pipeline.ts b/packages/astro/src/core/pipeline.ts index 87f833ee5cc4f..67081a47e93f9 100644 --- a/packages/astro/src/core/pipeline.ts +++ b/packages/astro/src/core/pipeline.ts @@ -1,10 +1,4 @@ -import type { - ComponentInstance, - EndpointHandler, - MiddlewareEndpointHandler, - MiddlewareHandler, - MiddlewareResponseHandler, -} from '../@types/astro.js'; +import type { ComponentInstance, EndpointHandler, MiddlewareHandler } from '../@types/astro.js'; import { callEndpoint, createAPIContext } from './endpoint/index.js'; import { callMiddleware } from './middleware/callMiddleware.js'; import { renderPage } from './render/core.js'; @@ -28,7 +22,7 @@ export type PipelineHookFunction = (ctx: RenderContext, mod: ComponentInstance | */ export class Pipeline { env: Environment; - #onRequest?: MiddlewareEndpointHandler; + #onRequest?: MiddlewareHandler; #hooks: PipelineHooks = { before: [], }; @@ -60,7 +54,7 @@ export class Pipeline { /** * A middleware function that will be called before each request. */ - setMiddlewareFunction(onRequest: MiddlewareEndpointHandler) { + setMiddlewareFunction(onRequest: MiddlewareHandler) { this.#onRequest = onRequest; } @@ -115,11 +109,11 @@ export class Pipeline { * * It throws an error if the page can't be rendered. */ - async #tryRenderRoute<MiddlewareReturnType = Response>( + async #tryRenderRoute( renderContext: Readonly<RenderContext>, env: Readonly<Environment>, mod: Readonly<ComponentInstance> | undefined, - onRequest?: MiddlewareHandler<MiddlewareReturnType> + onRequest?: MiddlewareHandler ): Promise<Response> { const apiContext = createAPIContext({ request: renderContext.request, @@ -128,7 +122,7 @@ export class Pipeline { site: env.site, adapterName: env.adapterName, locales: renderContext.locales, - routingStrategy: renderContext.routingStrategy, + routingStrategy: renderContext.routing, defaultLocale: renderContext.defaultLocale, }); @@ -137,19 +131,14 @@ export class Pipeline { case 'fallback': case 'redirect': { if (onRequest) { - return await callMiddleware<Response>( - env.logger, - onRequest as MiddlewareResponseHandler, - apiContext, - () => { - return renderPage({ - mod, - renderContext, - env, - cookies: apiContext.cookies, - }); - } - ); + return await callMiddleware(onRequest, apiContext, () => { + return renderPage({ + mod, + renderContext, + env, + cookies: apiContext.cookies, + }); + }); } else { return await renderPage({ mod, diff --git a/packages/astro/src/core/preview/static-preview-server.ts b/packages/astro/src/core/preview/static-preview-server.ts index 937ba1c99a1ef..ba692611e9396 100644 --- a/packages/astro/src/core/preview/static-preview-server.ts +++ b/packages/astro/src/core/preview/static-preview-server.ts @@ -42,7 +42,7 @@ export default async function createStaticPreviewServer( }); } catch (err) { if (err instanceof Error) { - logger.error('astro', err.stack || err.message); + logger.error(null, err.stack || err.message); } throw err; } @@ -51,7 +51,7 @@ export default async function createStaticPreviewServer( // Log server start URLs logger.info( - null, + 'SKIP_FORMAT', msg.serverStart({ startupTime: performance.now() - startServerTime, resolvedUrls: previewServer.resolvedUrls ?? { local: [], network: [] }, @@ -72,8 +72,6 @@ export default async function createStaticPreviewServer( host: getResolvedHostForHttpServer(settings.config.server.host), port: settings.config.server.port, closed, - // In Vite 5, `httpServer` may be a `Http2SecureServer`, but we know we are only starting a HTTP server - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion server: previewServer.httpServer as http.Server, stop: async () => { await new Promise((resolve, reject) => { diff --git a/packages/astro/src/core/preview/vite-plugin-astro-preview.ts b/packages/astro/src/core/preview/vite-plugin-astro-preview.ts index 7f99792756070..aafd69cb4f257 100644 --- a/packages/astro/src/core/preview/vite-plugin-astro-preview.ts +++ b/packages/astro/src/core/preview/vite-plugin-astro-preview.ts @@ -1,13 +1,13 @@ import fs from 'node:fs'; +import type { IncomingMessage, ServerResponse } from 'node:http'; import { fileURLToPath } from 'node:url'; import type { Connect, Plugin } from 'vite'; -import { version } from 'vite'; import type { AstroSettings } from '../../@types/astro.js'; import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js'; +import { cleanUrl } from '../../vite-plugin-utils/index.js'; import { stripBase } from './util.js'; const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/; -const IS_VITE_5 = version.startsWith('5.'); export function vitePluginAstroPreview(settings: AstroSettings): Plugin { const { base, outDir, trailingSlash } = settings.config; @@ -24,8 +24,7 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin { return; } - const strippedPathname = stripBase(req.url!, base); - const pathname = new URL(strippedPathname, 'https://a.b').pathname; + const pathname = cleanUrl(stripBase(req.url!, base)); const isRoot = pathname === '/'; // Validate trailingSlash @@ -53,29 +52,49 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin { }); return () => { - const fourOhFourMiddleware: Connect.NextHandleFunction = (req, res) => { - const errorPagePath = fileURLToPath(outDir + '/404.html'); - if (fs.existsSync(errorPagePath)) { - res.statusCode = 404; - res.setHeader('Content-Type', 'text/html;charset=utf-8'); - res.end(fs.readFileSync(errorPagePath)); - } else { - const pathname = stripBase(req.url!, base); - res.statusCode = 404; - res.end(notFoundTemplate(pathname, 'Not Found')); - } - }; + // NOTE: the `base` is stripped from `req.url` for post middlewares - // Vite 5 has its own 404 middleware, we replace it with ours instead. - if (IS_VITE_5) { - for (const middleware of server.middlewares.stack) { - // This hardcoded name will not break between Vite versions - if ((middleware.handle as Connect.HandleFunction).name === 'vite404Middleware') { - middleware.handle = fourOhFourMiddleware; + server.middlewares.use((req, res, next) => { + const pathname = cleanUrl(req.url!); + + // Vite doesn't handle /foo/ if /foo.html exists, we handle it anyways + if (pathname.endsWith('/')) { + const pathnameWithoutSlash = pathname.slice(0, -1); + const htmlPath = fileURLToPath(outDir + pathnameWithoutSlash + '.html'); + if (fs.existsSync(htmlPath)) { + req.url = pathnameWithoutSlash + '.html'; + return next(); } } - } else { - server.middlewares.use(fourOhFourMiddleware); + // Vite doesn't handle /foo if /foo/index.html exists, we handle it anyways + else { + const htmlPath = fileURLToPath(outDir + pathname + '/index.html'); + if (fs.existsSync(htmlPath)) { + req.url = pathname + '/index.html'; + return next(); + } + } + + next(); + }); + + // Vite has its own 404 middleware, we replace it with ours instead. + for (const middleware of server.middlewares.stack) { + // This hardcoded name will not break between Vite versions + if ((middleware.handle as Connect.HandleFunction).name === 'vite404Middleware') { + // Fallback to 404 page if it exists + middleware.handle = (req: IncomingMessage, res: ServerResponse) => { + const errorPagePath = fileURLToPath(outDir + '/404.html'); + if (fs.existsSync(errorPagePath)) { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/html;charset=utf-8'); + res.end(fs.readFileSync(errorPagePath)); + } else { + res.statusCode = 404; + res.end(notFoundTemplate(req.url!, 'Not Found')); + } + }; + } } }; }, diff --git a/packages/astro/src/core/render/context.ts b/packages/astro/src/core/render/context.ts index 0f0bf39b04654..459b2b8b48cca 100644 --- a/packages/astro/src/core/render/context.ts +++ b/packages/astro/src/core/render/context.ts @@ -1,12 +1,13 @@ import type { ComponentInstance, + Locales, Params, Props, RouteData, SSRElement, SSRResult, } from '../../@types/astro.js'; -import { normalizeTheLocale } from '../../i18n/index.js'; +import { normalizeTheLocale, toCodes } from '../../i18n/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; import type { Environment } from './environment.js'; import { getParamsAndProps } from './params-and-props.js'; @@ -28,9 +29,9 @@ export interface RenderContext { params: Params; props: Props; locals?: object; - locales: string[] | undefined; + locales: Locales | undefined; defaultLocale: string | undefined; - routingStrategy: 'prefix-always' | 'prefix-other-locales' | undefined; + routing: 'prefix-always' | 'prefix-other-locales' | undefined; } export type CreateRenderContextArgs = Partial< @@ -62,7 +63,7 @@ export async function createRenderContext( params, props, locales: options.locales, - routingStrategy: options.routingStrategy, + routing: options.routing, defaultLocale: options.defaultLocale, }; @@ -143,8 +144,8 @@ export function parseLocale(header: string): BrowserLocale[] { return result; } -function sortAndFilterLocales(browserLocaleList: BrowserLocale[], locales: string[]) { - const normalizedLocales = locales.map(normalizeTheLocale); +function sortAndFilterLocales(browserLocaleList: BrowserLocale[], locales: Locales) { + const normalizedLocales = toCodes(locales).map(normalizeTheLocale); return browserLocaleList .filter((browserLocale) => { if (browserLocale.locale !== '*') { @@ -170,18 +171,26 @@ function sortAndFilterLocales(browserLocaleList: BrowserLocale[], locales: strin * If multiple locales are present in the header, they are sorted by their quality value and the highest is selected as current locale. * */ -export function computePreferredLocale(request: Request, locales: string[]): string | undefined { +export function computePreferredLocale(request: Request, locales: Locales): string | undefined { const acceptHeader = request.headers.get('Accept-Language'); let result: string | undefined = undefined; if (acceptHeader) { const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); const firstResult = browserLocaleList.at(0); - if (firstResult) { - if (firstResult.locale !== '*') { - result = locales.find( - (locale) => normalizeTheLocale(locale) === normalizeTheLocale(firstResult.locale) - ); + if (firstResult && firstResult.locale !== '*') { + for (const currentLocale of locales) { + if (typeof currentLocale === 'string') { + if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) { + result = currentLocale; + } + } else { + for (const currentCode of currentLocale.codes) { + if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) { + result = currentLocale.path; + } + } + } } } } @@ -189,7 +198,7 @@ export function computePreferredLocale(request: Request, locales: string[]): str return result; } -export function computePreferredLocaleList(request: Request, locales: string[]) { +export function computePreferredLocaleList(request: Request, locales: Locales): string[] { const acceptHeader = request.headers.get('Accept-Language'); let result: string[] = []; if (acceptHeader) { @@ -197,14 +206,28 @@ export function computePreferredLocaleList(request: Request, locales: string[]) // SAFETY: bang operator is safe because checked by the previous condition if (browserLocaleList.length === 1 && browserLocaleList.at(0)!.locale === '*') { - return locales; + return locales.map((locale) => { + if (typeof locale === 'string') { + return locale; + } else { + // SAFETY: codes is never empty + return locale.codes.at(0)!; + } + }); } else if (browserLocaleList.length > 0) { for (const browserLocale of browserLocaleList) { - const found = locales.find( - (l) => normalizeTheLocale(l) === normalizeTheLocale(browserLocale.locale) - ); - if (found) { - result.push(found); + for (const loopLocale of locales) { + if (typeof loopLocale === 'string') { + if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) { + result.push(loopLocale); + } + } else { + for (const code of loopLocale.codes) { + if (code === browserLocale.locale) { + result.push(loopLocale.path); + } + } + } } } } @@ -215,15 +238,21 @@ export function computePreferredLocaleList(request: Request, locales: string[]) export function computeCurrentLocale( request: Request, - locales: string[], + locales: Locales, routingStrategy: 'prefix-always' | 'prefix-other-locales' | undefined, defaultLocale: string | undefined ): undefined | string { const requestUrl = new URL(request.url); for (const segment of requestUrl.pathname.split('/')) { for (const locale of locales) { - if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { - return locale; + if (typeof locale === 'string') { + if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { + return locale; + } + } else { + if (locale.path === segment) { + return locale.codes.at(0); + } } } } diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index ed9ea7fdbb508..1175f55d7bc3d 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -61,22 +61,14 @@ export async function renderPage({ mod, renderContext, env, cookies }: RenderPag locals: renderContext.locals ?? {}, locales: renderContext.locales, defaultLocale: renderContext.defaultLocale, - routingStrategy: renderContext.routingStrategy, + routingStrategy: renderContext.routing, }); - // TODO: Remove in Astro 4.0 - if (mod.frontmatter && typeof mod.frontmatter === 'object' && 'draft' in mod.frontmatter) { - env.logger.warn( - 'astro', - `The drafts feature is deprecated and used in ${renderContext.route.component}. You should migrate to content collections instead. See https://docs.astro.build/en/guides/content-collections/#filtering-collection-queries for more information.` - ); - } - const response = await runtimeRenderPage( result, Component, renderContext.props, - null, + {}, env.streaming, renderContext.route ); diff --git a/packages/astro/src/core/render/index.ts b/packages/astro/src/core/render/index.ts index 6d466c4117d82..5f3a702a3083b 100644 --- a/packages/astro/src/core/render/index.ts +++ b/packages/astro/src/core/render/index.ts @@ -24,5 +24,5 @@ export interface SSROptions { /** * Optional middlewares */ - middleware?: AstroMiddlewareInstance<unknown>; + middleware?: AstroMiddlewareInstance; } diff --git a/packages/astro/src/core/render/params-and-props.ts b/packages/astro/src/core/render/params-and-props.ts index 0ad5df205f5b1..3532c5f837266 100644 --- a/packages/astro/src/core/render/params-and-props.ts +++ b/packages/astro/src/core/render/params-and-props.ts @@ -4,7 +4,8 @@ import type { Logger } from '../logger/core.js'; import { routeIsFallback } from '../redirects/helpers.js'; import { routeIsRedirect } from '../redirects/index.js'; import { getParams } from '../routing/params.js'; -import { RouteCache, callGetStaticPaths, findPathItemByKey } from './route-cache.js'; +import type { RouteCache } from './route-cache.js'; +import { callGetStaticPaths, findPathItemByKey } from './route-cache.js'; interface GetParamsAndPropsOptions { mod: ComponentInstance | undefined; diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index e9c8302a1ed74..9a745fd5a95fc 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -1,6 +1,7 @@ import type { AstroGlobal, AstroGlobalPartial, + Locales, Params, SSRElement, SSRLoadedRenderer, @@ -50,7 +51,7 @@ export interface CreateResultArgs { status: number; locals: App.Locals; cookies?: AstroCookies; - locales: string[] | undefined; + locales: Locales | undefined; defaultLocale: string | undefined; routingStrategy: 'prefix-always' | 'prefix-other-locales' | undefined; } @@ -100,7 +101,7 @@ class Slots { const result = this.#result; if (!Array.isArray(args)) { this.#logger.warn( - 'Astro.slots.render', + null, `Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])` ); } else if (args.length > 0) { diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts index c318b8c44308e..8a4e821a523cb 100644 --- a/packages/astro/src/core/render/route-cache.ts +++ b/packages/astro/src/core/render/route-cache.ts @@ -8,7 +8,6 @@ import type { RouteData, RuntimeMode, } from '../../@types/astro.js'; -import { AstroError, AstroErrorData } from '../errors/index.js'; import type { Logger } from '../logger/core.js'; import { stringifyParams } from '../routing/params.js'; @@ -59,9 +58,6 @@ export async function callGetStaticPaths({ // Q: Why the cast? // A: So users downstream can have nicer typings, we have to make some sacrifice in our internal typings, which necessitate a cast here paginate: generatePaginateFunction(route) as PaginateFunction, - rss() { - throw new AstroError(AstroErrorData.GetStaticPathsRemovedRSSHelper); - }, }); validateGetStaticPathsResult(staticPaths, logger, route); @@ -107,10 +103,7 @@ export class RouteCache { // Warn here so that an unexpected double-call of getStaticPaths() // isn't invisible and developer can track down the issue. if (this.mode === 'production' && this.cache[route.component]?.staticPaths) { - this.logger.warn( - 'routeCache', - `Internal Warning: route cache overwritten. (${route.component})` - ); + this.logger.warn(null, `Internal Warning: route cache overwritten. (${route.component})`); } this.cache[route.component] = entry; } @@ -131,5 +124,5 @@ export function findPathItemByKey( if (matchedStaticPath) { return matchedStaticPath; } - logger.debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`); + logger.debug('router', `findPathItemByKey() - Unexpected cache miss looking for ${paramsKey}`); } diff --git a/packages/astro/src/core/request.ts b/packages/astro/src/core/request.ts index f478b0a320db9..8bf52d11a1a62 100644 --- a/packages/astro/src/core/request.ts +++ b/packages/astro/src/core/request.ts @@ -39,15 +39,6 @@ export function createRequest({ body, }); - Object.defineProperties(request, { - params: { - get() { - logger.warn('deprecation', `Astro.request.params has been moved to Astro.params`); - return undefined; - }, - }, - }); - if (!ssr) { // Warn when accessing headers in SSG mode const _headers = request.headers; @@ -56,8 +47,8 @@ export function createRequest({ ...headersDesc, get() { logger.warn( - 'ssg', - `Headers are not exposed in static (SSG) output mode. To enable headers: set \`output: "server"\` in your config file.` + null, + `\`Astro.request.headers\` is not available in "static" output mode. To enable header access: set \`output: "server"\` or \`output: "hybrid"\` in your config file.` ); return _headers; }, diff --git a/packages/astro/src/core/routing/manifest/create.ts b/packages/astro/src/core/routing/manifest/create.ts index 6a57972e07120..19e6e3006d163 100644 --- a/packages/astro/src/core/routing/manifest/create.ts +++ b/packages/astro/src/core/routing/manifest/create.ts @@ -8,6 +8,7 @@ import type { } from '../../../@types/astro.js'; import type { Logger } from '../../logger/core.js'; +import { bold } from 'kleur/colors'; import { createRequire } from 'module'; import nodeFs from 'node:fs'; import path from 'node:path'; @@ -183,13 +184,13 @@ function comparator(a: Item, b: Item) { function injectedRouteToItem( { config, cwd }: { config: AstroConfig; cwd?: string }, - { pattern, entryPoint }: InjectedRoute + { pattern, entrypoint }: InjectedRoute ): Item { let resolved: string; try { - resolved = require.resolve(entryPoint, { paths: [cwd || fileURLToPath(config.root)] }); + resolved = require.resolve(entrypoint, { paths: [cwd || fileURLToPath(config.root)] }); } catch (e) { - resolved = fileURLToPath(new URL(entryPoint, config.root)); + resolved = fileURLToPath(new URL(entrypoint, config.root)); } const ext = path.extname(pattern); @@ -234,8 +235,6 @@ export function createRouteManifest( const localFs = fsMod ?? nodeFs; const prerender = getPrerenderDefault(settings.config); - const foundInvalidFileExtensions = new Set<string>(); - function walk( fs: typeof nodeFs, dir: string, @@ -259,10 +258,12 @@ export function createRouteManifest( } // filter out "foo.astro_tmp" files, etc if (!isDir && !validPageExtensions.has(ext) && !validEndpointExtensions.has(ext)) { - if (!foundInvalidFileExtensions.has(ext)) { - foundInvalidFileExtensions.add(ext); - logger.warn('astro', `Invalid file extension for Pages: ${ext}`); - } + logger.warn( + null, + `Unsupported file type ${bold( + resolved + )} found. Prefix filename with an underscore (\`_\`) to ignore.` + ); return; } @@ -346,6 +347,7 @@ export function createRouteManifest( generate, pathname: pathname || undefined, prerender, + fallbackRoutes: [], }); } }); @@ -358,8 +360,7 @@ export function createRouteManifest( walk(localFs, fileURLToPath(pages), [], []); } else if (settings.injectedRoutes.length === 0) { const pagesDirRootRelative = pages.href.slice(settings.config.root.href.length); - - logger.warn('astro', `Missing pages directory: ${pagesDirRootRelative}`); + logger.warn(null, `Missing pages directory: ${pagesDirRootRelative}`); } settings.injectedRoutes @@ -368,12 +369,12 @@ export function createRouteManifest( comparator(injectedRouteToItem({ config, cwd }, a), injectedRouteToItem({ config, cwd }, b)) ) .reverse() // prepend to the routes array from lowest to highest priority - .forEach(({ pattern: name, entryPoint, prerender: prerenderInjected }) => { + .forEach(({ pattern: name, entrypoint, prerender: prerenderInjected }) => { let resolved: string; try { - resolved = require.resolve(entryPoint, { paths: [cwd || fileURLToPath(config.root)] }); + resolved = require.resolve(entrypoint, { paths: [cwd || fileURLToPath(config.root)] }); } catch (e) { - resolved = fileURLToPath(new URL(entryPoint, config.root)); + resolved = fileURLToPath(new URL(entrypoint, config.root)); } const component = slash(path.relative(cwd || fileURLToPath(config.root), resolved)); @@ -422,6 +423,7 @@ export function createRouteManifest( generate, pathname: pathname || void 0, prerender: prerenderInjected ?? prerender, + fallbackRoutes: [], }); }); @@ -449,6 +451,21 @@ export function createRouteManifest( .map(([{ dynamic, content }]) => (dynamic ? `[${content}]` : content)) .join('/')}`.toLowerCase(); + { + let destination: string; + if (typeof to === 'string') { + destination = to; + } else { + destination = to.destination; + } + if (/^https?:\/\//.test(destination)) { + logger.warn( + 'redirects', + `Redirecting to an external URL is not officially supported: ${from} -> ${to}` + ); + } + } + const routeData: RouteData = { type: 'redirect', route, @@ -461,6 +478,7 @@ export function createRouteManifest( prerender: false, redirect: to, redirectRoute: routes.find((r) => r.route === to), + fallbackRoutes: [], }; const lastSegmentIsDynamic = (r: RouteData) => !!r.segments.at(-1)?.at(-1)?.dynamic; @@ -487,7 +505,7 @@ export function createRouteManifest( // Didn't find a good place, insert last routes.push(routeData); }); - const i18n = settings.config.experimental.i18n; + const i18n = settings.config.i18n; if (i18n) { // In this block of code we group routes based on their locale @@ -495,11 +513,24 @@ export function createRouteManifest( const routesByLocale = new Map<string, RouteData[]>(); // This type is here only as a helper. We copy the routes and make them unique, so we don't "process" the same route twice. // The assumption is that a route in the file system belongs to only one locale. - const setRoutes = new Set(routes); + const setRoutes = new Set(routes.filter((route) => route.type === 'page')); // First loop // We loop over the locales minus the default locale and add only the routes that contain `/<locale>`. - for (const locale of i18n.locales.filter((loc) => loc !== i18n.defaultLocale)) { + const filteredLocales = i18n.locales + .filter((loc) => { + if (typeof loc === 'string') { + return loc !== i18n.defaultLocale; + } + return loc.path !== i18n.defaultLocale; + }) + .map((locale) => { + if (typeof locale === 'string') { + return locale; + } + return locale.path; + }); + for (const locale of filteredLocales) { for (const route of setRoutes) { if (!route.route.includes(`/${locale}`)) { continue; @@ -529,7 +560,7 @@ export function createRouteManifest( // Work done, now we start creating "fallback" routes based on the configuration - if (i18n.routingStrategy === 'prefix-always') { + if (i18n.routing === 'prefix-always') { // we attempt to retrieve the index page of the default locale const defaultLocaleRoutes = routesByLocale.get(i18n.defaultLocale); if (defaultLocaleRoutes) { @@ -549,6 +580,7 @@ export function createRouteManifest( validateSegment(s); return getParts(s, route); }); + routes.push({ ...indexDefaultRoute, pathname, @@ -599,22 +631,22 @@ export function createRouteManifest( if (!hasRoute) { let pathname: string | undefined; let route: string; - if (fallbackToLocale === i18n.defaultLocale) { + if ( + fallbackToLocale === i18n.defaultLocale && + i18n.routing === 'prefix-other-locales' + ) { if (fallbackToRoute.pathname) { pathname = `/${fallbackFromLocale}${fallbackToRoute.pathname}`; } route = `/${fallbackFromLocale}${fallbackToRoute.route}`; } else { - pathname = fallbackToRoute.pathname?.replace( - `/${fallbackToLocale}`, - `/${fallbackFromLocale}` - ); - route = fallbackToRoute.route.replace( - `/${fallbackToLocale}`, - `/${fallbackFromLocale}` - ); + pathname = fallbackToRoute.pathname + ?.replace(`/${fallbackToLocale}/`, `/${fallbackFromLocale}/`) + .replace(`/${fallbackToLocale}`, `/${fallbackFromLocale}`); + route = fallbackToRoute.route + .replace(`/${fallbackToLocale}`, `/${fallbackFromLocale}`) + .replace(`/${fallbackToLocale}/`, `/${fallbackFromLocale}/`); } - const segments = removeLeadingForwardSlash(route) .split(path.posix.sep) .filter(Boolean) @@ -622,14 +654,22 @@ export function createRouteManifest( validateSegment(s); return getParts(s, route); }); - routes.push({ - ...fallbackToRoute, - pathname, - route, - segments, - pattern: getPattern(segments, config, config.trailingSlash), - type: 'fallback', - }); + const generate = getRouteGenerator(segments, config.trailingSlash); + const index = routes.findIndex((r) => r === fallbackToRoute); + if (index >= 0) { + const fallbackRoute: RouteData = { + ...fallbackToRoute, + pathname, + route, + segments, + generate, + pattern: getPattern(segments, config, config.trailingSlash), + type: 'fallback', + fallbackRoutes: [], + }; + const routeData = routes[index]; + routeData.fallbackRoutes.push(fallbackRoute); + } } } } diff --git a/packages/astro/src/core/routing/manifest/serialization.ts b/packages/astro/src/core/routing/manifest/serialization.ts index 71ffc221dd54b..f70aa84dd0aca 100644 --- a/packages/astro/src/core/routing/manifest/serialization.ts +++ b/packages/astro/src/core/routing/manifest/serialization.ts @@ -13,6 +13,9 @@ export function serializeRouteData( redirectRoute: routeData.redirectRoute ? serializeRouteData(routeData.redirectRoute, trailingSlash) : undefined, + fallbackRoutes: routeData.fallbackRoutes.map((fallbackRoute) => { + return serializeRouteData(fallbackRoute, trailingSlash); + }), _meta: { trailingSlash }, }; } @@ -32,5 +35,8 @@ export function deserializeRouteData(rawRouteData: SerializedRouteData): RouteDa redirectRoute: rawRouteData.redirectRoute ? deserializeRouteData(rawRouteData.redirectRoute) : undefined, + fallbackRoutes: rawRouteData.fallbackRoutes.map((fallback) => { + return deserializeRouteData(fallback); + }), }; } diff --git a/packages/astro/src/core/routing/match.ts b/packages/astro/src/core/routing/match.ts index 9b91e1e9a2f3c..97659253e32eb 100644 --- a/packages/astro/src/core/routing/match.ts +++ b/packages/astro/src/core/routing/match.ts @@ -2,7 +2,13 @@ import type { ManifestData, RouteData } from '../../@types/astro.js'; /** Find matching route from pathname */ export function matchRoute(pathname: string, manifest: ManifestData): RouteData | undefined { - return manifest.routes.find((route) => route.pattern.test(decodeURI(pathname))); + const decodedPathname = decodeURI(pathname); + return manifest.routes.find((route) => { + return ( + route.pattern.test(decodedPathname) || + route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(decodedPathname)) + ); + }); } /** Finds all matching routes from pathname */ diff --git a/packages/astro/src/core/routing/validation.ts b/packages/astro/src/core/routing/validation.ts index 0261c865a433f..b68d5f3e89939 100644 --- a/packages/astro/src/core/routing/validation.ts +++ b/packages/astro/src/core/routing/validation.ts @@ -79,16 +79,16 @@ export function validateGetStaticPathsResult( for (const [key, val] of Object.entries(pathObject.params)) { if (!(typeof val === 'undefined' || typeof val === 'string' || typeof val === 'number')) { logger.warn( - 'getStaticPaths', - `invalid path param: ${key}. A string, number or undefined value was expected, but got \`${JSON.stringify( + 'router', + `getStaticPaths() returned an invalid path param: "${key}". A string, number or undefined value was expected, but got \`${JSON.stringify( val )}\`.` ); } if (typeof val === 'string' && val === '') { logger.warn( - 'getStaticPaths', - `invalid path param: ${key}. \`undefined\` expected for an optional param, but got empty string.` + 'router', + `getStaticPaths() returned an invalid path param: "${key}". \`undefined\` expected for an optional param, but got empty string.` ); } } diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts index 0c7b81c3aa676..966454845b302 100644 --- a/packages/astro/src/core/sync/index.ts +++ b/packages/astro/src/core/sync/index.ts @@ -117,7 +117,7 @@ export async function syncInternal( switch (typesResult.reason) { case 'no-content-dir': default: - logger.info('content', 'No content directory found. Skipping type generation.'); + logger.debug('types', 'No content directory found. Skipping type generation.'); return 0; } } @@ -137,7 +137,7 @@ export async function syncInternal( await tempViteServer.close(); } - logger.info('content', `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`); + logger.info(null, `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`); await setUpEnvTs({ settings, logger, fs: fs ?? fsMod }); return 0; diff --git a/packages/astro/src/i18n/index.ts b/packages/astro/src/i18n/index.ts index 937daf279a676..947689d516117 100644 --- a/packages/astro/src/i18n/index.ts +++ b/packages/astro/src/i18n/index.ts @@ -1,5 +1,5 @@ import { appendForwardSlash, joinPaths } from '@astrojs/internal-helpers/path'; -import type { AstroConfig } from '../@types/astro.js'; +import type { AstroConfig, Locales } from '../@types/astro.js'; import { shouldAppendForwardSlash } from '../core/build/util.js'; import { MissingLocale } from '../core/errors/errors-data.js'; import { AstroError } from '../core/errors/index.js'; @@ -7,10 +7,10 @@ import { AstroError } from '../core/errors/index.js'; type GetLocaleRelativeUrl = GetLocaleOptions & { locale: string; base: string; - locales: string[]; + locales: Locales; trailingSlash: AstroConfig['trailingSlash']; format: AstroConfig['build']['format']; - routingStrategy?: 'prefix-always' | 'prefix-other-locales'; + routing?: 'prefix-always' | 'prefix-other-locales'; defaultLocale: string; }; @@ -39,24 +39,25 @@ type GetLocaleAbsoluteUrl = GetLocaleRelativeUrl & { export function getLocaleRelativeUrl({ locale, base, - locales, + locales: _locales, trailingSlash, format, path, prependWith, normalizeLocale = true, - routingStrategy = 'prefix-other-locales', + routing = 'prefix-other-locales', defaultLocale, }: GetLocaleRelativeUrl) { - if (!locales.includes(locale)) { + const codeToUse = peekCodePathToUse(_locales, locale); + if (!codeToUse) { throw new AstroError({ ...MissingLocale, - message: MissingLocale.message(locale, locales), + message: MissingLocale.message(locale), }); } const pathsToJoin = [base, prependWith]; - const normalizedLocale = normalizeLocale ? normalizeTheLocale(locale) : locale; - if (routingStrategy === 'prefix-always') { + const normalizedLocale = normalizeLocale ? normalizeTheLocale(codeToUse) : codeToUse; + if (routing === 'prefix-always') { pathsToJoin.push(normalizedLocale); } else if (locale !== defaultLocale) { pathsToJoin.push(normalizedLocale); @@ -84,29 +85,30 @@ export function getLocaleAbsoluteUrl({ site, ...rest }: GetLocaleAbsoluteUrl) { type GetLocalesBaseUrl = GetLocaleOptions & { base: string; - locales: string[]; + locales: Locales; trailingSlash: AstroConfig['trailingSlash']; format: AstroConfig['build']['format']; - routingStrategy?: 'prefix-always' | 'prefix-other-locales'; + routing?: 'prefix-always' | 'prefix-other-locales'; defaultLocale: string; }; export function getLocaleRelativeUrlList({ base, - locales, + locales: _locales, trailingSlash, format, path, prependWith, normalizeLocale = false, - routingStrategy = 'prefix-other-locales', + routing = 'prefix-other-locales', defaultLocale, }: GetLocalesBaseUrl) { + const locales = toPaths(_locales); return locales.map((locale) => { const pathsToJoin = [base, prependWith]; const normalizedLocale = normalizeLocale ? normalizeTheLocale(locale) : locale; - if (routingStrategy === 'prefix-always') { + if (routing === 'prefix-always') { pathsToJoin.push(normalizedLocale); } else if (locale !== defaultLocale) { pathsToJoin.push(normalizedLocale); @@ -131,6 +133,45 @@ export function getLocaleAbsoluteUrlList({ site, ...rest }: GetLocaleAbsoluteUrl }); } +/** + * Given a locale (code), it returns its corresponding path + * @param locale + * @param locales + */ +export function getPathByLocale(locale: string, locales: Locales) { + for (const loopLocale of locales) { + if (typeof loopLocale === 'string') { + if (loopLocale === locale) { + return loopLocale; + } + } else { + for (const code of loopLocale.codes) { + if (code === locale) { + return loopLocale.path; + } + } + } + } +} + +/** + * An utility function that retrieves the preferred locale that correspond to a path. + * + * @param locale + * @param locales + */ +export function getLocaleByPath(path: string, locales: Locales): string | undefined { + for (const locale of locales) { + if (typeof locale !== 'string') { + // the first code is the one that user usually wants + const code = locale.codes.at(0); + return code; + } + 1; + } + return undefined; +} + /** * * Given a locale, this function: @@ -140,3 +181,53 @@ export function getLocaleAbsoluteUrlList({ site, ...rest }: GetLocaleAbsoluteUrl export function normalizeTheLocale(locale: string): string { return locale.replaceAll('_', '-').toLowerCase(); } + +/** + * Returns an array of only locales, by picking the `code` + * @param locales + */ +export function toCodes(locales: Locales): string[] { + const codes: string[] = []; + for (const locale of locales) { + if (typeof locale === 'string') { + codes.push(locale); + } else { + for (const code of locale.codes) { + codes.push(code); + } + } + } + return codes; +} + +/** + * It returns the array of paths + * @param locales + */ +export function toPaths(locales: Locales): string[] { + return locales.map((loopLocale) => { + if (typeof loopLocale === 'string') { + return loopLocale; + } else { + return loopLocale.path; + } + }); +} + +function peekCodePathToUse(locales: Locales, locale: string): undefined | string { + for (const loopLocale of locales) { + if (typeof loopLocale === 'string') { + if (loopLocale === locale) { + return loopLocale; + } + } else { + for (const code of loopLocale.codes) { + if (code === locale) { + return loopLocale.path; + } + } + } + } + + return undefined; +} diff --git a/packages/astro/src/i18n/middleware.ts b/packages/astro/src/i18n/middleware.ts index 854a39b77cda3..12732d880eb02 100644 --- a/packages/astro/src/i18n/middleware.ts +++ b/packages/astro/src/i18n/middleware.ts @@ -1,25 +1,33 @@ import { appendForwardSlash, joinPaths } from '@astrojs/internal-helpers/path'; -import type { MiddlewareEndpointHandler, RouteData, SSRManifest } from '../@types/astro.js'; +import type { Locales, MiddlewareHandler, RouteData, SSRManifest } from '../@types/astro.js'; import type { PipelineHookFunction } from '../core/pipeline.js'; +import { getPathByLocale, normalizeTheLocale } from './index.js'; const routeDataSymbol = Symbol.for('astro.routeData'); -// Checks if the pathname doesn't have any locale, exception for the defaultLocale, which is ignored on purpose -function checkIsLocaleFree(pathname: string, locales: string[]): boolean { - for (const locale of locales) { - if (pathname.includes(`/${locale}`)) { - return false; +// Checks if the pathname has any locale, exception for the defaultLocale, which is ignored on purpose. +function pathnameHasLocale(pathname: string, locales: Locales): boolean { + const segments = pathname.split('/'); + for (const segment of segments) { + for (const locale of locales) { + if (typeof locale === 'string') { + if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) { + return true; + } + } else if (segment === locale.path) { + return true; + } } } - return true; + return false; } export function createI18nMiddleware( i18n: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'] -): MiddlewareEndpointHandler | undefined { +): MiddlewareHandler | undefined { if (!i18n) { return undefined; } @@ -41,21 +49,19 @@ export function createI18nMiddleware( } const url = context.url; - const { locales, defaultLocale, fallback } = i18n; + const { locales, defaultLocale, fallback, routing } = i18n; const response = await next(); if (response instanceof Response) { - const separators = url.pathname.split('/'); const pathnameContainsDefaultLocale = url.pathname.includes(`/${defaultLocale}`); - const isLocaleFree = checkIsLocaleFree(url.pathname, i18n.locales); - if (i18n.routingStrategy === 'prefix-other-locales' && pathnameContainsDefaultLocale) { + if (i18n.routing === 'prefix-other-locales' && pathnameContainsDefaultLocale) { const newLocation = url.pathname.replace(`/${defaultLocale}`, ''); response.headers.set('Location', newLocation); return new Response(null, { status: 404, headers: response.headers, }); - } else if (i18n.routingStrategy === 'prefix-always') { + } else if (i18n.routing === 'prefix-always') { if (url.pathname === base + '/' || url.pathname === base) { if (trailingSlash === 'always') { return context.redirect(`${appendForwardSlash(joinPaths(base, i18n.defaultLocale))}`); @@ -65,7 +71,7 @@ export function createI18nMiddleware( } // Astro can't know where the default locale is supposed to be, so it returns a 404 with no content. - else if (isLocaleFree) { + else if (!pathnameHasLocale(url.pathname, i18n.locales)) { return new Response(null, { status: 404, headers: response.headers, @@ -75,17 +81,32 @@ export function createI18nMiddleware( if (response.status >= 300 && fallback) { const fallbackKeys = i18n.fallback ? Object.keys(i18n.fallback) : []; - const urlLocale = separators.find((s) => locales.includes(s)); + // we split the URL using the `/`, and then check in the returned array we have the locale + const segments = url.pathname.split('/'); + const urlLocale = segments.find((segment) => { + for (const locale of locales) { + if (typeof locale === 'string') { + if (locale === segment) { + return true; + } + } else if (locale.path === segment) { + return true; + } + } + return false; + }); if (urlLocale && fallbackKeys.includes(urlLocale)) { const fallbackLocale = fallback[urlLocale]; + // the user might have configured the locale using the granular locales, so we want to retrieve its corresponding path instead + const pathFallbackLocale = getPathByLocale(fallbackLocale, locales); let newPathname: string; // If a locale falls back to the default locale, we want to **remove** the locale because // the default locale doesn't have a prefix - if (fallbackLocale === defaultLocale) { + if (pathFallbackLocale === defaultLocale && routing === 'prefix-other-locales') { newPathname = url.pathname.replace(`/${urlLocale}`, ``); } else { - newPathname = url.pathname.replace(`/${urlLocale}`, `/${fallbackLocale}`); + newPathname = url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); } return context.redirect(newPathname); diff --git a/packages/astro/src/i18n/vite-plugin-i18n.ts b/packages/astro/src/i18n/vite-plugin-i18n.ts index 4aa6ee42e4f52..cd4c3f854bd3b 100644 --- a/packages/astro/src/i18n/vite-plugin-i18n.ts +++ b/packages/astro/src/i18n/vite-plugin-i18n.ts @@ -1,4 +1,4 @@ -import * as vite from 'vite'; +import type * as vite from 'vite'; import type { AstroSettings } from '../@types/astro.js'; const virtualModuleId = 'astro:i18n'; @@ -27,14 +27,15 @@ export default function astroInternationalization({ getLocaleRelativeUrlList as _getLocaleRelativeUrlList, getLocaleAbsoluteUrl as _getLocaleAbsoluteUrl, getLocaleAbsoluteUrlList as _getLocaleAbsoluteUrlList, - - } from "astro/i18n"; + getPathByLocale as _getPathByLocale, + getLocaleByPath as _getLocaleByPath, + } from "astro/virtual-modules/i18n.js"; const base = ${JSON.stringify(settings.config.base)}; const trailingSlash = ${JSON.stringify(settings.config.trailingSlash)}; const format = ${JSON.stringify(settings.config.build.format)}; const site = ${JSON.stringify(settings.config.site)}; - const i18n = ${JSON.stringify(settings.config.experimental.i18n)}; + const i18n = ${JSON.stringify(settings.config.i18n)}; export const getRelativeLocaleUrl = (locale, path = "", opts) => _getLocaleRelativeUrl({ locale, @@ -59,6 +60,9 @@ export default function astroInternationalization({ export const getRelativeLocaleUrlList = (path = "", opts) => _getLocaleRelativeUrlList({ base, path, trailingSlash, format, ...i18n, ...opts }); export const getAbsoluteLocaleUrlList = (path = "", opts) => _getLocaleAbsoluteUrlList({ base, path, trailingSlash, format, site, ...i18n, ...opts }); + + export const getPathByLocale = (locale) => _getPathByLocale(locale, i18n.locales); + export const getLocaleByPath = (locale) => _getLocaleByPath(locale, i18n.locales); `; } }, diff --git a/packages/astro/src/integrations/astroFeaturesValidation.ts b/packages/astro/src/integrations/astroFeaturesValidation.ts index a26f42afbe4c0..8bae77846c290 100644 --- a/packages/astro/src/integrations/astroFeaturesValidation.ts +++ b/packages/astro/src/integrations/astroFeaturesValidation.ts @@ -17,17 +17,6 @@ const UNSUPPORTED_ASSETS_FEATURE: AstroAssetsFeature = { isSharpCompatible: false, }; -// NOTE: remove for Astro 4.0 -const ALL_UNSUPPORTED: Required<AstroFeatureMap> = { - serverOutput: UNSUPPORTED, - staticOutput: UNSUPPORTED, - hybridOutput: UNSUPPORTED, - assets: UNSUPPORTED_ASSETS_FEATURE, - i18n: { - detectBrowserLanguage: UNSUPPORTED, - }, -}; - type ValidationResult = { [Property in keyof AstroFeatureMap]: boolean; }; @@ -41,7 +30,7 @@ type ValidationResult = { */ export function validateSupportedFeatures( adapterName: string, - featureMap: AstroFeatureMap = ALL_UNSUPPORTED, + featureMap: AstroFeatureMap, config: AstroConfig, logger: Logger ): ValidationResult { @@ -91,9 +80,9 @@ function validateSupportKind( if (supportKind === STABLE) { return true; } else if (supportKind === DEPRECATED) { - featureIsDeprecated(adapterName, logger); + featureIsDeprecated(adapterName, logger, featureName); } else if (supportKind === EXPERIMENTAL) { - featureIsExperimental(adapterName, logger); + featureIsExperimental(adapterName, logger, featureName); } if (hasCorrectConfig() && supportKind === UNSUPPORTED) { @@ -105,18 +94,21 @@ function validateSupportKind( } function featureIsUnsupported(adapterName: string, logger: Logger, featureName: string) { - logger.error( - `${adapterName}`, - `The feature ${featureName} is not supported by the adapter ${adapterName}.` - ); + logger.error('config', `The feature "${featureName}" is not supported (used by ${adapterName}).`); } -function featureIsExperimental(adapterName: string, logger: Logger) { - logger.warn(`${adapterName}`, 'The feature is experimental and subject to issues or changes.'); +function featureIsExperimental(adapterName: string, logger: Logger, featureName: string) { + logger.warn( + 'config', + `The feature "${featureName}" is experimental and subject to change (used by ${adapterName}).` + ); } -function featureIsDeprecated(adapterName: string, logger: Logger) { - logger.warn(`${adapterName}`, 'The feature is deprecated and will be moved in the next release.'); +function featureIsDeprecated(adapterName: string, logger: Logger, featureName: string) { + logger.warn( + 'config', + `The feature "${featureName}" is deprecated and will be removed in the future (used by ${adapterName}).` + ); } const SHARP_SERVICE = 'astro/assets/services/sharp'; @@ -135,7 +127,7 @@ function validateAssetsFeature( } = assets; if (config?.image?.service?.entrypoint === SHARP_SERVICE && !isSharpCompatible) { logger.warn( - 'astro', + null, `The currently selected adapter \`${adapterName}\` is not compatible with the image service "Sharp".` ); return false; @@ -143,7 +135,7 @@ function validateAssetsFeature( if (config?.image?.service?.entrypoint === SQUOOSH_SERVICE && !isSquooshCompatible) { logger.warn( - 'astro', + null, `The currently selected adapter \`${adapterName}\` is not compatible with the image service "Squoosh".` ); return false; diff --git a/packages/astro/src/integrations/index.ts b/packages/astro/src/integrations/index.ts index 8b40e5825fdb3..d082c438fbaa5 100644 --- a/packages/astro/src/integrations/index.ts +++ b/packages/astro/src/integrations/index.ts @@ -18,23 +18,30 @@ import type { SerializedSSRManifest } from '../core/app/types.js'; import type { PageBuildData } from '../core/build/types.js'; import { buildClientDirectiveEntrypoint } from '../core/client-directive/index.js'; import { mergeConfig } from '../core/config/index.js'; -import { AstroIntegrationLogger, type Logger } from '../core/logger/core.js'; +import type { AstroIntegrationLogger, Logger } from '../core/logger/core.js'; import { isServerLikeOutput } from '../prerender/utils.js'; import { validateSupportedFeatures } from './astroFeaturesValidation.js'; async function withTakingALongTimeMsg<T>({ name, + hookName, hookResult, timeoutMs = 3000, logger, }: { name: string; + hookName: string; hookResult: T | Promise<T>; timeoutMs?: number; logger: Logger; }): Promise<T> { const timeout = setTimeout(() => { - logger.info('build', `Waiting for the ${bold(name)} integration...`); + logger.info( + 'build', + `Waiting for integration ${bold(JSON.stringify(name))}, hook ${bold( + JSON.stringify(hookName) + )}...` + ); }, timeoutMs); const result = await hookResult; clearTimeout(timeout); @@ -118,15 +125,27 @@ export async function runHookConfigSetup({ }, updateConfig: (newConfig) => { updatedConfig = mergeConfig(updatedConfig, newConfig) as AstroConfig; + return { ...updatedConfig }; }, injectRoute: (injectRoute) => { + if (injectRoute.entrypoint == null && 'entryPoint' in injectRoute) { + logger.warn( + null, + `The injected route "${injectRoute.pattern}" by ${integration.name} specifies the entry point with the "entryPoint" property. This property is deprecated, please use "entrypoint" instead.` + ); + injectRoute.entrypoint = injectRoute.entryPoint as string; + } updatedSettings.injectedRoutes.push(injectRoute); }, addWatchFile: (path) => { updatedSettings.watchFiles.push(path instanceof URL ? fileURLToPath(path) : path); }, addDevOverlayPlugin: (entrypoint) => { - updatedSettings.devOverlayPlugins.push(entrypoint); + // TODO add a deprecation warning in Astro 5. + hooks.addDevToolbarApp(entrypoint); + }, + addDevToolbarApp: (entrypoint) => { + updatedSettings.devToolbarApps.push(entrypoint); }, addClientDirective: ({ name, entrypoint }) => { if (updatedSettings.clientDirectives.has(name) || addedClientDirectives.has(name)) { @@ -188,6 +207,7 @@ export async function runHookConfigSetup({ await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:config:setup', hookResult: integration.hooks['astro:config:setup'](hooks), logger, }); @@ -219,6 +239,7 @@ export async function runHookConfigDone({ if (integration?.hooks?.['astro:config:done']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:config:done', hookResult: integration.hooks['astro:config:done']({ config: settings.config, setAdapter(adapter) { @@ -228,10 +249,8 @@ export async function runHookConfigDone({ ); } if (!adapter.supportedAstroFeatures) { - // NOTE: throw an error in Astro 4.0 - logger.warn( - 'astro', - `The adapter ${adapter.name} doesn't provide a feature map. From Astro 3.0, an adapter can provide a feature map. Not providing a feature map will cause an error in Astro 4.0.` + throw new Error( + `The adapter ${adapter.name} doesn't provide a feature map. It is required in Astro 4.0.` ); } else { const validationResult = validateSupportedFeatures( @@ -247,7 +266,7 @@ export async function runHookConfigDone({ // if we would refactor the validation to support more than boolean, we could still be able to differentiate between the two cases if (!supported && featureName !== 'assets') { logger.error( - 'astro', + null, `The adapter ${adapter.name} doesn't support the feature ${featureName}. Your project won't be built. You should not use it.` ); } @@ -276,6 +295,7 @@ export async function runHookServerSetup({ if (integration?.hooks?.['astro:server:setup']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:server:setup', hookResult: integration.hooks['astro:server:setup']({ server, logger: getLogger(integration, logger), @@ -299,6 +319,7 @@ export async function runHookServerStart({ if (integration?.hooks?.['astro:server:start']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:server:start', hookResult: integration.hooks['astro:server:start']({ address, logger: getLogger(integration, logger), @@ -320,6 +341,7 @@ export async function runHookServerDone({ if (integration?.hooks?.['astro:server:done']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:server:done', hookResult: integration.hooks['astro:server:done']({ logger: getLogger(integration, logger), }), @@ -342,6 +364,7 @@ export async function runHookBuildStart({ await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:build:start', hookResult: integration.hooks['astro:build:start']({ logger }), logger: logging, }); @@ -368,12 +391,14 @@ export async function runHookBuildSetup({ if (integration?.hooks?.['astro:build:setup']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:build:setup', hookResult: integration.hooks['astro:build:setup']({ vite, pages, target, updateConfig: (newConfig) => { updatedConfig = mergeConfig(updatedConfig, newConfig); + return { ...updatedConfig }; }, logger: getLogger(integration, logger), }), @@ -404,6 +429,7 @@ export async function runHookBuildSsr({ if (integration?.hooks?.['astro:build:ssr']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:build:ssr', hookResult: integration.hooks['astro:build:ssr']({ manifest, entryPoints, @@ -429,6 +455,7 @@ export async function runHookBuildGenerated({ if (integration?.hooks?.['astro:build:generated']) { await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:build:generated', hookResult: integration.hooks['astro:build:generated']({ dir, logger: getLogger(integration, logger), @@ -456,6 +483,7 @@ export async function runHookBuildDone({ config, pages, routes, logging }: RunHo await withTakingALongTimeMsg({ name: integration.name, + hookName: 'astro:build:done', hookResult: integration.hooks['astro:build:done']({ pages: pages.map((p) => ({ pathname: p })), dir, diff --git a/packages/astro/src/preferences/README.md b/packages/astro/src/preferences/README.md new file mode 100644 index 0000000000000..4234ebac1b67b --- /dev/null +++ b/packages/astro/src/preferences/README.md @@ -0,0 +1,33 @@ +# Preferences + +The preferences module implements global and local user preferences for controlling certain Astro behavior. Whereas the `astro.config.mjs` file controls project-specific behavior for every user of a project, preferences are user-specific. + +The design of Preferences is inspired by [Git](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration) and [Visual Studio Code](https://code.visualstudio.com/docs/getstarted/settings). Both systems implement similar layering approaches with project-specific and global settings. + +## `AstroPreferences` + +The `AstroPreferences` interface exposes both a `get` and `set` function. + +### Reading a preference + +`preferences.get("dot.separated.value")` will read a preference value from multiple sources if needed. Local project preferences are read from `.astro/settings.json`, if it exists. Next, global user preferences are read from `<homedir>/<os-specific-preferences-dir>/astro/settings.json`. If neither of those are found, the default preferences defined in [`./defaults.ts`](./defaults.ts) will apply. + +In order to read a preference from a specific location, you can pass the `location: "global" | "project"` option. + +```js +await preferences.get('dot.separated.value', { location: 'global' }); +``` + +### Writing a preference + +`preferences.set("dot.separated.value", true)` will store a preference value. By default, preferences are stored locally in a project. + +In order to set a global user preference, you can pass the `location: "global"` option. + +```js +await preferences.set('dot.separated.value', 'value', { location: 'global' }); +``` + +## Relation to Telemetry + +This module evolved from the existing `@astrojs/telemetry` package, but has been generalized for user-facing `astro` preferences. At some point, we'll need to merge the logic in `@astrojs/telemetry` and the logic in this module so that all preferences are stored in the same location. diff --git a/packages/astro/src/preferences/defaults.ts b/packages/astro/src/preferences/defaults.ts new file mode 100644 index 0000000000000..f1c4d78135cbb --- /dev/null +++ b/packages/astro/src/preferences/defaults.ts @@ -0,0 +1,8 @@ +export const DEFAULT_PREFERENCES = { + devToolbar: { + /** Specifies whether the user has the Dev Overlay enabled */ + enabled: true, + }, +}; + +export type Preferences = typeof DEFAULT_PREFERENCES; diff --git a/packages/astro/src/preferences/index.ts b/packages/astro/src/preferences/index.ts new file mode 100644 index 0000000000000..ee50261158bc4 --- /dev/null +++ b/packages/astro/src/preferences/index.ts @@ -0,0 +1,125 @@ +import type { AstroConfig } from '../@types/astro.js'; + +import os from 'node:os'; +import path from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; + +import dget from 'dlv'; +import { DEFAULT_PREFERENCES, type Preferences } from './defaults.js'; +import { PreferenceStore } from './store.js'; + +type DotKeys<T> = T extends object + ? { + [K in keyof T]: `${Exclude<K, symbol>}${DotKeys<T[K]> extends never + ? '' + : `.${DotKeys<T[K]>}`}`; + }[keyof T] + : never; + +export type GetDotKey< + T extends Record<string | number, any>, + K extends string, +> = K extends `${infer U}.${infer Rest}` ? GetDotKey<T[U], Rest> : T[K]; + +export type PreferenceLocation = 'global' | 'project'; +export interface PreferenceOptions { + location?: PreferenceLocation; +} + +type DeepPartial<T> = T extends object + ? { + [P in keyof T]?: DeepPartial<T[P]>; + } + : T; + +export type PreferenceKey = DotKeys<Preferences>; +export interface PreferenceList extends Record<PreferenceLocation, DeepPartial<Preferences>> { + defaults: Preferences; +} + +export interface AstroPreferences { + get<Key extends PreferenceKey>( + key: Key, + opts?: PreferenceOptions + ): Promise<GetDotKey<Preferences, Key>>; + set<Key extends PreferenceKey>( + key: Key, + value: GetDotKey<Preferences, Key>, + opts?: PreferenceOptions + ): Promise<void>; + getAll(): Promise<Preferences>; + list(opts?: PreferenceOptions): Promise<PreferenceList>; +} + +export function isValidKey(key: string): key is PreferenceKey { + return dget(DEFAULT_PREFERENCES, key) !== undefined; +} +export function coerce(key: string, value: unknown) { + const type = typeof dget(DEFAULT_PREFERENCES, key); + switch (type) { + case 'string': + return value; + case 'number': + return Number(value); + case 'boolean': { + if (value === 'true' || value === 1) return true; + if (value === 'false' || value === 0) return false; + } + } + return value as any; +} + +export default function createPreferences(config: AstroConfig): AstroPreferences { + const global = new PreferenceStore(getGlobalPreferenceDir()); + const project = new PreferenceStore(fileURLToPath(new URL('./.astro/', config.root))); + const stores: Record<PreferenceLocation, PreferenceStore> = { global, project }; + + return { + async get(key, { location } = {}) { + if (!location) return project.get(key) ?? global.get(key) ?? dget(DEFAULT_PREFERENCES, key); + return stores[location].get(key); + }, + async set(key, value, { location = 'project' } = {}) { + stores[location].set(key, value); + }, + async getAll() { + return Object.assign( + {}, + DEFAULT_PREFERENCES, + stores['global'].getAll(), + stores['project'].getAll() + ); + }, + async list() { + return { + global: stores['global'].getAll(), + project: stores['project'].getAll(), + defaults: DEFAULT_PREFERENCES, + }; + }, + }; +} + +// Adapted from https://github.com/sindresorhus/env-paths +export function getGlobalPreferenceDir() { + const name = 'astro'; + const homedir = os.homedir(); + const macos = () => path.join(homedir, 'Library', 'Preferences', name); + const win = () => { + const { APPDATA = path.join(homedir, 'AppData', 'Roaming') } = process.env; + return path.join(APPDATA, name, 'Config'); + }; + const linux = () => { + const { XDG_CONFIG_HOME = path.join(homedir, '.config') } = process.env; + return path.join(XDG_CONFIG_HOME, name); + }; + switch (process.platform) { + case 'darwin': + return macos(); + case 'win32': + return win(); + default: + return linux(); + } +} diff --git a/packages/astro/src/preferences/store.ts b/packages/astro/src/preferences/store.ts new file mode 100644 index 0000000000000..1bf9c46c70df5 --- /dev/null +++ b/packages/astro/src/preferences/store.ts @@ -0,0 +1,62 @@ +import dget from 'dlv'; +import { dset } from 'dset'; +import fs from 'node:fs'; +import path from 'node:path'; + +export class PreferenceStore { + private file: string; + + constructor( + private dir: string, + filename = 'settings.json' + ) { + this.file = path.join(this.dir, filename); + } + + private _store?: Record<string, any>; + private get store(): Record<string, any> { + if (this._store) return this._store; + if (fs.existsSync(this.file)) { + try { + this._store = JSON.parse(fs.readFileSync(this.file).toString()); + } catch {} + } + if (!this._store) { + this._store = {}; + this.write(); + } + return this._store; + } + private set store(value: Record<string, any>) { + this._store = value; + this.write(); + } + write() { + if (!this._store || Object.keys(this._store).length === 0) return; + fs.mkdirSync(this.dir, { recursive: true }); + fs.writeFileSync(this.file, JSON.stringify(this.store, null, '\t')); + } + clear(): void { + this.store = {}; + fs.rmSync(this.file, { recursive: true }); + } + delete(key: string): boolean { + dset(this.store, key, undefined); + this.write(); + return true; + } + get(key: string): any { + return dget(this.store, key); + } + has(key: string): boolean { + return typeof this.get(key) !== 'undefined'; + } + set(key: string, value: any): void { + if (this.get(key) === value) return; + dset(this.store, key, value); + this.write(); + } + getAll(): Record<string, any> { + return this.store; + } +} diff --git a/packages/astro/src/prefetch/index.ts b/packages/astro/src/prefetch/index.ts index f47cff0606f98..15f4ef0ccd952 100644 --- a/packages/astro/src/prefetch/index.ts +++ b/packages/astro/src/prefetch/index.ts @@ -56,7 +56,7 @@ function initTapStrategy() { event, (e) => { if (elMatchesStrategy(e.target, 'tap')) { - prefetch(e.target.href, { with: 'fetch' }); + prefetch(e.target.href, { with: 'fetch', ignoreSlowConnection: true }); } }, { passive: true } @@ -176,6 +176,10 @@ export interface PrefetchOptions { * - `'fetch'`: use `fetch()`, has higher loading priority. */ with?: 'link' | 'fetch'; + /** + * Should prefetch even on data saver mode or slow connection. (default `false`) + */ + ignoreSlowConnection?: boolean; } /** @@ -190,7 +194,8 @@ export interface PrefetchOptions { * @param opts Additional options for prefetching. */ export function prefetch(url: string, opts?: PrefetchOptions) { - if (!canPrefetchUrl(url)) return; + const ignoreSlowConnection = opts?.ignoreSlowConnection ?? false; + if (!canPrefetchUrl(url, ignoreSlowConnection)) return; prefetchedUrls.add(url); const priority = opts?.with ?? 'link'; @@ -211,21 +216,17 @@ export function prefetch(url: string, opts?: PrefetchOptions) { } } -function canPrefetchUrl(url: string) { +function canPrefetchUrl(url: string, ignoreSlowConnection: boolean) { // Skip prefetch if offline if (!navigator.onLine) return false; - if ('connection' in navigator) { - // Untyped Chrome-only feature: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection - const conn = navigator.connection as any; - // Skip prefetch if using data saver mode or slow connection - if (conn.saveData || /(2|3)g/.test(conn.effectiveType)) return false; - } + // Skip prefetch if using data saver mode or slow connection + if (!ignoreSlowConnection && isSlowConnection()) return false; // Else check if URL is within the same origin, not the current page, and not already prefetched try { const urlObj = new URL(url, location.href); return ( location.origin === urlObj.origin && - location.pathname !== urlObj.pathname && + (location.pathname !== urlObj.pathname || location.search !== urlObj.search) && !prefetchedUrls.has(url) ); } catch {} @@ -241,6 +242,12 @@ function elMatchesStrategy(el: EventTarget | null, strategy: string): el is HTML if (attrValue === 'false') { return false; } + + // Fallback to tap strategy if using data saver mode or slow connection + if (strategy === 'tap' && (attrValue != null || prefetchAll) && isSlowConnection()) { + return true; + } + // If anchor has no dataset but we want to prefetch all, or has dataset but no value, // check against fallback default strategy if ((attrValue == null && prefetchAll) || attrValue === '') { @@ -254,6 +261,15 @@ function elMatchesStrategy(el: EventTarget | null, strategy: string): el is HTML return false; } +function isSlowConnection() { + if ('connection' in navigator) { + // Untyped Chrome-only feature: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection + const conn = navigator.connection as any; + return conn.saveData || /(2|3)g/.test(conn.effectiveType); + } + return false; +} + /** * Listen to page loads and handle Astro's View Transition specific events */ diff --git a/packages/astro/src/prefetch/vite-plugin-prefetch.ts b/packages/astro/src/prefetch/vite-plugin-prefetch.ts index 73ae53f63b53b..83c3c3ff7c592 100644 --- a/packages/astro/src/prefetch/vite-plugin-prefetch.ts +++ b/packages/astro/src/prefetch/vite-plugin-prefetch.ts @@ -1,10 +1,10 @@ -import * as vite from 'vite'; +import type * as vite from 'vite'; import type { AstroSettings } from '../@types/astro.js'; const virtualModuleId = 'astro:prefetch'; const resolvedVirtualModuleId = '\0' + virtualModuleId; const prefetchInternalModuleFsSubpath = 'astro/dist/prefetch/index.js'; -const prefetchCode = `import { init } from 'astro/prefetch';init()`; +const prefetchCode = `import { init } from 'astro/virtual-modules/prefetch.js';init()`; export default function astroPrefetch({ settings }: { settings: AstroSettings }): vite.Plugin { const prefetchOption = settings.config.prefetch; @@ -19,7 +19,7 @@ export default function astroPrefetch({ settings }: { settings: AstroSettings }) // Inject prefetch script to all pages settings.scripts.push({ stage: 'page', - content: `import { init } from 'astro/prefetch';init()`, + content: `import { init } from 'astro/virtual-modules/prefetch.js';init()`, }); } @@ -40,7 +40,7 @@ export default function astroPrefetch({ settings }: { settings: AstroSettings }) load(id) { if (id === resolvedVirtualModuleId) { if (!prefetch) throwPrefetchNotEnabledError(); - return `export { prefetch } from "astro/prefetch";`; + return `export { prefetch } from "astro/virtual-modules/prefetch.js";`; } }, transform(code, id) { diff --git a/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts b/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts index 65e50c98e03ef..fa3020b03c980 100644 --- a/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts +++ b/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts @@ -1,51 +1,65 @@ import type { DevOverlayPlugin as DevOverlayPluginDefinition } from '../../../@types/astro.js'; -import { type AstroDevOverlay, type DevOverlayPlugin } from './overlay.js'; - +import type { AstroDevOverlay, DevOverlayPlugin } from './overlay.js'; import { settings } from './settings.js'; -import type { Icon } from './ui-library/icons.js'; +// @ts-expect-error +import { loadDevOverlayPlugins } from 'astro:dev-overlay'; let overlay: AstroDevOverlay; document.addEventListener('DOMContentLoaded', async () => { const [ - { loadDevOverlayPlugins }, + customPluginsDefinitions, { default: astroDevToolPlugin }, { default: astroAuditPlugin }, { default: astroXrayPlugin }, { default: astroSettingsPlugin }, - { AstroDevOverlay, DevOverlayCanvas }, - { DevOverlayCard }, - { DevOverlayHighlight }, - { DevOverlayTooltip }, - { DevOverlayWindow }, - { DevOverlayToggle }, - { getIconElement, isDefinedIcon }, + { AstroDevOverlay, DevOverlayCanvas, getPluginIcon }, + { + DevOverlayCard, + DevOverlayHighlight, + DevOverlayTooltip, + DevOverlayWindow, + DevOverlayToggle, + DevOverlayButton, + DevOverlayBadge, + DevOverlayIcon, + }, ] = await Promise.all([ - // @ts-expect-error - import('astro:dev-overlay'), + loadDevOverlayPlugins() as DevOverlayPluginDefinition[], import('./plugins/astro.js'), - import('./plugins/audit.js'), + import('./plugins/audit/index.js'), import('./plugins/xray.js'), import('./plugins/settings.js'), import('./overlay.js'), - import('./ui-library/card.js'), - import('./ui-library/highlight.js'), - import('./ui-library/tooltip.js'), - import('./ui-library/window.js'), - import('./ui-library/toggle.js'), - import('./ui-library/icons.js'), + import('./ui-library/index.js'), ]); // Register custom elements - customElements.define('astro-dev-overlay', AstroDevOverlay); - customElements.define('astro-dev-overlay-window', DevOverlayWindow); - customElements.define('astro-dev-overlay-plugin-canvas', DevOverlayCanvas); - customElements.define('astro-dev-overlay-tooltip', DevOverlayTooltip); - customElements.define('astro-dev-overlay-highlight', DevOverlayHighlight); - customElements.define('astro-dev-overlay-card', DevOverlayCard); - customElements.define('astro-dev-overlay-toggle', DevOverlayToggle); - - overlay = document.createElement('astro-dev-overlay'); + customElements.define('astro-dev-toolbar', AstroDevOverlay); + customElements.define('astro-dev-toolbar-window', DevOverlayWindow); + customElements.define('astro-dev-toolbar-plugin-canvas', DevOverlayCanvas); + customElements.define('astro-dev-toolbar-tooltip', DevOverlayTooltip); + customElements.define('astro-dev-toolbar-highlight', DevOverlayHighlight); + customElements.define('astro-dev-toolbar-card', DevOverlayCard); + customElements.define('astro-dev-toolbar-toggle', DevOverlayToggle); + customElements.define('astro-dev-toolbar-button', DevOverlayButton); + customElements.define('astro-dev-toolbar-badge', DevOverlayBadge); + customElements.define('astro-dev-toolbar-icon', DevOverlayIcon); + + // Add deprecated names + const deprecated = (Parent: any) => class extends Parent {}; + customElements.define('astro-dev-overlay', deprecated(AstroDevOverlay)); + customElements.define('astro-dev-overlay-window', deprecated(DevOverlayWindow)); + customElements.define('astro-dev-overlay-plugin-canvas', deprecated(DevOverlayCanvas)); + customElements.define('astro-dev-overlay-tooltip', deprecated(DevOverlayTooltip)); + customElements.define('astro-dev-overlay-highlight', deprecated(DevOverlayHighlight)); + customElements.define('astro-dev-overlay-card', deprecated(DevOverlayCard)); + customElements.define('astro-dev-overlay-toggle', deprecated(DevOverlayToggle)); + customElements.define('astro-dev-overlay-button', deprecated(DevOverlayButton)); + customElements.define('astro-dev-overlay-badge', deprecated(DevOverlayBadge)); + customElements.define('astro-dev-overlay-icon', deprecated(DevOverlayIcon)); + + overlay = document.createElement('astro-dev-toolbar'); const preparePlugin = ( pluginDefinition: DevOverlayPluginDefinition, @@ -73,19 +87,21 @@ document.addEventListener('DOMContentLoaded', async () => { plugin.notification.state = newState; - if (settings.config.disablePluginNotification === false) { - target.querySelector('.notification')?.toggleAttribute('data-active', newState); - } + target.querySelector('.notification')?.toggleAttribute('data-active', newState); }); - eventTarget.addEventListener('toggle-plugin', async (evt) => { + const onToggleApp = async (evt: Event) => { let newState = undefined; if (evt instanceof CustomEvent) { newState = evt.detail.state ?? true; } - await overlay.togglePluginStatus(plugin, newState); - }); + await overlay.setPluginStatus(plugin, newState); + }; + + eventTarget.addEventListener('toggle-app', onToggleApp); + // Deprecated + eventTarget.addEventListener('toggle-plugin', onToggleApp); return plugin; }; @@ -109,9 +125,13 @@ document.addEventListener('DOMContentLoaded', async () => { border: 1px solid rgba(52, 56, 65, 1); border-radius: 12px; box-shadow: 0px 0px 0px 0px rgba(19, 21, 26, 0.30), 0px 1px 2px 0px rgba(19, 21, 26, 0.29), 0px 4px 4px 0px rgba(19, 21, 26, 0.26), 0px 10px 6px 0px rgba(19, 21, 26, 0.15), 0px 17px 7px 0px rgba(19, 21, 26, 0.04), 0px 26px 7px 0px rgba(19, 21, 26, 0.01); - width: 180px; + width: 192px; padding: 8px; - z-index: 9999999999; + z-index: 2000000010; + transform: translate(-50%, 0%); + position: fixed; + bottom: 72px; + left: 50%; } .notification { @@ -126,7 +146,7 @@ document.addEventListener('DOMContentLoaded', async () => { background: #B33E66; } - .notification[data-active] { + #dropdown:not([data-no-notification]) .notification[data-active] { display: block; } @@ -135,20 +155,19 @@ document.addEventListener('DOMContentLoaded', async () => { background: transparent; color: white; font-family: system-ui, sans-serif; - font-size: 16px; - line-height: 1.2; + font-size: 14px; white-space: nowrap; text-decoration: none; margin: 0; display: flex; - align-items: center; + align-items: center; width: 100%; padding: 8px; border-radius: 8px; } #dropdown button:hover, #dropdown button:focus-visible { - background: rgba(27, 30, 36, 1); + background: #FFFFFF20; cursor: pointer; } @@ -158,8 +177,9 @@ document.addEventListener('DOMContentLoaded', async () => { #dropdown .icon { position: relative; - height: 24px; - width: 24px; + height: 20px; + width: 20px; + padding: 1px; margin-right: 0.5em; } @@ -172,6 +192,7 @@ document.addEventListener('DOMContentLoaded', async () => { const dropdown = document.createElement('div'); dropdown.id = 'dropdown'; + dropdown.toggleAttribute('data-no-notification', settings.config.disablePluginNotification); for (const plugin of hiddenPlugins) { const buttonContainer = document.createElement('div'); @@ -180,8 +201,9 @@ document.addEventListener('DOMContentLoaded', async () => { button.setAttribute('data-plugin-id', plugin.id); const iconContainer = document.createElement('div'); - const iconElement = getPluginIcon(plugin.icon); - iconContainer.append(iconElement); + const iconElement = document.createElement('template'); + iconElement.innerHTML = getPluginIcon(plugin.icon); + iconContainer.append(iconElement.content.cloneNode(true)); const notification = document.createElement('div'); notification.classList.add('notification'); @@ -198,15 +220,10 @@ document.addEventListener('DOMContentLoaded', async () => { dropdown.append(buttonContainer); - eventTarget.addEventListener('plugin-toggled', positionDropdown); - window.addEventListener('resize', positionDropdown); - plugin.eventTarget.addEventListener('toggle-notification', (evt) => { if (!(evt instanceof CustomEvent)) return; - if (settings.config.disablePluginNotification === false) { - notification.toggleAttribute('data-active', evt.detail.state ?? true); - } + notification.toggleAttribute('data-active', evt.detail.state ?? true); eventTarget.dispatchEvent( new CustomEvent('toggle-notification', { @@ -219,34 +236,10 @@ document.addEventListener('DOMContentLoaded', async () => { } canvas.append(dropdown); - - function getPluginIcon(icon: Icon) { - if (isDefinedIcon(icon)) { - return getIconElement(icon)!; - } - - return icon; - } - - function positionDropdown() { - const moreButtonRect = overlay.shadowRoot - .querySelector('[data-plugin-id="astro:more"]') - ?.getBoundingClientRect(); - const dropdownRect = dropdown.getBoundingClientRect(); - - if (moreButtonRect && dropdownRect) { - dropdown.style.position = 'absolute'; - dropdown.style.top = `${moreButtonRect.top - dropdownRect.height - 12}px`; - dropdown.style.left = `${ - moreButtonRect.left + moreButtonRect.width - dropdownRect.width - }px`; - } - } } }, } satisfies DevOverlayPluginDefinition; - const customPluginsDefinitions = (await loadDevOverlayPlugins()) as DevOverlayPluginDefinition[]; const plugins: DevOverlayPlugin[] = [ ...[ astroDevToolPlugin, diff --git a/packages/astro/src/runtime/client/dev-overlay/overlay.ts b/packages/astro/src/runtime/client/dev-overlay/overlay.ts index 900c3fb0fe608..48241ded9f774 100644 --- a/packages/astro/src/runtime/client/dev-overlay/overlay.ts +++ b/packages/astro/src/runtime/client/dev-overlay/overlay.ts @@ -1,5 +1,8 @@ /* eslint-disable no-console */ -import type { DevOverlayPlugin as DevOverlayPluginDefinition } from '../../../@types/astro.js'; +import type { + DevOverlayMetadata, + DevOverlayPlugin as DevOverlayPluginDefinition, +} from '../../../@types/astro.js'; import { settings } from './settings.js'; import { getIconElement, isDefinedIcon, type Icon } from './ui-library/icons.js'; @@ -12,17 +15,17 @@ export type DevOverlayPlugin = DevOverlayPluginDefinition & { }; eventTarget: EventTarget; }; - -const WS_EVENT_NAME = 'astro-dev-overlay'; +const WS_EVENT_NAME = 'astro-dev-toolbar'; +const WS_EVENT_NAME_DEPRECATED = 'astro-dev-overlay'; +const HOVER_DELAY = 2 * 1000; export class AstroDevOverlay extends HTMLElement { shadowRoot: ShadowRoot; - hoverTimeout: number | undefined; - isHidden: () => boolean = () => this.devOverlay?.hasAttribute('data-hidden') ?? true; + delayedHideTimeout: number | undefined; devOverlay: HTMLDivElement | undefined; plugins: DevOverlayPlugin[] = []; - HOVER_DELAY = 750; hasBeenInitialized = false; + // TODO: This should be dynamic based on the screen size or at least configurable, erika - 2023-11-29 customPluginsToShow = 3; constructor() { @@ -30,31 +33,34 @@ export class AstroDevOverlay extends HTMLElement { this.shadowRoot = this.attachShadow({ mode: 'open' }); } - // Happens whenever the component is connected to the DOM - // When view transitions are enabled, this happens every time the view changes - async connectedCallback() { - if (!this.hasBeenInitialized) { - this.shadowRoot.innerHTML = ` - <style> + /** + * All one-time DOM setup runs through here. Only ever call this once, + * in connectedCallback(), and protect it from being called again. + */ + init() { + this.shadowRoot.innerHTML = ` + <style> :host { + /* Important! Reset all inherited styles to initial */ + all: initial; z-index: 999999; - view-transition-name: astro-dev-overlay; + view-transition-name: astro-dev-toolbar; display: contents; } - ::view-transition-old(astro-dev-overlay), - ::view-transition-new(astro-dev-overlay) { - animation: none; + ::view-transition-old(astro-dev-toolbar), + ::view-transition-new(astro-dev-toolbar) { + animation: none; } #dev-overlay { position: fixed; - bottom: 7.5%; - left: calc(50% + 32px); + bottom: 0px; + left: 50%; transform: translate(-50%, 0%); - z-index: 9999999999; + z-index: 2000000010; display: flex; - gap: 8px; + flex-direction: column; align-items: center; transition: bottom 0.35s cubic-bezier(0.485, -0.050, 0.285, 1.505); pointer-events: none; @@ -64,17 +70,23 @@ export class AstroDevOverlay extends HTMLElement { bottom: -40px; } - #dev-overlay[data-hidden]:hover, #dev-overlay[data-hidden]:focus-within { - bottom: -35px; - cursor: pointer; + #dev-overlay[data-hidden] #dev-bar .item { + opacity: 0.2; } - #dev-overlay[data-hidden] #minimize-button { - visibility: hidden; + #dev-bar-hitbox-above, + #dev-bar-hitbox-below { + width: 100%; + pointer-events: auto; } - - #dev-bar { - height: 56px; + #dev-bar-hitbox-above { + height: 42px; + } + #dev-bar-hitbox-below { + height: 16px; + } + #dev-bar { + height: 40px; overflow: hidden; pointer-events: auto; background: linear-gradient(180deg, #13151A 0%, rgba(19, 21, 26, 0.88) 100%); @@ -83,11 +95,17 @@ export class AstroDevOverlay extends HTMLElement { box-shadow: 0px 0px 0px 0px rgba(19, 21, 26, 0.30), 0px 1px 2px 0px rgba(19, 21, 26, 0.29), 0px 4px 4px 0px rgba(19, 21, 26, 0.26), 0px 10px 6px 0px rgba(19, 21, 26, 0.15), 0px 17px 7px 0px rgba(19, 21, 26, 0.04), 0px 26px 7px 0px rgba(19, 21, 26, 0.01); } + @media (forced-colors: active) { + #dev-bar { + background: white; + } + } + #dev-bar .item { display: flex; justify-content: center; align-items: center; - width: 64px; + width: 44px; border: 0; background: transparent; color: white; @@ -99,10 +117,11 @@ export class AstroDevOverlay extends HTMLElement { padding: 0; margin: 0; overflow: hidden; + transition: opacity 0.2s ease-out 0s; } #dev-bar #bar-container .item:hover, #dev-bar #bar-container .item:focus-visible { - background: rgba(27, 30, 36, 1); + background: #FFFFFF20; cursor: pointer; outline-offset: -3px; } @@ -110,11 +129,15 @@ export class AstroDevOverlay extends HTMLElement { #dev-bar .item:first-of-type { border-top-left-radius: 9999px; border-bottom-left-radius: 9999px; + width: 42px; + padding-left: 4px; } #dev-bar .item:last-of-type { border-top-right-radius: 9999px; border-bottom-right-radius: 9999px; + width: 42px; + padding-right: 4px; } #dev-bar #bar-container .item.active { background: rgba(71, 78, 94, 1); @@ -126,7 +149,8 @@ export class AstroDevOverlay extends HTMLElement { border-radius: 4px; padding: 4px 8px; position: absolute; - top: -40px; + top: 4px; + font-size: 14px; opacity: 0; transition: opacity 0.2s ease-in-out 0s; pointer-events: none; @@ -147,24 +171,37 @@ export class AstroDevOverlay extends HTMLElement { opacity: 1; } + @media (forced-colors: active) { + #dev-bar .item:hover .item-tooltip, + #dev-bar .item:not(.active):focus-visible .item-tooltip { + background: white; + } + } + #dev-bar #bar-container .item.active .notification { border-color: rgba(71, 78, 94, 1); } #dev-bar .item .icon { position: relative; - max-width: 24px; - max-height: 24px; + max-width: 20px; + max-height: 20px; user-select: none; } #dev-bar .item svg { - width: 24px; - height: 24px; + width: 20px; + height: 20px; display: block; margin: auto; } + @media (forced-colors: active) { + #dev-bar .item svg path[fill="#fff"] { + fill: black; + } + } + #dev-bar .item .notification { display: none; position: absolute; @@ -177,7 +214,7 @@ export class AstroDevOverlay extends HTMLElement { background: #B33E66; } - #dev-bar .item .notification[data-active] { + #dev-overlay:not([data-no-notification]) #dev-bar .item .notification[data-active] { display: block; } @@ -190,53 +227,11 @@ export class AstroDevOverlay extends HTMLElement { background: rgba(52, 56, 65, 1); width: 1px; } - - #minimize-button { - width: 32px; - height: 32px; - background: rgba(255, 255, 255, 0.75); - border-radius: 9999px; - display: flex; - justify-content: center; - align-items: center; - opacity: 0; - transition: opacity 0.2s ease-in-out; - pointer-events: auto; - border: 0; - color: white; - font-family: system-ui, sans-serif; - font-size: 1rem; - line-height: 1.2; - white-space: nowrap; - text-decoration: none; - padding: 0; - margin: 0; - } - - #minimize-button:hover, #minimize-button:focus { - cursor: pointer; - background: rgba(255, 255, 255, 0.90); - } - - #minimize-button svg { - width: 16px; - height: 16px; - } - - .sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; - } - </style> - - <div id="dev-overlay"> + </style> + <div id="dev-overlay" data-hidden ${ + settings.config.disablePluginNotification ? 'data-no-notification' : '' + }> + <div id="dev-bar-hitbox-above"></div> <div id="dev-bar"> <div id="bar-container"> ${this.plugins @@ -267,135 +262,100 @@ export class AstroDevOverlay extends HTMLElement { )} </div> </div> - <button id="minimize-button">${getIconElement('arrow-down')?.outerHTML}</button> + <div id="dev-bar-hitbox-below"></div> </div>`; - this.devOverlay = this.shadowRoot.querySelector<HTMLDivElement>('#dev-overlay')!; - this.attachEvents(); - } + + this.devOverlay = this.shadowRoot.querySelector<HTMLDivElement>('#dev-overlay')!; + this.attachEvents(); // Create plugin canvases this.plugins.forEach(async (plugin) => { - if (!this.hasBeenInitialized) { - if (settings.config.verbose) console.log(`Creating plugin canvas for ${plugin.id}`); - - const pluginCanvas = document.createElement('astro-dev-overlay-plugin-canvas'); - pluginCanvas.dataset.pluginId = plugin.id; - this.shadowRoot?.append(pluginCanvas); - } - - await this.togglePluginStatus(plugin, plugin.active); + if (settings.config.verbose) console.log(`Creating plugin canvas for ${plugin.id}`); + const pluginCanvas = document.createElement('astro-dev-toolbar-plugin-canvas'); + pluginCanvas.dataset.pluginId = plugin.id; + this.shadowRoot?.append(pluginCanvas); }); - // Init plugin lazily - This is safe to do here because only plugins that are not initialized yet will be affected + // Init plugin lazily, so that the page can load faster. + // Fallback to setTimeout for Safari (sad!) if ('requestIdleCallback' in window) { - window.requestIdleCallback(async () => { - await this.initAllPlugins(); - }); + window.requestIdleCallback( + async () => { + this.plugins.map((plugin) => this.initPlugin(plugin)); + }, + { timeout: 300 } + ); } else { - // Fallback to setTimeout for.. Safari... setTimeout(async () => { - await this.initAllPlugins(); - }, 200); + this.plugins.map((plugin) => this.initPlugin(plugin)); + }, 300); } + } - this.hasBeenInitialized = true; + // This is called whenever the component is connected to the DOM. + // This happens on first page load, and on each page change when + // view transitions are used. + connectedCallback() { + if (!this.hasBeenInitialized) { + this.init(); + this.hasBeenInitialized = true; + } + + // Run this every time to make sure the correct plugin is open. + this.plugins.forEach(async (plugin) => { + await this.setPluginStatus(plugin, plugin.active); + }); } attachEvents() { const items = this.shadowRoot.querySelectorAll<HTMLDivElement>('.item'); items.forEach((item) => { - item.addEventListener('click', async (e) => { - const target = e.currentTarget; + item.addEventListener('click', async (event) => { + const target = event.currentTarget; if (!target || !(target instanceof HTMLElement)) return; - const id = target.dataset.pluginId; if (!id) return; - const plugin = this.getPluginById(id); if (!plugin) return; - - if (plugin.status === 'loading') { - await this.initPlugin(plugin); - } - + event.stopPropagation(); await this.togglePluginStatus(plugin); }); }); - const minimizeButton = this.shadowRoot.querySelector<HTMLDivElement>('#minimize-button'); - if (minimizeButton && this.devOverlay) { - minimizeButton.addEventListener('click', () => { - this.toggleOverlay(false); - this.toggleMinimizeButton(false); - }); - } - - const devBar = this.shadowRoot.querySelector<HTMLDivElement>('#dev-bar'); - if (devBar) { - // On hover: - // - If the overlay is hidden, show it after the hover delay - // - If the overlay is visible, show the minimize button after the hover delay - (['mouseenter', 'focusin'] as const).forEach((event) => { - devBar.addEventListener(event, () => { - if (this.hoverTimeout) { - window.clearTimeout(this.hoverTimeout); - } - - if (this.isHidden()) { - this.hoverTimeout = window.setTimeout(() => { - this.toggleOverlay(true); - }, this.HOVER_DELAY + 200); // Slightly higher delay here to prevent users opening the overlay by accident - } else { - this.hoverTimeout = window.setTimeout(() => { - this.toggleMinimizeButton(true); - }, this.HOVER_DELAY); - } - }); - }); - - // On unhover: - // - Reset every timeout, as to avoid showing the overlay/minimize button when the user didn't really want to hover - // - If the overlay is visible, hide the minimize button after the hover delay - devBar.addEventListener('mouseleave', () => { - if (this.hoverTimeout) { - window.clearTimeout(this.hoverTimeout); - } - - if (!this.isHidden()) { - this.hoverTimeout = window.setTimeout(() => { - this.toggleMinimizeButton(false); - }, this.HOVER_DELAY); + (['mouseenter', 'focusin'] as const).forEach((event) => { + this.devOverlay!.addEventListener(event, () => { + this.clearDelayedHide(); + if (this.isHidden()) { + this.setOverlayVisible(true); } }); + }); - // On click, show the overlay if it's hidden, it's likely the user wants to interact with it - devBar.addEventListener('click', () => { - if (!this.isHidden()) return; - this.toggleOverlay(true); - }); - - devBar.addEventListener('keyup', (event) => { - if (event.code === 'Space' || event.code === 'Enter') { - if (!this.isHidden()) return; - this.toggleOverlay(true); + (['mouseleave', 'focusout'] as const).forEach((event) => { + this.devOverlay!.addEventListener(event, () => { + this.clearDelayedHide(); + if (this.getActivePlugin() || this.isHidden()) { + return; } + this.triggerDelayedHide(); }); - } - } + }); - async initAllPlugins() { - await Promise.all( - this.plugins - .filter((plugin) => plugin.status === 'loading') - .map((plugin) => this.initPlugin(plugin)) - ); + document.addEventListener('keyup', (event) => { + if (event.key !== 'Escape') return; + if (this.isHidden()) return; + const activePlugin = this.getActivePlugin(); + if (activePlugin) { + this.togglePluginStatus(activePlugin); + } else { + this.setOverlayVisible(false); + } + }); } async initPlugin(plugin: DevOverlayPlugin) { - if (plugin.status === 'ready') return; - const shadowRoot = this.getPluginCanvasById(plugin.id)!.shadowRoot!; - + plugin.status = 'loading'; try { if (settings.config.verbose) console.info(`Initializing plugin ${plugin.id}`); @@ -404,6 +364,7 @@ export class AstroDevOverlay extends HTMLElement { if (import.meta.hot) { import.meta.hot.send(`${WS_EVENT_NAME}:${plugin.id}:initialized`); + import.meta.hot.send(`${WS_EVENT_NAME_DEPRECATED}:${plugin.id}:initialized`); } } catch (e) { console.error(`Failed to init plugin ${plugin.id}, error: ${e}`); @@ -413,42 +374,51 @@ export class AstroDevOverlay extends HTMLElement { getPluginTemplate(plugin: DevOverlayPlugin) { return `<button class="item" data-plugin-id="${plugin.id}"> - <div class="icon">${this.getPluginIcon(plugin.icon)}<div class="notification"></div></div> + <div class="icon">${getPluginIcon(plugin.icon)}<div class="notification"></div></div> <span class="item-tooltip">${plugin.name}</span> </button>`; } - getPluginIcon(icon: Icon) { - if (isDefinedIcon(icon)) { - return getIconElement(icon)?.outerHTML; - } - - return icon; - } - getPluginById(id: string) { return this.plugins.find((plugin) => plugin.id === id); } getPluginCanvasById(id: string) { return this.shadowRoot.querySelector<HTMLElement>( - `astro-dev-overlay-plugin-canvas[data-plugin-id="${id}"]` + `astro-dev-toolbar-plugin-canvas[data-plugin-id="${id}"]` ); } - /** - * @param plugin The plugin to toggle the status of - * @param newStatus Optionally, force the plugin into a specific state - */ - async togglePluginStatus(plugin: DevOverlayPlugin, newStatus?: boolean) { + async togglePluginStatus(plugin: DevOverlayPlugin) { + const activePlugin = this.getActivePlugin(); + if (activePlugin) { + const closePlugin = await this.setPluginStatus(activePlugin, false); + + // If the plugin returned false, don't open the new plugin, the old plugin didn't want to close + if (!closePlugin) return; + } + + // TODO(fks): Handle a plugin that hasn't loaded yet. + // Currently, this will just do nothing. + if (plugin.status !== 'ready') return; + + // Open the selected plugin. If the selected plugin was + // already the active plugin then the desired outcome + // was to close that plugin, so no action needed. + if (plugin !== activePlugin) { + await this.setPluginStatus(plugin, true); + } + } + + async setPluginStatus(plugin: DevOverlayPlugin, newStatus: boolean) { const pluginCanvas = this.getPluginCanvasById(plugin.id); - if (!pluginCanvas) return; + if (!pluginCanvas) return false; if (plugin.active && !newStatus && plugin.beforeTogglingOff) { const shouldToggleOff = await plugin.beforeTogglingOff(pluginCanvas.shadowRoot!); // If the plugin returned false, don't toggle it off, maybe the plugin showed a confirmation dialog or similar - if (!shouldToggleOff) return; + if (!shouldToggleOff) return false; } plugin.active = newStatus ?? !plugin.active; @@ -465,12 +435,21 @@ export class AstroDevOverlay extends HTMLElement { moreBarButton.classList.toggle('active', plugin.active); } - pluginCanvas.style.display = plugin.active ? 'block' : 'none'; + if (plugin.active) { + pluginCanvas.style.display = 'block'; + pluginCanvas.setAttribute('data-active', ''); + } else { + pluginCanvas.style.display = 'none'; + pluginCanvas.removeAttribute('data-active'); + } - window.requestAnimationFrame(() => { - pluginCanvas.toggleAttribute('data-active', plugin.active); + [ + 'app-toggled', + // Deprecated + 'plugin-toggled', + ].forEach((eventName) => { plugin.eventTarget.dispatchEvent( - new CustomEvent('plugin-toggled', { + new CustomEvent(eventName, { detail: { state: plugin.active, plugin, @@ -481,53 +460,60 @@ export class AstroDevOverlay extends HTMLElement { if (import.meta.hot) { import.meta.hot.send(`${WS_EVENT_NAME}:${plugin.id}:toggled`, { state: plugin.active }); + import.meta.hot.send(`${WS_EVENT_NAME_DEPRECATED}:${plugin.id}:toggled`, { + state: plugin.active, + }); } + + return true; } - /** - * @param newStatus Optionally, force the minimize button into a specific state - */ - toggleMinimizeButton(newStatus?: boolean) { - const minimizeButton = this.shadowRoot.querySelector<HTMLDivElement>('#minimize-button'); - if (!minimizeButton) return; - - if (newStatus !== undefined) { - if (newStatus === true) { - minimizeButton.removeAttribute('inert'); - minimizeButton.style.opacity = '1'; - } else { - minimizeButton.setAttribute('inert', ''); - minimizeButton.style.opacity = '0'; - } - } else { - minimizeButton.toggleAttribute('inert'); - minimizeButton.style.opacity = minimizeButton.hasAttribute('inert') ? '0' : '1'; - } + isHidden(): boolean { + return this.devOverlay?.hasAttribute('data-hidden') ?? true; + } + + getActivePlugin(): DevOverlayPlugin | undefined { + return this.plugins.find((plugin) => plugin.active); + } + + clearDelayedHide() { + window.clearTimeout(this.delayedHideTimeout); + this.delayedHideTimeout = undefined; + } + + triggerDelayedHide() { + this.clearDelayedHide(); + this.delayedHideTimeout = window.setTimeout(() => { + this.setOverlayVisible(false); + this.delayedHideTimeout = undefined; + }, HOVER_DELAY); } - toggleOverlay(newStatus?: boolean) { + setOverlayVisible(newStatus: boolean) { const barContainer = this.shadowRoot.querySelector<HTMLDivElement>('#bar-container'); const devBar = this.shadowRoot.querySelector<HTMLDivElement>('#dev-bar'); - - if (newStatus !== undefined) { - if (newStatus === true) { - this.devOverlay?.removeAttribute('data-hidden'); - barContainer?.removeAttribute('inert'); - devBar?.removeAttribute('tabindex'); - } else { - this.devOverlay?.setAttribute('data-hidden', ''); - barContainer?.setAttribute('inert', ''); - devBar?.setAttribute('tabindex', '0'); - } - } else { - this.devOverlay?.toggleAttribute('data-hidden'); - barContainer?.toggleAttribute('inert'); - if (this.isHidden()) { - devBar?.setAttribute('tabindex', '0'); - } else { - devBar?.removeAttribute('tabindex'); - } + if (newStatus === true) { + this.devOverlay?.removeAttribute('data-hidden'); + barContainer?.removeAttribute('inert'); + devBar?.removeAttribute('tabindex'); + return; } + if (newStatus === false) { + this.devOverlay?.setAttribute('data-hidden', ''); + barContainer?.setAttribute('inert', ''); + devBar?.setAttribute('tabindex', '0'); + return; + } + } + + setNotificationVisible(newStatus: boolean) { + const devOverlayElement = this.shadowRoot.querySelector<HTMLDivElement>('#dev-overlay'); + devOverlayElement?.toggleAttribute('data-no-notification', !newStatus); + + const moreCanvas = this.getPluginCanvasById('astro:more'); + moreCanvas?.shadowRoot + ?.querySelector('#dropdown') + ?.toggleAttribute('data-no-notification', !newStatus); } } @@ -550,3 +536,11 @@ export class DevOverlayCanvas extends HTMLElement { </style>`; } } + +export function getPluginIcon(icon: Icon) { + if (isDefinedIcon(icon)) { + return getIconElement(icon).outerHTML; + } + + return icon; +} diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/astro.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/astro.ts index 352a018e11e22..d3f0d03e6789a 100644 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/astro.ts +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/astro.ts @@ -1,19 +1,85 @@ -import type { DevOverlayPlugin } from '../../../../@types/astro.js'; -import { createWindowWithTransition, waitForTransition } from './utils/window.js'; +import type { DevOverlayMetadata, DevOverlayPlugin } from '../../../../@types/astro.js'; +import { isDefinedIcon, type Icon } from '../ui-library/icons.js'; +import { colorForIntegration, iconForIntegration } from './utils/icons.js'; +import { createWindowElement } from './utils/window.js'; + +const astroLogo = + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 99 26" width="100"><path fill="#fff" d="M6.70402 22.1453c-1.17459-1.0737-1.51748-3.3297-1.02811-4.9641.84853 1.0304 2.02424 1.3569 3.24204 1.5411 1.88005.2844 3.72635.178 5.47285-.6813.1998-.0984.3844-.2292.6027-.3617.1639.4755.2065.9554.1493 1.4439-.1392 1.1898-.7313 2.1088-1.673 2.8054-.3765.2787-.775.5278-1.1639.7905-1.1948.8075-1.518 1.7544-1.0691 3.1318.0107.0336.0202.0671.0444.149-.6101-.273-1.0557-.6705-1.39518-1.1931-.3586-.5517-.52921-1.1619-.53819-1.8221-.00449-.3213-.00449-.6455-.0477-.9623-.10551-.7722-.46804-1.118-1.15102-1.1379-.70094-.0205-1.2554.4129-1.40244 1.0953-.01122.0523-.02749.1041-.04377.1649l.00112.0006Z"/><path fill="url(#paint0_linear_386_2739)" d="M6.70402 22.1453c-1.17459-1.0737-1.51748-3.3297-1.02811-4.9641.84853 1.0304 2.02424 1.3569 3.24204 1.5411 1.88005.2844 3.72635.178 5.47285-.6813.1998-.0984.3844-.2292.6027-.3617.1639.4755.2065.9554.1493 1.4439-.1392 1.1898-.7313 2.1088-1.673 2.8054-.3765.2787-.775.5278-1.1639.7905-1.1948.8075-1.518 1.7544-1.0691 3.1318.0107.0336.0202.0671.0444.149-.6101-.273-1.0557-.6705-1.39518-1.1931-.3586-.5517-.52921-1.1619-.53819-1.8221-.00449-.3213-.00449-.6455-.0477-.9623-.10551-.7722-.46804-1.118-1.15102-1.1379-.70094-.0205-1.2554.4129-1.40244 1.0953-.01122.0523-.02749.1041-.04377.1649l.00112.0006Z"/><path fill="#fff" d="M0 16.909s3.47815-1.6944 6.96603-1.6944l2.62973-8.13858c.09846-.39359.38592-.66106.71044-.66106.3246 0 .612.26747.7105.66106l2.6297 8.13858c4.1309 0 6.966 1.6944 6.966 1.6944S14.7045.814589 14.693.782298C14.5234.306461 14.2371 0 13.8512 0H6.76183c-.38593 0-.66063.306461-.84174.782298C5.90733.81398 0 16.909 0 16.909ZM36.671 11.7318c0 1.4262-1.7739 2.2779-4.2302 2.2779-1.5985 0-2.1638-.3962-2.1638-1.2281 0-.8715.7018-1.2875 2.3003-1.2875 1.4426 0 2.6707.0198 4.0937.1981v.0396Zm.0195-1.7629c-.8772-.19808-2.2028-.31693-3.7818-.31693-4.6006 0-6.7644 1.08943-6.7644 3.62483 0 2.6344 1.4815 3.6446 4.9125 3.6446 2.9046 0 4.8735-.7328 5.5947-2.5354h.117c-.0195.4358-.039.8716-.039 1.2083 0 .931.156 1.0102.9162 1.0102h3.5869c-.1949-.5546-.3119-2.1194-.3119-3.4663 0-1.446.0585-2.5355.0585-4.00123 0-2.99098-1.7934-4.89253-7.4077-4.89253-2.4173 0-5.1074.41596-7.1543 1.03.1949.81213.4679 2.45617.6043 3.5258 1.774-.83193 4.2887-1.18847 6.2381-1.18847 2.6902 0 3.4309.61404 3.4309 1.86193v.4952ZM46.5325 12.5637c-.4874.0594-1.1502.0594-1.8325.0594-.7213 0-1.3841-.0198-1.8324-.0792 0 .1585-.0195.3367-.0195.4952 0 2.476 1.618 3.922 7.3102 3.922 5.3609 0 7.0958-1.4262 7.0958-3.9418 0-2.3769-1.1501-3.5456-6.238-3.8031-3.9573-.17827-4.3082-.61404-4.3082-1.10924 0-.57442.5068-.87154 3.158-.87154 2.7487 0 3.4894.37635 3.4894 1.16866v.17827c.3899-.01981 1.0917-.03961 1.813-.03961.6823 0 1.423.0198 1.8519.05942 0-.17827.0195-.33674.0195-.47539 0-2.91175-2.4172-3.86252-7.0958-3.86252-5.2634 0-7.0373 1.2875-7.0373 3.8031 0 2.25805 1.423 3.66445 6.472 3.88235 3.7233.1188 4.1327.5348 4.1327 1.1092 0 .6141-.6043.8914-3.2165.8914-3.0021 0-3.7623-.416-3.7623-1.2677v-.1189ZM63.6883 2.125c-1.423 1.32712-3.9768 2.65425-5.3998 3.01079.0195.73289.0195 2.07982.0195 2.81271l1.3061.01981c-.0195 1.40635-.039 3.10979-.039 4.23889 0 2.6344 1.3841 4.6152 5.6922 4.6152 1.813 0 3.0216-.1981 4.5226-.515-.1559-.9706-.3314-2.4562-.3898-3.5852-.8968.2971-2.0274.4556-3.275.4556-1.735 0-2.4368-.4754-2.4368-1.8422 0-1.1884 0-2.29767.0195-3.32768 2.2223.01981 4.4446.05943 5.7507.09904-.0195-1.03.0195-2.51559.078-3.50598-1.8909.03961-4.0157.05942-5.7702.05942.0195-.87154.039-1.70347.0585-2.5354h-.1365ZM75.3313 7.35427c.0195-1.03001.039-1.90156.0585-2.75329h-3.9183c.0585 1.70347.0585 3.44656.0585 6.00172 0 2.5553-.0195 4.3182-.0585 6.0018h4.4836c-.078-1.1885-.0975-3.189-.0975-4.8925 0-2.69388 1.0917-3.46638 3.5674-3.46638 1.1502 0 1.9689.13865 2.6902.39615.0195-1.01019.2144-2.97117.3314-3.84271-.7408-.21789-1.5595-.35655-2.5537-.35655-2.1249-.0198-3.6844.85174-4.4056 2.93156l-.156-.0198ZM94.8501 10.5235c0 2.1591-1.5595 3.1693-4.0157 3.1693-2.4368 0-3.9963-.9508-3.9963-3.1693 0-2.21846 1.579-3.05039 3.9963-3.05039 2.4367 0 4.0157.89135 4.0157 3.05039Zm4.0743-.099c0-4.29832-3.353-6.21968-8.09-6.21968-4.7566 0-7.9926 1.92136-7.9926 6.21968 0 4.2785 3.0216 6.5762 7.9731 6.5762 4.9904 0 8.1095-2.2977 8.1095-6.5762Z"/><defs><linearGradient id="paint0_linear_386_2739" x1="5.46011" x2="16.8017" y1="25.9999" y2="20.6412" gradientUnits="userSpaceOnUse"><stop stop-color="#D83333"/><stop offset="1" stop-color="#F041FF"/></linearGradient></defs></svg>'; + +export interface Integration { + name: string; + title: string; + description: string; + image?: string; + categories: string[]; + repoUrl: string; + npmUrl: string; + homepageUrl: string; + official: boolean; + featured: number; + downloads: number; +} + +interface IntegrationData { + data: Integration[]; +} + +let integrationData: IntegrationData; export default { id: 'astro', - name: 'Astro', + name: 'Menu', icon: 'astro:logo', - init(canvas) { - createWindow(); + async init(canvas, eventTarget) { + createCanvas(); + + document.addEventListener('astro:after-swap', createCanvas); + + eventTarget.addEventListener('plugin-toggled', async (event) => { + resetDebugButton(); + if (!(event instanceof CustomEvent)) return; + + if (event.detail.state === true) { + if (!integrationData) + fetch('https://astro.build/api/v1/dev-overlay/', { + cache: 'no-cache', + }) + .then((res) => res.json()) + .then((data) => { + integrationData = data; + integrationData.data = integrationData.data.map((integration) => { + return integration; + }); + refreshIntegrationList(); + }); + } + }); - document.addEventListener('astro:after-swap', createWindow); + function createCanvas() { + const links: { icon: Icon; name: string; link: string }[] = [ + { + icon: 'bug', + name: 'Report a Bug', + link: 'https://github.com/withastro/astro/issues/new/choose', + }, + { + icon: 'lightbulb', + name: 'Feedback', + link: 'https://github.com/withastro/roadmap/discussions/new/choose', + }, + { + icon: 'file-search', + name: 'Documentation', + link: 'https://docs.astro.build', + }, + { + icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 14"><path fill="currentColor" d="M14.3451 1.9072c-1.0375-.47613-2.1323-.81595-3.257-1.010998-.0102-.001716-.0207-.000234-.03.004243s-.017.011728-.022.020757c-.141.249998-.297.576998-.406.832998-1.2124-.18399-2.44561-.18399-3.658 0-.12159-.28518-.25914-.56328-.412-.832998-.00513-.00893-.01285-.016098-.02213-.02056-.00928-.004462-.0197-.00601-.02987-.00444-1.125.193998-2.22.533998-3.257 1.010998-.00888.00339-.0163.00975-.021.018-2.074 3.099-2.643004 6.122-2.364004 9.107.001.014.01.028.021.037 1.207724.8946 2.558594 1.5777 3.995004 2.02.01014.0032.02103.0031.03111-.0003.01007-.0034.01878-.01.02489-.0187.308-.42.582-.863.818-1.329.00491-.0096.0066-.0205.0048-.0312-.00181-.0106-.007-.0204-.0148-.0278-.00517-.0049-.0113-.0086-.018-.011-.43084-.1656-.84811-.3645-1.248-.595-.01117-.0063-.01948-.0167-.0232-.029-.00373-.0123-.00258-.0255.0032-.037.0034-.0074.00854-.014.015-.019.084-.063.168-.129.248-.195.00706-.0057.01554-.0093.02453-.0106.00898-.0012.01813 0 .02647.0036 2.619 1.196 5.454 1.196 8.041 0 .0086-.0037.0181-.0051.0275-.0038.0093.0012.0181.0049.0255.0108.08.066.164.132.248.195.0068.005.0123.0116.0159.0192.0036.0076.0053.016.0049.0244-.0003.0084-.0028.0166-.0072.0238-.0043.0072-.0104.0133-.0176.0176-.399.2326-.8168.4313-1.249.594-.0069.0025-.0132.0065-.0183.0117-.0052.0051-.0092.0114-.0117.0183-.0023.0067-.0032.0138-.0027.0208.0005.0071.0024.0139.0057.0202.24.465.515.909.817 1.329.0061.0087.0148.0153.0249.0187.0101.0034.021.0035.0311.0003 1.4388-.441 2.7919-1.1241 4.001-2.02.0061-.0042.0111-.0097.0147-.0161.0037-.0064.0058-.0135.0063-.0209.334-3.451-.559-6.449-2.366-9.106-.0018-.00439-.0045-.00834-.008-.01162-.0034-.00327-.0075-.00578-.012-.00738Zm-8.198 7.307c-.789 0-1.438-.724-1.438-1.612 0-.889.637-1.613 1.438-1.613.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612Zm5.316 0c-.788 0-1.438-.724-1.438-1.612 0-.889.637-1.613 1.438-1.613.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612Z"/></svg>', + name: 'Community', + link: 'https://astro.build/chat', + }, + ]; - function createWindow() { - const window = createWindowWithTransition( - 'Astro', - 'astro:logo', + const windowComponent = createWindowElement( `<style> #buttons-container { display: flex; @@ -21,7 +87,7 @@ export default { justify-content: center; } - #buttons-container astro-dev-overlay-card { + #buttons-container astro-dev-toolbar-card { flex: 1; } @@ -42,35 +108,332 @@ export default { #main-container { display: flex; flex-direction: column; - justify-content: space-between; height: 100%; + gap: 24px; } p { margin-top: 0; } + + header { + display: flex; + justify-content: space-between; + align-items: center; + } + + header section { + display: flex; + gap: 0.8em; + } + + h2 { + color: white; + margin: 0; + font-size: 18px; + } + + a { + color: rgba(224, 204, 250, 1); + } + + a:hover { + color: #f4ecfd; + } + + #integration-list-wrapper { + position: relative; + --offset: 24px; + overflow-x: auto; + overflow-y: hidden; + margin-left: calc(var(--offset) * -1); + margin-right: calc(var(--offset) * -1); + padding-left: var(--offset); + padding-right: var(--offset); + height: 210px; + } + + /* Pseudo-elements to fade cards as they scroll out of viewport */ + #integration-list-wrapper::before, + #integration-list-wrapper::after { + content: ''; + height: 192px; + display: block; + position: fixed; + width: var(--offset); + top: 106px; + background: red; + } + + #integration-list-wrapper::before { + left: -1px; + border-left: 1px solid rgba(52, 56, 65, 1); + background: linear-gradient(to right, rgba(19, 21, 26, 1), rgba(19, 21, 26, 0)); + } + + #integration-list-wrapper::after { + right: -1px; + border-right: 1px solid rgba(52, 56, 65, 1); + background: linear-gradient(to left, rgba(19, 21, 26, 1), rgba(19, 21, 26, 0)); + } + + #integration-list-wrapper::-webkit-scrollbar { + width: 5px; + height: 8px; + background-color: rgba(255, 255, 255, 0.08); /* or add it to the track */ + border-radius: 4px; + } + + /* This is wild but gives us a gap on either side of the container */ + #integration-list-wrapper::-webkit-scrollbar-button:start:decrement, + #integration-list-wrapper::-webkit-scrollbar-button:end:increment { + display: block; + width: 24px; + background-color: #13151A; + } + + /* Removes arrows on both sides */ + #integration-list-wrapper::-webkit-scrollbar-button:horizontal:start:increment, + #integration-list-wrapper::-webkit-scrollbar-button:horizontal:end:decrement { + display: none; + } + + #integration-list-wrapper::-webkit-scrollbar-track-piece { + border-radius: 4px; + } + + #integration-list-wrapper::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.3); + border-radius: 4px; + } + + #integration-list { + margin-top: 1em; + display: flex; + gap: 16px; + padding-bottom: 1em; + } + + #integration-list::after { + content: " "; + display: inline-block; + white-space: pre; + width: 1px; + height: 1px; + } + + #integration-list astro-dev-toolbar-card, .integration-skeleton { + min-width: 240px; + height: 160px; + } + + .integration-skeleton { + animation: pulse 2s calc(var(--i, 0) * 250ms) cubic-bezier(0.4, 0, 0.6, 1) infinite; + background-color: rgba(35, 38, 45, 1); + border-radius: 8px; + } + + @keyframes pulse { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: .5; + } + } + + #integration-list astro-dev-toolbar-card .integration-image { + width: 40px; + height: 40px; + background-color: var(--integration-image-background, white); + border-radius: 9999px; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 8px; + } + + #integration-list astro-dev-toolbar-card img { + width: 24px; + height: 24px; + } + + #integration-list astro-dev-toolbar-card astro-dev-toolbar-icon { + width: 24px; + height: 24px; + color: #fff; + } + + #links { + margin: auto 0; + display: flex; + justify-content: center; + gap: 24px; + } + + #links a { + text-decoration: none; + align-items: center; + display: flex; + flex-direction: column; + gap: 0.7em; + flex: 1; + white-space: nowrap; + font-weight: 600; + color: white; + } + + #links a:hover { + color: rgba(145, 152, 173, 1); + } + + #links astro-dev-toolbar-icon { + width: 1.5em; + height: 1.5em; + display: block; + } + + #integration-list astro-dev-toolbar-card svg { + width: 24px; + height: 24px; + vertical-align: bottom; + } + + #integration-list astro-dev-toolbar-card h3 { + margin: 0; + margin-bottom: 8px; + color: white; + white-space: nowrap; + } + + #integration-list astro-dev-toolbar-card p { + font-size: 14px; + } + + @media (forced-colors: active) { + svg path[fill="#fff"] { + fill: black; + } + } </style> + <header> + <section> + ${astroLogo} + <astro-dev-toolbar-badge badge-style="gray" size="large">${ + (window as DevOverlayMetadata).__astro_dev_overlay__.version + }</astro-dev-toolbar-badge> + </section> + <astro-dev-toolbar-button id="copy-debug-button">Copy debug info <astro-dev-toolbar-icon icon="copy" /></astro-dev-toolbar-button> + </header> + <hr /> + <div id="main-container"> <div> - <p>Welcome to Astro!</p> - <div id="buttons-container"> - <astro-dev-overlay-card icon="bug" link="https://github.com/withastro/astro/issues/new/choose">Report an issue</astro-dev-overlay-card> - <astro-dev-overlay-card icon="file-search" link="https://docs.astro.build/en/getting-started/">View Astro Docs</astro-dev-overlay-card> - </div> + <header><h2>Featured integrations</h2><a href="https://astro.build/integrations/" target="_blank">View all</a></header> + <div id="integration-list-wrapper"> + <section id="integration-list"> + <div class="integration-skeleton" style="--i:0;"></div> + <div class="integration-skeleton" style="--i:1;"></div> + <div class="integration-skeleton" style="--i:2;"></div> + <div class="integration-skeleton" style="--i:3;"></div> + <div class="integration-skeleton" style="--i:4;"></div> + </section> + </div> </div> - <footer> - <a href="https://astro.build/chat" target="_blank">Join us on Discord</a> - <a href="https://astro.build" target="_blank">Visit the Astro website</a> - </footer> + <section id="links"> + ${links + .map( + (link) => + `<a href="${link.link}" target="_blank"><astro-dev-toolbar-icon ${ + isDefinedIcon(link.icon) ? `icon="${link.icon}">` : `>${link.icon}` + }</astro-dev-toolbar-icon>${link.name}</a>` + ) + .join('')} + </section> </div> ` ); - canvas.append(window); + const copyDebugButton = + windowComponent.querySelector<HTMLButtonElement>('#copy-debug-button'); + + copyDebugButton?.addEventListener('click', () => { + navigator.clipboard.writeText( + '```\n' + (window as DevOverlayMetadata).__astro_dev_overlay__.debugInfo + '\n```' + ); + copyDebugButton.textContent = 'Copied to clipboard!'; + + setTimeout(() => { + resetDebugButton(); + }, 3500); + }); + + canvas.append(windowComponent); + } + + function resetDebugButton() { + const copyDebugButton = canvas.querySelector<HTMLButtonElement>('#copy-debug-button'); + if (!copyDebugButton) return; + + copyDebugButton.innerHTML = 'Copy debug info <astro-dev-toolbar-icon icon="copy" />'; + } + + function refreshIntegrationList() { + const integrationList = canvas.querySelector<HTMLElement>('#integration-list'); + + if (!integrationList) return; + integrationList.innerHTML = ''; + + const fragment = document.createDocumentFragment(); + for (const integration of integrationData.data) { + const integrationComponent = document.createElement('astro-dev-toolbar-card'); + integrationComponent.link = integration.homepageUrl; + + const integrationContainer = document.createElement('div'); + integrationContainer.className = 'integration-container'; + + const integrationImage = document.createElement('div'); + integrationImage.className = 'integration-image'; + + if (integration.image) { + const img = document.createElement('img'); + img.src = integration.image; + img.alt = integration.title; + integrationImage.append(img); + } else { + const icon = document.createElement('astro-dev-toolbar-icon'); + icon.icon = iconForIntegration(integration); + integrationImage.append(icon); + integrationImage.style.setProperty( + '--integration-image-background', + colorForIntegration() + ); + } + + integrationContainer.append(integrationImage); + + let integrationTitle = document.createElement('h3'); + integrationTitle.textContent = integration.title; + if (integration.official || integration.categories.includes('official')) { + integrationTitle.innerHTML += + ' <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 21 20"><rect width="19" height="19" x="1.16602" y=".5" fill="url(#paint0_linear_917_1096)" fill-opacity=".33" rx="9.5"/><path fill="#fff" d="M15.139 6.80657c-.062-.06248-.1357-.11208-.217-.14592-.0812-.03385-.1683-.05127-.2563-.05127-.0881 0-.1752.01742-.2564.05127-.0813.03384-.155.08344-.217.14592L9.22566 11.7799 7.13899 9.68657c-.06435-.06216-.14031-.11103-.22355-.14383-.08323-.03281-.17211-.04889-.26157-.04735-.08945.00155-.17773.0207-.25978.05637a.68120694.68120694 0 0 0-.21843.15148c-.06216.06435-.11104.14031-.14384.22355-.0328.08321-.04889.17211-.04734.26161.00154.0894.0207.1777.05636.2597.03566.0821.08714.1563.15148.2185l2.56 2.56c.06198.0625.13571.1121.21695.1459s.16838.0513.25639.0513c.088 0 .17514-.0175.25638-.0513s.15497-.0834.21695-.1459L15.139 7.78657c.0677-.06242.1217-.13819.1586-.22253.0369-.08433.056-.1754.056-.26747 0-.09206-.0191-.18313-.056-.26747-.0369-.08433-.0909-.1601-.1586-.22253Z"/><rect width="19" height="19" x="1.16602" y=".5" stroke="url(#paint1_linear_917_1096)" rx="9.5"/><defs><linearGradient id="paint0_linear_917_1096" x1="20.666" x2="-3.47548" y1=".00000136" y2="10.1345" gradientUnits="userSpaceOnUse"><stop stop-color="#4AF2C8"/><stop offset="1" stop-color="#2F4CB3"/></linearGradient><linearGradient id="paint1_linear_917_1096" x1="20.666" x2="-3.47548" y1=".00000136" y2="10.1345" gradientUnits="userSpaceOnUse"><stop stop-color="#4AF2C8"/><stop offset="1" stop-color="#2F4CB3"/></linearGradient></defs></svg>'; + } + integrationContainer.append(integrationTitle); + + const integrationDescription = document.createElement('p'); + integrationDescription.textContent = + integration.description.length > 90 + ? integration.description.slice(0, 90) + '…' + : integration.description; + + integrationContainer.append(integrationDescription); + integrationComponent.append(integrationContainer); + + fragment.append(integrationComponent); + } + + integrationList.append(fragment); } - }, - async beforeTogglingOff(canvas) { - return await waitForTransition(canvas); }, } satisfies DevOverlayPlugin; diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/audit.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/audit.ts deleted file mode 100644 index 6961e12273294..0000000000000 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/audit.ts +++ /dev/null @@ -1,213 +0,0 @@ -import type { DevOverlayMetadata, DevOverlayPlugin } from '../../../../@types/astro.js'; -import type { DevOverlayHighlight } from '../ui-library/highlight.js'; -import { getIconElement } from '../ui-library/icons.js'; -import { attachTooltipToHighlight, createHighlight, positionHighlight } from './utils/highlight.js'; - -const icon = - '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 16"><path fill="#fff" d="M.6 2A1.1 1.1 0 0 1 1.7.9h16.6a1.1 1.1 0 1 1 0 2.2H1.6A1.1 1.1 0 0 1 .8 2Zm1.1 7.1h6a1.1 1.1 0 0 0 0-2.2h-6a1.1 1.1 0 0 0 0 2.2ZM9.3 13H1.8a1.1 1.1 0 1 0 0 2.2h7.5a1.1 1.1 0 1 0 0-2.2Zm11.3 1.9a1.1 1.1 0 0 1-1.5 0l-1.7-1.7a4.1 4.1 0 1 1 1.6-1.6l1.6 1.7a1.1 1.1 0 0 1 0 1.6Zm-5.3-3.4a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8Z"/></svg>'; - -interface AuditRule { - title: string; - message: string; -} - -const selectorBasedRules: (AuditRule & { selector: string })[] = [ - { - title: 'Missing `alt` tag', - message: 'The alt attribute is important for accessibility.', - selector: 'img:not([alt])', - }, -]; - -export default { - id: 'astro:audit', - name: 'Audit', - icon: icon, - async init(canvas, eventTarget) { - let audits: { highlightElement: DevOverlayHighlight; auditedElement: HTMLElement }[] = []; - - await lint(); - - document.addEventListener('astro:after-swap', async () => lint()); - document.addEventListener('astro:page-load', async () => refreshLintPositions); - - async function lint() { - initStyle(); - - audits.forEach(({ highlightElement }) => { - highlightElement.remove(); - }); - audits = []; - canvas.getElementById('no-audit')?.remove(); - - for (const rule of selectorBasedRules) { - const elements = document.querySelectorAll(rule.selector); - - for (const element of elements) { - await createAuditProblem(rule, element); - } - } - - if (audits.length > 0) { - eventTarget.dispatchEvent( - new CustomEvent('toggle-notification', { - detail: { - state: true, - }, - }) - ); - } else { - eventTarget.dispatchEvent( - new CustomEvent('toggle-notification', { - detail: { - state: false, - }, - }) - ); - - const noAuditBlock = document.createElement('div'); - noAuditBlock.id = 'no-audit'; - - const noAuditIcon = getIconElement('check-circle'); - const text = document.createElement('div'); - text.textContent = 'No issues found!'; - - if (noAuditIcon) { - noAuditIcon.style.width = '24px'; - noAuditBlock.append(noAuditIcon); - } - noAuditBlock.append(text); - - canvas.append(noAuditBlock); - } - - (['scroll', 'resize'] as const).forEach((event) => { - window.addEventListener(event, refreshLintPositions); - }); - } - - function refreshLintPositions() { - const noAuditBlock = canvas.getElementById('no-audit'); - if (noAuditBlock) { - const devOverlayRect = document - .querySelector('astro-dev-overlay') - ?.shadowRoot.querySelector('#dev-overlay') - ?.getBoundingClientRect(); - - noAuditBlock.style.top = `${ - (devOverlayRect?.top ?? 0) - (devOverlayRect?.height ?? 0) - 16 - }px`; - } - - audits.forEach(({ highlightElement, auditedElement }) => { - const rect = auditedElement.getBoundingClientRect(); - positionHighlight(highlightElement, rect); - }); - } - - async function createAuditProblem(rule: AuditRule, originalElement: Element) { - const computedStyle = window.getComputedStyle(originalElement); - const targetedElement = (originalElement.children[0] as HTMLElement) || originalElement; - - // If the element is hidden, don't do anything - if (targetedElement.offsetParent === null || computedStyle.display === 'none') { - return; - } - - // If the element is an image, wait for it to load - if (originalElement.nodeName === 'IMG' && !(originalElement as HTMLImageElement).complete) { - await (originalElement as HTMLImageElement).decode(); - } - - const rect = originalElement.getBoundingClientRect(); - const highlight = createHighlight(rect, 'warning'); - const tooltip = buildAuditTooltip(rule, originalElement); - attachTooltipToHighlight(highlight, tooltip, originalElement); - - canvas.append(highlight); - audits.push({ highlightElement: highlight, auditedElement: originalElement as HTMLElement }); - } - - function buildAuditTooltip(rule: AuditRule, element: Element) { - const tooltip = document.createElement('astro-dev-overlay-tooltip'); - - tooltip.sections = [ - { - icon: 'warning', - title: rule.title, - }, - { - content: rule.message, - }, - ]; - - const elementFile = element.getAttribute('data-astro-source-file'); - const elementPosition = element.getAttribute('data-astro-source-loc'); - - if (elementFile) { - const elementFileWithPosition = - elementFile + (elementPosition ? ':' + elementPosition : ''); - - tooltip.sections.push({ - content: elementFileWithPosition.slice( - (window as DevOverlayMetadata).__astro_dev_overlay__.root.length - 1 // We want to keep the final slash, so minus one. - ), - clickDescription: 'Click to go to file', - async clickAction() { - // NOTE: The path here has to be absolute and without any errors (no double slashes etc) - // or Vite will silently fail to open the file. Quite annoying. - await fetch('/__open-in-editor?file=' + encodeURIComponent(elementFileWithPosition)); - }, - }); - } - - return tooltip; - } - - function initStyle() { - const devOverlayRect = document - .querySelector('astro-dev-overlay') - ?.shadowRoot.querySelector('#dev-overlay') - ?.getBoundingClientRect(); - - const style = document.createElement('style'); - style.textContent = ` - :host { - opacity: 0; - transition: opacity 0.1s ease-in-out; - } - - :host([data-active]) { - opacity: 1; - } - - #no-audit { - border: 1px solid rgba(113, 24, 226, 1); - background-color: #310A65; - box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.30), 0px 1px 2px 0px rgba(0, 0, 0, 0.29), 0px 4px 4px 0px rgba(0, 0, 0, 0.26), 0px 10px 6px 0px rgba(0, 0, 0, 0.15), 0px 17px 7px 0px rgba(0, 0, 0, 0.04), 0px 26px 7px 0px rgba(0, 0, 0, 0.01); - color: white; - text-align: center; - border-radius: 4px; - padding: 8px; - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - position: fixed; - transform: translate(-50%, 0); - top: ${(devOverlayRect?.top ?? 0) - (devOverlayRect?.height ?? 0) - 16}px; - left: calc(50% + 12px); - width: 200px; - } - `; - - canvas.append(style); - } - }, - async beforeTogglingOff(canvas) { - canvas.host?.removeAttribute('data-active'); - - await new Promise((resolve) => { - canvas.host.addEventListener('transitionend', resolve); - }); - - return true; - }, -} satisfies DevOverlayPlugin; diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/audit/a11y.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/audit/a11y.ts new file mode 100644 index 0000000000000..a5e6e5073ad58 --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/audit/a11y.ts @@ -0,0 +1,481 @@ +/** + * https://github.com/sveltejs/svelte/blob/61e5e53eee82e895c1a5b4fd36efb87eafa1fc2d/LICENSE.md + * @license MIT + * + * Copyright (c) 2016-23 [these people](https://github.com/sveltejs/svelte/graphs/contributors) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import type { AuditRuleWithSelector } from './index.js'; + +const a11y_required_attributes = { + a: ['href'], + area: ['alt', 'aria-label', 'aria-labelledby'], + // html-has-lang + html: ['lang'], + // iframe-has-title + iframe: ['title'], + img: ['alt'], + object: ['title', 'aria-label', 'aria-labelledby'], +}; + +const interactiveElements = ['button', 'details', 'embed', 'iframe', 'label', 'select', 'textarea']; + +const aria_non_interactive_roles = [ + 'alert', + 'alertdialog', + 'application', + 'article', + 'banner', + 'button', + 'cell', + 'checkbox', + 'columnheader', + 'combobox', + 'complementary', + 'contentinfo', + 'definition', + 'dialog', + 'directory', + 'document', + 'feed', + 'figure', + 'form', + 'grid', + 'gridcell', + 'group', + 'heading', + 'img', + 'link', + 'list', + 'listbox', + 'listitem', + 'log', + 'main', + 'marquee', + 'math', + 'menu', + 'menubar', + 'menuitem', + 'menuitemcheckbox', + 'menuitemradio', + 'navigation', + 'none', + 'note', + 'option', + 'presentation', + 'progressbar', + 'radio', + 'radiogroup', + 'region', + 'row', + 'rowgroup', + 'rowheader', + 'scrollbar', + 'search', + 'searchbox', + 'separator', + 'slider', + 'spinbutton', + 'status', + 'switch', + 'tab', + 'tablist', + 'tabpanel', + 'term', + 'textbox', + 'timer', + 'toolbar', + 'tooltip', + 'tree', + 'treegrid', + 'treeitem', +]; + +const a11y_required_content = [ + // anchor-has-content + 'a', + // heading-has-content + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', +]; + +const a11y_distracting_elements = ['blink', 'marquee']; + +const a11y_nested_implicit_semantics = new Map([ + ['header', 'banner'], + ['footer', 'contentinfo'], +]); +const a11y_implicit_semantics = new Map([ + ['a', 'link'], + ['area', 'link'], + ['article', 'article'], + ['aside', 'complementary'], + ['body', 'document'], + ['button', 'button'], + ['datalist', 'listbox'], + ['dd', 'definition'], + ['dfn', 'term'], + ['dialog', 'dialog'], + ['details', 'group'], + ['dt', 'term'], + ['fieldset', 'group'], + ['figure', 'figure'], + ['form', 'form'], + ['h1', 'heading'], + ['h2', 'heading'], + ['h3', 'heading'], + ['h4', 'heading'], + ['h5', 'heading'], + ['h6', 'heading'], + ['hr', 'separator'], + ['img', 'img'], + ['li', 'listitem'], + ['link', 'link'], + ['main', 'main'], + ['menu', 'list'], + ['meter', 'progressbar'], + ['nav', 'navigation'], + ['ol', 'list'], + ['option', 'option'], + ['optgroup', 'group'], + ['output', 'status'], + ['progress', 'progressbar'], + ['section', 'region'], + ['summary', 'button'], + ['table', 'table'], + ['tbody', 'rowgroup'], + ['textarea', 'textbox'], + ['tfoot', 'rowgroup'], + ['thead', 'rowgroup'], + ['tr', 'row'], + ['ul', 'list'], +]); +const menuitem_type_to_implicit_role = new Map([ + ['command', 'menuitem'], + ['checkbox', 'menuitemcheckbox'], + ['radio', 'menuitemradio'], +]); +const input_type_to_implicit_role = new Map([ + ['button', 'button'], + ['image', 'button'], + ['reset', 'button'], + ['submit', 'button'], + ['checkbox', 'checkbox'], + ['radio', 'radio'], + ['range', 'slider'], + ['number', 'spinbutton'], + ['email', 'textbox'], + ['search', 'searchbox'], + ['tel', 'textbox'], + ['text', 'textbox'], + ['url', 'textbox'], +]); + +const ariaAttributes = new Set( + 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby description details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split( + ' ' + ) +); + +const ariaRoles = new Set( + 'alert alertdialog application article banner button cell checkbox columnheader combobox complementary contentinfo definition dialog directory document feed figure form grid gridcell group heading img link list listbox listitem log main marquee math menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status tab tablist tabpanel textbox timer toolbar tooltip tree treegrid treeitem'.split( + ' ' + ) +); + +export const a11y: AuditRuleWithSelector[] = [ + { + code: 'a11y-accesskey', + title: 'Avoid using `accesskey`', + message: + "The `accesskey` attribute can cause accessibility issues. The shortcuts can conflict with the browser's or operating system's shortcuts, and they are difficult for users to discover and use.", + selector: '[accesskey]', + }, + { + code: 'a11y-aria-activedescendant-has-tabindex', + title: 'Elements with attribute `aria-activedescendant` must be tabbable', + message: + 'This element must either have an inherent `tabindex` or declare `tabindex` as an attribute.', + selector: '[aria-activedescendant]', + match(element) { + if (!(element as HTMLElement).tabIndex && !element.hasAttribute('tabindex')) return true; + }, + }, + { + code: 'a11y-aria-attributes', + title: 'Element does not support ARIA roles.', + message: 'Elements like `meta`, `html`, `script`, `style` do not support having ARIA roles.', + selector: ':is(meta, html, script, style)[role]', + match(element) { + for (const attribute of element.attributes) { + if (attribute.name.startsWith('aria-')) return true; + } + }, + }, + { + code: 'a11y-autofocus', + title: 'Avoid using `autofocus`', + message: + 'The `autofocus` attribute can cause accessibility issues, as it can cause the focus to move around unexpectedly for screen reader users.', + selector: '[autofocus]', + }, + { + code: 'a11y-distracting-elements', + title: 'Distracting elements should not be used', + message: + 'Elements that can be visually distracting like `<marquee>` or `<blink>` can cause accessibility issues for visually impaired users and should be avoided.', + selector: `:is(${a11y_distracting_elements.join(',')})`, + }, + { + code: 'a11y-hidden', + title: 'Certain DOM elements are useful for screen reader navigation and should not be hidden', + message: (element) => `${element.localName} element should not be hidden.`, + selector: '[aria-hidden]:is(h1,h2,h3,h4,h5,h6)', + }, + { + code: 'a11y-img-redundant-alt', + title: 'Redundant text in alt attribute', + message: + 'Screen readers already announce `img` elements as an image. There is no need to use words such as "image", "photo", and/or "picture".', + selector: 'img[alt]:not([aria-hidden])', + match: (img: HTMLImageElement) => /\b(image|picture|photo)\b/i.test(img.alt), + }, + { + code: 'a11y-incorrect-aria-attribute-type', + title: 'Incorrect value for ARIA attribute.', + message: '`aria-hidden` should only receive a boolean.', + selector: '[aria-hidden]', + match(element) { + const value = element.getAttribute('aria-hidden'); + if (!value) return true; + if (!['true', 'false'].includes(value)) return true; + }, + }, + { + code: 'a11y-invalid-attribute', + title: 'Attributes important for accessibility should have a valid value', + message: "`href` should not be empty, `'#'`, or `javascript:`.", + selector: 'a[href]:is([href=""], [href="#"], [href^="javascript:" i])', + }, + { + code: 'a11y-label-has-associated-control', + title: '`label` tag should have an associated control and a text content.', + message: + 'The `label` tag must be associated with a control using either `for` or having a nested input. Additionally, the `label` tag must have text content.', + selector: 'label:not([for])', + match(element) { + const inputChild = element.querySelector('input'); + if (!inputChild?.textContent) return true; + }, + }, + { + code: 'a11y-media-has-caption', + title: 'Unmuted video elements should have captions', + message: + 'Videos without captions can be difficult for deaf and hard-of-hearing users to follow along with. If the video does not need captions, add the `muted` attribute.', + selector: 'video:not([muted])', + match(element) { + const tracks = element.querySelectorAll('track'); + if (!tracks.length) return true; + + const hasCaptionTrack = Array.from(tracks).some( + (track) => track.getAttribute('kind') === 'captions' + ); + + return !hasCaptionTrack; + }, + }, + { + code: 'a11y-misplaced-scope', + title: 'The `scope` attribute should only be used on `<th>` elements', + message: + 'The `scope` attribute tells the browser and screen readers how to navigate tables. In HTML5, it should only be used on `<th>` elements.', + selector: ':not(th)[scope]', + }, + { + code: 'a11y-missing-attribute', + title: 'Required attributes missing.', + message: (element) => { + const requiredAttributes = + a11y_required_attributes[element.localName as keyof typeof a11y_required_attributes]; + + const missingAttributes = requiredAttributes.filter( + (attribute) => !element.hasAttribute(attribute) + ); + + return `${ + element.localName + } element is missing required attributes for accessibility: ${missingAttributes.join(', ')} `; + }, + selector: Object.keys(a11y_required_attributes).join(','), + match(element) { + const requiredAttributes = + a11y_required_attributes[element.localName as keyof typeof a11y_required_attributes]; + + if (!requiredAttributes) return true; + for (const attribute of requiredAttributes) { + if (!element.hasAttribute(attribute)) return true; + } + + return false; + }, + }, + { + code: 'a11y-missing-content', + title: 'Missing content on element important for accessibility', + message: 'Headings and anchors must have content to be accessible.', + selector: a11y_required_content.join(','), + match(element) { + if (!element.textContent) return true; + }, + }, + { + code: 'a11y-no-redundant-roles', + title: 'HTML element has redundant ARIA roles', + message: + 'Giving these elements an ARIA role that is already set by the browser has no effect and is redundant.', + selector: [...a11y_implicit_semantics.keys()].join(','), + match(element) { + const role = element.getAttribute('role'); + + if (element.localName === 'input') { + const type = element.getAttribute('type'); + if (!type) return true; + + const implicitRoleForType = input_type_to_implicit_role.get(type); + if (!implicitRoleForType) return true; + + if (role === implicitRoleForType) return false; + } + + // TODO: Handle menuitem and elements that inherit their role from their parent + + const implicitRole = a11y_implicit_semantics.get(element.localName); + if (!implicitRole) return true; + + if (role === implicitRole) return false; + }, + }, + { + code: 'a11y-no-interactive-element-to-noninteractive-role', + title: 'Non-interactive ARIA role used on interactive HTML element.', + message: + 'Interactive HTML elements like `<a>` and `<button>` cannot use non-interactive roles like `heading`, `list`, `menu`, and `toolbar`.', + selector: `[role]:is(${interactiveElements.join(',')})`, + match(element) { + const role = element.getAttribute('role'); + if (!role) return false; + if (!ariaRoles.has(role)) return false; + + if (aria_non_interactive_roles.includes(role)) return true; + }, + }, + { + code: 'a11y-no-noninteractive-element-to-interactive-role', + title: 'Interactive ARIA role used on non-interactive HTML element.', + message: + 'Interactive roles should not be used to convert a non-interactive element to an interactive element', + selector: `[role]:not(${interactiveElements.join(',')})`, + match(element) { + const role = element.getAttribute('role'); + if (!role) return false; + if (!ariaRoles.has(role)) return false; + const exceptions = + a11y_non_interactive_element_to_interactive_role_exceptions[ + element.localName as keyof typeof a11y_non_interactive_element_to_interactive_role_exceptions + ]; + if (exceptions?.includes(role)) return false; + + if (!aria_non_interactive_roles.includes(role)) return true; + }, + }, + { + code: 'a11y-no-noninteractive-tabindex', + title: 'Invalid `tabindex` on non-interactive element', + message: (element) => `${element.localName} elements should not have \`tabindex\` attribute`, + selector: '[tabindex]', + match(element) { + // Scrollable elements are considered interactive + // See: https://www.w3.org/WAI/standards-guidelines/act/rules/0ssw9k/proposed/ + const isScrollable = + element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth; + if (isScrollable) return false; + + if (!interactiveElements.includes(element.localName)) return true; + }, + }, + { + code: 'a11y-positive-tabindex', + title: 'Avoid positive `tabindex` property values', + message: + 'This will move elements out of the expected tab order, creating a confusing experience for keyboard users.', + selector: '[tabindex]:not([tabindex="-1"]):not([tabindex="0"])', + }, + { + code: 'a11y-structure', + title: 'Invalid DOM structure', + message: + 'The DOM structure must be valid for accessibility of the page, for example `figcaption` must be a direct child of `figure`.', + selector: 'figcaption:not(figure > figcaption)', + }, + { + code: 'a11y-unknown-aria-attribute', + title: 'Unknown ARIA attribute', + message: 'ARIA attributes prefixed with `aria-` must be valid, non-abstract ARIA attributes.', + selector: '*', + match(element) { + for (const attribute of element.attributes) { + if (attribute.name.startsWith('aria-')) { + if (!ariaAttributes.has(attribute.name.slice('aria-'.length))) return true; + } + } + }, + }, + { + code: 'a11y-unknown-role', + title: 'Unknown ARIA role', + message: 'ARIA roles must be valid, non-abstract ARIA roles.', + selector: '[role]', + match(element) { + const role = element.getAttribute('role'); + if (!role) return true; + if (!ariaRoles.has(role)) return true; + }, + }, +]; + +/** + * Exceptions to the rule which follows common A11y conventions + * TODO make this configurable by the user + * @type {Record<string, string[]>} + */ +const a11y_non_interactive_element_to_interactive_role_exceptions = { + ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'], + ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'], + li: ['menuitem', 'option', 'row', 'tab', 'treeitem'], + table: ['grid'], + td: ['gridcell'], + fieldset: ['radiogroup', 'presentation'], +}; diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/audit/index.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/audit/index.ts new file mode 100644 index 0000000000000..175fe0ab66c1d --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/audit/index.ts @@ -0,0 +1,266 @@ +import type { DevOverlayMetadata, DevOverlayPlugin } from '../../../../../@types/astro.js'; +import type { DevOverlayHighlight } from '../../ui-library/highlight.js'; +import { + attachTooltipToHighlight, + createHighlight, + getElementsPositionInDocument, + positionHighlight, +} from '../utils/highlight.js'; +import { createWindowElement } from '../utils/window.js'; +import { a11y } from './a11y.js'; + +const icon = + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 1 20 16"><path fill="#fff" d="M.6 2A1.1 1.1 0 0 1 1.7.9h16.6a1.1 1.1 0 1 1 0 2.2H1.6A1.1 1.1 0 0 1 .8 2Zm1.1 7.1h6a1.1 1.1 0 0 0 0-2.2h-6a1.1 1.1 0 0 0 0 2.2ZM9.3 13H1.8a1.1 1.1 0 1 0 0 2.2h7.5a1.1 1.1 0 1 0 0-2.2Zm11.3 1.9a1.1 1.1 0 0 1-1.5 0l-1.7-1.7a4.1 4.1 0 1 1 1.6-1.6l1.6 1.7a1.1 1.1 0 0 1 0 1.6Zm-5.3-3.4a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8Z"/></svg>'; + +type DynamicString = string | ((element: Element) => string); + +export interface AuditRule { + code: string; + title: DynamicString; + message: DynamicString; +} + +export interface ResolvedAuditRule { + code: string; + title: string; + message: string; +} + +export interface AuditRuleWithSelector extends AuditRule { + selector: string; + match?: (element: Element) => boolean | null | undefined | void; +} + +const rules = [...a11y]; + +const dynamicAuditRuleKeys: Array<keyof AuditRule> = ['title', 'message']; +function resolveAuditRule(rule: AuditRule, element: Element): ResolvedAuditRule { + let resolved: ResolvedAuditRule = { ...rule } as any; + for (const key of dynamicAuditRuleKeys) { + const value = rule[key]; + if (typeof value === 'string') continue; + resolved[key] = value(element); + } + return resolved; +} + +export default { + id: 'astro:audit', + name: 'Audit', + icon: icon, + async init(canvas, eventTarget) { + let audits: { highlightElement: DevOverlayHighlight; auditedElement: HTMLElement }[] = []; + + await lint(); + + document.addEventListener('astro:after-swap', async () => lint()); + document.addEventListener('astro:page-load', async () => refreshLintPositions); + + function onPageClick(event: MouseEvent) { + const target = event.target as Element | null; + if (!target) return; + if (!target.closest) return; + if (target.closest('astro-dev-toolbar')) return; + eventTarget.dispatchEvent( + new CustomEvent('toggle-plugin', { + detail: { + state: false, + }, + }) + ); + } + eventTarget.addEventListener('plugin-toggled', (event: any) => { + if (event.detail.state === true) { + document.addEventListener('click', onPageClick, true); + } else { + document.removeEventListener('click', onPageClick, true); + } + }); + + async function lint() { + audits.forEach(({ highlightElement }) => { + highlightElement.remove(); + }); + audits = []; + canvas.getElementById('no-audit')?.remove(); + const selectorCache = new Map<string, NodeListOf<Element>>(); + + for (const rule of rules) { + const elements = + selectorCache.get(rule.selector) ?? document.querySelectorAll(rule.selector); + let matches: Element[] = []; + if (typeof rule.match === 'undefined') { + matches = Array.from(elements); + } else { + for (const element of elements) { + if (rule.match(element)) { + matches.push(element); + } + } + } + for (const element of matches) { + await createAuditProblem(rule, element); + } + } + + if (audits.length > 0) { + eventTarget.dispatchEvent( + new CustomEvent('toggle-notification', { + detail: { + state: true, + }, + }) + ); + } else { + eventTarget.dispatchEvent( + new CustomEvent('toggle-notification', { + detail: { + state: false, + }, + }) + ); + + const window = createWindowElement( + `<style> + header { + display: flex; + } + + h1 { + display: flex; + align-items: center; + gap: 8px; + font-weight: 600; + color: #fff; + margin: 0; + font-size: 22px; + } + + astro-dev-toolbar-icon { + width: 1em; + height: 1em; + padding: 8px; + display: block; + background: green; + border-radius: 9999px; + } + </style> + <header> + <h1><astro-dev-toolbar-icon icon="check-circle"></astro-dev-toolbar-icon>No accessibility issues detected.</h1> + </header> + <p> + Nice work! This app scans the page and highlights common accessibility issues for you, like a missing "alt" attribute on an image. + </p> + ` + ); + + canvas.append(window); + } + + (['scroll', 'resize'] as const).forEach((event) => { + window.addEventListener(event, refreshLintPositions); + }); + } + + function refreshLintPositions() { + const noAuditBlock = canvas.getElementById('no-audit'); + if (noAuditBlock) { + const devOverlayRect = document + .querySelector('astro-dev-toolbar') + ?.shadowRoot.querySelector('#dev-overlay') + ?.getBoundingClientRect(); + + noAuditBlock.style.top = `${ + (devOverlayRect?.top ?? 0) - (devOverlayRect?.height ?? 0) - 16 + }px`; + } + + audits.forEach(({ highlightElement, auditedElement }) => { + const rect = auditedElement.getBoundingClientRect(); + positionHighlight(highlightElement, rect); + }); + } + + async function createAuditProblem(rule: AuditRule, originalElement: Element) { + const computedStyle = window.getComputedStyle(originalElement); + const targetedElement = (originalElement.children[0] as HTMLElement) || originalElement; + + // If the element is hidden, don't do anything + if (targetedElement.offsetParent === null || computedStyle.display === 'none') { + return; + } + + // If the element is an image but not yet loaded, ignore it + // TODO: We shouldn't ignore this, because it is valid for an image to not be loaded at start (e.g. lazy loading) + if (originalElement.nodeName === 'IMG' && !(originalElement as HTMLImageElement).complete) { + return; + } + + const rect = originalElement.getBoundingClientRect(); + const highlight = createHighlight(rect, 'warning'); + const tooltip = buildAuditTooltip(rule, originalElement); + + // Set the highlight/tooltip as being fixed position the highlighted element + // is fixed. We do this so that we don't mistakenly take scroll position + // into account when setting the tooltip/highlight positioning. + // + // We only do this once due to how expensive computed styles are to calculate, + // and are unlikely to change. If that turns out to be wrong, reconsider this. + const { isFixed } = getElementsPositionInDocument(originalElement); + if (isFixed) { + tooltip.style.position = highlight.style.position = 'fixed'; + } + + attachTooltipToHighlight(highlight, tooltip, originalElement); + + canvas.append(highlight); + audits.push({ highlightElement: highlight, auditedElement: originalElement as HTMLElement }); + } + + function buildAuditTooltip(rule: AuditRule, element: Element) { + const tooltip = document.createElement('astro-dev-toolbar-tooltip'); + const { title, message } = resolveAuditRule(rule, element); + + tooltip.sections = [ + { + icon: 'warning', + title: escapeHtml(title), + }, + { + content: escapeHtml(message), + }, + ]; + + const elementFile = element.getAttribute('data-astro-source-file'); + const elementPosition = element.getAttribute('data-astro-source-loc'); + + if (elementFile) { + const elementFileWithPosition = + elementFile + (elementPosition ? ':' + elementPosition : ''); + + tooltip.sections.push({ + content: elementFileWithPosition.slice( + (window as DevOverlayMetadata).__astro_dev_overlay__.root.length - 1 // We want to keep the final slash, so minus one. + ), + clickDescription: 'Click to go to file', + async clickAction() { + // NOTE: The path here has to be absolute and without any errors (no double slashes etc) + // or Vite will silently fail to open the file. Quite annoying. + await fetch('/__open-in-editor?file=' + encodeURIComponent(elementFileWithPosition)); + }, + }); + } + + return tooltip; + } + + function escapeHtml(unsafe: string) { + return unsafe + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + }, +} satisfies DevOverlayPlugin; diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts index e0d3384463ef3..dc5fe4ae3637c 100644 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts @@ -1,6 +1,6 @@ import type { DevOverlayPlugin } from '../../../../@types/astro.js'; import { settings, type Settings } from '../settings.js'; -import { createWindowWithTransition, waitForTransition } from './utils/window.js'; +import { createWindowElement } from './utils/window.js'; interface SettingRow { name: string; @@ -13,23 +13,33 @@ interface SettingRow { const settingsRows = [ { name: 'Disable notifications', - description: 'Notification bubbles will not be shown when this is enabled.', + description: 'Hide notification badges in the toolbar.', input: 'checkbox', settingKey: 'disablePluginNotification', changeEvent: (evt: Event) => { if (evt.currentTarget instanceof HTMLInputElement) { + const devOverlay = document.querySelector('astro-dev-toolbar'); + + if (devOverlay) { + devOverlay.setNotificationVisible(!evt.currentTarget.checked); + } + settings.updateSetting('disablePluginNotification', evt.currentTarget.checked); + const action = evt.currentTarget.checked ? 'disabled' : 'enabled'; + settings.log(`Plugin notification badges ${action}`); } }, }, { name: 'Verbose logging', - description: 'Log additional information to the console.', + description: 'Logs dev overlay events in the browser console.', input: 'checkbox', settingKey: 'verbose', changeEvent: (evt: Event) => { if (evt.currentTarget instanceof HTMLInputElement) { settings.updateSetting('verbose', evt.currentTarget.checked); + const action = evt.currentTarget.checked ? 'enabled' : 'disabled'; + settings.log(`Verbose logging ${action}`); } }, }, @@ -37,7 +47,7 @@ const settingsRows = [ export default { id: 'astro:settings', - name: 'Overlay settings', + name: 'Settings', icon: 'gear', init(canvas) { createSettingsWindow(); @@ -45,10 +55,17 @@ export default { document.addEventListener('astro:after-swap', createSettingsWindow); function createSettingsWindow() { - const window = createWindowWithTransition( - 'Settings', - 'gear', + const windowElement = createWindowElement( `<style> + :host astro-dev-toolbar-window { + height: 480px; + + --color-purple: rgba(224, 204, 250, 1); + } + header { + display: flex; + } + h2, h3 { margin-top: 0; } @@ -63,22 +80,73 @@ export default { font-size: 16px; font-weight: 400; color: white; - margin-bottom: 0; + margin-bottom: 4px; } label { - font-size: 15px; + font-size: 14px; line-height: 1.5rem; } + + h1 { + display: flex; + align-items: center; + gap: 8px; + font-weight: 600; + color: #fff; + margin: 0; + font-size: 22px; + } + + astro-dev-toolbar-icon { + width: 1em; + height: 1em; + display: block; + } + + code { + color: var(--color-purple); + border-color: #343841; + border-style: solid; + border-width: 1px; + border-radius: .4em; + background-color: #24262D; + padding: .3em; + } + + label > section { + max-width: 67%; + } + p { + line-height: 1.5em; + } + a, a:visited { + color: var(--color-purple); + } + a:hover { + color: #f4ecfd; + } </style> - <h2>General</h2> - `, - settingsRows.flatMap((setting) => [ - getElementForSettingAsString(setting), - document.createElement('hr'), - ]) + <header> + <h1><astro-dev-toolbar-icon icon="gear"></astro-dev-toolbar-icon> Settings</h1> + </header> + + <hr id="general"/> + + <label class="setting-row"> + <section> + <h3>Hide toolbar</h3> + Run <code>astro preferences disable devToolbar</code> in your terminal to disable the toolbar. <a href="https://docs.astro.build/en/reference/cli-reference/#astro-preferences" target="_blank">Learn more</a>. + </section> + </label> + ` ); - canvas.append(window); + const general = windowElement.querySelector('#general')!; + for (const settingsRow of settingsRows) { + general.after(document.createElement('hr')); + general.after(getElementForSettingAsString(settingsRow)); + } + canvas.append(windowElement); function getElementForSettingAsString(setting: SettingRow) { const label = document.createElement('label'); @@ -89,7 +157,7 @@ export default { switch (setting.input) { case 'checkbox': { - const astroToggle = document.createElement('astro-dev-overlay-toggle'); + const astroToggle = document.createElement('astro-dev-toolbar-toggle'); astroToggle.input.addEventListener('change', setting.changeEvent); astroToggle.input.checked = settings.config[setting.settingKey]; label.append(astroToggle); @@ -100,7 +168,4 @@ export default { } } }, - async beforeTogglingOff(canvas) { - return await waitForTransition(canvas); - }, } satisfies DevOverlayPlugin; diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/utils/highlight.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/utils/highlight.ts index 3af467ecdc15b..6ad37aad2af24 100644 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/utils/highlight.ts +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/utils/highlight.ts @@ -2,7 +2,7 @@ import type { DevOverlayHighlight } from '../../ui-library/highlight.js'; import type { Icon } from '../../ui-library/icons.js'; export function createHighlight(rect: DOMRect, icon?: Icon) { - const highlight = document.createElement('astro-dev-overlay-highlight'); + const highlight = document.createElement('astro-dev-toolbar-highlight'); if (icon) highlight.icon = icon; highlight.tabIndex = 0; @@ -15,10 +15,30 @@ export function createHighlight(rect: DOMRect, icon?: Icon) { return highlight; } +// Figures out the element's position, based on it's parents. +export function getElementsPositionInDocument(el: Element) { + let isFixed = false; + let current: Element | ParentNode | null = el; + while (current instanceof Element) { + // all the way up the tree. We are only doing so when the app initializes, so the cost is one-time + // If perf becomes an issue we'll want to refactor this somehow so that it reads this info in a rAF + let style = getComputedStyle(current); + if (style.position === 'fixed') { + isFixed = true; + } + current = current.parentNode; + } + return { + isFixed, + }; +} + export function positionHighlight(highlight: DevOverlayHighlight, rect: DOMRect) { highlight.style.display = 'block'; + // If the highlight is fixed, don't position based on scroll + const scrollY = highlight.style.position === 'fixed' ? 0 : window.scrollY; // Make an highlight that is 10px bigger than the element on all sides - highlight.style.top = `${Math.max(rect.top + window.scrollY - 10, 0)}px`; + highlight.style.top = `${Math.max(rect.top + scrollY - 10, 0)}px`; highlight.style.left = `${Math.max(rect.left + window.scrollX - 10, 0)}px`; highlight.style.width = `${rect.width + 15}px`; highlight.style.height = `${rect.height + 15}px`; diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/utils/icons.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/utils/icons.ts new file mode 100644 index 0000000000000..ec5a34ad89a10 --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/utils/icons.ts @@ -0,0 +1,43 @@ +import type { Integration } from '../astro.js'; + +function randomFromArray<T>(list: T[]) { + return list[Math.floor(Math.random() * list.length)]; +} + +const categoryIcons = new Map( + Object.entries({ + frameworks: ['puzzle', 'grid'], + adapters: ['puzzle', 'grid', 'compress'], + 'css+ui': ['compress', 'grid', 'image', 'resizeImage', 'puzzle'], + 'performance+seo': ['approveUser', 'checkCircle', 'compress', 'robot', 'searchFile', 'sitemap'], + analytics: ['checkCircle', 'compress', 'searchFile'], + accessibility: ['approveUser', 'checkCircle'], + other: ['checkCircle', 'grid', 'puzzle', 'sitemap'], + }) +); + +export function iconForIntegration(integration: Integration) { + const icons = integration.categories + .filter((category: string) => categoryIcons.has(category)) + .map((category: string) => categoryIcons.get(category)!) + .flat(); + + return randomFromArray(icons); +} + +const iconColors = [ + '#BC52EE', + '#6D6AF0', + '#52EEBD', + '#52B7EE', + '#52EE55', + '#B7EE52', + '#EEBD52', + '#EE5552', + '#EE52B7', + '#858B98', +]; + +export function colorForIntegration() { + return randomFromArray(iconColors); +} diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/utils/window.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/utils/window.ts index 04f09d6e64735..fb107e19c8027 100644 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/utils/window.ts +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/utils/window.ts @@ -1,56 +1,5 @@ -import type { Icon } from '../../ui-library/icons.js'; - -export function createWindowWithTransition( - title: string, - icon: Icon, - windowContent: string, - addedNodes: Node[] = [] -): DocumentFragment { - const fragment = document.createDocumentFragment(); - - const style = document.createElement('style'); - style.textContent = ` - :host { - opacity: 0; - transition: opacity 0.15s ease-in-out; - } - - :host([data-active]) { - opacity: 1; - } - - @media screen and (prefers-reduced-motion: no-preference) { - :host astro-dev-overlay-window { - transform: translateY(55px) translate(-50%, -50%); - transition: transform 0.15s ease-in-out; - transform-origin: center bottom; - } - - :host([data-active]) astro-dev-overlay-window { - transform: translateY(0) translate(-50%, -50%); - } - } - `; - fragment.append(style); - - const window = document.createElement('astro-dev-overlay-window'); - window.windowTitle = title; - window.windowIcon = icon; - window.innerHTML = windowContent; - - window.append(...addedNodes); - - fragment.append(window); - - return fragment; -} - -export async function waitForTransition(canvas: ShadowRoot): Promise<boolean> { - canvas.host?.removeAttribute('data-active'); - - await new Promise((resolve) => { - canvas.host.addEventListener('transitionend', resolve); - }); - - return true; +export function createWindowElement(content: string) { + const windowElement = document.createElement('astro-dev-toolbar-window'); + windowElement.innerHTML = content; + return windowElement; } diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/xray.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/xray.ts index ab927bacc2353..edc038df7afeb 100644 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/xray.ts +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/xray.ts @@ -1,15 +1,21 @@ import type { DevOverlayMetadata, DevOverlayPlugin } from '../../../../@types/astro.js'; import type { DevOverlayHighlight } from '../ui-library/highlight.js'; -import { attachTooltipToHighlight, createHighlight, positionHighlight } from './utils/highlight.js'; +import { + attachTooltipToHighlight, + createHighlight, + getElementsPositionInDocument, + positionHighlight, +} from './utils/highlight.js'; +import { createWindowElement } from './utils/window.js'; const icon = '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#fff" d="M7.9 1.5v-.4a1.1 1.1 0 0 1 2.2 0v.4a1.1 1.1 0 1 1-2.2 0Zm-6.4 8.6a1.1 1.1 0 1 0 0-2.2h-.4a1.1 1.1 0 0 0 0 2.2h.4ZM12 3.7a1.1 1.1 0 0 0 1.4-.7l.4-1.1a1.1 1.1 0 0 0-2.1-.8l-.4 1.2a1.1 1.1 0 0 0 .7 1.4Zm-9.7 7.6-1.2.4a1.1 1.1 0 1 0 .8 2.1l1-.4a1.1 1.1 0 1 0-.6-2ZM20.8 17a1.9 1.9 0 0 1 0 2.6l-1.2 1.2a1.9 1.9 0 0 1-2.6 0l-4.3-4.2-1.6 3.6a1.9 1.9 0 0 1-1.7 1.2A1.9 1.9 0 0 1 7.5 20L2.7 5a1.9 1.9 0 0 1 2.4-2.4l15 5a1.9 1.9 0 0 1 .2 3.4l-3.7 1.6 4.2 4.3ZM19 18.3 14.6 14a1.9 1.9 0 0 1 .6-3l3.2-1.5L5.1 5.1l4.3 13.3 1.5-3.2a1.9 1.9 0 0 1 3-.6l4.4 4.4.7-.7Z"/></svg>'; export default { id: 'astro:xray', - name: 'Xray', + name: 'Inspect', icon: icon, - init(canvas) { + init(canvas, eventTarget) { let islandsOverlays: { highlightElement: DevOverlayHighlight; island: HTMLElement }[] = []; addIslandsOverlay(); @@ -17,8 +23,31 @@ export default { document.addEventListener('astro:after-swap', addIslandsOverlay); document.addEventListener('astro:page-load', refreshIslandsOverlayPositions); + function onPageClick(event: MouseEvent) { + const target = event.target as Element | null; + if (!target) return; + if (!target.closest) return; + if (target.closest('astro-dev-toolbar')) return; + event.preventDefault(); + event.stopPropagation(); + eventTarget.dispatchEvent( + new CustomEvent('toggle-plugin', { + detail: { + state: false, + }, + }) + ); + } + + eventTarget.addEventListener('plugin-toggled', (event: any) => { + if (event.detail.state === true) { + document.addEventListener('click', onPageClick, true); + } else { + document.removeEventListener('click', onPageClick, true); + } + }); + function addIslandsOverlay() { - initStyle(); islandsOverlays.forEach(({ highlightElement }) => { highlightElement.remove(); }); @@ -26,6 +55,45 @@ export default { const islands = document.querySelectorAll<HTMLElement>('astro-island'); + if (islands.length === 0) { + const window = createWindowElement( + `<style> + header { + display: flex; + } + + h1 { + display: flex; + align-items: center; + gap: 8px; + font-weight: 600; + color: #fff; + margin: 0; + font-size: 22px; + } + + astro-dev-toolbar-icon { + width: 1em; + height: 1em; + padding: 8px; + display: block; + background: #5f9ea0; + border-radius: 9999px; + } + </style> + <header> + <h1><astro-dev-toolbar-icon icon="lightbulb"></astro-dev-toolbar-icon>No islands detected.</h1> + </header> + <p> + It looks like there are no interactive component islands on this page. Did you forget to add a client directive to your interactive UI component? + </p> + ` + ); + + canvas.append(window); + return; + } + islands.forEach((island) => { const computedStyle = window.getComputedStyle(island); const islandElement = (island.children[0] as HTMLElement) || island; @@ -39,8 +107,19 @@ export default { const rect = islandElement.getBoundingClientRect(); const highlight = createHighlight(rect); const tooltip = buildIslandTooltip(island); - attachTooltipToHighlight(highlight, tooltip, islandElement); + // Set the highlight/tooltip as being fixed position the highlighted element + // is fixed. We do this so that we don't mistakenly take scroll position + // into account when setting the tooltip/highlight positioning. + // + // We only do this once due to how expensive computed styles are to calculate, + // and are unlikely to change. If that turns out to be wrong, reconsider this. + const { isFixed } = getElementsPositionInDocument(islandElement); + if (isFixed) { + tooltip.style.position = highlight.style.position = 'fixed'; + } + + attachTooltipToHighlight(highlight, tooltip, islandElement); canvas.append(highlight); islandsOverlays.push({ highlightElement: highlight, island: islandElement }); }); @@ -58,7 +137,7 @@ export default { } function buildIslandTooltip(island: HTMLElement) { - const tooltip = document.createElement('astro-dev-overlay-tooltip'); + const tooltip = document.createElement('astro-dev-toolbar-tooltip'); tooltip.sections = []; const islandProps = island.getAttribute('props') @@ -74,13 +153,19 @@ export default { }); } - // Add the props if we have any - if (Object.keys(islandProps).length > 0) { + // Display the props if we have any + // Ignore the "data-astro-cid-XXXXXX" prop (internal) + const islandPropsEntries = Object.entries(islandProps).filter( + (prop: any) => !prop[0].startsWith('data-astro-cid-') + ); + if (islandPropsEntries.length > 0) { tooltip.sections.push({ title: 'Props', - content: `${Object.entries(islandProps) - .map((prop) => `<code>${prop[0]}=${getPropValue(prop[1] as any)}</code>`) - .join(', ')}`, + content: `<pre><code>${JSON.stringify( + Object.fromEntries(islandPropsEntries.map((prop: any) => [prop[0], prop[1][1]])), + undefined, + 2 + )}</code></pre>`, }); } @@ -106,35 +191,5 @@ export default { return tooltip; } - - function getPropValue(prop: [number, any]) { - const [_, value] = prop; - return JSON.stringify(value, null, 2); - } - - function initStyle() { - const style = document.createElement('style'); - style.textContent = ` - :host { - opacity: 0; - transition: opacity 0.1s ease-in-out; - } - - :host([data-active]) { - opacity: 1; - } - `; - - canvas.append(style); - } - }, - async beforeTogglingOff(canvas) { - canvas.host?.removeAttribute('data-active'); - - await new Promise((resolve) => { - canvas.host.addEventListener('transitionend', resolve); - }); - - return true; }, } satisfies DevOverlayPlugin; diff --git a/packages/astro/src/runtime/client/dev-overlay/settings.ts b/packages/astro/src/runtime/client/dev-overlay/settings.ts index 7ba12f2dbf6f3..d3f1c0d369891 100644 --- a/packages/astro/src/runtime/client/dev-overlay/settings.ts +++ b/packages/astro/src/runtime/client/dev-overlay/settings.ts @@ -23,10 +23,20 @@ function getSettings() { localStorage.setItem('astro:dev-overlay:settings', JSON.stringify(_settings)); } + function log(message: string) { + // eslint-disable-next-line no-console + console.log( + `%cAstro`, + 'background: linear-gradient(66.77deg, #D83333 0%, #F041FF 100%); color: white; padding-inline: 4px; border-radius: 2px; font-family: monospace;', + message + ); + } + return { get config() { return _settings; }, updateSetting, + log, }; } diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/badge.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/badge.ts new file mode 100644 index 0000000000000..5a8eea07ed9f8 --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/badge.ts @@ -0,0 +1,71 @@ +type BadgeSize = 'small' | 'large'; +type BadgeStyle = 'purple' | 'gray' | 'red' | 'green' | 'yellow'; + +export class DevOverlayBadge extends HTMLElement { + size: BadgeSize = 'small'; + badgeStyle: BadgeStyle = 'purple'; + + shadowRoot: ShadowRoot; + + constructor() { + super(); + this.shadowRoot = this.attachShadow({ mode: 'open' }); + + if (this.hasAttribute('size')) this.size = this.getAttribute('size') as BadgeSize; + + if (this.hasAttribute('badge-style')) + this.badgeStyle = this.getAttribute('badge-style') as BadgeStyle; + + const classes = [`badge--${this.size}`, `badge--${this.badgeStyle}`]; + this.shadowRoot.innerHTML = ` + <style> + .badge { + box-sizing: border-box; + border-radius: 4px; + border: 1px solid transparent; + padding: 8px; + font-size: 12px; + color: #fff; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + } + + .badge--large { + height: 24px; + } + + .badge--gray { + color: rgba(191, 193, 201, 1); + border-color: rgba(191, 193, 201, 1); + } + + .badge--purple { + color: rgba(224, 204, 250, 1); + border-color: rgba(113, 24, 226, 1); + } + + .badge--red { + color: rgba(249, 196, 215, 1); + border-color: rgba(179, 62, 102, 1); + } + + .badge--green { + color: rgba(213, 249, 196, 1); + border-color: rgba(61, 125, 31, 1); + } + + .badge--yellow { + color: rgba(249, 233, 196, 1); + border-color: rgba(181, 138, 45, 1); + } + </style> + + <div class="badge ${classes.join(' ')}"> + <slot></slot> + </div> + `; + } +} diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/button.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/button.ts new file mode 100644 index 0000000000000..f2bd75d70269b --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/button.ts @@ -0,0 +1,89 @@ +type ButtonSize = 'small' | 'medium' | 'large'; +type ButtonStyle = 'ghost' | 'outline' | 'purple' | 'gray' | 'red'; + +export class DevOverlayButton extends HTMLElement { + size: ButtonSize = 'small'; + buttonStyle: ButtonStyle = 'purple'; + + shadowRoot: ShadowRoot; + + constructor() { + super(); + this.shadowRoot = this.attachShadow({ mode: 'open' }); + + if (this.hasAttribute('size')) this.size = this.getAttribute('size') as ButtonSize; + + if (this.hasAttribute('button-style')) + this.buttonStyle = this.getAttribute('button-style') as ButtonStyle; + + const classes = [`button--${this.size}`, `button--${this.buttonStyle}`]; + + this.shadowRoot.innerHTML = ` + <style> + button { + border: 1px solid transparent; + color: #fff; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + } + + button:hover { + cursor: pointer; + } + + .button--small { + font-size: 12px; + padding: 4px 8px; + } + + .button--medium { + font-size: 14px; + padding: 8px 12px; + } + + .button--large { + font-size: 16px; + padding: 12px 16px; + } + + .button--ghost { + background: transparent; + } + + .button--outline { + background: transparent; + border-color: #fff; + } + + .button--purple { + background: rgba(113, 24, 226, 1); + border-color: rgba(224, 204, 250, 0.33); + } + + .button--gray { + background: rgba(52, 56, 65, 1); + border-color: rgba(71, 78, 94, 1); + } + + .button--red { + background: rgba(179, 62, 102, 1); + border-color: rgba(249, 196, 215, 0.33); + } + + ::slotted(astro-dev-overlay-icon), + ::slotted(astro-dev-toolbar-icon) { + display: inline-block; + height: 1em; + width: 1em; + margin-left: 0.5em; + } + </style> + + <button class="${classes.join(' ')}"> + <slot></slot> + </button> + `; + } +} diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/card.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/card.ts index 9d7062f8babfe..90d4739f165f3 100644 --- a/packages/astro/src/runtime/client/dev-overlay/ui-library/card.ts +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/card.ts @@ -1,8 +1,6 @@ -import { getIconElement, isDefinedIcon, type Icon } from './icons.js'; - export class DevOverlayCard extends HTMLElement { - icon?: Icon; link?: string | undefined | null; + clickAction?: () => void | (() => Promise<void>); shadowRoot: ShadowRoot; constructor() { @@ -10,26 +8,30 @@ export class DevOverlayCard extends HTMLElement { this.shadowRoot = this.attachShadow({ mode: 'open' }); this.link = this.getAttribute('link'); - this.icon = this.hasAttribute('icon') ? (this.getAttribute('icon') as Icon) : undefined; } connectedCallback() { - const element = this.link ? 'a' : 'button'; + const element = this.link ? 'a' : this.clickAction ? 'button' : 'div'; this.shadowRoot.innerHTML = ` <style> - a, button { + :host>a, :host>button, :host>div { + box-sizing: border-box; + padding: 16px; display: block; - padding: 40px 16px; border-radius: 8px; border: 1px solid rgba(35, 38, 45, 1); - color: #fff; - font-size: 16px; - font-weight: 600; - line-height: 19px; + color: rgba(191, 193, 201, 1); text-decoration: none; background-color: #13151A; box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.10), 0px 1px 2px 0px rgba(0, 0, 0, 0.10), 0px 4px 4px 0px rgba(0, 0, 0, 0.09), 0px 10px 6px 0px rgba(0, 0, 0, 0.05), 0px 17px 7px 0px rgba(0, 0, 0, 0.01), 0px 26px 7px 0px rgba(0, 0, 0, 0.00); + width: 100%; + height: 100%; + } + + h1, h2, h3, h4, h5, h6 { + color: #fff; + font-weight: 600; } a:hover, button:hover { @@ -49,26 +51,15 @@ export class DevOverlayCard extends HTMLElement { } </style> - <${element}${this.link ? ` href="${this.link}" target="_blank"` : ``}> - ${this.icon ? this.getElementForIcon(this.icon) : ''} - <span><slot /></span> + <${element}${this.link ? ` href="${this.link}" target="_blank"` : ``} id="astro-overlay-card"> + <slot /> </${element}> `; - } - getElementForIcon(icon: Icon) { - let iconElement; - if (isDefinedIcon(icon)) { - iconElement = getIconElement(icon); - } else { - iconElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - iconElement.setAttribute('viewBox', '0 0 16 16'); - iconElement.innerHTML = icon; + if (this.clickAction) { + this.shadowRoot + .getElementById('astro-overlay-card') + ?.addEventListener('click', this.clickAction); } - - iconElement?.style.setProperty('height', '24px'); - iconElement?.style.setProperty('width', '24px'); - - return iconElement?.outerHTML ?? ''; } } diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/highlight.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/highlight.ts index 7d91535e0a40e..16d02df0cc7a3 100644 --- a/packages/astro/src/runtime/client/dev-overlay/ui-library/highlight.ts +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/highlight.ts @@ -21,11 +21,13 @@ export class DevOverlayHighlight extends HTMLElement { width: 100%; height: 100%; position: absolute; + z-index: 2000000000; } .icon { width: 24px; height: 24px; + color: white; background: linear-gradient(0deg, #B33E66, #B33E66), linear-gradient(0deg, #351722, #351722); border: 1px solid rgba(53, 23, 34, 1); border-radius: 9999px; diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/icon.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/icon.ts new file mode 100644 index 0000000000000..3211e1857620b --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/icon.ts @@ -0,0 +1,51 @@ +import { getIconElement, isDefinedIcon, type Icon } from './icons.js'; + +export class DevOverlayIcon extends HTMLElement { + _icon: Icon | undefined = undefined; + shadowRoot: ShadowRoot; + + get icon() { + return this._icon; + } + set icon(name: Icon | undefined) { + this._icon = name; + this.buildTemplate(); + } + + constructor() { + super(); + + this.shadowRoot = this.attachShadow({ mode: 'open' }); + + if (this.hasAttribute('icon')) { + this.icon = this.getAttribute('icon') as Icon; + } else { + this.buildTemplate(); + } + } + + getIconHTML(icon: Icon | undefined) { + if (icon && isDefinedIcon(icon)) { + return getIconElement(icon)?.outerHTML ?? ''; + } + + // If the icon that was passed isn't one of the predefined one, assume that they're passing it in as a slot + return '<slot />'; + } + + buildTemplate() { + this.shadowRoot.innerHTML = ` + <style> + svg { + width: 100%; + height: 100%; + } + + @media (forced-colors: active) { + svg path[fill="#fff"] { + fill: black; + } + } + </style>\n${this.getIconHTML(this._icon)}`; + } +} diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/icons.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/icons.ts index d9445e44acf8a..28878ef11c6bb 100644 --- a/packages/astro/src/runtime/client/dev-overlay/ui-library/icons.ts +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/icons.ts @@ -5,10 +5,12 @@ export function isDefinedIcon(icon: Icon): icon is DefinedIcon { return icon in icons; } +export function getIconElement(name: DefinedIcon): SVGElement; +export function getIconElement(name: string & NonNullable<unknown>): undefined; export function getIconElement( - name: keyof typeof icons | (string & NonNullable<unknown>) + name: DefinedIcon | (string & NonNullable<unknown>) ): SVGElement | undefined { - const icon = icons[name as keyof typeof icons]; + const icon = icons[name as DefinedIcon]; if (!icon) { return undefined; @@ -22,15 +24,41 @@ export function getIconElement( const icons = { 'astro:logo': `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 85 107"><path fill="#fff" d="M27.6 91.1c-4.8-4.4-6.3-13.7-4.2-20.4 3.5 4.2 8.3 5.6 13.3 6.3 7.7 1.2 15.3.8 22.5-2.8l2.5-1.4c.7 2 .9 3.9.6 5.9-.6 4.9-3 8.7-6.9 11.5-1.5 1.2-3.2 2.2-4.8 3.3-4.9 3.3-6.2 7.2-4.4 12.9l.2.6a13 13 0 0 1-5.7-5 13.8 13.8 0 0 1-2.2-7.4c0-1.3 0-2.7-.2-4-.5-3.1-2-4.6-4.8-4.7a5.5 5.5 0 0 0-5.7 4.6l-.2.6Z"/><path fill="url(#a)" d="M27.6 91.1c-4.8-4.4-6.3-13.7-4.2-20.4 3.5 4.2 8.3 5.6 13.3 6.3 7.7 1.2 15.3.8 22.5-2.8l2.5-1.4c.7 2 .9 3.9.6 5.9-.6 4.9-3 8.7-6.9 11.5-1.5 1.2-3.2 2.2-4.8 3.3-4.9 3.3-6.2 7.2-4.4 12.9l.2.6a13 13 0 0 1-5.7-5 13.8 13.8 0 0 1-2.2-7.4c0-1.3 0-2.7-.2-4-.5-3.1-2-4.6-4.8-4.7a5.5 5.5 0 0 0-5.7 4.6l-.2.6Z"/><path fill="#fff" d="M0 69.6s14.3-7 28.7-7l10.8-33.5c.4-1.6 1.6-2.7 3-2.7 1.2 0 2.4 1.1 2.8 2.7l10.9 33.5c17 0 28.6 7 28.6 7L60.5 3.2c-.7-2-2-3.2-3.5-3.2H27.8c-1.6 0-2.7 1.3-3.4 3.2L0 69.6Z"/><defs><linearGradient id="a" x1="22.5" x2="69.1" y1="107" y2="84.9" gradientUnits="userSpaceOnUse"><stop stop-color="#D83333"/><stop offset="1" stop-color="#F041FF"/></linearGradient></defs></svg>`, - warning: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#fff" d="M8 .40625c-1.5019 0-2.97007.445366-4.21886 1.27978C2.53236 2.52044 1.55905 3.70642.984293 5.094.40954 6.48157.259159 8.00842.552165 9.48147.845172 10.9545 1.56841 12.3076 2.63041 13.3696c1.06201 1.062 2.41508 1.7852 3.88813 2.0782 1.47304.293 2.99989.1427 4.38746-.4321 1.3876-.5747 2.5736-1.5481 3.408-2.7968.8344-1.2488 1.2798-2.717 1.2798-4.2189-.0023-2.0133-.8031-3.9435-2.2267-5.36713C11.9435 1.20925 10.0133.408483 8 .40625ZM8 13.9062c-1.16814 0-2.31006-.3463-3.28133-.9953-.97128-.649-1.7283-1.5715-2.17533-2.6507-.44703-1.0792-.56399-2.26675-.3361-3.41245.22789-1.1457.79041-2.1981 1.61641-3.0241.82601-.826 1.8784-1.38852 3.0241-1.61641 1.1457-.2279 2.33325-.11093 3.41245.3361 1.0793.44703 2.0017 1.20405 2.6507 2.17532.649.97128.9954 2.11319.9954 3.28134-.0017 1.56592-.6245 3.0672-1.7318 4.1745S9.56592 13.9046 8 13.9062Zm-.84375-5.62495V4.625c0-.22378.0889-.43839.24713-.59662.15824-.15824.37285-.24713.59662-.24713.22378 0 .43839.08889.59662.24713.15824.15823.24713.37284.24713.59662v3.65625c0 .22378-.08889.43839-.24713.59662C8.43839 9.03611 8.22378 9.125 8 9.125c-.22377 0-.43838-.08889-.59662-.24713-.15823-.15823-.24713-.37284-.24713-.59662ZM9.125 11.0938c0 .2225-.06598.44-.18959.625-.12362.185-.29932.3292-.50489.4143-.20556.0852-.43176.1074-.64999.064-.21823-.0434-.41869-.1505-.57602-.3079-.15734-.1573-.26448-.3577-.30789-.576-.04341-.2182-.02113-.4444.06402-.65.08515-.2055.22934-.3812.41435-.5049.185-.1236.40251-.18955.62501-.18955.29837 0 .58452.11855.7955.32955.21098.2109.3295.4971.3295.7955Z"/></svg>`, + warning: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="currentColor" d="M8 .40625c-1.5019 0-2.97007.445366-4.21886 1.27978C2.53236 2.52044 1.55905 3.70642.984293 5.094.40954 6.48157.259159 8.00842.552165 9.48147.845172 10.9545 1.56841 12.3076 2.63041 13.3696c1.06201 1.062 2.41508 1.7852 3.88813 2.0782 1.47304.293 2.99989.1427 4.38746-.4321 1.3876-.5747 2.5736-1.5481 3.408-2.7968.8344-1.2488 1.2798-2.717 1.2798-4.2189-.0023-2.0133-.8031-3.9435-2.2267-5.36713C11.9435 1.20925 10.0133.408483 8 .40625ZM8 13.9062c-1.16814 0-2.31006-.3463-3.28133-.9953-.97128-.649-1.7283-1.5715-2.17533-2.6507-.44703-1.0792-.56399-2.26675-.3361-3.41245.22789-1.1457.79041-2.1981 1.61641-3.0241.82601-.826 1.8784-1.38852 3.0241-1.61641 1.1457-.2279 2.33325-.11093 3.41245.3361 1.0793.44703 2.0017 1.20405 2.6507 2.17532.649.97128.9954 2.11319.9954 3.28134-.0017 1.56592-.6245 3.0672-1.7318 4.1745S9.56592 13.9046 8 13.9062Zm-.84375-5.62495V4.625c0-.22378.0889-.43839.24713-.59662.15824-.15824.37285-.24713.59662-.24713.22378 0 .43839.08889.59662.24713.15824.15823.24713.37284.24713.59662v3.65625c0 .22378-.08889.43839-.24713.59662C8.43839 9.03611 8.22378 9.125 8 9.125c-.22377 0-.43838-.08889-.59662-.24713-.15823-.15823-.24713-.37284-.24713-.59662ZM9.125 11.0938c0 .2225-.06598.44-.18959.625-.12362.185-.29932.3292-.50489.4143-.20556.0852-.43176.1074-.64999.064-.21823-.0434-.41869-.1505-.57602-.3079-.15734-.1573-.26448-.3577-.30789-.576-.04341-.2182-.02113-.4444.06402-.65.08515-.2055.22934-.3812.41435-.5049.185-.1236.40251-.18955.62501-.18955.29837 0 .58452.11855.7955.32955.21098.2109.3295.4971.3295.7955Z"/></svg>`, 'arrow-down': - '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 12 14"><path fill="#13151A" d="m11.0306 8.53063-4.5 4.49997c-.06968.0699-.15247.1254-.24364.1633-.09116.0378-.1889.0573-.28761.0573-.09871 0-.19645-.0195-.28762-.0573-.09116-.0379-.17395-.0934-.24363-.1633L.968098 8.53063c-.140896-.1409-.220051-.332-.220051-.53125 0-.19926.079155-.39036.220051-.53125.140892-.1409.331992-.22006.531252-.22006.19926 0 .39035.07916.53125.22006l3.21937 3.21937V1.5c0-.19891.07902-.38968.21967-.53033C5.61029.829018 5.80106.75 5.99997.75c.19891 0 .38968.079018.53033.21967.14065.14065.21967.33142.21967.53033v9.1875l3.21938-3.22c.14085-.1409.33195-.22005.53125-.22005.1993 0 .3904.07915.5312.22005.1409.1409.2201.33199.2201.53125s-.0792.39035-.2201.53125l-.0012.00063Z"/></svg>', - bug: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 24"><path fill="#CCCED8" d="M13.7916 8.25006c0-.29667.088-.58668.2528-.83335.1648-.24668.3991-.43893.6732-.55247.2741-.11353.5757-.14323.8667-.08536.2909.05788.5582.20074.768.41052s.3526.47706.4105.76803c.0579.29097.0282.59257-.0854.86666-.1135.27409-.3057.50836-.5524.67318-.2467.16482-.5367.25279-.8334.25279-.3978 0-.7793-.15803-1.0606-.43934-.2813-.2813-.4394-.66283-.4394-1.06066Zm-3.75-1.5c-.29665 0-.58666.08798-.83333.2528-.24667.16482-.43893.39909-.55246.67318-.11354.27409-.14324.57569-.08536.86666.05788.29097.20074.55824.41052.76802.20977.20978.47705.35264.76802.41052.29101.05788.59261.02817.86671-.08536.274-.11353.5083-.30579.6731-.55246.1649-.24668.2528-.53668.2528-.83336 0-.39782-.158-.77935-.4393-1.06066-.2813-.2813-.6628-.43934-1.0607-.43934Zm11.25 6.75004c.0003.6512-.0733 1.3003-.2193 1.935l1.7953.7837c.1354.0592.2578.1445.3603.2511.1024.1065.1829.2322.2368.3698.0539.1377.0801.2846.0772.4323-.0028.1478-.0348.2936-.094.429-.0592.1354-.1446.2579-.2511.3603-.1065.1025-.2322.1829-.3698.2368-.1377.0539-.2846.0802-.4323.0773-.1478-.0029-.2936-.0349-.429-.0941l-1.6875-.7359c-.7348 1.3818-1.8317 2.5377-3.1732 3.3437s-2.8771 1.2319-4.4421 1.2319c-1.5651 0-3.10061-.4259-4.44213-1.2319-1.34151-.806-2.43843-1.9619-3.17321-3.3437l-1.6875.7359c-.13542.0592-.28119.0912-.42896.0941-.14778.0029-.29468-.0234-.43232-.0773-.13763-.0539-.2633-.1343-.36984-.2368-.10653-.1024-.19185-.2249-.25106-.3603-.05922-.1354-.09119-.2812-.09407-.429-.00289-.1477.02336-.2946.07725-.4323.05389-.1376.13436-.2633.23681-.3698.10246-.1066.22489-.1919.36032-.2511l1.79531-.7837c-.14354-.635-.21462-1.2841-.21187-1.935v-.375h-1.875c-.29837 0-.58452-.1186-.7955-.3295-.21098-.211-.3295-.4972-.3295-.7955 0-.2984.11852-.5846.3295-.7955.21098-.211.49713-.3295.7955-.3295h1.875v-.375c-.00029-.65126.0733-1.30041.21937-1.93504l-1.79531-.78375c-.27351-.11959-.4883-.34294-.59713-.6209-.10883-.27797-.10278-.58778.01682-.86128.11959-.27351.34294-.4883.6209-.59713.27797-.10883.58778-.10278.86128.01681l1.6875.73594c.73478-1.38183 1.8317-2.53769 3.17321-3.34373 1.34152-.80604 2.87703-1.23187 4.44213-1.23187 1.565 0 3.1006.42583 4.4421 1.23187 1.3415.80604 2.4384 1.9619 3.1732 3.34373l1.6875-.73594c.1354-.05921.2812-.09118.429-.09406.1477-.00289.2946.02336.4323.07725.1376.05389.2633.13435.3698.23681.1065.10245.1919.22489.2511.36032.0592.13542.0912.28118.094.42896.0029.14778-.0233.29468-.0772.43232-.0539.13763-.1344.2633-.2368.36984-.1025.10653-.2249.19185-.3603.25106l-1.7953.78375c.1435.63492.2146 1.28407.2118 1.93504v.375h1.875c.2984 0 .5845.1185.7955.3295.211.2109.3295.4971.3295.7955 0 .2983-.1185.5845-.3295.7955-.211.2109-.4971.3295-.7955.3295h-1.875v.375Zm-14.99997-2.625H19.0416v-.375c0-1.69079-.6716-3.3123-1.8672-4.50784-1.1955-1.19555-2.817-1.8672-4.5078-1.8672-1.6907 0-3.31224.67165-4.50778 1.8672C6.96328 7.1878 6.29163 8.80931 6.29163 10.5001v.375Zm5.24997 8.8987v-6.6487H6.29163v.375c.00211 1.4949.52876 2.9417 1.48816 4.0882.95939 1.1464 2.29071 1.9199 3.76181 2.1855Zm7.5-6.2737v-.375h-5.25v6.6487c1.4712-.2656 2.8025-1.0391 3.7619-2.1855.9594-1.1465 1.486-2.5933 1.4881-4.0882Z"/></svg>', - 'file-search': - '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 24"><path fill="#CCCED8" d="m20.6293 7.455-5.25-5.25c-.1045-.10461-.2285-.1876-.3651-.24422-.1366-.05662-.283-.08577-.4308-.08578H5.58337c-.49728 0-.97419.19754-1.32582.54917-.35163.35164-.54918.82855-.54918 1.32583v16.5c0 .4973.19755.9742.54918 1.3258.35163.3517.82854.5492 1.32582.5492H19.0834c.4973 0 .9742-.1975 1.3258-.5492.3516-.3516.5492-.8285.5492-1.3258v-12c0-.29813-.1184-.58407-.3291-.795Zm-3.1397.045h-2.1562V5.34375L17.4896 7.5ZM5.95837 19.875V4.125h7.12503v4.5c0 .29837.1185.58452.3295.7955.211.21097.4971.3295.7955.3295h4.5v10.125H5.95837Zm9.04503-4.5459c.3426-.7185.4202-1.5349.2192-2.3051-.2011-.7702-.6679-1.4445-1.3179-1.9038-.65-.4594-1.4415-.6742-2.2346-.6066-.7931.0677-1.5368.4135-2.0996.9763-.56283.5629-.90863 1.3065-.9763 2.0996-.06766.7931.14716 1.5846.60651 2.2346.45936.6501 1.13369 1.1169 1.90389 1.3179.7701.201 1.5866.1234 2.305-.2192l1.125 1.125c.2114.2114.498.3301.7969.3301.2989 0 .5855-.1187.7969-.3301.2113-.2113.3301-.498.3301-.7969 0-.2988-.1188-.5855-.3301-.7968l-1.125-1.125Zm-4.17-1.4541c0-.2225.066-.44.1896-.625.1236-.185.2993-.3292.5049-.4144.2055-.0851.4317-.1074.65-.064.2182.0434.4186.1506.576.3079.1573.1573.2644.3578.3079.576.0434.2183.0211.4445-.0641.65-.0851.2056-.2293.3813-.4143.5049-.185.1236-.4025.1896-.625.1896-.2984 0-.5845-.1185-.7955-.3295-.211-.211-.3295-.4971-.3295-.7955Z"/></svg>', + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 12 14"><path fill="currentColor" d="m11.0306 8.53063-4.5 4.49997c-.06968.0699-.15247.1254-.24364.1633-.09116.0378-.1889.0573-.28761.0573-.09871 0-.19645-.0195-.28762-.0573-.09116-.0379-.17395-.0934-.24363-.1633L.968098 8.53063c-.140896-.1409-.220051-.332-.220051-.53125 0-.19926.079155-.39036.220051-.53125.140892-.1409.331992-.22006.531252-.22006.19926 0 .39035.07916.53125.22006l3.21937 3.21937V1.5c0-.19891.07902-.38968.21967-.53033C5.61029.829018 5.80106.75 5.99997.75c.19891 0 .38968.079018.53033.21967.14065.14065.21967.33142.21967.53033v9.1875l3.21938-3.22c.14085-.1409.33195-.22005.53125-.22005.1993 0 .3904.07915.5312.22005.1409.1409.2201.33199.2201.53125s-.0792.39035-.2201.53125l-.0012.00063Z"/></svg>', + bug: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 24"><path fill="currentColor" d="M13.7916 8.25006c0-.29667.088-.58668.2528-.83335.1648-.24668.3991-.43893.6732-.55247.2741-.11353.5757-.14323.8667-.08536.2909.05788.5582.20074.768.41052s.3526.47706.4105.76803c.0579.29097.0282.59257-.0854.86666-.1135.27409-.3057.50836-.5524.67318-.2467.16482-.5367.25279-.8334.25279-.3978 0-.7793-.15803-1.0606-.43934-.2813-.2813-.4394-.66283-.4394-1.06066Zm-3.75-1.5c-.29665 0-.58666.08798-.83333.2528-.24667.16482-.43893.39909-.55246.67318-.11354.27409-.14324.57569-.08536.86666.05788.29097.20074.55824.41052.76802.20977.20978.47705.35264.76802.41052.29101.05788.59261.02817.86671-.08536.274-.11353.5083-.30579.6731-.55246.1649-.24668.2528-.53668.2528-.83336 0-.39782-.158-.77935-.4393-1.06066-.2813-.2813-.6628-.43934-1.0607-.43934Zm11.25 6.75004c.0003.6512-.0733 1.3003-.2193 1.935l1.7953.7837c.1354.0592.2578.1445.3603.2511.1024.1065.1829.2322.2368.3698.0539.1377.0801.2846.0772.4323-.0028.1478-.0348.2936-.094.429-.0592.1354-.1446.2579-.2511.3603-.1065.1025-.2322.1829-.3698.2368-.1377.0539-.2846.0802-.4323.0773-.1478-.0029-.2936-.0349-.429-.0941l-1.6875-.7359c-.7348 1.3818-1.8317 2.5377-3.1732 3.3437s-2.8771 1.2319-4.4421 1.2319c-1.5651 0-3.10061-.4259-4.44213-1.2319-1.34151-.806-2.43843-1.9619-3.17321-3.3437l-1.6875.7359c-.13542.0592-.28119.0912-.42896.0941-.14778.0029-.29468-.0234-.43232-.0773-.13763-.0539-.2633-.1343-.36984-.2368-.10653-.1024-.19185-.2249-.25106-.3603-.05922-.1354-.09119-.2812-.09407-.429-.00289-.1477.02336-.2946.07725-.4323.05389-.1376.13436-.2633.23681-.3698.10246-.1066.22489-.1919.36032-.2511l1.79531-.7837c-.14354-.635-.21462-1.2841-.21187-1.935v-.375h-1.875c-.29837 0-.58452-.1186-.7955-.3295-.21098-.211-.3295-.4972-.3295-.7955 0-.2984.11852-.5846.3295-.7955.21098-.211.49713-.3295.7955-.3295h1.875v-.375c-.00029-.65126.0733-1.30041.21937-1.93504l-1.79531-.78375c-.27351-.11959-.4883-.34294-.59713-.6209-.10883-.27797-.10278-.58778.01682-.86128.11959-.27351.34294-.4883.6209-.59713.27797-.10883.58778-.10278.86128.01681l1.6875.73594c.73478-1.38183 1.8317-2.53769 3.17321-3.34373 1.34152-.80604 2.87703-1.23187 4.44213-1.23187 1.565 0 3.1006.42583 4.4421 1.23187 1.3415.80604 2.4384 1.9619 3.1732 3.34373l1.6875-.73594c.1354-.05921.2812-.09118.429-.09406.1477-.00289.2946.02336.4323.07725.1376.05389.2633.13435.3698.23681.1065.10245.1919.22489.2511.36032.0592.13542.0912.28118.094.42896.0029.14778-.0233.29468-.0772.43232-.0539.13763-.1344.2633-.2368.36984-.1025.10653-.2249.19185-.3603.25106l-1.7953.78375c.1435.63492.2146 1.28407.2118 1.93504v.375h1.875c.2984 0 .5845.1185.7955.3295.211.2109.3295.4971.3295.7955 0 .2983-.1185.5845-.3295.7955-.211.2109-.4971.3295-.7955.3295h-1.875v.375Zm-14.99997-2.625H19.0416v-.375c0-1.69079-.6716-3.3123-1.8672-4.50784-1.1955-1.19555-2.817-1.8672-4.5078-1.8672-1.6907 0-3.31224.67165-4.50778 1.8672C6.96328 7.1878 6.29163 8.80931 6.29163 10.5001v.375Zm5.24997 8.8987v-6.6487H6.29163v.375c.00211 1.4949.52876 2.9417 1.48816 4.0882.95939 1.1464 2.29071 1.9199 3.76181 2.1855Zm7.5-6.2737v-.375h-5.25v6.6487c1.4712-.2656 2.8025-1.0391 3.7619-2.1855.9594-1.1465 1.486-2.5933 1.4881-4.0882Z"/></svg>', + '': '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 24"><path fill="currentColor" d="m20.6293 7.455-5.25-5.25c-.1045-.10461-.2285-.1876-.3651-.24422-.1366-.05662-.283-.08577-.4308-.08578H5.58337c-.49728 0-.97419.19754-1.32582.54917-.35163.35164-.54918.82855-.54918 1.32583v16.5c0 .4973.19755.9742.54918 1.3258.35163.3517.82854.5492 1.32582.5492H19.0834c.4973 0 .9742-.1975 1.3258-.5492.3516-.3516.5492-.8285.5492-1.3258v-12c0-.29813-.1184-.58407-.3291-.795Zm-3.1397.045h-2.1562V5.34375L17.4896 7.5ZM5.95837 19.875V4.125h7.12503v4.5c0 .29837.1185.58452.3295.7955.211.21097.4971.3295.7955.3295h4.5v10.125H5.95837Zm9.04503-4.5459c.3426-.7185.4202-1.5349.2192-2.3051-.2011-.7702-.6679-1.4445-1.3179-1.9038-.65-.4594-1.4415-.6742-2.2346-.6066-.7931.0677-1.5368.4135-2.0996.9763-.56283.5629-.90863 1.3065-.9763 2.0996-.06766.7931.14716 1.5846.60651 2.2346.45936.6501 1.13369 1.1169 1.90389 1.3179.7701.201 1.5866.1234 2.305-.2192l1.125 1.125c.2114.2114.498.3301.7969.3301.2989 0 .5855-.1187.7969-.3301.2113-.2113.3301-.498.3301-.7969 0-.2988-.1188-.5855-.3301-.7968l-1.125-1.125Zm-4.17-1.4541c0-.2225.066-.44.1896-.625.1236-.185.2993-.3292.5049-.4144.2055-.0851.4317-.1074.65-.064.2182.0434.4186.1506.576.3079.1573.1573.2644.3578.3079.576.0434.2183.0211.4445-.0641.65-.0851.2056-.2293.3813-.4143.5049-.185.1236-.4025.1896-.625.1896-.2984 0-.5845-.1185-.7955-.3295-.211-.211-.3295-.4971-.3295-.7955Z"/></svg>', 'check-circle': - '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"><path fill="#fff" d="M10.0306 4.96938c.0699.06967.1254.15247.1633.24363.0378.09116.0573.1889.0573.28762 0 .09871-.0195.19645-.0573.28761-.0379.09116-.0934.17396-.1633.24364L6.53063 9.53187c-.06968.06992-.15247.1254-.24364.16326-.09116.03785-.1889.05734-.28761.05734-.09871 0-.19645-.01949-.28762-.05734-.09116-.03786-.17395-.09334-.24363-.16326l-1.5-1.5c-.06977-.06976-.12511-.15258-.16286-.24373-.03776-.09116-.05719-.18885-.05719-.28752 0-.09866.01943-.19635.05719-.28751.03775-.09115.09309-.17397.16286-.24373.06976-.06977.15259-.12511.24374-.16287.09115-.03775.18885-.05719.28751-.05719s.19636.01944.28751.05719c.09115.03776.17397.0931.24374.16287L6 7.9375l2.96938-2.97c.06978-.06961.15259-.12478.24371-.16237.09111-.03758.18874-.05683.2873-.05666.09856.00018.19612.01978.28711.05768.09098.0379.1736.09337.2431.16323ZM13.75 7c0 1.33502-.3959 2.64007-1.1376 3.7501-.7417 1.11-1.7959 1.9752-3.02928 2.4861-1.23341.5109-2.5906.6446-3.89998.3841-1.30937-.2605-2.5121-.9033-3.45611-1.8473-.944-.944-1.586877-2.14677-1.847328-3.45614-.26045-1.30937-.126777-2.66657.384114-3.89997C1.27471 3.18349 2.13987 2.12928 3.2499 1.38758 4.35994.645881 5.66498.25 7 .25c1.78961.001985 3.5053.713781 4.7708 1.97922C13.0362 3.49466 13.748 5.2104 13.75 7Zm-1.5 0c0-1.03835-.3079-2.05339-.8848-2.91674-.5769-.86336-1.3968-1.53627-2.35611-1.93363-.95931-.39736-2.01491-.50133-3.03331-.29875-1.0184.20257-1.95386.70258-2.68809 1.43681-.73422.73422-1.23424 1.66969-1.43681 2.68809-.20257 1.0184-.0986 2.074.29876 3.03331.39736.95931 1.07026 1.77921 1.93362 2.35611.86336.5769 1.87839.8848 2.91674.8848 1.39193-.0015 2.72643-.5551 3.7107-1.5393C11.6949 9.72642 12.2485 8.39193 12.25 7Z"/></svg>', - gear: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22"><path fill="#fff" d="M11 6.12507c-.9642 0-1.90671.28592-2.7084.82159-.80169.53567-1.42653 1.29704-1.79551 2.18783-.36898.89081-.46552 1.87101-.27742 2.81661.18811.9457.6524 1.8143 1.33419 2.4961.68178.6818 1.55042 1.1461 2.49604 1.3342.9457.1881 1.9259.0916 2.8167-.2774s1.6521-.9938 2.1878-1.7955c.5357-.8017.8216-1.7442.8216-2.7084-.0015-1.2925-.5156-2.53161-1.4295-3.44553-.9139-.91392-2.153-1.42801-3.4455-1.4295Zm0 7.50003c-.5192 0-1.02669-.154-1.45837-.4424-.43168-.2885-.76813-.6984-.96681-1.1781-.19868-.4796-.25067-1.0074-.14938-1.5166.10129-.50924.35129-.97697.71841-1.34408.36711-.36712.83484-.61712 1.34405-.71841.5092-.10129 1.037-.0493 1.5166.14938.4797.19868.8897.53513 1.1781.96681.2884.43168.4424.9392.4424 1.4584 0 .6962-.2766 1.3638-.7688 1.8561-.4923.4923-1.16.7689-1.8562.7689Zm8.625-2.551v-.1481l1.3125-1.64155c.1102-.13755.1865-.29905.2228-.4715s.0316-.35102-.0137-.52131c-.2369-.89334-.5909-1.75142-1.0528-2.55188-.089-.15264-.2127-.28218-.3611-.37811-.1484-.09594-.3173-.15557-.493-.17408l-2.0888-.23437-.104-.10406-.2344-2.08969c-.0186-.17556-.0783-.34426-.1743-.49247-.0959-.1482-.2254-.27175-.3779-.36066-.8005-.46341-1.6589-.81869-2.5528-1.056559-.1704-.044683-.349-.048704-.5213-.01174-.1723.036965-.3335.113881-.4706.224549l-1.6415 1.3125h-.1482l-1.64152-1.3125C9.14683.9524 8.98532.87608 8.81288.839767c-.17245-.036314-.35102-.031606-.52132.013744-.89357.238319-1.75165.593909-2.55187 1.057499-.15205.08854-.28121.2115-.37712.35901-.0959.14752-.15586.31547-.17507.49037l-.23437 2.08875-.10407.10406-2.08968.23437c-.17556.01865-.34426.07835-.49247.17428-.14821.09593-.27176.22539-.36066.37791-.46211.80072-.81613 1.65912-1.052812 2.55281-.045195.17016-.049823.34855-.013512.52082.03631.17227.112546.33362.222574.47106L2.375 10.926v.1481l-1.3125 1.6416c-.110173.1375-.186492.299-.222806.4715-.036313.1724-.031605.351.013744.5213.238622.8936.594522 1.7517 1.058442 2.5519.08844.1519.21126.281.3586.3769.14734.0959.3151.1559.48983.1753l2.08875.2325.10407.104.23437 2.0916c.01865.1756.07835.3443.17428.4925.09592.1482.22538.2717.37791.3606.80052.4634 1.65893.8187 2.55281 1.0566.17045.0447.349.0487.52129.0117.17228-.0369.33347-.1139.47059-.2245l1.64152-1.3125h.1482l1.6415 1.3125c.1376.1101.2991.1865.4715.2228.1725.0363.351.0316.5213-.0138.8934-.2368 1.7514-.5908 2.5519-1.0528.1524-.0883.2819-.2112.3782-.3587.0962-.1475.1565-.3156.1759-.4907l.2325-2.0887.104-.1041 2.0897-.239c.1751-.0194.3432-.0797.4907-.1759.1475-.0963.2704-.2258.3587-.3782.4634-.8005.8187-1.6589 1.0566-2.5528.0448-.1699.0493-.3479.013-.5198-.0363-.172-.1124-.333-.2221-.4702l-1.3125-1.6416Zm-2.2612-.4584c.015.256.015.5127 0 .7687-.0168.2784.0704.553.2446.7707l1.2038 1.5047c-.1136.3363-.2492.6648-.406.9834l-1.9153.2128c-.2773.0317-.5329.1654-.7171.375-.1704.1919-.3519.3735-.5438.5438-.2096.1842-.3433.4398-.375.7171l-.2119 1.9144c-.3185.1574-.647.2936-.9834.4078l-1.5047-1.2047c-.1997-.1593-.4477-.2459-.7031-.2456h-.0675c-.2561.015-.5127.015-.7688 0-.2781-.0165-.5525.0703-.7706.2438l-1.50469 1.2047c-.33634-.1137-.66486-.2493-.98343-.406l-.21282-1.9153c-.0317-.2773-.16536-.5329-.375-.7172-.19187-.1703-.37344-.3519-.54375-.5437-.18426-.2097-.43988-.3433-.71718-.375l-1.91438-.2119c-.15734-.3185-.29357-.647-.40781-.9834l1.20375-1.5047c.17424-.2177.26144-.4923.24469-.7707-.01501-.256-.01501-.5127 0-.7687.01675-.2783-.07045-.553-.24469-.77063L3.18781 8.34038c.11364-.33634.24924-.66486.40594-.98343l1.91531-.21281c.27731-.03171.53292-.16537.71719-.375.17031-.19188.35188-.37345.54375-.54375.20964-.18427.3433-.43989.375-.71719l.21188-1.91438c.31852-.15734.64704-.29357.98343-.40781L9.845 4.3907c.2181.17343.4925.26023.7706.24375.2561-.015.5127-.015.7688 0 .2782.01701.5528-.06985.7706-.24375l1.5047-1.20469c.3364.11424.6649.25047.9834.40781l.2128 1.91532c.0317.2773.1654.53292.375.71718.1919.17031.3735.35188.5438.54375.1843.20964.4399.3433.7172.375l1.9143.21188c.1574.31852.2936.64704.4079.98343l-1.2038 1.50469c-.1749.21743-.2628.49203-.2465.77063Z"/></svg>', + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"><path fill="currentColor" d="M10.0306 4.96938c.0699.06967.1254.15247.1633.24363.0378.09116.0573.1889.0573.28762 0 .09871-.0195.19645-.0573.28761-.0379.09116-.0934.17396-.1633.24364L6.53063 9.53187c-.06968.06992-.15247.1254-.24364.16326-.09116.03785-.1889.05734-.28761.05734-.09871 0-.19645-.01949-.28762-.05734-.09116-.03786-.17395-.09334-.24363-.16326l-1.5-1.5c-.06977-.06976-.12511-.15258-.16286-.24373-.03776-.09116-.05719-.18885-.05719-.28752 0-.09866.01943-.19635.05719-.28751.03775-.09115.09309-.17397.16286-.24373.06976-.06977.15259-.12511.24374-.16287.09115-.03775.18885-.05719.28751-.05719s.19636.01944.28751.05719c.09115.03776.17397.0931.24374.16287L6 7.9375l2.96938-2.97c.06978-.06961.15259-.12478.24371-.16237.09111-.03758.18874-.05683.2873-.05666.09856.00018.19612.01978.28711.05768.09098.0379.1736.09337.2431.16323ZM13.75 7c0 1.33502-.3959 2.64007-1.1376 3.7501-.7417 1.11-1.7959 1.9752-3.02928 2.4861-1.23341.5109-2.5906.6446-3.89998.3841-1.30937-.2605-2.5121-.9033-3.45611-1.8473-.944-.944-1.586877-2.14677-1.847328-3.45614-.26045-1.30937-.126777-2.66657.384114-3.89997C1.27471 3.18349 2.13987 2.12928 3.2499 1.38758 4.35994.645881 5.66498.25 7 .25c1.78961.001985 3.5053.713781 4.7708 1.97922C13.0362 3.49466 13.748 5.2104 13.75 7Zm-1.5 0c0-1.03835-.3079-2.05339-.8848-2.91674-.5769-.86336-1.3968-1.53627-2.35611-1.93363-.95931-.39736-2.01491-.50133-3.03331-.29875-1.0184.20257-1.95386.70258-2.68809 1.43681-.73422.73422-1.23424 1.66969-1.43681 2.68809-.20257 1.0184-.0986 2.074.29876 3.03331.39736.95931 1.07026 1.77921 1.93362 2.35611.86336.5769 1.87839.8848 2.91674.8848 1.39193-.0015 2.72643-.5551 3.7107-1.5393C11.6949 9.72642 12.2485 8.39193 12.25 7Z"/></svg>', + gear: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22"><path fill="currentColor" d="M11 6.12507c-.9642 0-1.90671.28592-2.7084.82159-.80169.53567-1.42653 1.29704-1.79551 2.18783-.36898.89081-.46552 1.87101-.27742 2.81661.18811.9457.6524 1.8143 1.33419 2.4961.68178.6818 1.55042 1.1461 2.49604 1.3342.9457.1881 1.9259.0916 2.8167-.2774s1.6521-.9938 2.1878-1.7955c.5357-.8017.8216-1.7442.8216-2.7084-.0015-1.2925-.5156-2.53161-1.4295-3.44553-.9139-.91392-2.153-1.42801-3.4455-1.4295Zm0 7.50003c-.5192 0-1.02669-.154-1.45837-.4424-.43168-.2885-.76813-.6984-.96681-1.1781-.19868-.4796-.25067-1.0074-.14938-1.5166.10129-.50924.35129-.97697.71841-1.34408.36711-.36712.83484-.61712 1.34405-.71841.5092-.10129 1.037-.0493 1.5166.14938.4797.19868.8897.53513 1.1781.96681.2884.43168.4424.9392.4424 1.4584 0 .6962-.2766 1.3638-.7688 1.8561-.4923.4923-1.16.7689-1.8562.7689Zm8.625-2.551v-.1481l1.3125-1.64155c.1102-.13755.1865-.29905.2228-.4715s.0316-.35102-.0137-.52131c-.2369-.89334-.5909-1.75142-1.0528-2.55188-.089-.15264-.2127-.28218-.3611-.37811-.1484-.09594-.3173-.15557-.493-.17408l-2.0888-.23437-.104-.10406-.2344-2.08969c-.0186-.17556-.0783-.34426-.1743-.49247-.0959-.1482-.2254-.27175-.3779-.36066-.8005-.46341-1.6589-.81869-2.5528-1.056559-.1704-.044683-.349-.048704-.5213-.01174-.1723.036965-.3335.113881-.4706.224549l-1.6415 1.3125h-.1482l-1.64152-1.3125C9.14683.9524 8.98532.87608 8.81288.839767c-.17245-.036314-.35102-.031606-.52132.013744-.89357.238319-1.75165.593909-2.55187 1.057499-.15205.08854-.28121.2115-.37712.35901-.0959.14752-.15586.31547-.17507.49037l-.23437 2.08875-.10407.10406-2.08968.23437c-.17556.01865-.34426.07835-.49247.17428-.14821.09593-.27176.22539-.36066.37791-.46211.80072-.81613 1.65912-1.052812 2.55281-.045195.17016-.049823.34855-.013512.52082.03631.17227.112546.33362.222574.47106L2.375 10.926v.1481l-1.3125 1.6416c-.110173.1375-.186492.299-.222806.4715-.036313.1724-.031605.351.013744.5213.238622.8936.594522 1.7517 1.058442 2.5519.08844.1519.21126.281.3586.3769.14734.0959.3151.1559.48983.1753l2.08875.2325.10407.104.23437 2.0916c.01865.1756.07835.3443.17428.4925.09592.1482.22538.2717.37791.3606.80052.4634 1.65893.8187 2.55281 1.0566.17045.0447.349.0487.52129.0117.17228-.0369.33347-.1139.47059-.2245l1.64152-1.3125h.1482l1.6415 1.3125c.1376.1101.2991.1865.4715.2228.1725.0363.351.0316.5213-.0138.8934-.2368 1.7514-.5908 2.5519-1.0528.1524-.0883.2819-.2112.3782-.3587.0962-.1475.1565-.3156.1759-.4907l.2325-2.0887.104-.1041 2.0897-.239c.1751-.0194.3432-.0797.4907-.1759.1475-.0963.2704-.2258.3587-.3782.4634-.8005.8187-1.6589 1.0566-2.5528.0448-.1699.0493-.3479.013-.5198-.0363-.172-.1124-.333-.2221-.4702l-1.3125-1.6416Zm-2.2612-.4584c.015.256.015.5127 0 .7687-.0168.2784.0704.553.2446.7707l1.2038 1.5047c-.1136.3363-.2492.6648-.406.9834l-1.9153.2128c-.2773.0317-.5329.1654-.7171.375-.1704.1919-.3519.3735-.5438.5438-.2096.1842-.3433.4398-.375.7171l-.2119 1.9144c-.3185.1574-.647.2936-.9834.4078l-1.5047-1.2047c-.1997-.1593-.4477-.2459-.7031-.2456h-.0675c-.2561.015-.5127.015-.7688 0-.2781-.0165-.5525.0703-.7706.2438l-1.50469 1.2047c-.33634-.1137-.66486-.2493-.98343-.406l-.21282-1.9153c-.0317-.2773-.16536-.5329-.375-.7172-.19187-.1703-.37344-.3519-.54375-.5437-.18426-.2097-.43988-.3433-.71718-.375l-1.91438-.2119c-.15734-.3185-.29357-.647-.40781-.9834l1.20375-1.5047c.17424-.2177.26144-.4923.24469-.7707-.01501-.256-.01501-.5127 0-.7687.01675-.2783-.07045-.553-.24469-.77063L3.18781 8.34038c.11364-.33634.24924-.66486.40594-.98343l1.91531-.21281c.27731-.03171.53292-.16537.71719-.375.17031-.19188.35188-.37345.54375-.54375.20964-.18427.3433-.43989.375-.71719l.21188-1.91438c.31852-.15734.64704-.29357.98343-.40781L9.845 4.3907c.2181.17343.4925.26023.7706.24375.2561-.015.5127-.015.7688 0 .2782.01701.5528-.06985.7706-.24375l1.5047-1.20469c.3364.11424.6649.25047.9834.40781l.2128 1.91532c.0317.2773.1654.53292.375.71718.1919.17031.3735.35188.5438.54375.1843.20964.4399.3433.7172.375l1.9143.21188c.1574.31852.2936.64704.4079.98343l-1.2038 1.50469c-.1749.21743-.2628.49203-.2465.77063Z"/></svg>', + lightbulb: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 13 16"><path fill="currentColor" d="M9.84994 14.5002c0 .1989-.07902.3897-.21967.5303-.14066.1407-.33142.2197-.53033.2197h-5c-.19891 0-.38968-.079-.53033-.2197-.14065-.1406-.21967-.3314-.21967-.5303 0-.1989.07902-.3897.21967-.5303.14065-.1407.33142-.2197.53033-.2197h5c.19891 0 .38967.079.53033.2197.14065.1406.21967.3314.21967.5303Zm2.49996-8.00001c.0023.87138-.1945 1.73175-.5755 2.51544-.381.78368-.9359 1.46997-1.6226 2.00647-.093.0708-.16853.162-.22085.2665-.05233.1046-.08004.2197-.08101.3366v.125c0 .3315-.1317.6495-.36612.8839-.23442.2344-.55236.3661-.88388.3661h-4c-.33152 0-.64947-.1317-.88389-.3661-.23442-.2344-.36611-.5524-.36611-.8839v-.125c-.00014-.115-.0267-.2284-.07763-.3314-.05094-.1031-.12488-.193-.21612-.263-.68477-.5334-1.23925-1.2155-1.62148-1.9948-.38223-.77929-.582201-1.63532-.584772-2.50331C.833063 3.41832 3.34994.825195 6.46181.750195c.76665-.018422 1.52923.116696 2.24287.397405.71365.2807 1.36392.70132 1.91262 1.23711.5486.53578.9846 1.1759 1.2821 1.88268.2976.70678.4508 1.46594.4505 2.2328Zm-1.5 0c.0002-.5669-.113-1.12811-.3331-1.65058-.22-.52247-.54226-.99565-.9479-1.39168-.40563-.39602-.8864-.70689-1.414-.91431-.52759-.20741-1.09135-.30718-1.65809-.29343-2.29937.055-4.15937 1.97188-4.14687 4.27375.00214.64152.15011 1.27416.43271 1.85009.2826.57592.69244 1.08006 1.19854 1.47429.25496.19678.46453.44618.61444.73128.14992.285.23665.599.25431.9206h3.50625c.018-.3222.10486-.6368.25472-.9226.14986-.2859.35924-.5362.61403-.73428.50754-.39672.91776-.90412 1.19936-1.4835.2817-.57938.4272-1.21543.4256-1.85963Zm-1.25434-.3325c-.06636-.56119-.28826-1.09265-.64067-1.53441-.35241-.44175-.82128-.7762-1.3537-.96559-.1861-.0608-.38859-.04643-.56423.04006-.17565.08648-.31051.23821-.37579.42278-.06527.18458-.05579.38736.02642.56504.08222.17767.23065.31616.4136.38587.26755.09379.50353.26056.68124.48146.17771.2209.29008.48712.32438.76854.02188.19776.12142.37872.27673.50308.0769.06157.16517.1074.25978.13486.09461.02747.1937.03602.29162.02519.09791-.01083.19274-.04085.27905-.08833.08632-.04748.16244-.1115.22402-.1884.06158-.07689.1074-.16517.13487-.25978.02746-.09461.03602-.1937.02518-.29162l-.0025.00125Z"/></svg>', + 'file-search': + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 12 14"><path fill="currentColor" d="M11.5306 3.97 8.03063.47C7.96097.400261 7.87826.344936 7.78721.307186 7.69616.269437 7.59856.250005 7.5.25h-6C1.16848.25.850537.381696.616117.616117.381696.850537.25 1.16848.25 1.5v11c0 .3315.131696.6495.366117.8839.23442.2344.552363.3661.883883.3661h9c.3315 0 .6495-.1317.8839-.3661.2344-.2344.3661-.5524.3661-.8839v-8c0-.19876-.0789-.38938-.2194-.53ZM9.4375 4H8V2.5625L9.4375 4ZM1.75 12.25V1.75H6.5v3c0 .19891.07902.38968.21967.53033.14065.14065.33142.21967.53033.21967h3v6.75h-8.5Zm6.03-3.03063c.2284-.47897.28015-1.02326.14613-1.53671-.13403-.51344-.44521-.96299-.87858-1.26923-.43337-.30623-.96102-.44945-1.48975-.40433-.52872.04511-1.02449.27564-1.39971.65086-.37523.37522-.60576.87099-.65087 1.39972-.04511.52872.0981 1.05638.40434 1.48975.30624.43336.75579.74457 1.26923.87857.51344.134 1.05773.0823 1.53671-.1461l.75.75c.1409.1409.33199.22.53125.22s.39035-.0791.53125-.22c.1409-.1409.22005-.332.22005-.5313 0-.1992-.07915-.3903-.22005-.53123l-.75-.75ZM5 8.25c0-.14834.04399-.29334.1264-.41668.08241-.12333.19954-.21946.33659-.27623.13704-.05676.28784-.07162.43333-.04268.14548.02894.27912.10037.38401.20526.10489.10489.17632.23853.20526.38401.02894.14549.01408.29629-.04268.43333-.05677.13705-.1529.25418-.27623.33659C6.04334 8.95601 5.89834 9 5.75 9c-.19891 0-.38968-.07902-.53033-.21967C5.07902 8.63968 5 8.44891 5 8.25Z"/></svg>', + star: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 15 15"><path fill="currentColor" d="M14.5873 6.00333c-.0759-.23292-.2187-.43838-.4105-.59083-.1918-.15245-.4241-.24519-.6682-.26667L9.9461 4.8377 8.55235 1.51645c-.09588-.22586-.25611-.4185-.46072-.553929-.2046-.135425-.44454-.207638-.68991-.207638-.24537 0-.48531.072213-.68991.207638-.20461.135429-.36484.328069-.46071.553929L4.85547 4.8377l-3.5625.30813c-.24538.02032-.479299.11265-.6724.26542-.193101.15276-.336784.35916-.413023.59328-.076238.23412-.081634.48554-.015512.72272s.200817.44954.387185.61045l2.7075 2.3625-.8125 3.515c-.05572.2394-.03965.4898.04619.7201.08585.2303.23767.4301.43648.5746.19881.1444.4358.2271.68132.2376.24553.0105.48871-.0516.69914-.1785l3.0625-1.86 3.06245 1.86c.2105.1267.4536.1886.699.178.2454-.0106.4822-.0933.6809-.2377.1987-.1444.3505-.3442.4363-.5743.0858-.2302.102-.4805.0463-.7198l-.8125-3.515 2.7075-2.3625c.1859-.16149.32-.37429.3853-.61168.0654-.23739.0592-.4888-.0178-.72269Zm-4.1718 2.66375c-.1714.14913-.299.34215-.3689.55831-.0699.21617-.07959.44731-.028.66857l.7119 3.08254-2.68378-1.63c-.1949-.1187-.41869-.1815-.64687-.1815-.22819 0-.45198.0628-.64688.1815l-2.68375 1.63.71188-3.08254c.05158-.22126.04189-.4524-.02803-.66857-.06993-.21616-.19745-.40918-.36885-.55831L2.00359 6.5902l3.13376-.27125c.22692-.01943.44417-.10073.62809-.23507.18393-.13433.32748-.31654.41503-.5268l1.21938-2.90563 1.21937 2.90563c.08755.21026.2311.39247.41503.5268.18392.13434.40117.21564.62809.23507l3.13376.27125-2.3806 2.07688Z"/></svg>', + checkmark: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 8"><path fill="#fff" d="M9.47334.806574C9.41136.744088 9.33763.694492 9.25639.660646S9.08802.609375 9.00001.609375 8.82486.6268 8.74362.660646s-.15497.083442-.21695.145928L3.56001 5.77991 1.47334 3.68657c-.06435-.06216-.14031-.11103-.22354-.14383-.08324-.03281-.17212-.04889-.261578-.04735-.089454.00155-.177727.0207-.259779.05637-.082052.03566-.156277.08713-.218436.15148-.062159.06435-.111035.14031-.143837.22355-.032803.08323-.04889.17212-.047342.26157.001547.08945.020699.17773.056361.25978.035663.08205.087137.15627.151485.21843l2.559996 2.56c.06198.06249.13571.11209.21695.14593.08124.03385.16838.05127.25639.05127s.17514-.01742.25638-.05127c.08124-.03384.15498-.08344.21695-.14593l5.44-5.44c.06767-.06242.12168-.13819.15861-.22253.03694-.08433.05601-.1754.05601-.26747 0-.09206-.01907-.18313-.05601-.26747-.03693-.08433-.09094-.160098-.15861-.222526Z"/></svg>', 'dots-three': '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 4"><path fill="#fff" d="M9.5 2c0 .29667-.08797.58668-.2528.83336-.16482.24667-.39908.43893-.67317.55246-.27409.11353-.57569.14324-.86666.08536-.29098-.05788-.55825-.20074-.76803-.41052-.20978-.20978-.35264-.47705-.41052-.76802-.05788-.29098-.02817-.59258.08536-.86666.11353-.27409.30579-.508362.55247-.673184C7.41332.587974 7.70333.5 8 .5c.39783 0 .77936.158036 1.06066.43934C9.34196 1.22064 9.5 1.60218 9.5 2ZM1.625.5c-.29667 0-.58668.087974-.833354.252796-.246674.164822-.438933.399094-.552465.673184-.113531.27408-.1432361.57568-.085358.86666.057878.29097.200739.55824.410518.76802.209778.20978.477049.35264.768029.41052.29097.05788.59257.02817.86666-.08536.27408-.11353.50835-.30579.67318-.55246C3.03703 2.58668 3.125 2.29667 3.125 2c0-.39782-.15803-.77936-.43934-1.06066C2.40436.658036 2.02283.5 1.625.5Zm12.75 0c-.2967 0-.5867.087974-.8334.252796-.2466.164822-.4389.399094-.5524.673184-.1135.27408-.1433.57568-.0854.86666.0579.29097.2008.55824.4105.76802.2098.20978.4771.35264.7681.41052.2909.05788.5925.02817.8666-.08536s.5084-.30579.6732-.55246c.1648-.24668.2528-.53669.2528-.83336 0-.39782-.158-.77936-.4393-1.06066C15.1544.658036 14.7728.5 14.375.5Z"/></svg>', + copy: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 11"><path fill="#fff" d="M9.125.8125h-6c-.14918 0-.29226.059263-.39775.164752-.10549.105488-.16475.248568-.16475.397748v1.6875H.875c-.149184 0-.292258.05926-.397748.16475C.371763 3.33274.3125 3.47582.3125 3.625v6c0 .14918.059263.29226.164752.3977.10549.1055.248564.1648.397748.1648h6c.14918 0 .29226-.0593.39775-.1648.10549-.10544.16475-.24852.16475-.3977V7.9375H9.125c.14918 0 .29226-.05926.39775-.16475.10549-.10549.16475-.24857.16475-.39775v-6c0-.14918-.05926-.29226-.16475-.397748C9.41726.871763 9.27418.8125 9.125.8125Zm-2.8125 8.25h-4.875v-4.875h4.875v4.875Zm2.25-2.25h-1.125V3.625c0-.14918-.05926-.29226-.16475-.39775-.10549-.10549-.24857-.16475-.39775-.16475H3.6875v-1.125h4.875v4.875Z"/></svg>', + compress: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32"><path fill="currentColor" d="M13.84 17.44c-.16-.07-.33-.1-.5-.1H8A1.33 1.33 0 1 0 8 20h2.12l-7.07 7.05a1.33 1.33 0 0 0 .44 2.19 1.33 1.33 0 0 0 1.46-.3L12 21.89V24a1.33 1.33 0 1 0 2.67 0v-5.33a1.37 1.37 0 0 0-.83-1.23Zm-.5-10.77A1.33 1.33 0 0 0 12 8v2.12L4.95 3.05a1.34 1.34 0 1 0-1.9 1.9L10.12 12H8a1.33 1.33 0 0 0 0 2.67h5.33c.18 0 .35-.04.5-.11a1.33 1.33 0 0 0 .84-1.23V8a1.33 1.33 0 0 0-1.34-1.33Zm4.82 7.89c.16.07.33.1.5.1H24A1.33 1.33 0 0 0 24 12h-2.12l7.07-7.05a1.34 1.34 0 1 0-1.9-1.9L20 10.12V8a1.33 1.33 0 0 0-2.67 0v5.33a1.33 1.33 0 0 0 .83 1.23ZM21.88 20H24a1.33 1.33 0 0 0 0-2.67h-5.33c-.18 0-.35.04-.51.11a1.33 1.33 0 0 0-.83 1.23V24A1.33 1.33 0 0 0 20 24v-2.12l7.05 7.07a1.33 1.33 0 0 0 2.19-.44 1.33 1.33 0 0 0-.3-1.46L21.89 20Z"/></svg>', + grid: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32"><path fill="currentColor" d="M13.33 17.33H4a1.33 1.33 0 0 0-1.33 1.34V28A1.33 1.33 0 0 0 4 29.33h9.33A1.33 1.33 0 0 0 14.67 28v-9.33a1.33 1.33 0 0 0-1.34-1.34ZM12 26.67H5.33V20H12v6.67Zm16-24h-9.33A1.33 1.33 0 0 0 17.33 4v9.33a1.33 1.33 0 0 0 1.34 1.34H28a1.33 1.33 0 0 0 1.33-1.34V4A1.33 1.33 0 0 0 28 2.67ZM26.67 12H20V5.33h6.67V12ZM28 17.33h-9.33a1.33 1.33 0 0 0-1.34 1.34V28a1.33 1.33 0 0 0 1.34 1.33H28A1.33 1.33 0 0 0 29.33 28v-9.33A1.33 1.33 0 0 0 28 17.33Zm-1.33 9.34H20V20h6.67v6.67Zm-13.34-24H4A1.33 1.33 0 0 0 2.67 4v9.33A1.33 1.33 0 0 0 4 14.67h9.33a1.33 1.33 0 0 0 1.34-1.34V4a1.33 1.33 0 0 0-1.34-1.33ZM12 12H5.33V5.33H12V12Z"/></svg>', + puzzle: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="M23 29.33H7a4 4 0 0 1-4-4V12a4 4 0 0 1 4-4h1.33A5.33 5.33 0 0 1 19 8h4a1.33 1.33 0 0 1 1.33 1.33v4a5.33 5.33 0 0 1 0 10.67v4A1.33 1.33 0 0 1 23 29.33ZM7 10.67A1.33 1.33 0 0 0 5.67 12v13.33A1.33 1.33 0 0 0 7 26.67h14.67v-4.24a1.33 1.33 0 0 1 1.77-1.27 2.36 2.36 0 0 0 2.32-.3A2.67 2.67 0 0 0 27 19.02a2.67 2.67 0 0 0-.64-2.12 2.52 2.52 0 0 0-2.9-.74 1.33 1.33 0 0 1-1.77-1.26v-4.24h-4.26a1.33 1.33 0 0 1-1.34-1.78 2.36 2.36 0 0 0-.3-2.32 2.59 2.59 0 0 0-4-.57A2.67 2.67 0 0 0 11 8c0 .3.06.6.17.9a1.33 1.33 0 0 1-1.26 1.77H7Z"/></svg>', + approveUser: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="M18.4 16.3a6.56 6.56 0 0 0 2.27-4.97 6.67 6.67 0 1 0-12.74 2.73c.39.86.96 1.62 1.67 2.23A10.67 10.67 0 0 0 3.33 26 1.33 1.33 0 0 0 6 26a8 8 0 0 1 16 0 1.33 1.33 0 0 0 2.67 0 10.67 10.67 0 0 0-6.27-9.7Zm-4.4-.97a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm15.61-3.16a1.33 1.33 0 0 0-1.9 0l-2.66 2.67-.82-.84a1.33 1.33 0 1 0-1.9 1.88l1.79 1.79a1.33 1.33 0 0 0 1.88 0l3.56-3.56a1.33 1.33 0 0 0 .05-1.94Z"/></svg>', + checkCircle: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="m20.3 11.72-5.73 5.73-2.2-2.2a1.33 1.33 0 1 0-1.88 1.88l3.14 3.15a1.33 1.33 0 0 0 1.88 0l6.66-6.67a1.33 1.33 0 1 0-1.88-1.89Zm-3.63-9.05a13.33 13.33 0 1 0 0 26.66 13.33 13.33 0 0 0 0-26.66Zm0 24a10.67 10.67 0 1 1 0-21.34 10.67 10.67 0 0 1 0 21.34Z"/></svg>', + resizeImage: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="M17.67 14.67H3A1.33 1.33 0 0 0 1.67 16v12A1.33 1.33 0 0 0 3 29.33h14.67A1.33 1.33 0 0 0 19 28V16a1.33 1.33 0 0 0-1.33-1.33Zm-7.42 12 2.58-2.58a.4.4 0 0 1 .66 0l2.56 2.58h-5.8Zm6.08-3.5-.96-.94a3.21 3.21 0 0 0-4.44 0l-4.45 4.44H4.33v-9.34h12v5.84ZM3 5.48a1.33 1.33 0 0 0 1.15-.65 1.4 1.4 0 0 0-.16-1.8A1.33 1.33 0 0 0 3 2.67 1.33 1.33 0 0 0 1.67 4v.13A1.33 1.33 0 0 0 3 5.48Zm10.55-.15h.25a1.33 1.33 0 0 0 0-2.66h-.25a1.33 1.33 0 0 0 0 2.66ZM3 11.71a1.33 1.33 0 0 0 1.33-1.34v-.29a1.33 1.33 0 0 0-2.66 0v.3A1.33 1.33 0 0 0 3 11.7Zm16.12-9.04h-.25a1.33 1.33 0 0 0 0 2.66h.25a1.33 1.33 0 0 0 0-2.66ZM8.22 5.33h.25a1.33 1.33 0 1 0 0-2.66H8.2a1.33 1.33 0 1 0 0 2.66Zm21.45 3.2a1.33 1.33 0 0 0-1.34 1.34v.28a1.33 1.33 0 0 0 2.67 0v-.28a1.33 1.33 0 0 0-1.33-1.34Zm-6.5 18.14h-.33a1.33 1.33 0 1 0 0 2.66h.32a1.33 1.33 0 0 0 0-2.66Zm6.36-24a1.33 1.33 0 1 0 .36 2.64A1.33 1.33 0 0 0 31 4.15V4a1.45 1.45 0 0 0-1.47-1.33Zm.14 11.86a1.33 1.33 0 0 0-1.34 1.34v.29a1.33 1.33 0 1 0 2.67 0v-.3a1.33 1.33 0 0 0-1.33-1.33ZM24.45 2.67h-.25a1.33 1.33 0 1 0 0 2.66h.25a1.33 1.33 0 1 0 0-2.66Zm5.22 24A1.33 1.33 0 0 0 28.34 28a1.33 1.33 0 0 0 1.33 1.33A1.45 1.45 0 0 0 31 27.87a1.33 1.33 0 0 0-1.33-1.2Zm0-6.08a1.33 1.33 0 0 0-1.34 1.33v.3a1.33 1.33 0 0 0 2.67 0v-.35a1.33 1.33 0 0 0-1.33-1.34v.06Z"/></svg>', + searchFile: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32"><path fill="currentColor" d="M16 26.67H6.67a1.33 1.33 0 0 1-1.34-1.34V6.67a1.33 1.33 0 0 1 1.34-1.34h6.66v4a4 4 0 0 0 4 4h4v1.34a1.33 1.33 0 0 0 2.67 0v-2.75a1.75 1.75 0 0 0-.08-.36v-.12a1.43 1.43 0 0 0-.25-.37l-8-8c-.11-.1-.24-.2-.38-.26h-.12a1.17 1.17 0 0 0-.44-.14H6.67a4 4 0 0 0-4 4v18.66a4 4 0 0 0 4 4H16a1.33 1.33 0 0 0 0-2.66ZM16 7.2l3.45 3.46h-2.12A1.33 1.33 0 0 1 16 9.33V7.21Zm-6.67 3.46a1.33 1.33 0 0 0 0 2.66h1.34a1.33 1.33 0 0 0 0-2.66H9.33Zm19.62 16.38-1.56-1.54a4.59 4.59 0 0 0-.72-5.51 4.65 4.65 0 0 0-8 3.32 4.61 4.61 0 0 0 6.84 4.07l1.54 1.56a1.33 1.33 0 0 0 2.19-.44 1.33 1.33 0 0 0-.3-1.46Zm-4.23-2.33a2.05 2.05 0 0 1-2.81 0 2 2 0 0 1 0-2.81 2 2 0 0 1 1.34-.58 1.96 1.96 0 0 1 1.47 3.39ZM17.33 16h-8a1.33 1.33 0 0 0 0 2.67h8a1.33 1.33 0 1 0 0-2.67Zm-2.66 8a1.33 1.33 0 0 0 0-2.67H9.33a1.33 1.33 0 0 0 0 2.67h5.34Z"/></svg>', + image: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="M26 2.67H7.33a4 4 0 0 0-4 4v18.66a4 4 0 0 0 4 4H26c.22 0 .44-.02.65-.06l.4-.1h.16l.5-.18.17-.1c.13-.08.28-.14.41-.24.18-.13.35-.27.5-.42l.1-.12c.13-.14.25-.28.36-.43l.12-.17c.1-.15.18-.3.24-.47l.1-.2.16-.5v-.2c.07-.27.12-.54.13-.8V6.66a4 4 0 0 0-4-4Zm-18.67 24A1.33 1.33 0 0 1 6 25.33V19.6l4.39-4.4a1.33 1.33 0 0 1 1.89 0l11.47 11.48H7.33Zm20-1.34c0 .17-.03.33-.1.48a1.33 1.33 0 0 1-.22.35l-7.13-7.13 1.17-1.18a1.33 1.33 0 0 1 1.9 0l4.38 4.4v3.08Zm0-6.85L24.83 16a4.1 4.1 0 0 0-5.66 0L18 17.17l-3.84-3.84a4.1 4.1 0 0 0-5.65 0L6 15.81V6.67a1.33 1.33 0 0 1 1.33-1.34H26a1.33 1.33 0 0 1 1.33 1.34v11.81Z"/></svg>', + robot: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="M12.67 20a1.33 1.33 0 1 0 0 2.67 1.33 1.33 0 0 0 0-2.67Zm-9.34-1.33A1.33 1.33 0 0 0 2 20v2.67a1.33 1.33 0 1 0 2.67 0V20a1.33 1.33 0 0 0-1.34-1.33Zm26.67 0A1.33 1.33 0 0 0 28.67 20v2.67a1.33 1.33 0 1 0 2.66 0V20A1.33 1.33 0 0 0 30 18.67Zm-6.67-9.34H18v-1.7a2.67 2.67 0 0 0 .55-4.18 2.67 2.67 0 0 0-4.19 3.2c.24.41.57.74.97.98v1.7H10a4 4 0 0 0-4 4v12a4 4 0 0 0 4 4h13.33a4 4 0 0 0 4-4v-12a4 4 0 0 0-4-4ZM18.96 12l-.67 2.67h-3.25L14.37 12h4.59Zm5.7 13.33a1.33 1.33 0 0 1-1.33 1.34H10a1.33 1.33 0 0 1-1.33-1.34v-12A1.33 1.33 0 0 1 10 12h1.63l1.04 4.32A1.33 1.33 0 0 0 14 17.33h5.33a1.33 1.33 0 0 0 1.34-1.01L21.7 12h1.62a1.33 1.33 0 0 1 1.34 1.33v12Zm-4-5.33a1.33 1.33 0 1 0 0 2.67 1.33 1.33 0 0 0 0-2.67Z"/></svg>', + sitemap: + '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 32"><path fill="currentColor" d="M29.67 20H27v-4a1.33 1.33 0 0 0-1.33-1.33h-8V12h2.66a1.33 1.33 0 0 0 1.34-1.33v-8a1.33 1.33 0 0 0-1.34-1.34h-8A1.33 1.33 0 0 0 11 2.67v8A1.33 1.33 0 0 0 12.33 12H15v2.67H7A1.33 1.33 0 0 0 5.67 16v4H3a1.33 1.33 0 0 0-1.33 1.33v8A1.33 1.33 0 0 0 3 30.67h8a1.33 1.33 0 0 0 1.33-1.34v-8A1.33 1.33 0 0 0 11 20H8.33v-2.67h16V20h-2.66a1.33 1.33 0 0 0-1.34 1.33v8a1.33 1.33 0 0 0 1.34 1.34h8A1.33 1.33 0 0 0 31 29.33v-8A1.33 1.33 0 0 0 29.67 20Zm-20 2.67V28H4.33v-5.33h5.34Zm4-13.34V4H19v5.33h-5.33ZM28.33 28H23v-5.33h5.33V28Z"/></svg>', } as const; diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/index.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/index.ts new file mode 100644 index 0000000000000..a9c039a417ff1 --- /dev/null +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/index.ts @@ -0,0 +1,8 @@ +export { DevOverlayBadge } from './badge.js'; +export { DevOverlayButton } from './button.js'; +export { DevOverlayCard } from './card.js'; +export { DevOverlayHighlight } from './highlight.js'; +export { DevOverlayIcon } from './icon.js'; +export { DevOverlayToggle } from './toggle.js'; +export { DevOverlayTooltip } from './tooltip.js'; +export { DevOverlayWindow } from './window.js'; diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/toggle.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/toggle.ts index 63dcba65e304d..1fb0b686a9d1a 100644 --- a/packages/astro/src/runtime/client/dev-overlay/ui-library/toggle.ts +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/toggle.ts @@ -30,6 +30,14 @@ export class DevOverlayToggle extends HTMLElement { position: relative; } + @media (forced-colors: active) { + input::after { + border: 1px solid black; + top: 0px; + left: 0px; + } + } + input:checked { border: 1px solid rgba(213, 249, 196, 1); background-color: rgba(61, 125, 31, 1); diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/tooltip.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/tooltip.ts index dbd7add5dd516..9f7224ca479fc 100644 --- a/packages/astro/src/runtime/client/dev-overlay/ui-library/tooltip.ts +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/tooltip.ts @@ -32,10 +32,10 @@ export class DevOverlayTooltip extends HTMLElement { font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 14px; margin: 0; - z-index: 9999999; + z-index: 2000000001; max-width: 45ch; width: fit-content; - min-width: 27ch; + min-width: 30ch; box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.30), 0px 1px 2px 0px rgba(0, 0, 0, 0.29), 0px 4px 4px 0px rgba(0, 0, 0, 0.26), 0px 10px 6px 0px rgba(0, 0, 0, 0.15), 0px 17px 7px 0px rgba(0, 0, 0, 0.04), 0px 26px 7px 0px rgba(0, 0, 0, 0.01); } @@ -101,13 +101,18 @@ export class DevOverlayTooltip extends HTMLElement { cursor: pointer; } - code { - background: rgba(136, 58, 234, 0.33); + pre, code { + background: rgb(78, 27, 145); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; border-radius: 2px; font-size: 14px; padding: 2px; } + pre { + padding: 1em; + margin: 0 0; + overflow: auto; + } `; const fragment = new DocumentFragment(); diff --git a/packages/astro/src/runtime/client/dev-overlay/ui-library/window.ts b/packages/astro/src/runtime/client/dev-overlay/ui-library/window.ts index 18b515429ad82..bab936d4bbd87 100644 --- a/packages/astro/src/runtime/client/dev-overlay/ui-library/window.ts +++ b/packages/astro/src/runtime/client/dev-overlay/ui-library/window.ts @@ -1,18 +1,9 @@ -import { getIconElement, isDefinedIcon, type Icon } from './icons.js'; - export class DevOverlayWindow extends HTMLElement { - windowTitle?: string | undefined | null; - windowIcon?: Icon | undefined | null; shadowRoot: ShadowRoot; constructor() { super(); this.shadowRoot = this.attachShadow({ mode: 'open' }); - - this.windowTitle = this.getAttribute('window-title'); - this.windowIcon = this.hasAttribute('window-icon') - ? (this.getAttribute('window-icon') as Icon) - : undefined; } async connectedCallback() { @@ -25,31 +16,34 @@ export class DevOverlayWindow extends HTMLElement { background: linear-gradient(0deg, #13151A, #13151A), linear-gradient(0deg, #343841, #343841); border: 1px solid rgba(52, 56, 65, 1); width: min(640px, 100%); - height: 480px; + max-height: 480px; border-radius: 12px; padding: 24px; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - color: rgba(204, 206, 216, 1); + color: rgba(191, 193, 201, 1); position: fixed; z-index: 999999999; - top: 55%; + bottom: 72px; left: 50%; - transform: translate(-50%, -50%); + transform: translateX(-50%); box-shadow: 0px 0px 0px 0px rgba(19, 21, 26, 0.30), 0px 1px 2px 0px rgba(19, 21, 26, 0.29), 0px 4px 4px 0px rgba(19, 21, 26, 0.26), 0px 10px 6px 0px rgba(19, 21, 26, 0.15), 0px 17px 7px 0px rgba(19, 21, 26, 0.04), 0px 26px 7px 0px rgba(19, 21, 26, 0.01); } - ::slotted(h1), ::slotted(h2), ::slotted(h3), ::slotted(h4), ::slotted(h5) { - font-weight: 600; - color: #fff; + @media (forced-colors: active) { + :host { + background: white; + } + } + + @media (max-width: 640px) { + :host { + border-radius: 0; + } } - #window-title { - display: flex; - align-items: center; + ::slotted(h1), ::slotted(h2), ::slotted(h3), ::slotted(h4), ::slotted(h5) { font-weight: 600; color: #fff; - margin: 0; - font-size: 22px; } ::slotted(h1) { @@ -72,37 +66,17 @@ export class DevOverlayWindow extends HTMLElement { font-size: 14px; } - #window-title svg { - margin-right: 8px; - height: 1em; - } - hr, ::slotted(hr) { border: 1px solid rgba(27, 30, 36, 1); margin: 1em 0; } + + p, ::slotted(p) { + line-height: 1.5em; + } </style> - <h1 id="window-title">${this.windowIcon ? this.getElementForIcon(this.windowIcon) : ''}${ - this.windowTitle ?? '' - }</h1> - <hr /> <slot /> `; } - - getElementForIcon(icon: Icon) { - if (isDefinedIcon(icon)) { - const iconElement = getIconElement(icon); - iconElement?.style.setProperty('height', '1em'); - - return iconElement?.outerHTML; - } else { - const iconElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - iconElement.setAttribute('viewBox', '0 0 16 16'); - iconElement.innerHTML = icon; - - return iconElement.outerHTML; - } - } } diff --git a/packages/astro/src/runtime/server/endpoint.ts b/packages/astro/src/runtime/server/endpoint.ts index 7db5f07ee6fff..f8fc1c071c78f 100644 --- a/packages/astro/src/runtime/server/endpoint.ts +++ b/packages/astro/src/runtime/server/endpoint.ts @@ -1,35 +1,12 @@ +import { bold } from 'kleur/colors'; import type { APIContext, EndpointHandler, Params } from '../../@types/astro.js'; import type { Logger } from '../../core/logger/core.js'; -function getHandlerFromModule(mod: EndpointHandler, method: string, logger: Logger) { - const lowerCaseMethod = method.toLowerCase(); - - // TODO: remove in Astro 4.0 - if (mod[lowerCaseMethod]) { - logger.warn( - 'astro', - `Lower case endpoint names are deprecated and will not be supported in Astro 4.0. Rename the endpoint ${lowerCaseMethod} to ${method}.` - ); - } +function getHandlerFromModule(mod: EndpointHandler, method: string) { // If there was an exact match on `method`, return that function. if (mod[method]) { return mod[method]; } - - // TODO: remove in Astro 4.0 - if (mod[lowerCaseMethod]) { - return mod[lowerCaseMethod]; - } - // TODO: remove in Astro 4.0 - // Handle `del` instead of `delete`, since `delete` is a reserved word in JS. - if (method === 'delete' && mod['del']) { - return mod['del']; - } - // TODO: remove in Astro 4.0 - // If a single `all` handler was used, return that function. - if (mod['all']) { - return mod['all']; - } if (mod['ALL']) { return mod['ALL']; } @@ -44,15 +21,17 @@ export async function renderEndpoint( ssr: boolean, logger: Logger ) { - const { request } = context; + const { request, url } = context; const chosenMethod = request.method?.toUpperCase(); - const handler = getHandlerFromModule(mod, chosenMethod, logger); - // TODO: remove the 'get' check in Astro 4.0 - if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'GET' && chosenMethod !== 'get') { - // eslint-disable-next-line no-console - console.warn(` -${chosenMethod} requests are not available when building a static site. Update your config to \`output: 'server'\` or \`output: 'hybrid'\` with an \`export const prerender = false\` to handle ${chosenMethod} requests.`); + const handler = getHandlerFromModule(mod, chosenMethod); + if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'GET') { + logger.warn( + null, + `${url.pathname} ${bold( + chosenMethod + )} requests are not available for a static site. Update your config to \`output: 'server'\` or \`output: 'hybrid'\` to enable.` + ); } if (!handler || typeof handler !== 'function') { // No handler found, so this should be a 404. Using a custom header diff --git a/packages/astro/src/runtime/server/render/common.ts b/packages/astro/src/runtime/server/render/common.ts index e5a5d5e860e06..f595dc78cf130 100644 --- a/packages/astro/src/runtime/server/render/common.ts +++ b/packages/astro/src/runtime/server/render/common.ts @@ -1,7 +1,8 @@ import type { SSRResult } from '../../../@types/astro.js'; import type { RenderInstruction } from './instruction.js'; -import { HTMLBytes, HTMLString, markHTMLString } from '../escape.js'; +import type { HTMLBytes, HTMLString } from '../escape.js'; +import { markHTMLString } from '../escape.js'; import { determineIfNeedsHydrationScript, determinesIfNeedsDirectiveScript, @@ -67,8 +68,8 @@ function stringifyChunk( let prescriptType: PrescriptType = needsHydrationScript ? 'both' : needsDirectiveScript - ? 'directive' - : null; + ? 'directive' + : null; if (prescriptType) { let prescripts = getPrescripts(result, prescriptType, hydration.directive); return markHTMLString(prescripts); diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts index dfc5d6c5b62af..42987f011e905 100644 --- a/packages/astro/src/runtime/server/render/component.ts +++ b/packages/astro/src/runtime/server/render/component.ts @@ -8,7 +8,8 @@ import { createRenderInstruction, type RenderInstruction } from './instruction.j import { clsx } from 'clsx'; import { AstroError, AstroErrorData } from '../../../core/errors/index.js'; -import { HTMLBytes, markHTMLString } from '../escape.js'; +import type { HTMLBytes } from '../escape.js'; +import { markHTMLString } from '../escape.js'; import { extractDirectives, generateHydrateScript } from '../hydration.js'; import { serializeProps } from '../serialize.js'; import { shorthash } from '../shorthash.js'; diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index 8bc5366cfb346..fbfe567a8380e 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -25,7 +25,7 @@ export async function renderPage( componentFactory.name, componentFactory, pageProps, - null, + {}, true, route ); diff --git a/packages/astro/src/runtime/server/transition.ts b/packages/astro/src/runtime/server/transition.ts index 17eece1d98198..0fed017dfdc97 100644 --- a/packages/astro/src/runtime/server/transition.ts +++ b/packages/astro/src/runtime/server/transition.ts @@ -1,7 +1,9 @@ import type { SSRResult, TransitionAnimation, + TransitionAnimationPair, TransitionAnimationValue, + TransitionDirectionalAnimations, } from '../../@types/astro.js'; import { fade, slide } from '../../transitions/index.js'; import { markHTMLString } from './escape.js'; @@ -34,6 +36,19 @@ const getAnimations = (name: TransitionAnimationValue) => { if (typeof name === 'object') return name; }; +const addPairs = ( + animations: TransitionDirectionalAnimations | Record<string, TransitionAnimationPair>, + stylesheet: ViewTransitionStyleSheet +) => { + for (const [direction, images] of Object.entries(animations) as Entries<typeof animations>) { + for (const [image, rules] of Object.entries(images) as Entries< + (typeof animations)[typeof direction] + >) { + stylesheet.addAnimationPair(direction, image, rules); + } + } +}; + export function renderTransition( result: SSRResult, hash: string, @@ -48,13 +63,7 @@ export function renderTransition( const animations = getAnimations(animationName); if (animations) { - for (const [direction, images] of Object.entries(animations) as Entries<typeof animations>) { - for (const [image, rules] of Object.entries(images) as Entries< - (typeof animations)[typeof direction] - >) { - sheet.addAnimationPair(direction, image, rules); - } - } + addPairs(animations, sheet); } else if (animationName === 'none') { sheet.addFallback('old', 'animation: none; mix-blend-mode: normal;'); sheet.addModern('old', 'animation: none; opacity: 0; mix-blend-mode: normal;'); @@ -65,6 +74,19 @@ export function renderTransition( return scope; } +export function createAnimationScope( + transitionName: string, + animations: Record<string, TransitionAnimationPair> +) { + const hash = Math.random().toString(36).slice(2, 8); + const scope = `astro-${hash}`; + const sheet = new ViewTransitionStyleSheet(scope, transitionName); + + addPairs(animations, sheet); + + return { scope, styles: sheet.toString().replaceAll('"', '') }; +} + class ViewTransitionStyleSheet { private modern: string[] = []; private fallback: string[] = []; @@ -113,13 +135,18 @@ class ViewTransitionStyleSheet { } addAnimationPair( - direction: 'forwards' | 'backwards', + direction: 'forwards' | 'backwards' | string, image: 'old' | 'new', rules: TransitionAnimation | TransitionAnimation[] ) { const { scope, name } = this; const animation = stringifyAnimation(rules); - const prefix = direction === 'backwards' ? `[data-astro-transition=back]` : ''; + const prefix = + direction === 'backwards' + ? `[data-astro-transition=back]` + : direction === 'forwards' + ? '' + : `[data-astro-transition=${direction}]`; this.addRule('modern', `${prefix}::view-transition-${image}(${name}) { ${animation} }`); this.addRule( 'fallback', diff --git a/packages/astro/src/transitions/events.ts b/packages/astro/src/transitions/events.ts new file mode 100644 index 0000000000000..b3921b31f0c96 --- /dev/null +++ b/packages/astro/src/transitions/events.ts @@ -0,0 +1,184 @@ +import { updateScrollPosition } from './router.js'; +import type { Direction, NavigationTypeString } from './types.js'; + +export const TRANSITION_BEFORE_PREPARATION = 'astro:before-preparation'; +export const TRANSITION_AFTER_PREPARATION = 'astro:after-preparation'; +export const TRANSITION_BEFORE_SWAP = 'astro:before-swap'; +export const TRANSITION_AFTER_SWAP = 'astro:after-swap'; +export const TRANSITION_PAGE_LOAD = 'astro:page-load'; + +type Events = + | typeof TRANSITION_AFTER_PREPARATION + | typeof TRANSITION_AFTER_SWAP + | typeof TRANSITION_PAGE_LOAD; +export const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name)); +export const onPageLoad = () => triggerEvent(TRANSITION_PAGE_LOAD); + +/* + * Common stuff + */ +class BeforeEvent extends Event { + readonly from: URL; + to: URL; + direction: Direction | string; + readonly navigationType: NavigationTypeString; + readonly sourceElement: Element | undefined; + readonly info: any; + newDocument: Document; + + constructor( + type: string, + eventInitDict: EventInit | undefined, + from: URL, + to: URL, + direction: Direction | string, + navigationType: NavigationTypeString, + sourceElement: Element | undefined, + info: any, + newDocument: Document + ) { + super(type, eventInitDict); + this.from = from; + this.to = to; + this.direction = direction; + this.navigationType = navigationType; + this.sourceElement = sourceElement; + this.info = info; + this.newDocument = newDocument; + + Object.defineProperties(this, { + from: { enumerable: true }, + to: { enumerable: true, writable: true }, + direction: { enumerable: true, writable: true }, + navigationType: { enumerable: true }, + sourceElement: { enumerable: true }, + info: { enumerable: true }, + newDocument: { enumerable: true, writable: true }, + }); + } +} + +/* + * TransitionBeforePreparationEvent + + */ +export const isTransitionBeforePreparationEvent = ( + value: any +): value is TransitionBeforePreparationEvent => value.type === TRANSITION_BEFORE_PREPARATION; +export class TransitionBeforePreparationEvent extends BeforeEvent { + formData: FormData | undefined; + loader: () => Promise<void>; + constructor( + from: URL, + to: URL, + direction: Direction | string, + navigationType: NavigationTypeString, + sourceElement: Element | undefined, + info: any, + newDocument: Document, + formData: FormData | undefined, + loader: (event: TransitionBeforePreparationEvent) => Promise<void> + ) { + super( + TRANSITION_BEFORE_PREPARATION, + { cancelable: true }, + from, + to, + direction, + navigationType, + sourceElement, + info, + newDocument + ); + this.formData = formData; + this.loader = loader.bind(this, this); + Object.defineProperties(this, { + formData: { enumerable: true }, + loader: { enumerable: true, writable: true }, + }); + } +} + +/* + * TransitionBeforeSwapEvent + */ + +export const isTransitionBeforeSwapEvent = (value: any): value is TransitionBeforeSwapEvent => + value.type === TRANSITION_BEFORE_SWAP; +export class TransitionBeforeSwapEvent extends BeforeEvent { + readonly direction: Direction | string; + readonly viewTransition: ViewTransition; + swap: () => void; + + constructor( + afterPreparation: BeforeEvent, + viewTransition: ViewTransition, + swap: (event: TransitionBeforeSwapEvent) => void + ) { + super( + TRANSITION_BEFORE_SWAP, + undefined, + afterPreparation.from, + afterPreparation.to, + afterPreparation.direction, + afterPreparation.navigationType, + afterPreparation.sourceElement, + afterPreparation.info, + afterPreparation.newDocument + ); + this.direction = afterPreparation.direction; + this.viewTransition = viewTransition; + this.swap = swap.bind(this, this); + + Object.defineProperties(this, { + direction: { enumerable: true }, + viewTransition: { enumerable: true }, + swap: { enumerable: true, writable: true }, + }); + } +} + +export async function doPreparation( + from: URL, + to: URL, + direction: Direction | string, + navigationType: NavigationTypeString, + sourceElement: Element | undefined, + info: any, + formData: FormData | undefined, + defaultLoader: (event: TransitionBeforePreparationEvent) => Promise<void> +) { + const event = new TransitionBeforePreparationEvent( + from, + to, + direction, + navigationType, + sourceElement, + info, + window.document, + formData, + defaultLoader + ); + if (document.dispatchEvent(event)) { + await event.loader(); + if (!event.defaultPrevented) { + triggerEvent(TRANSITION_AFTER_PREPARATION); + if (event.navigationType !== 'traverse') { + // save the current scroll position before we change the DOM and transition to the new page + updateScrollPosition({ scrollX, scrollY }); + } + } + } + return event; +} + +export async function doSwap( + afterPreparation: BeforeEvent, + viewTransition: ViewTransition, + defaultSwap: (event: TransitionBeforeSwapEvent) => void +) { + const event = new TransitionBeforeSwapEvent(afterPreparation, viewTransition, defaultSwap); + document.dispatchEvent(event); + event.swap(); + return event; +} diff --git a/packages/astro/src/transitions/index.ts b/packages/astro/src/transitions/index.ts index 0a58d2d4b48ae..d87052f2daf23 100644 --- a/packages/astro/src/transitions/index.ts +++ b/packages/astro/src/transitions/index.ts @@ -1,4 +1,5 @@ import type { TransitionAnimationPair, TransitionDirectionalAnimations } from '../@types/astro.js'; +export { createAnimationScope } from '../runtime/server/transition.js'; const EASE_IN_OUT_QUART = 'cubic-bezier(0.76, 0, 0.24, 1)'; diff --git a/packages/astro/src/transitions/router.ts b/packages/astro/src/transitions/router.ts index c4da38c2c8bea..e710c2e1b2e8c 100644 --- a/packages/astro/src/transitions/router.ts +++ b/packages/astro/src/transitions/router.ts @@ -1,32 +1,48 @@ -export type Fallback = 'none' | 'animate' | 'swap'; -export type Direction = 'forward' | 'back'; -export type Options = { - history?: 'auto' | 'push' | 'replace'; - formData?: FormData; -}; +import type { TransitionBeforePreparationEvent, TransitionBeforeSwapEvent } from './events.js'; +import { TRANSITION_AFTER_SWAP, doPreparation, doSwap } from './events.js'; +import type { Direction, Fallback, Options } from './types.js'; type State = { index: number; scrollX: number; scrollY: number; - intraPage?: boolean; }; type Events = 'astro:page-load' | 'astro:after-swap'; +// Create bound versions of pushState/replaceState so that Partytown doesn't hijack them, +// which breaks Firefox. +const inBrowser = import.meta.env.SSR === false; +const pushState = (inBrowser && history.pushState.bind(history)) as typeof history.pushState; +const replaceState = (inBrowser && + history.replaceState.bind(history)) as typeof history.replaceState; + // only update history entries that are managed by us // leave other entries alone and do not accidently add state. -const updateScrollPosition = (positions: { scrollX: number; scrollY: number }) => - history.state && history.replaceState({ ...history.state, ...positions }, ''); - -const inBrowser = import.meta.env.SSR === false; +export const updateScrollPosition = (positions: { scrollX: number; scrollY: number }) => { + if (history.state) { + history.scrollRestoration = 'manual'; + replaceState({ ...history.state, ...positions }, ''); + } +}; export const supportsViewTransitions = inBrowser && !!document.startViewTransition; export const transitionEnabledOnThisPage = () => inBrowser && !!document.querySelector('[name="astro-view-transitions-enabled"]'); -const samePage = (otherLocation: URL) => - location.pathname === otherLocation.pathname && location.search === otherLocation.search; +const samePage = (thisLocation: URL, otherLocation: URL) => + thisLocation.pathname === otherLocation.pathname && thisLocation.search === otherLocation.search; + +// When we traverse the history, the window.location is already set to the new location. +// This variable tells us where we came from +let originalLocation: URL; +// The result of startViewTransition (browser or simulation) +let viewTransition: ViewTransition | undefined; +// skip transition flag for fallback simulation +let skipTransition = false; +// The resolve function of the finished promise for fallback simulation +let viewTransitionFinished: () => void; + const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name)); const onPageLoad = () => triggerEvent('astro:page-load'); const announce = () => { @@ -48,6 +64,9 @@ const announce = () => { }; const PERSIST_ATTR = 'data-astro-transition-persist'; +const DIRECTION_ATTR = 'data-astro-transition'; +const OLD_NEW_ATTR = 'data-astro-transition-fallback'; + const VITE_ID = 'data-vite-dev-id'; let parser: DOMParser; @@ -66,7 +85,8 @@ if (inBrowser) { } else if (transitionEnabledOnThisPage()) { // This page is loaded from the browser addressbar or via a link from extern, // it needs a state in the history - history.replaceState({ index: currentHistoryIndex, scrollX, scrollY, intraPage: false }, ''); + replaceState({ index: currentHistoryIndex, scrollX, scrollY }, ''); + history.scrollRestoration = 'manual'; } } @@ -147,50 +167,62 @@ function runScripts() { return wait; } -function isInfinite(animation: Animation) { - const effect = animation.effect; - if (!effect || !(effect instanceof KeyframeEffect) || !effect.target) return false; - const style = window.getComputedStyle(effect.target, effect.pseudoElement); - return style.animationIterationCount === 'infinite'; -} - // Add a new entry to the browser history. This also sets the new page in the browser addressbar. // Sets the scroll position according to the hash fragment of the new location. -const moveToLocation = (toLocation: URL, replace: boolean, intraPage: boolean) => { - const fresh = !samePage(toLocation); +const moveToLocation = (to: URL, from: URL, options: Options, historyState?: State) => { + const intraPage = samePage(from, to); + let scrolledToTop = false; - if (toLocation.href !== location.href) { - if (replace) { - history.replaceState({ ...history.state }, '', toLocation.href); + if (to.href !== location.href && !historyState) { + if (options.history === 'replace') { + const current = history.state; + replaceState( + { + ...options.state, + index: current.index, + scrollX: current.scrollX, + scrollY: current.scrollY, + }, + '', + to.href + ); } else { - history.replaceState({ ...history.state, intraPage }, ''); - history.pushState( - { index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 }, + pushState( + { ...options.state, index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 }, '', - toLocation.href + to.href ); } - // now we are on the new page for non-history navigations! - // (with history navigation page change happens before popstate is fired) - // freshly loaded pages start from the top - if (fresh) { - scrollTo({ left: 0, top: 0, behavior: 'instant' }); - scrolledToTop = true; - } } - if (toLocation.hash) { - // because we are already on the target page ... - // ... what comes next is a intra-page navigation - // that won't reload the page but instead scroll to the fragment - location.href = toLocation.href; + // now we are on the new page for non-history navigations! + // (with history navigation page change happens before popstate is fired) + originalLocation = to; + + // freshly loaded pages start from the top + if (!intraPage) { + scrollTo({ left: 0, top: 0, behavior: 'instant' }); + scrolledToTop = true; + } + + if (historyState) { + scrollTo(historyState.scrollX, historyState.scrollY); } else { - if (!scrolledToTop) { - scrollTo({ left: 0, top: 0, behavior: 'instant' }); + if (to.hash) { + // because we are already on the target page ... + // ... what comes next is a intra-page navigation + // that won't reload the page but instead scroll to the fragment + history.scrollRestoration = 'auto'; + location.href = to.href; + } else { + if (!scrolledToTop) { + scrollTo({ left: 0, top: 0, behavior: 'instant' }); + } } + history.scrollRestoration = 'manual'; } }; -function stylePreloadLinks(newDocument: Document) { +function preloadStyleLinks(newDocument: Document) { const links: Promise<any>[] = []; for (const el of newDocument.querySelectorAll('head link[rel=stylesheet]')) { // Do not preload links that are already on the page. @@ -221,24 +253,23 @@ function stylePreloadLinks(newDocument: Document) { // if popState is given, this holds the scroll position for history navigation // if fallback === "animate" then simulate view transitions async function updateDOM( - newDocument: Document, - toLocation: URL, + preparationEvent: TransitionBeforePreparationEvent, options: Options, - popState?: State, + historyState?: State, fallback?: Fallback ) { // Check for a head element that should persist and returns it, // either because it has the data attribute or is a link el. // Returns null if the element is not part of the new head, undefined if it should be left alone. - const persistedHeadElement = (el: HTMLElement): Element | null => { + const persistedHeadElement = (el: HTMLElement, newDoc: Document): Element | null => { const id = el.getAttribute(PERSIST_ATTR); - const newEl = id && newDocument.head.querySelector(`[${PERSIST_ATTR}="${id}"]`); + const newEl = id && newDoc.head.querySelector(`[${PERSIST_ATTR}="${id}"]`); if (newEl) { return newEl; } if (el.matches('link[rel=stylesheet]')) { const href = el.getAttribute('href'); - return newDocument.head.querySelector(`link[rel=stylesheet][href="${href}"]`); + return newDoc.head.querySelector(`link[rel=stylesheet][href="${href}"]`); } return null; }; @@ -282,22 +313,22 @@ async function updateDOM( } }; - const swap = () => { + const defaultSwap = (beforeSwapEvent: TransitionBeforeSwapEvent) => { // swap attributes of the html element // - delete all attributes from the current document // - insert all attributes from doc // - reinsert all original attributes that are named 'data-astro-*' const html = document.documentElement; - const astro = [...html.attributes].filter( + const astroAttributes = [...html.attributes].filter( ({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-')) ); - [...newDocument.documentElement.attributes, ...astro].forEach(({ name, value }) => - html.setAttribute(name, value) + [...beforeSwapEvent.newDocument.documentElement.attributes, ...astroAttributes].forEach( + ({ name, value }) => html.setAttribute(name, value) ); // Replace scripts in both the head and body. for (const s1 of document.scripts) { - for (const s2 of newDocument.scripts) { + for (const s2 of beforeSwapEvent.newDocument.scripts) { if ( // Inline (!s1.src && s1.textContent === s2.textContent) || @@ -313,7 +344,7 @@ async function updateDOM( // Swap head for (const el of Array.from(document.head.children)) { - const newEl = persistedHeadElement(el as HTMLElement); + const newEl = persistedHeadElement(el as HTMLElement, beforeSwapEvent.newDocument); // If the element exists in the document already, remove it // from the new document and leave the current node alone if (newEl) { @@ -325,7 +356,7 @@ async function updateDOM( } // Everything left in the new head is new, append it all. - document.head.append(...newDocument.head.children); + document.head.append(...beforeSwapEvent.newDocument.head.children); // Persist elements in the existing body const oldBody = document.body; @@ -333,7 +364,7 @@ async function updateDOM( const savedFocus = saveFocus(); // this will reset scroll Position - document.body.replaceWith(newDocument.body); + document.body.replaceWith(beforeSwapEvent.newDocument.body); for (const el of oldBody.querySelectorAll(`[${PERSIST_ATTR}]`)) { const id = el.getAttribute(PERSIST_ATTR); @@ -345,103 +376,180 @@ async function updateDOM( } } restoreFocus(savedFocus); - - if (popState) { - scrollTo(popState.scrollX, popState.scrollY); // usings 'auto' scrollBehavior - } else { - moveToLocation(toLocation, options.history === 'replace', false); - } - - triggerEvent('astro:after-swap'); }; - const links = stylePreloadLinks(newDocument); - links.length && (await Promise.all(links)); - - if (fallback === 'animate') { + async function animate(phase: string) { + function isInfinite(animation: Animation) { + const effect = animation.effect; + if (!effect || !(effect instanceof KeyframeEffect) || !effect.target) return false; + const style = window.getComputedStyle(effect.target, effect.pseudoElement); + return style.animationIterationCount === 'infinite'; + } // Trigger the animations const currentAnimations = document.getAnimations(); - document.documentElement.dataset.astroTransitionFallback = 'old'; - const newAnimations = document - .getAnimations() - .filter((a) => !currentAnimations.includes(a) && !isInfinite(a)); - const finished = Promise.all(newAnimations.map((a) => a.finished)); - await finished; - swap(); - document.documentElement.dataset.astroTransitionFallback = 'new'; + document.documentElement.setAttribute(OLD_NEW_ATTR, phase); + const nextAnimations = document.getAnimations(); + const newAnimations = nextAnimations.filter( + (a) => !currentAnimations.includes(a) && !isInfinite(a) + ); + return Promise.all(newAnimations.map((a) => a.finished)); + } + + if (!skipTransition) { + document.documentElement.setAttribute(DIRECTION_ATTR, preparationEvent.direction); + + if (fallback === 'animate') { + await animate('old'); + } } else { - swap(); + // that's what Chrome does + throw new DOMException('Transition was skipped'); + } + + const swapEvent = await doSwap(preparationEvent, viewTransition!, defaultSwap); + moveToLocation(swapEvent.to, swapEvent.from, options, historyState); + triggerEvent(TRANSITION_AFTER_SWAP); + + if (fallback === 'animate' && !skipTransition) { + animate('new').then(() => viewTransitionFinished()); } } async function transition( direction: Direction, - toLocation: URL, + from: URL, + to: URL, options: Options, - popState?: State + historyState?: State ) { - let finished: Promise<void>; - const href = toLocation.href; - const init: RequestInit = {}; - if (options.formData) { - init.method = 'POST'; - init.body = options.formData; - } - const response = await fetchHTML(href, init); - // If there is a problem fetching the new page, just do an MPA navigation to it. - if (response === null) { - location.href = href; + // not ours + if (!transitionEnabledOnThisPage() || location.origin !== to.origin) { + location.href = to.href; return; } - // if there was a redirection, show the final URL in the browser's address bar - if (response.redirected) { - toLocation = new URL(response.redirected); - } - parser ??= new DOMParser(); + const navigationType = historyState + ? 'traverse' + : options.history === 'replace' + ? 'replace' + : 'push'; - const newDocument = parser.parseFromString(response.html, response.mediaType); - // The next line might look like a hack, - // but it is actually necessary as noscript elements - // and their contents are returned as markup by the parser, - // see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString - newDocument.querySelectorAll('noscript').forEach((el) => el.remove()); + if (navigationType !== 'traverse') { + updateScrollPosition({ scrollX, scrollY }); + } + if (samePage(from, to) && !!to.hash) { + moveToLocation(to, from, options, historyState); + return; + } - // If ViewTransitions is not enabled on the incoming page, do a full page load to it. - // Unless this was a form submission, in which case we do not want to trigger another mutation. - if (!newDocument.querySelector('[name="astro-view-transitions-enabled"]') && !options.formData) { - location.href = href; + const prepEvent = await doPreparation( + from, + to, + direction, + navigationType, + options.sourceElement, + options.info, + options.formData, + defaultLoader + ); + if (prepEvent.defaultPrevented) { + location.href = to.href; return; } - if (import.meta.env.DEV) await prepareForClientOnlyComponents(newDocument, toLocation); + async function defaultLoader(preparationEvent: TransitionBeforePreparationEvent) { + const href = preparationEvent.to.href; + const init: RequestInit = {}; + if (preparationEvent.formData) { + init.method = 'POST'; + init.body = preparationEvent.formData; + } + const response = await fetchHTML(href, init); + // If there is a problem fetching the new page, just do an MPA navigation to it. + if (response === null) { + preparationEvent.preventDefault(); + return; + } + // if there was a redirection, show the final URL in the browser's address bar + if (response.redirected) { + preparationEvent.to = new URL(response.redirected); + } + + parser ??= new DOMParser(); + + preparationEvent.newDocument = parser.parseFromString(response.html, response.mediaType); + // The next line might look like a hack, + // but it is actually necessary as noscript elements + // and their contents are returned as markup by the parser, + // see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + preparationEvent.newDocument.querySelectorAll('noscript').forEach((el) => el.remove()); + + // If ViewTransitions is not enabled on the incoming page, do a full page load to it. + // Unless this was a form submission, in which case we do not want to trigger another mutation. + if ( + !preparationEvent.newDocument.querySelector('[name="astro-view-transitions-enabled"]') && + !preparationEvent.formData + ) { + preparationEvent.preventDefault(); + return; + } + + const links = preloadStyleLinks(preparationEvent.newDocument); + links.length && (await Promise.all(links)); - if (!popState) { - // save the current scroll position before we change the DOM and transition to the new page - history.replaceState({ ...history.state, scrollX, scrollY }, ''); + if (import.meta.env.DEV) + await prepareForClientOnlyComponents(preparationEvent.newDocument, preparationEvent.to); } - document.documentElement.dataset.astroTransition = direction; + + skipTransition = false; if (supportsViewTransitions) { - finished = document.startViewTransition(() => - updateDOM(newDocument, toLocation, options, popState) - ).finished; + viewTransition = document.startViewTransition( + async () => await updateDOM(prepEvent, options, historyState) + ); } else { - finished = updateDOM(newDocument, toLocation, options, popState, getFallback()); + const updateDone = (async () => { + // immediatelly paused to setup the ViewTransition object for Fallback mode + await new Promise((r) => setTimeout(r)); + await updateDOM(prepEvent, options, historyState, getFallback()); + })(); + + // When the updateDone promise is settled, + // we have run and awaited all swap functions and the after-swap event + // This qualifies for "updateCallbackDone". + // + // For the build in ViewTransition, "ready" settles shortly after "updateCallbackDone", + // i.e. after all pseudo elements are created and the animation is about to start. + // In simulation mode the "old" animation starts before swap, + // the "new" animation starts after swap. That is not really comparable. + // Thus we go with "very, very shortly after updateCallbackDone" and make both equal. + // + // "finished" resolves after all animations are done. + + viewTransition = { + updateCallbackDone: updateDone, // this is about correct + ready: updateDone, // good enough + finished: new Promise((r) => (viewTransitionFinished = r)), // see end of updateDOM + skipTransition: () => { + skipTransition = true; + }, + }; } - try { - await finished; - } finally { - // skip this for the moment as it tends to stop fallback animations - // document.documentElement.removeAttribute('data-astro-transition'); + + viewTransition.ready.then(async () => { await runScripts(); onPageLoad(); announce(); - } + }); + viewTransition.finished.then(() => { + document.documentElement.removeAttribute(DIRECTION_ATTR); + document.documentElement.removeAttribute(OLD_NEW_ATTR); + }); + await viewTransition.ready; } let navigateOnServerWarned = false; -export function navigate(href: string, options?: Options) { +export async function navigate(href: string, options?: Options) { if (inBrowser === false) { if (!navigateOnServerWarned) { // instantiate an error for the stacktrace to show to user. @@ -455,23 +563,7 @@ export function navigate(href: string, options?: Options) { } return; } - - // not ours - if (!transitionEnabledOnThisPage()) { - location.href = href; - return; - } - const toLocation = new URL(href, location.href); - // We do not have page transitions on navigations to the same page (intra-page navigation) - // *unless* they are form posts which have side-effects and so need to happen - // but we want to handle prevent reload on navigation to the same page - // Same page means same origin, path and query params (but maybe different hash) - if (location.origin === toLocation.origin && samePage(toLocation) && !options?.formData) { - moveToLocation(toLocation, options?.history === 'replace', true); - } else { - // different origin will be detected by fetch - transition('forward', toLocation, options ?? {}); - } + await transition('forward', originalLocation, new URL(href, location.href), options ?? {}); } function onPopState(ev: PopStateEvent) { @@ -479,10 +571,6 @@ function onPopState(ev: PopStateEvent) { // The current page doesn't have View Transitions enabled // but the page we navigate to does (because it set the state). // Do a full page refresh to reload the client-side router from the new page. - // Scroll restauration will then happen during the reload when the router's code is re-executed - if (history.scrollRestoration) { - history.scrollRestoration = 'manual'; - } location.reload(); return; } @@ -492,28 +580,13 @@ function onPopState(ev: PopStateEvent) { // Just ignore stateless entries. // The browser will handle navigation fine without our help if (ev.state === null) { - if (history.scrollRestoration) { - history.scrollRestoration = 'auto'; - } return; } - - // With the default "auto", the browser will jump to the old scroll position - // before the ViewTransition is complete. - if (history.scrollRestoration) { - history.scrollRestoration = 'manual'; - } - const state: State = history.state; - if (state.intraPage) { - // this is non transition intra-page scrolling - scrollTo(state.scrollX, state.scrollY); - } else { - const nextIndex = state.index; - const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back'; - currentHistoryIndex = nextIndex; - transition(direction, new URL(location.href), {}, state); - } + const nextIndex = state.index; + const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back'; + currentHistoryIndex = nextIndex; + transition(direction, originalLocation, new URL(location.href), {}, state); } // There's not a good way to record scroll position before a back button. @@ -522,8 +595,10 @@ const onScroll = () => { updateScrollPosition({ scrollX, scrollY }); }; +// initialization if (inBrowser) { if (supportsViewTransitions || getFallback() !== 'none') { + originalLocation = new URL(location.href); addEventListener('popstate', onPopState); addEventListener('load', onPageLoad); if ('onscrollend' in window) addEventListener('scrollend', onScroll); diff --git a/packages/astro/src/transitions/types.ts b/packages/astro/src/transitions/types.ts new file mode 100644 index 0000000000000..0e70825e59673 --- /dev/null +++ b/packages/astro/src/transitions/types.ts @@ -0,0 +1,10 @@ +export type Fallback = 'none' | 'animate' | 'swap'; +export type Direction = 'forward' | 'back'; +export type NavigationTypeString = 'push' | 'replace' | 'traverse'; +export type Options = { + history?: 'auto' | 'push' | 'replace'; + info?: any; + state?: any; + formData?: FormData; + sourceElement?: Element; // more than HTMLElement, e.g. SVGAElement +}; diff --git a/packages/astro/src/transitions/vite-plugin-transitions.ts b/packages/astro/src/transitions/vite-plugin-transitions.ts index 8d5dbe553804b..16cb174baf444 100644 --- a/packages/astro/src/transitions/vite-plugin-transitions.ts +++ b/packages/astro/src/transitions/vite-plugin-transitions.ts @@ -1,4 +1,4 @@ -import * as vite from 'vite'; +import type * as vite from 'vite'; import type { AstroSettings } from '../@types/astro.js'; const virtualModuleId = 'astro:transitions'; @@ -21,13 +21,20 @@ export default function astroTransitions({ settings }: { settings: AstroSettings load(id) { if (id === resolvedVirtualModuleId) { return ` - export * from "astro/transitions"; + export * from "astro/virtual-modules/transitions.js"; export { default as ViewTransitions } from "astro/components/ViewTransitions.astro"; `; } if (id === resolvedVirtualClientModuleId) { return ` - export * from "astro/transitions/router"; + export { navigate, supportsViewTransitions, transitionEnabledOnThisPage } from "astro/virtual-modules/transitions-router.js"; + export * from "astro/virtual-modules/transitions-types.js"; + export { + TRANSITION_BEFORE_PREPARATION, isTransitionBeforePreparationEvent, TransitionBeforePreparationEvent, + TRANSITION_AFTER_PREPARATION, + TRANSITION_BEFORE_SWAP, isTransitionBeforeSwapEvent, TransitionBeforeSwapEvent, + TRANSITION_AFTER_SWAP, TRANSITION_PAGE_LOAD + } from "astro/virtual-modules/transitions-events.js"; `; } }, diff --git a/packages/astro/src/type-utils.ts b/packages/astro/src/type-utils.ts index d777a9f287893..4304438dbfdef 100644 --- a/packages/astro/src/type-utils.ts +++ b/packages/astro/src/type-utils.ts @@ -30,3 +30,13 @@ export type ValueOf<T> = T[keyof T]; // Gets the type of the values of a Map export type MapValue<T> = T extends Map<any, infer V> ? V : never; + +// Allow the user to create a type where all keys are optional. +// Useful for functions where props are merged. +export type DeepPartial<T> = { + [P in keyof T]?: T[P] extends (infer U)[] + ? DeepPartial<U>[] + : T[P] extends object | undefined + ? DeepPartial<T[P]> + : T[P]; +}; diff --git a/packages/astro/src/virtual-modules/README.md b/packages/astro/src/virtual-modules/README.md new file mode 100644 index 0000000000000..137e2e16f59a5 --- /dev/null +++ b/packages/astro/src/virtual-modules/README.md @@ -0,0 +1,3 @@ +# virtual-modules + +This directory contains the entry points for Astro virtual modules. For example, `astro:foobar` would re-export or use `astro/virtual-modules/foobar.js` which maps to the internal file `astro/dist/virtual-modules/foobar.js`. diff --git a/packages/astro/src/virtual-modules/i18n.ts b/packages/astro/src/virtual-modules/i18n.ts new file mode 100644 index 0000000000000..a55c1f6cfb59c --- /dev/null +++ b/packages/astro/src/virtual-modules/i18n.ts @@ -0,0 +1 @@ +export * from '../i18n/index.js'; diff --git a/packages/astro/src/virtual-modules/middleware.ts b/packages/astro/src/virtual-modules/middleware.ts new file mode 100644 index 0000000000000..4874c88d00a40 --- /dev/null +++ b/packages/astro/src/virtual-modules/middleware.ts @@ -0,0 +1 @@ +export { defineMiddleware, sequence } from '../core/middleware/index.js'; diff --git a/packages/astro/src/virtual-modules/prefetch.ts b/packages/astro/src/virtual-modules/prefetch.ts new file mode 100644 index 0000000000000..72bc23e2d04e3 --- /dev/null +++ b/packages/astro/src/virtual-modules/prefetch.ts @@ -0,0 +1 @@ +export * from '../prefetch/index.js'; diff --git a/packages/astro/src/virtual-modules/transitions-events.ts b/packages/astro/src/virtual-modules/transitions-events.ts new file mode 100644 index 0000000000000..35ecaf64f8974 --- /dev/null +++ b/packages/astro/src/virtual-modules/transitions-events.ts @@ -0,0 +1 @@ +export * from '../transitions/events.js'; diff --git a/packages/astro/src/virtual-modules/transitions-router.ts b/packages/astro/src/virtual-modules/transitions-router.ts new file mode 100644 index 0000000000000..666089f3f6fcb --- /dev/null +++ b/packages/astro/src/virtual-modules/transitions-router.ts @@ -0,0 +1 @@ +export * from '../transitions/router.js'; diff --git a/packages/astro/src/virtual-modules/transitions-types.ts b/packages/astro/src/virtual-modules/transitions-types.ts new file mode 100644 index 0000000000000..66dfb1d0ef6c5 --- /dev/null +++ b/packages/astro/src/virtual-modules/transitions-types.ts @@ -0,0 +1 @@ +export * from '../transitions/types.js'; diff --git a/packages/astro/src/virtual-modules/transitions.ts b/packages/astro/src/virtual-modules/transitions.ts new file mode 100644 index 0000000000000..84aeb3a2cfdf4 --- /dev/null +++ b/packages/astro/src/virtual-modules/transitions.ts @@ -0,0 +1 @@ +export * from '../transitions/index.js'; diff --git a/packages/astro/src/vite-plugin-astro-server/base.ts b/packages/astro/src/vite-plugin-astro-server/base.ts index 7bf57d10a3949..68eeae21a3e65 100644 --- a/packages/astro/src/vite-plugin-astro-server/base.ts +++ b/packages/astro/src/vite-plugin-astro-server/base.ts @@ -1,10 +1,10 @@ import type * as vite from 'vite'; import type { AstroSettings } from '../@types/astro.js'; +import { bold } from 'kleur/colors'; import * as fs from 'node:fs'; import type { Logger } from '../core/logger/core.js'; import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js'; -import { log404 } from './common.js'; import { writeHtmlResponse } from './response.js'; export function baseMiddleware( @@ -28,13 +28,11 @@ export function baseMiddleware( } if (pathname === '/' || pathname === '/index.html') { - log404(logger, pathname); const html = subpathNotUsedTemplate(devRoot, pathname); return writeHtmlResponse(res, 404, html); } if (req.headers.accept?.includes('text/html')) { - log404(logger, pathname); const html = notFoundTemplate({ statusCode: 404, title: 'Not found', @@ -49,14 +47,14 @@ export function baseMiddleware( fs.stat(publicPath, (_err, stats) => { if (stats) { const expectedLocation = new URL('.' + url, devRootURL).pathname; - logger.warn( - 'dev', - `Requests for items in your public folder must also include your base. ${url} should be ${expectedLocation}. Omitting the base will break in production.` + logger.error( + 'router', + `Request URLs for ${bold( + 'public/' + )} assets must also include your base. "${expectedLocation}" expected, but received "${url}".` ); - res.writeHead(301, { - Location: expectedLocation, - }); - res.end(); + const html = subpathNotUsedTemplate(devRoot, pathname); + return writeHtmlResponse(res, 404, html); } else { next(); } diff --git a/packages/astro/src/vite-plugin-astro-server/common.ts b/packages/astro/src/vite-plugin-astro-server/common.ts deleted file mode 100644 index 9e331232c1c72..0000000000000 --- a/packages/astro/src/vite-plugin-astro-server/common.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Logger } from '../core/logger/core.js'; -import * as msg from '../core/messages.js'; - -export function log404(logger: Logger, pathname: string) { - logger.info('serve', msg.req({ url: pathname, statusCode: 404 })); -} diff --git a/packages/astro/src/vite-plugin-astro-server/error.ts b/packages/astro/src/vite-plugin-astro-server/error.ts new file mode 100644 index 0000000000000..cbab6e7be0904 --- /dev/null +++ b/packages/astro/src/vite-plugin-astro-server/error.ts @@ -0,0 +1,38 @@ +import type { ModuleLoader } from '../core/module-loader/index.js'; +import type { AstroConfig } from '../@types/astro.js'; +import type DevPipeline from './devPipeline.js'; + +import { collectErrorMetadata } from '../core/errors/dev/index.js'; +import { createSafeError } from '../core/errors/index.js'; +import { formatErrorMessage } from '../core/messages.js'; +import { eventError, telemetry } from '../events/index.js'; + +export function recordServerError( + loader: ModuleLoader, + config: AstroConfig, + pipeline: DevPipeline, + _err: unknown +) { + const err = createSafeError(_err); + + // This could be a runtime error from Vite's SSR module, so try to fix it here + try { + loader.fixStacktrace(err); + } catch {} + + // This is our last line of defense regarding errors where we still might have some information about the request + // Our error should already be complete, but let's try to add a bit more through some guesswork + const errorWithMetadata = collectErrorMetadata(err, config.root); + + telemetry.record(eventError({ cmd: 'dev', err: errorWithMetadata, isFatal: false })); + + pipeline.logger.error( + null, + formatErrorMessage(errorWithMetadata, pipeline.logger.level() === 'debug') + ); + + return { + error: err, + errorWithMetadata, + }; +} diff --git a/packages/astro/src/vite-plugin-astro-server/plugin.ts b/packages/astro/src/vite-plugin-astro-server/plugin.ts index b8f4ab661aba9..67aef0babadd4 100644 --- a/packages/astro/src/vite-plugin-astro-server/plugin.ts +++ b/packages/astro/src/vite-plugin-astro-server/plugin.ts @@ -10,6 +10,12 @@ import { baseMiddleware } from './base.js'; import { createController } from './controller.js'; import DevPipeline from './devPipeline.js'; import { handleRequest } from './request.js'; +import { AstroError, AstroErrorData } from '../core/errors/index.js'; +import { getViteErrorPayload } from '../core/errors/dev/index.js'; +import { AsyncLocalStorage } from 'node:async_hooks'; +import { IncomingMessage } from 'node:http'; +import { setRouteError } from './server-state.js'; +import { recordServerError } from './error.js'; export interface AstroPluginOptions { settings: AstroSettings; @@ -30,6 +36,7 @@ export default function createVitePluginAstroServer({ const pipeline = new DevPipeline({ logger, manifest, settings, loader }); let manifestData: ManifestData = createRouteManifest({ settings, fsMod }, logger); const controller = createController({ loader }); + const localStorage = new AsyncLocalStorage(); /** rebuild the route cache + manifest, as needed. */ function rebuildManifest(needsManifestRebuild: boolean) { @@ -43,6 +50,25 @@ export default function createVitePluginAstroServer({ viteServer.watcher.on('unlink', rebuildManifest.bind(null, true)); viteServer.watcher.on('change', rebuildManifest.bind(null, false)); + function handleUnhandledRejection(rejection: any) { + const error = new AstroError({ + ...AstroErrorData.UnhandledRejection, + message: AstroErrorData.UnhandledRejection.message(rejection?.stack || rejection), + }); + const store = localStorage.getStore(); + if (store instanceof IncomingMessage) { + const request = store; + setRouteError(controller.state, request.url!, error); + } + const { errorWithMetadata } = recordServerError(loader, settings.config, pipeline, error); + setTimeout( + async () => loader.webSocketSend(await getViteErrorPayload(errorWithMetadata)), + 200 + ); + } + + process.on('unhandledRejection', handleUnhandledRejection); + return () => { // Push this middleware to the front of the stack so that it can intercept responses. // fix(#6067): always inject this to ensure zombie base handling is killed after restarts @@ -57,13 +83,15 @@ export default function createVitePluginAstroServer({ response.end(); return; } - handleRequest({ - pipeline, - manifestData, - controller, - incomingRequest: request, - incomingResponse: response, - manifest, + localStorage.run(request, () => { + handleRequest({ + pipeline, + manifestData, + controller, + incomingRequest: request, + incomingResponse: response, + manifest, + }); }); }); }; @@ -87,12 +115,12 @@ export default function createVitePluginAstroServer({ */ export function createDevelopmentManifest(settings: AstroSettings): SSRManifest { let i18nManifest: SSRManifestI18n | undefined = undefined; - if (settings.config.experimental.i18n) { + if (settings.config.i18n) { i18nManifest = { - fallback: settings.config.experimental.i18n.fallback, - routingStrategy: settings.config.experimental.i18n.routingStrategy, - defaultLocale: settings.config.experimental.i18n.defaultLocale, - locales: settings.config.experimental.i18n.locales, + fallback: settings.config.i18n.fallback, + routing: settings.config.i18n.routing, + defaultLocale: settings.config.i18n.defaultLocale, + locales: settings.config.i18n.locales, }; } return { diff --git a/packages/astro/src/vite-plugin-astro-server/request.ts b/packages/astro/src/vite-plugin-astro-server/request.ts index 65e97b96ff1a8..5dd507c75b8d1 100644 --- a/packages/astro/src/vite-plugin-astro-server/request.ts +++ b/packages/astro/src/vite-plugin-astro-server/request.ts @@ -1,16 +1,13 @@ import type http from 'node:http'; import type { ManifestData, SSRManifest } from '../@types/astro.js'; -import { collectErrorMetadata } from '../core/errors/dev/index.js'; -import { createSafeError } from '../core/errors/index.js'; -import * as msg from '../core/messages.js'; import { collapseDuplicateSlashes, removeTrailingForwardSlash } from '../core/path.js'; -import { eventError, telemetry } from '../events/index.js'; import { isServerLikeOutput } from '../prerender/utils.js'; import type { DevServerController } from './controller.js'; import { runWithErrorHandling } from './controller.js'; import type DevPipeline from './devPipeline.js'; import { handle500Response } from './response.js'; import { handleRoute, matchRoute } from './route.js'; +import { recordServerError } from './error.js'; type HandleRequest = { pipeline: DevPipeline; @@ -89,23 +86,9 @@ export async function handleRequest({ }); }, onError(_err) { - const err = createSafeError(_err); - - // This could be a runtime error from Vite's SSR module, so try to fix it here - try { - moduleLoader.fixStacktrace(err); - } catch {} - - // This is our last line of defense regarding errors where we still might have some information about the request - // Our error should already be complete, but let's try to add a bit more through some guesswork - const errorWithMetadata = collectErrorMetadata(err, config.root); - - telemetry.record(eventError({ cmd: 'dev', err: errorWithMetadata, isFatal: false })); - - pipeline.logger.error(null, msg.formatErrorMessage(errorWithMetadata)); + const { error, errorWithMetadata } = recordServerError(moduleLoader, config, pipeline, _err); handle500Response(moduleLoader, incomingResponse, errorWithMetadata); - - return err; + return error; }, }); } diff --git a/packages/astro/src/vite-plugin-astro-server/response.ts b/packages/astro/src/vite-plugin-astro-server/response.ts index b1c9480956b41..ac36e703b0723 100644 --- a/packages/astro/src/vite-plugin-astro-server/response.ts +++ b/packages/astro/src/vite-plugin-astro-server/response.ts @@ -68,7 +68,7 @@ export async function writeWebResponse(res: http.ServerResponse, webResponse: Re // Previously, `headers.entries()` would already have these merged, but it seems like this isn't the case anymore. if (headers.has('set-cookie')) { if ('getSetCookie' in headers && typeof headers.getSetCookie === 'function') { - _headers['set-cookie'] = headers.getSetCookie(); + _headers['set-cookie'] = headers.getSetCookie().toString(); } else { _headers['set-cookie'] = headers.get('set-cookie')!; } diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts index 48f89db043a30..3196b951a796a 100644 --- a/packages/astro/src/vite-plugin-astro-server/route.ts +++ b/packages/astro/src/vite-plugin-astro-server/route.ts @@ -2,13 +2,17 @@ import type http from 'node:http'; import { fileURLToPath } from 'node:url'; import type { ComponentInstance, + DevOverlayMetadata, ManifestData, - MiddlewareEndpointHandler, + MiddlewareHandler, RouteData, SSRElement, SSRManifest, } from '../@types/astro.js'; +import { getInfoOutput } from '../cli/info/index.js'; +import { ASTRO_VERSION } from '../core/constants.js'; import { AstroErrorData, isAstroError } from '../core/errors/index.js'; +import { req } from '../core/messages.js'; import { sequence } from '../core/middleware/index.js'; import { loadMiddleware } from '../core/middleware/loadMiddleware.js'; import { @@ -24,13 +28,13 @@ import { createI18nMiddleware, i18nPipelineHook } from '../i18n/middleware.js'; import { getSortedPreloadedMatches } from '../prerender/routing.js'; import { isServerLikeOutput } from '../prerender/utils.js'; import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js'; -import { log404 } from './common.js'; import { getStylesForURL } from './css.js'; import type DevPipeline from './devPipeline.js'; import { preload } from './index.js'; import { getComponentMetadata } from './metadata.js'; import { handle404Response, writeSSRResult, writeWebResponse } from './response.js'; import { getScriptsForURL } from './scripts.js'; +import { normalizeTheLocale } from '../i18n/index.js'; const clientLocalsSymbol = Symbol.for('astro.locals'); @@ -48,6 +52,10 @@ export interface MatchedRoute { mod: ComponentInstance; } +function isLoggedRequest(url: string) { + return url !== '/favicon.ico'; +} + function getCustom404Route(manifestData: ManifestData): RouteData | undefined { const route404 = /^\/404\/?$/; return manifestData.routes.find((r) => route404.test(r.route)); @@ -108,14 +116,13 @@ export async function matchRoute( const possibleRoutes = matches.flatMap((route) => route.component); pipeline.logger.warn( - 'getStaticPaths', + 'router', `${AstroErrorData.NoMatchingStaticPathFound.message( pathname )}\n\n${AstroErrorData.NoMatchingStaticPathFound.hint(possibleRoutes)}` ); } - log404(logger, pathname); const custom404 = getCustom404Route(manifestData); if (custom404) { @@ -161,11 +168,15 @@ export async function handleRoute({ incomingResponse, manifest, }: HandleRoute): Promise<void> { + const timeStart = performance.now(); const env = pipeline.getEnvironment(); const config = pipeline.getConfig(); const moduleLoader = pipeline.getModuleLoader(); const { logger } = env; - if (!matchedRoute && !config.experimental.i18n) { + if (!matchedRoute && !config.i18n) { + if (isLoggedRequest(pathname)) { + logger.info(null, req({ url: pathname, method: incomingRequest.method, statusCode: 404 })); + } return handle404Response(origin, incomingRequest, incomingResponse); } @@ -179,13 +190,27 @@ export async function handleRoute({ const middleware = await loadMiddleware(moduleLoader); if (!matchedRoute) { - if (config.experimental.i18n) { - const locales = config.experimental.i18n.locales; + if (config.i18n) { + const locales = config.i18n.locales; const pathNameHasLocale = pathname .split('/') .filter(Boolean) .some((segment) => { - return locales.includes(segment); + let found = false; + for (const locale of locales) { + if (typeof locale === 'string') { + if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { + found = true; + break; + } + } else { + if (locale.path === segment) { + found = true; + break; + } + } + } + return found; }); // Even when we have `config.base`, the pathname is still `/` because it gets stripped before if (!pathNameHasLocale && pathname !== '/') { @@ -208,6 +233,7 @@ export async function handleRoute({ segments: [], type: 'fallback', route: '', + fallbackRoutes: [], }; renderContext = await createRenderContext({ request, @@ -216,7 +242,7 @@ export async function handleRoute({ mod, route, locales: manifest.i18n?.locales, - routingStrategy: manifest.i18n?.routingStrategy, + routing: manifest.i18n?.routing, defaultLocale: manifest.i18n?.defaultLocale, }); } else { @@ -262,7 +288,7 @@ export async function handleRoute({ filePath: options.filePath, }); - const i18n = pipeline.getConfig().experimental.i18n; + const i18n = pipeline.getConfig().i18n; renderContext = await createRenderContext({ request: options.request, @@ -275,18 +301,14 @@ export async function handleRoute({ mod, env, locales: i18n?.locales, - routingStrategy: i18n?.routingStrategy, + routing: i18n?.routing, defaultLocale: i18n?.defaultLocale, }); } - const onRequest = middleware?.onRequest as MiddlewareEndpointHandler | undefined; - if (config.experimental.i18n) { - const i18Middleware = createI18nMiddleware( - config.experimental.i18n, - config.base, - config.trailingSlash - ); + const onRequest = middleware?.onRequest as MiddlewareHandler | undefined; + if (config.i18n) { + const i18Middleware = createI18nMiddleware(config.i18n, config.base, config.trailingSlash); if (i18Middleware) { if (onRequest) { @@ -303,6 +325,18 @@ export async function handleRoute({ } let response = await pipeline.renderRoute(renderContext, mod); + if (isLoggedRequest(pathname)) { + const timeEnd = performance.now(); + logger.info( + null, + req({ + url: pathname, + method: incomingRequest.method, + statusCode: status ?? response.status, + reqTime: timeEnd - timeStart, + }) + ); + } if (response.status === 404 && has404Route(manifestData)) { const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline); if (options && fourOhFourRoute?.route !== options.route) @@ -322,24 +356,23 @@ export async function handleRoute({ } if (route.type === 'endpoint') { await writeWebResponse(incomingResponse, response); - } else { - if ( - // We are in a recursion, and it's possible that this function is called itself with a status code - // By default, the status code passed via parameters is computed by the matched route. - // - // By default, we should give priority to the status code passed, although it's possible that - // the `Response` emitted by the user is a redirect. If so, then return the returned response. - response.status < 400 && - response.status >= 300 - ) { - await writeSSRResult(request, response, incomingResponse); - return; - } else if (status && response.status !== status && (status === 404 || status === 500)) { - // Response.status is read-only, so a clone is required to override - response = new Response(response.body, { ...response, status }); - } + return; + } + // We are in a recursion, and it's possible that this function is called itself with a status code + // By default, the status code passed via parameters is computed by the matched route. + // + // By default, we should give priority to the status code passed, although it's possible that + // the `Response` emitted by the user is a redirect. If so, then return the returned response. + if (response.status < 400 && response.status >= 300) { await writeSSRResult(request, response, incomingResponse); + return; + } + // Apply the `status` override to the response object before responding. + // Response.status is read-only, so a clone is required to override. + if (status && response.status !== status && (status === 404 || status === 500)) { + response = new Response(response.body, { ...response, status }); } + await writeSSRResult(request, response, incomingResponse); } interface GetScriptsAndStylesParams { @@ -361,7 +394,10 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa children: '', }); - if (settings.config.experimental.devOverlay) { + if ( + settings.config.devToolbar.enabled && + (await settings.preferences.get('devToolbar.enabled')) + ) { scripts.add({ props: { type: 'module', @@ -370,12 +406,16 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa children: '', }); + const additionalMetadata: DevOverlayMetadata['__astro_dev_overlay__'] = { + root: fileURLToPath(settings.config.root), + version: ASTRO_VERSION, + debugInfo: await getInfoOutput({ userConfig: settings.config, print: false }), + }; + // Additional data for the dev overlay scripts.add({ props: {}, - children: `window.__astro_dev_overlay__ = {root: ${JSON.stringify( - fileURLToPath(settings.config.root) - )}}`, + children: `window.__astro_dev_overlay__ = ${JSON.stringify(additionalMetadata)}`, }); } } diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts index 27cc2d10fca81..d06a8338f6624 100644 --- a/packages/astro/src/vite-plugin-astro/hmr.ts +++ b/packages/astro/src/vite-plugin-astro/hmr.ts @@ -1,23 +1,11 @@ -import { slash } from '@astrojs/internal-helpers/path'; -import { fileURLToPath } from 'node:url'; import type { HmrContext, ModuleNode } from 'vite'; import type { AstroConfig } from '../@types/astro.js'; -import { - cachedCompilation, - invalidateCompilation, - isCached, - type CompileResult, -} from '../core/compile/index.js'; +import type { cachedCompilation } from '../core/compile/index.js'; +import { invalidateCompilation, isCached, type CompileResult } from '../core/compile/index.js'; import type { Logger } from '../core/logger/core.js'; -import * as msg from '../core/messages.js'; +import { isAstroSrcFile } from '../core/logger/vite.js'; import { isAstroScript } from './query.js'; -const PKG_PREFIX = fileURLToPath(new URL('../../', import.meta.url)); -const E2E_PREFIX = fileURLToPath(new URL('../../e2e', import.meta.url)); -const isPkgFile = (id: string | null) => { - return id?.startsWith(PKG_PREFIX) && !id.startsWith(E2E_PREFIX); -}; - export interface HandleHotUpdateOptions { config: AstroConfig; logger: Logger; @@ -47,7 +35,7 @@ export async function handleHotUpdate( } // Skip monorepo files to avoid console spam - if (isPkgFile(ctx.file)) { + if (isAstroSrcFile(ctx.file)) { return; } @@ -57,7 +45,7 @@ export async function handleHotUpdate( const files = new Set<string>(); for (const mod of ctx.modules) { // Skip monorepo files to avoid console spam - if (isPkgFile(mod.id ?? mod.file)) { + if (isAstroSrcFile(mod.id ?? mod.file)) { filtered.delete(mod); continue; } @@ -92,13 +80,12 @@ export async function handleHotUpdate( // Bugfix: sometimes style URLs get normalized and end with `lang.css=` // These will cause full reloads, so filter them out here const mods = [...filtered].filter((m) => !m.url.endsWith('=')); - const file = ctx.file.replace(slash(fileURLToPath(config.root)), '/'); // If only styles are changed, remove the component file from the update list if (isStyleOnlyChange) { - logger.info('astro', msg.hmr({ file, style: true })); - // remove base file and hoisted scripts - return mods.filter((mod) => mod.id !== ctx.file && !mod.id?.endsWith('.ts')); + logger.debug('watch', 'style-only change'); + // Only return the Astro styles that have changed! + return mods.filter((mod) => mod.id?.includes('astro&type=style')); } // Add hoisted scripts so these get invalidated @@ -110,15 +97,6 @@ export async function handleHotUpdate( } } - // TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be - const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte')); - if (isSelfAccepting) { - if (/astro\.config\.[cm][jt]s$/.test(file)) return mods; - logger.info('astro', msg.hmr({ file })); - } else { - logger.info('astro', msg.reload({ file })); - } - return mods; } diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts index 1649d80691513..d02d78d6ae6a3 100644 --- a/packages/astro/src/vite-plugin-astro/index.ts +++ b/packages/astro/src/vite-plugin-astro/index.ts @@ -139,6 +139,7 @@ export default function astro({ settings, logger }: AstroPluginOptions): vite.Pl const compileProps: CompileProps = { astroConfig: config, viteConfig: resolvedConfig, + preferences: settings.preferences, filename: normalizePath(parsedId.filename), source, }; @@ -173,18 +174,21 @@ export default function astro({ settings, logger }: AstroPluginOptions): vite.Pl }, async handleHotUpdate(context) { if (context.server.config.isProduction) return; - const compileProps: CompileProps = { - astroConfig: config, - viteConfig: resolvedConfig, - filename: context.file, - source: await context.read(), - }; - const compile = () => cachedCompilation(compileProps); + const filename = context.file; + const source = await context.read(); + const compile = () => + cachedCompilation({ + astroConfig: config, + viteConfig: resolvedConfig, + preferences: settings.preferences, + filename, + source, + }); return handleHotUpdate(context, { config, logger, compile, - source: compileProps.source, + source, }); }, }; diff --git a/packages/astro/src/vite-plugin-dev-overlay/vite-plugin-dev-overlay.ts b/packages/astro/src/vite-plugin-dev-overlay/vite-plugin-dev-overlay.ts index 5c3aabe5ac6d8..201e6aac63f57 100644 --- a/packages/astro/src/vite-plugin-dev-overlay/vite-plugin-dev-overlay.ts +++ b/packages/astro/src/vite-plugin-dev-overlay/vite-plugin-dev-overlay.ts @@ -16,7 +16,7 @@ export default function astroDevOverlay({ settings }: AstroPluginOptions): vite. if (id === resolvedVirtualModuleId) { return ` export const loadDevOverlayPlugins = async () => { - return [${settings.devOverlayPlugins + return [${settings.devToolbarApps .map((plugin) => `(await import('${plugin}')).default`) .join(',')}]; }; diff --git a/packages/astro/src/vite-plugin-fileurl/index.ts b/packages/astro/src/vite-plugin-fileurl/index.ts new file mode 100644 index 0000000000000..4a14323a07597 --- /dev/null +++ b/packages/astro/src/vite-plugin-fileurl/index.ts @@ -0,0 +1,13 @@ +import type { Plugin as VitePlugin } from 'vite'; + +export default function vitePluginFileURL({}): VitePlugin { + return { + name: 'astro:vite-plugin-file-url', + resolveId(source, importer) { + if (source.startsWith('file://')) { + const rest = source.slice(7); + return this.resolve(rest, importer); + } + }, + }; +} diff --git a/packages/astro/src/vite-plugin-inject-env-ts/index.ts b/packages/astro/src/vite-plugin-inject-env-ts/index.ts index d884075ab09e7..855d3a2e05386 100644 --- a/packages/astro/src/vite-plugin-inject-env-ts/index.ts +++ b/packages/astro/src/vite-plugin-inject-env-ts/index.ts @@ -50,16 +50,6 @@ export async function setUpEnvTs({ if (fs.existsSync(envTsPath)) { let typesEnvContents = await fs.promises.readFile(envTsPath, 'utf-8'); - // TODO: Remove this in 4.0, this code is only to help users migrate away from assets being experimental for a long time - if (typesEnvContents.includes('types="astro/client-image"')) { - typesEnvContents = typesEnvContents.replace( - 'types="astro/client-image"', - 'types="astro/client"' - ); - await fs.promises.writeFile(envTsPath, typesEnvContents, 'utf-8'); - logger.info('assets', `Removed ${bold(envTsPathRelativetoRoot)} types`); - } - if (!fs.existsSync(dotAstroDir)) // Add `.astro` types reference if none exists return; @@ -68,7 +58,7 @@ export async function setUpEnvTs({ if (!typesEnvContents.includes(expectedTypeReference)) { typesEnvContents = `${expectedTypeReference}\n${typesEnvContents}`; await fs.promises.writeFile(envTsPath, typesEnvContents, 'utf-8'); - logger.info('content', `Added ${bold(envTsPathRelativetoRoot)} types`); + logger.info('types', `Added ${bold(envTsPathRelativetoRoot)} type declarations`); } } else { // Otherwise, inject the `env.d.ts` file @@ -81,6 +71,6 @@ export async function setUpEnvTs({ await fs.promises.mkdir(settings.config.srcDir, { recursive: true }); await fs.promises.writeFile(envTsPath, referenceDefs.join('\n'), 'utf-8'); - logger.info('astro', `Added ${bold(envTsPathRelativetoRoot)} types`); + logger.info('types', `Added ${bold(envTsPathRelativetoRoot)} type declarations`); } } diff --git a/packages/astro/src/vite-plugin-integrations-container/index.ts b/packages/astro/src/vite-plugin-integrations-container/index.ts index b18d2e5e99561..2125df857d9fb 100644 --- a/packages/astro/src/vite-plugin-integrations-container/index.ts +++ b/packages/astro/src/vite-plugin-integrations-container/index.ts @@ -34,7 +34,7 @@ async function resolveEntryPoint( this: PluginContext, route: InjectedRoute ): Promise<ResolvedInjectedRoute> { - const resolvedId = await this.resolve(route.entryPoint) + const resolvedId = await this.resolve(route.entrypoint) .then((res) => res?.id) .catch(() => undefined); if (!resolvedId) return route; diff --git a/packages/astro/src/vite-plugin-load-fallback/index.ts b/packages/astro/src/vite-plugin-load-fallback/index.ts index e11f317ca8f08..80db39edd4330 100644 --- a/packages/astro/src/vite-plugin-load-fallback/index.ts +++ b/packages/astro/src/vite-plugin-load-fallback/index.ts @@ -2,6 +2,7 @@ import nodeFs from 'node:fs'; import npath from 'node:path'; import type * as vite from 'vite'; import { slash } from '../core/path.js'; +import { cleanUrl } from '../vite-plugin-utils/index.js'; type NodeFileSystemModule = typeof nodeFs; @@ -77,8 +78,3 @@ export default function loadFallbackPlugin({ }, ]; } - -const queryRE = /\?.*$/s; -const hashRE = /#.*$/s; - -const cleanUrl = (url: string): string => url.replace(hashRE, '').replace(queryRE, ''); diff --git a/packages/astro/src/vite-plugin-scanner/index.ts b/packages/astro/src/vite-plugin-scanner/index.ts index d48aed203dde7..678f3ac187d8a 100644 --- a/packages/astro/src/vite-plugin-scanner/index.ts +++ b/packages/astro/src/vite-plugin-scanner/index.ts @@ -52,12 +52,11 @@ export default function astroScannerPlugin({ // this should only be valid for `.astro`, `.js` and `.ts` files KNOWN_FILE_EXTENSIONS.includes(extname(filename)) ) { - const reason = ` because \`output: "${settings.config.output}"\` is set`; logger.warn( - 'getStaticPaths', - `The getStaticPaths() statement in ${bold( + 'router', + `getStaticPaths() ignored in dynamic page ${bold( rootRelativePath(settings.config.root, fileURL, true) - )} has been ignored${reason}.\n\nAdd \`export const prerender = true;\` to prerender this page.` + )}. Add \`export const prerender = true;\` to prerender the page as static HTML during the build process.` ); } diff --git a/packages/astro/src/vite-plugin-scanner/scan.ts b/packages/astro/src/vite-plugin-scanner/scan.ts index 3eb834ea24db5..6c277567d4161 100644 --- a/packages/astro/src/vite-plugin-scanner/scan.ts +++ b/packages/astro/src/vite-plugin-scanner/scan.ts @@ -72,7 +72,7 @@ export async function scan( message: AstroErrorData.InvalidPrerenderExport.message( prefix, suffix, - settings?.config.output === 'hybrid' ?? false + settings?.config.output === 'hybrid' ), location: { file: id }, }); diff --git a/packages/astro/src/vite-plugin-scripts/index.ts b/packages/astro/src/vite-plugin-scripts/index.ts index 0066b98f5e703..9b2848923752a 100644 --- a/packages/astro/src/vite-plugin-scripts/index.ts +++ b/packages/astro/src/vite-plugin-scripts/index.ts @@ -50,8 +50,7 @@ export default function astroScriptsPlugin({ settings }: { settings: AstroSettin }, buildStart() { const hasHydrationScripts = settings.scripts.some((s) => s.stage === 'before-hydration'); - // @ts-expect-error Vite 5 renamed `ssrBuild` to `isSsrBuild` - const isSsrBuild = env?.ssrBuild || env?.isSsrBuild; + const isSsrBuild = env?.isSsrBuild; if (hasHydrationScripts && env?.command === 'build' && !isSsrBuild) { this.emitFile({ type: 'chunk', diff --git a/packages/astro/src/vite-plugin-utils/index.ts b/packages/astro/src/vite-plugin-utils/index.ts index 51f0e6cc4c1c1..7bf9f092f618d 100644 --- a/packages/astro/src/vite-plugin-utils/index.ts +++ b/packages/astro/src/vite-plugin-utils/index.ts @@ -56,3 +56,8 @@ export function normalizeFilename(filename: string, root: URL) { } return removeLeadingForwardSlashWindows(filename); } + +const postfixRE = /[?#].*$/s; +export function cleanUrl(url: string): string { + return url.replace(postfixRE, ''); +} diff --git a/packages/astro/test/astro-basic.test.js b/packages/astro/test/astro-basic.test.js index 37a5693cf315b..78c3a0ed5e7b6 100644 --- a/packages/astro/test/astro-basic.test.js +++ b/packages/astro/test/astro-basic.test.js @@ -151,6 +151,19 @@ describe('Astro basics', () => { expect($('body > :nth-child(5)').prop('outerHTML')).to.equal('<textarea>textarea</textarea>'); }); + it('Generates pages that end with .mjs', async () => { + const content1 = await fixture.readFile('/get-static-paths-with-mjs/example.mjs'); + expect(content1).to.be.ok; + const content2 = await fixture.readFile('/get-static-paths-with-mjs/example.js'); + expect(content2).to.be.ok; + }); + + it('allows file:// urls as module specifiers', async () => { + const html = await fixture.readFile('/fileurl/index.html'); + const $ = cheerio.load(html); + expect($('h1').text()).to.equal('WORKS'); + }); + describe('preview', () => { it('returns 200 for valid URLs', async () => { const result = await fixture.fetch('/'); diff --git a/packages/astro/test/astro-markdown-drafts.test.js b/packages/astro/test/astro-markdown-drafts.test.js deleted file mode 100644 index 8f6c753e4c5f8..0000000000000 --- a/packages/astro/test/astro-markdown-drafts.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import { expect } from 'chai'; -import * as cheerio from 'cheerio'; -import { loadFixture } from './test-utils.js'; - -describe('Astro Markdown with draft posts disabled', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/astro-markdown-drafts/', - }); - await fixture.build(); - }); - it('Does not render the draft post', async () => { - let renderedDraft = false; - try { - await fixture.readFile('/wip/index.html'); - renderedDraft = true; - } catch (err) { - expect(err.code).to.equal('ENOENT'); - } - expect(renderedDraft).to.equal(false, 'Rendered a draft post'); - }); -}); - -describe('Astro Markdown with draft posts enabled', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/astro-markdown-drafts/', - markdown: { - drafts: true, - }, - }); - await fixture.build(); - }); - it('Renders the draft post', async () => { - const html = await fixture.readFile('/wip/index.html'); - const $ = cheerio.load(html); - expect($('h1').length).to.be.ok; - expect($('h1').text()).to.equal('WIP'); - }); -}); diff --git a/packages/astro/test/astro-markdown-remarkRehype.test.js b/packages/astro/test/astro-markdown-remarkRehype.test.js index 59b0eeda6f158..17b20b51ea220 100644 --- a/packages/astro/test/astro-markdown-remarkRehype.test.js +++ b/packages/astro/test/astro-markdown-remarkRehype.test.js @@ -15,7 +15,7 @@ describe('Astro Markdown without remark-rehype config', () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); expect($('#footnote-label').text()).to.equal('Footnotes'); - expect($('.data-footnote-backref').first().attr('aria-label')).to.equal('Back to content'); + expect($('.data-footnote-backref').first().attr('aria-label')).to.equal('Back to reference 1'); }); }); diff --git a/packages/astro/test/astro-markdown-shiki.test.js b/packages/astro/test/astro-markdown-shiki.test.js index 6315edbffbad3..459fc646457bd 100644 --- a/packages/astro/test/astro-markdown-shiki.test.js +++ b/packages/astro/test/astro-markdown-shiki.test.js @@ -95,10 +95,6 @@ describe('Astro Markdown Shiki', () => { const unknownLang = $('.astro-code').get(1); expect(unknownLang.attribs.style).to.contain('background-color:#24292e;color:#e1e4e8;'); - - const caddyLang = $('.astro-code').last(); - const caddySegments = caddyLang.find('.line'); - expect(caddySegments.get(1).children[0].attribs.style).to.contain('color:#B392F0'); }); }); diff --git a/packages/astro/test/astro-scripts.test.js b/packages/astro/test/astro-scripts.test.js index ae2268d8097f9..f36e24d924d3e 100644 --- a/packages/astro/test/astro-scripts.test.js +++ b/packages/astro/test/astro-scripts.test.js @@ -145,7 +145,7 @@ describe('Scripts (hoisted and not)', () => { hooks: { 'astro:config:setup': ({ injectRoute, injectScript }) => { injectScript('page', `import '/src/scripts/something.js';`); - injectRoute({ pattern: 'injected-route', entryPoint: 'src/external-page.astro' }); + injectRoute({ pattern: 'injected-route', entrypoint: 'src/external-page.astro' }); }, }, }, diff --git a/packages/astro/test/astro-slots.test.js b/packages/astro/test/astro-slots.test.js index 34f1d82255ccd..69a0025e1f275 100644 --- a/packages/astro/test/astro-slots.test.js +++ b/packages/astro/test/astro-slots.test.js @@ -40,13 +40,20 @@ describe('Slots', () => { expect($('#default').text().trim()).to.equal('Default'); }); - it('Slots render fallback content by default', async () => { + it('Slots of a component render fallback content by default', async () => { const html = await fixture.readFile('/fallback/index.html'); const $ = cheerio.load(html); expect($('#default')).to.have.lengthOf(1); }); + it('Slots of a page render fallback content', async () => { + const html = await fixture.readFile('/fallback-own/index.html'); + const $ = cheerio.load(html); + + expect($('#default')).to.have.lengthOf(1); + }); + it('Slots override fallback content', async () => { const html = await fixture.readFile('/fallback-override/index.html'); const $ = cheerio.load(html); diff --git a/packages/astro/test/cli.test.js b/packages/astro/test/cli.test.js index 82cf7a12dca8e..caec4241daceb 100644 --- a/packages/astro/test/cli.test.js +++ b/packages/astro/test/cli.test.js @@ -106,7 +106,7 @@ describe('astro cli', () => { expect(messages[0]).to.contain('astro'); expect(messages[0]).to.contain(pkgVersion); - expect(messages[0]).to.contain('started in'); + expect(messages[0]).to.contain('ready in'); }); ['dev', 'preview'].forEach((cmd) => { diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index 74f86ba7ff6e8..0d9b690b4817f 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -640,14 +640,13 @@ describe('astro:image', () => { expect(logs[0].message).to.contain('Expected getImage() parameter'); }); - // TODO: For some reason, this error crashes the dev server? - it.skip('properly error when src is undefined', async () => { + it('properly error when src is undefined', async () => { logs.length = 0; let res = await fixture.fetch('/get-image-undefined'); await res.text(); expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('Expected src to be an image.'); + expect(logs[0].message).to.contain('Expected `src` property'); }); it('properly error image in Markdown frontmatter is not found', async () => { @@ -663,7 +662,6 @@ describe('astro:image', () => { logs.length = 0; let res = await fixture.fetch('/post'); await res.text(); - expect(logs).to.have.a.lengthOf(1); expect(logs[0].message).to.contain('Could not find requested image'); }); diff --git a/packages/astro/test/events.test.js b/packages/astro/test/events.test.js index b0732a15c61ba..c0c6266d9f1e7 100644 --- a/packages/astro/test/events.test.js +++ b/packages/astro/test/events.test.js @@ -105,7 +105,6 @@ describe('Events', () => { config: 'path/to/config.mjs', experimentalSsr: true, experimentalIntegrations: true, - drafts: true, }; const [{ payload }] = events.eventCliSession( { @@ -122,7 +121,6 @@ describe('Events', () => { 'config', 'experimentalSsr', 'experimentalIntegrations', - 'drafts', ]); }); }); diff --git a/packages/astro/test/featuresSupport.test.js b/packages/astro/test/featuresSupport.test.js index c25d9d5f8f08c..15606b927c1de 100644 --- a/packages/astro/test/featuresSupport.test.js +++ b/packages/astro/test/featuresSupport.test.js @@ -10,14 +10,9 @@ describe('Adapter', () => { fixture = await loadFixture({ root: './fixtures/middleware space/', output: 'server', - build: { - excludeMiddleware: true, - }, adapter: testAdapter({ extendAdapter: { - supportsFeatures: { - edgeMiddleware: 'Unsupported', - }, + supportedAstroFeatures: {}, }, }), }); @@ -34,14 +29,9 @@ describe('Adapter', () => { fixture = await loadFixture({ root: './fixtures/middleware space/', output: 'server', - build: { - split: true, - }, adapter: testAdapter({ extendAdapter: { - supportsFeatures: { - functionPerPage: 'Unsupported', - }, + supportedAstroFeatures: {}, }, }), }); diff --git a/packages/astro/test/fixtures/0-css/package.json b/packages/astro/test/fixtures/0-css/package.json index 6ecfb1d9e925a..fca80fd91b260 100644 --- a/packages/astro/test/fixtures/0-css/package.json +++ b/packages/astro/test/fixtures/0-css/package.json @@ -9,7 +9,7 @@ "astro": "workspace:*", "react": "^18.1.0", "react-dom": "^18.1.0", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json index a708628bbc154..a632b84638dcc 100644 --- a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/alias-tsconfig/package.json b/packages/astro/test/fixtures/alias-tsconfig/package.json index e27fc9130d95c..80033bdf9e01f 100644 --- a/packages/astro/test/fixtures/alias-tsconfig/package.json +++ b/packages/astro/test/fixtures/alias-tsconfig/package.json @@ -6,6 +6,6 @@ "@astrojs/svelte": "workspace:*", "@test/namespace-package": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/alias/package.json b/packages/astro/test/fixtures/alias/package.json index e23fb4d581ef2..74351e6e39e6e 100644 --- a/packages/astro/test/fixtures/alias/package.json +++ b/packages/astro/test/fixtures/alias/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js b/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js index d18eb086f9a5e..cb9308ba45540 100644 --- a/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js +++ b/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js @@ -15,10 +15,10 @@ export function getStaticPaths() { } export function GET({ params, request }) { - return { - body: JSON.stringify({ + return new Response( + JSON.stringify({ param: params.param, pathname: new URL(request.url).pathname }) - }; + ); } diff --git a/packages/astro/test/fixtures/astro-basic/package.json b/packages/astro/test/fixtures/astro-basic/package.json index c2e0be656281d..417636229c93b 100644 --- a/packages/astro/test/fixtures/astro-basic/package.json +++ b/packages/astro/test/fixtures/astro-basic/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/astro-basic/src/pages/fileurl.astro b/packages/astro/test/fixtures/astro-basic/src/pages/fileurl.astro new file mode 100644 index 0000000000000..e85507941c5db --- /dev/null +++ b/packages/astro/test/fixtures/astro-basic/src/pages/fileurl.astro @@ -0,0 +1,10 @@ +--- +import {capitalize} from 'file://../strings.js'; +--- + +<html> + <head><title>Testing + +

{capitalize('works')

+ + diff --git a/packages/astro/test/fixtures/astro-basic/src/pages/get-static-paths-with-mjs/[...file].js b/packages/astro/test/fixtures/astro-basic/src/pages/get-static-paths-with-mjs/[...file].js new file mode 100644 index 0000000000000..8aae81326907e --- /dev/null +++ b/packages/astro/test/fixtures/astro-basic/src/pages/get-static-paths-with-mjs/[...file].js @@ -0,0 +1,10 @@ +export function getStaticPaths() { + return [ + { params: { file: 'example.mjs' } }, + { params: { file: 'example.js' } }, + ]; +} + +export function GET() { + return new Response('console.log("fileContent");') +} diff --git a/packages/astro/test/fixtures/astro-basic/src/strings.js b/packages/astro/test/fixtures/astro-basic/src/strings.js new file mode 100644 index 0000000000000..8d34ca3077f01 --- /dev/null +++ b/packages/astro/test/fixtures/astro-basic/src/strings.js @@ -0,0 +1,4 @@ + +export function capitalize(str) { + return str.toUpperCase(); +} diff --git a/packages/astro/test/fixtures/astro-children/package.json b/packages/astro/test/fixtures/astro-children/package.json index 5fc2951be5973..1ed097ea12716 100644 --- a/packages/astro/test/fixtures/astro-children/package.json +++ b/packages/astro/test/fixtures/astro-children/package.json @@ -7,8 +7,8 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "preact": "^10.19.2", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/astro-client-only/package.json b/packages/astro/test/fixtures/astro-client-only/package.json index a550b3a7b6361..2d55fe99cb4c6 100644 --- a/packages/astro/test/fixtures/astro-client-only/package.json +++ b/packages/astro/test/fixtures/astro-client-only/package.json @@ -9,6 +9,6 @@ "astro": "workspace:*", "react": "^18.1.0", "react-dom": "^18.1.0", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/astro-dynamic/package.json b/packages/astro/test/fixtures/astro-dynamic/package.json index 2dc810458302c..6209dabe9120c 100644 --- a/packages/astro/test/fixtures/astro-dynamic/package.json +++ b/packages/astro/test/fixtures/astro-dynamic/package.json @@ -8,6 +8,6 @@ "astro": "workspace:*", "react": "^18.1.0", "react-dom": "^18.1.0", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/astro-envs/package.json b/packages/astro/test/fixtures/astro-envs/package.json index c46f4d6814acb..86bad5a8713c6 100644 --- a/packages/astro/test/fixtures/astro-envs/package.json +++ b/packages/astro/test/fixtures/astro-envs/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/astro-expr/package.json b/packages/astro/test/fixtures/astro-expr/package.json index c6dce6e21a6a3..ac553abf2fe77 100644 --- a/packages/astro/test/fixtures/astro-expr/package.json +++ b/packages/astro/test/fixtures/astro-expr/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/astro-fallback/package.json b/packages/astro/test/fixtures/astro-fallback/package.json index ea2281e0811d5..8726d73a91aa2 100644 --- a/packages/astro/test/fixtures/astro-fallback/package.json +++ b/packages/astro/test/fixtures/astro-fallback/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts index 32a0fd140f123..21df537cd4a28 100644 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts @@ -1,14 +1,12 @@ export async function getStaticPaths() { - return [ + return [ { params: { slug: 'thing1' } }, { params: { slug: 'thing2' } } ]; } export async function GET() { - return { - body: JSON.stringify({ - title: '[slug]' - }, null, 4) - }; + return Response.json({ + title: '[slug]', + }); } diff --git a/packages/astro/test/fixtures/astro-markdown-drafts/package.json b/packages/astro/test/fixtures/astro-markdown-drafts/package.json deleted file mode 100644 index fa376d6f134f8..0000000000000 --- a/packages/astro/test/fixtures/astro-markdown-drafts/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@test/astro-markdown-drafts", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/index.md b/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/index.md deleted file mode 100644 index 0e06444da3ccd..0000000000000 --- a/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -foo: bar ---- - -# Hello world - -This should be visible. \ No newline at end of file diff --git a/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/wip.md b/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/wip.md deleted file mode 100644 index 27b8296140d76..0000000000000 --- a/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/wip.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -foo: bar -draft: true ---- - -# WIP - -This is a draft. Don't build me! \ No newline at end of file diff --git a/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js b/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js index 3aae6d89a8a90..1916378c93c09 100644 --- a/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js +++ b/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js @@ -1,6 +1,4 @@ export async function GET() { const docs = await import.meta.glob('./*.md', { eager: true }); - return { - body: JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)), - } + return Response.json(Object.values(docs).map((doc) => doc.frontmatter)); } diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/package.json b/packages/astro/test/fixtures/astro-markdown-plugins/package.json index a7953b785825a..bd48d532e2412 100644 --- a/packages/astro/test/fixtures/astro-markdown-plugins/package.json +++ b/packages/astro/test/fixtures/astro-markdown-plugins/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "astro": "workspace:*", - "hast-util-select": "^6.0.0", - "rehype-slug": "^5.0.1" + "hast-util-select": "^6.0.2", + "rehype-slug": "^6.0.0" } } diff --git a/packages/astro/test/fixtures/astro-markdown-shiki/langs/astro.config.mjs b/packages/astro/test/fixtures/astro-markdown-shiki/langs/astro.config.mjs index 9a5f2eced5523..130596b0c4c53 100644 --- a/packages/astro/test/fixtures/astro-markdown-shiki/langs/astro.config.mjs +++ b/packages/astro/test/fixtures/astro-markdown-shiki/langs/astro.config.mjs @@ -13,14 +13,6 @@ export default { grammar: riGrammar, aliases: ['ri'], }, - { - id: 'caddy', - scopeName: 'source.Caddyfile', - // shiki compat: resolves from astro package directory. - // careful as astro is linked, this relative path is based on astro/packages/astro. - // it's weird but we're testing to prevent regressions. - path: './test/fixtures/astro-markdown-shiki/langs/src/caddyfile.tmLanguage.json', - }, ], }, }, diff --git a/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/caddyfile.tmLanguage.json b/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/caddyfile.tmLanguage.json deleted file mode 100644 index 8a9f87c870cb1..0000000000000 --- a/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/caddyfile.tmLanguage.json +++ /dev/null @@ -1,365 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - - "name": "Caddyfile", - "fileTypes": ["Caddyfile"], - "scopeName": "source.Caddyfile", - - "patterns": [ - { "include": "#comments" }, - { "include": "#strings" }, - { "include": "#domains" }, - { "include": "#status_codes" }, - { "include": "#path" }, - { "include": "#global_options" }, - { "include": "#matchers" }, - { "include": "#directive" }, - { "include": "#site_block_common" } - ], - - "repository": { - "comments": { - "patterns": [ - { - "name": "comment.line.Caddyfile", - "match": "\\s#.*" - }, - { - "name": "comment.line.Caddyfile", - "match": "^#.*" - } - ] - }, - - "strings": { - "patterns": [ - { - "comment": "Double Quoted Strings", - "begin": "\"", - "end": "\"", - "name": "string.quoted.double.Caddyfile", - "patterns": [ - { - "name": "constant.character.escape.Caddyfile", - "match": "\\\\\"" - } - ] - }, - { - "comment": "Backtick Strings", - "begin": "`", - "end": "`", - "name": "string.quoted.single.Caddyfile" - } - ] - }, - - "status_codes": { - "patterns": [ - { - "name": "constant.numeric.decimal", - "match": "\\s[0-9]{3}(?!\\.)" - } - ] - }, - - "path": { - "patterns": [ - { - "name": "keyword.control.caddyfile", - "match": "(unix/)*/[a-zA-Z0-9_\\-./*]+" - }, - { - "name": "variable.other.property.caddyfile", - "match": "\\*.[a-z]{1,5}" - }, - { - "name": "variable.other.property.caddyfile", - "match": "\\*/?" - }, - { - "name": "variable.other.property.caddyfile", - "match": "\\?/" - } - ] - }, - - "domains": { - "patterns": [ - { - "comment": "Domains and URLs", - "name": "keyword.control.caddyfile", - "match": "(https?://)*[a-z0-9-\\*]*(?:\\.[a-zA-Z]{2,})+(:[0-9]+)*\\S*" - }, - { - "comment": "localhost", - "name": "keyword.control.caddyfile", - "match": "localhost(:[0-9]+)*" - }, - { - "comment": "IPv4", - "name": "keyword.control.caddyfile", - "match": "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" - }, - { - "comment": "IPv6", - "name": "keyword.control.caddyfile", - "match": "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" - }, - { - "comment": "Ports", - "name": "keyword.control.caddyfile", - "match": ":[0-9]+" - } - ] - }, - - "global_options": { - "patterns": [ - { - "begin": "^(\\{)$", - "end": "^(\\})$", - - "beginCaptures": { - "0": { "name": "punctuation.definition.dictionary.begin" } - }, - - "endCaptures": { - "0": { "name": "punctuation.definition.dictionary.end" } - }, - - "patterns": [ - { "include": "#comments" }, - { - "name": "support.constant.Caddyfile", - "match": "^\\s*(debug|https?_port|default_bind|order|storage|storage_clean_interval|renew_interval|ocsp_interval|admin|log|grace_period|shutdown_delay|auto_https|email|default_sni|local_certs|skip_install_trust|acme_ca|acme_ca_root|acme_eab|acme_dns|on_demand_tls|key_type|cert_issuer|ocsp_stapling|preferred_chains|servers|pki|events)" - } - ] - } - ] - }, - - "site_block_common": { - "patterns": [{ "include": "#placeholders" }, { "include": "#block" }] - }, - - "matchers": { - "patterns": [ - { - "comment": "Matchers", - "name": "support.function.Caddyfile", - "match": "@[^\\s]+(?=\\s)" - } - ] - }, - - "placeholders": { - "patterns": [ - { - "name": "keyword.control.Caddyfile", - "match": "\\{[\\[\\]\\w.\\$+-]+\\}" - } - ] - }, - - "directive": { - "patterns": [ - { - "name": "entity.name.function.Caddyfile", - "match": "^\\s*[a-zA-Z_\\-+]+" - }, - { "include": "#content_types" }, - { "include": "#heredoc" } - ] - }, - - "content_types": { - "patterns": [ - { - "comment": "Content Types", - "name": "variable.other.property.caddyfile", - "match": "(application|audio|example|font|image|message|model|multipart|text|video)/[a-zA-Z0-9*+\\-.]+;* *[a-zA-Z0-9=\\-]*" - } - ] - }, - - "block": { - "patterns": [ - { - "begin": "\\{", - "end": "\\}", - - "patterns": [{ "include": "#block_content" }] - } - ] - }, - - "block_content": { - "patterns": [ - { - "patterns": [ - { "include": "#comments" }, - { "include": "#strings" }, - { "include": "#domains" }, - { "include": "#status_codes" }, - { "include": "#path" }, - { "include": "#matchers" }, - { "include": "#placeholders" }, - { "include": "#directive" }, - { "include": "#block" } - ] - } - ] - }, - - "heredoc": { - "patterns": [ - { - "begin": "(?i)(?=<<\\s*([a-z_\\x{7f}-\\x{10ffff}][a-z0-9_\\x{7f}-\\x{10ffff}]*)\\s*$)", - "end": "(?!\\G)", - "name": "string.unquoted.heredoc.caddyfile", - "patterns": [{ "include": "#heredoc_interior" }] - } - ] - }, - - "heredoc_interior": { - "patterns": [ - { - "comment": "CSS", - - "name": "meta.embedded.css", - "contentName": "source.css", - - "begin": "(<<)\\s*(CSS)(\\s*)$", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.caddyfile" }, - "1": { "name": "punctuation.definition.string.begin" }, - "2": { "name": "keyword.operator.heredoc.caddyfile" }, - "4": { "name": "invalid.illegal.trailing-whitespace.caddyfile" } - }, - - "end": "^\\s*(\\2)(?![A-Za-z0-9_\\x{7f}-\\x{10ffff}])", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.caddyfile" }, - "1": { "name": "keyword.operator.heredoc.caddyfile" } - }, - - "patterns": [{ "include": "source.css" }] - }, - - { - "comment": "HTML", - - "name": "meta.embedded.html", - "contentName": "text.html", - - "begin": "(<<)\\s*(HTML)(\\s*)$", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.caddyfile" }, - "1": { "name": "punctuation.definition.string.begin" }, - "2": { "name": "keyword.operator.heredoc.caddyfile" }, - "4": { "name": "invalid.illegal.trailing-whitespace.caddyfile" } - }, - - "end": "^\\s*(\\2)(?![A-Za-z0-9_\\x{7f}-\\x{10ffff}])", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.caddyfile" }, - "1": { "name": "keyword.operator.heredoc.caddyfile" } - }, - - "patterns": [{ "include": "text.html.basic" }] - }, - - { - "comment": "JavaScript", - - "name": "meta.embedded.js", - "contentName": "source.js", - - "begin": "(<<)\\s*(JAVASCRIPT|JS)(\\s*)$", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.caddyfile" }, - "1": { "name": "punctuation.definition.string.begin" }, - "2": { "name": "keyword.operator.heredoc.caddyfile" }, - "4": { "name": "invalid.illegal.trailing-whitespace.caddyfile" } - }, - - "end": "^\\s*(\\2)(?![A-Za-z0-9_\\x{7f}-\\x{10ffff}])", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.caddyfile" }, - "1": { "name": "keyword.operator.heredoc.caddyfile" } - }, - - "patterns": [{ "include": "source.js" }] - }, - - { - "comment": "JSON", - - "name": "meta.embedded.json", - "contentName": "source.json", - - "begin": "(<<)\\s*(JSON)(\\s*)$", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.caddyfile" }, - "1": { "name": "punctuation.definition.string.begin" }, - "2": { "name": "keyword.operator.heredoc.caddyfile" }, - "4": { "name": "invalid.illegal.trailing-whitespace.caddyfile" } - }, - - "end": "^\\s*(\\2)(?![A-Za-z0-9_\\x{7f}-\\x{10ffff}])", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.caddyfile" }, - "1": { "name": "keyword.operator.heredoc.caddyfile" } - }, - - "patterns": [{ "include": "source.json" }] - }, - - { - "comment": "XML", - - "name": "meta.embedded.xml", - "contentName": "text.xml", - - "begin": "(<<)\\s*(XML)(\\s*)$", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.caddyfile" }, - "1": { "name": "punctuation.definition.string.begin" }, - "2": { "name": "keyword.operator.heredoc.caddyfile" }, - "4": { "name": "invalid.illegal.trailing-whitespace.caddyfile" } - }, - - "end": "^\\s*(\\2)(?![A-Za-z0-9_\\x{7f}-\\x{10ffff}])", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.caddyfile" }, - "1": { "name": "keyword.operator.heredoc.caddyfile" } - }, - - "patterns": [{ "include": "text.xml" }] - }, - - { - "comment": "Any other heredoc", - - "begin": "(?i)(<<)\\s*([a-z_\\x{7f}-\\x{10ffff}]+[a-z0-9_\\x{7f}-\\x{10ffff}]*)(\\s*)", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.caddyfile" }, - "1": { "name": "punctuation.definition.string.caddyfile" }, - "2": { "name": "keyword.operator.heredoc.caddyfile" }, - "4": { "name": "invalid.illegal.trailing-whitespace.caddyfile" } - }, - - "end": "^\\s*(\\2)(?![A-Za-z0-9_\\x{7f}-\\x{10ffff}])", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.caddyfile" }, - "1": { "name": "keyword.operator.heredoc.caddyfile" } - }, - - "patterns": [] - } - ] - } - } -} diff --git a/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/pages/index.md b/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/pages/index.md index cdd74060f3a89..d2d756b95dc1f 100644 --- a/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/pages/index.md +++ b/packages/astro/test/fixtures/astro-markdown-shiki/langs/src/pages/index.md @@ -24,12 +24,3 @@ fin ```unknown This language does not exist ``` - -```caddy -example.com { - root * /var/www/wordpress - encode gzip - php_fastcgi unix//run/php/php-version-fpm.sock - file_server -} -``` diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js index b2c9ea6ea25f3..3cc852c6f565b 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js @@ -1,9 +1,7 @@ import { getHeadings } from './with-layout.md'; export async function GET() { - return { - body: JSON.stringify({ - headings: getHeadings(), - }), - } + return Response.json({ + headings: getHeadings(), + }); } diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js index 82977443dc11a..cf499bb39c018 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js @@ -1,10 +1,8 @@ import { rawContent, compiledContent } from './basic.md'; export async function GET() { - return { - body: JSON.stringify({ - raw: rawContent(), - compiled: await compiledContent(), - }), - } + return Response.json({ + raw: rawContent(), + compiled: await compiledContent(), + }); } diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js index 7a5d00f47ac08..7dfe96294701a 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js @@ -1,7 +1,5 @@ import { frontmatter } from './vite-env-vars.md'; export async function GET() { - return { - body: JSON.stringify(frontmatter), - } + return Response.json(frontmatter); } diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars.md b/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars.md index f4983af2c75b9..5fac527272449 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars.md +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars.md @@ -21,7 +21,7 @@ This should also work outside of code blocks: // src/pages/rss.xml.js import rss from '@astrojs/rss'; -export const get = () => rss({ +export const GET = () => rss({ // Use Vite env vars with import.meta.env site: import.meta.env.SITE, title: import.meta.env.TITLE, diff --git a/packages/astro/test/fixtures/astro-slot-with-client/package.json b/packages/astro/test/fixtures/astro-slot-with-client/package.json index 830c205cfaf90..eb88bae982ff3 100644 --- a/packages/astro/test/fixtures/astro-slot-with-client/package.json +++ b/packages/astro/test/fixtures/astro-slot-with-client/package.json @@ -4,6 +4,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/astro-slots-nested/package.json b/packages/astro/test/fixtures/astro-slots-nested/package.json index e40fa03968cb0..2e1a6bef901cb 100644 --- a/packages/astro/test/fixtures/astro-slots-nested/package.json +++ b/packages/astro/test/fixtures/astro-slots-nested/package.json @@ -9,11 +9,11 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/astro-slots/src/pages/fallback-own.astro b/packages/astro/test/fixtures/astro-slots/src/pages/fallback-own.astro new file mode 100644 index 0000000000000..89319f8b18581 --- /dev/null +++ b/packages/astro/test/fixtures/astro-slots/src/pages/fallback-own.astro @@ -0,0 +1,10 @@ + + + + + + +
+
+ + diff --git a/packages/astro/test/fixtures/astro-slots/src/pages/fallback.astro b/packages/astro/test/fixtures/astro-slots/src/pages/fallback.astro index 88aba06e9fa59..aa1a4795859d0 100644 --- a/packages/astro/test/fixtures/astro-slots/src/pages/fallback.astro +++ b/packages/astro/test/fixtures/astro-slots/src/pages/fallback.astro @@ -7,8 +7,6 @@ import Fallback from '../components/Fallback.astro'; -
- -
+ diff --git a/packages/astro/test/fixtures/before-hydration/package.json b/packages/astro/test/fixtures/before-hydration/package.json index a49804cd70e55..cf419345b9af0 100644 --- a/packages/astro/test/fixtures/before-hydration/package.json +++ b/packages/astro/test/fixtures/before-hydration/package.json @@ -4,6 +4,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/build-assets/package.json b/packages/astro/test/fixtures/build-assets/package.json index 3a8c744ed0f05..b09d02c66826a 100644 --- a/packages/astro/test/fixtures/build-assets/package.json +++ b/packages/astro/test/fixtures/build-assets/package.json @@ -4,6 +4,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/component-library-shared/package.json b/packages/astro/test/fixtures/component-library-shared/package.json index b6d1bdfe87e9e..b91ef821600de 100644 --- a/packages/astro/test/fixtures/component-library-shared/package.json +++ b/packages/astro/test/fixtures/component-library-shared/package.json @@ -18,7 +18,7 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.2.0" } } diff --git a/packages/astro/test/fixtures/component-library/package.json b/packages/astro/test/fixtures/component-library/package.json index 3697c7a7ef76c..14a8cb44a6575 100644 --- a/packages/astro/test/fixtures/component-library/package.json +++ b/packages/astro/test/fixtures/component-library/package.json @@ -8,9 +8,9 @@ "@astrojs/svelte": "workspace:*", "@test/component-library-shared": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/content-collection-references/src/pages/welcome-data.json.js b/packages/astro/test/fixtures/content-collection-references/src/pages/welcome-data.json.js index 27f97174d29b0..f2e34420acd3c 100644 --- a/packages/astro/test/fixtures/content-collection-references/src/pages/welcome-data.json.js +++ b/packages/astro/test/fixtures/content-collection-references/src/pages/welcome-data.json.js @@ -4,9 +4,7 @@ export async function GET() { const welcomePost = await getEntry('blog', 'welcome'); if (!welcomePost?.data) { - return { - body: { error: 'blog/welcome did not return `data`.' }, - } + return Response.json({ error: 'blog/welcome did not return `data`.' }, { status: 404 }) } const banner = await getEntry(welcomePost.data.banner); diff --git a/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js b/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js index e335d2b05d7c0..b7b7d847253e3 100644 --- a/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js +++ b/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js @@ -8,7 +8,7 @@ export async function GET() { const withSlugConfig = stripAllRenderFn(await getCollection('with-custom-slugs')); const withUnionSchema = stripAllRenderFn(await getCollection('with-union-schema')); - return { - body: devalue.stringify({withoutConfig, withSchemaConfig, withSlugConfig, withUnionSchema}), - } + return new Response( + devalue.stringify({ withoutConfig, withSchemaConfig, withSlugConfig, withUnionSchema }) + ); } diff --git a/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js b/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js index 311b76cc8bca6..a05a9138b1d85 100644 --- a/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js +++ b/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js @@ -5,10 +5,17 @@ import { stripRenderFn } from '../utils.js'; export async function GET() { const columbiaWithoutConfig = stripRenderFn(await getEntryBySlug('without-config', 'columbia')); const oneWithSchemaConfig = stripRenderFn(await getEntryBySlug('with-schema-config', 'one')); - const twoWithSlugConfig = stripRenderFn(await getEntryBySlug('with-custom-slugs', 'interesting-two')); + const twoWithSlugConfig = stripRenderFn( + await getEntryBySlug('with-custom-slugs', 'interesting-two') + ); const postWithUnionSchema = stripRenderFn(await getEntryBySlug('with-union-schema', 'post')); - return { - body: devalue.stringify({columbiaWithoutConfig, oneWithSchemaConfig, twoWithSlugConfig, postWithUnionSchema}), - } + return new Response( + devalue.stringify({ + columbiaWithoutConfig, + oneWithSchemaConfig, + twoWithSlugConfig, + postWithUnionSchema, + }) + ); } diff --git a/packages/astro/test/fixtures/core-image-errors/src/pages/get-image-undefined.astro b/packages/astro/test/fixtures/core-image-errors/src/pages/get-image-undefined.astro index c75fd10d2b4e9..e417c28b3a151 100644 --- a/packages/astro/test/fixtures/core-image-errors/src/pages/get-image-undefined.astro +++ b/packages/astro/test/fixtures/core-image-errors/src/pages/get-image-undefined.astro @@ -1,5 +1,5 @@ --- import { getImage } from "astro:assets"; -const myImage = getImage({src: undefined}); +const myImage = await getImage({src: undefined}); --- diff --git a/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts b/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts index 7847baf62cb86..261fb6bb7dc75 100644 --- a/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts +++ b/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts @@ -3,8 +3,5 @@ import type { APIRoute } from "../../../../../src/@types/astro"; export const GET = (async ({ params, request }) => { const url = new URL(request.url); const src = url.searchParams.get("src"); - - return { - body: "An image: " + JSON.stringify(src), - }; + return new Response("An image: " + JSON.stringify(src)); }) satisfies APIRoute; diff --git a/packages/astro/test/fixtures/css-dangling-references/package.json b/packages/astro/test/fixtures/css-dangling-references/package.json index 9ac28d2822148..03878694edd0d 100644 --- a/packages/astro/test/fixtures/css-dangling-references/package.json +++ b/packages/astro/test/fixtures/css-dangling-references/package.json @@ -1,11 +1,10 @@ { - "name": "@test/css-dangling-references", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*", - "@astrojs/svelte": "workspace:*", - "svelte": "4" - } + "name": "@test/css-dangling-references", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/svelte": "workspace:*", + "astro": "workspace:*", + "svelte": "^4.2.5" } - \ No newline at end of file +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/custom-404-injected-from-dep/astro.config.mjs b/packages/astro/test/fixtures/custom-404-injected-from-dep/astro.config.mjs index 840a9524cbdb1..15a3b3e795098 100644 --- a/packages/astro/test/fixtures/custom-404-injected-from-dep/astro.config.mjs +++ b/packages/astro/test/fixtures/custom-404-injected-from-dep/astro.config.mjs @@ -9,7 +9,7 @@ export default defineConfig({ 'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '404', - entryPoint: '@test/custom-404-pkg/404.astro', + entrypoint: '@test/custom-404-pkg/404.astro', }); }, }, diff --git a/packages/astro/test/fixtures/custom-404-injected/astro.config.mjs b/packages/astro/test/fixtures/custom-404-injected/astro.config.mjs index d46ce7eb77c94..ae0d4e111a2e0 100644 --- a/packages/astro/test/fixtures/custom-404-injected/astro.config.mjs +++ b/packages/astro/test/fixtures/custom-404-injected/astro.config.mjs @@ -9,7 +9,7 @@ export default defineConfig({ 'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '404', - entryPoint: 'src/404.astro', + entrypoint: 'src/404.astro', }); }, }, diff --git a/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js b/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js index 76f4d57606d29..8d5365a2eb2d2 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js @@ -1,9 +1,9 @@ import { getEntry } from 'astro:content'; -const ids = ['Ben Holmes', 'Fred K Schott', 'Nate Moore'] +const ids = ['Ben Holmes', 'Fred K Schott', 'Nate Moore']; export function getStaticPaths() { - return ids.map(id => ({ params: { id } })) + return ids.map((id) => ({ params: { id } })); } /** @param {import('astro').APIContext} params */ @@ -11,12 +11,8 @@ export async function GET({ params }) { const { id } = params; const author = await getEntry('authors-without-config', id); if (!author) { - return { - body: JSON.stringify({ error: `Author ${id} Not found` }), - } + return Response.json({ error: `Author ${id} Not found` }); } else { - return { - body: JSON.stringify(author), - } + return Response.json(author); } } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js b/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js index 5b5007fedb701..79dd8cd9dd3c2 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js @@ -2,8 +2,5 @@ import { getCollection } from 'astro:content'; export async function GET() { const authors = await getCollection('authors-without-config'); - - return { - body: JSON.stringify(authors), - } + return Response.json(authors); } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js b/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js index ab8cc764e353c..c6b0cfff669b5 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js @@ -1,9 +1,9 @@ import { getEntry } from 'astro:content'; -const langs = ['en', 'es', 'fr'] +const langs = ['en', 'es', 'fr']; export function getStaticPaths() { - return langs.map(lang => ({ params: { lang } })) + return langs.map((lang) => ({ params: { lang } })); } /** @param {import('astro').APIContext} params */ @@ -11,12 +11,8 @@ export async function GET({ params }) { const { lang } = params; const translations = await getEntry('i18n', lang); if (!translations) { - return { - body: JSON.stringify({ error: `Translation ${lang} Not found` }), - } + return Response.json({ error: `Translation ${lang} Not found` }); } else { - return { - body: JSON.stringify(translations), - } + return Response.json(translations); } } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js b/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js index e8a1fee92908d..f1ebb15b761e6 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js @@ -2,8 +2,5 @@ import { getCollection } from 'astro:content'; export async function GET() { const translations = await getCollection('i18n'); - - return { - body: JSON.stringify(translations), - } + return Response.json(translations); } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js b/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js index f7b84752dd3f2..5f71c80e9f7b8 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js @@ -2,8 +2,5 @@ import { getDataEntryById } from 'astro:content'; export async function GET() { const item = await getDataEntryById('i18n', 'en'); - - return { - body: JSON.stringify(item), - } + return Response.json(item); } diff --git a/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts b/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts index 8fccd6695a8c0..96a9d56f6cb4f 100644 --- a/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts +++ b/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts @@ -1,15 +1,13 @@ -import type { APIRoute } from "astro"; +import type { APIRoute } from 'astro'; -const slugs = ["one", undefined]; +const slugs = ['one', undefined]; export const GET: APIRoute = ({ params }) => { - return { - body: JSON.stringify({ - slug: params.slug || "index", - }), - }; + return Response.json({ + slug: params.slug || 'index', + }); }; export function getStaticPaths() { - return slugs.map((u) => ({ params: { slug: u } })); + return slugs.map((u) => ({ params: { slug: u } })); } diff --git a/packages/astro/test/fixtures/entry-file-names/package.json b/packages/astro/test/fixtures/entry-file-names/package.json index a405afb9eac84..bfd58eae787e7 100644 --- a/packages/astro/test/fixtures/entry-file-names/package.json +++ b/packages/astro/test/fixtures/entry-file-names/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/fetch/package.json b/packages/astro/test/fixtures/fetch/package.json index 2d215ec891188..60cfd4166c4b0 100644 --- a/packages/astro/test/fixtures/fetch/package.json +++ b/packages/astro/test/fixtures/fetch/package.json @@ -7,8 +7,8 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "preact": "^10.19.2", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/fontsource-package/package.json b/packages/astro/test/fixtures/fontsource-package/package.json index 7cfd6d26cf44b..55140976cb6e4 100644 --- a/packages/astro/test/fixtures/fontsource-package/package.json +++ b/packages/astro/test/fixtures/fontsource-package/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@fontsource/monofett": "5.0.9", - "@fontsource/montserrat": "5.0.8", + "@fontsource/monofett": "5.0.17", + "@fontsource/montserrat": "5.0.15", "astro": "workspace:*" } } diff --git a/packages/astro/test/fixtures/hydration-race/package.json b/packages/astro/test/fixtures/hydration-race/package.json index aa0a5d47ef8de..08319bc2be2cc 100644 --- a/packages/astro/test/fixtures/hydration-race/package.json +++ b/packages/astro/test/fixtures/hydration-race/package.json @@ -9,6 +9,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/i18n-routing-base/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing-base/astro.config.mjs index d20245efb0105..ee4909209d5a9 100644 --- a/packages/astro/test/fixtures/i18n-routing-base/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing-base/astro.config.mjs @@ -2,13 +2,16 @@ import { defineConfig} from "astro/config"; export default defineConfig({ base: "new-site", - experimental: { i18n: { defaultLocale: 'en', locales: [ - 'en', 'pt', 'it' + 'en', 'pt', 'it', { + path: "spanish", + codes: ["es", "es-ar"] + } ], - routingStrategy: "prefix-always" - } + routing: { + prefixDefaultLocale: true + } } }) diff --git a/packages/astro/test/fixtures/i18n-routing-base/src/pages/spanish/blog/[id].astro b/packages/astro/test/fixtures/i18n-routing-base/src/pages/spanish/blog/[id].astro new file mode 100644 index 0000000000000..f560f94f5adec --- /dev/null +++ b/packages/astro/test/fixtures/i18n-routing-base/src/pages/spanish/blog/[id].astro @@ -0,0 +1,18 @@ +--- +export function getStaticPaths() { + return [ + {params: {id: '1'}, props: { content: "Lo siento" }}, + {params: {id: '2'}, props: { content: "Eat Something" }}, + {params: {id: '3'}, props: { content: "How are you?" }}, + ]; +} +const { content } = Astro.props; +--- + + + Astro + + +{content} + + diff --git a/packages/astro/test/fixtures/i18n-routing-base/src/pages/spanish/start.astro b/packages/astro/test/fixtures/i18n-routing-base/src/pages/spanish/start.astro new file mode 100644 index 0000000000000..d67e9de3f0854 --- /dev/null +++ b/packages/astro/test/fixtures/i18n-routing-base/src/pages/spanish/start.astro @@ -0,0 +1,12 @@ +--- +const currentLocale = Astro.currentLocale; +--- + + + Astro + + +Espanol +Current Locale: {currentLocale ? currentLocale : "none"} + + diff --git a/packages/astro/test/fixtures/i18n-routing-fallback/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing-fallback/astro.config.mjs index f7524a64210d7..45c3b49a064d7 100644 --- a/packages/astro/test/fixtures/i18n-routing-fallback/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing-fallback/astro.config.mjs @@ -2,7 +2,6 @@ import { defineConfig} from "astro/config"; export default defineConfig({ base: "new-site", - experimental: { i18n: { defaultLocale: 'en', locales: [ @@ -13,5 +12,4 @@ export default defineConfig({ pt: "en" } } - } }) diff --git a/packages/astro/test/fixtures/i18n-routing-fallback/src/pages/index.astro b/packages/astro/test/fixtures/i18n-routing-fallback/src/pages/index.astro index 05faf7b0bccec..34b39fcd6747e 100644 --- a/packages/astro/test/fixtures/i18n-routing-fallback/src/pages/index.astro +++ b/packages/astro/test/fixtures/i18n-routing-fallback/src/pages/index.astro @@ -1,8 +1,13 @@ Astro + Hello + + diff --git a/packages/astro/test/fixtures/i18n-routing-prefix-always/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing-prefix-always/astro.config.mjs index f2aac5899cbbe..58eb50540ec10 100644 --- a/packages/astro/test/fixtures/i18n-routing-prefix-always/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing-prefix-always/astro.config.mjs @@ -1,14 +1,17 @@ import { defineConfig} from "astro/config"; export default defineConfig({ - experimental: { i18n: { defaultLocale: 'en', locales: [ - 'en', 'pt', 'it' + 'en', 'pt', 'it', { + path: "spanish", + codes: ["es", "es-ar"] + } ], - routingStrategy: "prefix-always" - } - }, + routing: { + prefixDefaultLocale: true + } + }, base: "/new-site" }) diff --git a/packages/astro/test/fixtures/i18n-routing-prefix-always/src/pages/spanish/blog/[id].astro b/packages/astro/test/fixtures/i18n-routing-prefix-always/src/pages/spanish/blog/[id].astro new file mode 100644 index 0000000000000..f560f94f5adec --- /dev/null +++ b/packages/astro/test/fixtures/i18n-routing-prefix-always/src/pages/spanish/blog/[id].astro @@ -0,0 +1,18 @@ +--- +export function getStaticPaths() { + return [ + {params: {id: '1'}, props: { content: "Lo siento" }}, + {params: {id: '2'}, props: { content: "Eat Something" }}, + {params: {id: '3'}, props: { content: "How are you?" }}, + ]; +} +const { content } = Astro.props; +--- + + + Astro + + +{content} + + diff --git a/packages/astro/test/fixtures/i18n-routing-prefix-always/src/pages/spanish/start.astro b/packages/astro/test/fixtures/i18n-routing-prefix-always/src/pages/spanish/start.astro new file mode 100644 index 0000000000000..d67e9de3f0854 --- /dev/null +++ b/packages/astro/test/fixtures/i18n-routing-prefix-always/src/pages/spanish/start.astro @@ -0,0 +1,12 @@ +--- +const currentLocale = Astro.currentLocale; +--- + + + Astro + + +Espanol +Current Locale: {currentLocale ? currentLocale : "none"} + + diff --git a/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/astro.config.mjs index 3b8911f6d4b76..93ecee2941b2d 100644 --- a/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/astro.config.mjs @@ -1,15 +1,11 @@ import { defineConfig} from "astro/config"; export default defineConfig({ - experimental: { - i18n: { - defaultLocale: 'en', - locales: [ - 'en', 'pt', 'it' - ], - routingStrategy: "prefix-other-locales" - }, - + i18n: { + defaultLocale: 'en', + locales: [ + 'en', 'pt', 'it' + ], }, base: "/new-site" }) diff --git a/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/src/pages/spanish/blog/[id].astro b/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/src/pages/spanish/blog/[id].astro new file mode 100644 index 0000000000000..f560f94f5adec --- /dev/null +++ b/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/src/pages/spanish/blog/[id].astro @@ -0,0 +1,18 @@ +--- +export function getStaticPaths() { + return [ + {params: {id: '1'}, props: { content: "Lo siento" }}, + {params: {id: '2'}, props: { content: "Eat Something" }}, + {params: {id: '3'}, props: { content: "How are you?" }}, + ]; +} +const { content } = Astro.props; +--- + + + Astro + + +{content} + + diff --git a/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/src/pages/spanish/start.astro b/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/src/pages/spanish/start.astro new file mode 100644 index 0000000000000..d67e9de3f0854 --- /dev/null +++ b/packages/astro/test/fixtures/i18n-routing-prefix-other-locales/src/pages/spanish/start.astro @@ -0,0 +1,12 @@ +--- +const currentLocale = Astro.currentLocale; +--- + + + Astro + + +Espanol +Current Locale: {currentLocale ? currentLocale : "none"} + + diff --git a/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs index 209ad40fd0579..259b10d07d3f2 100644 --- a/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs @@ -1,12 +1,10 @@ import { defineConfig} from "astro/config"; export default defineConfig({ - experimental: { - i18n: { - defaultLocale: 'en', - locales: [ - 'en', 'pt', 'it' - ] - } - }, + i18n: { + defaultLocale: 'en', + locales: [ + 'en', 'pt', 'it' + ] + } }) diff --git a/packages/astro/test/fixtures/i18n-routing/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing/astro.config.mjs index 209ad40fd0579..42559e778a30d 100644 --- a/packages/astro/test/fixtures/i18n-routing/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing/astro.config.mjs @@ -1,12 +1,16 @@ import { defineConfig} from "astro/config"; export default defineConfig({ - experimental: { i18n: { defaultLocale: 'en', locales: [ - 'en', 'pt', 'it' + 'en', + 'pt', + 'it', + { + path: "spanish", + codes: ["es", "es-SP"] + } ] } - }, }) diff --git a/packages/astro/test/fixtures/i18n-routing/src/pages/virtual-module.astro b/packages/astro/test/fixtures/i18n-routing/src/pages/virtual-module.astro index e6fa2ac2ffbf6..ca33030dbed02 100644 --- a/packages/astro/test/fixtures/i18n-routing/src/pages/virtual-module.astro +++ b/packages/astro/test/fixtures/i18n-routing/src/pages/virtual-module.astro @@ -1,8 +1,10 @@ --- -import { getRelativeLocaleUrl } from "astro:i18n"; +import { getRelativeLocaleUrl, getPathByLocale, getLocaleByPath } from "astro:i18n"; let about = getRelativeLocaleUrl("pt", "about"); - +let spanish = getRelativeLocaleUrl("es", "about"); +let spainPath = getPathByLocale("es-SP"); +let localeByPath = getLocaleByPath("spanish"); --- @@ -13,5 +15,8 @@ let about = getRelativeLocaleUrl("pt", "about"); Virtual module doesn't break About: {about} + About spanish: {spanish} + Spain path: {spainPath} + Preferred path: {localeByPath} diff --git a/packages/astro/test/fixtures/integration-add-page-extension/astro.config.mjs b/packages/astro/test/fixtures/integration-add-page-extension/astro.config.mjs index 0a0a336976b4a..4c52ae0dab410 100644 --- a/packages/astro/test/fixtures/integration-add-page-extension/astro.config.mjs +++ b/packages/astro/test/fixtures/integration-add-page-extension/astro.config.mjs @@ -1,4 +1,4 @@ -import { defineConfig } from 'rollup' +import { defineConfig } from 'astro/config' import test from './integration.js' export default defineConfig({ diff --git a/packages/astro/test/fixtures/integration-server-setup/astro.config.mjs b/packages/astro/test/fixtures/integration-server-setup/astro.config.mjs index 0a0a336976b4a..4c52ae0dab410 100644 --- a/packages/astro/test/fixtures/integration-server-setup/astro.config.mjs +++ b/packages/astro/test/fixtures/integration-server-setup/astro.config.mjs @@ -1,4 +1,4 @@ -import { defineConfig } from 'rollup' +import { defineConfig } from 'astro/config' import test from './integration.js' export default defineConfig({ diff --git a/packages/astro/test/fixtures/jsx/package.json b/packages/astro/test/fixtures/jsx/package.json index 73113746da073..f4b89d76e9f63 100644 --- a/packages/astro/test/fixtures/jsx/package.json +++ b/packages/astro/test/fixtures/jsx/package.json @@ -12,11 +12,11 @@ "astro": "workspace:*" }, "dependencies": { - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/large-array/package.json b/packages/astro/test/fixtures/large-array/package.json index e4559b4aeff64..69f74d0406370 100644 --- a/packages/astro/test/fixtures/large-array/package.json +++ b/packages/astro/test/fixtures/large-array/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/solid-js": "workspace:*", "astro": "workspace:*", - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/test/fixtures/middleware space/src/middleware.js b/packages/astro/test/fixtures/middleware space/src/middleware.js index 779bc5c93930e..1404169ef96c7 100644 --- a/packages/astro/test/fixtures/middleware space/src/middleware.js +++ b/packages/astro/test/fixtures/middleware space/src/middleware.js @@ -7,6 +7,12 @@ const first = defineMiddleware(async (context, next) => { return new Response('New content!!', { status: 200, }); + } else if (context.request.url.includes('/content-policy')) { + const response = await next(); + response.headers.append('X-Content-Type-Options', 'nosniff'); + response.headers.append('Content-Type', 'application/json'); + + return next(); } else if (context.request.url.includes('/broken-500')) { return new Response(null, { status: 500, @@ -19,21 +25,21 @@ const first = defineMiddleware(async (context, next) => { headers: response.headers, }); } else if (context.url.pathname === '/throw') { - throw new Error; + throw new Error(); } else if (context.url.pathname === '/clone') { const response = await next(); const newResponse = response.clone(); const /** @type {string} */ html = await newResponse.text(); const newhtml = html.replace('testing', 'it works'); return new Response(newhtml, { status: 200, headers: response.headers }); - } else if(context.url.pathname === '/return-response-cookies') { + } else if (context.url.pathname === '/return-response-cookies') { const response = await next(); - const html = await response.text(); + const html = await response.text(); - return new Response(html, { - status: 200, - headers: response.headers - }); + return new Response(html, { + status: 200, + headers: response.headers, + }); } else { if (context.url.pathname === '/') { context.cookies.set('foo', 'bar'); diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts deleted file mode 100644 index 3936cbe85ba75..0000000000000 --- a/packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts +++ /dev/null @@ -1,12 +0,0 @@ -// NOTE: test deprecated object form -// Returns the file body for this non-HTML file. -// The content type is based off of the extension in the filename, -// in this case: about.json. -export async function GET() { - return { - body: JSON.stringify({ - name: 'Astro', - url: 'https://astro.build/', - }), - }; -} diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts deleted file mode 100644 index 11415900400cc..0000000000000 --- a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { promises as fs } from 'node:fs'; - -import type { APIRoute } from 'astro'; - -// NOTE: test deprecated object form -export const GET: APIRoute = async function get() { - try { - // Image is in the public domain. Sourced from - // https://en.wikipedia.org/wiki/File:Portrait_placeholder.png - const buffer = await fs.readFile('./test/fixtures/non-html-pages/src/images/placeholder.png'); - return { - body: buffer.toString('binary'), - encoding: 'binary', - } as const; - } catch (error: unknown) { - throw new Error(`Something went wrong in placeholder.png route!: ${error as string}`); - } -}; diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts index 50c6b877b09f8..1ac93597e62bd 100644 --- a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts +++ b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts @@ -2,12 +2,13 @@ import { promises as fs } from 'node:fs'; import type { APIRoute } from 'astro'; -export const GET: APIRoute = async function get({ ResponseWithEncoding }) { +export const GET: APIRoute = async function get() { try { // Image is in the public domain. Sourced from // https://en.wikipedia.org/wiki/File:Portrait_placeholder.png const buffer = await fs.readFile('./test/fixtures/non-html-pages/src/images/placeholder.png'); - return new ResponseWithEncoding(buffer.toString('binary'), undefined, 'binary') + // NOTE: SSG only so not Content-Type needed + return new Response(buffer.buffer) } catch (error: unknown) { throw new Error(`Something went wrong in placeholder.png route!: ${error as string}`); } diff --git a/packages/astro/test/fixtures/postcss/package.json b/packages/astro/test/fixtures/postcss/package.json index c9e4ba833cda9..db86ba46c61c2 100644 --- a/packages/astro/test/fixtures/postcss/package.json +++ b/packages/astro/test/fixtures/postcss/package.json @@ -9,11 +9,11 @@ "astro": "workspace:*", "autoprefixer": "^10.4.15", "postcss": "^8.4.28", - "solid-js": "^1.7.11", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "solid-js": "^1.8.5", + "svelte": "^4.2.5", + "vue": "^3.3.8" }, "devDependencies": { - "postcss-preset-env": "^9.1.1" + "postcss-preset-env": "^9.3.0" } } diff --git a/packages/astro/test/fixtures/preact-compat-component/package.json b/packages/astro/test/fixtures/preact-compat-component/package.json index bbab4a6299a43..68de1f1b7fd9d 100644 --- a/packages/astro/test/fixtures/preact-compat-component/package.json +++ b/packages/astro/test/fixtures/preact-compat-component/package.json @@ -6,6 +6,6 @@ "@astrojs/preact": "workspace:*", "@test/react-lib": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/preact-component/package.json b/packages/astro/test/fixtures/preact-component/package.json index bdb2524aabfa9..43e8fd8f8463d 100644 --- a/packages/astro/test/fixtures/preact-component/package.json +++ b/packages/astro/test/fixtures/preact-component/package.json @@ -6,6 +6,6 @@ "@astrojs/preact": "workspace:*", "@preact/signals": "1.2.1", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/react-and-solid/package.json b/packages/astro/test/fixtures/react-and-solid/package.json index 01ac7866e634d..a585a2c95073c 100644 --- a/packages/astro/test/fixtures/react-and-solid/package.json +++ b/packages/astro/test/fixtures/react-and-solid/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*", "react": "^18.2.0", "react-dom": "^18.1.0", - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json b/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json index 0a7f6e7cf6bd7..1388cc07a3078 100644 --- a/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json +++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json @@ -4,6 +4,6 @@ "dependencies": { "@astrojs/preact": "workspace:", "astro": "workspace:", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/routing-priority/integration.mjs b/packages/astro/test/fixtures/routing-priority/integration.mjs index 213812790e649..57ecc307336c1 100644 --- a/packages/astro/test/fixtures/routing-priority/integration.mjs +++ b/packages/astro/test/fixtures/routing-priority/integration.mjs @@ -5,15 +5,15 @@ export default function() { 'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '/injected', - entryPoint: './src/to-inject.astro' + entrypoint: './src/to-inject.astro' }); injectRoute({ pattern: '/_injected', - entryPoint: './src/_to-inject.astro' + entrypoint: './src/_to-inject.astro' }); injectRoute({ pattern: '/[id]', - entryPoint: './src/[id].astro' + entrypoint: './src/[id].astro' }); } } diff --git a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts index bc7e1b774698e..4b26f41e56a01 100644 --- a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts +++ b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts @@ -1,11 +1,11 @@ import type { APIRoute } from 'astro'; export const GET: APIRoute = async ({ params }) => { - return { - body: JSON.stringify({ + return new Response( + JSON.stringify({ path: params.slug, - }), - }; + }) + ); }; export function getStaticPaths() { diff --git a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts index b06efff6f213b..b9d2f0cabff12 100644 --- a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts +++ b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts @@ -1,12 +1,12 @@ import type { APIRoute } from 'astro'; export const GET: APIRoute = async ({ params }) => { - return { - body: JSON.stringify({ + return new Response( + JSON.stringify({ foo: params.foo, - bar: params.bar, - }), - }; + bar: params.bar, + }) + ); }; export function getStaticPaths() { diff --git a/packages/astro/test/fixtures/slots-preact/package.json b/packages/astro/test/fixtures/slots-preact/package.json index 33dcf78bccec2..bcd612323fd7f 100644 --- a/packages/astro/test/fixtures/slots-preact/package.json +++ b/packages/astro/test/fixtures/slots-preact/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/slots-solid/package.json b/packages/astro/test/fixtures/slots-solid/package.json index 87b0e75bf01cf..688101adf72f9 100644 --- a/packages/astro/test/fixtures/slots-solid/package.json +++ b/packages/astro/test/fixtures/slots-solid/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/solid-js": "workspace:*", "astro": "workspace:*", - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/test/fixtures/slots-svelte/package.json b/packages/astro/test/fixtures/slots-svelte/package.json index f166a1fc91625..5335dd2add8ff 100644 --- a/packages/astro/test/fixtures/slots-svelte/package.json +++ b/packages/astro/test/fixtures/slots-svelte/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/slots-vue/package.json b/packages/astro/test/fixtures/slots-vue/package.json index e61cf2bbec644..4beb43ad927d8 100644 --- a/packages/astro/test/fixtures/slots-vue/package.json +++ b/packages/astro/test/fixtures/slots-vue/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json b/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json index e9d0ed6c027f4..59568a5143821 100644 --- a/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json +++ b/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json @@ -10,6 +10,6 @@ } }, "dependencies": { - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/test/fixtures/solid-component/package.json b/packages/astro/test/fixtures/solid-component/package.json index 9cd5517550fe7..8a8696964ace9 100644 --- a/packages/astro/test/fixtures/solid-component/package.json +++ b/packages/astro/test/fixtures/solid-component/package.json @@ -4,9 +4,9 @@ "private": true, "dependencies": { "@astrojs/solid-js": "workspace:*", - "@solidjs/router": "^0.8.3", + "@solidjs/router": "^0.9.1", "@test/solid-jsx-component": "file:./deps/solid-jsx-component", "astro": "workspace:*", - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" } } diff --git a/packages/astro/test/fixtures/ssr-api-route-custom-404/src/pages/api/route.js b/packages/astro/test/fixtures/ssr-api-route-custom-404/src/pages/api/route.js index 5a1cacc115bc7..3547e0ad676d5 100644 --- a/packages/astro/test/fixtures/ssr-api-route-custom-404/src/pages/api/route.js +++ b/packages/astro/test/fixtures/ssr-api-route-custom-404/src/pages/api/route.js @@ -1,6 +1,4 @@ export function POST() { - return { - body: JSON.stringify({ ok: true }) - }; + return Response.json({ ok: true }); } diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/binary.js b/packages/astro/test/fixtures/ssr-api-route/src/pages/binary.js index 796bf4616be32..b5f1b013617ec 100644 --- a/packages/astro/test/fixtures/ssr-api-route/src/pages/binary.js +++ b/packages/astro/test/fixtures/ssr-api-route/src/pages/binary.js @@ -4,7 +4,7 @@ export function GET() { return new Response('ok') } -export async function post({ request }) { +export async function POST({ request }) { const data = await request.formData(); const file = data.get('file'); diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js b/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js index ba110ee13f4d7..d5c9f4033d67a 100644 --- a/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js +++ b/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js @@ -1,18 +1,16 @@ /** - * @param {import('astro').APIContext} api + * @param {import('astro').APIContext} api */ export function GET(ctx) { - return { - body: JSON.stringify({ - cookiesExist: !!ctx.cookies, - requestExist: !!ctx.request, - redirectExist: !!ctx.redirect, - propsExist: !!ctx.props, - params: ctx.params, - site: ctx.site?.toString(), - generator: ctx.generator, - url: ctx.url.toString(), - clientAddress: ctx.clientAddress, - }) - }; + return Response.json({ + cookiesExist: !!ctx.cookies, + requestExist: !!ctx.request, + redirectExist: !!ctx.redirect, + propsExist: !!ctx.props, + params: ctx.params, + site: ctx.site?.toString(), + generator: ctx.generator, + url: ctx.url.toString(), + clientAddress: ctx.clientAddress, + }); } diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js b/packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js deleted file mode 100644 index 7992e697aacc8..0000000000000 --- a/packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js +++ /dev/null @@ -1,10 +0,0 @@ -// NOTE: test deprecated object form -export function GET() { - return { - body: JSON.stringify([ - { name: 'lettuce' }, - { name: 'broccoli' }, - { name: 'pizza' } - ]) - }; -} diff --git a/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js b/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js index 8c7c393029c16..8956f0d4ccc3c 100644 --- a/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js +++ b/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js @@ -1,6 +1,3 @@ - export function GET({ params }) { - return { - body: JSON.stringify(params) - }; + return Response.json(params); } diff --git a/packages/astro/test/fixtures/ssr-env/package.json b/packages/astro/test/fixtures/ssr-env/package.json index 9a78d42135d44..4cc5e8ea55233 100644 --- a/packages/astro/test/fixtures/ssr-env/package.json +++ b/packages/astro/test/fixtures/ssr-env/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts index d969873c54d1f..7a1b6af282416 100644 --- a/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts @@ -1,16 +1,14 @@ export const prerender = true; export async function getStaticPaths() { - return [ + return [ { params: { slug: 'thing1' } }, { params: { slug: 'thing2' } } ]; } export async function GET() { - return { - body: JSON.stringify({ - title: '[slug]' - }, null, 4) - }; + return Response.json({ + title: '[slug]', + }); } diff --git a/packages/astro/test/fixtures/ssr-scripts/package.json b/packages/astro/test/fixtures/ssr-scripts/package.json index 5b4a8abb76242..3489d3ba42487 100644 --- a/packages/astro/test/fixtures/ssr-scripts/package.json +++ b/packages/astro/test/fixtures/ssr-scripts/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/preact": "workspace:", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/static-build-frameworks/package.json b/packages/astro/test/fixtures/static-build-frameworks/package.json index 4df7c2b126424..f2ba47078a676 100644 --- a/packages/astro/test/fixtures/static-build-frameworks/package.json +++ b/packages/astro/test/fixtures/static-build-frameworks/package.json @@ -6,7 +6,7 @@ "@astrojs/preact": "workspace:*", "@astrojs/react": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1", + "preact": "^10.19.2", "react": "^18.1.0", "react-dom": "^18.1.0" } diff --git a/packages/astro/test/fixtures/static-build/package.json b/packages/astro/test/fixtures/static-build/package.json index df47dd1ef6fc3..e8eaa87d3501b 100644 --- a/packages/astro/test/fixtures/static-build/package.json +++ b/packages/astro/test/fixtures/static-build/package.json @@ -6,6 +6,6 @@ "@astrojs/preact": "workspace:*", "@test/static-build-pkg": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/astro/test/fixtures/static-build/src/pages/company.json.ts b/packages/astro/test/fixtures/static-build/src/pages/company.json.ts index 08f45a7b87f8a..6a08cc9399bb0 100644 --- a/packages/astro/test/fixtures/static-build/src/pages/company.json.ts +++ b/packages/astro/test/fixtures/static-build/src/pages/company.json.ts @@ -1,8 +1,6 @@ -export async function GET() { - return { - body: JSON.stringify({ - name: 'Astro Technology Company', - url: 'https://astro.build/' - }) - } +export function GET() { + return Response.json({ + name: 'Astro Technology Company', + url: 'https://astro.build/', + }); } diff --git a/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts index 2fa13ac1820e3..2c78812ec1070 100644 --- a/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts @@ -6,11 +6,9 @@ export async function getStaticPaths() { } export async function GET({ params }) { - return { - body: JSON.stringify({ - slug: params.slug, - name: 'Astro Technology Company', - url: 'https://astro.build/' - }) - } + return Response.json({ + slug: params.slug, + name: 'Astro Technology Company', + url: 'https://astro.build/' + }); } diff --git a/packages/astro/test/fixtures/static-build/src/pages/posts.json.js b/packages/astro/test/fixtures/static-build/src/pages/posts.json.js index aefbbffff72cc..b72a000d96387 100644 --- a/packages/astro/test/fixtures/static-build/src/pages/posts.json.js +++ b/packages/astro/test/fixtures/static-build/src/pages/posts.json.js @@ -15,8 +15,5 @@ async function fetchPosts() { export async function GET() { const posts = await fetchPosts(); - - return { - body: JSON.stringify(posts, null, 4), - }; + return Response.json(posts); } diff --git a/packages/astro/test/fixtures/svelte-component/package.json b/packages/astro/test/fixtures/svelte-component/package.json index eb6c574703a90..bc4d8b5aa6eae 100644 --- a/packages/astro/test/fixtures/svelte-component/package.json +++ b/packages/astro/test/fixtures/svelte-component/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0" + "svelte": "^4.2.5" } } diff --git a/packages/astro/test/fixtures/tailwindcss-ts/package.json b/packages/astro/test/fixtures/tailwindcss-ts/package.json index a54b4779ec03c..98ca7985cddb2 100644 --- a/packages/astro/test/fixtures/tailwindcss-ts/package.json +++ b/packages/astro/test/fixtures/tailwindcss-ts/package.json @@ -6,6 +6,6 @@ "@astrojs/tailwind": "workspace:*", "astro": "workspace:*", "postcss": "^8.4.28", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.3.5" } } diff --git a/packages/astro/test/fixtures/tailwindcss/package.json b/packages/astro/test/fixtures/tailwindcss/package.json index 6117883a95716..7815a3b2eee28 100644 --- a/packages/astro/test/fixtures/tailwindcss/package.json +++ b/packages/astro/test/fixtures/tailwindcss/package.json @@ -8,6 +8,6 @@ "astro": "workspace:*", "autoprefixer": "^10.4.15", "postcss": "^8.4.28", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.3.5" } } diff --git a/packages/astro/test/fixtures/third-party-astro/package.json b/packages/astro/test/fixtures/third-party-astro/package.json index cd9d0743c1784..01bdf2b209e6b 100644 --- a/packages/astro/test/fixtures/third-party-astro/package.json +++ b/packages/astro/test/fixtures/third-party-astro/package.json @@ -4,6 +4,6 @@ "private": true, "dependencies": { "astro": "workspace:*", - "astro-embed": "^0.5.1" + "astro-embed": "^0.6.0" } } diff --git a/packages/astro/test/fixtures/vue-component/package.json b/packages/astro/test/fixtures/vue-component/package.json index b1f716dd65fce..7913b77208d0b 100644 --- a/packages/astro/test/fixtures/vue-component/package.json +++ b/packages/astro/test/fixtures/vue-component/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/vue-jsx/package.json b/packages/astro/test/fixtures/vue-jsx/package.json index e04e8077d66cc..76bd57acfa427 100644 --- a/packages/astro/test/fixtures/vue-jsx/package.json +++ b/packages/astro/test/fixtures/vue-jsx/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/package.json b/packages/astro/test/fixtures/vue-with-multi-renderer/package.json index 476c7f680fb60..adc7555259943 100644 --- a/packages/astro/test/fixtures/vue-with-multi-renderer/package.json +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/package.json @@ -6,7 +6,7 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.0", - "vue": "^3.3.4" + "svelte": "^4.2.5", + "vue": "^3.3.8" } } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts index 7830316054672..3c1408300f25c 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts @@ -6,10 +6,8 @@ export async function getStaticPaths() { } export async function GET({ params }) { - return { - body: JSON.stringify({ - slug: params.slug, - title: '[slug]' - }) - }; + return Response.json({ + slug: params.slug, + title: '[slug]' + }); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts index 707c39fa9c9ca..26cd9b065c34a 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts @@ -6,10 +6,8 @@ export async function getStaticPaths() { } export async function GET({ params }) { - return { - body: JSON.stringify({ - slug: params.slug, - title: 'data [slug]' - }) - }; + return Response.json({ + slug: params.slug, + title: 'data [slug]' + }); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts index 5eaac42f1d572..2bee50a8e3281 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts @@ -1,7 +1,3 @@ export async function GET() { - return { - body: JSON.stringify({ - title: 'home' - }) - }; + return Response.json({ title: 'home' }); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts index c6fa887116715..cef9dd60855d5 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts @@ -1,14 +1,16 @@ export async function getStaticPaths() { - return [ - { params: { image: 1 } }, - { params: { image: 2 } }, - ]; + return [{ params: { image: 1 } }, { params: { image: 2 } }]; } export async function GET({ params }) { - return { - body: ` + return new Response( + ` ${params.image} -` - }; +`, + { + headers: { + 'content-type': 'image/svg+xml', + }, + } + ); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts index 84dd6dcaa19a6..c258c3091c2dc 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts @@ -1,9 +1,6 @@ -import { readFileSync } from "node:fs"; +import { readFile } from 'node:fs/promises'; -export async function GET({ params, request }) { - const buffer = readFileSync(new URL('../../astro.png', import.meta.url)); - return { - body: buffer.toString('hex'), - encoding: 'hex', - }; +export async function GET() { + const buffer = await readFile(new URL('../../astro.png', import.meta.url)); + return new Response(buffer.buffer); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts index 93fcf40228bc0..423f258f8c17b 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts @@ -1,7 +1,12 @@ -export async function GET() { - return { - body: ` +export function GET() { + return new Response( + ` Static SVG -` - }; +`, + { + headers: { + 'content-type': 'image/svg+xml', + }, + } + ); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts index b1b48634f1457..9e8e40580ea88 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts @@ -1,4 +1,4 @@ -export const get = () => { +export const GET = () => { return new Response( undefined, { diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js index f305a5747b26d..567dc040e30ec 100644 --- a/packages/astro/test/i18n-routing.test.js +++ b/packages/astro/test/i18n-routing.test.js @@ -1,7 +1,7 @@ -import { loadFixture } from './test-utils.js'; import { expect } from 'chai'; import * as cheerio from 'cheerio'; import testAdapter from './test-adapter.js'; +import { loadFixture } from './test-utils.js'; describe('astro:i18n virtual module', () => { /** @type {import('./test-utils').Fixture} */ @@ -26,6 +26,9 @@ describe('astro:i18n virtual module', () => { const text = await response.text(); expect(text).includes("Virtual module doesn't break"); expect(text).includes('About: /pt/about'); + expect(text).includes('About spanish: /spanish/about'); + expect(text).includes('Spain path: spanish'); + expect(text).includes('Preferred path: es'); }); }); describe('[DEV] i18n routing', () => { @@ -66,6 +69,16 @@ describe('[DEV] i18n routing', () => { expect(await response2.text()).includes('Hola mundo'); }); + it('should render localised page correctly when using path+codes', async () => { + const response = await fixture.fetch('/spanish/start'); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + + const response2 = await fixture.fetch('/spanish/blog/1'); + expect(response2.status).to.equal(200); + expect(await response2.text()).includes('Lo siento'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { const response = await fixture.fetch('/it/start'); expect(response.status).to.equal(404); @@ -114,6 +127,16 @@ describe('[DEV] i18n routing', () => { expect(await response2.text()).includes('Hola mundo'); }); + it('should render localised page correctly when using path+codes', async () => { + const response = await fixture.fetch('/new-site/spanish/start'); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + + const response2 = await fixture.fetch('/new-site/spanish/blog/1'); + expect(response2.status).to.equal(200); + expect(await response2.text()).includes('Lo siento'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { const response = await fixture.fetch('/new-site/it/start'); expect(response.status).to.equal(404); @@ -134,13 +157,20 @@ describe('[DEV] i18n routing', () => { before(async () => { fixture = await loadFixture({ root: './fixtures/i18n-routing-prefix-other-locales/', - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['en', 'pt', 'it'], - fallback: { - it: 'en', + i18n: { + defaultLocale: 'en', + locales: [ + 'en', + 'pt', + 'it', + { + path: 'spanish', + codes: ['es', 'es-AR'], }, + ], + fallback: { + it: 'en', + spanish: 'en', }, }, }); @@ -179,6 +209,16 @@ describe('[DEV] i18n routing', () => { expect(await response2.text()).includes('Hola mundo'); }); + it('should render localised page correctly when using path+codes', async () => { + const response = await fixture.fetch('/new-site/spanish/start'); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + + const response2 = await fixture.fetch('/new-site/spanish/blog/1'); + expect(response2.status).to.equal(200); + expect(await response2.text()).includes('Lo siento'); + }); + it('should redirect to the english locale, which is the first fallback', async () => { const response = await fixture.fetch('/new-site/it/start'); expect(response.status).to.equal(200); @@ -244,6 +284,16 @@ describe('[DEV] i18n routing', () => { expect(await response2.text()).includes('Hola mundo'); }); + it('should render localised page correctly when using path+codes', async () => { + const response = await fixture.fetch('/new-site/spanish/start'); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + + const response2 = await fixture.fetch('/new-site/spanish/blog/1'); + expect(response2.status).to.equal(200); + expect(await response2.text()).includes('Lo siento'); + }); + it('should not redirect to the english locale', async () => { const response = await fixture.fetch('/new-site/it/start'); expect(response.status).to.equal(404); @@ -284,14 +334,23 @@ describe('[DEV] i18n routing', () => { before(async () => { fixture = await loadFixture({ root: './fixtures/i18n-routing-fallback/', - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['en', 'pt', 'it'], - fallback: { - it: 'en', + i18n: { + defaultLocale: 'en', + locales: [ + 'en', + 'pt', + 'it', + { + path: 'spanish', + codes: ['es', 'es-AR'], }, - routingStrategy: 'prefix-other-locales', + ], + fallback: { + it: 'en', + spanish: 'en', + }, + routing: { + prefixDefaultLocale: false, }, }, }); @@ -322,6 +381,16 @@ describe('[DEV] i18n routing', () => { expect(await response2.text()).includes('Hola mundo'); }); + it('should render localised page correctly when using path+codes', async () => { + const response = await fixture.fetch('/new-site/spanish/start'); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Start'); + + const response2 = await fixture.fetch('/new-site/spanish/blog/1'); + expect(response2.status).to.equal(200); + expect(await response2.text()).includes('Hello world'); + }); + it('should redirect to the english locale, which is the first fallback', async () => { const response = await fixture.fetch('/new-site/it/start'); expect(response.status).to.equal(200); @@ -366,6 +435,16 @@ describe('[SSG] i18n routing', () => { expect($('body').text()).includes('Hola mundo'); }); + it('should render localised page correctly when it has codes+path', async () => { + let html = await fixture.readFile('/spanish/start/index.html'); + let $ = cheerio.load(html); + expect($('body').text()).includes('Espanol'); + + html = await fixture.readFile('/spanish/blog/1/index.html'); + $ = cheerio.load(html); + expect($('body').text()).includes('Lo siento'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { try { await fixture.readFile('/it/start/index.html'); @@ -420,6 +499,16 @@ describe('[SSG] i18n routing', () => { expect($('body').text()).includes('Hola mundo'); }); + it('should render localised page correctly when it has codes+path', async () => { + let html = await fixture.readFile('/spanish/start/index.html'); + let $ = cheerio.load(html); + expect($('body').text()).includes('Espanol'); + + html = await fixture.readFile('/spanish/blog/1/index.html'); + $ = cheerio.load(html); + expect($('body').text()).includes('Lo siento'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { try { await fixture.readFile('/it/start/index.html'); @@ -485,6 +574,16 @@ describe('[SSG] i18n routing', () => { expect($('body').text()).includes('Hola mundo'); }); + it('should render localised page correctly when it has codes+path', async () => { + let html = await fixture.readFile('/spanish/start/index.html'); + let $ = cheerio.load(html); + expect($('body').text()).includes('Espanol'); + + html = await fixture.readFile('/spanish/blog/1/index.html'); + $ = cheerio.load(html); + expect($('body').text()).includes('Lo siento'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { try { await fixture.readFile('/it/start/index.html'); @@ -545,6 +644,16 @@ describe('[SSG] i18n routing', () => { expect($('body').text()).includes('Hola mundo'); }); + it('should render localised page correctly when it has codes+path', async () => { + let html = await fixture.readFile('/spanish/start/index.html'); + let $ = cheerio.load(html); + expect($('body').text()).includes('Espanol'); + + html = await fixture.readFile('/spanish/blog/1/index.html'); + $ = cheerio.load(html); + expect($('body').text()).includes('Lo siento'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { try { await fixture.readFile('/it/start/index.html'); @@ -590,13 +699,20 @@ describe('[SSG] i18n routing', () => { before(async () => { fixture = await loadFixture({ root: './fixtures/i18n-routing-fallback/', - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['en', 'pt', 'it'], - fallback: { - it: 'en', + i18n: { + defaultLocale: 'en', + locales: [ + 'en', + 'pt', + 'it', + { + path: 'spanish', + codes: ['es', 'es-AR'], }, + ], + fallback: { + it: 'en', + spanish: 'en', }, }, }); @@ -623,10 +739,23 @@ describe('[SSG] i18n routing', () => { expect($('body').text()).includes('Hola mundo'); }); + it('should redirect to the english locale correctly when it has codes+path', async () => { + let html = await fixture.readFile('/spanish/start/index.html'); + let $ = cheerio.load(html); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/new-site/start'); + html = await fixture.readFile('/spanish/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/new-site'); + }); + it('should redirect to the english locale, which is the first fallback', async () => { - const html = await fixture.readFile('/it/start/index.html'); + let html = await fixture.readFile('/it/start/index.html'); expect(html).to.include('http-equiv="refresh'); expect(html).to.include('url=/new-site/start'); + html = await fixture.readFile('/it/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/new-site'); }); it("should render a 404 because the route `fr` isn't included in the list of locales of the configuration", async () => { @@ -639,6 +768,103 @@ describe('[SSG] i18n routing', () => { return true; } }); + + it('should render the page with client scripts', async () => { + let html = await fixture.readFile('/index.html'); + let $ = cheerio.load(html); + expect($('script').text()).includes('console.log("this is a script")'); + }); + }); + + describe('i18n routing with fallback and [prefix-always]', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-prefix-always/', + i18n: { + defaultLocale: 'en', + locales: ['en', 'pt', 'it'], + fallback: { + it: 'en', + }, + routing: { + prefixDefaultLocale: true, + }, + }, + }); + await fixture.build(); + }); + + it('should render the en locale', async () => { + let html = await fixture.readFile('/it/start/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/new-site/en/start'); + html = await fixture.readFile('/it/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/new-site/en'); + }); + }); + + describe('i18n routing with fallback and redirect', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-fallback/', + redirects: { + '/': '/en', + }, + i18n: { + defaultLocale: 'en', + locales: ['en', 'pt', 'it'], + fallback: { + it: 'en', + }, + }, + }); + await fixture.build(); + }); + + it('should render the en locale', async () => { + let html = await fixture.readFile('/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('Redirecting to: /en'); + }); + }); + + describe('i18n routing with fallback and trailing slash', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-fallback/', + trailingSlash: 'always', + build: { + format: 'directory', + }, + i18n: { + defaultLocale: 'en', + locales: ['en', 'pt', 'it'], + fallback: { + it: 'en', + }, + routing: { + prefixDefaultLocale: false, + }, + }, + }); + await fixture.build(); + }); + + it('should render the en locale', async () => { + let html = await fixture.readFile('/it/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('Redirecting to: /new-site/'); + }); }); }); describe('[SSR] i18n routing', () => { @@ -678,6 +904,13 @@ describe('[SSR] i18n routing', () => { expect(await response.text()).includes('Oi essa e start'); }); + it('should render localised page correctly when locale has codes+path', async () => { + let request = new Request('http://example.com/spanish/start'); + let response = await app.render(request); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { let request = new Request('http://example.com/it/start'); let response = await app.render(request); @@ -766,6 +999,13 @@ describe('[SSR] i18n routing', () => { expect(await response.text()).includes('Oi essa e start'); }); + it('should render localised page correctly when locale has codes+path', async () => { + let request = new Request('http://example.com/new-site/spanish/start'); + let response = await app.render(request); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { let request = new Request('http://example.com/new-site/it/start'); let response = await app.render(request); @@ -814,6 +1054,13 @@ describe('[SSR] i18n routing', () => { expect(await response.text()).includes('Oi essa e start'); }); + it('should render localised page correctly when locale has codes+path', async () => { + let request = new Request('http://example.com/spanish/start'); + let response = await app.render(request); + expect(response.status).to.equal(200); + expect(await response.text()).includes('Espanol'); + }); + it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => { let request = new Request('http://example.com/it/start'); let response = await app.render(request); @@ -856,13 +1103,20 @@ describe('[SSR] i18n routing', () => { root: './fixtures/i18n-routing-fallback/', output: 'server', adapter: testAdapter(), - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['en', 'pt', 'it'], - fallback: { - it: 'en', + i18n: { + defaultLocale: 'en', + locales: [ + 'en', + 'pt', + 'it', + { + codes: ['es', 'es-AR'], + path: 'spanish', }, + ], + fallback: { + it: 'en', + spanish: 'en', }, }, }); @@ -891,11 +1145,47 @@ describe('[SSR] i18n routing', () => { expect(response.headers.get('location')).to.equal('/new-site/start'); }); + it('should redirect to the english locale when locale has codes+path', async () => { + let request = new Request('http://example.com/new-site/spanish/start'); + let response = await app.render(request); + expect(response.status).to.equal(302); + expect(response.headers.get('location')).to.equal('/new-site/start'); + }); + it("should render a 404 because the route `fr` isn't included in the list of locales of the configuration", async () => { let request = new Request('http://example.com/new-site/fr/start'); let response = await app.render(request); expect(response.status).to.equal(404); }); + + describe('with routing strategy [prefix-always]', () => { + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-fallback/', + output: 'server', + adapter: testAdapter(), + i18n: { + defaultLocale: 'en', + locales: ['en', 'pt', 'it'], + fallback: { + it: 'en', + }, + routing: { + prefixDefaultLocale: false, + }, + }, + }); + await fixture.build(); + app = await fixture.loadTestAdapterApp(); + }); + + it('should redirect to the english locale, which is the first fallback', async () => { + let request = new Request('http://example.com/new-site/it/start'); + let response = await app.render(request); + expect(response.status).to.equal(302); + expect(response.headers.get('location')).to.equal('/new-site/start'); + }); + }); }); describe('preferred locale', () => { @@ -966,11 +1256,9 @@ describe('[SSR] i18n routing', () => { root: './fixtures/i18n-routing/', output: 'server', adapter: testAdapter(), - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['en_AU', 'pt_BR', 'es_US'], - }, + i18n: { + defaultLocale: 'en', + locales: ['en_AU', 'pt_BR', 'es_US'], }, }); await fixture.build(); @@ -990,6 +1278,40 @@ describe('[SSR] i18n routing', () => { expect(text).includes('Locale list: pt_BR, en_AU'); }); }); + + describe('in case the configured locales are granular', () => { + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing/', + output: 'server', + adapter: testAdapter(), + i18n: { + defaultLocale: 'en', + locales: [ + { + path: 'english', + codes: ['en', 'en-AU', 'pt-BR', 'es-US'], + }, + ], + }, + }); + await fixture.build(); + app = await fixture.loadTestAdapterApp(); + }); + + it('they should be still considered when parsing the Accept-Language header', async () => { + let request = new Request('http://example.com/preferred-locale', { + headers: { + 'Accept-Language': 'en-AU;q=0.1,pt-BR;q=0.9', + }, + }); + let response = await app.render(request); + const text = await response.text(); + expect(response.status).to.equal(200); + expect(text).includes('Locale: english'); + expect(text).includes('Locale list: english'); + }); + }); }); describe('current locale', () => { @@ -1058,6 +1380,27 @@ describe('[SSR] i18n routing', () => { }); }); }); + + describe('i18n routing should work with hybrid rendering', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-prefix-always/', + output: 'hybrid', + adapter: testAdapter(), + }); + await fixture.build(); + app = await fixture.loadTestAdapterApp(); + }); + + it('and render the index page, which is static', async () => { + const html = await fixture.readFile('/client/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/new-site/en'); + }); + }); }); describe('i18n routing does not break assets and endpoints', () => { @@ -1068,11 +1411,9 @@ describe('i18n routing does not break assets and endpoints', () => { before(async () => { fixture = await loadFixture({ root: './fixtures/core-image-base/', - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['en', 'es'], - }, + i18n: { + defaultLocale: 'en', + locales: ['en', 'es'], }, base: '/blog', }); diff --git a/packages/astro/test/middleware.test.js b/packages/astro/test/middleware.test.js index 8332dfe41949c..64dc29cd9150b 100644 --- a/packages/astro/test/middleware.test.js +++ b/packages/astro/test/middleware.test.js @@ -251,8 +251,8 @@ describe('Middleware API in PROD mode, SSR', () => { it('should correctly call the middleware function for 404', async () => { const request = new Request('http://example.com/funky-url'); - const routeData = app.match(request, { matchNotFound: true }); - const response = await app.render(request, routeData); + const routeData = app.match(request); + const response = await app.render(request, { routeData }); const text = await response.text(); expect(text.includes('Error')).to.be.true; expect(text.includes('bar')).to.be.true; @@ -260,7 +260,7 @@ describe('Middleware API in PROD mode, SSR', () => { it('should render 500.astro when the middleware throws an error', async () => { const request = new Request('http://example.com/throw'); - const routeData = app.match(request, { matchNotFound: true }); + const routeData = app.match(request); const response = await app.render(request, routeData); expect(response).to.deep.include({ status: 500 }); @@ -269,6 +269,16 @@ describe('Middleware API in PROD mode, SSR', () => { expect(text).to.include('

There was an error rendering the page.

'); }); + it('should correctly render the page even when custom headers are set in a middleware', async () => { + const request = new Request('http://example.com/content-policy'); + const routeData = app.match(request); + + const response = await app.render(request, { routeData }); + expect(response).to.deep.include({ status: 404 }); + expect(response.headers.get('content-type')).equal('text/html'); + }); + + // keep this last it('the integration should receive the path to the middleware', async () => { fixture = await loadFixture({ root: './fixtures/middleware space/', @@ -277,6 +287,11 @@ describe('Middleware API in PROD mode, SSR', () => { excludeMiddleware: true, }, adapter: testAdapter({ + extendAdapter: { + adapterFeatures: { + edgeMiddleware: true, + }, + }, setMiddlewareEntryPoint(entryPointsOrMiddleware) { middlewarePath = entryPointsOrMiddleware; }, @@ -317,7 +332,9 @@ describe('Middleware with tailwind', () => { }); }); -describe('Middleware, split middleware option', () => { +// `loadTestAdapterApp()` does not understand how to load the page with `functionPerRoute` +// since there's no `entry.mjs`. Skip for now. +describe.skip('Middleware supports functionPerRoute feature', () => { /** @type {import('./test-utils').Fixture} */ let fixture; @@ -325,10 +342,13 @@ describe('Middleware, split middleware option', () => { fixture = await loadFixture({ root: './fixtures/middleware space/', output: 'server', - build: { - excludeMiddleware: true, - }, - adapter: testAdapter({}), + adapter: testAdapter({ + extendAdapter: { + adapterFeatures: { + functionPerRoute: true, + }, + }, + }), }); await fixture.build(); }); diff --git a/packages/astro/test/non-html-pages.test.js b/packages/astro/test/non-html-pages.test.js index 2cf5811041bcb..9f050ae96f35c 100644 --- a/packages/astro/test/non-html-pages.test.js +++ b/packages/astro/test/non-html-pages.test.js @@ -15,12 +15,6 @@ describe('Non-HTML Pages', () => { expect(json).to.have.property('name', 'Astro'); expect(json).to.have.property('url', 'https://astro.build/'); }); - - it('should match contents (deprecated object form)', async () => { - const json = JSON.parse(await fixture.readFile('/about-object.json')); - expect(json).to.have.property('name', 'Astro'); - expect(json).to.have.property('url', 'https://astro.build/'); - }); }); describe('png', () => { @@ -40,22 +34,5 @@ describe('Non-HTML Pages', () => { 'iVBORw0KGgoAAAANSUhEUgAAAGQAAACWCAMAAAAfZt10AAAABlBMVEXd3d3+/v7B/CFgAAAA3UlEQVR42u3ZMQ7DIBQFQeb+l06bNgUbG/5eYApLFjzWNE3TNE3TNE035av9AhAQEBBQGAQEFAaFQWFQGBQGhUGCKAwKgwQpDJ6JECgCRYIEikH8YAyCRyEGyRCDvBWRIPNNBpm/8G6kUM45EhXKlQfuFSHFpbFH+jt2j/S7xwqUYvBaCRIozZy6X2km7v1K8uwQIIWBwkBAQEBg3Tyj3z4LnzRBKgwKg8KgMEgQhaEwSBCFQWBEiMIgQQqDBCkMEqQw+APixYgcsa0TERs7D/F6xGmIAxCD/Iw4AvEB92Ec3ZAPdlMAAAAASUVORK5CYII=' ); }); - - it('should not have had its encoding mangled (deprecated object form)', async () => { - const buffer = await fixture.readFile('/placeholder-object.png', 'base64'); - - // Sanity check the first byte - const hex = Buffer.from(buffer, 'base64').toString('hex'); - const firstHexByte = hex.slice(0, 2); - // If we accidentally utf8 encode the png, the first byte (in hex) will be 'c2' - expect(firstHexByte).to.not.equal('c2'); - // and if correctly encoded in binary, it should be '89' - expect(firstHexByte).to.equal('89'); - - // Make sure the whole buffer (in base64) matches this snapshot - expect(buffer).to.equal( - 'iVBORw0KGgoAAAANSUhEUgAAAGQAAACWCAMAAAAfZt10AAAABlBMVEXd3d3+/v7B/CFgAAAA3UlEQVR42u3ZMQ7DIBQFQeb+l06bNgUbG/5eYApLFjzWNE3TNE3TNE035av9AhAQEBBQGAQEFAaFQWFQGBQGhUGCKAwKgwQpDJ6JECgCRYIEikH8YAyCRyEGyRCDvBWRIPNNBpm/8G6kUM45EhXKlQfuFSHFpbFH+jt2j/S7xwqUYvBaCRIozZy6X2km7v1K8uwQIIWBwkBAQEBg3Tyj3z4LnzRBKgwKg8KgMEgQhaEwSBCFQWBEiMIgQQqDBCkMEqQw+APixYgcsa0TERs7D/F6xGmIAxCD/Iw4AvEB92Ec3ZAPdlMAAAAASUVORK5CYII=' - ); - }); }); }); diff --git a/packages/astro/test/parallel.js b/packages/astro/test/parallel.test.js similarity index 100% rename from packages/astro/test/parallel.js rename to packages/astro/test/parallel.test.js diff --git a/packages/astro/test/preview-routing.test.js b/packages/astro/test/preview-routing.test.js index 8a4653a727872..9e986c47c243e 100644 --- a/packages/astro/test/preview-routing.test.js +++ b/packages/astro/test/preview-routing.test.js @@ -1,12 +1,7 @@ import { expect } from 'chai'; -import { version } from 'vite'; import { loadFixture } from './test-utils.js'; -const IS_VITE_5 = version.startsWith('5.'); - -// Skip in Vite 5 as it changes how HTML files are served. We may want to review aligning -// trailingSlash and build.format to avoid potential footguns in Astro 4 -(IS_VITE_5 ? describe.skip : describe)('Preview Routing', function () { +describe('Preview Routing', function () { describe('build format: directory', () => { describe('Subpath without trailing slash and trailingSlash: never', () => { /** @type {import('./test-utils').Fixture} */ diff --git a/packages/astro/test/redirects.test.js b/packages/astro/test/redirects.test.js index bf9ad15f56f3a..63a09312478fb 100644 --- a/packages/astro/test/redirects.test.js +++ b/packages/astro/test/redirects.test.js @@ -14,6 +14,7 @@ describe('Astro.redirect', () => { adapter: testAdapter(), redirects: { '/api/redirect': '/test', + '/external/redirect': 'https://example.com/', }, }); await fixture.build(); @@ -27,6 +28,15 @@ describe('Astro.redirect', () => { expect(response.headers.get('location')).to.equal('/login'); }); + // ref: https://github.com/withastro/astro/pull/9287 + it.skip('Ignores external redirect', async () => { + const app = await fixture.loadTestAdapterApp(); + const request = new Request('http://example.com/external/redirect'); + const response = await app.render(request); + expect(response.status).to.equal(404); + expect(response.headers.get('location')).to.equal(null); + }); + it('Warns when used inside a component', async () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/late'); diff --git a/packages/astro/test/ssr-404-500-pages.test.js b/packages/astro/test/ssr-404-500-pages.test.js index 253f9bc1ca99b..1c735e88995d9 100644 --- a/packages/astro/test/ssr-404-500-pages.test.js +++ b/packages/astro/test/ssr-404-500-pages.test.js @@ -56,7 +56,7 @@ describe('404 and 500 pages', () => { it('404 page returned when a route does not match and passing routeData', async () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/some/fake/route'); - const routeData = app.match(request, { matchNotFound: true }); + const routeData = app.match(request); const response = await app.render(request, routeData); expect(response.status).to.equal(404); const html = await response.text(); diff --git a/packages/astro/test/ssr-adapter-build-config.test.js b/packages/astro/test/ssr-adapter-build-config.test.js index d739cee3cd092..5d2221c312986 100644 --- a/packages/astro/test/ssr-adapter-build-config.test.js +++ b/packages/astro/test/ssr-adapter-build-config.test.js @@ -47,6 +47,7 @@ describe('Integration buildConfig hook', () => { name: 'my-ssr-adapter', serverEntrypoint: '@my-ssr', exports: ['manifest', 'createApp'], + supportedAstroFeatures: {}, }); }, }, diff --git a/packages/astro/test/ssr-api-route.test.js b/packages/astro/test/ssr-api-route.test.js index fbaafc82275c9..e15993b88681e 100644 --- a/packages/astro/test/ssr-api-route.test.js +++ b/packages/astro/test/ssr-api-route.test.js @@ -33,17 +33,6 @@ describe('API routes in SSR', () => { expect(body.length).to.equal(3); }); - it('Can load the API route too (deprecated object form)', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/food-object.json'); - const response = await app.render(request); - expect(response.status).to.equal(200); - expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8'); - expect(response.headers.get('Content-Length')).to.not.be.empty; - const body = await response.json(); - expect(body.length).to.equal(3); - }); - it('Has valid api context', async () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/context/any'); @@ -96,13 +85,6 @@ describe('API routes in SSR', () => { expect(res.status).to.equal(200); }); - it('Infer content type with charset for { body } shorthand (deprecated object form)', async () => { - const response = await fixture.fetch('/food-object.json', { - method: 'GET', - }); - expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8'); - }); - it('Can set multiple headers of the same type', async () => { const response = await new Promise((resolve) => { let { port } = devServer.address; diff --git a/packages/astro/test/ssr-dynamic.test.js b/packages/astro/test/ssr-dynamic.test.js index 62e67e410d323..f867ff999d711 100644 --- a/packages/astro/test/ssr-dynamic.test.js +++ b/packages/astro/test/ssr-dynamic.test.js @@ -18,7 +18,7 @@ describe('Dynamic pages in SSR', () => { 'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '/path-alias/[id]', - entryPoint: './src/pages/api/products/[id].js', + entrypoint: './src/pages/api/products/[id].js', }); }, }, diff --git a/packages/astro/test/ssr-locals.test.js b/packages/astro/test/ssr-locals.test.js index 41e5710fbbb84..68e6289908596 100644 --- a/packages/astro/test/ssr-locals.test.js +++ b/packages/astro/test/ssr-locals.test.js @@ -20,7 +20,7 @@ describe('SSR Astro.locals from server', () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/foo'); const locals = { foo: 'bar' }; - const response = await app.render(request, undefined, locals); + const response = await app.render(request, { locals }); const html = await response.text(); const $ = cheerio.load(html); diff --git a/packages/astro/test/ssr-split-manifest.test.js b/packages/astro/test/ssr-split-manifest.test.js index 89c8e00ef8980..74d2fe74e5747 100644 --- a/packages/astro/test/ssr-split-manifest.test.js +++ b/packages/astro/test/ssr-split-manifest.test.js @@ -109,7 +109,6 @@ describe('astro:ssr-manifest, split', () => { const request = new Request('http://example.com/'); const response = await app.render(request); const html = await response.text(); - console.log(html); expect(html.includes('Testing')).to.be.true; }); }); diff --git a/packages/astro/test/static-build.test.js b/packages/astro/test/static-build.test.js index 8bde08132e977..5ec225133458d 100644 --- a/packages/astro/test/static-build.test.js +++ b/packages/astro/test/static-build.test.js @@ -186,8 +186,7 @@ describe('Static build', () => { let found = false; for (const log of logs) { if ( - log.label === 'ssg' && - /[hH]eaders are not exposed in static \(SSG\) output mode/.test(log.message) + /\`Astro\.request\.headers\` is not available in "static" output mode/.test(log.message) ) { found = true; } diff --git a/packages/astro/test/test-adapter.js b/packages/astro/test/test-adapter.js index 0090b6d9da922..0a30583b22e77 100644 --- a/packages/astro/test/test-adapter.js +++ b/packages/astro/test/test-adapter.js @@ -77,15 +77,7 @@ export default function ( name: 'my-ssr-adapter', serverEntrypoint: '@my-ssr', exports: ['manifest', 'createApp'], - supportedFeatures: { - assets: { - supportKind: 'Stable', - isNodeCompatible: true, - }, - serverOutput: 'Stable', - staticOutput: 'Stable', - hybridOutput: 'Stable', - }, + supportedAstroFeatures: {}, ...extendAdapter, }); }, diff --git a/packages/astro/test/units/config/config-validate.test.js b/packages/astro/test/units/config/config-validate.test.js index 93dd0e28dd773..341ed47b422c2 100644 --- a/packages/astro/test/units/config/config-validate.test.js +++ b/packages/astro/test/units/config/config-validate.test.js @@ -82,11 +82,9 @@ describe('Config Validation', () => { it('defaultLocale is not in locales', async () => { const configError = await validateConfig( { - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['es'], - }, + i18n: { + defaultLocale: 'en', + locales: ['es'], }, }, process.cwd() @@ -97,16 +95,56 @@ describe('Config Validation', () => { ); }); - it('errors if a fallback value does not exist', async () => { + it('errors if codes are empty', async () => { const configError = await validateConfig( { - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['es', 'en'], - fallback: { - es: 'it', + i18n: { + defaultLocale: 'uk', + locales: [ + 'es', + { + path: 'something', + codes: [], }, + ], + }, + }, + process.cwd() + ).catch((err) => err); + expect(configError instanceof z.ZodError).to.equal(true); + expect(configError.errors[0].message).to.equal('Array must contain at least 1 element(s)'); + }); + + it('errors if the default locale is not in path', async () => { + const configError = await validateConfig( + { + i18n: { + defaultLocale: 'uk', + locales: [ + 'es', + { + path: 'something', + codes: ['en-UK'], + }, + ], + }, + }, + process.cwd() + ).catch((err) => err); + expect(configError instanceof z.ZodError).to.equal(true); + expect(configError.errors[0].message).to.equal( + 'The default locale `uk` is not present in the `i18n.locales` array.' + ); + }); + + it('errors if a fallback value does not exist', async () => { + const configError = await validateConfig( + { + i18n: { + defaultLocale: 'en', + locales: ['es', 'en'], + fallback: { + es: 'it', }, }, }, @@ -121,13 +159,11 @@ describe('Config Validation', () => { it('errors if a fallback key does not exist', async () => { const configError = await validateConfig( { - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['es', 'en'], - fallback: { - it: 'en', - }, + i18n: { + defaultLocale: 'en', + locales: ['es', 'en'], + fallback: { + it: 'en', }, }, }, @@ -142,13 +178,11 @@ describe('Config Validation', () => { it('errors if a fallback key contains the default locale', async () => { const configError = await validateConfig( { - experimental: { - i18n: { - defaultLocale: 'en', - locales: ['es', 'en'], - fallback: { - en: 'es', - }, + i18n: { + defaultLocale: 'en', + locales: ['es', 'en'], + fallback: { + en: 'es', }, }, }, diff --git a/packages/astro/test/units/dev/dev.test.js b/packages/astro/test/units/dev/dev.test.js index 810d8d1c30848..9b713d62a77db 100644 --- a/packages/astro/test/units/dev/dev.test.js +++ b/packages/astro/test/units/dev/dev.test.js @@ -133,7 +133,7 @@ describe('dev container', () => { 'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '/another-[slug]', - entryPoint: './src/components/test.astro', + entrypoint: './src/components/test.astro', }); }, }, @@ -184,7 +184,7 @@ describe('dev container', () => { 'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '/404', - entryPoint: './src/components/404.astro', + entrypoint: './src/components/404.astro', }); }, }, @@ -199,7 +199,6 @@ describe('dev container', () => { container.handle(r.req, r.res); await r.done; const doc = await r.text(); - console.log(doc); expect(doc).to.match(/Regular page/); expect(r.res.statusCode).to.equal(200); } @@ -254,8 +253,7 @@ describe('dev container', () => { container.handle(r.req, r.res); await r.done; - expect(r.res.statusCode).to.equal(301); - expect(r.res.getHeader('location')).to.equal('/sub/test.txt'); + expect(r.res.statusCode).to.equal(404); } ); }); diff --git a/packages/astro/test/units/i18n/astro_i18n.js b/packages/astro/test/units/i18n/astro_i18n.test.js similarity index 90% rename from packages/astro/test/units/i18n/astro_i18n.js rename to packages/astro/test/units/i18n/astro_i18n.test.js index f90ad14e69ef7..ad5a2fa23e0e7 100644 --- a/packages/astro/test/units/i18n/astro_i18n.js +++ b/packages/astro/test/units/i18n/astro_i18n.test.js @@ -18,7 +18,15 @@ describe('getLocaleRelativeUrl', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'en_US', 'es'], + locales: [ + 'en', + 'en_US', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -82,6 +90,16 @@ describe('getLocaleRelativeUrl', () => { format: 'file', }) ).to.throw; + + expect( + getLocaleRelativeUrl({ + locale: 'it-VA', + base: '/blog/', + ...config.experimental.i18n, + trailingSlash: 'always', + format: 'file', + }) + ).to.eq('/blog/italiano/'); }); it('should correctly return the URL without base', () => { @@ -127,7 +145,14 @@ describe('getLocaleRelativeUrl', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'es'], + locales: [ + 'en', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -151,6 +176,16 @@ describe('getLocaleRelativeUrl', () => { }) ).to.eq('/blog/es/'); + expect( + getLocaleRelativeUrl({ + locale: 'it-VA', + base: '/blog/', + ...config.experimental.i18n, + trailingSlash: 'always', + format: 'file', + }) + ).to.eq('/blog/italiano/'); + expect( getLocaleRelativeUrl({ locale: 'en', @@ -251,7 +286,7 @@ describe('getLocaleRelativeUrl', () => { i18n: { defaultLocale: 'en', locales: ['en', 'es', 'en_US', 'en_AU'], - routingStrategy: 'prefix-always', + routing: 'prefix-always', }, }, }; @@ -328,7 +363,15 @@ describe('getLocaleRelativeUrlList', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'en_US', 'es'], + locales: [ + 'en', + 'en_US', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -341,7 +384,7 @@ describe('getLocaleRelativeUrlList', () => { trailingSlash: 'never', format: 'directory', }) - ).to.have.members(['/blog', '/blog/en_US', '/blog/es']); + ).to.have.members(['/blog', '/blog/en_US', '/blog/es', '/blog/italiano']); }); it('should retrieve the correct list of base URL with locales [format: directory, trailingSlash: always]', () => { @@ -353,7 +396,15 @@ describe('getLocaleRelativeUrlList', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'en_US', 'es'], + locales: [ + 'en', + 'en_US', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -366,7 +417,7 @@ describe('getLocaleRelativeUrlList', () => { trailingSlash: 'always', format: 'directory', }) - ).to.have.members(['/blog/', '/blog/en_US/', '/blog/es/']); + ).to.have.members(['/blog/', '/blog/en_US/', '/blog/es/', '/blog/italiano/']); }); it('should retrieve the correct list of base URL with locales [format: file, trailingSlash: always]', () => { @@ -479,7 +530,7 @@ describe('getLocaleRelativeUrlList', () => { i18n: { defaultLocale: 'en', locales: ['en', 'en_US', 'es'], - routingStrategy: 'prefix-always', + routing: 'prefix-always', }, }, }; @@ -507,7 +558,15 @@ describe('getLocaleAbsoluteUrl', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'en_US', 'es'], + locales: [ + 'en', + 'en_US', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -577,6 +636,16 @@ describe('getLocaleAbsoluteUrl', () => { site: 'https://example.com', }) ).to.throw; + expect( + getLocaleAbsoluteUrl({ + locale: 'it-VA', + base: '/blog/', + ...config.experimental.i18n, + trailingSlash: 'always', + format: 'file', + site: 'https://example.com', + }) + ).to.eq('https://example.com/blog/italiano/'); }); it('should correctly return the URL without base', () => { @@ -588,7 +657,14 @@ describe('getLocaleAbsoluteUrl', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'es'], + locales: [ + 'en', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -613,6 +689,16 @@ describe('getLocaleAbsoluteUrl', () => { site: 'https://example.com', }) ).to.eq('https://example.com/es/'); + expect( + getLocaleAbsoluteUrl({ + locale: 'it-VA', + base: '/', + ...config.experimental.i18n, + trailingSlash: 'always', + format: 'directory', + site: 'https://example.com', + }) + ).to.eq('https://example.com/italiano/'); }); it('should correctly handle the trailing slash', () => { @@ -636,6 +722,7 @@ describe('getLocaleAbsoluteUrl', () => { ...config.experimental.i18n, trailingSlash: 'never', format: 'directory', + site: 'https://example.com', }) ).to.eq('https://example.com/blog'); expect( @@ -645,6 +732,7 @@ describe('getLocaleAbsoluteUrl', () => { ...config.experimental.i18n, trailingSlash: 'always', format: 'directory', + site: 'https://example.com', }) ).to.eq('https://example.com/blog/es/'); @@ -655,6 +743,7 @@ describe('getLocaleAbsoluteUrl', () => { ...config.experimental.i18n, trailingSlash: 'ignore', format: 'directory', + site: 'https://example.com', }) ).to.eq('https://example.com/blog/'); @@ -666,6 +755,7 @@ describe('getLocaleAbsoluteUrl', () => { ...config.experimental.i18n, trailingSlash: 'never', format: 'file', + site: 'https://example.com', }) ).to.eq('https://example.com/blog'); expect( @@ -675,6 +765,7 @@ describe('getLocaleAbsoluteUrl', () => { ...config.experimental.i18n, trailingSlash: 'always', format: 'file', + site: 'https://example.com', }) ).to.eq('https://example.com/blog/es/'); @@ -686,6 +777,7 @@ describe('getLocaleAbsoluteUrl', () => { ...config.experimental.i18n, trailingSlash: 'ignore', format: 'file', + site: 'https://example.com', }) ).to.eq('https://example.com/blog'); }); @@ -748,7 +840,7 @@ describe('getLocaleAbsoluteUrl', () => { i18n: { defaultLocale: 'en', locales: ['en', 'es', 'en_US', 'en_AU'], - routingStrategy: 'prefix-always', + routing: 'prefix-always', }, }, }; @@ -831,7 +923,15 @@ describe('getLocaleAbsoluteUrlList', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'en_US', 'es'], + locales: [ + 'en', + 'en_US', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -849,6 +949,7 @@ describe('getLocaleAbsoluteUrlList', () => { 'https://example.com/blog', 'https://example.com/blog/en_US', 'https://example.com/blog/es', + 'https://example.com/blog/italiano', ]); }); @@ -891,7 +992,15 @@ describe('getLocaleAbsoluteUrlList', () => { experimental: { i18n: { defaultLocale: 'en', - locales: ['en', 'en_US', 'es'], + locales: [ + 'en', + 'en_US', + 'es', + { + path: 'italiano', + codes: ['it', 'it-VA'], + }, + ], }, }, }; @@ -909,6 +1018,7 @@ describe('getLocaleAbsoluteUrlList', () => { 'https://example.com/blog/', 'https://example.com/blog/en_US/', 'https://example.com/blog/es/', + 'https://example.com/blog/italiano/', ]); }); @@ -1012,7 +1122,7 @@ describe('getLocaleAbsoluteUrlList', () => { i18n: { defaultLocale: 'en', locales: ['en', 'en_US', 'es'], - routingStrategy: 'prefix-always', + routing: 'prefix-always', }, }, }; diff --git a/packages/astro/test/units/integrations/api.test.js b/packages/astro/test/units/integrations/api.test.js index a4a76975a3415..ff700833ef840 100644 --- a/packages/astro/test/units/integrations/api.test.js +++ b/packages/astro/test/units/integrations/api.test.js @@ -30,6 +30,33 @@ describe('Integration API', () => { expect(updatedViteConfig).to.haveOwnProperty('define'); }); + it('runHookBuildSetup should return updated config', async () => { + let updatedInternalConfig; + const updatedViteConfig = await runHookBuildSetup({ + config: { + integrations: [ + { + name: 'test', + hooks: { + 'astro:build:setup'({ updateConfig }) { + updatedInternalConfig = updateConfig({ + define: { + foo: 'bar', + }, + }); + }, + }, + }, + ], + }, + vite: {}, + logger: defaultLogger, + pages: new Map(), + target: 'server', + }); + expect(updatedViteConfig).to.be.deep.equal(updatedInternalConfig); + }); + it('runHookConfigSetup can update Astro config', async () => { const site = 'https://test.com/'; const updatedSettings = await runHookConfigSetup({ @@ -106,7 +133,7 @@ describe('Astro feature map', function () { it('should not support the feature when not provided', () => { let result = validateSupportedFeatures( 'test', - undefined, + {}, { output: 'hybrid', }, diff --git a/packages/astro/test/units/vite-plugin-astro-server/request.test.js b/packages/astro/test/units/vite-plugin-astro-server/request.test.js index d3472c56b59b8..d1d0cf464e841 100644 --- a/packages/astro/test/units/vite-plugin-astro-server/request.test.js +++ b/packages/astro/test/units/vite-plugin-astro-server/request.test.js @@ -21,7 +21,7 @@ async function createDevPipeline(overrides = {}) { return new DevPipeline({ manifest, settings, - logging: defaultLogger, + logger: defaultLogger, loader, }); } diff --git a/packages/create-astro/CHANGELOG.md b/packages/create-astro/CHANGELOG.md index d50bb1c7f8b1b..f1c16fdc21e97 100644 --- a/packages/create-astro/CHANGELOG.md +++ b/packages/create-astro/CHANGELOG.md @@ -1,5 +1,17 @@ # create-astro +## 4.5.2 + +### Patch Changes + +- [#9105](https://github.com/withastro/astro/pull/9105) [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Stop clearing the console on start + +## 4.5.2-beta.0 + +### Patch Changes + +- [#9105](https://github.com/withastro/astro/pull/9105) [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Stop clearing the console on start + ## 4.5.1 ### Patch Changes diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 7aa1b62f6e2eb..8f1ed83da9916 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -1,6 +1,6 @@ { "name": "create-astro", - "version": "4.5.1", + "version": "4.5.2", "type": "module", "author": "withastro", "license": "MIT", @@ -32,7 +32,7 @@ "//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES", "dependencies": { "@astrojs/cli-kit": "^0.3.1", - "giget": "1.1.2" + "giget": "1.1.3" }, "devDependencies": { "arg": "^5.0.2", diff --git a/packages/create-astro/src/actions/dependencies.ts b/packages/create-astro/src/actions/dependencies.ts index e920fcf8e4821..26557d5a2f1d4 100644 --- a/packages/create-astro/src/actions/dependencies.ts +++ b/packages/create-astro/src/actions/dependencies.ts @@ -51,6 +51,14 @@ async function install({ packageManager, cwd }: { packageManager: string; cwd: s return shell(packageManager, ['install'], { cwd, timeout: 90_000, stdio: 'ignore' }); } +/** + * Yarn Berry (PnP) versions will throw an error if there isn't an existing `yarn.lock` file + * If a `yarn.lock` file doesn't exist, this function writes an empty `yarn.lock` one. + * Unfortunately this hack is required to run `yarn install`. + * + * The empty `yarn.lock` file is immediately overwritten by the installation process. + * See https://github.com/withastro/astro/pull/8028 + */ async function ensureYarnLock({ cwd }: { cwd: string }) { const yarnLock = path.join(cwd, 'yarn.lock'); if (fs.existsSync(yarnLock)) return; diff --git a/packages/create-astro/src/index.ts b/packages/create-astro/src/index.ts index 3ac5d231bfcc5..f641e876e414f 100644 --- a/packages/create-astro/src/index.ts +++ b/packages/create-astro/src/index.ts @@ -19,9 +19,9 @@ process.on('SIGTERM', exit); // https://github.com/withastro/docs/blob/main/src/pages/en/install/auto.md // if you make any changes to the flow or wording here. export async function main() { - // Clear console because PNPM startup is super ugly + // Add some extra spacing from the noisy npm/pnpm init output // eslint-disable-next-line no-console - console.clear(); + console.log(''); // NOTE: In the v7.x version of npm, the default behavior of `npm init` was changed // to no longer require `--` to pass args and instead pass `--` directly to us. This // broke our arg parser, since `--` is a special kind of flag. Filtering for `--` here diff --git a/packages/create-astro/test/typescript.test.js b/packages/create-astro/test/typescript.test.js index 498d3384b8a8f..461a3ed637457 100644 --- a/packages/create-astro/test/typescript.test.js +++ b/packages/create-astro/test/typescript.test.js @@ -5,7 +5,6 @@ import { fileURLToPath } from 'node:url'; import { typescript, setupTypeScript } from '../dist/index.js'; import { setup, resetFixtures } from './utils.js'; -import { describe } from 'node:test'; describe('typescript', () => { const fixture = setup(); diff --git a/packages/integrations/lit/CHANGELOG.md b/packages/integrations/lit/CHANGELOG.md index 44880912aa754..ac850f3701161 100644 --- a/packages/integrations/lit/CHANGELOG.md +++ b/packages/integrations/lit/CHANGELOG.md @@ -1,5 +1,11 @@ # @astrojs/lit +## 4.0.0 + +### Major Changes + +- [#8822](https://github.com/withastro/astro/pull/8822) [`b0a71946f`](https://github.com/withastro/astro/commit/b0a71946f4320d4e76f31e990fe5821f823f0e12) Thanks [@Geoffrey-Pliez](https://github.com/Geoffrey-Pliez)! - Upgrade to Lit 3.0 + ## 3.0.3 ### Patch Changes diff --git a/packages/integrations/lit/package.json b/packages/integrations/lit/package.json index 252a412d17efd..9588462ba4269 100644 --- a/packages/integrations/lit/package.json +++ b/packages/integrations/lit/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/lit", - "version": "3.0.3", + "version": "4.0.0", "description": "Use Lit components within Astro", "type": "module", "types": "./dist/index.d.ts", @@ -42,9 +42,9 @@ "test": "mocha" }, "dependencies": { - "@lit-labs/ssr": "3.1.7", - "@lit-labs/ssr-client": "1.1.3", - "@lit-labs/ssr-dom-shim": "^1.1.1", + "@lit-labs/ssr": "^3.2.0", + "@lit-labs/ssr-client": "^1.1.5", + "@lit-labs/ssr-dom-shim": "^1.1.2", "parse5": "^7.1.2" }, "overrides": { @@ -57,13 +57,13 @@ "astro-scripts": "workspace:*", "chai": "^4.3.7", "cheerio": "1.0.0-rc.12", - "lit": "^2.8.0", + "lit": "^3.1.0", "mocha": "^10.2.0", - "sass": "^1.66.1" + "sass": "^1.69.5" }, "peerDependencies": { "@webcomponents/template-shadowroot": "^0.2.1", - "lit": "^2.7.0" + "lit": "^3.1.0" }, "publishConfig": { "provenance": true diff --git a/packages/integrations/lit/src/index.ts b/packages/integrations/lit/src/index.ts index de6d5b0f91c38..f8fbeccba1d22 100644 --- a/packages/integrations/lit/src/index.ts +++ b/packages/integrations/lit/src/index.ts @@ -9,7 +9,7 @@ function getViteConfiguration() { '@astrojs/lit/client-shim.js', '@astrojs/lit/hydration-support.js', '@webcomponents/template-shadowroot/template-shadowroot.js', - 'lit/experimental-hydrate-support.js', + '@lit-labs/ssr-client/lit-element-hydrate-support.js', ], exclude: ['@astrojs/lit/server.js'], }, diff --git a/packages/integrations/markdoc/CHANGELOG.md b/packages/integrations/markdoc/CHANGELOG.md index 574607c2859a6..67a9d249e5c8d 100644 --- a/packages/integrations/markdoc/CHANGELOG.md +++ b/packages/integrations/markdoc/CHANGELOG.md @@ -1,5 +1,24 @@ # @astrojs/markdoc +## 0.8.0 + +### Minor Changes + +- [#9263](https://github.com/withastro/astro/pull/9263) [`3cbd8ea75`](https://github.com/withastro/astro/commit/3cbd8ea7534910e3beae396dcfa93ce87dcdd91f) Thanks [@bluwy](https://github.com/bluwy)! - Removes internal `propagators` handling for Astro 3 + +## 1.0.0-beta.1 + +### Minor Changes + +- [#9263](https://github.com/withastro/astro/pull/9263) [`3cbd8ea75`](https://github.com/withastro/astro/commit/3cbd8ea7534910e3beae396dcfa93ce87dcdd91f) Thanks [@bluwy](https://github.com/bluwy)! - Removes internal `propagators` handling for Astro 3 + +## 1.0.0-beta.0 + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + ## 0.7.2 ### Patch Changes diff --git a/packages/integrations/markdoc/components/TreeNode.ts b/packages/integrations/markdoc/components/TreeNode.ts index 01bd20d71ba10..abec17d7be7a3 100644 --- a/packages/integrations/markdoc/components/TreeNode.ts +++ b/packages/integrations/markdoc/components/TreeNode.ts @@ -1,17 +1,17 @@ -import type { AstroInstance } from 'astro'; import type { RenderableTreeNode } from '@markdoc/markdoc'; import Markdoc from '@markdoc/markdoc'; +import type { AstroInstance } from 'astro'; +import type { HTMLString } from 'astro/runtime/server/index.js'; import { createComponent, - renderComponent, + createHeadAndContent, + isHTMLString, render, + renderComponent, renderScriptElement, + renderTemplate, renderUniqueStylesheet, - createHeadAndContent, unescapeHTML, - renderTemplate, - HTMLString, - isHTMLString, } from 'astro/runtime/server/index.js'; export type TreeNode = @@ -89,10 +89,7 @@ export const ComponentNode = createComponent({ ); // Let the runtime know that this component is being used. - // `result.propagators` has been moved to `result._metadata.propagators` - // TODO: remove this fallback in the next markdoc integration major - const propagators = result._metadata.propagators || result.propagators; - propagators.add({ + result._metadata.propagators.add({ init() { return headAndContent; }, diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json index 18e6aca5ef6d2..f75a56466ccad 100644 --- a/packages/integrations/markdoc/package.json +++ b/packages/integrations/markdoc/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/markdoc", "description": "Add support for Markdoc in your Astro site", - "version": "0.7.2", + "version": "0.8.0", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -65,32 +65,31 @@ "dependencies": { "@astrojs/internal-helpers": "workspace:*", "@astrojs/prism": "workspace:*", - "@markdoc/markdoc": "^0.3.0", - "esbuild": "^0.19.2", + "@markdoc/markdoc": "^0.3.5", + "esbuild": "^0.19.6", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "htmlparser2": "^9.0.0", "kleur": "^4.1.5", - "shikiji": "^0.6.8", + "shikiji": "^0.6.13", "zod": "^3.22.4" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^3.0.0 || ^4.0.0" }, "devDependencies": { "@astrojs/markdown-remark": "workspace:*", - "@types/chai": "^4.3.5", - "@types/html-escaper": "^3.0.0", - "@types/markdown-it": "^13.0.0", - "@types/mocha": "^10.0.1", + "@types/chai": "^4.3.10", + "@types/html-escaper": "^3.0.2", + "@types/markdown-it": "^13.0.6", + "@types/mocha": "^10.0.4", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", "devalue": "^4.3.2", - "linkedom": "^0.15.1", + "linkedom": "^0.16.4", "mocha": "^10.2.0", - "rollup": "^3.28.1", - "vite": "^4.4.9" + "vite": "^5.0.0" }, "engines": { "node": ">=18.14.1" diff --git a/packages/integrations/markdoc/src/content-entry-type.ts b/packages/integrations/markdoc/src/content-entry-type.ts index 07c5268e4cc28..384dec9445e51 100644 --- a/packages/integrations/markdoc/src/content-entry-type.ts +++ b/packages/integrations/markdoc/src/content-entry-type.ts @@ -6,8 +6,7 @@ import matter from 'gray-matter'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import type * as rollup from 'rollup'; -import type { ErrorPayload as ViteErrorPayload } from 'vite'; +import type { Rollup, ErrorPayload as ViteErrorPayload } from 'vite'; import type { ComponentConfig } from './config.js'; import { htmlTokenTransform } from './html/transform/html-token-transform.js'; import type { MarkdocConfigResult } from './load-config.js'; @@ -174,7 +173,7 @@ function getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) async function emitOptimizedImages( nodeChildren: Node[], ctx: { - pluginContext: rollup.PluginContext; + pluginContext: Rollup.PluginContext; filePath: string; astroConfig: AstroConfig; } diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js index 98ae36a58247b..cb3c84652622f 100644 --- a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js +++ b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js @@ -2,9 +2,7 @@ import { getCollection } from 'astro:content'; import { stringify } from 'devalue'; import { stripAllRenderFn } from '../../utils.js'; -export async function get() { +export async function GET() { const posts = await getCollection('blog'); - return { - body: stringify(stripAllRenderFn(posts)) - }; + return new Response(stringify(stripAllRenderFn(posts))); } diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js index 7899a757a9291..53dd17013ba79 100644 --- a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js +++ b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js @@ -2,9 +2,7 @@ import { getEntryBySlug } from 'astro:content'; import { stringify } from 'devalue'; import { stripRenderFn } from '../../utils.js'; -export async function get() { +export async function GET() { const post = await getEntryBySlug('blog', 'post-1'); - return { - body: stringify(stripRenderFn(post)), - }; + return new Response(stringify(stripRenderFn(post))); } diff --git a/packages/integrations/mdx/CHANGELOG.md b/packages/integrations/mdx/CHANGELOG.md index 80febcb54e0ea..6161b6238d59f 100644 --- a/packages/integrations/mdx/CHANGELOG.md +++ b/packages/integrations/mdx/CHANGELOG.md @@ -1,5 +1,41 @@ # @astrojs/mdx +## 2.0.1 + +### Patch Changes + +- [#9366](https://github.com/withastro/astro/pull/9366) [`1b4e91898`](https://github.com/withastro/astro/commit/1b4e91898116f75b02b66ec402385cf44e559118) Thanks [@lilnasy](https://github.com/lilnasy)! - Updates NPM package to refer to the stable Astro version instead of a beta. + +- Updated dependencies [[`270c6cc27`](https://github.com/withastro/astro/commit/270c6cc27f20995883fcdabbff9b56d7f041f9e4)]: + - @astrojs/markdown-remark@4.0.1 + +## 2.0.0 + +### Major Changes + +- [#9138](https://github.com/withastro/astro/pull/9138) [`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3) Thanks [@bluwy](https://github.com/bluwy)! - Updates the unified, remark, and rehype dependencies to latest. Make sure to update your custom remark and rehype plugins as well to be compatible with the latest versions. + + **Potentially breaking change:** The default value of `markdown.remarkRehype.footnoteBackLabel` is changed from `"Back to content"` to `"Back to reference 1"`. See the `mdast-util-to-hast` [commit](https://github.com/syntax-tree/mdast-util-to-hast/commit/56c88e45690be138fad9f0bf367b939d09816863) for more information. + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`addb57c8e`](https://github.com/withastro/astro/commit/addb57c8e80b7b67ec61224666f3a1db5c44410c), [`c7953645e`](https://github.com/withastro/astro/commit/c7953645eeaaf9e87c6db4494b0023d2c1878ff0)]: + - @astrojs/markdown-remark@4.0.0 + +## 2.0.0-beta.0 + +### Major Changes + +- [#9138](https://github.com/withastro/astro/pull/9138) [`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3) Thanks [@bluwy](https://github.com/bluwy)! - Updates the unified, remark, and rehype dependencies to latest. Make sure to update your custom remark and rehype plugins as well to be compatible with the latest versions. + + **Potentially breaking change:** The default value of `markdown.remarkRehype.footnoteBackLabel` is changed from `"Back to content"` to `"Back to reference 1"`. See the `mdast-util-to-hast` [commit](https://github.com/syntax-tree/mdast-util-to-hast/commit/56c88e45690be138fad9f0bf367b939d09816863) for more information. + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`addb57c8e`](https://github.com/withastro/astro/commit/addb57c8e80b7b67ec61224666f3a1db5c44410c), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`c7953645e`](https://github.com/withastro/astro/commit/c7953645eeaaf9e87c6db4494b0023d2c1878ff0), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - @astrojs/markdown-remark@4.0.0-beta.0 + - astro@4.0.0-beta.0 + ## 1.1.5 ### Patch Changes diff --git a/packages/integrations/mdx/README.md b/packages/integrations/mdx/README.md index df0458ce9e27b..150ada5e8da37 100644 --- a/packages/integrations/mdx/README.md +++ b/packages/integrations/mdx/README.md @@ -83,11 +83,7 @@ You can configure how your MDX is rendered with the following options: ### Options inherited from Markdown config -All [`markdown` configuration options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) except `drafts` can be configured separately in the MDX integration. This includes remark and rehype plugins, syntax highlighting, and more. Options will default to those in your Markdown config ([see the `extendMarkdownConfig` option](#extendmarkdownconfig) to modify this). - -:::note -There is no separate MDX configuration for [including pages marked as draft in the build](https://docs.astro.build/en/reference/configuration-reference/#markdowndrafts). This Markdown setting will be respected by both Markdown and MDX files and cannot be overridden for MDX files specifically. -::: +All [`markdown` configuration options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) can be configured separately in the MDX integration. This includes remark and rehype plugins, syntax highlighting, and more. Options will default to those in your Markdown config ([see the `extendMarkdownConfig` option](#extendmarkdownconfig) to modify this). ```js // astro.config.mjs diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json index f9e22d58c8a22..00ddefe47a3b1 100644 --- a/packages/integrations/mdx/package.json +++ b/packages/integrations/mdx/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/mdx", "description": "Add support for MDX pages in your Astro site", - "version": "1.1.5", + "version": "2.0.1", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -35,47 +35,47 @@ }, "dependencies": { "@astrojs/markdown-remark": "workspace:*", - "@mdx-js/mdx": "^2.3.0", - "acorn": "^8.10.0", - "es-module-lexer": "^1.3.0", - "estree-util-visit": "^1.2.1", + "@mdx-js/mdx": "^3.0.0", + "acorn": "^8.11.2", + "es-module-lexer": "^1.4.1", + "estree-util-visit": "^2.0.0", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", - "hast-util-to-html": "^8.0.4", + "hast-util-to-html": "^9.0.0", "kleur": "^4.1.4", - "rehype-raw": "^6.1.1", - "remark-gfm": "^3.0.1", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.0", "remark-smartypants": "^2.0.0", "source-map": "^0.7.4", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^4.0.0" }, "devDependencies": { - "@types/chai": "^4.3.5", - "@types/estree": "^1.0.1", - "@types/mdast": "^3.0.12", - "@types/mocha": "^10.0.1", - "@types/yargs-parser": "^21.0.0", + "@types/chai": "^4.3.10", + "@types/estree": "^1.0.5", + "@types/mdast": "^4.0.3", + "@types/mocha": "^10.0.4", + "@types/yargs-parser": "^21.0.3", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", "cheerio": "1.0.0-rc.12", - "linkedom": "^0.15.1", - "mdast-util-mdx": "^2.0.1", - "mdast-util-to-string": "^3.2.0", + "linkedom": "^0.16.4", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", "mocha": "^10.2.0", "reading-time": "^1.5.0", - "rehype-mathjax": "^4.0.3", - "rehype-pretty-code": "^0.10.0", - "remark-math": "^5.1.1", - "remark-rehype": "^10.1.0", + "rehype-mathjax": "^5.0.0", + "rehype-pretty-code": "^0.10.2", + "remark-math": "^6.0.0", + "remark-rehype": "^11.0.0", "remark-shiki-twoslash": "^3.1.3", - "remark-toc": "^8.0.1", - "unified": "^10.1.2", - "vite": "^4.4.9" + "remark-toc": "^9.0.0", + "unified": "^11.0.4", + "vite": "^5.0.0" }, "engines": { "node": ">=18.14.1" diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index fd330625e1374..3092ad51f02b1 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -1,11 +1,11 @@ import { markdownConfigDefaults, setVfileFrontmatter } from '@astrojs/markdown-remark'; -import type { PluggableList } from '@mdx-js/mdx/lib/core.js'; import type { AstroIntegration, ContentEntryType, HookParameters, SSRError } from 'astro'; import astroJSXRenderer from 'astro/jsx/renderer.js'; import { parse as parseESM } from 'es-module-lexer'; import fs from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import type { Options as RemarkRehypeOptions } from 'remark-rehype'; +import type { PluggableList } from 'unified'; import { VFile } from 'vfile'; import type { Plugin as VitePlugin } from 'vite'; import { createMdxProcessor } from './plugins.js'; @@ -190,7 +190,10 @@ export default function mdx(partialMdxOptions: Partial = {}): AstroI componentsCode += ' }'; // Make `Content` the default export so we can wrap `MDXContent` and pass in `Fragment` - code = code.replace('export default MDXContent;', ''); + code = code.replace( + 'export default function MDXContent', + 'function MDXContent' + ); code += `\nexport const Content = (props = {}) => MDXContent({ ...props, components: ${componentsCode}, diff --git a/packages/integrations/mdx/src/plugins.ts b/packages/integrations/mdx/src/plugins.ts index 3286a9fd877b4..e6584aacf13d4 100644 --- a/packages/integrations/mdx/src/plugins.ts +++ b/packages/integrations/mdx/src/plugins.ts @@ -5,12 +5,11 @@ import { remarkShiki, } from '@astrojs/markdown-remark'; import { createProcessor, nodeTypes } from '@mdx-js/mdx'; -import type { PluggableList } from '@mdx-js/mdx/lib/core.js'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; import remarkSmartypants from 'remark-smartypants'; import { SourceMapGenerator } from 'source-map'; -import type { Processor } from 'unified'; +import type { PluggableList } from 'unified'; import type { MdxOptions } from './index.js'; import { recmaInjectImportMetaEnv } from './recma-inject-import-meta-env.js'; import { rehypeApplyFrontmatterExport } from './rehype-apply-frontmatter-export.js'; @@ -27,10 +26,7 @@ interface MdxProcessorExtraOptions { importMetaEnv: Record; } -export function createMdxProcessor( - mdxOptions: MdxOptions, - extraOptions: MdxProcessorExtraOptions -): Processor { +export function createMdxProcessor(mdxOptions: MdxOptions, extraOptions: MdxProcessorExtraOptions) { return createProcessor({ remarkPlugins: getRemarkPlugins(mdxOptions), rehypePlugins: getRehypePlugins(mdxOptions), diff --git a/packages/integrations/mdx/src/remark-images-to-component.ts b/packages/integrations/mdx/src/remark-images-to-component.ts index f83f5d76abf9b..810056deff0ac 100644 --- a/packages/integrations/mdx/src/remark-images-to-component.ts +++ b/packages/integrations/mdx/src/remark-images-to-component.ts @@ -15,7 +15,7 @@ export function remarkImageToComponent() { const importsStatements: MdxjsEsm[] = []; const importedImages = new Map(); - visit(tree, 'image', (node: Image, index: number | null, parent: Parent | null) => { + visit(tree, 'image', (node: Image, index: number | undefined, parent: Parent | null) => { // Use the imagePaths set from the remark-collect-images so we don't have to duplicate the logic for // checking if an image should be imported or not if (file.data.imagePaths?.has(node.url)) { diff --git a/packages/integrations/mdx/src/utils.ts b/packages/integrations/mdx/src/utils.ts index 3425c50e34847..a5b198116a9e7 100644 --- a/packages/integrations/mdx/src/utils.ts +++ b/packages/integrations/mdx/src/utils.ts @@ -1,10 +1,10 @@ -import type { PluggableList } from '@mdx-js/mdx/lib/core.js'; import type { Options as AcornOpts } from 'acorn'; import { parse } from 'acorn'; import type { AstroConfig, SSRError } from 'astro'; import matter from 'gray-matter'; import { bold, yellow } from 'kleur/colors'; import type { MdxjsEsm } from 'mdast-util-mdx'; +import type { PluggableList } from 'unified'; function appendForwardSlash(path: string) { return path.endsWith('/') ? path : path + '/'; @@ -75,8 +75,8 @@ export function jsToTreeNode( type: 'mdxjsEsm', value: '', data: { + // @ts-expect-error `parse` return types is incompatible but it should work in runtime estree: { - body: [], ...parse(jsString, acornOpts), type: 'Program', sourceType: 'module', diff --git a/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js b/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js index b73cd234d75d4..63248dc56f882 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js @@ -1,6 +1,6 @@ -export async function get() { +export async function GET() { const docs = await import.meta.glob('./*.mdx', { eager: true }); - return { - body: JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)), - } + return new Response( + JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)) + ); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js b/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js index a1d6a4ac42dda..d82d9f770517c 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js @@ -1,9 +1,6 @@ -export async function get() { +export async function GET() { const mdxPages = await import.meta.glob('./*.mdx', { eager: true }); - - return { - body: JSON.stringify({ - titles: Object.values(mdxPages ?? {}).map(v => v?.frontmatter?.title), - }) - } + return Response.json({ + titles: Object.values(mdxPages ?? {}).map((v) => v?.frontmatter?.title), + }); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js b/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js index 940e5c141c38f..e57192c6151d4 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js @@ -1,11 +1,8 @@ -export async function get() { +export async function GET() { const mdxPages = await import.meta.glob('./*.mdx', { eager: true }); - - return { - body: JSON.stringify({ - headingsByPage: Object.fromEntries( - Object.entries(mdxPages ?? {}).map(([k, v]) => [k, v?.getHeadings()]) - ), - }), - } + return Response.json({ + headingsByPage: Object.fromEntries( + Object.entries(mdxPages ?? {}).map(([k, v]) => [k, v?.getHeadings()]) + ), + }); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-infinite-loop/package.json b/packages/integrations/mdx/test/fixtures/mdx-infinite-loop/package.json index d2fb7a75d0f5c..a00e19d5b2207 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-infinite-loop/package.json +++ b/packages/integrations/mdx/test/fixtures/mdx-infinite-loop/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/preact": "workspace:*", "astro": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" } } diff --git a/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js b/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js index 36b6f7af69aaf..02cff64a8af11 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js @@ -1,9 +1,6 @@ -export async function get() { +export async function GET() { const mdxPages = await import.meta.glob('./*.mdx', { eager: true }); - - return { - body: JSON.stringify({ - urls: Object.values(mdxPages ?? {}).map(v => v?.url), - }) - } + return Response.json({ + urls: Object.values(mdxPages ?? {}).map((v) => v?.url), + }); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js b/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js index ce3cf81e5cf85..152285b9cf944 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js @@ -1,7 +1,5 @@ import { frontmatter } from './vite-env-vars.mdx'; -export function get() { - return { - body: JSON.stringify(frontmatter), - } +export function GET() { + return Response.json(frontmatter); } diff --git a/packages/integrations/mdx/test/mdx-astro-markdown-remarkRehype.test.js b/packages/integrations/mdx/test/mdx-astro-markdown-remarkRehype.test.js index ddcce4ba59769..eab2c61b089cd 100644 --- a/packages/integrations/mdx/test/mdx-astro-markdown-remarkRehype.test.js +++ b/packages/integrations/mdx/test/mdx-astro-markdown-remarkRehype.test.js @@ -79,7 +79,7 @@ describe('MDX with Astro Markdown remark-rehype config', () => { expect(document.querySelector('#footnote-label').textContent).to.equal('Catatan kaki'); expect(document.querySelector('.data-footnote-backref').getAttribute('aria-label')).to.equal( - 'Back to content' + 'Back to reference 1' ); }); }); diff --git a/packages/integrations/mdx/test/mdx-math.test.js b/packages/integrations/mdx/test/mdx-math.test.js index f39ea42c83992..52ee94a46919e 100644 --- a/packages/integrations/mdx/test/mdx-math.test.js +++ b/packages/integrations/mdx/test/mdx-math.test.js @@ -4,7 +4,7 @@ import { parseHTML } from 'linkedom'; import { loadFixture } from '../../../astro/test/test-utils.js'; import remarkMath from 'remark-math'; import rehypeMathjaxSvg from 'rehype-mathjax'; -import rehypeMathjaxChtml from 'rehype-mathjax/chtml.js'; +import rehypeMathjaxChtml from 'rehype-mathjax/chtml'; const FIXTURE_ROOT = new URL('./fixtures/mdx-math/', import.meta.url); diff --git a/packages/integrations/mdx/test/mdx-slots.js b/packages/integrations/mdx/test/mdx-slots.test.js similarity index 100% rename from packages/integrations/mdx/test/mdx-slots.js rename to packages/integrations/mdx/test/mdx-slots.test.js diff --git a/packages/integrations/node/CHANGELOG.md b/packages/integrations/node/CHANGELOG.md index 8ef4b80ac4737..89c7a40218447 100644 --- a/packages/integrations/node/CHANGELOG.md +++ b/packages/integrations/node/CHANGELOG.md @@ -1,5 +1,42 @@ # @astrojs/node +## 7.0.1 + +### Patch Changes + +- [#9366](https://github.com/withastro/astro/pull/9366) [`1b4e91898`](https://github.com/withastro/astro/commit/1b4e91898116f75b02b66ec402385cf44e559118) Thanks [@lilnasy](https://github.com/lilnasy)! - Updates NPM package to refer to the stable Astro version instead of a beta. + +## 7.0.0 + +### Major Changes + +- [#9199](https://github.com/withastro/astro/pull/9199) [`49aa215a0`](https://github.com/withastro/astro/commit/49aa215a01ee1c4805316c85bb0aea6cfbc25a31) Thanks [@lilnasy](https://github.com/lilnasy)! - The internals of the integration have been updated to support Astro 4.0. Make sure to upgrade your Astro version as Astro 3.0 is no longer supported. + +## 7.0.0-beta.1 + +### Major Changes + +- [#9199](https://github.com/withastro/astro/pull/9199) [`49aa215a0`](https://github.com/withastro/astro/commit/49aa215a01ee1c4805316c85bb0aea6cfbc25a31) Thanks [@lilnasy](https://github.com/lilnasy)! - The internals of the integration have been updated to support Astro 4.0. Make sure to upgrade your Astro version as Astro 3.0 is no longer supported. + +## 7.0.0-beta.0 + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + +## 6.1.0 + +### Minor Changes + +- [#9125](https://github.com/withastro/astro/pull/9125) [`8f1d50957`](https://github.com/withastro/astro/commit/8f1d509574f5ee5d77816a13d89ce452dce403ff) Thanks [@matthewp](https://github.com/matthewp)! - Automatically sets immutable cache headers for assets served from the `/_astro` directory. + +## 6.1.0 + +### Minor Changes + +- [#9125](https://github.com/withastro/astro/pull/9125) [`8f1d50957`](https://github.com/withastro/astro/commit/8f1d509574f5ee5d77816a13d89ce452dce403ff) Thanks [@matthewp](https://github.com/matthewp)! - Automatically sets immutable cache headers for assets served from the `/_astro` directory. + ## 6.0.4 ### Patch Changes diff --git a/packages/integrations/node/README.md b/packages/integrations/node/README.md index 5753a59bc4ed0..af11405c04741 100644 --- a/packages/integrations/node/README.md +++ b/packages/integrations/node/README.md @@ -190,6 +190,16 @@ In the case of multiple run-time variables, store them in a seperate file (e.g. export $(cat .env.runtime) && astro build ``` +#### Assets + +In standalone mode, assets in your `dist/client/` folder are served via the standalone server. You might be deploying these assets to a CDN, in which case the server will never actually be serving them. But in some cases, such as intranet sites, it's fine to serve static assets directly from the application server. + +Assets in the `dist/client/_astro/` folder are the ones that Astro has built. These assets are all named with a hash and therefore can be given long cache headers. Internally the adapter adds this header for these assets: + +``` +Cache-Control: public, max-age=31536000, immutable +``` + ## Troubleshooting ### SyntaxError: Named export 'compile' not found diff --git a/packages/integrations/node/package.json b/packages/integrations/node/package.json index b50b3e1757f02..402bb6f7b966c 100644 --- a/packages/integrations/node/package.json +++ b/packages/integrations/node/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/node", "description": "Deploy your site to a Node.js server", - "version": "6.0.4", + "version": "7.0.1", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -37,12 +37,12 @@ "server-destroy": "^1.0.1" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^4.0.0" }, "devDependencies": { "@types/node": "^18.17.8", - "@types/send": "^0.17.1", - "@types/server-destroy": "^1.0.1", + "@types/send": "^0.17.4", + "@types/server-destroy": "^1.0.3", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", diff --git a/packages/integrations/node/src/createOutgoingHttpHeaders.ts b/packages/integrations/node/src/createOutgoingHttpHeaders.ts index 781a74de6e903..44bbf81ca9935 100644 --- a/packages/integrations/node/src/createOutgoingHttpHeaders.ts +++ b/packages/integrations/node/src/createOutgoingHttpHeaders.ts @@ -23,8 +23,7 @@ export const createOutgoingHttpHeaders = ( // if there is > 1 set-cookie header, we have to fix it to be an array of values if (headers.has('set-cookie')) { - // @ts-expect-error - const cookieHeaders = headers.getSetCookie() as string[]; + const cookieHeaders = headers.getSetCookie(); if (cookieHeaders.length > 1) { // the Headers.entries() API already normalized all header names to lower case so we can safely index this as 'set-cookie' nodeHeaders['set-cookie'] = cookieHeaders; diff --git a/packages/integrations/node/src/http-server.ts b/packages/integrations/node/src/http-server.ts index 2f2339cdf75a5..90493760176c4 100644 --- a/packages/integrations/node/src/http-server.ts +++ b/packages/integrations/node/src/http-server.ts @@ -10,6 +10,7 @@ interface CreateServerOptions { port: number; host: string | undefined; removeBase: (pathname: string) => string; + assets: string; } function parsePathname(pathname: string, host: string | undefined, port: number) { @@ -22,9 +23,16 @@ function parsePathname(pathname: string, host: string | undefined, port: number) } export function createServer( - { client, port, host, removeBase }: CreateServerOptions, + { client, port, host, removeBase, assets }: CreateServerOptions, handler: http.RequestListener ) { + // The `base` is removed before passed to this function, so we don't + // need to check for it here. + const assetsPrefix = `/${assets}/`; + function isImmutableAsset(pathname: string) { + return pathname.startsWith(assetsPrefix); + } + const listener: http.RequestListener = (req, res) => { if (req.url) { let pathname: string | undefined = removeBase(req.url); @@ -54,6 +62,12 @@ export function createServer( // File not found, forward to the SSR handler handler(req, res); }); + stream.on('headers', (_res: http.ServerResponse) => { + if (isImmutableAsset(encodedURI)) { + // Taken from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#immutable + _res.setHeader('Cache-Control', 'public, max-age=31536000, immutable'); + } + }); stream.on('directory', () => { // On directory find, redirect to the trailing slash let location: string; diff --git a/packages/integrations/node/src/index.ts b/packages/integrations/node/src/index.ts index 1f3707949d08b..bac5c25ef5bfa 100644 --- a/packages/integrations/node/src/index.ts +++ b/packages/integrations/node/src/index.ts @@ -6,7 +6,7 @@ export function getAdapter(options: Options): AstroAdapter { name: '@astrojs/node', serverEntrypoint: '@astrojs/node/server.js', previewEntrypoint: '@astrojs/node/preview.js', - exports: ['handler', 'startServer'], + exports: ['handler', 'startServer', 'options'], args: options, supportedAstroFeatures: { hybridOutput: 'stable', @@ -49,6 +49,7 @@ export default function createIntegration(userOptions: UserOptions): AstroIntegr server: config.build.server?.toString(), host: config.server.host, port: config.server.port, + assets: config.build.assets, }; setAdapter(getAdapter(_options)); diff --git a/packages/integrations/node/src/nodeMiddleware.ts b/packages/integrations/node/src/nodeMiddleware.ts index 4fd0a4bc23f5d..0b9381f1d0a29 100644 --- a/packages/integrations/node/src/nodeMiddleware.ts +++ b/packages/integrations/node/src/nodeMiddleware.ts @@ -30,10 +30,10 @@ export default function (app: NodeApp, mode: Options['mode']) { } try { - const route = app.match(req); - if (route) { + const routeData = app.match(req); + if (routeData) { try { - const response = await app.render(req, route, locals); + const response = await app.render(req, { routeData, locals }); await writeWebResponse(app, res, response); } catch (err: unknown) { if (next) { diff --git a/packages/integrations/node/src/preview.ts b/packages/integrations/node/src/preview.ts index 70ed5469875b9..89baa1897b69d 100644 --- a/packages/integrations/node/src/preview.ts +++ b/packages/integrations/node/src/preview.ts @@ -17,11 +17,13 @@ const preview: CreatePreviewServer = async function ({ type ServerModule = ReturnType; type MaybeServerModule = Partial; let ssrHandler: ServerModule['handler']; + let options: ServerModule['options']; try { process.env.ASTRO_NODE_AUTOSTART = 'disabled'; const ssrModule: MaybeServerModule = await import(serverEntrypoint.toString()); if (typeof ssrModule.handler === 'function') { ssrHandler = ssrModule.handler; + options = ssrModule.options!; } else { throw new AstroError( `The server entrypoint doesn't have a handler. Are you sure this is the right file?` @@ -59,6 +61,7 @@ const preview: CreatePreviewServer = async function ({ port, host, removeBase, + assets: options.assets, }, handler ); diff --git a/packages/integrations/node/src/server.ts b/packages/integrations/node/src/server.ts index 90bf8c44c46f9..88bcd7d62e5f0 100644 --- a/packages/integrations/node/src/server.ts +++ b/packages/integrations/node/src/server.ts @@ -8,6 +8,7 @@ applyPolyfills(); export function createExports(manifest: SSRManifest, options: Options) { const app = new NodeApp(manifest); return { + options: options, handler: middleware(app, options.mode), startServer: () => startServer(app, options), }; diff --git a/packages/integrations/node/src/standalone.ts b/packages/integrations/node/src/standalone.ts index abe40ff5cced8..e167e8ab69a5b 100644 --- a/packages/integrations/node/src/standalone.ts +++ b/packages/integrations/node/src/standalone.ts @@ -52,6 +52,7 @@ export default function startServer(app: NodeApp, options: Options) { port, host, removeBase: app.removeBase.bind(app), + assets: options.assets, }, handler ); diff --git a/packages/integrations/node/src/types.ts b/packages/integrations/node/src/types.ts index 85f4f4fbce981..273b805292cc4 100644 --- a/packages/integrations/node/src/types.ts +++ b/packages/integrations/node/src/types.ts @@ -1,4 +1,4 @@ -import { IncomingMessage, ServerResponse } from 'node:http'; +import type { IncomingMessage, ServerResponse } from 'node:http'; export interface UserOptions { /** @@ -15,6 +15,7 @@ export interface Options extends UserOptions { port: number; server: string; client: string; + assets: string; } export type RequestHandlerParams = [ diff --git a/packages/integrations/node/test/assets.test.js b/packages/integrations/node/test/assets.test.js new file mode 100644 index 0000000000000..9e44ab31d151d --- /dev/null +++ b/packages/integrations/node/test/assets.test.js @@ -0,0 +1,43 @@ +import { expect } from 'chai'; +import nodejs from '../dist/index.js'; +import { loadFixture } from './test-utils.js'; +import * as cheerio from 'cheerio'; + +describe('Assets', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + let devPreview; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/image/', + output: 'server', + adapter: nodejs({ mode: 'standalone' }), + vite: { + build: { + assetsInlineLimit: 0, + }, + }, + }); + await fixture.build(); + devPreview = await fixture.preview(); + }); + + after(async () => { + await devPreview.stop(); + }); + + it('Assets within the _astro folder should be given immutable headers', async () => { + let response = await fixture.fetch('/text-file'); + let cacheControl = response.headers.get('cache-control'); + expect(cacheControl).to.equal(null); + const html = await response.text(); + const $ = cheerio.load(html); + + // Fetch the asset + const fileURL = $('a').attr('href'); + response = await fixture.fetch(fileURL); + cacheControl = response.headers.get('cache-control'); + expect(cacheControl).to.equal('public, max-age=31536000, immutable'); + }); +}); diff --git a/packages/integrations/node/test/bad-urls.test.js b/packages/integrations/node/test/bad-urls.test.js index de7484b808e1e..894729e3679b1 100644 --- a/packages/integrations/node/test/bad-urls.test.js +++ b/packages/integrations/node/test/bad-urls.test.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import nodejs from '../dist/index.js'; import { loadFixture } from './test-utils.js'; -describe('API routes', () => { +describe('Bad URLs', () => { /** @type {import('./test-utils').Fixture} */ let fixture; let devPreview; diff --git a/packages/integrations/node/test/fixtures/image/src/assets/file.txt b/packages/integrations/node/test/fixtures/image/src/assets/file.txt new file mode 100644 index 0000000000000..e9ea42a12b959 --- /dev/null +++ b/packages/integrations/node/test/fixtures/image/src/assets/file.txt @@ -0,0 +1 @@ +this is a text file diff --git a/packages/integrations/node/test/fixtures/image/src/pages/text-file.astro b/packages/integrations/node/test/fixtures/image/src/pages/text-file.astro new file mode 100644 index 0000000000000..8932503605095 --- /dev/null +++ b/packages/integrations/node/test/fixtures/image/src/pages/text-file.astro @@ -0,0 +1,14 @@ +--- +import txt from '../assets/file.txt?url'; +--- + + + Testing + + +

Testing

+
+ Download text file +
+ + diff --git a/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts b/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts index 93543190f1e20..423db341a46e7 100644 --- a/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts +++ b/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts @@ -1,9 +1,7 @@ -export async function get() { +export async function GET() { let number = Math.random(); - return { - body: JSON.stringify({ - number, - message: `Here's a random number: ${number}`, - }), - }; + return Response.json({ + number, + message: `Here's a random number: ${number}`, + }); } diff --git a/packages/integrations/node/test/headers.test.js.js b/packages/integrations/node/test/headers.test.js similarity index 100% rename from packages/integrations/node/test/headers.test.js.js rename to packages/integrations/node/test/headers.test.js diff --git a/packages/integrations/preact/package.json b/packages/integrations/preact/package.json index 29a10439aa66d..84043fb762a74 100644 --- a/packages/integrations/preact/package.json +++ b/packages/integrations/preact/package.json @@ -37,15 +37,15 @@ "dependencies": { "@babel/plugin-transform-react-jsx": "^7.22.5", "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@preact/preset-vite": "^2.5.0", + "@preact/preset-vite": "^2.7.0", "@preact/signals": "^1.2.1", "babel-plugin-transform-hook-names": "^1.0.2", - "preact-render-to-string": "^6.2.1" + "preact-render-to-string": "^6.3.1" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", - "preact": "^10.17.1" + "preact": "^10.19.2" }, "peerDependencies": { "preact": "^10.6.5" diff --git a/packages/integrations/prefetch/@types/network-information.d.ts b/packages/integrations/prefetch/@types/network-information.d.ts deleted file mode 100644 index bf1d787f3f6a6..0000000000000 --- a/packages/integrations/prefetch/@types/network-information.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export {}; - -declare global { - interface NetworkInformation { - // http://wicg.github.io/netinfo/#effectiveconnectiontype-enum - readonly effectiveType: '2g' | '3g' | '4g' | 'slow-2g'; - // http://wicg.github.io/netinfo/#savedata-attribute - readonly saveData?: boolean; - } - - var NetworkInformation: { - prototype: NetworkInformation; - new (): NetworkInformation; - }; -} diff --git a/packages/integrations/prefetch/CHANGELOG.md b/packages/integrations/prefetch/CHANGELOG.md deleted file mode 100644 index de7ba588e7908..0000000000000 --- a/packages/integrations/prefetch/CHANGELOG.md +++ /dev/null @@ -1,140 +0,0 @@ -# @astrojs/prefetch - -## 0.4.1 - -### Patch Changes - -- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI - -## 0.4.0 - -### Minor Changes - -- [#8188](https://github.com/withastro/astro/pull/8188) [`d0679a666`](https://github.com/withastro/astro/commit/d0679a666f37da0fca396d42b9b32bbb25d29312) Thanks [@ematipico](https://github.com/ematipico)! - Remove support for Node 16. The lowest supported version by Astro and all integrations is now v18.14.1. As a reminder, Node 16 will be deprecated on the 11th September 2023. - -- [#8179](https://github.com/withastro/astro/pull/8179) [`6011d52d3`](https://github.com/withastro/astro/commit/6011d52d38e43c3e3d52bc3bc41a60e36061b7b7) Thanks [@matthewp](https://github.com/matthewp)! - Astro 3.0 Release Candidate - -## 0.4.0-rc.1 - -### Minor Changes - -- [#8179](https://github.com/withastro/astro/pull/8179) [`6011d52d3`](https://github.com/withastro/astro/commit/6011d52d38e43c3e3d52bc3bc41a60e36061b7b7) Thanks [@matthewp](https://github.com/matthewp)! - Astro 3.0 Release Candidate - -## 0.4.0-beta.0 - -### Minor Changes - -- [`1eae2e3f7`](https://github.com/withastro/astro/commit/1eae2e3f7d693c9dfe91c8ccfbe606d32bf2fb81) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Remove support for Node 16. The lowest supported version by Astro and all integrations is now v18.14.1. As a reminder, Node 16 will be deprecated on the 11th September 2023. - -## 0.3.0 - -### Minor Changes - -- [#6585](https://github.com/withastro/astro/pull/6585) [`9807e4dc2`](https://github.com/withastro/astro/commit/9807e4dc22355f0b3b2ff65b0724a95af8e9702d) Thanks [@kory-smith](https://github.com/kory-smith)! - Adds the option to prefetch a link only when it is hovered or focused. - -### Patch Changes - -- [#7613](https://github.com/withastro/astro/pull/7613) [`131c92279`](https://github.com/withastro/astro/commit/131c92279ee8a282e71a09523870bb0e7df80627) Thanks [@Yan-Thomas](https://github.com/Yan-Thomas)! - Update prefetch README filename syntax - -## 0.2.3 - -### Patch Changes - -- [#7123](https://github.com/withastro/astro/pull/7123) [`147373722`](https://github.com/withastro/astro/commit/147373722b37126af949bb054a1cdfb0aed6c2ff) Thanks [@connor-baer](https://github.com/connor-baer)! - Fix the inclusion of `@types/network-information`. - -## 0.2.2 - -### Patch Changes - -- [#7104](https://github.com/withastro/astro/pull/7104) [`826e02890`](https://github.com/withastro/astro/commit/826e0289005f645b902375b98d5549c6a95ccafa) Thanks [@bluwy](https://github.com/bluwy)! - Specify `"files"` field to only publish necessary files - -## 0.2.1 - -### Patch Changes - -- [#6494](https://github.com/withastro/astro/pull/6494) [`a13e9d7e3`](https://github.com/withastro/astro/commit/a13e9d7e33baccf51e7d4815f99b481ad174bc57) Thanks [@Yan-Thomas](https://github.com/Yan-Thomas)! - Consistency improvements to several package descriptions - -## 0.2.0 - -### Minor Changes - -- [#6213](https://github.com/withastro/astro/pull/6213) [`afbbc4d5b`](https://github.com/withastro/astro/commit/afbbc4d5bfafc1779bac00b41c2a1cb1c90f2808) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Updated compilation settings to disable downlevelling for Node 14 - -## 0.1.2 - -### Patch Changes - -- [#5478](https://github.com/withastro/astro/pull/5478) [`1c7eef308`](https://github.com/withastro/astro/commit/1c7eef308e808aa5ed4662b53e67ec8d1b814d1f) Thanks [@nemo0](https://github.com/nemo0)! - Update READMEs for consistency - -## 0.1.1 - -### Patch Changes - -- [#5244](https://github.com/withastro/astro/pull/5244) [`6ad91bd80`](https://github.com/withastro/astro/commit/6ad91bd80dae935b67a5c18b8dfbb95f2cfe10ef) Thanks [@deeprobin](https://github.com/deeprobin)! - Do not prefetch if browser is offline or uses 3G - -- [#5271](https://github.com/withastro/astro/pull/5271) [`b6afe2c1d`](https://github.com/withastro/astro/commit/b6afe2c1db613aabf3139fb58e0fc2ab60322f37) Thanks [@tony-sull](https://github.com/tony-sull)! - Adds additional package.json keywords used for discoverability in the Integrations catalog - -## 0.1.0 - -### Minor Changes - -- [#5125](https://github.com/withastro/astro/pull/5125) [`5a674f976`](https://github.com/withastro/astro/commit/5a674f976d6138ec5c87441a579c2ccf37713e73) Thanks [@Jelenkee](https://github.com/Jelenkee)! - Prefetch CSS files once - -## 0.0.8 - -### Patch Changes - -- [#5009](https://github.com/withastro/astro/pull/5009) [`92b27e9c9`](https://github.com/withastro/astro/commit/92b27e9c9253cea3d00f1f81223de19ff75c2c74) Thanks [@panwauu](https://github.com/panwauu)! - Prevents prefetching the current page - -## 0.0.7 - -### Patch Changes - -- [#4207](https://github.com/withastro/astro/pull/4207) [`ceb0eef94`](https://github.com/withastro/astro/commit/ceb0eef944f2f867cb2dba04adfb6b028cf8c228) Thanks [@jablonski](https://github.com/jablonski)! - Use `passive` event listeners for performance - -## 0.0.6 - -### Patch Changes - -- [#4004](https://github.com/withastro/astro/pull/4004) [`ef9c4152b`](https://github.com/withastro/astro/commit/ef9c4152b2b399e25bf4e8aa7b37adcf6d0d8f17) Thanks [@sarah11918](https://github.com/sarah11918)! - [READMEs] removed "experimental" from astro add instructions - -## 0.0.5 - -### Patch Changes - -- [#3885](https://github.com/withastro/astro/pull/3885) [`bf5d1cc1e`](https://github.com/withastro/astro/commit/bf5d1cc1e71da38a14658c615e9481f2145cc6e7) Thanks [@delucis](https://github.com/delucis)! - Integration README fixes - -## 0.0.4 - -### Patch Changes - -- [#3865](https://github.com/withastro/astro/pull/3865) [`1f9e4857`](https://github.com/withastro/astro/commit/1f9e4857ff2b2cb7db89d619618cdf546cd3b3dc) Thanks [@delucis](https://github.com/delucis)! - Small README fixes - -* [#3854](https://github.com/withastro/astro/pull/3854) [`b012ee55`](https://github.com/withastro/astro/commit/b012ee55b107dea0730286263b27d83e530fad5d) Thanks [@bholmesdev](https://github.com/bholmesdev)! - [astro add] Support adapters and third party packages - -## 0.0.3 - -### Patch Changes - -- [#3778](https://github.com/withastro/astro/pull/3778) [`91635f05`](https://github.com/withastro/astro/commit/91635f05df207d33ee8b50a2afe970b94b24ba7b) Thanks [@hippotastic](https://github.com/hippotastic)! - Fix integration name (`prefetch` instead of `lit`) - -## 0.0.2 - -### Patch Changes - -- [#3736](https://github.com/withastro/astro/pull/3736) [`bd4dac0e`](https://github.com/withastro/astro/commit/bd4dac0e1a8598045f10c42faf08abff96ed6766) Thanks [@tony-sull](https://github.com/tony-sull)! - Adds a new `@astrojs/prefetch` integration with the goal of adding near-instant page navigation for Astro projects. HTML and CSS for visible links marked with `rel="prefetch"` will be preloaded in the browser when the browser is idle. - - **astro.config.mjs** - - ```js - import prefetch from '@astrojs/prefetch'; - export default { - // ... - integrations: [prefetch()], - }; - ``` - - ```html - - All Products - ``` diff --git a/packages/integrations/prefetch/README.md b/packages/integrations/prefetch/README.md deleted file mode 100644 index a357618e4f303..0000000000000 --- a/packages/integrations/prefetch/README.md +++ /dev/null @@ -1,148 +0,0 @@ -# @astrojs/prefetch 🔗 - -> NOTE: `@astrojs/prefetch` is deprecated. Use the `prefetch` feature in Astro 3.5 instead. Check out the [migration guide](https://docs.astro.build/en/guides/prefetch/#migrating-from-astrojsprefetch). - -- [Why Prefetch?](#why-prefetch) -- [Installation](#installation) -- [Usage](#usage) -- [Configuration](#configuration) -- [Troubleshooting](#troubleshooting) -- [Contributing](#contributing) -- [Changelog](#changelog) - -## Why Prefetch? - -Page load times play a big role in usability and overall enjoyment of a site. This integration brings the benefits of near-instant page navigations to your multi-page application (MPA) by prefetching page links when they are visible on screen. - -To further improve the experience, especially on similar pages, stylesheets are also prefetched along with the HTML. This is particularly useful when navigating between tabs on a static site, where most of the page's content and styles don't change. - -## Installation - -### Quick Install - -The `astro add` command-line tool automates the installation for you. Run one of the following commands in a new terminal window. (If you aren't sure which package manager you're using, run the first command.) Then, follow the prompts, and type "y" in the terminal (meaning "yes") for each one. - -```sh -# Using NPM -npx astro add prefetch -# Using Yarn -yarn astro add prefetch -# Using PNPM -pnpm astro add prefetch -``` - -If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. - -### Manual Install - -First, install the `@astrojs/prefetch` package using your package manager. If you're using npm or aren't sure, run this in the terminal: - -```sh -npm install @astrojs/prefetch -``` - -Then, apply this integration to your `astro.config.*` file using the `integrations` property: - -```diff lang="js" "prefetch()" - // astro.config.mjs - import { defineConfig } from 'astro/config'; -+ import prefetch from '@astrojs/prefetch'; - - export default defineConfig({ - // ... - integrations: [prefetch()], - // ^^^^^^^^^^ - }); -``` - -## Usage - -When you install the integration, the prefetch script is automatically added to every page in the project. Just add `rel="prefetch"` to any `` links on your page and you're ready to go! - -In addition, you can add `rel="prefetch-intent"` to any `` links on your page to prefetch them only when they are hovered over, touched, or focused. This is especially useful to conserve data usage when viewing your site. - -## Configuration - -The Astro Prefetch integration handles which links on the site are prefetched and it has its own options. Change these in the `astro.config.mjs` file which is where your project's integration settings live. - -### config.selector - -By default the prefetch script searches the page for any links that include a `rel="prefetch"` attribute, ex: `` or ``. This behavior can be changed in your `astro.config.*` file to use a custom query selector when finding prefetch links. - -```js -// astro.config.mjs -import { defineConfig } from 'astro/config'; -import prefetch from '@astrojs/prefetch'; - -export default defineConfig({ - // ... - integrations: [ - prefetch({ - // Only prefetch links with an href that begins with `/products` - selector: "a[href^='/products']", - }), - ], -}); -``` - -### config.intentSelector - -By default, the prefetch script also searches the page for any links that include a `rel="prefetch-intent"` attribute, ex: ``. This behavior can be changed in your `astro.config.*` file to use a custom query selector when finding prefetch-intent links. - -```js -// astro.config.mjs -import { defineConfig } from 'astro/config'; -import prefetch from '@astrojs/prefetch'; - -export default defineConfig({ - // ... - integrations: [ - prefetch({ - // Only prefetch links with an href that begins with `/products` or `/coupons` - intentSelector: ["a[href^='/products']", "a[href^='/coupons']"], - - // Use a string to prefetch a single selector - // intentSelector: "a[href^='/products']" - }), - ], -}); -``` - -### config.throttle - -By default the prefetch script will only prefetch one link at a time. This behavior can be changed in your `astro.config.*` file to increase the limit for concurrent downloads. - -```js -// astro.config.mjs -import { defineConfig } from 'astro/config'; -import prefetch from '@astrojs/prefetch'; - -export default defineConfig({ - // ... - integrations: [ - prefetch({ - // Allow up to three links to be prefetched concurrently - throttle: 3, - }), - ], -}); -``` - -## Troubleshooting - -- If your installation doesn't seem to be working, try restarting the dev server. -- If a link doesn't seem to be prefetching, make sure that the link is pointing to a page on the same domain and matches the integration's `selector` option. - -For help, check out the `#support` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help! - -You can also check our [Astro Integration Documentation][astro-integration] for more on integrations. - -## Contributing - -This package is maintained by Astro's Core team. You're welcome to submit an issue or PR! - -## Changelog - -See [CHANGELOG.md](CHANGELOG.md) for a history of changes to this integration. - -[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/ diff --git a/packages/integrations/prefetch/package.json b/packages/integrations/prefetch/package.json deleted file mode 100644 index da199b43a5b97..0000000000000 --- a/packages/integrations/prefetch/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@astrojs/prefetch", - "description": "Prefetch page navigations in your Astro site", - "version": "0.4.1", - "type": "module", - "types": "./dist/index.d.ts", - "author": "withastro", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/withastro/astro.git", - "directory": "packages/astro-prefetch" - }, - "keywords": [ - "astro-integration", - "performance", - "withastro" - ], - "bugs": "https://github.com/withastro/astro/issues", - "homepage": "https://docs.astro.build/en/guides/integrations-guide/prefetch/", - "exports": { - ".": "./dist/index.js", - "./client.js": "./dist/client.js", - "./package.json": "./package.json" - }, - "files": [ - "dist" - ], - "scripts": { - "build": "astro-scripts build \"src/**/*.ts\" && tsc", - "build:ci": "astro-scripts build \"src/**/*.ts\"", - "dev": "astro-scripts dev \"src/**/*.ts\"", - "test": "playwright test", - "test:match": "playwright test -g" - }, - "devDependencies": { - "@playwright/test": "^1.37.1", - "astro": "workspace:*", - "astro-scripts": "workspace:*" - }, - "dependencies": { - "throttles": "^1.0.1" - }, - "publishConfig": { - "provenance": true - } -} diff --git a/packages/integrations/prefetch/playwright.config.js b/packages/integrations/prefetch/playwright.config.js deleted file mode 100644 index 7fb92ae0c0ef7..0000000000000 --- a/packages/integrations/prefetch/playwright.config.js +++ /dev/null @@ -1,44 +0,0 @@ -// NOTE: Prefetch tests fail with `TypeError: process.stdout.clearLine is not a function` -// for some reason. This comes from Vite, and is conditionally called based on `isTTY`. -// We set it to false here to skip this odd behavior. -process.stdout.isTTY = false; - -const config = { - testMatch: 'test/*.test.js', - /* Maximum time one test can run for. */ - timeout: 30 * 1000, - expect: { - /** - * Maximum time expect() should wait for the condition to be met. - * For example in `await expect(locator).toHaveText();` - */ - timeout: 5000, - }, - /* Fail the build on CI if you accidentally left test in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 5 : 0, - /* Opt out of parallel tests on CI. */ - workers: 1, - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:4321', - - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, - projects: [ - { - name: 'Chrome Stable', - use: { - browserName: 'chromium', - channel: 'chrome', - }, - }, - ], -}; - -export default config; diff --git a/packages/integrations/prefetch/src/client.ts b/packages/integrations/prefetch/src/client.ts deleted file mode 100644 index dc05cb84b0f17..0000000000000 --- a/packages/integrations/prefetch/src/client.ts +++ /dev/null @@ -1,155 +0,0 @@ -/// -import throttles from 'throttles'; -import requestIdleCallback from './requestIdleCallback.js'; - -const events = ['mouseenter', 'touchstart', 'focus']; - -const preloaded = new Set(); -const loadedStyles = new Set(); - -function shouldPreload({ href }: { href: string }) { - try { - const url = new URL(href); - return ( - window.location.origin === url.origin && - window.location.pathname !== url.pathname && - !preloaded.has(href) - ); - } catch {} - - return false; -} - -let parser: DOMParser; -let observer: IntersectionObserver; - -function observe(link: HTMLAnchorElement) { - preloaded.add(link.href); - observer.observe(link); - events.map((event) => link.addEventListener(event, onLinkEvent, { passive: true, once: true })); -} - -function unobserve(link: HTMLAnchorElement) { - observer.unobserve(link); - events.map((event) => link.removeEventListener(event, onLinkEvent)); -} - -function onLinkEvent({ target }: Event) { - if (!(target instanceof HTMLAnchorElement)) { - return; - } - - preloadHref(target); -} - -async function preloadHref(link: HTMLAnchorElement) { - unobserve(link); - const { href } = link; - - try { - const contents = await fetch(href).then((res) => res.text()); - parser ||= new DOMParser(); - - const html = parser.parseFromString(contents, 'text/html'); - const styles = Array.from(html.querySelectorAll('link[rel="stylesheet"]')); - - await Promise.all( - styles - .filter((el) => !loadedStyles.has(el.href)) - .map((el) => { - loadedStyles.add(el.href); - return fetch(el.href); - }) - ); - } catch {} -} - -export interface PrefetchOptions { - /** - * Element selector used to find all links on the page that should be prefetched. - * - * @default 'a[href][rel~="prefetch"]' - */ - selector?: string; - /** - * The number of pages that can be prefetched concurrently. - * - * @default 1 - */ - throttle?: number; - /** - * Element selector used to find all links on the page that should be prefetched on user interaction. - * - * @default 'a[href][rel~="prefetch-intent"]' - */ - intentSelector?: string | string[]; -} - -export default function prefetch({ - selector = 'a[href][rel~="prefetch"]', - throttle = 1, - intentSelector = 'a[href][rel~="prefetch-intent"]', -}: PrefetchOptions) { - // If the navigator is offline, it is very unlikely that a request can be made successfully - if (!navigator.onLine) { - return Promise.reject(new Error('Cannot prefetch, no network connection')); - } - - // `Navigator.connection` is an experimental API and is not supported in every browser. - if ('connection' in navigator) { - const connection = (navigator as any).connection; - // Don't prefetch if Save-Data is enabled. - if (connection.saveData) { - return Promise.reject(new Error('Cannot prefetch, Save-Data is enabled')); - } - - // Do not prefetch if using 2G or 3G - if (/(2|3)g/.test(connection.effectiveType)) { - return Promise.reject(new Error('Cannot prefetch, network conditions are poor')); - } - } - - const [toAdd, isDone] = throttles(throttle); - - observer = - observer || - new IntersectionObserver((entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting && entry.target instanceof HTMLAnchorElement) { - const relAttributeValue = entry.target.getAttribute('rel') || ''; - let matchesIntentSelector = false; - // Check if intentSelector is an array - if (Array.isArray(intentSelector)) { - // If intentSelector is an array, use .some() to check for matches - matchesIntentSelector = intentSelector.some((intent) => - relAttributeValue.includes(intent) - ); - } else { - // If intentSelector is a string, use .includes() to check for a match - matchesIntentSelector = relAttributeValue.includes(intentSelector); - } - if (!matchesIntentSelector) { - toAdd(() => preloadHref(entry.target as HTMLAnchorElement).finally(isDone)); - } - } - }); - }); - - requestIdleCallback(() => { - const links = [...document.querySelectorAll(selector)].filter(shouldPreload); - links.forEach(observe); - - const intentSelectorFinal = Array.isArray(intentSelector) - ? intentSelector.join(',') - : intentSelector; - // Observe links with prefetch-intent - const intentLinks = [ - ...document.querySelectorAll(intentSelectorFinal), - ].filter(shouldPreload); - intentLinks.forEach((link) => { - events.map((event) => - link.addEventListener(event, onLinkEvent, { passive: true, once: true }) - ); - }); - }); -} diff --git a/packages/integrations/prefetch/src/index.ts b/packages/integrations/prefetch/src/index.ts deleted file mode 100644 index 74ec5186e6c59..0000000000000 --- a/packages/integrations/prefetch/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { AstroIntegration } from 'astro'; -import type { PrefetchOptions } from './client.js'; - -export default function (options: PrefetchOptions = {}): AstroIntegration { - return { - name: '@astrojs/prefetch', - hooks: { - 'astro:config:setup': ({ injectScript }) => { - // Inject the necessary polyfills on every page (inlined for speed). - injectScript( - 'page', - `import prefetch from "@astrojs/prefetch/client.js"; prefetch(${JSON.stringify( - options - )});` - ); - }, - }, - }; -} diff --git a/packages/integrations/prefetch/src/requestIdleCallback.ts b/packages/integrations/prefetch/src/requestIdleCallback.ts deleted file mode 100644 index 9435bd41d780c..0000000000000 --- a/packages/integrations/prefetch/src/requestIdleCallback.ts +++ /dev/null @@ -1,16 +0,0 @@ -function shim(callback: IdleRequestCallback, options?: IdleRequestOptions) { - const timeout = options?.timeout ?? 50; - const start = Date.now(); - - return setTimeout(function () { - callback({ - didTimeout: false, - timeRemaining: function () { - return Math.max(0, timeout - (Date.now() - start)); - }, - }); - }, 1); -} - -const requestIdleCallback = window.requestIdleCallback || shim; -export default requestIdleCallback; diff --git a/packages/integrations/prefetch/test/basic-prefetch.test.js b/packages/integrations/prefetch/test/basic-prefetch.test.js deleted file mode 100644 index 5fab536aa8fa2..0000000000000 --- a/packages/integrations/prefetch/test/basic-prefetch.test.js +++ /dev/null @@ -1,130 +0,0 @@ -import { expect } from '@playwright/test'; -import { testFactory } from './test-utils.js'; - -const test = testFactory({ root: './fixtures/basic-prefetch/' }); - -test.describe('Basic prefetch', () => { - test.describe('dev', () => { - let devServer; - - test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); - }); - - test.afterEach(async () => { - await devServer.stop(); - }); - - test.describe('prefetches rel="prefetch" links', () => { - test('skips /admin', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect(requests.includes(astro.resolveUrl('/about')), '/about was prefetched').toBeTruthy(); - expect( - requests.includes(astro.resolveUrl('/contact')), - '/contact was prefetched' - ).toBeTruthy(); - expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); - expect( - requests.filter((r) => r === astro.resolveUrl('/')).length === 1, - '/ was skipped by prefetch and only queried once' - ).toBeTruthy(); - }); - }); - - test.describe('prefetches rel="prefetch-intent" links only on hover', () => { - test('prefetches /uses on hover', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/uses')), - '/uses was not prefetched' - ).toBeFalsy(); - - await page.hover('a[href="/uses"]'); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/uses')), - '/uses was prefetched on hover' - ).toBeTruthy(); - }); - }); - }); - - test.describe('build', () => { - let previewServer; - - test.beforeEach(async ({ astro }) => { - await astro.build(); - previewServer = await astro.preview(); - }); - - // important: close preview server (free up port and connection) - test.afterEach(async () => { - await previewServer.stop(); - }); - - test.describe('prefetches rel="prefetch" links', () => { - test('skips /admin', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect(requests.includes(astro.resolveUrl('/about')), '/about was prefetched').toBeTruthy(); - expect( - requests.includes(astro.resolveUrl('/contact')), - '/contact was prefetched' - ).toBeTruthy(); - expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); - expect( - requests.filter((r) => r === astro.resolveUrl('/')).length === 1, - '/ was skipped by prefetch and only queried once' - ).toBeTruthy(); - }); - }); - - test.describe('prefetches rel="prefetch-intent" links only on hover', () => { - test('prefetches /uses on hover', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/uses')), - '/uses was not prefetched' - ).toBeFalsy(); - - await page.hover('a[href="/uses"]'); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/uses')), - '/uses was prefetched on hover' - ).toBeTruthy(); - }); - }); - }); -}); diff --git a/packages/integrations/prefetch/test/custom-selectors.test.js b/packages/integrations/prefetch/test/custom-selectors.test.js deleted file mode 100644 index b680388dfa74f..0000000000000 --- a/packages/integrations/prefetch/test/custom-selectors.test.js +++ /dev/null @@ -1,260 +0,0 @@ -import { expect } from '@playwright/test'; -import { testFactory } from './test-utils.js'; -import prefetch from '../dist/index.js'; - -const customSelector = 'a[href="/contact"]'; -const customIntentSelector = [ - 'a[href][rel~="custom-intent"]', - 'a[href][rel~="customer-intent"]', - 'a[href][rel~="customest-intent"]', -]; - -const test = testFactory({ - // pass custom prefetch configuration - configFile: false, - root: './fixtures/basic-prefetch/', - integrations: [ - prefetch({ - selector: customSelector, - intentSelector: customIntentSelector, - }), - ], -}); - -test.describe('Custom prefetch selectors', () => { - test.describe('dev', () => { - let devServer; - - test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); - }); - - test.afterEach(async () => { - await devServer.stop(); - }); - - test.describe('prefetches links by custom selector', () => { - test('only prefetches /contact', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect(requests.includes(astro.resolveUrl('/about')), '/about was skipped').toBeFalsy(); - expect( - requests.includes(astro.resolveUrl('/contact')), - '/contact was prefetched' - ).toBeTruthy(); - expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); - expect( - requests.filter((r) => r === astro.resolveUrl('/')).length === 1, - '/ was skipped by prefetch and only queried once' - ).toBeTruthy(); - }); - }); - }); - - test.describe('build', () => { - let previewServer; - - test.beforeEach(async ({ astro }) => { - await astro.build(); - previewServer = await astro.preview(); - }); - - // important: close preview server (free up port and connection) - test.afterEach(async () => { - await previewServer.stop(); - }); - - test.describe('prefetches links by custom selector', () => { - test('only prefetches /contact', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect(requests.includes(astro.resolveUrl('/about')), '/about was skipped').toBeFalsy(); - expect( - requests.includes(astro.resolveUrl('/contact')), - '/contact was prefetched' - ).toBeTruthy(); - expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); - expect( - requests.filter((r) => r === astro.resolveUrl('/')).length === 1, - '/ was skipped by prefetch and only queried once' - ).toBeTruthy(); - }); - }); - }); -}); - -test.describe('Custom prefetch intent selectors', () => { - test.describe('dev', () => { - let devServer; - - test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); - }); - - test.afterEach(async () => { - await devServer.stop(); - }); - - test('prefetches custom intent links only on hover if provided an array', async ({ - page, - astro, - }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was not prefetched initially' - ).toBeFalsy(); - - expect( - requests.includes(astro.resolveUrl('/conditions')), - '/conditions was not prefetched initially' - ).toBeFalsy(); - - const combinedIntentSelectors = customIntentSelector.join(','); - const intentElements = await page.$$(combinedIntentSelectors); - - for (const element of intentElements) { - await element.hover(); - } - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was prefetched on hover' - ).toBeTruthy(); - expect( - requests.includes(astro.resolveUrl('/conditions')), - '/conditions was prefetched on hover' - ).toBeTruthy(); - }); - - test('prefetches custom intent links only on hover if provided a string', async ({ - page, - astro, - }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was not prefetched initially' - ).toBeFalsy(); - - await page.hover(customIntentSelector[0]); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was prefetched on hover' - ).toBeTruthy(); - }); - }); - - test.describe('build', () => { - let previewServer; - - test.beforeEach(async ({ astro }) => { - await astro.build(); - previewServer = await astro.preview(); - }); - - // important: close preview server (free up port and connection) - test.afterEach(async () => { - await previewServer.stop(); - }); - - test('prefetches custom intent links only on hover if provided an array', async ({ - page, - astro, - }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was not prefetched initially' - ).toBeFalsy(); - - expect( - requests.includes(astro.resolveUrl('/conditions')), - '/conditions was not prefetched initially' - ).toBeFalsy(); - - const combinedIntentSelectors = customIntentSelector.join(','); - const intentElements = await page.$$(combinedIntentSelectors); - - for (const element of intentElements) { - await element.hover(); - } - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was prefetched on hover' - ).toBeTruthy(); - expect( - requests.includes(astro.resolveUrl('/conditions')), - '/conditions was prefetched on hover' - ).toBeTruthy(); - }); - - test('prefetches custom intent links only on hover if provided a string', async ({ - page, - astro, - }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was not prefetched initially' - ).toBeFalsy(); - - await page.hover(customIntentSelector[0]); - - await page.waitForLoadState('networkidle'); - - expect( - requests.includes(astro.resolveUrl('/terms')), - '/terms was prefetched on hover' - ).toBeTruthy(); - }); - }); -}); diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/astro.config.mjs b/packages/integrations/prefetch/test/fixtures/basic-prefetch/astro.config.mjs deleted file mode 100644 index 092813b22f734..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/astro.config.mjs +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'astro/config'; -import prefetch from '@astrojs/prefetch'; - -// https://astro.build/config -export default defineConfig({ - integrations: [prefetch()], -}); diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/package.json b/packages/integrations/prefetch/test/fixtures/basic-prefetch/package.json deleted file mode 100644 index cf10d74712024..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@test/astro-prefetch", - "version": "0.0.0", - "private": true, - "dependencies": { - "@astrojs/prefetch": "workspace:*", - "astro": "workspace:*" - } -} diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/about.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/about.astro deleted file mode 100644 index dc2aeb8feefbc..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/about.astro +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - -About Us - - -

About Us

- - diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/admin.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/admin.astro deleted file mode 100644 index 7e44fc97d1c52..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/admin.astro +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - -Admin - - -

Admin

- - diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/conditions.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/conditions.astro deleted file mode 100644 index 345abaa38476d..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/conditions.astro +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - -Conditions - - -

Conditions

- - diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/contact.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/contact.astro deleted file mode 100644 index b565db9125534..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/contact.astro +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - -Contact Us - - -

Contact Us

- - diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro deleted file mode 100644 index b78e3955301d9..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro +++ /dev/null @@ -1,34 +0,0 @@ ---- ---- - - - -Home - - -

Home

- -
- - - - diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/terms.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/terms.astro deleted file mode 100644 index a0fcc100478cd..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/terms.astro +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - -Terms - - -

Terms

- - diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/uses.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/uses.astro deleted file mode 100644 index 15b050061e7a0..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/uses.astro +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - -Uses - - -

Uses

- - diff --git a/packages/integrations/prefetch/test/fixtures/style-prefetch/astro.config.mjs b/packages/integrations/prefetch/test/fixtures/style-prefetch/astro.config.mjs deleted file mode 100644 index 092813b22f734..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/style-prefetch/astro.config.mjs +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'astro/config'; -import prefetch from '@astrojs/prefetch'; - -// https://astro.build/config -export default defineConfig({ - integrations: [prefetch()], -}); diff --git a/packages/integrations/prefetch/test/fixtures/style-prefetch/package.json b/packages/integrations/prefetch/test/fixtures/style-prefetch/package.json deleted file mode 100644 index dce71e357b46f..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/style-prefetch/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@test/astro-style-prefetch", - "version": "0.0.0", - "private": true, - "dependencies": { - "@astrojs/prefetch": "workspace:*", - "astro": "workspace:*" - } -} diff --git a/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/index.astro b/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/index.astro deleted file mode 100644 index 9b8b84eec184b..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/index.astro +++ /dev/null @@ -1,18 +0,0 @@ ---- ---- - - - - - - - Home - - -

Home

-
    -
  • 1
  • -
  • 2
  • -
- - \ No newline at end of file diff --git a/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/style1.astro b/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/style1.astro deleted file mode 100644 index def02918c9ca3..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/style1.astro +++ /dev/null @@ -1,15 +0,0 @@ ---- ---- - - - - - - - Style1 - - - -

Style1

- - \ No newline at end of file diff --git a/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/style2.astro b/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/style2.astro deleted file mode 100644 index 2e3b6949c771d..0000000000000 --- a/packages/integrations/prefetch/test/fixtures/style-prefetch/src/pages/style2.astro +++ /dev/null @@ -1,15 +0,0 @@ ---- ---- - - - - - - - Style2 - - - -

Style2

- - \ No newline at end of file diff --git a/packages/integrations/prefetch/test/style-prefetch.test.js b/packages/integrations/prefetch/test/style-prefetch.test.js deleted file mode 100644 index b9bb0b04369aa..0000000000000 --- a/packages/integrations/prefetch/test/style-prefetch.test.js +++ /dev/null @@ -1,55 +0,0 @@ -import { expect } from '@playwright/test'; -import { testFactory } from './test-utils.js'; - -const test = testFactory({ root: './fixtures/style-prefetch/' }); - -test.describe('Style prefetch', () => { - test.describe('dev', () => { - let devServer; - - test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); - }); - - test.afterEach(async () => { - await devServer.stop(); - }); - - testPrefetch(); - }); - - test.describe('build', () => { - let previewServer; - - test.beforeAll(async ({ astro }) => { - await astro.build(); - previewServer = await astro.preview(); - }); - - // important: close preview server (free up port and connection) - test.afterAll(async () => { - await previewServer.stop(); - }); - - testPrefetch(); - }); - - function testPrefetch() { - test.describe('prefetches rel="prefetch" links', () => { - test('style fetching', async ({ page, astro }) => { - const requests = []; - - page.on('request', (request) => requests.push(request.url())); - - await page.goto(astro.resolveUrl('/')); - - await page.waitForLoadState('networkidle'); - - await expect(requests.filter((req) => req.includes('/style1'))).toBeTruthy(); - await expect(requests.filter((req) => req.includes('/style2'))).toBeTruthy(); - const cssRequestCount = requests.filter((req) => req.includes('/main.css')).length; - await expect(cssRequestCount).toBe(1); - }); - }); - } -}); diff --git a/packages/integrations/prefetch/test/test-utils.js b/packages/integrations/prefetch/test/test-utils.js deleted file mode 100644 index 0b5de1f9db735..0000000000000 --- a/packages/integrations/prefetch/test/test-utils.js +++ /dev/null @@ -1,30 +0,0 @@ -import { test as testBase } from '@playwright/test'; -import { loadFixture as baseLoadFixture } from '../../../astro/test/test-utils.js'; - -export function loadFixture(inlineConfig) { - if (!inlineConfig?.root) throw new Error("Must provide { root: './fixtures/...' }"); - - // resolve the relative root (i.e. "./fixtures/tailwindcss") to a full filepath - // without this, the main `loadFixture` helper will resolve relative to `packages/astro/test` - return baseLoadFixture({ - ...inlineConfig, - root: new URL(inlineConfig.root, import.meta.url).toString(), - }); -} - -export function testFactory(inlineConfig) { - let fixture; - - const test = testBase.extend({ - astro: async ({}, use) => { - fixture = await loadFixture(inlineConfig); - await use(fixture); - }, - }); - - test.afterEach(() => { - fixture.resetAllFiles(); - }); - - return test; -} diff --git a/packages/integrations/prefetch/tsconfig.json b/packages/integrations/prefetch/tsconfig.json deleted file mode 100644 index dadc37a826de4..0000000000000 --- a/packages/integrations/prefetch/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "include": ["src", "@types"], - "compilerOptions": { - "outDir": "./dist" - } -} diff --git a/packages/integrations/react/CHANGELOG.md b/packages/integrations/react/CHANGELOG.md index 5b127b75337eb..1ba942a77295d 100644 --- a/packages/integrations/react/CHANGELOG.md +++ b/packages/integrations/react/CHANGELOG.md @@ -1,5 +1,23 @@ # @astrojs/react +## 3.0.7 + +### Patch Changes + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +## 3.0.7-beta.0 + +### Patch Changes + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +## 3.0.6 + +### Patch Changes + +- [#9141](https://github.com/withastro/astro/pull/9141) [`af43fb517`](https://github.com/withastro/astro/commit/af43fb51726fa2242cec03cb019fa4fa4a4403ef) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where slotting self-closing elements (img, br, hr) into react components with `experimentalReactChildren` enabled led to an error. + ## 3.0.5 ### Patch Changes diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json index 49d357a946f7c..4ab958bcc4533 100644 --- a/packages/integrations/react/package.json +++ b/packages/integrations/react/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/react", "description": "Use React components within Astro", - "version": "3.0.5", + "version": "3.0.7", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -42,22 +42,24 @@ "scripts": { "build": "astro-scripts build \"src/**/*.ts\" && tsc", "build:ci": "astro-scripts build \"src/**/*.ts\"", - "dev": "astro-scripts dev \"src/**/*.ts\"" + "dev": "astro-scripts dev \"src/**/*.ts\"", + "test": "mocha --exit --timeout 20000" }, "dependencies": { - "@vitejs/plugin-react": "^4.0.4", + "@vitejs/plugin-react": "^4.2.0", "ultrahtml": "^1.3.0" }, "devDependencies": { - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", "cheerio": "1.0.0-rc.12", "react": "^18.1.0", "react-dom": "^18.1.0", - "vite": "^4.4.9" + "vite": "^5.0.0", + "mocha": "^10.2.0" }, "peerDependencies": { "@types/react": "^17.0.50 || ^18.0.21", diff --git a/packages/integrations/react/test/fixtures/react-component/package.json b/packages/integrations/react/test/fixtures/react-component/package.json index cf7b2b057fce8..e7b7ac5d9b5c2 100644 --- a/packages/integrations/react/test/fixtures/react-component/package.json +++ b/packages/integrations/react/test/fixtures/react-component/package.json @@ -8,6 +8,6 @@ "astro": "workspace:*", "react": "^18.1.0", "react-dom": "^18.1.0", - "vue": "^3.3.4" + "vue": "^3.3.8" } } diff --git a/packages/integrations/react/test/parsed-react-children.test.js b/packages/integrations/react/test/parsed-react-children.test.js new file mode 100644 index 0000000000000..1c845836f37f7 --- /dev/null +++ b/packages/integrations/react/test/parsed-react-children.test.js @@ -0,0 +1,15 @@ +import { expect } from 'chai'; +import convert from '../vnode-children.js'; + +describe('experimental react children', () => { + it('has undefined as children for direct children', () => { + const [imgVNode] = convert(''); + expect(imgVNode.props).to.deep.include({ children: undefined }); + }); + + it('has undefined as children for nested children', () => { + const [divVNode] = convert('
'); + const [imgVNode] = divVNode.props.children; + expect(imgVNode.props).to.deep.include({ children: undefined }); + }); +}); diff --git a/packages/integrations/react/vnode-children.js b/packages/integrations/react/vnode-children.js index cc8ec351090c1..0b26ef4239af7 100644 --- a/packages/integrations/react/vnode-children.js +++ b/packages/integrations/react/vnode-children.js @@ -8,24 +8,19 @@ export default function convert(children) { let key = 0; function createReactElementFromNode(node) { - const childVnodes = Array.isArray(node.children) - ? node.children - .map((child) => { - if (child.type === ELEMENT_NODE) { - return createReactElementFromNode(child); - } else if (child.type === TEXT_NODE) { - // 0-length text gets omitted in JSX - return child.value.trim() ? child.value : undefined; - } - }) - .filter((n) => !!n) - : undefined; + const childVnodes = + Array.isArray(node.children) && node.children.length + ? node.children.map((child) => createReactElementFromNode(child)).filter(Boolean) + : undefined; if (node.type === DOCUMENT_NODE) { return createElement(Fragment, {}, childVnodes); } else if (node.type === ELEMENT_NODE) { const { class: className, ...props } = node.attributes; return createElement(node.name, { ...props, className, key: `${id}-${key++}` }, childVnodes); + } else if (node.type === TEXT_NODE) { + // 0-length text gets omitted in JSX + return node.value.trim() ? node.value : undefined; } } diff --git a/packages/integrations/sitemap/src/index.ts b/packages/integrations/sitemap/src/index.ts index 43728b1a3d6bb..79f6f9dfcb073 100644 --- a/packages/integrations/sitemap/src/index.ts +++ b/packages/integrations/sitemap/src/index.ts @@ -1,16 +1,11 @@ import type { AstroConfig, AstroIntegration } from 'astro'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { - EnumChangefreq, - simpleSitemapAndIndex, - type LinkItem as LinkItemBase, - type SitemapItemLoose, -} from 'sitemap'; +import type { EnumChangefreq, LinkItem as LinkItemBase, SitemapItemLoose } from 'sitemap'; +import { simpleSitemapAndIndex } from 'sitemap'; import { ZodError } from 'zod'; import { generateSitemap } from './generate-sitemap.js'; -import { Logger } from './utils/logger.js'; import { validateOptions } from './validate-options.js'; export { EnumChangefreq as ChangeFreqEnum } from 'sitemap'; @@ -62,7 +57,6 @@ function isStatusCodePage(pathname: string): boolean { const createPlugin = (options?: SitemapOptions): AstroIntegration => { let config: AstroConfig; - const logger = new Logger(PKG_NAME); return { name: PKG_NAME, @@ -72,7 +66,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => { config = cfg; }, - 'astro:build:done': async ({ dir, routes, pages }) => { + 'astro:build:done': async ({ dir, routes, pages, logger }) => { try { if (!config.site) { logger.warn( @@ -178,7 +172,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => { limit: entryLimit, gzip: false, }); - logger.success(`\`${OUTFILE}\` created at \`${path.relative(process.cwd(), destDir)}\``); + logger.info(`\`${OUTFILE}\` created at \`${path.relative(process.cwd(), destDir)}\``); } catch (err) { if (err instanceof ZodError) { logger.warn(formatConfigErrorMessage(err)); diff --git a/packages/integrations/sitemap/src/utils/logger.ts b/packages/integrations/sitemap/src/utils/logger.ts deleted file mode 100644 index 3292bbdfc6bba..0000000000000 --- a/packages/integrations/sitemap/src/utils/logger.ts +++ /dev/null @@ -1,46 +0,0 @@ -// @internal -export interface ILogger { - info(msg: string): void; - success(msg: string): void; - warn(msg: string): void; - error(msg: string): void; -} - -// @internal -export class Logger implements ILogger { - private colors = { - reset: '\x1b[0m', - fg: { - red: '\x1b[31m', - green: '\x1b[32m', - yellow: '\x1b[33m', - }, - } as const; - - private packageName: string; - - constructor(packageName: string) { - this.packageName = packageName; - } - - private log(msg: string, prefix = '') { - // eslint-disable-next-line no-console - console.log(`%s${this.packageName}:%s ${msg}\n`, prefix, prefix ? this.colors.reset : ''); - } - - info(msg: string) { - this.log(msg); - } - - success(msg: string) { - this.log(msg, this.colors.fg.green); - } - - warn(msg: string) { - this.log(`Skipped!\n${msg}`, this.colors.fg.yellow); - } - - error(msg: string) { - this.log(`Failed!\n${msg}`, this.colors.fg.red); - } -} diff --git a/packages/integrations/sitemap/test/fixtures/static/src/pages/endpoint.json.ts b/packages/integrations/sitemap/test/fixtures/static/src/pages/endpoint.json.ts index 8f9fa2c90c108..2e088376fb736 100644 --- a/packages/integrations/sitemap/test/fixtures/static/src/pages/endpoint.json.ts +++ b/packages/integrations/sitemap/test/fixtures/static/src/pages/endpoint.json.ts @@ -1,8 +1,6 @@ -export async function get({}) { - return { - body: JSON.stringify({ - name: 'Astro', - url: 'https://astro.build/', - }), - }; +export async function GET({}) { + return Response.json({ + name: 'Astro', + url: 'https://astro.build/', + }); } diff --git a/packages/integrations/solid/package.json b/packages/integrations/solid/package.json index 7e3fcd11b2674..407d5d870625c 100644 --- a/packages/integrations/solid/package.json +++ b/packages/integrations/solid/package.json @@ -40,7 +40,7 @@ "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", - "solid-js": "^1.7.11" + "solid-js": "^1.8.5" }, "peerDependencies": { "solid-js": "^1.4.3" diff --git a/packages/integrations/solid/src/index.ts b/packages/integrations/solid/src/index.ts index 127d9ddb668aa..8707c006f25ad 100644 --- a/packages/integrations/solid/src/index.ts +++ b/packages/integrations/solid/src/index.ts @@ -1,4 +1,4 @@ -import type { AstroIntegration, AstroRenderer } from 'astro'; +import type { AstroConfig, AstroIntegration, AstroRenderer } from 'astro'; import solid, { type Options as ViteSolidPluginOptions } from 'vite-plugin-solid'; async function getViteConfiguration(isDev: boolean, { include, exclude }: Options = {}) { @@ -34,7 +34,7 @@ async function getViteConfiguration(isDev: boolean, { include, exclude }: Option ssr: { external: ['babel-preset-solid'], }, - }; + } satisfies AstroConfig['vite']; } function getRenderer(): AstroRenderer { diff --git a/packages/integrations/svelte/CHANGELOG.md b/packages/integrations/svelte/CHANGELOG.md index 2681a45c0461b..cf253e29089bb 100644 --- a/packages/integrations/svelte/CHANGELOG.md +++ b/packages/integrations/svelte/CHANGELOG.md @@ -1,5 +1,34 @@ # @astrojs/svelte +## 5.0.1 + +### Patch Changes + +- [#9285](https://github.com/withastro/astro/pull/9285) [`1aa7fe85c`](https://github.com/withastro/astro/commit/1aa7fe85c1f18fb22e417a1958270443e94cdc32) Thanks [@bluwy](https://github.com/bluwy)! - When using Svelte 5, slots can now be rendered as snippets + +- [#9366](https://github.com/withastro/astro/pull/9366) [`1b4e91898`](https://github.com/withastro/astro/commit/1b4e91898116f75b02b66ec402385cf44e559118) Thanks [@lilnasy](https://github.com/lilnasy)! - Updates NPM package to refer to the stable Astro version instead of a beta. + +## 5.0.0 + +### Major Changes + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Drops support for Svelte 3 as `@sveltejs/vite-plugin-svelte` is updated to `3.0.0` which does not support Svelte 3 + +## 5.0.0-beta.0 + +### Major Changes + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Drops support for Svelte 3 as `@sveltejs/vite-plugin-svelte` is updated to `3.0.0` which does not support Svelte 3 + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + ## 4.0.4 ### Patch Changes diff --git a/packages/integrations/svelte/client-v5.js b/packages/integrations/svelte/client-v5.js index b3d2e1964eb8e..eaa06974c2423 100644 --- a/packages/integrations/svelte/client-v5.js +++ b/packages/integrations/svelte/client-v5.js @@ -1,4 +1,8 @@ import { mount } from 'svelte'; +import { add_snippet_symbol } from 'svelte/internal'; + +// Allow a slot to be rendered as a snippet (dev validation only) +const tagSlotAsSnippet = import.meta.env.DEV ? add_snippet_symbol : (s) => s; export default (element) => { return async (Component, props, slotted) => { @@ -32,7 +36,7 @@ function createSlotDefinition(key, children) { /** * @param {Comment} $$anchor A comment node for slots in Svelte 5 */ - return ($$anchor, _$$slotProps) => { + const fn = ($$anchor, _$$slotProps) => { const parent = $$anchor.parentNode; const el = document.createElement('div'); el.innerHTML = `${children}`; parent.insertBefore(el.children[0], $$anchor); }; + return tagSlotAsSnippet(fn); } diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 4c7e8bb63486c..11dd8f0f00cb9 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/svelte", - "version": "4.0.4", + "version": "5.0.1", "description": "Use Svelte components within Astro", "type": "module", "types": "./dist/index.d.ts", @@ -42,18 +42,18 @@ "dev": "astro-scripts dev \"src/**/*.ts\"" }, "dependencies": { - "@sveltejs/vite-plugin-svelte": "^2.5.2", - "svelte2tsx": "^0.6.20" + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte2tsx": "^0.6.25" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", - "svelte": "^4.2.0", - "vite": "^4.4.9" + "svelte": "^4.2.5", + "vite": "^5.0.0" }, "peerDependencies": { - "astro": "^3.0.0", - "svelte": "^3.55.0 || ^4.0.0 || ^5.0.0-next.1" + "astro": "^4.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.1" }, "engines": { "node": ">=18.14.1" diff --git a/packages/integrations/svelte/server-v5.js b/packages/integrations/svelte/server-v5.js index 105b843fb1bf0..e1d246ff4e269 100644 --- a/packages/integrations/svelte/server-v5.js +++ b/packages/integrations/svelte/server-v5.js @@ -1,4 +1,8 @@ import { render } from 'svelte/server'; +import { add_snippet_symbol } from 'svelte/internal'; + +// Allow a slot to be rendered as a snippet (dev validation only) +const tagSlotAsSnippet = import.meta.env.DEV ? add_snippet_symbol : (s) => s; function check(Component) { // Svelte 5 generated components always accept these two props @@ -18,10 +22,10 @@ async function renderToStaticMarkup(Component, props, slotted, metadata) { let $$slots = undefined; for (const [key, value] of Object.entries(slotted)) { if (key === 'default') { - children = () => `<${tagName}>${value}`; + children = tagSlotAsSnippet(() => `<${tagName}>${value}`); } else { $$slots ??= {}; - $$slots[key] = () => `<${tagName} name="${key}">${value}`; + $$slots[key] = tagSlotAsSnippet(() => `<${tagName} name="${key}">${value}`); } } diff --git a/packages/integrations/svelte/src/index.ts b/packages/integrations/svelte/src/index.ts index 695214223def4..b894ee623a192 100644 --- a/packages/integrations/svelte/src/index.ts +++ b/packages/integrations/svelte/src/index.ts @@ -73,6 +73,7 @@ async function getViteConfiguration({ } if (!resolvedOptions.preprocess && !(await svelteConfigHasPreprocess(root))) { + // @ts-expect-error there's a bug with the types where the first arg should be optional resolvedOptions.preprocess = vitePreprocess(); } diff --git a/packages/integrations/tailwind/CHANGELOG.md b/packages/integrations/tailwind/CHANGELOG.md index 5810ea59b0104..50e3b07861390 100644 --- a/packages/integrations/tailwind/CHANGELOG.md +++ b/packages/integrations/tailwind/CHANGELOG.md @@ -1,5 +1,20 @@ # @astrojs/tailwind +## 5.0.3 + +### Patch Changes + +- [#9313](https://github.com/withastro/astro/pull/9313) [`2f110a501`](https://github.com/withastro/astro/commit/2f110a501664d9fa8b03814d3fe818956031cfc4) Thanks [@matthewp](https://github.com/matthewp)! - Upgrade for compatibility with Astro 4 + + The Tailwind now supports both Astro 3 and Astro 4. + +## 6.0.0-beta.0 + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + ## 5.0.2 ### Patch Changes diff --git a/packages/integrations/tailwind/package.json b/packages/integrations/tailwind/package.json index d093ffc614e4c..dd3fcd79af498 100644 --- a/packages/integrations/tailwind/package.json +++ b/packages/integrations/tailwind/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/tailwind", "description": "Use Tailwind CSS to style your Astro site", - "version": "5.0.2", + "version": "5.0.3", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -34,16 +34,16 @@ "dependencies": { "autoprefixer": "^10.4.15", "postcss": "^8.4.28", - "postcss-load-config": "^4.0.1" + "postcss-load-config": "^4.0.2" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", - "tailwindcss": "^3.3.3", - "vite": "^4.4.9" + "tailwindcss": "^3.3.5", + "vite": "^5.0.0" }, "peerDependencies": { - "astro": "^3.0.0", + "astro": "^3.0.0 || ^4.0.0", "tailwindcss": "^3.0.24" }, "publishConfig": { diff --git a/packages/integrations/tailwind/src/index.ts b/packages/integrations/tailwind/src/index.ts index daee5f857bcb0..1333665b69803 100644 --- a/packages/integrations/tailwind/src/index.ts +++ b/packages/integrations/tailwind/src/index.ts @@ -1,6 +1,5 @@ import type { AstroIntegration } from 'astro'; import autoprefixerPlugin from 'autoprefixer'; -import type { ResultPlugin } from 'postcss-load-config'; import tailwindPlugin from 'tailwindcss'; import type { CSSOptions, UserConfig } from 'vite'; @@ -33,8 +32,7 @@ async function getViteConfiguration( const postcssOptions = postcssConfigResult?.options ?? {}; const postcssPlugins = postcssConfigResult?.plugins?.slice() ?? []; - // @ts-expect-error Tailwind plugin types are wrong - postcssPlugins.push(tailwindPlugin(tailwindConfigPath) as ResultPlugin); + postcssPlugins.push(tailwindPlugin(tailwindConfigPath)); postcssPlugins.push(autoprefixerPlugin()); return { diff --git a/packages/integrations/vercel/CHANGELOG.md b/packages/integrations/vercel/CHANGELOG.md index 26d26539350ad..8df3a723e530b 100644 --- a/packages/integrations/vercel/CHANGELOG.md +++ b/packages/integrations/vercel/CHANGELOG.md @@ -1,5 +1,64 @@ # @astrojs/vercel +## 6.1.0 + +### Minor Changes + +- [#9413](https://github.com/withastro/astro/pull/9413) [`836ab6214`](https://github.com/withastro/astro/commit/836ab6214e5ef778ef2db2c079f49e87ce70d711) Thanks [@jacobdalamb](https://github.com/jacobdalamb)! - Adds support for Node 20 (currently in `beta` on Vercel). + +### Patch Changes + +- [#9289](https://github.com/withastro/astro/pull/9289) [`8aeb0b579`](https://github.com/withastro/astro/commit/8aeb0b5797853c2eee7630b572d6abc503d59c6f) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where dots in redirects were incorrectly handled. + +## 6.0.2 + +### Patch Changes + +- [#9287](https://github.com/withastro/astro/pull/9287) [`1e342e34e`](https://github.com/withastro/astro/commit/1e342e34eb9cef465b838654cea7bb4b0d24e602) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where redirects did not work with the static adapter. + +- [#9383](https://github.com/withastro/astro/pull/9383) [`bebf5cf22`](https://github.com/withastro/astro/commit/bebf5cf22d0d842670825aa961529e8b342e2b26) Thanks [@sarah11918](https://github.com/sarah11918)! - Fixes some incorrect code examples in the README documentation. + +- [#9334](https://github.com/withastro/astro/pull/9334) [`dfbc70790`](https://github.com/withastro/astro/commit/dfbc7079081d3346713cb536358a3854362a2c95) Thanks [@Geo25rey](https://github.com/Geo25rey)! - Allows the edge middleware to be an async function. + +## 6.0.1 + +### Patch Changes + +- [#9348](https://github.com/withastro/astro/pull/9348) [`1685cc42b`](https://github.com/withastro/astro/commit/1685cc42b51603eb98b5ba3e072cf2d3953339f2) Thanks [@matthewp](https://github.com/matthewp)! - Uses the latest astro as the peerDependency + +## 6.0.0 + +### Major Changes + +- [#9199](https://github.com/withastro/astro/pull/9199) [`49aa215a0`](https://github.com/withastro/astro/commit/49aa215a01ee1c4805316c85bb0aea6cfbc25a31) Thanks [@lilnasy](https://github.com/lilnasy)! - The internals of the integration have been updated to support Astro 4.0. Make sure to upgrade your Astro version as Astro 3.0 is no longer supported. + +- [#9184](https://github.com/withastro/astro/pull/9184) [`a145ac07e`](https://github.com/withastro/astro/commit/a145ac07e75927e13af62e28d13bc8217a362b8e) Thanks [@bluwy](https://github.com/bluwy)! - Removes deprecated `analytics` option. Use the `webAnalytics` option instead. + +- [#9263](https://github.com/withastro/astro/pull/9263) [`3cbd8ea75`](https://github.com/withastro/astro/commit/3cbd8ea7534910e3beae396dcfa93ce87dcdd91f) Thanks [@bluwy](https://github.com/bluwy)! - Removes the deprecated `@astrojs/vercel/edge` export. You should use `@astrojs/vercel/serverless` instead with the `edgeMiddleware` option. + +## 6.0.0-beta.2 + +### Major Changes + +- [#9263](https://github.com/withastro/astro/pull/9263) [`3cbd8ea75`](https://github.com/withastro/astro/commit/3cbd8ea7534910e3beae396dcfa93ce87dcdd91f) Thanks [@bluwy](https://github.com/bluwy)! - Removes the deprecated `@astrojs/vercel/edge` export. You should use `@astrojs/vercel/serverless` instead with the `edgeMiddleware` option. + +## 6.0.0-beta.1 + +### Major Changes + +- [#9199](https://github.com/withastro/astro/pull/9199) [`49aa215a0`](https://github.com/withastro/astro/commit/49aa215a01ee1c4805316c85bb0aea6cfbc25a31) Thanks [@lilnasy](https://github.com/lilnasy)! - The internals of the integration have been updated to support Astro 4.0. Make sure to upgrade your Astro version as Astro 3.0 is no longer supported. + +## 6.0.0-beta.0 + +### Major Changes + +- [#9184](https://github.com/withastro/astro/pull/9184) [`a145ac07e`](https://github.com/withastro/astro/commit/a145ac07e75927e13af62e28d13bc8217a362b8e) Thanks [@bluwy](https://github.com/bluwy)! - Removes deprecated `analytics` option. Use the `webAnalytics` option instead. + +### Patch Changes + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + ## 5.2.0 ### Minor Changes diff --git a/packages/integrations/vercel/README.md b/packages/integrations/vercel/README.md index bad219b98c89a..9c80eae4bcb77 100644 --- a/packages/integrations/vercel/README.md +++ b/packages/integrations/vercel/README.md @@ -88,7 +88,7 @@ To configure this adapter, pass an object to the `vercel()` function call in `as ### Web Analytics **Type:** `VercelWebAnalyticsConfig`
-**Available for:** Serverless, Edge, Static
+**Available for:** Serverless, Static
**Added in:** `@astrojs/vercel@3.8.0` You can enable [Vercel Web Analytics](https://vercel.com/docs/concepts/analytics) by setting `webAnalytics: { enabled: true }`. This will inject Vercel’s tracking scripts into all of your pages. @@ -113,7 +113,7 @@ export default defineConfig({ You can enable [Vercel Speed Insights](https://vercel.com/docs/concepts/speed-insights) by setting `speedInsights: { enabled: true }`. This will collect and send Web Vital data to Vercel. **Type:** `VercelSpeedInsightsConfig`
-**Available for:** Serverless, Edge, Static
+**Available for:** Serverless, Static
**Added in:** `@astrojs/vercel@3.8.0` ```js @@ -147,7 +147,7 @@ import { defineConfig } from 'astro/config'; import vercel from '@astrojs/vercel/static'; export default defineConfig({ - output: 'server', + output: 'static', adapter: vercel({ imagesConfig: { sizes: [320, 640, 1280], @@ -170,7 +170,7 @@ import { defineConfig } from 'astro/config'; import vercel from '@astrojs/vercel/static'; export default defineConfig({ - output: 'server', + output: 'static', adapter: vercel({ imageService: true, }), @@ -401,6 +401,12 @@ When you opt in to this feature, there are few constraints to note: - Only `request` and `context` may be used to produce an `Astro.locals` object. Operations like redirects, etc. should be delegated to Astro middleware. - `Astro.locals` **must be serializable**. Failing to do so will result in a **runtime error**. This means that you **cannot** store complex types like `Map`, `function`, `Set`, etc. +### Node.js Version Support + +The `@astrojs/vercel` adapter supports specific Node.js versions for deploying your Astro project on Vercel. To view the supported Node.js versions on Vercel, click on the settings tab for a project and scroll down to "Node.js Version" section. + +Check out the [Vercel documentation](https://vercel.com/docs/functions/serverless-functions/runtimes/node-js#default-and-available-versions) to learn more. + ## Troubleshooting **A few known complex packages (example: [puppeteer](https://github.com/puppeteer/puppeteer)) do not support bundling and therefore will not work properly with this adapter.** By default, Vercel doesn't include npm installed files & packages from your project's `./node_modules` folder. To address this, the `@astrojs/vercel` adapter automatically bundles your final build output using `esbuild`. diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json index dc9433c5a64dc..bd2071508ff36 100644 --- a/packages/integrations/vercel/package.json +++ b/packages/integrations/vercel/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/vercel", "description": "Deploy your site to Vercel", - "version": "5.2.0", + "version": "6.1.0", "type": "module", "author": "withastro", "license": "MIT", @@ -17,8 +17,6 @@ "bugs": "https://github.com/withastro/astro/issues", "homepage": "https://docs.astro.build/en/guides/integrations-guide/vercel/", "exports": { - "./edge": "./dist/edge/throw.js", - "./edge/entrypoint": "./dist/edge/throw.js", "./serverless": "./dist/serverless/adapter.js", "./serverless/entrypoint": "./dist/serverless/entrypoint.js", "./static": "./dist/static/adapter.js", @@ -54,18 +52,18 @@ "dependencies": { "@astrojs/internal-helpers": "workspace:*", "@vercel/analytics": "^1.0.2", - "@vercel/nft": "^0.23.1", - "esbuild": "^0.19.2", - "fast-glob": "^3.3.1", + "@vercel/nft": "^0.24.3", + "esbuild": "^0.19.6", + "fast-glob": "^3.3.2", "set-cookie-parser": "^2.6.0", "web-vitals": "^3.4.0" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^4.0.2" }, "devDependencies": { - "@types/set-cookie-parser": "^2.4.3", - "@vercel/edge": "^1.0.0", + "@types/set-cookie-parser": "^2.4.6", + "@vercel/edge": "^1.1.1", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", diff --git a/packages/integrations/vercel/src/edge/throw.ts b/packages/integrations/vercel/src/edge/throw.ts deleted file mode 100644 index 5041370e06bb1..0000000000000 --- a/packages/integrations/vercel/src/edge/throw.ts +++ /dev/null @@ -1,18 +0,0 @@ -const msg = ` -The Astro Vercel Edge adapter has been removed. We recommend switching to @astrojs/vercel/serverless and enabling Edge middleware. - -import { defineConfig } from 'astro/config'; -import vercel from '@astrojs/vercel/serverless'; - -export default defineConfig({ - output: 'server', - adapter: vercel({ - edgeMiddleware: true, - }) -}) -`.trim(); - -throw new Error(msg); - -// Make sure bundlers treat this as ESM. -export default {}; diff --git a/packages/integrations/vercel/src/lib/redirects.ts b/packages/integrations/vercel/src/lib/redirects.ts index 8613be2ed72db..46c97d3496915 100644 --- a/packages/integrations/vercel/src/lib/redirects.ts +++ b/packages/integrations/vercel/src/lib/redirects.ts @@ -21,23 +21,22 @@ function getMatchPattern(segments: RoutePart[][]) { .map((segment) => { return segment[0].spread ? '(?:\\/(.*?))?' - : '\\/' + - segment - .map((part) => { - if (part) - return part.dynamic - ? '([^/]+?)' - : part.content - .normalize() - .replace(/\?/g, '%3F') - .replace(/#/g, '%23') - .replace(/%5B/g, '[') - .replace(/%5D/g, ']') - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - }) - .join(''); + : segment + .map((part) => { + if (part) + return part.dynamic + ? '([^/]+?)' + : part.content + .normalize() + .replace(/\?/g, '%3F') + .replace(/#/g, '%23') + .replace(/%5B/g, '[') + .replace(/%5D/g, ']') + .replace(/[*+?^${}()|[\]\\]/g, '\\$&'); + }) + .join(''); }) - .join(''); + .join('/'); } function getReplacePattern(segments: RoutePart[][]) { diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index 621849688ff3c..26e33663a7522 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -35,11 +35,11 @@ export const VERCEL_EDGE_MIDDLEWARE_FILE = 'vercel-edge-middleware'; // https://vercel.com/docs/concepts/functions/serverless-functions/runtimes/node-js#node.js-version const SUPPORTED_NODE_VERSIONS: Record< string, - { status: 'current' } | { status: 'deprecated'; removal: Date } + { status: 'current' } | { status: 'beta' } | { status: 'deprecated'; removal: Date } > = { - 14: { status: 'deprecated', removal: new Date('August 15 2023') }, 16: { status: 'deprecated', removal: new Date('February 6 2024') }, 18: { status: 'current' }, + 20: { status: 'beta' }, }; function getAdapter({ @@ -71,11 +71,6 @@ function getAdapter({ } export interface VercelServerlessConfig { - /** - * @deprecated - */ - analytics?: boolean; - /** Configuration for [Vercel Web Analytics](https://vercel.com/docs/concepts/analytics). */ webAnalytics?: VercelWebAnalyticsConfig; @@ -108,7 +103,6 @@ export interface VercelServerlessConfig { } export default function vercelServerless({ - analytics, webAnalytics, speedInsights, includeFiles, @@ -151,13 +145,7 @@ export default function vercelServerless({ ); } - if (webAnalytics?.enabled || analytics) { - if (analytics) { - logger.warn( - `The \`analytics\` property is deprecated. Please use the new \`webAnalytics\` and \`speedInsights\` properties instead.` - ); - } - + if (webAnalytics?.enabled) { injectScript( 'head-inline', await getInjectableWebAnalyticsContent({ @@ -165,7 +153,7 @@ export default function vercelServerless({ }) ); } - if (command === 'build' && (speedInsights?.enabled || analytics)) { + if (command === 'build' && speedInsights?.enabled) { injectScript('page', 'import "@astrojs/vercel/speed-insights"'); } const outDir = getVercelOutput(config.root); @@ -178,7 +166,7 @@ export default function vercelServerless({ redirects: false, }, vite: { - ...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics), + ...getSpeedInsightsViteConfig(speedInsights?.enabled), ssr: { external: ['@vercel/nft'], }, @@ -389,6 +377,13 @@ function validateRuntime() { const version = process.version.slice(1); // 'v16.5.0' --> '16.5.0' const major = version.split('.')[0]; // '16.5.0' --> '16' const support = SUPPORTED_NODE_VERSIONS[major]; + if (support.status === 'beta') { + console.warn( + `[${PACKAGE_NAME}] The local Node.js version (${major}) is currently in beta for Vercel Serverless Functions.` + ); + console.warn(`[${PACKAGE_NAME}] Make sure to update your Vercel settings to use ${major}.`); + return; + } if (support === undefined) { console.warn( `[${PACKAGE_NAME}] The local Node.js version (${major}) is not supported by Vercel Serverless Functions.` diff --git a/packages/integrations/vercel/src/serverless/entrypoint.ts b/packages/integrations/vercel/src/serverless/entrypoint.ts index 7b548dc37bfac..513c34640af62 100644 --- a/packages/integrations/vercel/src/serverless/entrypoint.ts +++ b/packages/integrations/vercel/src/serverless/entrypoint.ts @@ -29,7 +29,7 @@ export const createExports = (manifest: SSRManifest) => { locals = JSON.parse(localsAsString); } } - await setResponse(app, res, await app.render(request, routeData, locals)); + await setResponse(app, res, await app.render(request, { routeData, locals })); }; return { default: handler }; diff --git a/packages/integrations/vercel/src/serverless/middleware.ts b/packages/integrations/vercel/src/serverless/middleware.ts index a2e44722b20d0..b3ada80d15bf4 100644 --- a/packages/integrations/vercel/src/serverless/middleware.ts +++ b/packages/integrations/vercel/src/serverless/middleware.ts @@ -53,7 +53,7 @@ function edgeMiddlewareTemplate(middlewarePath: string, vercelEdgeMiddlewareHand if (existsSync(filePathEdgeMiddleware + '.js') || existsSync(filePathEdgeMiddleware + '.ts')) { const stringified = JSON.stringify(filePathEdgeMiddleware.replace(/\\/g, '/')); handlerTemplateImport = `import handler from ${stringified}`; - handlerTemplateCall = `handler({ request, context })`; + handlerTemplateCall = `await handler({ request, context })`; } else { } return ` diff --git a/packages/integrations/vercel/src/static/adapter.ts b/packages/integrations/vercel/src/static/adapter.ts index df2995c372ade..80b42b95d2674 100644 --- a/packages/integrations/vercel/src/static/adapter.ts +++ b/packages/integrations/vercel/src/static/adapter.ts @@ -41,10 +41,6 @@ function getAdapter(): AstroAdapter { } export interface VercelStaticConfig { - /** - * @deprecated - */ - analytics?: boolean; webAnalytics?: VercelWebAnalyticsConfig; speedInsights?: VercelSpeedInsightsConfig; imageService?: boolean; @@ -53,7 +49,6 @@ export interface VercelStaticConfig { } export default function vercelStatic({ - analytics, webAnalytics, speedInsights, imageService, @@ -65,14 +60,8 @@ export default function vercelStatic({ return { name: '@astrojs/vercel', hooks: { - 'astro:config:setup': async ({ command, config, injectScript, updateConfig, logger }) => { - if (webAnalytics?.enabled || analytics) { - if (analytics) { - logger.warn( - `The \`analytics\` property is deprecated. Please use the new \`webAnalytics\` and \`speedInsights\` properties instead.` - ); - } - + 'astro:config:setup': async ({ command, config, injectScript, updateConfig }) => { + if (webAnalytics?.enabled) { injectScript( 'head-inline', await getInjectableWebAnalyticsContent({ @@ -80,7 +69,7 @@ export default function vercelStatic({ }) ); } - if (command === 'build' && (speedInsights?.enabled || analytics)) { + if (command === 'build' && speedInsights?.enabled) { injectScript('page', 'import "@astrojs/vercel/speed-insights"'); } const outDir = new URL('./static/', getVercelOutput(config.root)); @@ -91,7 +80,7 @@ export default function vercelStatic({ redirects: false, }, vite: { - ...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics), + ...getSpeedInsightsViteConfig(speedInsights?.enabled), }, ...getAstroImageConfig( imageService, diff --git a/packages/integrations/vercel/test/redirects.test.js b/packages/integrations/vercel/test/redirects.test.js index df17664eec6e1..795529ece9de7 100644 --- a/packages/integrations/vercel/test/redirects.test.js +++ b/packages/integrations/vercel/test/redirects.test.js @@ -16,6 +16,7 @@ describe('Redirects', () => { destination: '/', }, '/blog/[...slug]': '/team/articles/[...slug]', + '/Basic/http-2-0.html': '/posts/http2', }, trailingSlash: 'always', }); @@ -32,23 +33,32 @@ describe('Redirects', () => { it('define static routes', async () => { const config = await getConfig(); - const oneRoute = config.routes.find((r) => r.src === '/\\/one'); + const oneRoute = config.routes.find((r) => r.src === '/one'); expect(oneRoute.headers.Location).to.equal('/'); expect(oneRoute.status).to.equal(301); - const twoRoute = config.routes.find((r) => r.src === '/\\/two'); + const twoRoute = config.routes.find((r) => r.src === '/two'); expect(twoRoute.headers.Location).to.equal('/'); expect(twoRoute.status).to.equal(301); - const threeRoute = config.routes.find((r) => r.src === '/\\/three'); + const threeRoute = config.routes.find((r) => r.src === '/three'); expect(threeRoute.headers.Location).to.equal('/'); expect(threeRoute.status).to.equal(302); }); + it('define redirects for static files', async () => { + const config = await getConfig(); + + const staticRoute = config.routes.find((r) => r.src === '/Basic/http-2-0.html'); + expect(staticRoute).to.not.be.undefined; + expect(staticRoute.headers.Location).to.equal('/posts/http2'); + expect(staticRoute.status).to.equal(301); + }); + it('defines dynamic routes', async () => { const config = await getConfig(); - const blogRoute = config.routes.find((r) => r.src.startsWith('/\\/blog')); + const blogRoute = config.routes.find((r) => r.src.startsWith('/blog')); expect(blogRoute).to.not.be.undefined; expect(blogRoute.headers.Location.startsWith('/team/articles')).to.equal(true); expect(blogRoute.status).to.equal(301); @@ -57,7 +67,7 @@ describe('Redirects', () => { it('define trailingSlash redirect for sub pages', async () => { const config = await getConfig(); - const subpathRoute = config.routes.find((r) => r.src === '/\\/subpage'); + const subpathRoute = config.routes.find((r) => r.src === '/subpage'); expect(subpathRoute).to.not.be.undefined; expect(subpathRoute.headers.Location).to.equal('/subpage/'); }); diff --git a/packages/integrations/vue/CHANGELOG.md b/packages/integrations/vue/CHANGELOG.md index fc54ae2ea9d3e..8377a7e84eb3f 100644 --- a/packages/integrations/vue/CHANGELOG.md +++ b/packages/integrations/vue/CHANGELOG.md @@ -1,5 +1,38 @@ # @astrojs/vue +## 4.0.3 + +### Patch Changes + +- [#9366](https://github.com/withastro/astro/pull/9366) [`1b4e91898`](https://github.com/withastro/astro/commit/1b4e91898116f75b02b66ec402385cf44e559118) Thanks [@lilnasy](https://github.com/lilnasy)! - Updates NPM package to refer to the stable Astro version instead of a beta. + +## 4.0.2 + +### Patch Changes + +- [#9333](https://github.com/withastro/astro/pull/9333) [`b832cd190`](https://github.com/withastro/astro/commit/b832cd190199d4269d25d5d6e6b7efb399a69070) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Fixes issue with `appEntrypoint` when running `astro dev` + +## 4.0.1 + +### Patch Changes + +- [#8794](https://github.com/withastro/astro/pull/8794) [`4d4e34d45`](https://github.com/withastro/astro/commit/4d4e34d451e351f8a52e04124027850a575ba752) Thanks [@yoyo837](https://github.com/yoyo837)! - Prevents Astro from crashing when no default function is exported from the `appEntrypoint`. Now, the entrypoint will be ignored with a warning instead. + +## 4.0.0 + +### Patch Changes + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +## 4.0.0-beta.0 + +### Patch Changes + +- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + ## 3.0.4 ### Patch Changes diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index b8fa62d381ccf..5435447d98abf 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/vue", - "version": "3.0.4", + "version": "4.0.3", "description": "Use Vue components within Astro", "type": "module", "types": "./dist/index.d.ts", @@ -40,24 +40,24 @@ "test": "mocha --timeout 20000" }, "dependencies": { - "@vitejs/plugin-vue": "^4.3.3", - "@vitejs/plugin-vue-jsx": "^3.0.2", + "@vitejs/plugin-vue": "^4.5.0", + "@vitejs/plugin-vue-jsx": "^3.1.0", "@vue/babel-plugin-jsx": "^1.1.5", - "@vue/compiler-sfc": "^3.3.4" + "@vue/compiler-sfc": "^3.3.8" }, "devDependencies": { - "@types/chai": "^4.3.5", + "@types/chai": "^4.3.10", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", - "linkedom": "^0.15.1", "cheerio": "1.0.0-rc.12", + "linkedom": "^0.16.4", "mocha": "^10.2.0", - "vite": "^4.4.9", - "vue": "^3.3.4" + "vite": "^5.0.0", + "vue": "^3.3.8" }, "peerDependencies": { - "astro": "^3.0.0", + "astro": "^4.0.0", "vue": "^3.2.30" }, "engines": { diff --git a/packages/integrations/vue/src/index.ts b/packages/integrations/vue/src/index.ts index 2c234952b6932..ef35055877d7a 100644 --- a/packages/integrations/vue/src/index.ts +++ b/packages/integrations/vue/src/index.ts @@ -1,14 +1,21 @@ import type { Options as VueOptions } from '@vitejs/plugin-vue'; -import vue from '@vitejs/plugin-vue'; import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx'; -import type { AstroIntegration, AstroRenderer } from 'astro'; -import type { UserConfig } from 'vite'; +import type { AstroIntegration, AstroIntegrationLogger, AstroRenderer } from 'astro'; +import type { UserConfig, Plugin } from 'vite'; + +import { fileURLToPath } from 'node:url'; +import vue from '@vitejs/plugin-vue'; interface Options extends VueOptions { jsx?: boolean | VueJsxOptions; appEntrypoint?: string; } +interface ViteOptions extends Options { + root: URL; + logger: AstroIntegrationLogger; +} + function getRenderer(): AstroRenderer { return { name: '@astrojs/vue', @@ -32,28 +39,71 @@ function getJsxRenderer(): AstroRenderer { }; } -function virtualAppEntrypoint(options?: Options) { +function virtualAppEntrypoint(options: ViteOptions) { const virtualModuleId = 'virtual:@astrojs/vue/app'; const resolvedVirtualModuleId = '\0' + virtualModuleId; + let getExports: (id: string) => Promise; return { name: '@astrojs/vue/virtual-app', + buildStart() { + if (!getExports) { + getExports = async (id: string) => { + const info = await this.load.call(this, { id }); + return info.exports ?? []; + }; + } + }, + configureServer(server) { + if (!getExports) { + getExports = async (id: string) => { + const mod = await server.ssrLoadModule(id); + return Object.keys(mod) ?? []; + }; + } + }, resolveId(id: string) { if (id == virtualModuleId) { return resolvedVirtualModuleId; } }, - load(id: string) { + async load(id: string) { + const noop = `export const setup = (app) => app;`; if (id === resolvedVirtualModuleId) { - if (options?.appEntrypoint) { - return `export { default as setup } from "${options.appEntrypoint}";`; + if (options.appEntrypoint) { + try { + let resolved; + if (options.appEntrypoint.startsWith('.')) { + resolved = await this.resolve( + fileURLToPath(new URL(options.appEntrypoint, options.root)) + ); + } else { + resolved = await this.resolve(options.appEntrypoint, fileURLToPath(options.root)); + } + if (!resolved) { + // This error is handled below, the message isn't shown to the user + throw new Error('Unable to resolve appEntrypoint'); + } + const exports = await getExports(resolved.id); + if (!exports.includes('default')) { + options.logger.warn( + `appEntrypoint \`${options.appEntrypoint}\` does not export a default function. Check out https://docs.astro.build/en/guides/integrations-guide/vue/#appentrypoint.` + ); + return noop; + } + return `export { default as setup } from "${resolved.id}";`; + } catch { + options.logger.warn( + `Unable to resolve appEntrypoint \`${options.appEntrypoint}\`. Does the file exist?` + ); + } } - return `export const setup = () => {};`; + return noop; } }, - }; + } satisfies Plugin; } -async function getViteConfiguration(options?: Options): Promise { +async function getViteConfiguration(options: ViteOptions): Promise { const config: UserConfig = { optimizeDeps: { include: ['@astrojs/vue/client.js', 'vue'], @@ -79,12 +129,14 @@ export default function (options?: Options): AstroIntegration { return { name: '@astrojs/vue', hooks: { - 'astro:config:setup': async ({ addRenderer, updateConfig }) => { + 'astro:config:setup': async ({ addRenderer, updateConfig, config, logger }) => { addRenderer(getRenderer()); if (options?.jsx) { addRenderer(getJsxRenderer()); } - updateConfig({ vite: await getViteConfiguration(options) }); + updateConfig({ + vite: await getViteConfiguration({ ...options, root: config.root, logger }), + }); }, }, }; diff --git a/packages/integrations/vue/test/app-entrypoint.test.js b/packages/integrations/vue/test/app-entrypoint.test.js index b20e7be7e33c8..3a374be1c287f 100644 --- a/packages/integrations/vue/test/app-entrypoint.test.js +++ b/packages/integrations/vue/test/app-entrypoint.test.js @@ -51,3 +51,137 @@ describe('App Entrypoint', () => { expect(client).not.to.be.undefined; }); }); + +describe('App Entrypoint no export default (dev)', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + let devServer; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/app-entrypoint-no-export-default/', + }); + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('loads during SSR', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + const { document } = parseHTML(html); + const bar = document.querySelector('#foo > #bar'); + expect(bar).not.to.be.undefined; + expect(bar.textContent).to.eq('works'); + }); + + it('loads svg components without transforming them to assets', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + const { document } = parseHTML(html); + const client = document.querySelector('astro-island svg'); + + expect(client).not.to.be.undefined; + }); +}); + +describe('App Entrypoint no export default', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/app-entrypoint-no-export-default/', + }); + await fixture.build(); + }); + + it('loads during SSR', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const bar = document.querySelector('#foo > #bar'); + expect(bar).not.to.be.undefined; + expect(bar.textContent).to.eq('works'); + }); + + it('component not included in renderer bundle', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const island = document.querySelector('astro-island'); + const client = island.getAttribute('renderer-url'); + expect(client).not.to.be.undefined; + + const js = await fixture.readFile(client); + expect(js).not.to.match(/\w+\.component\(\"Bar\"/gm); + }); + + it('loads svg components without transforming them to assets', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const client = document.querySelector('astro-island svg'); + + expect(client).not.to.be.undefined; + }); +}); + +describe('App Entrypoint relative', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/app-entrypoint-relative/', + }); + await fixture.build(); + }); + + it('loads during SSR', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const bar = document.querySelector('#foo > #bar'); + expect(bar).not.to.be.undefined; + expect(bar.textContent).to.eq('works'); + }); + + it('component not included in renderer bundle', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const island = document.querySelector('astro-island'); + const client = island.getAttribute('renderer-url'); + expect(client).not.to.be.undefined; + + const js = await fixture.readFile(client); + expect(js).not.to.match(/\w+\.component\(\"Bar\"/gm); + }); +}); + +describe('App Entrypoint /src/absolute', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/app-entrypoint-src-absolute/', + }); + await fixture.build(); + }); + + it('loads during SSR', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const bar = document.querySelector('#foo > #bar'); + expect(bar).not.to.be.undefined; + expect(bar.textContent).to.eq('works'); + }); + + it('component not included in renderer bundle', async () => { + const data = await fixture.readFile('/index.html'); + const { document } = parseHTML(data); + const island = document.querySelector('astro-island'); + const client = island.getAttribute('renderer-url'); + expect(client).not.to.be.undefined; + + const js = await fixture.readFile(client); + expect(js).not.to.match(/\w+\.component\(\"Bar\"/gm); + }); +}); diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/astro.config.mjs b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/astro.config.mjs new file mode 100644 index 0000000000000..fa04f9c8b5921 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/astro.config.mjs @@ -0,0 +1,14 @@ +import { defineConfig } from 'astro/config'; +import vue from '@astrojs/vue'; +import ViteSvgLoader from 'vite-svg-loader' + +export default defineConfig({ + integrations: [vue({ + appEntrypoint: '/src/pages/_app' + })], + vite: { + plugins: [ + ViteSvgLoader(), + ], + }, +}) diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json new file mode 100644 index 0000000000000..29ab3c34264cf --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json @@ -0,0 +1,13 @@ +{ + "name": "@test/vue-app-entrypoint-no-export-default", + "version": "0.0.0", + "private": true, + "scripts": { + "astro": "astro" + }, + "dependencies": { + "@astrojs/vue": "workspace:*", + "astro": "workspace:*", + "vite-svg-loader": "4.0.0" + } +} diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Bar.vue b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Bar.vue new file mode 100644 index 0000000000000..9e690ea06adc6 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Bar.vue @@ -0,0 +1,3 @@ + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Circle.svg b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Circle.svg new file mode 100644 index 0000000000000..cf2bd92fc1353 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Foo.vue b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Foo.vue new file mode 100644 index 0000000000000..7f6808477f18b --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/components/Foo.vue @@ -0,0 +1,11 @@ + + + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/pages/_app.ts b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/pages/_app.ts new file mode 100644 index 0000000000000..2fc8bde52d689 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/pages/_app.ts @@ -0,0 +1,3 @@ +export const setup = () => {} + +// no default export diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/pages/index.astro b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/pages/index.astro new file mode 100644 index 0000000000000..3240cbe0fd73a --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/src/pages/index.astro @@ -0,0 +1,12 @@ +--- +import Foo from '../components/Foo.vue'; +--- + + + + Vue App Entrypoint + + + + + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/astro.config.mjs b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/astro.config.mjs new file mode 100644 index 0000000000000..acafc8270a9d3 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/astro.config.mjs @@ -0,0 +1,8 @@ +import { defineConfig } from 'astro/config'; +import vue from '@astrojs/vue'; + +export default defineConfig({ + integrations: [vue({ + appEntrypoint: './src/vue.ts' + })] +}) diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/package.json new file mode 100644 index 0000000000000..80483c7c6ce8a --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/package.json @@ -0,0 +1,12 @@ +{ + "name": "@test/vue-app-entrypoint-relative", + "version": "0.0.0", + "private": true, + "scripts": { + "astro": "astro" + }, + "dependencies": { + "@astrojs/vue": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Bar.vue b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Bar.vue new file mode 100644 index 0000000000000..9e690ea06adc6 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Bar.vue @@ -0,0 +1,3 @@ + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Circle.svg b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Circle.svg new file mode 100644 index 0000000000000..cf2bd92fc1353 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Foo.vue b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Foo.vue new file mode 100644 index 0000000000000..7f6808477f18b --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/components/Foo.vue @@ -0,0 +1,11 @@ + + + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/pages/index.astro b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/pages/index.astro new file mode 100644 index 0000000000000..3240cbe0fd73a --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/pages/index.astro @@ -0,0 +1,12 @@ +--- +import Foo from '../components/Foo.vue'; +--- + + + + Vue App Entrypoint + + + + + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/vue.ts b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/vue.ts new file mode 100644 index 0000000000000..ead516c976e9b --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-relative/src/vue.ts @@ -0,0 +1 @@ +export default () => {} diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/astro.config.mjs b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/astro.config.mjs new file mode 100644 index 0000000000000..6eae678920512 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/astro.config.mjs @@ -0,0 +1,8 @@ +import { defineConfig } from 'astro/config'; +import vue from '@astrojs/vue'; + +export default defineConfig({ + integrations: [vue({ + appEntrypoint: '/src/vue.ts' + })] +}) diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/package.json new file mode 100644 index 0000000000000..244f9120c8251 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/package.json @@ -0,0 +1,12 @@ +{ + "name": "@test/vue-app-entrypoint-src-absolute", + "version": "0.0.0", + "private": true, + "scripts": { + "astro": "astro" + }, + "dependencies": { + "@astrojs/vue": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Bar.vue b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Bar.vue new file mode 100644 index 0000000000000..9e690ea06adc6 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Bar.vue @@ -0,0 +1,3 @@ + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Circle.svg b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Circle.svg new file mode 100644 index 0000000000000..cf2bd92fc1353 --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Foo.vue b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Foo.vue new file mode 100644 index 0000000000000..7f6808477f18b --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/components/Foo.vue @@ -0,0 +1,11 @@ + + + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/pages/index.astro b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/pages/index.astro new file mode 100644 index 0000000000000..3240cbe0fd73a --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/pages/index.astro @@ -0,0 +1,12 @@ +--- +import Foo from '../components/Foo.vue'; +--- + + + + Vue App Entrypoint + + + + + diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/vue.ts b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/vue.ts new file mode 100644 index 0000000000000..ead516c976e9b --- /dev/null +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute/src/vue.ts @@ -0,0 +1 @@ +export default () => {} diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint/package.json index abdab9e4cbf7b..0795ba955af36 100644 --- a/packages/integrations/vue/test/fixtures/app-entrypoint/package.json +++ b/packages/integrations/vue/test/fixtures/app-entrypoint/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "astro": "workspace:*", "@astrojs/vue": "workspace:*", - "vite-svg-loader": "4.0.0" + "astro": "workspace:*", + "vite-svg-loader": "5.0.1" } } \ No newline at end of file diff --git a/packages/markdown/remark/CHANGELOG.md b/packages/markdown/remark/CHANGELOG.md index 54510d68c4263..6a53750b4a03e 100644 --- a/packages/markdown/remark/CHANGELOG.md +++ b/packages/markdown/remark/CHANGELOG.md @@ -1,5 +1,42 @@ # @astrojs/markdown-remark +## 4.0.1 + +### Patch Changes + +- [#9349](https://github.com/withastro/astro/pull/9349) [`270c6cc27`](https://github.com/withastro/astro/commit/270c6cc27f20995883fcdabbff9b56d7f041f9e4) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixes an issue where this package could not be installed alongside Astro 4.0. + +## 4.0.0 + +### Major Changes + +- [#9138](https://github.com/withastro/astro/pull/9138) [`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3) Thanks [@bluwy](https://github.com/bluwy)! - Updates the unified, remark, and rehype dependencies to latest. Make sure to update your custom remark and rehype plugins as well to be compatible with the latest versions. + + **Potentially breaking change:** The default value of `markdown.remarkRehype.footnoteBackLabel` is changed from `"Back to content"` to `"Back to reference 1"`. See the `mdast-util-to-hast` [commit](https://github.com/syntax-tree/mdast-util-to-hast/commit/56c88e45690be138fad9f0bf367b939d09816863) for more information. + +- [#9182](https://github.com/withastro/astro/pull/9182) [`c7953645e`](https://github.com/withastro/astro/commit/c7953645eeaaf9e87c6db4494b0023d2c1878ff0) Thanks [@bluwy](https://github.com/bluwy)! - Removes deprecated APIs. All Astro packages had been refactored to not use these APIs. + +### Patch Changes + +- [#9147](https://github.com/withastro/astro/pull/9147) [`addb57c8e`](https://github.com/withastro/astro/commit/addb57c8e80b7b67ec61224666f3a1db5c44410c) Thanks [@bluwy](https://github.com/bluwy)! - Fixes `RemarkRehype` type's `handler` and `handlers` properties + +## 4.0.0-beta.0 + +### Major Changes + +- [#9138](https://github.com/withastro/astro/pull/9138) [`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3) Thanks [@bluwy](https://github.com/bluwy)! - Updates the unified, remark, and rehype dependencies to latest. Make sure to update your custom remark and rehype plugins as well to be compatible with the latest versions. + + **Potentially breaking change:** The default value of `markdown.remarkRehype.footnoteBackLabel` is changed from `"Back to content"` to `"Back to reference 1"`. See the `mdast-util-to-hast` [commit](https://github.com/syntax-tree/mdast-util-to-hast/commit/56c88e45690be138fad9f0bf367b939d09816863) for more information. + +- [#9182](https://github.com/withastro/astro/pull/9182) [`c7953645e`](https://github.com/withastro/astro/commit/c7953645eeaaf9e87c6db4494b0023d2c1878ff0) Thanks [@bluwy](https://github.com/bluwy)! - Removes deprecated APIs. All Astro packages had been refactored to not use these APIs. + +### Patch Changes + +- [#9147](https://github.com/withastro/astro/pull/9147) [`addb57c8e`](https://github.com/withastro/astro/commit/addb57c8e80b7b67ec61224666f3a1db5c44410c) Thanks [@bluwy](https://github.com/bluwy)! - Fixes `RemarkRehype` type's `handler` and `handlers` properties + +- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]: + - astro@4.0.0-beta.0 + ## 3.5.0 ### Minor Changes diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json index 9f248eb32fa2a..c65a582e77a79 100644 --- a/packages/markdown/remark/package.json +++ b/packages/markdown/remark/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/markdown-remark", - "version": "3.5.0", + "version": "4.0.1", "type": "module", "author": "withastro", "license": "MIT", @@ -27,35 +27,32 @@ "dev": "astro-scripts dev \"src/**/*.ts\"", "test": "mocha --exit --timeout 20000" }, - "peerDependencies": { - "astro": "^3.0.0" - }, "dependencies": { "@astrojs/prism": "^3.0.0", "github-slugger": "^2.0.0", - "import-meta-resolve": "^3.0.0", + "import-meta-resolve": "^4.0.0", "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^6.1.1", - "rehype-stringify": "^9.0.4", - "remark-gfm": "^3.0.1", - "remark-parse": "^10.0.2", - "remark-rehype": "^10.1.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.0", + "remark-gfm": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", "remark-smartypants": "^2.0.0", - "shikiji": "^0.6.8", - "unified": "^10.1.2", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" + "shikiji": "^0.6.13", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1" }, "devDependencies": { - "@types/chai": "^4.3.5", - "@types/estree": "^1.0.1", - "@types/hast": "^2.3.5", - "@types/mdast": "^3.0.12", - "@types/mocha": "^10.0.1", - "@types/unist": "^2.0.7", + "@types/chai": "^4.3.10", + "@types/estree": "^1.0.5", + "@types/hast": "^3.0.3", + "@types/mdast": "^4.0.3", + "@types/mocha": "^10.0.4", + "@types/unist": "^3.0.2", "astro-scripts": "workspace:*", "chai": "^4.3.7", - "mdast-util-mdx-expression": "^1.3.2", + "mdast-util-mdx-expression": "^2.0.0", "mocha": "^10.2.0" }, "publishConfig": { diff --git a/packages/markdown/remark/src/frontmatter-injection.ts b/packages/markdown/remark/src/frontmatter-injection.ts index 4828873fd2c12..91b98ebcba63a 100644 --- a/packages/markdown/remark/src/frontmatter-injection.ts +++ b/packages/markdown/remark/src/frontmatter-injection.ts @@ -32,19 +32,3 @@ export function setVfileFrontmatter(vfile: VFile, frontmatter: Record; -}) { - return () => - function (tree: any, vfile: VFile) { - if (!vfile.data.astro) { - vfile.data.astro = { frontmatter: userFrontmatter }; - } - }; -} diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts index a60ab88c0ef54..14301584793c1 100644 --- a/packages/markdown/remark/src/index.ts +++ b/packages/markdown/remark/src/index.ts @@ -1,10 +1,4 @@ -import type { - AstroMarkdownOptions, - MarkdownProcessor, - MarkdownRenderingOptions, - MarkdownRenderingResult, - MarkdownVFile, -} from './types.js'; +import type { AstroMarkdownOptions, MarkdownProcessor, MarkdownVFile } from './types.js'; import { InvalidAstroDataError, @@ -35,7 +29,7 @@ export { remarkShiki } from './remark-shiki.js'; export { createShikiHighlighter, replaceCssVariables, type ShikiHighlighter } from './shiki.js'; export * from './types.js'; -export const markdownConfigDefaults: Omit, 'drafts'> = { +export const markdownConfigDefaults: Required = { syntaxHighlight: 'shiki', shikiConfig: { langs: [], @@ -102,7 +96,7 @@ export async function createMarkdownProcessor( } // Remark -> Rehype - parser.use(remarkRehype as any, { + parser.use(remarkRehype, { allowDangerousHtml: true, passThrough: [], ...remarkRehypeOptions, @@ -150,42 +144,11 @@ export async function createMarkdownProcessor( imagePaths: result.data.imagePaths ?? new Set(), frontmatter: astroData.frontmatter ?? {}, }, - // Compat for `renderMarkdown` only. Do not use! - __renderMarkdownCompat: { - result, - }, }; }, }; } -/** - * Shared utility for rendering markdown - * - * @deprecated Use `createMarkdownProcessor` instead for better performance - */ -export async function renderMarkdown( - content: string, - opts: MarkdownRenderingOptions -): Promise { - const processor = await createMarkdownProcessor(opts); - - const result = await processor.render(content, { - fileURL: opts.fileURL, - frontmatter: opts.frontmatter, - }); - - return { - code: result.code, - metadata: { - headings: result.metadata.headings, - source: content, - html: result.code, - }, - vfile: (result as any).__renderMarkdownCompat.result, - }; -} - function prefixError(err: any, prefix: string) { // If the error is an object with a `message` property, attempt to prefix the message if (err?.message) { diff --git a/packages/markdown/remark/src/internal.ts b/packages/markdown/remark/src/internal.ts index 0ab7e34bb3940..6201ef62f48bb 100644 --- a/packages/markdown/remark/src/internal.ts +++ b/packages/markdown/remark/src/internal.ts @@ -1,5 +1 @@ -export { - InvalidAstroDataError, - safelyGetAstroData, - toRemarkInitializeAstroData, -} from './frontmatter-injection.js'; +export { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js'; diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts index 7038e24253530..ab5af8ed134bf 100644 --- a/packages/markdown/remark/src/types.ts +++ b/packages/markdown/remark/src/types.ts @@ -1,10 +1,6 @@ import type * as hast from 'hast'; import type * as mdast from 'mdast'; -import type { - one as Handler, - all as Handlers, - Options as RemarkRehypeOptions, -} from 'remark-rehype'; +import type { Options as RemarkRehypeOptions } from 'remark-rehype'; import type { BuiltinTheme, LanguageRegistration, @@ -34,10 +30,7 @@ export type RehypePlugin = unified.Plugi export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[]; -export type RemarkRehype = Omit & { - handlers?: typeof Handlers; - handler?: typeof Handler; -}; +export type RemarkRehype = RemarkRehypeOptions; export interface ShikiConfig { langs?: LanguageRegistration[]; @@ -47,7 +40,6 @@ export interface ShikiConfig { } export interface AstroMarkdownOptions { - drafts?: boolean; syntaxHighlight?: 'shiki' | 'prism' | false; shikiConfig?: ShikiConfig; remarkPlugins?: RemarkPlugins; diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 66edc3fba603a..f7708ef8b81e1 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -29,19 +29,19 @@ "dist" ], "dependencies": { - "ci-info": "^3.8.0", + "ci-info": "^4.0.0", "debug": "^4.3.4", "dlv": "^1.1.3", - "dset": "^3.1.2", + "dset": "^3.1.3", "is-docker": "^3.0.0", "is-wsl": "^3.0.0", "which-pm-runs": "^1.1.0" }, "devDependencies": { - "@types/debug": "^4.1.8", - "@types/dlv": "^1.1.2", + "@types/debug": "^4.1.12", + "@types/dlv": "^1.1.4", "@types/node": "^18.17.8", - "@types/which-pm-runs": "^1.0.0", + "@types/which-pm-runs": "^1.0.2", "astro-scripts": "workspace:*", "chai": "^4.3.7", "mocha": "^10.2.0" diff --git a/packages/telemetry/src/config.ts b/packages/telemetry/src/config.ts index 6efcb7fe5bdf1..dee6c1d25ae54 100644 --- a/packages/telemetry/src/config.ts +++ b/packages/telemetry/src/config.ts @@ -1,5 +1,4 @@ import dget from 'dlv'; -// @ts-expect-error `dset` is mispackaged: https://publint.dev/dset@3.1.2 import { dset } from 'dset'; import fs from 'node:fs'; import os from 'node:os'; diff --git a/packages/underscore-redirects/package.json b/packages/underscore-redirects/package.json index 17daae1a8dd53..31606be682e03 100644 --- a/packages/underscore-redirects/package.json +++ b/packages/underscore-redirects/package.json @@ -28,8 +28,8 @@ "test": "mocha --exit --timeout 20000" }, "devDependencies": { - "@types/chai": "^4.3.5", - "@types/mocha": "^10.0.1", + "@types/chai": "^4.3.10", + "@types/mocha": "^10.0.4", "astro": "workspace:*", "astro-scripts": "workspace:*", "chai": "^4.3.7", diff --git a/packages/upgrade/CHANGELOG.md b/packages/upgrade/CHANGELOG.md new file mode 100644 index 0000000000000..e39000145f31b --- /dev/null +++ b/packages/upgrade/CHANGELOG.md @@ -0,0 +1,97 @@ +# @astrojs/upgrade + +## 0.2.1 + +### Patch Changes + +- [#9317](https://github.com/withastro/astro/pull/9317) [`d1c91add0`](https://github.com/withastro/astro/commit/d1c91add074c2e08056f01df5a6043c9716b7e1f) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improves dependency handling by ignoring packages that don't use a semver version + +## 0.2.0 + +### Minor Changes + +- [#9118](https://github.com/withastro/astro/pull/9118) [`000e8f465`](https://github.com/withastro/astro/commit/000e8f4654cae9982e21e0a858366c4844139db6) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Initial release! + + `@astrojs/upgrade` is an automated command-line tool for upgrading Astro and your official Astro integrations together. + + Inside of your existing `astro` project, run the following command to install the `latest` version of your integrations. + + **With NPM:** + + ```bash + npx @astrojs/upgrade + ``` + + **With Yarn:** + + ```bash + yarn dlx @astrojs/upgrade + ``` + + **With PNPM:** + + ```bash + pnpm dlx @astrojs/upgrade + ``` + +## 0.1.0-beta.0 + +### Minor Changes + +- [#9118](https://github.com/withastro/astro/pull/9118) [`000e8f465`](https://github.com/withastro/astro/commit/000e8f4654cae9982e21e0a858366c4844139db6) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Initial release! + + `@astrojs/upgrade` is an automated command-line tool for upgrading Astro and your official Astro integrations together. + + Inside of your existing `astro` project, run the following command to install the `latest` version of your integrations. + + **With NPM:** + + ```bash + npx @astrojs/upgrade + ``` + + **With Yarn:** + + ```bash + yarn dlx @astrojs/upgrade + ``` + + **With PNPM:** + + ```bash + pnpm dlx @astrojs/upgrade + ``` + +## 0.1.1 + +### Patch Changes + +- [#9213](https://github.com/withastro/astro/pull/9213) [`54e57fe9d`](https://github.com/withastro/astro/commit/54e57fe9d7600c888fc7b0bc3f5dbca5543f36cd) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Fix unhandled error when running `@astrojs/upgrade beta` outside of a monorepo + +## 0.1.0 + +### Minor Changes + +- [#8525](https://github.com/withastro/astro/pull/8525) [`5a3875018`](https://github.com/withastro/astro/commit/5a38750188d1af30ea5277cea70f454c363b5062) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Initial release! + + `@astrojs/upgrade` is an automated command-line tool for upgrading Astro and your official Astro integrations together. + + Inside of your existing `astro` project, run the following command to install the `latest` version of your integrations. + + **With NPM:** + + ```bash + npx @astrojs/upgrade + ``` + + **With Yarn:** + + ```bash + yarn dlx @astrojs/upgrade + ``` + + **With PNPM:** + + ```bash + pnpm dlx @astrojs/upgrade + ``` diff --git a/packages/upgrade/README.md b/packages/upgrade/README.md new file mode 100644 index 0000000000000..3744671f72cb7 --- /dev/null +++ b/packages/upgrade/README.md @@ -0,0 +1,53 @@ +# @astrojs/upgrade + +A command-line tool for upgrading your Astro integrations and dependencies. + +You can run this command in your terminal to upgrade your official Astro integrations at the same time you upgrade your version of Astro. + +## Usage + +`@astrojs/upgrade` should not be added as a dependency to your project, but run as a temporary executable whenever you want to upgrade using [`npx`](https://docs.npmjs.com/cli/v10/commands/npx) or [`dlx`](https://pnpm.io/cli/dlx). + +**With NPM:** + +```bash +npx @astrojs/upgrade +``` + +**With Yarn:** + +```bash +yarn dlx @astrojs/upgrade +``` + +**With PNPM:** + +```bash +pnpm dlx @astrojs/upgrade +``` + +## Options + +### tag (optional) + +It is possible to pass a specific `tag` to resolve packages against. If not included, `@astrojs/upgrade` looks for the `latest` tag. + +For example, Astro often releases `beta` versions prior to an upcoming major release. Upgrade an existing Astro project and it's dependencies to the `beta` version using one of the following commands: + +**With NPM:** + +```bash +npx @astrojs/upgrade beta +``` + +**With Yarn:** + +```bash +yarn dlx @astrojs/upgrade beta +``` + +**With PNPM:** + +```bash +pnpm dlx @astrojs/upgrade beta +``` diff --git a/packages/upgrade/package.json b/packages/upgrade/package.json new file mode 100644 index 0000000000000..fb765e47b37f8 --- /dev/null +++ b/packages/upgrade/package.json @@ -0,0 +1,49 @@ +{ + "name": "@astrojs/upgrade", + "version": "0.2.1", + "type": "module", + "author": "withastro", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/withastro/astro.git", + "directory": "packages/upgrade" + }, + "bugs": "https://github.com/withastro/astro/issues", + "homepage": "https://astro.build", + "exports": { + ".": "./upgrade.mjs" + }, + "main": "./upgrade.mjs", + "bin": "./upgrade.mjs", + "scripts": { + "build": "astro-scripts build \"src/index.ts\" --bundle && tsc", + "build:ci": "astro-scripts build \"src/index.ts\" --bundle", + "dev": "astro-scripts dev \"src/**/*.ts\"", + "test": "mocha --exit --timeout 20000 --parallel" + }, + "files": [ + "dist", + "upgrade.js" + ], + "//a": "MOST PACKAGES SHOULD GO IN DEV_DEPENDENCIES! THEY WILL BE BUNDLED.", + "//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES", + "dependencies": { + "@astrojs/cli-kit": "^0.2.3", + "semver": "^7.5.4", + "which-pm-runs": "^1.1.0", + "terminal-link": "^3.0.0" + }, + "devDependencies": { + "@types/semver": "^7.5.2", + "@types/which-pm-runs": "^1.0.0", + "arg": "^5.0.2", + "astro-scripts": "workspace:*", + "chai": "^4.3.7", + "mocha": "^10.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18.14.1" + } +} diff --git a/packages/upgrade/src/actions/context.ts b/packages/upgrade/src/actions/context.ts new file mode 100644 index 0000000000000..f821864b5ea70 --- /dev/null +++ b/packages/upgrade/src/actions/context.ts @@ -0,0 +1,56 @@ +import { prompt } from '@astrojs/cli-kit'; +import arg from 'arg'; +import { pathToFileURL } from 'node:url'; +import detectPackageManager from 'which-pm-runs'; + +export interface Context { + help: boolean; + prompt: typeof prompt; + version: string; + dryRun?: boolean; + cwd: URL; + stdin?: typeof process.stdin; + stdout?: typeof process.stdout; + packageManager: string; + packages: PackageInfo[]; + exit(code: number): never; +} + +export interface PackageInfo { + name: string; + currentVersion: string; + targetVersion: string; + tag?: string; + isDevDependency?: boolean; + isMajor?: boolean; + changelogURL?: string; + changelogTitle?: string; +} + +export async function getContext(argv: string[]): Promise { + const flags = arg( + { + '--dry-run': Boolean, + '--help': Boolean, + + '-h': '--help', + }, + { argv, permissive: true } + ); + + const packageManager = detectPackageManager()?.name ?? 'npm'; + const { _: [version = 'latest'] = [], '--help': help = false, '--dry-run': dryRun } = flags; + + return { + help, + prompt, + packageManager, + packages: [], + cwd: new URL(pathToFileURL(process.cwd()) + '/'), + dryRun, + version, + exit(code) { + process.exit(code); + }, + } satisfies Context; +} diff --git a/packages/upgrade/src/actions/help.ts b/packages/upgrade/src/actions/help.ts new file mode 100644 index 0000000000000..2e25b7e8442bf --- /dev/null +++ b/packages/upgrade/src/actions/help.ts @@ -0,0 +1,15 @@ +import { printHelp } from '../messages.js'; + +export function help() { + printHelp({ + commandName: '@astrojs/upgrade', + usage: '[version] [...flags]', + headline: 'Upgrade Astro dependencies.', + tables: { + Flags: [ + ['--help (-h)', 'See all available flags.'], + ['--dry-run', 'Walk through steps without executing.'], + ], + }, + }); +} diff --git a/packages/upgrade/src/actions/install.ts b/packages/upgrade/src/actions/install.ts new file mode 100644 index 0000000000000..3f343463fadff --- /dev/null +++ b/packages/upgrade/src/actions/install.ts @@ -0,0 +1,187 @@ +import type { Context, PackageInfo } from './context.js'; + +import { color, say } from '@astrojs/cli-kit'; +import { random, sleep } from '@astrojs/cli-kit/utils'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { + banner, + bye, + celebrations, + changelog, + done, + error, + info, + newline, + pluralize, + spinner, + success, + title, + upgrade, + warn, +} from '../messages.js'; +import { shell } from '../shell.js'; + +export async function install( + ctx: Pick< + Context, + 'version' | 'packages' | 'packageManager' | 'prompt' | 'dryRun' | 'exit' | 'cwd' + > +) { + await banner(); + newline(); + const { current, dependencies, devDependencies } = filterPackages(ctx); + const toInstall = [...dependencies, ...devDependencies].sort(sortPackages); + for (const packageInfo of current.sort(sortPackages)) { + const tag = /^\d/.test(packageInfo.targetVersion) + ? packageInfo.targetVersion + : packageInfo.targetVersion.slice(1); + await info(`${packageInfo.name}`, `is up to date on`, `v${tag}`); + await sleep(random(50, 150)); + } + if (toInstall.length === 0 && !ctx.dryRun) { + newline(); + await success(random(celebrations), random(done)); + return; + } + const majors: PackageInfo[] = []; + for (const packageInfo of toInstall) { + const word = ctx.dryRun ? 'can' : 'will'; + await upgrade(packageInfo, `${word} be updated to`); + if (packageInfo.isMajor) { + majors.push(packageInfo); + } + } + if (majors.length > 0) { + const { proceed } = await ctx.prompt({ + name: 'proceed', + type: 'confirm', + label: title('wait'), + message: `${pluralize( + ['One package has', 'Some packages have'], + majors.length + )} breaking changes. Continue?`, + initial: true, + }); + if (!proceed) { + return ctx.exit(0); + } + + newline(); + + await warn('check', `Be sure to follow the ${pluralize('CHANGELOG', majors.length)}.`); + for (const pkg of majors.sort(sortPackages)) { + await changelog(pkg.name, pkg.changelogTitle!, pkg.changelogURL!); + } + } + + newline(); + if (ctx.dryRun) { + await info('--dry-run', `Skipping dependency installation`); + } else { + await runInstallCommand(ctx, dependencies, devDependencies); + } +} + +function filterPackages(ctx: Pick) { + const current: PackageInfo[] = []; + const dependencies: PackageInfo[] = []; + const devDependencies: PackageInfo[] = []; + for (const packageInfo of ctx.packages) { + const { currentVersion, targetVersion, isDevDependency } = packageInfo; + // Remove prefix from `currentVersion` before comparing + if (currentVersion.replace(/^\D+/, '') === targetVersion) { + current.push(packageInfo); + } else { + const arr = isDevDependency ? devDependencies : dependencies; + arr.push(packageInfo); + } + } + return { current, dependencies, devDependencies }; +} + +/** + * An `Array#sort` comparator function to normalize how packages are displayed. + * This only changes how the packages are displayed in the CLI, it is not persisted to `package.json`. + */ +function sortPackages(a: PackageInfo, b: PackageInfo): number { + if (a.isMajor && !b.isMajor) return 1; + if (b.isMajor && !a.isMajor) return -1; + if (a.name === 'astro') return -1; + if (b.name === 'astro') return 1; + if (a.name.startsWith('@astrojs') && !b.name.startsWith('@astrojs')) return -1; + if (b.name.startsWith('@astrojs') && !a.name.startsWith('@astrojs')) return 1; + return a.name.localeCompare(b.name); +} + +async function runInstallCommand( + ctx: Pick, + dependencies: PackageInfo[], + devDependencies: PackageInfo[] +) { + const cwd = fileURLToPath(ctx.cwd); + if (ctx.packageManager === 'yarn') await ensureYarnLock({ cwd }); + + await spinner({ + start: `Installing dependencies with ${ctx.packageManager}...`, + end: `Installed dependencies!`, + while: async () => { + try { + if (dependencies.length > 0) { + await shell( + ctx.packageManager, + [ + 'install', + ...dependencies.map( + ({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, '')}` + ), + ], + { cwd, timeout: 90_000, stdio: 'ignore' } + ); + } + if (devDependencies.length > 0) { + await shell( + ctx.packageManager, + [ + 'install', + '--save-dev', + ...devDependencies.map( + ({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, '')}` + ), + ], + { cwd, timeout: 90_000, stdio: 'ignore' } + ); + } + } catch { + const packages = [...dependencies, ...devDependencies] + .map(({ name, targetVersion }) => `${name}@${targetVersion}`) + .join(' '); + newline(); + error( + 'error', + `Dependencies failed to install, please run the following command manually:\n${color.bold( + `${ctx.packageManager} install ${packages}` + )}` + ); + return ctx.exit(1); + } + }, + }); + + await say([`${random(celebrations)} ${random(done)}`, random(bye)], { clear: false }); +} + +/** + * Yarn Berry (PnP) versions will throw an error if there isn't an existing `yarn.lock` file + * If a `yarn.lock` file doesn't exist, this function writes an empty `yarn.lock` one. + * Unfortunately this hack is required to run `yarn install`. + * + * The empty `yarn.lock` file is immediately overwritten by the installation process. + * See https://github.com/withastro/astro/pull/8028 + */ +async function ensureYarnLock({ cwd }: { cwd: string }) { + const yarnLock = path.join(cwd, 'yarn.lock'); + if (fs.existsSync(yarnLock)) return; + return fs.promises.writeFile(yarnLock, '', { encoding: 'utf-8' }); +} diff --git a/packages/upgrade/src/actions/verify.ts b/packages/upgrade/src/actions/verify.ts new file mode 100644 index 0000000000000..8233a5caf1572 --- /dev/null +++ b/packages/upgrade/src/actions/verify.ts @@ -0,0 +1,197 @@ +import type { Context, PackageInfo } from './context.js'; + +import { color } from '@astrojs/cli-kit'; +import dns from 'node:dns/promises'; +import { existsSync } from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import semverCoerce from 'semver/functions/coerce.js'; +import semverDiff from 'semver/functions/diff.js'; +import semverParse from 'semver/functions/parse.js'; +import { bannerAbort, error, getRegistry, info, newline } from '../messages.js'; + +export async function verify( + ctx: Pick +) { + const registry = await getRegistry(); + + if (!ctx.dryRun) { + const online = await isOnline(registry); + if (!online) { + bannerAbort(); + newline(); + error('error', `Unable to connect to the internet.`); + ctx.exit(1); + } + } + + await verifyAstroProject(ctx); + + const ok = await verifyVersions(ctx, registry); + if (!ok) { + bannerAbort(); + newline(); + error('error', `Version ${color.reset(ctx.version)} ${color.dim('could not be found!')}`); + await info('check', 'https://github.com/withastro/astro/releases'); + ctx.exit(1); + } +} + +function isOnline(registry: string): Promise { + const { host } = new URL(registry); + return dns.lookup(host).then( + () => true, + () => false + ); +} + +function safeJSONParse(value: string) { + try { + return JSON.parse(value); + } catch {} + return {}; +} + +async function verifyAstroProject(ctx: Pick) { + const packageJson = new URL('./package.json', ctx.cwd); + if (!existsSync(packageJson)) return false; + const contents = await readFile(packageJson, { encoding: 'utf-8' }); + if (!contents.includes('astro')) return false; + + const { dependencies = {}, devDependencies = {} } = safeJSONParse(contents); + if (dependencies['astro'] === undefined && devDependencies['astro'] === undefined) return false; + + // Side-effect! Persist dependency info to the shared context + collectPackageInfo(ctx, dependencies, devDependencies); + + return true; +} + +function isAstroPackage(name: string, _version: string) { + return name === 'astro' || name.startsWith('@astrojs/'); +} + +function isAllowedPackage(name: string, _version: string) { + return name !== '@astrojs/upgrade'; +} + +function isValidVersion(_name: string, version: string) { + return semverCoerce(version, { loose: true }) !== null; +} + +function isSupportedPackage(name: string, version: string): boolean { + for (const validator of [isAstroPackage, isAllowedPackage, isValidVersion]) { + if (!validator(name, version)) return false; + } + return true; +} + +export function collectPackageInfo( + ctx: Pick, + dependencies: Record = {}, + devDependencies: Record = {} +) { + for (const [name, currentVersion] of Object.entries(dependencies)) { + if (!isSupportedPackage(name, currentVersion)) continue; + ctx.packages.push({ + name, + currentVersion, + targetVersion: ctx.version, + }); + } + for (const [name, currentVersion] of Object.entries(devDependencies)) { + if (!isSupportedPackage(name, currentVersion)) continue; + ctx.packages.push({ + name, + currentVersion, + targetVersion: ctx.version, + isDevDependency: true, + }); + } +} + +async function verifyVersions( + ctx: Pick, + registry: string +) { + const tasks: Promise[] = []; + for (const packageInfo of ctx.packages) { + tasks.push(resolveTargetVersion(packageInfo, registry)); + } + try { + await Promise.all(tasks); + } catch { + return false; + } + for (const packageInfo of ctx.packages) { + if (!packageInfo.targetVersion) { + return false; + } + } + return true; +} + +async function resolveTargetVersion(packageInfo: PackageInfo, registry: string): Promise { + const packageMetadata = await fetch(`${registry}/${packageInfo.name}`, { + headers: { accept: 'application/vnd.npm.install-v1+json' }, + }); + if (packageMetadata.status >= 400) { + throw new Error(`Unable to resolve "${packageInfo.name}"`); + } + const { 'dist-tags': distTags } = await packageMetadata.json(); + let version = distTags[packageInfo.targetVersion]; + if (version) { + packageInfo.tag = packageInfo.targetVersion; + packageInfo.targetVersion = version; + } else { + packageInfo.targetVersion = 'latest'; + version = distTags.latest; + } + if (packageInfo.currentVersion === version) { + return; + } + const prefix = packageInfo.targetVersion === 'latest' ? '^' : ''; + packageInfo.targetVersion = `${prefix}${version}`; + const fromVersion = semverCoerce(packageInfo.currentVersion)!; + const toVersion = semverParse(version)!; + const bump = semverDiff(fromVersion, toVersion); + if ((bump === 'major' && toVersion.prerelease.length === 0) || bump === 'premajor') { + packageInfo.isMajor = true; + if (packageInfo.name === 'astro') { + const upgradeGuide = `https://docs.astro.build/en/guides/upgrade-to/v${toVersion.major}/`; + const docsRes = await fetch(upgradeGuide); + // OK if this request fails, it's probably a prerelease without a public migration guide. + // In that case, we should fallback to the CHANGELOG check below. + if (docsRes.status === 200) { + packageInfo.changelogURL = upgradeGuide; + packageInfo.changelogTitle = `Upgrade to Astro v${toVersion.major}`; + return; + } + } + const latestMetadata = await fetch(`${registry}/${packageInfo.name}/latest`); + if (latestMetadata.status >= 400) { + throw new Error(`Unable to resolve "${packageInfo.name}"`); + } + const { repository } = await latestMetadata.json(); + const branch = bump === 'premajor' ? 'next' : 'main'; + packageInfo.changelogURL = extractChangelogURLFromRepository(repository, version, branch); + packageInfo.changelogTitle = 'CHANGELOG'; + } else { + // Dependency updates should not include the specific dist-tag + // since they are just for compatability + packageInfo.tag = undefined; + } +} + +function extractChangelogURLFromRepository( + repository: Record, + version: string, + branch = 'main' +) { + return ( + repository.url.replace('git+', '').replace('.git', '') + + `/blob/${branch}/` + + repository.directory + + '/CHANGELOG.md#' + + version.replace(/\./g, '') + ); +} diff --git a/packages/upgrade/src/index.ts b/packages/upgrade/src/index.ts new file mode 100644 index 0000000000000..8dac82c1c8547 --- /dev/null +++ b/packages/upgrade/src/index.ts @@ -0,0 +1,32 @@ +import { getContext } from './actions/context.js'; + +import { help } from './actions/help.js'; +import { install } from './actions/install.js'; +import { verify, collectPackageInfo } from './actions/verify.js'; +import { setStdout } from './messages.js'; + +const exit = () => process.exit(0); +process.on('SIGINT', exit); +process.on('SIGTERM', exit); + +export async function main() { + // NOTE: In the v7.x version of npm, the default behavior of `npm init` was changed + // to no longer require `--` to pass args and instead pass `--` directly to us. This + // broke our arg parser, since `--` is a special kind of flag. Filtering for `--` here + // fixes the issue so that create-astro now works on all npm versions. + const cleanArgv = process.argv.slice(2).filter((arg) => arg !== '--'); + const ctx = await getContext(cleanArgv); + if (ctx.help) { + help(); + return; + } + + const steps = [verify, install]; + + for (const step of steps) { + await step(ctx); + } + process.exit(0); +} + +export { getContext, install, setStdout, verify, collectPackageInfo }; diff --git a/packages/upgrade/src/messages.ts b/packages/upgrade/src/messages.ts new file mode 100644 index 0000000000000..ae2ec49eb8c66 --- /dev/null +++ b/packages/upgrade/src/messages.ts @@ -0,0 +1,211 @@ +/* eslint no-console: 'off' */ +import { color, label, spinner as load } from '@astrojs/cli-kit'; +import { align } from '@astrojs/cli-kit/utils'; +import terminalLink from 'terminal-link'; +import detectPackageManager from 'which-pm-runs'; +import type { PackageInfo } from './actions/context.js'; +import { shell } from './shell.js'; + +// Users might lack access to the global npm registry, this function +// checks the user's project type and will return the proper npm registry +// +// A copy of this function also exists in the astro package +export async function getRegistry(): Promise { + const packageManager = detectPackageManager()?.name || 'npm'; + try { + const { stdout } = await shell(packageManager, ['config', 'get', 'registry']); + return stdout?.trim()?.replace(/\/$/, '') || 'https://registry.npmjs.org'; + } catch (e) { + return 'https://registry.npmjs.org'; + } +} + +let stdout = process.stdout; +/** @internal Used to mock `process.stdout.write` for testing purposes */ +export function setStdout(writable: typeof process.stdout) { + stdout = writable; +} + +export async function spinner(args: { + start: string; + end: string; + while: (...args: any) => Promise; +}) { + await load(args, { stdout }); +} + +export function pluralize(word: string | [string, string], n: number) { + const [singular, plural] = Array.isArray(word) ? word : [word, word + 's']; + if (n === 1) return singular; + return plural; +} + +export const celebrations = [ + 'Beautiful.', + 'Excellent!', + 'Sweet!', + 'Nice!', + 'Huzzah!', + 'Success.', + 'Nice.', + 'Wonderful.', + 'Lovely!', + "Lookin' good.", + 'Awesome.', +]; + +export const done = [ + "You're on the latest and greatest.", + 'Your integrations are up-to-date.', + 'Everything is current.', + 'Everything is up to date.', + 'Integrations are all up to date.', + 'Everything is on the latest and greatest.', + 'Integrations are up to date.', +]; + +export const bye = [ + 'Thanks for using Astro!', + 'Have fun building!', + 'Take it easy, astronaut!', + "Can't wait to see what you build.", + 'Good luck out there.', + 'See you around, astronaut.', +]; + +export const log = (message: string) => stdout.write(message + '\n'); + +export const newline = () => stdout.write('\n'); + +export const banner = async () => + log( + `\n${label('astro', color.bgGreen, color.black)} ${color.bold( + 'Integration upgrade in progress.' + )}` + ); + +export const bannerAbort = () => + log(`\n${label('astro', color.bgRed)} ${color.bold('Integration upgrade aborted.')}`); + +export const warn = async (prefix: string, text: string) => { + log(`${label(prefix, color.bgCyan, color.black)} ${text}`); +}; + +export const info = async (prefix: string, text: string, version = '') => { + const length = 11 + prefix.length + text.length + version?.length; + const symbol = '◼'; + if (length > stdout.columns) { + log(`${' '.repeat(5)} ${color.cyan(symbol)} ${prefix}`); + log(`${' '.repeat(9)}${color.dim(text)} ${color.reset(version)}`); + } else { + log( + `${' '.repeat(5)} ${color.cyan(symbol)} ${prefix} ${color.dim(text)} ${color.reset(version)}` + ); + } +}; +export const upgrade = async (packageInfo: PackageInfo, text: string) => { + const { name, isMajor = false, targetVersion } = packageInfo; + + const bg = isMajor ? (v: string) => color.bgYellow(color.black(` ${v} `)) : color.green; + const style = isMajor ? color.yellow : color.green; + const symbol = isMajor ? '▲' : '●'; + const toVersion = targetVersion.replace(/^\D+/, ''); + const version = `v${toVersion}`; + + const length = 12 + name.length + text.length + version.length; + if (length > stdout.columns) { + log(`${' '.repeat(5)} ${style(symbol)} ${name}`); + log(`${' '.repeat(9)}${color.dim(text)} ${bg(version)}`); + } else { + log(`${' '.repeat(5)} ${style(symbol)} ${name} ${color.dim(text)} ${bg(version)}`); + } +}; + +export const title = (text: string) => + align(label(text, color.bgYellow, color.black), 'end', 7) + ' '; + +export const success = async (prefix: string, text: string) => { + const length = 10 + prefix.length + text.length; + if (length > stdout.columns) { + log(`${' '.repeat(5)} ${color.green('✔')} ${prefix}`); + log(`${' '.repeat(9)}${color.dim(text)}`); + } else { + log(`${' '.repeat(5)} ${color.green('✔')} ${prefix} ${color.dim(text)}`); + } +}; + +export const error = async (prefix: string, text: string) => { + if (stdout.columns < 80) { + log(`${' '.repeat(5)} ${color.red('▲')} ${color.red(prefix)}`); + log(`${' '.repeat(9)}${color.dim(text)}`); + } else { + log(`${' '.repeat(5)} ${color.red('▲')} ${color.red(prefix)} ${color.dim(text)}`); + } +}; + +export const changelog = async (name: string, text: string, url: string) => { + const link = terminalLink(text, url, { fallback: () => url }); + const linkLength = terminalLink.isSupported ? text.length : url.length; + const symbol = ' '; + + const length = 12 + name.length + linkLength; + if (length > stdout.columns) { + log(`${' '.repeat(5)} ${symbol} ${name}`); + log(`${' '.repeat(9)}${color.cyan(color.underline(link))}`); + } else { + log(`${' '.repeat(5)} ${symbol} ${name} ${color.cyan(color.underline(link))}`); + } +}; + +export function printHelp({ + commandName, + usage, + tables, + description, +}: { + commandName: string; + headline?: string; + usage?: string; + tables?: Record; + description?: string; +}) { + const linebreak = () => ''; + const table = (rows: [string, string][], { padding }: { padding: number }) => { + const split = stdout.columns < 60; + let raw = ''; + + for (const row of rows) { + if (split) { + raw += ` ${row[0]}\n `; + } else { + raw += `${`${row[0]}`.padStart(padding)}`; + } + raw += ' ' + color.dim(row[1]) + '\n'; + } + + return raw.slice(0, -1); // remove latest \n + }; + + let message = []; + + if (usage) { + message.push(linebreak(), `${color.green(commandName)} ${color.bold(usage)}`); + } + + if (tables) { + function calculateTablePadding(rows: [string, string][]) { + return rows.reduce((val, [first]) => Math.max(val, first.length), 0); + } + const tableEntries = Object.entries(tables); + const padding = Math.max(...tableEntries.map(([, rows]) => calculateTablePadding(rows))); + for (const [, tableRows] of tableEntries) { + message.push(linebreak(), table(tableRows, { padding })); + } + } + + if (description) { + message.push(linebreak(), `${description}`); + } + + log(message.join('\n') + '\n'); +} diff --git a/packages/upgrade/src/shell.ts b/packages/upgrade/src/shell.ts new file mode 100644 index 0000000000000..65a83327d8b81 --- /dev/null +++ b/packages/upgrade/src/shell.ts @@ -0,0 +1,60 @@ +// This is an extremely simplified version of [`execa`](https://github.com/sindresorhus/execa) +// intended to keep our dependency size down +import type { ChildProcess, StdioOptions } from 'node:child_process'; +import type { Readable } from 'node:stream'; + +import { spawn } from 'node:child_process'; +import { text as textFromStream } from 'node:stream/consumers'; + +export interface ExecaOptions { + cwd?: string | URL; + stdio?: StdioOptions; + timeout?: number; +} +export interface Output { + stdout: string; + stderr: string; + exitCode: number; +} +const text = (stream: NodeJS.ReadableStream | Readable | null) => + stream ? textFromStream(stream).then((t) => t.trimEnd()) : ''; + +let signal: AbortSignal; +export async function shell( + command: string, + flags: string[], + opts: ExecaOptions = {} +): Promise { + let child: ChildProcess; + let stdout = ''; + let stderr = ''; + if (!signal) { + const controller = new AbortController(); + // Ensure spawned process is cancelled on exit + process.once('beforeexit', () => controller.abort()); + process.once('exit', () => controller.abort()); + signal = controller.signal; + } + try { + child = spawn(command, flags, { + cwd: opts.cwd, + shell: true, + stdio: opts.stdio, + timeout: opts.timeout, + signal, + }); + const done = new Promise((resolve) => child.on('close', resolve)); + [stdout, stderr] = await Promise.all([text(child.stdout), text(child.stderr)]); + await done; + } catch (e) { + throw { stdout, stderr, exitCode: 1 }; + } + const { exitCode } = child; + if (exitCode === null) { + throw new Error('Timeout'); + } + if (exitCode !== 0) { + throw new Error(stderr); + } + return { stdout, stderr, exitCode }; +} diff --git a/packages/upgrade/test/context.test.js b/packages/upgrade/test/context.test.js new file mode 100644 index 0000000000000..5b6b8c6b22018 --- /dev/null +++ b/packages/upgrade/test/context.test.js @@ -0,0 +1,19 @@ +import { expect } from 'chai'; +import { getContext } from '../dist/index.js'; + +describe('context', () => { + it('no arguments', async () => { + const ctx = await getContext([]); + expect(ctx.version).to.eq('latest'); + expect(ctx.dryRun).to.be.undefined; + }); + it('tag', async () => { + const ctx = await getContext(['beta']); + expect(ctx.version).to.eq('beta'); + expect(ctx.dryRun).to.be.undefined; + }); + it('dry run', async () => { + const ctx = await getContext(['--dry-run']); + expect(ctx.dryRun).to.eq(true); + }); +}); diff --git a/packages/upgrade/test/install.test.js b/packages/upgrade/test/install.test.js new file mode 100644 index 0000000000000..05c46cdce9ef7 --- /dev/null +++ b/packages/upgrade/test/install.test.js @@ -0,0 +1,211 @@ +import { expect } from 'chai'; +import { setup } from './utils.js'; +import { install } from '../dist/index.js'; + +describe('install', () => { + const fixture = setup(); + const ctx = { + cwd: '', + version: 'latest', + packageManager: 'npm', + dryRun: true, + }; + + it('up to date', async () => { + const context = { + ...ctx, + packages: [ + { + name: 'astro', + currentVersion: '1.0.0', + targetVersion: '1.0.0', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('◼ astro is up to date on v1.0.0')).to.be.true; + }); + + it('patch', async () => { + const context = { + ...ctx, + packages: [ + { + name: 'astro', + currentVersion: '1.0.0', + targetVersion: '1.0.1', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('● astro can be updated to v1.0.1')).to.be.true; + }); + + it('minor', async () => { + const context = { + ...ctx, + packages: [ + { + name: 'astro', + currentVersion: '1.0.0', + targetVersion: '1.2.0', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('● astro can be updated to v1.2.0')).to.be.true; + }); + + it('major (reject)', async () => { + let prompted = false; + let exitCode; + const context = { + ...ctx, + prompt: () => { + prompted = true; + return { proceed: false }; + }, + exit: (code) => { + exitCode = code; + }, + packages: [ + { + name: 'astro', + currentVersion: '1.0.0', + targetVersion: '2.0.0', + isMajor: true, + changelogTitle: 'CHANGELOG', + changelogURL: 'https://example.com', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('▲ astro can be updated to v2.0.0')).to.be.true; + expect(prompted).to.be.true; + expect(exitCode).to.eq(0); + expect(fixture.hasMessage('check Be sure to follow the CHANGELOG.')).to.be.false; + }); + + it('major (accept)', async () => { + let prompted = false; + let exitCode; + const context = { + ...ctx, + prompt: () => { + prompted = true; + return { proceed: true }; + }, + exit: (code) => { + exitCode = code; + }, + packages: [ + { + name: 'astro', + currentVersion: '1.0.0', + targetVersion: '2.0.0', + isMajor: true, + changelogTitle: 'CHANGELOG', + changelogURL: 'https://example.com', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('▲ astro can be updated to v2.0.0')).to.be.true; + expect(prompted).to.be.true; + expect(exitCode).to.be.undefined; + expect(fixture.hasMessage('check Be sure to follow the CHANGELOG.')).to.be.true; + }); + + it('multiple major', async () => { + let prompted = false; + let exitCode; + const context = { + ...ctx, + prompt: () => { + prompted = true; + return { proceed: true }; + }, + exit: (code) => { + exitCode = code; + }, + packages: [ + { + name: 'a', + currentVersion: '1.0.0', + targetVersion: '2.0.0', + isMajor: true, + changelogTitle: 'CHANGELOG', + changelogURL: 'https://example.com', + }, + { + name: 'b', + currentVersion: '6.0.0', + targetVersion: '7.0.0', + isMajor: true, + changelogTitle: 'CHANGELOG', + changelogURL: 'https://example.com', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('▲ a can be updated to v2.0.0')).to.be.true; + expect(fixture.hasMessage('▲ b can be updated to v7.0.0')).to.be.true; + expect(prompted).to.be.true; + expect(exitCode).to.be.undefined; + const [changelog, a, b] = fixture.messages().slice(-5); + expect(changelog).to.match(/^check/); + expect(a).to.match(/^a/); + expect(b).to.match(/^b/); + }); + + it('current patch minor major', async () => { + let prompted = false; + let exitCode; + const context = { + ...ctx, + prompt: () => { + prompted = true; + return { proceed: true }; + }, + exit: (code) => { + exitCode = code; + }, + packages: [ + { + name: 'current', + currentVersion: '1.0.0', + targetVersion: '1.0.0', + }, + { + name: 'patch', + currentVersion: '1.0.0', + targetVersion: '1.0.1', + }, + { + name: 'minor', + currentVersion: '1.0.0', + targetVersion: '1.2.0', + }, + { + name: 'major', + currentVersion: '1.0.0', + targetVersion: '3.0.0', + isMajor: true, + changelogTitle: 'CHANGELOG', + changelogURL: 'https://example.com', + }, + ], + }; + await install(context); + expect(fixture.hasMessage('◼ current is up to date on v1.0.0')).to.be.true; + expect(fixture.hasMessage('● patch can be updated to v1.0.1')).to.be.true; + expect(fixture.hasMessage('● minor can be updated to v1.2.0')).to.be.true; + expect(fixture.hasMessage('▲ major can be updated to v3.0.0')).to.be.true; + expect(prompted).to.be.true; + expect(exitCode).to.be.undefined; + expect(fixture.hasMessage('check Be sure to follow the CHANGELOG.')).to.be.true; + const [changelog, major] = fixture.messages().slice(-4); + expect(changelog).to.match(/^check/); + expect(major).to.match(/^major/); + }); +}); diff --git a/packages/upgrade/test/utils.js b/packages/upgrade/test/utils.js new file mode 100644 index 0000000000000..ff5d5dd832af5 --- /dev/null +++ b/packages/upgrade/test/utils.js @@ -0,0 +1,31 @@ +import { setStdout } from '../dist/index.js'; +import stripAnsi from 'strip-ansi'; + +export function setup() { + const ctx = { messages: [] }; + before(() => { + setStdout( + Object.assign({}, process.stdout, { + write(buf) { + ctx.messages.push(stripAnsi(String(buf)).trim()); + return true; + }, + }) + ); + }); + beforeEach(() => { + ctx.messages = []; + }); + + return { + messages() { + return ctx.messages; + }, + length() { + return ctx.messages.length; + }, + hasMessage(content) { + return !!ctx.messages.find((msg) => msg.includes(content)); + }, + }; +} diff --git a/packages/upgrade/test/verify.test.js b/packages/upgrade/test/verify.test.js new file mode 100644 index 0000000000000..a54cb6bb5085b --- /dev/null +++ b/packages/upgrade/test/verify.test.js @@ -0,0 +1,76 @@ +import { expect } from 'chai'; +import { collectPackageInfo } from '../dist/index.js'; + +describe('collectPackageInfo', () => { + const context = { + cwd: '', + version: 'latest', + packageManager: 'npm', + dryRun: true, + packages: [], + }; + + beforeEach(() => { + context.packages = []; + }); + + it('detects astro', async () => { + collectPackageInfo(context, { astro: '1.0.0' }, {}); + expect(context.packages).deep.equal([ + { name: 'astro', currentVersion: '1.0.0', targetVersion: 'latest' }, + ]); + }); + + it('detects @astrojs', async () => { + collectPackageInfo(context, { '@astrojs/preact': '1.0.0' }, {}); + expect(context.packages).deep.equal([ + { name: '@astrojs/preact', currentVersion: '1.0.0', targetVersion: 'latest' }, + ]); + }); + + it('supports ^ prefixes', async () => { + collectPackageInfo(context, { astro: '^1.0.0' }, {}); + expect(context.packages).deep.equal([ + { name: 'astro', currentVersion: '^1.0.0', targetVersion: 'latest' }, + ]); + }); + + it('supports ~ prefixes', async () => { + collectPackageInfo(context, { astro: '~1.0.0' }, {}); + expect(context.packages).deep.equal([ + { name: 'astro', currentVersion: '~1.0.0', targetVersion: 'latest' }, + ]); + }); + + it('supports prereleases', async () => { + collectPackageInfo(context, { astro: '1.0.0-beta.0' }, {}); + expect(context.packages).deep.equal([ + { name: 'astro', currentVersion: '1.0.0-beta.0', targetVersion: 'latest' }, + ]); + }); + + it('ignores self', async () => { + collectPackageInfo(context, { '@astrojs/upgrade': '0.0.1' }, {}); + expect(context.packages).deep.equal([]); + }); + + it('ignores linked packages', async () => { + collectPackageInfo(context, { '@astrojs/preact': 'link:../packages/preact' }, {}); + expect(context.packages).deep.equal([]); + }); + + it('ignores workspace packages', async () => { + collectPackageInfo(context, { '@astrojs/preact': 'workspace:*' }, {}); + expect(context.packages).deep.equal([]); + }); + + it('ignores github packages', async () => { + collectPackageInfo(context, { '@astrojs/preact': 'github:withastro/astro' }, {}); + expect(context.packages).deep.equal([]); + }); + + it('ignores tag', async () => { + collectPackageInfo(context, { '@astrojs/preact': 'beta' }, {}); + expect(context.packages).deep.equal([]); + }); +}); diff --git a/packages/upgrade/tsconfig.json b/packages/upgrade/tsconfig.json new file mode 100644 index 0000000000000..d15ade00ff800 --- /dev/null +++ b/packages/upgrade/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src", "index.d.ts"], + "compilerOptions": { + "allowJs": true, + "emitDeclarationOnly": false, + "noEmit": true, + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "outDir": "./dist", + "declarationDir": "./dist/types" + } +} diff --git a/packages/upgrade/upgrade.mjs b/packages/upgrade/upgrade.mjs new file mode 100755 index 0000000000000..f9df779d871c4 --- /dev/null +++ b/packages/upgrade/upgrade.mjs @@ -0,0 +1,15 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ +'use strict'; + +const currentVersion = process.versions.node; +const requiredMajorVersion = parseInt(currentVersion.split('.')[0], 10); +const minimumMajorVersion = 18; + +if (requiredMajorVersion < minimumMajorVersion) { + console.error(`Node.js v${currentVersion} is out of date and unsupported!`); + console.error(`Please use Node.js v${minimumMajorVersion} or higher.`); + process.exit(1); +} + +import('./dist/index.js').then(({ main }) => main()); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68aed44e57bef..796f0da528c26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,7 +8,7 @@ overrides: organize-imports-cli>ts-morph: ^19.0.0 tsconfig-resolver>type-fest: 3.0.0 -packageExtensionsChecksum: 01871422d489547c532184effb134b35 +packageExtensionsChecksum: 2d0a8c56e33c7d11bb9ef3c997d67c33 importers: @@ -19,8 +19,8 @@ importers: version: link:benchmark devDependencies: '@astrojs/check': - specifier: ^0.1.0 - version: 0.1.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6) + specifier: ^0.3.1 + version: 0.3.1(prettier-plugin-astro@0.12.2)(prettier@3.1.0)(typescript@5.2.2) '@changesets/changelog-github': specifier: ^0.4.8 version: 0.4.8 @@ -31,26 +31,26 @@ importers: specifier: ^18.17.8 version: 18.18.6 '@typescript-eslint/eslint-plugin': - specifier: ^6.4.1 - version: 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.1.6) + specifier: ^6.11.0 + version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^6.4.1 - version: 6.8.0(eslint@8.52.0)(typescript@5.1.6) + specifier: ^6.11.0 + version: 6.11.0(eslint@8.54.0)(typescript@5.2.2) esbuild: - specifier: ^0.19.2 - version: 0.19.5 + specifier: ^0.19.6 + version: 0.19.6 eslint: - specifier: ^8.47.0 - version: 8.52.0 + specifier: ^8.54.0 + version: 8.54.0 eslint-config-prettier: specifier: ^9.0.0 - version: 9.0.0(eslint@8.52.0) + version: 9.0.0(eslint@8.54.0) eslint-plugin-no-only-tests: specifier: ^3.1.0 version: 3.1.0 eslint-plugin-prettier: specifier: ^5.0.0 - version: 5.0.1(eslint-config-prettier@9.0.0)(eslint@8.52.0)(prettier@3.0.3) + version: 5.0.1(eslint-config-prettier@9.0.0)(eslint@8.54.0)(prettier@3.1.0) only-allow: specifier: ^1.1.1 version: 1.2.1 @@ -58,11 +58,11 @@ importers: specifier: ^0.10.0 version: 0.10.0 prettier: - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 prettier-plugin-astro: - specifier: ^0.12.0 - version: 0.12.0 + specifier: ^0.12.2 + version: 0.12.2 tiny-glob: specifier: ^0.2.9 version: 0.2.9 @@ -70,8 +70,8 @@ importers: specifier: ^1.10.12 version: 1.10.16 typescript: - specifier: ~5.1.6 - version: 5.1.6 + specifier: ~5.2.2 + version: 5.2.2 benchmark: dependencies: @@ -113,8 +113,8 @@ importers: version: 1.0.1 devDependencies: '@types/server-destroy': - specifier: ^1.0.1 - version: 1.0.2 + specifier: ^1.0.3 + version: 1.0.3 astro: specifier: workspace:* version: link:../../../packages/astro @@ -125,28 +125,28 @@ importers: examples/basics: dependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/blog: dependencies: '@astrojs/mdx': - specifier: ^1.1.5 + specifier: ^2.0.1 version: link:../../packages/integrations/mdx '@astrojs/rss': - specifier: ^3.0.0 + specifier: ^4.0.1 version: link:../../packages/astro-rss '@astrojs/sitemap': specifier: ^3.0.3 version: link:../../packages/integrations/sitemap astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/component: devDependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/framework-alpine: @@ -155,25 +155,25 @@ importers: specifier: ^0.3.1 version: link:../../packages/integrations/alpinejs '@types/alpinejs': - specifier: ^3.7.2 - version: 3.13.3 + specifier: ^3.13.5 + version: 3.13.5 alpinejs: - specifier: ^3.12.3 - version: 3.13.2 + specifier: ^3.13.3 + version: 3.13.3 astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/framework-lit: dependencies: '@astrojs/lit': - specifier: ^3.0.3 + specifier: ^4.0.0 version: link:../../packages/integrations/lit '@webcomponents/template-shadowroot': specifier: ^0.2.1 version: 0.2.1 astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro lit: specifier: ^2.8.0 @@ -185,23 +185,23 @@ importers: specifier: ^3.0.1 version: link:../../packages/integrations/preact '@astrojs/react': - specifier: ^3.0.5 + specifier: ^3.0.7 version: link:../../packages/integrations/react '@astrojs/solid-js': specifier: ^3.0.2 version: link:../../packages/integrations/solid '@astrojs/svelte': - specifier: ^4.0.4 + specifier: ^5.0.1 version: link:../../packages/integrations/svelte '@astrojs/vue': - specifier: ^3.0.4 + specifier: ^4.0.3 version: link:../../packages/integrations/vue astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.2.0 version: 18.2.0 @@ -209,14 +209,14 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) examples/framework-preact: dependencies: @@ -225,27 +225,27 @@ importers: version: link:../../packages/integrations/preact '@preact/signals': specifier: ^1.2.1 - version: 1.2.1(preact@10.18.1) + version: 1.2.1(preact@10.19.2) astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 examples/framework-react: dependencies: '@astrojs/react': - specifier: ^3.0.5 + specifier: ^3.0.7 version: link:../../packages/integrations/react '@types/react': - specifier: ^18.2.21 - version: 18.2.31 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.14 + specifier: ^18.2.15 + version: 18.2.15 astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro react: specifier: ^18.2.0 @@ -260,58 +260,58 @@ importers: specifier: ^3.0.2 version: link:../../packages/integrations/solid astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 examples/framework-svelte: dependencies: '@astrojs/svelte': - specifier: ^4.0.4 + specifier: ^5.0.1 version: link:../../packages/integrations/svelte astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 examples/framework-vue: dependencies: '@astrojs/vue': - specifier: ^3.0.4 + specifier: ^4.0.3 version: link:../../packages/integrations/vue astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) examples/hackernews: dependencies: '@astrojs/node': - specifier: ^6.0.4 + specifier: ^7.0.1 version: link:../../packages/integrations/node astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/integration: devDependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/middleware: dependencies: '@astrojs/node': - specifier: ^6.0.4 + specifier: ^7.0.1 version: link:../../packages/integrations/node astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro html-minifier: specifier: ^4.0.0 @@ -320,74 +320,74 @@ importers: examples/minimal: dependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/non-html-pages: dependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/portfolio: dependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/ssr: dependencies: '@astrojs/node': - specifier: ^6.0.4 + specifier: ^7.0.1 version: link:../../packages/integrations/node '@astrojs/svelte': - specifier: ^4.0.4 + specifier: ^5.0.1 version: link:../../packages/integrations/svelte astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 examples/view-transitions: devDependencies: '@astrojs/node': - specifier: ^6.0.4 + specifier: ^7.0.1 version: link:../../packages/integrations/node '@astrojs/tailwind': - specifier: ^5.0.2 + specifier: ^5.0.3 version: link:../../packages/integrations/tailwind astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/with-markdoc: dependencies: '@astrojs/markdoc': - specifier: ^0.7.2 + specifier: ^0.8.0 version: link:../../packages/integrations/markdoc astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/with-markdown-plugins: dependencies: '@astrojs/markdown-remark': - specifier: ^3.5.0 + specifier: ^4.0.1 version: link:../../packages/markdown/remark astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro hast-util-select: - specifier: ^5.0.5 - version: 5.0.5 + specifier: ^6.0.2 + version: 6.0.2 rehype-autolink-headings: - specifier: ^6.1.1 - version: 6.1.1 + specifier: ^7.1.0 + version: 7.1.0 rehype-slug: - specifier: ^5.1.0 - version: 5.1.0 + specifier: ^6.0.0 + version: 6.0.0 rehype-toc: specifier: ^3.0.2 version: 3.0.2 @@ -398,23 +398,23 @@ importers: examples/with-markdown-shiki: dependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro examples/with-mdx: dependencies: '@astrojs/mdx': - specifier: ^1.1.5 + specifier: ^2.0.1 version: link:../../packages/integrations/mdx '@astrojs/preact': specifier: ^3.0.1 version: link:../../packages/integrations/preact astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 examples/with-nanostores: dependencies: @@ -423,60 +423,48 @@ importers: version: link:../../packages/integrations/preact '@nanostores/preact': specifier: ^0.5.0 - version: 0.5.0(nanostores@0.9.4)(preact@10.18.1) + version: 0.5.0(nanostores@0.9.5)(preact@10.19.2) astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro nanostores: - specifier: ^0.9.3 - version: 0.9.4 + specifier: ^0.9.5 + version: 0.9.5 preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 examples/with-tailwindcss: dependencies: '@astrojs/mdx': - specifier: ^1.1.5 + specifier: ^2.0.1 version: link:../../packages/integrations/mdx '@astrojs/tailwind': - specifier: ^5.0.2 + specifier: ^5.0.3 version: link:../../packages/integrations/tailwind '@types/canvas-confetti': - specifier: ^1.6.0 - version: 1.6.2 + specifier: ^1.6.3 + version: 1.6.3 astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro autoprefixer: specifier: ^10.4.15 version: 10.4.16(postcss@8.4.31) canvas-confetti: - specifier: ^1.6.0 - version: 1.9.0 + specifier: ^1.9.1 + version: 1.9.1 postcss: specifier: ^8.4.28 version: 8.4.31 tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 - - examples/with-vite-plugin-pwa: - dependencies: - astro: - specifier: ^3.5.5 - version: link:../../packages/astro - vite-plugin-pwa: - specifier: 0.16.4 - version: 0.16.4(workbox-window@7.0.0) - workbox-window: - specifier: ^7.0.0 - version: 7.0.0 + specifier: ^3.3.5 + version: 3.3.5 examples/with-vitest: dependencies: astro: - specifier: ^3.5.5 + specifier: ^4.0.5 version: link:../../packages/astro vitest: specifier: ^0.34.2 @@ -485,8 +473,8 @@ importers: packages/astro: dependencies: '@astrojs/compiler': - specifier: ^2.3.0 - version: 2.3.0 + specifier: ^2.3.2 + version: 2.3.2 '@astrojs/internal-helpers': specifier: workspace:* version: link:../internal-helpers @@ -497,29 +485,29 @@ importers: specifier: workspace:* version: link:../telemetry '@babel/core': - specifier: ^7.22.10 - version: 7.23.2 + specifier: ^7.23.3 + version: 7.23.3 '@babel/generator': - specifier: ^7.22.10 - version: 7.23.0 + specifier: ^7.23.3 + version: 7.23.3 '@babel/parser': - specifier: ^7.22.10 - version: 7.23.0 + specifier: ^7.23.3 + version: 7.23.3 '@babel/plugin-transform-react-jsx': specifier: ^7.22.5 - version: 7.22.15(@babel/core@7.23.2) + version: 7.22.15(@babel/core@7.23.3) '@babel/traverse': - specifier: ^7.22.10 - version: 7.23.2 + specifier: ^7.23.3 + version: 7.23.3 '@babel/types': - specifier: ^7.22.10 - version: 7.23.0 + specifier: ^7.23.3 + version: 7.23.3 '@types/babel__core': - specifier: ^7.20.1 - version: 7.20.3 + specifier: ^7.20.4 + version: 7.20.4 acorn: - specifier: ^8.10.0 - version: 8.10.0 + specifier: ^8.11.2 + version: 8.11.2 boxen: specifier: ^7.1.1 version: 7.1.1 @@ -527,8 +515,8 @@ importers: specifier: ^3.5.3 version: 3.5.3 ci-info: - specifier: ^3.8.0 - version: 3.9.0 + specifier: ^4.0.0 + version: 4.0.0 clsx: specifier: ^2.0.0 version: 2.0.0 @@ -536,26 +524,32 @@ importers: specifier: ^1.0.1 version: 1.0.1 cookie: - specifier: ^0.5.0 - version: 0.5.0 + specifier: ^0.6.0 + version: 0.6.0 debug: specifier: ^4.3.4 version: 4.3.4(supports-color@8.1.1) deterministic-object-hash: - specifier: ^1.3.1 - version: 1.3.1 + specifier: ^2.0.1 + version: 2.0.1 devalue: specifier: ^4.3.2 version: 4.3.2 diff: specifier: ^5.1.0 version: 5.1.0 + dlv: + specifier: ^1.1.3 + version: 1.1.3 + dset: + specifier: ^3.1.3 + version: 3.1.3 es-module-lexer: - specifier: ^1.3.0 - version: 1.3.1 + specifier: ^1.4.1 + version: 1.4.1 esbuild: - specifier: ^0.19.2 - version: 0.19.5 + specifier: ^0.19.6 + version: 0.19.6 estree-walker: specifier: ^3.0.3 version: 3.0.3 @@ -563,8 +557,11 @@ importers: specifier: ^8.0.1 version: 8.0.1 fast-glob: - specifier: ^3.3.1 - version: 3.3.1 + specifier: ^3.3.2 + version: 3.3.2 + flattie: + specifier: ^1.1.0 + version: 1.1.0 github-slugger: specifier: ^2.0.0 version: 2.0.0 @@ -587,8 +584,8 @@ importers: specifier: ^0.30.3 version: 0.30.5 mdast-util-to-hast: - specifier: 12.3.0 - version: 12.3.0 + specifier: 13.0.2 + version: 13.0.2 mime: specifier: ^3.0.0 version: 3.0.0 @@ -596,8 +593,8 @@ importers: specifier: ^7.0.1 version: 7.0.1 p-limit: - specifier: ^4.0.0 - version: 4.0.0 + specifier: ^5.0.0 + version: 5.0.0 p-queue: specifier: ^7.4.1 version: 7.4.1 @@ -614,8 +611,8 @@ importers: specifier: ^2.4.2 version: 2.4.2 rehype: - specifier: ^12.0.1 - version: 12.0.1 + specifier: ^13.0.1 + version: 13.0.1 resolve: specifier: ^1.22.4 version: 1.22.8 @@ -626,29 +623,29 @@ importers: specifier: ^1.0.1 version: 1.0.1 shikiji: - specifier: ^0.6.8 - version: 0.6.10 + specifier: ^0.6.13 + version: 0.6.13 string-width: - specifier: ^6.1.0 - version: 6.1.0 + specifier: ^7.0.0 + version: 7.0.0 strip-ansi: specifier: ^7.1.0 version: 7.1.0 tsconfck: specifier: ^3.0.0 - version: 3.0.0(typescript@5.1.6) + version: 3.0.0(typescript@5.2.2) unist-util-visit: - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^5.0.0 + version: 5.0.0 vfile: - specifier: ^5.3.7 - version: 5.3.7 + specifier: ^6.0.1 + version: 6.0.1 vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) vitefu: - specifier: ^0.2.4 - version: 0.2.5(vite@4.5.0) + specifier: ^0.2.5 + version: 0.2.5(vite@5.0.0) which-pm: specifier: ^2.1.1 version: 2.1.1 @@ -664,80 +661,86 @@ importers: version: 0.32.6 devDependencies: '@astrojs/check': - specifier: ^0.1.0 - version: 0.1.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6) + specifier: ^0.3.1 + version: 0.3.1(prettier-plugin-astro@0.12.2)(prettier@3.1.0)(typescript@5.2.2) '@playwright/test': - specifier: 1.40.0-alpha-nov-13-2023 - version: 1.40.0-alpha-nov-13-2023 + specifier: 1.40.0 + version: 1.40.0 '@types/babel__generator': - specifier: ^7.6.4 - version: 7.6.6 + specifier: ^7.6.7 + version: 7.6.7 '@types/babel__traverse': - specifier: ^7.20.1 - version: 7.20.3 + specifier: ^7.20.4 + version: 7.20.4 '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 '@types/common-ancestor-path': - specifier: ^1.0.0 - version: 1.0.1 + specifier: ^1.0.2 + version: 1.0.2 '@types/connect': - specifier: ^3.4.35 - version: 3.4.37 + specifier: ^3.4.38 + version: 3.4.38 '@types/cookie': - specifier: ^0.5.1 - version: 0.5.3 + specifier: ^0.5.4 + version: 0.5.4 '@types/debug': - specifier: ^4.1.8 - version: 4.1.10 + specifier: ^4.1.12 + version: 4.1.12 '@types/diff': - specifier: ^5.0.3 - version: 5.0.7 + specifier: ^5.0.8 + version: 5.0.8 + '@types/dlv': + specifier: ^1.1.4 + version: 1.1.4 '@types/dom-view-transitions': - specifier: ^1.0.1 - version: 1.0.3 + specifier: ^1.0.4 + version: 1.0.4 '@types/estree': - specifier: ^1.0.1 - version: 1.0.3 + specifier: ^1.0.5 + version: 1.0.5 '@types/hast': - specifier: ^2.3.5 - version: 2.3.7 + specifier: ^3.0.3 + version: 3.0.3 '@types/html-escaper': - specifier: ^3.0.0 - version: 3.0.1 + specifier: ^3.0.2 + version: 3.0.2 '@types/http-cache-semantics': - specifier: ^4.0.1 - version: 4.0.3 + specifier: ^4.0.4 + version: 4.0.4 '@types/js-yaml': - specifier: ^4.0.5 - version: 4.0.8 + specifier: ^4.0.9 + version: 4.0.9 '@types/mime': - specifier: ^3.0.1 - version: 3.0.3 + specifier: ^3.0.4 + version: 3.0.4 '@types/mocha': - specifier: ^10.0.1 - version: 10.0.3 + specifier: ^10.0.4 + version: 10.0.4 '@types/probe-image-size': - specifier: ^7.2.0 - version: 7.2.2 + specifier: ^7.2.3 + version: 7.2.3 '@types/prompts': - specifier: ^2.4.4 - version: 2.4.7 + specifier: ^2.4.8 + version: 2.4.8 '@types/resolve': - specifier: ^1.20.2 - version: 1.20.4 + specifier: ^1.20.5 + version: 1.20.5 + '@types/semver': + specifier: ^7.5.2 + version: 7.5.4 '@types/send': - specifier: ^0.17.1 - version: 0.17.3 + specifier: ^0.17.4 + version: 0.17.4 '@types/server-destroy': - specifier: ^1.0.1 - version: 1.0.2 + specifier: ^1.0.3 + version: 1.0.3 '@types/unist': - specifier: ^2.0.7 - version: 2.0.9 + specifier: ^3.0.2 + version: 3.0.2 '@types/yargs-parser': - specifier: ^21.0.0 - version: 21.0.2 + specifier: ^21.0.3 + version: 21.0.3 astro-scripts: specifier: workspace:* version: link:../../scripts @@ -763,11 +766,11 @@ importers: specifier: ^1.0.2 version: 1.0.2 rehype-autolink-headings: - specifier: ^6.1.1 - version: 6.1.1 + specifier: ^7.1.0 + version: 7.1.0 rehype-slug: - specifier: ^5.0.1 - version: 5.1.0 + specifier: ^6.0.0 + version: 6.0.0 rehype-toc: specifier: ^3.0.2 version: 3.0.2 @@ -775,17 +778,17 @@ importers: specifier: ^0.1.2 version: 0.1.2 rollup: - specifier: ^3.28.1 - version: 3.29.4 + specifier: ^4.5.0 + version: 4.5.0 sass: - specifier: ^1.66.1 - version: 1.69.4 + specifier: ^1.69.5 + version: 1.69.5 srcset-parse: specifier: ^1.1.0 version: 1.1.0 unified: - specifier: ^10.1.2 - version: 10.1.2 + specifier: ^11.0.4 + version: 11.0.4 packages/astro-prism: dependencies: @@ -794,8 +797,8 @@ importers: version: 1.29.0 devDependencies: '@types/prismjs': - specifier: 1.26.0 - version: 1.26.0 + specifier: 1.26.3 + version: 1.26.3 astro-scripts: specifier: workspace:* version: link:../../scripts @@ -810,14 +813,14 @@ importers: version: 4.1.5 devDependencies: '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 '@types/chai-as-promised': - specifier: ^7.1.5 - version: 7.1.7 + specifier: ^7.1.8 + version: 7.1.8 '@types/mocha': - specifier: ^10.0.1 - version: 10.0.3 + specifier: ^10.0.4 + version: 10.0.4 astro: specifier: workspace:* version: link:../astro @@ -855,8 +858,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/e2e/fixtures/astro-envs: dependencies: @@ -867,14 +870,14 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/e2e/fixtures/client-only: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -882,14 +885,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -940,8 +943,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/e2e/fixtures/error-cyclic: dependencies: @@ -952,8 +955,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/e2e/fixtures/error-sass: dependencies: @@ -961,8 +964,8 @@ importers: specifier: workspace:* version: link:../../.. sass: - specifier: ^1.66.1 - version: 1.69.4 + specifier: ^1.69.5 + version: 1.69.5 packages/astro/e2e/fixtures/errors: dependencies: @@ -985,8 +988,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -994,17 +997,17 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) sass: - specifier: ^1.66.1 - version: 1.69.4 + specifier: ^1.69.5 + version: 1.69.5 solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/e2e/fixtures/hmr: devDependencies: @@ -1012,8 +1015,8 @@ importers: specifier: workspace:* version: link:../../.. sass: - specifier: ^1.66.1 - version: 1.69.4 + specifier: ^1.69.5 + version: 1.69.5 packages/astro/e2e/fixtures/hydration-race: dependencies: @@ -1024,8 +1027,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/e2e/fixtures/lit-component: dependencies: @@ -1039,8 +1042,8 @@ importers: specifier: workspace:* version: link:../../.. lit: - specifier: ^2.8.0 - version: 2.8.0 + specifier: ^3.1.0 + version: 3.1.0 packages/astro/e2e/fixtures/multiple-frameworks: dependencies: @@ -1051,8 +1054,8 @@ importers: specifier: ^2.8.0 version: 2.8.0 preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1060,14 +1063,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/lit': specifier: workspace:* @@ -1094,8 +1097,8 @@ importers: packages/astro/e2e/fixtures/namespaced-component: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 devDependencies: '@astrojs/mdx': specifier: workspace:* @@ -1110,8 +1113,8 @@ importers: packages/astro/e2e/fixtures/nested-in-preact: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1119,14 +1122,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -1150,8 +1153,8 @@ importers: packages/astro/e2e/fixtures/nested-in-react: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1159,14 +1162,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -1190,8 +1193,8 @@ importers: packages/astro/e2e/fixtures/nested-in-solid: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1199,14 +1202,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -1230,8 +1233,8 @@ importers: packages/astro/e2e/fixtures/nested-in-svelte: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1239,14 +1242,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -1270,8 +1273,8 @@ importers: packages/astro/e2e/fixtures/nested-in-vue: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1279,14 +1282,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -1310,8 +1313,8 @@ importers: packages/astro/e2e/fixtures/nested-recursive: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -1319,14 +1322,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/preact': specifier: workspace:* @@ -1378,8 +1381,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/e2e/fixtures/preact-component: dependencies: @@ -1393,8 +1396,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/e2e/fixtures/prefetch: dependencies: @@ -1430,8 +1433,8 @@ importers: version: link:../../.. devDependencies: solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/e2e/fixtures/solid-component: dependencies: @@ -1445,8 +1448,8 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/e2e/fixtures/solid-recurse: dependencies: @@ -1458,8 +1461,8 @@ importers: version: link:../../.. devDependencies: solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/e2e/fixtures/svelte-component: dependencies: @@ -1473,8 +1476,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/e2e/fixtures/tailwindcss: dependencies: @@ -1491,8 +1494,8 @@ importers: specifier: ^8.4.28 version: 8.4.31 tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.3.5 + version: 3.3.5 packages/astro/e2e/fixtures/ts-resolution: dependencies: @@ -1533,11 +1536,11 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/e2e/fixtures/vue-component: dependencies: @@ -1551,14 +1554,14 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/performance: devDependencies: '@types/yargs-parser': - specifier: ^21.0.0 - version: 21.0.2 + specifier: ^21.0.3 + version: 21.0.3 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -1581,11 +1584,11 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.2.21 - version: 18.2.31 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.14 + specifier: ^18.2.15 + version: 18.2.15 astro: specifier: workspace:* version: link:../../.. @@ -1608,11 +1611,11 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.2.21 - version: 18.2.31 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.14 + specifier: ^18.2.15 + version: 18.2.15 astro: specifier: workspace:* version: link:../../.. @@ -1635,11 +1638,11 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.2.21 - version: 18.2.31 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.14 + specifier: ^18.2.15 + version: 18.2.15 astro: specifier: workspace:* version: link:../../.. @@ -1683,11 +1686,11 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/alias: dependencies: @@ -1698,8 +1701,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/alias-tsconfig: dependencies: @@ -1713,8 +1716,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/alias-tsconfig-baseurl-only: dependencies: @@ -1725,8 +1728,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/alias-tsconfig/deps/namespace-package: {} @@ -1796,8 +1799,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/astro-check-errors: dependencies: @@ -1832,14 +1835,14 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/astro-class-list: dependencies: @@ -1868,8 +1871,8 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/astro-client-only/pkg: {} @@ -1954,8 +1957,8 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/astro-envs: dependencies: @@ -1966,8 +1969,8 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/astro-expr: dependencies: @@ -1978,8 +1981,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/astro-external-files: dependencies: @@ -1996,8 +1999,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/astro-generator: dependencies: @@ -2038,12 +2041,6 @@ importers: specifier: workspace:* version: link:../../.. - packages/astro/test/fixtures/astro-markdown-drafts: - dependencies: - astro: - specifier: workspace:* - version: link:../../.. - packages/astro/test/fixtures/astro-markdown-frontmatter-injection: dependencies: astro: @@ -2065,11 +2062,11 @@ importers: specifier: workspace:* version: link:../../.. hast-util-select: - specifier: ^6.0.0 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 rehype-slug: - specifier: ^5.0.1 - version: 5.1.0 + specifier: ^6.0.0 + version: 6.0.0 packages/astro/test/fixtures/astro-markdown-remarkRehype: dependencies: @@ -2212,8 +2209,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/astro-slots: dependencies: @@ -2242,8 +2239,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.2.0 version: 18.2.0 @@ -2251,14 +2248,14 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/before-hydration: dependencies: @@ -2269,8 +2266,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/build-assets: dependencies: @@ -2281,8 +2278,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/client-address: dependencies: @@ -2314,8 +2311,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -2323,14 +2320,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/component-library-shared: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.2.0 version: 18.2.0 @@ -2503,8 +2500,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: '4' - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/css-import-as-inline: dependencies: @@ -2674,8 +2671,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/error-bad-js: dependencies: @@ -2710,23 +2707,23 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/fontsource-package: dependencies: '@fontsource/monofett': - specifier: 5.0.9 - version: 5.0.9 + specifier: 5.0.17 + version: 5.0.17 '@fontsource/montserrat': - specifier: 5.0.8 - version: 5.0.8 + specifier: 5.0.15 + version: 5.0.15 astro: specifier: workspace:* version: link:../../.. @@ -2794,8 +2791,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/i18n-routing: dependencies: @@ -2869,8 +2866,8 @@ importers: packages/astro/test/fixtures/jsx: dependencies: preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -2878,14 +2875,14 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: '@astrojs/mdx': specifier: workspace:* @@ -2918,8 +2915,8 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/test/fixtures/lazy-layout: dependencies: @@ -3060,18 +3057,18 @@ importers: specifier: ^8.4.28 version: 8.4.31 solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) devDependencies: postcss-preset-env: - specifier: ^9.1.1 - version: 9.2.0(postcss@8.4.31) + specifier: ^9.3.0 + version: 9.3.0(postcss@8.4.31) packages/astro/test/fixtures/preact-compat-component: dependencies: @@ -3085,8 +3082,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/preact-compat-component/packages/react-lib: dependencies: @@ -3101,13 +3098,13 @@ importers: version: link:../../../../integrations/preact '@preact/signals': specifier: 1.2.1 - version: 1.2.1(preact@10.18.1) + version: 1.2.1(preact@10.19.2) astro: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/public-base-404: dependencies: @@ -3133,8 +3130,8 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/test/fixtures/react-jsx-export: dependencies: @@ -3167,8 +3164,8 @@ importers: specifier: 'workspace:' version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/remote-css: dependencies: @@ -3218,8 +3215,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/slots-react: dependencies: @@ -3251,8 +3248,8 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/test/fixtures/slots-svelte: dependencies: @@ -3266,8 +3263,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/slots-vue: dependencies: @@ -3281,8 +3278,8 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/solid-component: dependencies: @@ -3290,8 +3287,8 @@ importers: specifier: workspace:* version: link:../../../../integrations/solid '@solidjs/router': - specifier: ^0.8.3 - version: 0.8.3(solid-js@1.8.3) + specifier: ^0.9.1 + version: 0.9.1(solid-js@1.8.5) '@test/solid-jsx-component': specifier: file:./deps/solid-jsx-component version: file:packages/astro/test/fixtures/solid-component/deps/solid-jsx-component @@ -3299,14 +3296,14 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/test/fixtures/solid-component/deps/solid-jsx-component: dependencies: solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/astro/test/fixtures/sourcemap: dependencies: @@ -3383,8 +3380,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/ssr-hoisted-script: dependencies: @@ -3464,8 +3461,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/ssr-split-manifest: dependencies: @@ -3485,8 +3482,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/astro/test/fixtures/static-build-code-component: dependencies: @@ -3512,8 +3509,8 @@ importers: specifier: workspace:* version: link:../../.. preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 react: specifier: ^18.1.0 version: 18.2.0 @@ -3562,8 +3559,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 packages/astro/test/fixtures/tailwindcss: dependencies: @@ -3583,8 +3580,8 @@ importers: specifier: ^8.4.28 version: 8.4.31 tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.3.5 + version: 3.3.5 packages/astro/test/fixtures/tailwindcss-ts: dependencies: @@ -3598,8 +3595,8 @@ importers: specifier: ^8.4.28 version: 8.4.31 tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.3.5 + version: 3.3.5 packages/astro/test/fixtures/third-party-astro: dependencies: @@ -3607,8 +3604,8 @@ importers: specifier: workspace:* version: link:../../.. astro-embed: - specifier: ^0.5.1 - version: 0.5.1(astro@packages+astro) + specifier: ^0.6.0 + version: 0.6.0(astro@packages+astro) packages/astro/test/fixtures/type-imports: dependencies: @@ -3652,8 +3649,8 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/vue-jsx: dependencies: @@ -3664,8 +3661,8 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/vue-with-multi-renderer: dependencies: @@ -3679,11 +3676,11 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/astro/test/fixtures/with-endpoint-routes: dependencies: @@ -3709,8 +3706,8 @@ importers: specifier: ^0.3.1 version: 0.3.1 giget: - specifier: 1.1.2 - version: 1.1.2 + specifier: 1.1.3 + version: 1.1.3 devDependencies: arg: specifier: ^5.0.2 @@ -3747,13 +3744,13 @@ importers: packages/integrations/lit: dependencies: '@lit-labs/ssr': - specifier: 3.1.7 - version: 3.1.7 + specifier: ^3.2.0 + version: 3.2.0 '@lit-labs/ssr-client': - specifier: 1.1.3 - version: 1.1.3 + specifier: ^1.1.5 + version: 1.1.5 '@lit-labs/ssr-dom-shim': - specifier: ^1.1.1 + specifier: ^1.1.2 version: 1.1.2 parse5: specifier: ^7.1.2 @@ -3772,14 +3769,14 @@ importers: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 lit: - specifier: ^2.8.0 - version: 2.8.0 + specifier: ^3.1.0 + version: 3.1.0 mocha: specifier: ^10.2.0 version: 10.2.0 sass: - specifier: ^1.66.1 - version: 1.69.4 + specifier: ^1.69.5 + version: 1.69.5 packages/integrations/markdoc: dependencies: @@ -3790,11 +3787,11 @@ importers: specifier: workspace:* version: link:../../astro-prism '@markdoc/markdoc': - specifier: ^0.3.0 - version: 0.3.4 + specifier: ^0.3.5 + version: 0.3.5 esbuild: - specifier: ^0.19.2 - version: 0.19.5 + specifier: ^0.19.6 + version: 0.19.6 github-slugger: specifier: ^2.0.0 version: 2.0.0 @@ -3808,8 +3805,8 @@ importers: specifier: ^4.1.5 version: 4.1.5 shikiji: - specifier: ^0.6.8 - version: 0.6.10 + specifier: ^0.6.13 + version: 0.6.13 zod: specifier: ^3.22.4 version: 3.22.4 @@ -3818,17 +3815,17 @@ importers: specifier: workspace:* version: link:../../markdown/remark '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 '@types/html-escaper': - specifier: ^3.0.0 - version: 3.0.1 + specifier: ^3.0.2 + version: 3.0.2 '@types/markdown-it': - specifier: ^13.0.0 - version: 13.0.4 + specifier: ^13.0.6 + version: 13.0.6 '@types/mocha': - specifier: ^10.0.1 - version: 10.0.3 + specifier: ^10.0.4 + version: 10.0.4 astro: specifier: workspace:* version: link:../../astro @@ -3842,17 +3839,14 @@ importers: specifier: ^4.3.2 version: 4.3.2 linkedom: - specifier: ^0.15.1 - version: 0.15.6 + specifier: ^0.16.4 + version: 0.16.4 mocha: specifier: ^10.2.0 version: 10.2.0 - rollup: - specifier: ^3.28.1 - version: 3.29.4 vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) packages/integrations/markdoc/test/fixtures/content-collections: dependencies: @@ -3977,17 +3971,17 @@ importers: specifier: workspace:* version: link:../../markdown/remark '@mdx-js/mdx': - specifier: ^2.3.0 - version: 2.3.0 + specifier: ^3.0.0 + version: 3.0.0 acorn: - specifier: ^8.10.0 - version: 8.10.0 + specifier: ^8.11.2 + version: 8.11.2 es-module-lexer: - specifier: ^1.3.0 - version: 1.3.1 + specifier: ^1.4.1 + version: 1.4.1 estree-util-visit: - specifier: ^1.2.1 - version: 1.2.1 + specifier: ^2.0.0 + version: 2.0.0 github-slugger: specifier: ^2.0.0 version: 2.0.0 @@ -3995,17 +3989,17 @@ importers: specifier: ^4.0.3 version: 4.0.3 hast-util-to-html: - specifier: ^8.0.4 - version: 8.0.4 + specifier: ^9.0.0 + version: 9.0.0 kleur: specifier: ^4.1.4 version: 4.1.5 rehype-raw: - specifier: ^6.1.1 - version: 6.1.1 + specifier: ^7.0.0 + version: 7.0.0 remark-gfm: - specifier: ^3.0.1 - version: 3.0.1 + specifier: ^4.0.0 + version: 4.0.0 remark-smartypants: specifier: ^2.0.0 version: 2.0.0 @@ -4013,27 +4007,27 @@ importers: specifier: ^0.7.4 version: 0.7.4 unist-util-visit: - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^5.0.0 + version: 5.0.0 vfile: - specifier: ^5.3.7 - version: 5.3.7 + specifier: ^6.0.1 + version: 6.0.1 devDependencies: '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 '@types/estree': - specifier: ^1.0.1 - version: 1.0.3 + specifier: ^1.0.5 + version: 1.0.5 '@types/mdast': - specifier: ^3.0.12 - version: 3.0.14 + specifier: ^4.0.3 + version: 4.0.3 '@types/mocha': - specifier: ^10.0.1 - version: 10.0.3 + specifier: ^10.0.4 + version: 10.0.4 '@types/yargs-parser': - specifier: ^21.0.0 - version: 21.0.2 + specifier: ^21.0.3 + version: 21.0.3 astro: specifier: workspace:* version: link:../../astro @@ -4047,14 +4041,14 @@ importers: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 linkedom: - specifier: ^0.15.1 - version: 0.15.6 + specifier: ^0.16.4 + version: 0.16.4 mdast-util-mdx: - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^3.0.0 + version: 3.0.0 mdast-util-to-string: - specifier: ^3.2.0 - version: 3.2.0 + specifier: ^4.0.0 + version: 4.0.0 mocha: specifier: ^10.2.0 version: 10.2.0 @@ -4062,29 +4056,29 @@ importers: specifier: ^1.5.0 version: 1.5.0 rehype-mathjax: - specifier: ^4.0.3 - version: 4.0.3 + specifier: ^5.0.0 + version: 5.0.0 rehype-pretty-code: - specifier: ^0.10.0 - version: 0.10.1 + specifier: ^0.10.2 + version: 0.10.2 remark-math: - specifier: ^5.1.1 - version: 5.1.1 + specifier: ^6.0.0 + version: 6.0.0 remark-rehype: - specifier: ^10.1.0 - version: 10.1.0 + specifier: ^11.0.0 + version: 11.0.0 remark-shiki-twoslash: specifier: ^3.1.3 - version: 3.1.3(typescript@5.1.6) + version: 3.1.3(typescript@5.2.2) remark-toc: - specifier: ^8.0.1 - version: 8.0.1 - unified: - specifier: ^10.1.2 - version: 10.1.2 + specifier: ^9.0.0 + version: 9.0.0 + unified: + specifier: ^11.0.4 + version: 11.0.4 vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) packages/integrations/mdx/test/fixtures/css-head-mdx: dependencies: @@ -4143,8 +4137,8 @@ importers: specifier: workspace:* version: link:../../../../../astro preact: - specifier: ^10.17.1 - version: 10.18.1 + specifier: ^10.19.2 + version: 10.19.2 packages/integrations/mdx/test/fixtures/mdx-namespace: dependencies: @@ -4230,11 +4224,11 @@ importers: specifier: ^18.17.8 version: 18.18.6 '@types/send': - specifier: ^0.17.1 - version: 0.17.3 + specifier: ^0.17.4 + version: 0.17.4 '@types/server-destroy': - specifier: ^1.0.1 - version: 1.0.2 + specifier: ^1.0.3 + version: 1.0.3 astro: specifier: workspace:* version: link:../../astro @@ -4385,22 +4379,22 @@ importers: dependencies: '@babel/plugin-transform-react-jsx': specifier: ^7.22.5 - version: 7.22.15(@babel/core@7.23.2) + version: 7.22.15(@babel/core@7.23.3) '@babel/plugin-transform-react-jsx-development': specifier: ^7.22.5 version: 7.22.5 '@preact/preset-vite': - specifier: ^2.5.0 - version: 2.6.0(preact@10.18.1) + specifier: ^2.7.0 + version: 2.7.0(preact@10.19.2) '@preact/signals': specifier: ^1.2.1 - version: 1.2.1(preact@10.18.1) + version: 1.2.1(preact@10.19.2) babel-plugin-transform-hook-names: specifier: ^1.0.2 version: 1.0.2 preact-render-to-string: - specifier: ^6.2.1 - version: 6.2.2(preact@10.18.1) + specifier: ^6.3.1 + version: 6.3.1(preact@10.19.2) devDependencies: astro: specifier: workspace:* @@ -4409,58 +4403,24 @@ importers: specifier: workspace:* version: link:../../../scripts preact: - specifier: ^10.17.1 - version: 10.18.1 - - packages/integrations/prefetch: - dependencies: - throttles: - specifier: ^1.0.1 - version: 1.0.1 - devDependencies: - '@playwright/test': - specifier: ^1.37.1 - version: 1.39.0 - astro: - specifier: workspace:* - version: link:../../astro - astro-scripts: - specifier: workspace:* - version: link:../../../scripts - - packages/integrations/prefetch/test/fixtures/basic-prefetch: - dependencies: - '@astrojs/prefetch': - specifier: workspace:* - version: link:../../.. - astro: - specifier: workspace:* - version: link:../../../../../astro - - packages/integrations/prefetch/test/fixtures/style-prefetch: - dependencies: - '@astrojs/prefetch': - specifier: workspace:* - version: link:../../.. - astro: - specifier: workspace:* - version: link:../../../../../astro + specifier: ^10.19.2 + version: 10.19.2 packages/integrations/react: dependencies: '@vitejs/plugin-react': - specifier: ^4.0.4 - version: 4.1.0(vite@4.5.0) + specifier: ^4.2.0 + version: 4.2.0(vite@5.0.0) ultrahtml: specifier: ^1.3.0 version: 1.5.2 devDependencies: '@types/react': - specifier: ^18.2.21 - version: 18.2.31 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.14 + specifier: ^18.2.15 + version: 18.2.15 astro: specifier: workspace:* version: link:../../astro @@ -4473,6 +4433,9 @@ importers: cheerio: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 + mocha: + specifier: ^10.2.0 + version: 10.2.0 react: specifier: ^18.1.0 version: 18.2.0 @@ -4480,8 +4443,8 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) packages/integrations/react/test/fixtures/react-component: dependencies: @@ -4501,8 +4464,8 @@ importers: specifier: ^18.1.0 version: 18.2.0(react@18.2.0) vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/integrations/sitemap: dependencies: @@ -4563,7 +4526,7 @@ importers: dependencies: vite-plugin-solid: specifier: ^2.7.0 - version: 2.7.2(solid-js@1.8.3) + version: 2.7.2(solid-js@1.8.5) devDependencies: astro: specifier: workspace:* @@ -4572,17 +4535,17 @@ importers: specifier: workspace:* version: link:../../../scripts solid-js: - specifier: ^1.7.11 - version: 1.8.3 + specifier: ^1.8.5 + version: 1.8.5 packages/integrations/svelte: dependencies: '@sveltejs/vite-plugin-svelte': - specifier: ^2.5.2 - version: 2.5.2(svelte@4.2.2)(vite@4.5.0) + specifier: ^3.0.0 + version: 3.0.0(svelte@4.2.5)(vite@5.0.0) svelte2tsx: - specifier: ^0.6.20 - version: 0.6.23(svelte@4.2.2)(typescript@5.1.6) + specifier: ^0.6.25 + version: 0.6.25(svelte@4.2.5)(typescript@5.2.2) devDependencies: astro: specifier: workspace:* @@ -4591,11 +4554,11 @@ importers: specifier: workspace:* version: link:../../../scripts svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) packages/integrations/tailwind: dependencies: @@ -4606,8 +4569,8 @@ importers: specifier: ^8.4.28 version: 8.4.31 postcss-load-config: - specifier: ^4.0.1 - version: 4.0.1(postcss@8.4.31) + specifier: ^4.0.2 + version: 4.0.2(postcss@8.4.31) devDependencies: astro: specifier: workspace:* @@ -4616,11 +4579,11 @@ importers: specifier: workspace:* version: link:../../../scripts tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.3.5 + version: 3.3.5 vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) packages/integrations/vercel: dependencies: @@ -4631,14 +4594,14 @@ importers: specifier: ^1.0.2 version: 1.1.1 '@vercel/nft': - specifier: ^0.23.1 - version: 0.23.1 + specifier: ^0.24.3 + version: 0.24.3 esbuild: - specifier: ^0.19.2 - version: 0.19.5 + specifier: ^0.19.6 + version: 0.19.6 fast-glob: - specifier: ^3.3.1 - version: 3.3.1 + specifier: ^3.3.2 + version: 3.3.2 set-cookie-parser: specifier: ^2.6.0 version: 2.6.0 @@ -4647,11 +4610,11 @@ importers: version: 3.5.0 devDependencies: '@types/set-cookie-parser': - specifier: ^2.4.3 - version: 2.4.5 + specifier: ^2.4.6 + version: 2.4.6 '@vercel/edge': - specifier: ^1.0.0 - version: 1.1.0 + specifier: ^1.1.1 + version: 1.1.1 astro: specifier: workspace:* version: link:../../astro @@ -4827,21 +4790,21 @@ importers: packages/integrations/vue: dependencies: '@vitejs/plugin-vue': - specifier: ^4.3.3 - version: 4.4.0(vite@4.5.0)(vue@3.3.6) + specifier: ^4.5.0 + version: 4.5.0(vite@5.0.0)(vue@3.3.8) '@vitejs/plugin-vue-jsx': - specifier: ^3.0.2 - version: 3.0.2(vite@4.5.0)(vue@3.3.6) + specifier: ^3.1.0 + version: 3.1.0(vite@5.0.0)(vue@3.3.8) '@vue/babel-plugin-jsx': specifier: ^1.1.5 - version: 1.1.5(@babel/core@7.23.2) + version: 1.1.5(@babel/core@7.23.3) '@vue/compiler-sfc': - specifier: ^3.3.4 - version: 3.3.6 + specifier: ^3.3.8 + version: 3.3.8 devDependencies: '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 astro: specifier: workspace:* version: link:../../astro @@ -4855,19 +4818,31 @@ importers: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 linkedom: - specifier: ^0.15.1 - version: 0.15.6 + specifier: ^0.16.4 + version: 0.16.4 mocha: specifier: ^10.2.0 version: 10.2.0 vite: - specifier: ^4.4.9 - version: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + specifier: ^5.0.0 + version: 5.0.0(@types/node@18.18.6)(sass@1.69.5) vue: - specifier: ^3.3.4 - version: 3.3.6(typescript@5.1.6) + specifier: ^3.3.8 + version: 3.3.8(typescript@5.2.2) packages/integrations/vue/test/fixtures/app-entrypoint: + dependencies: + '@astrojs/vue': + specifier: workspace:* + version: link:../../.. + astro: + specifier: workspace:* + version: link:../../../../../astro + vite-svg-loader: + specifier: 5.0.1 + version: 5.0.1 + + packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default: dependencies: '@astrojs/vue': specifier: workspace:* @@ -4879,6 +4854,24 @@ importers: specifier: 4.0.0 version: 4.0.0 + packages/integrations/vue/test/fixtures/app-entrypoint-relative: + dependencies: + '@astrojs/vue': + specifier: workspace:* + version: link:../../.. + astro: + specifier: workspace:* + version: link:../../../../../astro + + packages/integrations/vue/test/fixtures/app-entrypoint-src-absolute: + dependencies: + '@astrojs/vue': + specifier: workspace:* + version: link:../../.. + astro: + specifier: workspace:* + version: link:../../../../../astro + packages/integrations/vue/test/fixtures/basics: dependencies: '@astrojs/vue': @@ -4903,60 +4896,60 @@ importers: specifier: ^2.0.0 version: 2.0.0 import-meta-resolve: - specifier: ^3.0.0 - version: 3.0.0 + specifier: ^4.0.0 + version: 4.0.0 mdast-util-definitions: specifier: ^6.0.0 version: 6.0.0 rehype-raw: - specifier: ^6.1.1 - version: 6.1.1 + specifier: ^7.0.0 + version: 7.0.0 rehype-stringify: - specifier: ^9.0.4 - version: 9.0.4 + specifier: ^10.0.0 + version: 10.0.0 remark-gfm: - specifier: ^3.0.1 - version: 3.0.1 + specifier: ^4.0.0 + version: 4.0.0 remark-parse: - specifier: ^10.0.2 - version: 10.0.2 + specifier: ^11.0.0 + version: 11.0.0 remark-rehype: - specifier: ^10.1.0 - version: 10.1.0 + specifier: ^11.0.0 + version: 11.0.0 remark-smartypants: specifier: ^2.0.0 version: 2.0.0 shikiji: - specifier: ^0.6.8 - version: 0.6.10 + specifier: ^0.6.13 + version: 0.6.13 unified: - specifier: ^10.1.2 - version: 10.1.2 + specifier: ^11.0.4 + version: 11.0.4 unist-util-visit: - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^5.0.0 + version: 5.0.0 vfile: - specifier: ^5.3.7 - version: 5.3.7 + specifier: ^6.0.1 + version: 6.0.1 devDependencies: '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 '@types/estree': - specifier: ^1.0.1 - version: 1.0.3 + specifier: ^1.0.5 + version: 1.0.5 '@types/hast': - specifier: ^2.3.5 - version: 2.3.7 + specifier: ^3.0.3 + version: 3.0.3 '@types/mdast': - specifier: ^3.0.12 - version: 3.0.14 + specifier: ^4.0.3 + version: 4.0.3 '@types/mocha': - specifier: ^10.0.1 - version: 10.0.3 + specifier: ^10.0.4 + version: 10.0.4 '@types/unist': - specifier: ^2.0.7 - version: 2.0.9 + specifier: ^3.0.2 + version: 3.0.2 astro-scripts: specifier: workspace:* version: link:../../../scripts @@ -4964,8 +4957,8 @@ importers: specifier: ^4.3.7 version: 4.3.10 mdast-util-mdx-expression: - specifier: ^1.3.2 - version: 1.3.2 + specifier: ^2.0.0 + version: 2.0.0 mocha: specifier: ^10.2.0 version: 10.2.0 @@ -4973,8 +4966,8 @@ importers: packages/telemetry: dependencies: ci-info: - specifier: ^3.8.0 - version: 3.9.0 + specifier: ^4.0.0 + version: 4.0.0 debug: specifier: ^4.3.4 version: 4.3.4(supports-color@8.1.1) @@ -4982,8 +4975,8 @@ importers: specifier: ^1.1.3 version: 1.1.3 dset: - specifier: ^3.1.2 - version: 3.1.2 + specifier: ^3.1.3 + version: 3.1.3 is-docker: specifier: ^3.0.0 version: 3.0.0 @@ -4995,17 +4988,17 @@ importers: version: 1.1.0 devDependencies: '@types/debug': - specifier: ^4.1.8 - version: 4.1.10 + specifier: ^4.1.12 + version: 4.1.12 '@types/dlv': - specifier: ^1.1.2 - version: 1.1.3 + specifier: ^1.1.4 + version: 1.1.4 '@types/node': specifier: ^18.17.8 version: 18.18.6 '@types/which-pm-runs': - specifier: ^1.0.0 - version: 1.0.1 + specifier: ^1.0.2 + version: 1.0.2 astro-scripts: specifier: workspace:* version: link:../../scripts @@ -5019,11 +5012,11 @@ importers: packages/underscore-redirects: devDependencies: '@types/chai': - specifier: ^4.3.5 - version: 4.3.9 + specifier: ^4.3.10 + version: 4.3.10 '@types/mocha': - specifier: ^10.0.1 - version: 10.0.3 + specifier: ^10.0.4 + version: 10.0.4 astro: specifier: workspace:* version: link:../astro @@ -5037,26 +5030,63 @@ importers: specifier: ^10.2.0 version: 10.2.0 + packages/upgrade: + dependencies: + '@astrojs/cli-kit': + specifier: ^0.2.3 + version: 0.2.3 + semver: + specifier: ^7.5.4 + version: 7.5.4 + terminal-link: + specifier: ^3.0.0 + version: 3.0.0 + which-pm-runs: + specifier: ^1.1.0 + version: 1.1.0 + devDependencies: + '@types/semver': + specifier: ^7.5.2 + version: 7.5.4 + '@types/which-pm-runs': + specifier: ^1.0.0 + version: 1.0.2 + arg: + specifier: ^5.0.2 + version: 5.0.2 + astro-scripts: + specifier: workspace:* + version: link:../../scripts + chai: + specifier: ^4.3.7 + version: 4.3.10 + mocha: + specifier: ^10.2.0 + version: 10.2.0 + strip-ansi: + specifier: ^7.1.0 + version: 7.1.0 + scripts: dependencies: arg: specifier: ^5.0.2 version: 5.0.2 esbuild: - specifier: ^0.19.2 - version: 0.19.5 + specifier: ^0.19.6 + version: 0.19.6 globby: - specifier: ^13.2.2 - version: 13.2.2 + specifier: ^14.0.0 + version: 14.0.0 kleur: specifier: ^4.1.4 version: 4.1.5 p-limit: - specifier: ^4.0.0 - version: 4.0.0 + specifier: ^5.0.0 + version: 5.0.0 svelte: - specifier: ^4.2.0 - version: 4.2.2 + specifier: ^4.2.5 + version: 4.2.5 tar: specifier: ^6.1.15 version: 6.2.0 @@ -5069,7 +5099,7 @@ importers: version: 7.1.0 esbuild-plugin-copy: specifier: ^2.1.1 - version: 2.1.1(esbuild@0.19.5) + version: 2.1.1(esbuild@0.19.6) execa: specifier: ^8.0.1 version: 8.0.1 @@ -5095,33 +5125,21 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 - /@apideck/better-ajv-errors@0.3.6(ajv@8.12.0): - resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} - engines: {node: '>=10'} - peerDependencies: - ajv: '>=8' - dependencies: - ajv: 8.12.0 - json-schema: 0.4.0 - jsonpointer: 5.0.1 - leven: 3.1.0 - dev: false - /@assemblyscript/loader@0.19.23: resolution: {integrity: sha512-ulkCYfFbYj01ie1MDOyxv2F6SpRN1TOj7fQxbP07D6HmeR+gr2JLSmINKjga2emB+b1L2KGrFKBTc+e00p54nw==} dev: false - /@astro-community/astro-embed-integration@0.5.1(astro@packages+astro): - resolution: {integrity: sha512-K1mJHRs0GGAwn2VmOR9JhXFOoCgW2G4GjjdJDqPncfT+BxeoTa/6IP7EMdRlHetIxNliPETVbleRUTV04ztrTA==} + /@astro-community/astro-embed-integration@0.6.0(astro@packages+astro): + resolution: {integrity: sha512-PQGtMLfZ1t0znrY/ElPu3gAT/up9rJVyEDaoqvhoUcEmhp7e99EiuTZNKNKIkeH+biWyKJoKTSClu300i91Kzw==} peerDependencies: astro: '*' dependencies: '@astro-community/astro-embed-twitter': 0.5.2(astro@packages+astro) '@astro-community/astro-embed-vimeo': 0.3.1(astro@packages+astro) '@astro-community/astro-embed-youtube': 0.4.1(astro@packages+astro) - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 astro: link:packages/astro - astro-auto-import: 0.3.1(astro@packages+astro) + astro-auto-import: 0.3.2(astro@packages+astro) unist-util-select: 4.0.3 dev: false @@ -5155,23 +5173,31 @@ packages: lite-youtube-embed: 0.2.0 dev: false - /@astrojs/check@0.1.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6): - resolution: {integrity: sha512-tgjq+Vehgv0dwdsRlT4ai3QgT3etn8W5C4E4dvQ0Xe9ccwjKdMTWmpty5exfBtHLLAAOvwe5/OkYQsQ9OyKoVw==} + /@astrojs/check@0.3.1(prettier-plugin-astro@0.12.2)(prettier@3.1.0)(typescript@5.2.2): + resolution: {integrity: sha512-3LjEUvh7Z4v9NPokaqKMXQ0DwnSXfmtcyAuWVTjNt9yzjv54SxykobV5CTOB3TIko+Rqg59ejamJBxaJN6fvkw==} hasBin: true peerDependencies: typescript: ^5.0.0 dependencies: - '@astrojs/language-server': 2.4.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6) + '@astrojs/language-server': 2.5.2(prettier-plugin-astro@0.12.2)(prettier@3.1.0)(typescript@5.2.2) chokidar: 3.5.3 - fast-glob: 3.3.1 + fast-glob: 3.3.2 kleur: 4.1.5 - typescript: 5.1.6 + typescript: 5.2.2 yargs: 17.7.2 transitivePeerDependencies: - prettier - prettier-plugin-astro dev: true + /@astrojs/cli-kit@0.2.3: + resolution: {integrity: sha512-MjB42mpIG/F2rFtdp4f3NylFCILuFSib2yITSq65fRaDFn8+UC8EMh6T7Jr3YqHAbUY5r8V8QWNgH4keOEO2BA==} + dependencies: + chalk: 5.3.0 + log-update: 5.0.1 + sisteransi: 1.0.5 + dev: false + /@astrojs/cli-kit@0.3.1: resolution: {integrity: sha512-BEzf3gudr4XrrrInJKD+GSS5O+GXRTukLUpOfgqdTSq6d48EWVhigNHobmlQGbpa9FEAw+sZmvmHmhS29QhnwA==} engines: {node: '>=18.14.1'} @@ -5181,20 +5207,15 @@ packages: sisteransi: 1.0.5 dev: false - /@astrojs/compiler@1.5.7: - resolution: {integrity: sha512-dFU7GAMbpTUGPkRoCoMQrGFlTe3qIiQMSOxIXp/nB1Do4My9uogjEmBHdR5Cwr4i6rc5/1R3Od9v8kU/pkHXGQ==} - dev: true - /@astrojs/compiler@1.8.2: resolution: {integrity: sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==} dev: true - /@astrojs/compiler@2.3.0: - resolution: {integrity: sha512-pxYRAaRdMS6XUll8lbFM+Lr0DI1HKIDT+VpiC+S+9di5H/nmm3znZOgdMlLiMxADot+56eps+M1BvtKfQremXA==} - dev: false + /@astrojs/compiler@2.3.2: + resolution: {integrity: sha512-jkY7bCVxl27KeZsSxIZ+pqACe+g8VQUdTiSJRj/sXYdIaZlW3ZMq4qF2M17P/oDt3LBq0zLNwQr4Cb7fSpRGxQ==} - /@astrojs/language-server@2.4.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6): - resolution: {integrity: sha512-L5lbTt1zZiCYGxahGhbJ1m2THaZxBBuA3MrwvhwZ+xVy6/k13W0Xy4nVe0gUBoCizZdKEDL3puoW615waJaTBQ==} + /@astrojs/language-server@2.5.2(prettier-plugin-astro@0.12.2)(prettier@3.1.0)(typescript@5.2.2): + resolution: {integrity: sha512-O5SMzoQ65wSxA1KygreI9UJYmHpgt15bSYBxceHwqX7OCDM4Ek8mr6mZn45LGDtwM3dp1uup7kp8exfRPwIFbA==} hasBin: true peerDependencies: prettier: ^3.0.0 @@ -5205,25 +5226,25 @@ packages: prettier-plugin-astro: optional: true dependencies: - '@astrojs/compiler': 1.5.7 + '@astrojs/compiler': 2.3.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@volar/kit': 1.10.4(typescript@5.1.6) - '@volar/language-core': 1.10.4 - '@volar/language-server': 1.10.4 - '@volar/language-service': 1.10.4 - '@volar/source-map': 1.10.4 - '@volar/typescript': 1.10.4 - fast-glob: 3.3.1 + '@volar/kit': 1.10.10(typescript@5.2.2) + '@volar/language-core': 1.10.10 + '@volar/language-server': 1.10.10 + '@volar/language-service': 1.10.10 + '@volar/source-map': 1.10.10 + '@volar/typescript': 1.10.10 + fast-glob: 3.3.2 muggle-string: 0.3.1 - prettier: 3.0.3 - prettier-plugin-astro: 0.12.0 - volar-service-css: 0.0.14(@volar/language-service@1.10.4) - volar-service-emmet: 0.0.14(@volar/language-service@1.10.4) - volar-service-html: 0.0.14(@volar/language-service@1.10.4) - volar-service-prettier: 0.0.14(@volar/language-service@1.10.4)(prettier@3.0.3) - volar-service-typescript: 0.0.14(@volar/language-service@1.10.4)(@volar/typescript@1.10.4) - volar-service-typescript-twoslash-queries: 0.0.14(@volar/language-service@1.10.4) - vscode-html-languageservice: 5.1.0 + prettier: 3.1.0 + prettier-plugin-astro: 0.12.2 + volar-service-css: 0.0.16(@volar/language-service@1.10.10) + volar-service-emmet: 0.0.16(@volar/language-service@1.10.10) + volar-service-html: 0.0.16(@volar/language-service@1.10.10) + volar-service-prettier: 0.0.16(@volar/language-service@1.10.10)(prettier@3.1.0) + volar-service-typescript: 0.0.16(@volar/language-service@1.10.10)(@volar/typescript@1.10.10) + volar-service-typescript-twoslash-queries: 0.0.16(@volar/language-service@1.10.10) + vscode-html-languageservice: 5.1.1 vscode-uri: 3.0.8 transitivePeerDependencies: - typescript @@ -5236,25 +5257,25 @@ packages: '@babel/highlight': 7.22.20 chalk: 2.4.2 - /@babel/compat-data@7.23.2: - resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} + /@babel/compat-data@7.23.3: + resolution: {integrity: sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==} engines: {node: '>=6.9.0'} dev: false - /@babel/core@7.23.2: - resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} + /@babel/core@7.23.3: + resolution: {integrity: sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/generator': 7.23.3 '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3) '@babel/helpers': 7.23.2 - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.3 '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 convert-source-map: 2.0.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 @@ -5264,11 +5285,11 @@ packages: - supports-color dev: false - /@babel/generator@7.23.0: - resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + /@babel/generator@7.23.3: + resolution: {integrity: sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 @@ -5278,28 +5299,21 @@ packages: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - dev: false - - /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: - resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.23.2 + '@babel/compat-data': 7.23.3 '@babel/helper-validator-option': 7.22.15 browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 dev: false - /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.2): + /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.3): resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} engines: {node: '>=6.9.0'} peerDependencies: @@ -5308,51 +5322,18 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.3) '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 dev: false - /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - regexpu-core: 5.3.2 - semver: 6.3.1 - dev: false - - /@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.23.2): - resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4(supports-color@8.1.1) - lodash.debounce: 4.0.8 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - dev: false - /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -5363,39 +5344,39 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-member-expression-to-functions@7.23.0: resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.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.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false - /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -5403,7 +5384,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -5415,7 +5396,7 @@ packages: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-plugin-utils@7.22.5: @@ -5423,22 +5404,7 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.2): - resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-wrap-function': 7.22.20 - dev: false - - /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.2): + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.3): resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} engines: {node: '>=6.9.0'} peerDependencies: @@ -5447,7 +5413,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 @@ -5457,21 +5423,21 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-skip-transparent-expression-wrappers@7.22.5: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: false /@babel/helper-string-parser@7.22.5: @@ -5487,22 +5453,13 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/helper-wrap-function@7.22.20: - resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.22.15 - '@babel/types': 7.23.0 - dev: false - /@babel/helpers@7.23.2: resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 transitivePeerDependencies: - supports-color dev: false @@ -5515,43 +5472,41 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.23.0: - resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + /@babel/parser@7.23.3: + resolution: {integrity: sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==} + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.3): + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==} + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.13.0 + '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2) dev: false - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2): - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.3): + resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -5559,35 +5514,39 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 dev: false - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + /@babel/plugin-transform-react-jsx-development@7.22.5: + resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.3) dev: false - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.2): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.2): - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -5595,36 +5554,45 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.23.3): + resolution: {integrity: sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.3) + '@babel/types': 7.23.3 dev: false - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + /@babel/plugin-transform-typescript@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-ogV0yWnq38CFwH20l2Afz0dfKuZBx9o/Y2Rmh5vuSS0YD1hswgEgTfyTzuSrT2q9btmHRSqYoSfwFUVaC1M1Jw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.3) '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.3) dev: false - /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} + /@babel/preset-typescript@7.23.2(@babel/core@7.23.3): + resolution: {integrity: sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -5632,1096 +5600,50 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.15 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.3) + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.3) + '@babel/plugin-transform-typescript': 7.23.3(@babel/core@7.23.3) dev: false - /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false + regenerator-runtime: 0.14.0 + dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.2): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 dev: false - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.2): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.2): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.2): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.2): - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.2): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.2): - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-async-generator-functions@7.23.2(@babel/core@7.23.2): - resolution: {integrity: sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-classes@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) - '@babel/helper-split-export-declaration': 7.22.6 - globals: 11.12.0 - dev: false - - /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/template': 7.22.15 - dev: false - - /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-literals@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - dev: false - - /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 - dev: false - - /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/compat-data': 7.23.2 - '@babel/core': 7.23.2 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.2): - resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-react-jsx-development@7.22.5: - resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) - '@babel/types': 7.23.0 - dev: false - - /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.23.2): - resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - regenerator-transform: 0.15.2 - dev: false - - /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-spread@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - dev: false - - /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.2): - resolution: {integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2) - dev: false - - /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.23.2): - resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/preset-env@7.23.2(@babel/core@7.23.2): - resolution: {integrity: sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/compat-data': 7.23.2 - '@babel/core': 7.23.2 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.22.15 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.23.2) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.23.2) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.2) - '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-async-generator-functions': 7.23.2(@babel/core@7.23.2) - '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.23.2) - '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.23.2) - '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.23.2) - '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2) - '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.23.2) - '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.23.2) - '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.23.2) - '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.2) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.2) - '@babel/types': 7.23.0 - babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.23.2) - babel-plugin-polyfill-corejs3: 0.8.6(@babel/core@7.23.2) - babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.23.2) - core-js-compat: 3.33.1 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.2): - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/types': 7.23.0 - esutils: 2.0.3 - dev: false - - /@babel/preset-typescript@7.23.2(@babel/core@7.23.2): - resolution: {integrity: sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.22.15 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2) - '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.2) - dev: false - - /@babel/regjsgen@0.8.0: - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - dev: false - - /@babel/runtime@7.23.2: - resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.0 - - /@babel/template@7.22.15: - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - dev: false - - /@babel/traverse@7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + /@babel/traverse@7.23.3: + resolution: {integrity: sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/generator': 7.23.3 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color dev: false - /@babel/types@7.23.0: - resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + /@babel/types@7.23.3: + resolution: {integrity: sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.22.5 @@ -6799,7 +5721,7 @@ packages: '@changesets/write': 0.2.3 '@manypkg/get-packages': 1.1.3 '@types/is-ci': 3.0.3 - '@types/semver': 7.5.4 + '@types/semver': 7.5.5 ansi-colors: 4.1.3 chalk: 2.4.2 enquirer: 2.4.1 @@ -7009,8 +5931,8 @@ packages: '@csstools/css-tokenizer': 2.2.1 dev: true - /@csstools/postcss-cascade-layers@4.0.0(postcss@8.4.31): - resolution: {integrity: sha512-dVPVVqQG0FixjM9CG/+8eHTsCAxRKqmNh6H69IpruolPlnEF1611f2AoLK8TijTSAsqBSclKd4WHs1KUb/LdJw==} + /@csstools/postcss-cascade-layers@4.0.1(postcss@8.4.31): + resolution: {integrity: sha512-UYFuFL9GgVnftg9v7tBvVEBRLaBeAD66euD+yYy5fYCUld9ZIWTJNCE30hm6STMEdt6FL5xzeVw1lAZ1tpvUEg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 @@ -7145,6 +6067,24 @@ packages: postcss: 8.4.31 dev: true + /@csstools/postcss-logical-overflow@1.0.0(postcss@8.4.31): + resolution: {integrity: sha512-cIrZ8f7bGGvr+W53nEuMspcwaeaI2YTmz6LZ4yiAO5z14/PQgOOv+Pn+qjvPOPoadeY2BmpaoTzZKvdAQuM17w==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.31 + dev: true + + /@csstools/postcss-logical-overscroll-behavior@1.0.0(postcss@8.4.31): + resolution: {integrity: sha512-e89S2LWjnxf0SB2wNUAbqDyFb/Fow/tlOe1XqOLbNx4rf3LrQokM9qldVx7sarnddml3ORE5LDUmlKpPOOeJTA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.31 + dev: true + /@csstools/postcss-logical-resize@2.0.0(postcss@8.4.31): resolution: {integrity: sha512-lCQ1aX8c5+WI4t5EoYf3alTzJNNocMqTb+u1J9CINdDhFh1fjovqK+0aHalUHsNstZmzFPNzIkU4Mb3eM9U8SA==} engines: {node: ^14 || ^16 || >=18} @@ -7331,10 +6271,11 @@ packages: cpu: [arm64] os: [android] requiresBuild: true + dev: false optional: true - /@esbuild/android-arm64@0.19.5: - resolution: {integrity: sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==} + /@esbuild/android-arm64@0.19.6: + resolution: {integrity: sha512-KQ/hbe9SJvIJ4sR+2PcZ41IBV+LPJyYp6V1K1P1xcMRup9iYsBoQn4MzE3mhMLOld27Au2eDcLlIREeKGUXpHQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -7347,10 +6288,11 @@ packages: cpu: [arm] os: [android] requiresBuild: true + dev: false optional: true - /@esbuild/android-arm@0.19.5: - resolution: {integrity: sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==} + /@esbuild/android-arm@0.19.6: + resolution: {integrity: sha512-muPzBqXJKCbMYoNbb1JpZh/ynl0xS6/+pLjrofcR3Nad82SbsCogYzUE6Aq9QT3cLP0jR/IVK/NHC9b90mSHtg==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -7363,10 +6305,11 @@ packages: cpu: [x64] os: [android] requiresBuild: true + dev: false optional: true - /@esbuild/android-x64@0.19.5: - resolution: {integrity: sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==} + /@esbuild/android-x64@0.19.6: + resolution: {integrity: sha512-VVJVZQ7p5BBOKoNxd0Ly3xUM78Y4DyOoFKdkdAe2m11jbh0LEU4bPles4e/72EMl4tapko8o915UalN/5zhspg==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -7379,10 +6322,11 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: false optional: true - /@esbuild/darwin-arm64@0.19.5: - resolution: {integrity: sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==} + /@esbuild/darwin-arm64@0.19.6: + resolution: {integrity: sha512-91LoRp/uZAKx6ESNspL3I46ypwzdqyDLXZH7x2QYCLgtnaU08+AXEbabY2yExIz03/am0DivsTtbdxzGejfXpA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -7395,10 +6339,11 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: false optional: true - /@esbuild/darwin-x64@0.19.5: - resolution: {integrity: sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==} + /@esbuild/darwin-x64@0.19.6: + resolution: {integrity: sha512-QCGHw770ubjBU1J3ZkFJh671MFajGTYMZumPs9E/rqU52md6lIil97BR0CbPq6U+vTh3xnTNDHKRdR8ggHnmxQ==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -7411,10 +6356,11 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true + dev: false optional: true - /@esbuild/freebsd-arm64@0.19.5: - resolution: {integrity: sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==} + /@esbuild/freebsd-arm64@0.19.6: + resolution: {integrity: sha512-J53d0jGsDcLzWk9d9SPmlyF+wzVxjXpOH7jVW5ae7PvrDst4kiAz6sX+E8btz0GB6oH12zC+aHRD945jdjF2Vg==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -7427,10 +6373,11 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true + dev: false optional: true - /@esbuild/freebsd-x64@0.19.5: - resolution: {integrity: sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==} + /@esbuild/freebsd-x64@0.19.6: + resolution: {integrity: sha512-hn9qvkjHSIB5Z9JgCCjED6YYVGCNpqB7dEGavBdG6EjBD8S/UcNUIlGcB35NCkMETkdYwfZSvD9VoDJX6VeUVA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -7443,10 +6390,11 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-arm64@0.19.5: - resolution: {integrity: sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==} + /@esbuild/linux-arm64@0.19.6: + resolution: {integrity: sha512-HQCOrk9XlH3KngASLaBfHpcoYEGUt829A9MyxaI8RMkfRA8SakG6YQEITAuwmtzFdEu5GU4eyhKcpv27dFaOBg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -7459,10 +6407,11 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-arm@0.19.5: - resolution: {integrity: sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==} + /@esbuild/linux-arm@0.19.6: + resolution: {integrity: sha512-G8IR5zFgpXad/Zp7gr7ZyTKyqZuThU6z1JjmRyN1vSF8j0bOlGzUwFSMTbctLAdd7QHpeyu0cRiuKrqK1ZTwvQ==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -7475,10 +6424,11 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-ia32@0.19.5: - resolution: {integrity: sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==} + /@esbuild/linux-ia32@0.19.6: + resolution: {integrity: sha512-22eOR08zL/OXkmEhxOfshfOGo8P69k8oKHkwkDrUlcB12S/sw/+COM4PhAPT0cAYW/gpqY2uXp3TpjQVJitz7w==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -7491,10 +6441,11 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-loong64@0.19.5: - resolution: {integrity: sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==} + /@esbuild/linux-loong64@0.19.6: + resolution: {integrity: sha512-82RvaYAh/SUJyjWA8jDpyZCHQjmEggL//sC7F3VKYcBMumQjUL3C5WDl/tJpEiKtt7XrWmgjaLkrk205zfvwTA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -7507,10 +6458,11 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-mips64el@0.19.5: - resolution: {integrity: sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==} + /@esbuild/linux-mips64el@0.19.6: + resolution: {integrity: sha512-8tvnwyYJpR618vboIv2l8tK2SuK/RqUIGMfMENkeDGo3hsEIrpGldMGYFcWxWeEILe5Fi72zoXLmhZ7PR23oQA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -7523,10 +6475,11 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-ppc64@0.19.5: - resolution: {integrity: sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==} + /@esbuild/linux-ppc64@0.19.6: + resolution: {integrity: sha512-Qt+D7xiPajxVNk5tQiEJwhmarNnLPdjXAoA5uWMpbfStZB0+YU6a3CtbWYSy+sgAsnyx4IGZjWsTzBzrvg/fMA==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -7539,10 +6492,11 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-riscv64@0.19.5: - resolution: {integrity: sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==} + /@esbuild/linux-riscv64@0.19.6: + resolution: {integrity: sha512-lxRdk0iJ9CWYDH1Wpnnnc640ajF4RmQ+w6oHFZmAIYu577meE9Ka/DCtpOrwr9McMY11ocbp4jirgGgCi7Ls/g==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -7555,10 +6509,11 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-s390x@0.19.5: - resolution: {integrity: sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==} + /@esbuild/linux-s390x@0.19.6: + resolution: {integrity: sha512-MopyYV39vnfuykHanRWHGRcRC3AwU7b0QY4TI8ISLfAGfK+tMkXyFuyT1epw/lM0pflQlS53JoD22yN83DHZgA==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -7571,10 +6526,11 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/linux-x64@0.19.5: - resolution: {integrity: sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==} + /@esbuild/linux-x64@0.19.6: + resolution: {integrity: sha512-UWcieaBzsN8WYbzFF5Jq7QULETPcQvlX7KL4xWGIB54OknXJjBO37sPqk7N82WU13JGWvmDzFBi1weVBajPovg==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -7587,10 +6543,11 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true + dev: false optional: true - /@esbuild/netbsd-x64@0.19.5: - resolution: {integrity: sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==} + /@esbuild/netbsd-x64@0.19.6: + resolution: {integrity: sha512-EpWiLX0fzvZn1wxtLxZrEW+oQED9Pwpnh+w4Ffv8ZLuMhUoqR9q9rL4+qHW8F4Mg5oQEKxAoT0G+8JYNqCiR6g==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -7603,10 +6560,11 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true + dev: false optional: true - /@esbuild/openbsd-x64@0.19.5: - resolution: {integrity: sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==} + /@esbuild/openbsd-x64@0.19.6: + resolution: {integrity: sha512-fFqTVEktM1PGs2sLKH4M5mhAVEzGpeZJuasAMRnvDZNCV0Cjvm1Hu35moL2vC0DOrAQjNTvj4zWrol/lwQ8Deg==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -7619,10 +6577,11 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true + dev: false optional: true - /@esbuild/sunos-x64@0.19.5: - resolution: {integrity: sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==} + /@esbuild/sunos-x64@0.19.6: + resolution: {integrity: sha512-M+XIAnBpaNvaVAhbe3uBXtgWyWynSdlww/JNZws0FlMPSBy+EpatPXNIlKAdtbFVII9OpX91ZfMb17TU3JKTBA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -7635,10 +6594,11 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: false optional: true - /@esbuild/win32-arm64@0.19.5: - resolution: {integrity: sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==} + /@esbuild/win32-arm64@0.19.6: + resolution: {integrity: sha512-2DchFXn7vp/B6Tc2eKdTsLzE0ygqKkNUhUBCNtMx2Llk4POIVMUq5rUYjdcedFlGLeRe1uLCpVvCmE+G8XYybA==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -7651,10 +6611,11 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: false optional: true - /@esbuild/win32-ia32@0.19.5: - resolution: {integrity: sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==} + /@esbuild/win32-ia32@0.19.6: + resolution: {integrity: sha512-PBo/HPDQllyWdjwAVX+Gl2hH0dfBydL97BAH/grHKC8fubqp02aL4S63otZ25q3sBdINtOBbz1qTZQfXbP4VBg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -7667,40 +6628,41 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: false optional: true - /@esbuild/win32-x64@0.19.5: - resolution: {integrity: sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==} + /@esbuild/win32-x64@0.19.6: + resolution: {integrity: sha512-OE7yIdbDif2kKfrGa+V0vx/B3FJv2L4KnIiLlvtibPyO9UkgO3rzYE0HhpREo2vmJ1Ixq1zwm9/0er+3VOSZJA==} engines: {node: '>=12'} cpu: [x64] os: [win32] requiresBuild: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 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.52.0 + eslint: 8.54.0 eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp@4.9.1: - resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==} + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.2: - resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + /@eslint/eslintrc@2.1.3: + resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4(supports-color@8.1.1) espree: 9.6.1 globals: 13.23.0 - ignore: 5.2.4 + ignore: 5.3.0 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -7709,8 +6671,8 @@ packages: - supports-color dev: true - /@eslint/js@8.52.0: - resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} + /@eslint/js@8.54.0: + resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -7719,12 +6681,12 @@ packages: engines: {node: '>=14'} dev: true - /@fontsource/monofett@5.0.9: - resolution: {integrity: sha512-huRzEMeEuZE5LuiDqGQdcvtOKEIOYnIpfz9g/IeZn06sdRbVu8HEjJgRnJvtdT4NYV7U/XGnB3LL/LYQb1F0hg==} + /@fontsource/monofett@5.0.17: + resolution: {integrity: sha512-MTSxMPkTXeqEVeaugMh9nUbSqL/0tm0KlwdTInRv3s1JY3S7rzM1hnue+m8p1ZU89viNNjeCBTLaE77MosKdjQ==} dev: false - /@fontsource/montserrat@5.0.8: - resolution: {integrity: sha512-bNj6wfiWXXbsxb2ffatjpX+GBv30cWZ1lwNXW9qTeX2FnzPomsGRV4HdPrf3TqyTiVqX6fLo80zrQcMi7r8+fA==} + /@fontsource/montserrat@5.0.15: + resolution: {integrity: sha512-ZJbsCIJp6VHL1wYQUPpyBjXMzwGdfFedrmrw4r5sFi7WrMpnfJv+el1uVO6yDPIqnVqkPvjJ+xeKgJwnj2LuQQ==} dev: false /@humanwhocodes/config-array@0.11.13: @@ -7770,13 +6732,6 @@ packages: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - /@jridgewell/source-map@0.3.5: - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 - dev: false - /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} @@ -7790,30 +6745,30 @@ packages: resolution: {integrity: sha512-n5JEf16Wr4mdkRMZ8wMP/wN9/sHmTjRPbouXjJH371mZ2LEGDl72t8tEsMRNFerQN/QJtivOxqK1frdGa4QK5Q==} engines: {node: '>=10'} - /@lit-labs/ssr-client@1.1.3: - resolution: {integrity: sha512-JIvpvfCEJGTIKH1L/kZYN68jiXuTBbHI6JG3H4HQI0Ko/8Z0qtlSP9G35IVDzNdMt+xVE4WYKsY9Vk6N2S55kQ==} + /@lit-labs/ssr-client@1.1.5: + resolution: {integrity: sha512-rAXd2OsuxfGA579RiDS2YQSm1HreE8knQHj+fcMhGIPYenBoW4M70Yl8K3a35MSLlpQnnF//s2TPfkHFmy2RhA==} dependencies: - '@lit/reactive-element': 1.6.3 - lit: 2.8.0 - lit-html: 2.8.0 + '@lit/reactive-element': 2.0.2 + lit: 3.1.0 + lit-html: 3.1.0 dev: false /@lit-labs/ssr-dom-shim@1.1.2: resolution: {integrity: sha512-jnOD+/+dSrfTWYfSXBXlo5l5f0q1UuJo3tkbMDCYA2lKUYq79jaxqtGEvnRoh049nt1vdo1+45RinipU6FGY2g==} - /@lit-labs/ssr@3.1.7: - resolution: {integrity: sha512-eoH2Ech9lvk3VCMbG6d0yRqCJOD1Zs+ZKBRuGIxOG2OQoNYtQg8JV5JPeRhlx9OKy/wVAGPtIaWDL25n4mVjYQ==} + /@lit-labs/ssr@3.2.0: + resolution: {integrity: sha512-5ZwVMEpYCHI5MF7+5ER3IvOyDjJimq/nzKtV4momqSKr3a/9gEFouHzTDogwaYoOwIBBtO8jl5SX2Vsb0kfZgA==} engines: {node: '>=13.9.0'} dependencies: - '@lit-labs/ssr-client': 1.1.3 + '@lit-labs/ssr-client': 1.1.5 '@lit-labs/ssr-dom-shim': 1.1.2 - '@lit/reactive-element': 1.6.3 + '@lit/reactive-element': 2.0.2 '@parse5/tools': 0.3.0 - '@types/node': 16.18.59 + '@types/node': 16.18.61 enhanced-resolve: 5.15.0 - lit: 2.8.0 - lit-element: 3.3.3 - lit-html: 2.8.0 + lit: 3.1.0 + lit-element: 4.0.2 + lit-html: 3.1.0 node-fetch: 3.3.2 parse5: 7.1.2 dev: false @@ -7822,6 +6777,12 @@ packages: resolution: {integrity: sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==} dependencies: '@lit-labs/ssr-dom-shim': 1.1.2 + dev: false + + /@lit/reactive-element@2.0.2: + resolution: {integrity: sha512-SVOwLAWUQg3Ji1egtOt1UiFe4zdDpnWHyc5qctSceJ5XIu0Uc76YmGpIjZgx9YJ0XtdW0Jm507sDvjOu+HnB8w==} + dependencies: + '@lit-labs/ssr-dom-shim': 1.1.2 /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -7861,8 +6822,8 @@ packages: - supports-color dev: false - /@markdoc/markdoc@0.3.4: - resolution: {integrity: sha512-cTyucw4YcQL3JfKMjjjszuTuR97nELN0mvPQhYLvVR/flvYaZUZUNBs8O3lv0vf7g0bfM2ZTUezBq0u8+1hTdg==} + /@markdoc/markdoc@0.3.5: + resolution: {integrity: sha512-Z3agu2wnodoOYd5kzKbtwZduSfX19Kbsg/FlK0TeMn29cTTEEVPJtjfgKSMTN/Wq+kUQXnPtOEhHRgke5d/Xiw==} engines: {node: '>=14.7.0'} peerDependencies: '@types/react': '*' @@ -7876,39 +6837,45 @@ packages: '@types/markdown-it': 12.2.3 dev: false - /@mdx-js/mdx@2.3.0: - resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} + /@mdx-js/mdx@3.0.0: + resolution: {integrity: sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==} dependencies: - '@types/estree-jsx': 1.0.2 - '@types/mdx': 2.0.9 - estree-util-build-jsx: 2.2.2 - estree-util-is-identifier-name: 2.1.0 - estree-util-to-js: 1.2.0 + '@types/estree': 1.0.5 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdx': 2.0.10 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-build-jsx: 3.0.1 + estree-util-is-identifier-name: 3.0.0 + estree-util-to-js: 2.0.0 estree-walker: 3.0.3 - hast-util-to-estree: 2.3.3 - markdown-extensions: 1.1.1 + hast-util-to-estree: 3.1.0 + hast-util-to-jsx-runtime: 2.2.0 + markdown-extensions: 2.0.0 periscopic: 3.1.0 - remark-mdx: 2.3.0 - remark-parse: 10.0.2 - remark-rehype: 10.1.0 - unified: 10.1.2 - unist-util-position-from-estree: 1.1.2 - unist-util-stringify-position: 3.0.3 - unist-util-visit: 4.1.2 - vfile: 5.3.7 + remark-mdx: 3.0.0 + remark-parse: 11.0.0 + remark-rehype: 11.0.0 + source-map: 0.7.4 + unified: 11.0.4 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 transitivePeerDependencies: - supports-color dev: false - /@nanostores/preact@0.5.0(nanostores@0.9.4)(preact@10.18.1): + /@nanostores/preact@0.5.0(nanostores@0.9.5)(preact@10.19.2): resolution: {integrity: sha512-Zq5DEAY+kIfwJ1NPd43D1mpsbISuiD6N/SuTHrt/8jUoifLwXaReaZMAnvkvbIGOgcB1Hy++A9jZix2taNNYxQ==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} peerDependencies: nanostores: ^0.9.0 preact: '>=10.0.0' dependencies: - nanostores: 0.9.4 - preact: 10.18.1 + nanostores: 0.9.5 + preact: 10.19.2 dev: false /@nodelib/fs.scandir@2.1.5: @@ -8046,43 +7013,35 @@ packages: engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} dependencies: cross-spawn: 7.0.3 - fast-glob: 3.3.1 + fast-glob: 3.3.2 is-glob: 4.0.3 open: 9.1.0 picocolors: 1.0.0 tslib: 2.6.2 dev: true - /@playwright/test@1.39.0: - resolution: {integrity: sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==} - engines: {node: '>=16'} - hasBin: true - dependencies: - playwright: 1.39.0 - dev: true - - /@playwright/test@1.40.0-alpha-nov-13-2023: - resolution: {integrity: sha512-qb5AzKN2pf14C4AT90ps3VGbDhx1/9LnzzT+D2TBZQ/vRUUvacvxxhjieelFKvw+FN4BIXFnEs2bNecc37Jyww==} + /@playwright/test@1.40.0: + resolution: {integrity: sha512-PdW+kn4eV99iP5gxWNSDQCbhMaDVej+RXL5xr6t04nbKLCBwYtA046t7ofoczHOm8u6c+45hpDKQVZqtqwkeQg==} engines: {node: '>=16'} hasBin: true dependencies: - playwright: 1.40.0-alpha-nov-13-2023 + playwright: 1.40.0 dev: true - /@preact/preset-vite@2.6.0(preact@10.18.1): - resolution: {integrity: sha512-5nztNzXbCpqyVum/K94nB2YQ5PTnvWdz4u7/X0jc8+kLyskSSpkNUxLQJeI90zfGSFIX1Ibj2G2JIS/mySHWYQ==} + /@preact/preset-vite@2.7.0(preact@10.19.2): + resolution: {integrity: sha512-m5N0FVtxbCCDxNk55NGhsRpKJChYcupcuQHzMJc/Bll07IKZKn8amwYciyKFS9haU6AgzDAJ/ewvApr6Qg1DHw==} peerDependencies: '@babel/core': 7.x - vite: 2.x || 3.x || 4.x + vite: 2.x || 3.x || 4.x || 5.x peerDependenciesMeta: '@babel/core': optional: true vite: optional: true dependencies: - '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.3) '@babel/plugin-transform-react-jsx-development': 7.22.5 - '@prefresh/vite': 2.4.1(preact@10.18.1) + '@prefresh/vite': 2.4.4(preact@10.19.2) '@rollup/pluginutils': 4.2.1 babel-plugin-transform-hook-names: 1.0.2 debug: 4.3.4(supports-color@8.1.1) @@ -8097,33 +7056,33 @@ packages: resolution: {integrity: sha512-U2diO1Z4i1n2IoFgMYmRdHWGObNrcuTRxyNEn7deSq2cru0vj0583HYQZHsAqcs7FE+hQyX3mjIV7LAfHCvy8w==} dev: false - /@preact/signals@1.2.1(preact@10.18.1): + /@preact/signals@1.2.1(preact@10.19.2): resolution: {integrity: sha512-hRPvp1C2ooDzOHqfnhdpHgoIFDbYFAXLhoid3+jSItuPPD/J0r/UsiWKv/8ZO/oEhjRaP0M5niuRYsWqmY2GEA==} peerDependencies: preact: 10.x dependencies: '@preact/signals-core': 1.5.0 - preact: 10.18.1 + preact: 10.19.2 dev: false - /@prefresh/babel-plugin@0.5.0: - resolution: {integrity: sha512-joAwpkUDwo7ZqJnufXRGzUb+udk20RBgfA8oLPBh5aJH2LeStmV1luBfeJTztPdyCscC2j2SmZ/tVxFRMIxAEw==} + /@prefresh/babel-plugin@0.5.1: + resolution: {integrity: sha512-uG3jGEAysxWoyG3XkYfjYHgaySFrSsaEb4GagLzYaxlydbuREtaX+FTxuIidp241RaLl85XoHg9Ej6E4+V1pcg==} dev: false - /@prefresh/core@1.5.2(preact@10.18.1): + /@prefresh/core@1.5.2(preact@10.19.2): resolution: {integrity: sha512-A/08vkaM1FogrCII5PZKCrygxSsc11obExBScm3JF1CryK2uDS3ZXeni7FeKCx1nYdUkj4UcJxzPzc1WliMzZA==} peerDependencies: preact: ^10.0.0 dependencies: - preact: 10.18.1 + preact: 10.19.2 dev: false /@prefresh/utils@1.2.0: resolution: {integrity: sha512-KtC/fZw+oqtwOLUFM9UtiitB0JsVX0zLKNyRTA332sqREqSALIIQQxdUCS1P3xR/jT1e2e8/5rwH6gdcMLEmsQ==} dev: false - /@prefresh/vite@2.4.1(preact@10.18.1): - resolution: {integrity: sha512-vthWmEqu8TZFeyrBNc9YE5SiC3DVSzPgsOCp/WQ7FqdHpOIJi7Z8XvCK06rBPOtG4914S52MjG9Ls22eVAiuqQ==} + /@prefresh/vite@2.4.4(preact@10.19.2): + resolution: {integrity: sha512-7jcz3j5pXufOWTjl31n0Lc3BcU8oGoacoaWx/Ur1QJ+fd4Xu0G7g/ER1xV02x7DCiVoFi7xtSgaophOXoJvpmA==} peerDependencies: preact: ^10.4.0 vite: '>=2.0.0' @@ -8131,83 +7090,16 @@ packages: vite: optional: true dependencies: - '@babel/core': 7.23.2 - '@prefresh/babel-plugin': 0.5.0 - '@prefresh/core': 1.5.2(preact@10.18.1) + '@babel/core': 7.23.3 + '@prefresh/babel-plugin': 0.5.1 + '@prefresh/core': 1.5.2(preact@10.19.2) '@prefresh/utils': 1.2.0 '@rollup/pluginutils': 4.2.1 - preact: 10.18.1 + preact: 10.19.2 transitivePeerDependencies: - supports-color dev: false - /@rollup/plugin-babel@5.3.1(@babel/core@7.23.2)(rollup@2.79.1): - resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} - engines: {node: '>= 10.0.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@types/babel__core': ^7.1.9 - rollup: ^1.20.0||^2.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - '@types/babel__core': - optional: true - rollup: - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-module-imports': 7.22.15 - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) - rollup: 2.79.1 - dev: false - - /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.1): - resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} - engines: {node: '>= 10.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) - '@types/resolve': 1.17.1 - builtin-modules: 3.3.0 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.8 - rollup: 2.79.1 - dev: false - - /@rollup/plugin-replace@2.4.2(rollup@2.79.1): - resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) - magic-string: 0.25.9 - rollup: 2.79.1 - dev: false - - /@rollup/pluginutils@3.1.0(rollup@2.79.1): - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.1 - rollup: 2.79.1 - dev: false - /@rollup/pluginutils@4.2.1: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -8216,65 +7108,145 @@ packages: picomatch: 2.3.1 dev: false + /@rollup/rollup-android-arm-eabi@4.5.0: + resolution: {integrity: sha512-OINaBGY+Wc++U0rdr7BLuFClxcoWaVW3vQYqmQq6B3bqQ/2olkaoz+K8+af/Mmka/C2yN5j+L9scBkv4BtKsDA==} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-android-arm64@4.5.0: + resolution: {integrity: sha512-UdMf1pOQc4ZmUA/NTmKhgJTBimbSKnhPS2zJqucqFyBRFPnPDtwA8MzrGNTjDeQbIAWfpJVAlxejw+/lQyBK/w==} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-arm64@4.5.0: + resolution: {integrity: sha512-L0/CA5p/idVKI+c9PcAPGorH6CwXn6+J0Ys7Gg1axCbTPgI8MeMlhA6fLM9fK+ssFhqogMHFC8HDvZuetOii7w==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-x64@4.5.0: + resolution: {integrity: sha512-QZCbVqU26mNlLn8zi/XDDquNmvcr4ON5FYAHQQsyhrHx8q+sQi/6xduoznYXwk/KmKIXG5dLfR0CvY+NAWpFYQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.5.0: + resolution: {integrity: sha512-VpSQ+xm93AeV33QbYslgf44wc5eJGYfYitlQzAi3OObu9iwrGXEnmu5S3ilkqE3Pr/FkgOiJKV/2p0ewf4Hrtg==} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.5.0: + resolution: {integrity: sha512-OrEyIfpxSsMal44JpEVx9AEcGpdBQG1ZuWISAanaQTSMeStBW+oHWwOkoqR54bw3x8heP8gBOyoJiGg+fLY8qQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.5.0: + resolution: {integrity: sha512-1H7wBbQuE6igQdxMSTjtFfD+DGAudcYWhp106z/9zBA8OQhsJRnemO4XGavdzHpGhRtRxbgmUGdO3YQgrWf2RA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.5.0: + resolution: {integrity: sha512-FVyFI13tXw5aE65sZdBpNjPVIi4Q5mARnL/39UIkxvSgRAIqCo5sCpCELk0JtXHGee2owZz5aNLbWNfBHzr71Q==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.5.0: + resolution: {integrity: sha512-eBPYl2sLpH/o8qbSz6vPwWlDyThnQjJfcDOGFbNjmjb44XKC1F5dQfakOsADRVrXCNzM6ZsSIPDG5dc6HHLNFg==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.5.0: + resolution: {integrity: sha512-xaOHIfLOZypoQ5U2I6rEaugS4IYtTgP030xzvrBf5js7p9WI9wik07iHmsKaej8Z83ZDxN5GyypfoyKV5O5TJA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.5.0: + resolution: {integrity: sha512-Al6quztQUrHwcOoU2TuFblUQ5L+/AmPBXFR6dUvyo4nRj2yQRK0WIUaGMF/uwKulvRcXkpHe3k9A8Vf93VDktA==} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.5.0: + resolution: {integrity: sha512-8kdW+brNhI/NzJ4fxDufuJUjepzINqJKLGHuxyAtpPG9bMbn8P5mtaCcbOm0EzLJ+atg+kF9dwg8jpclkVqx5w==} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: false - /@solidjs/router@0.8.3(solid-js@1.8.3): - resolution: {integrity: sha512-oJuqQo10rVTiQYhe1qXIG1NyZIZ2YOwHnlLc8Xx+g/iJhFCJo1saLOIrD/Dkh2fpIaIny5ZMkz1cYYqoTYGJbg==} - peerDependencies: - solid-js: ^1.5.3 - dependencies: - solid-js: 1.8.3 + /@sindresorhus/merge-streams@1.0.0: + resolution: {integrity: sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==} + engines: {node: '>=18'} dev: false - /@surma/rollup-plugin-off-main-thread@2.2.3: - resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} + /@solidjs/router@0.9.1(solid-js@1.8.5): + resolution: {integrity: sha512-kRY75piOQsyoH75E/RP6lr7uVGFCjeeCCCJx7Z2D1Vc6+I1yFQjLCvE+6agXGwqDoWi6vbETP1g7gmp/L1mNLg==} + peerDependencies: + solid-js: ^1.8.4 dependencies: - ejs: 3.1.9 - json5: 2.2.3 - magic-string: 0.25.9 - string.prototype.matchall: 4.0.10 + solid-js: 1.8.5 dev: false - /@sveltejs/vite-plugin-svelte-inspector@1.0.4(@sveltejs/vite-plugin-svelte@2.5.2)(svelte@4.2.2)(vite@4.5.0): - resolution: {integrity: sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==} - engines: {node: ^14.18.0 || >= 16} + /@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@4.2.5)(vite@5.0.0): + resolution: {integrity: sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==} + engines: {node: ^18.0.0 || >=20} peerDependencies: - '@sveltejs/vite-plugin-svelte': ^2.2.0 - svelte: ^3.54.0 || ^4.0.0 - vite: ^4.0.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 peerDependenciesMeta: vite: optional: true dependencies: - '@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.2)(vite@4.5.0) + '@sveltejs/vite-plugin-svelte': 3.0.0(svelte@4.2.5)(vite@5.0.0) debug: 4.3.4(supports-color@8.1.1) - svelte: 4.2.2 - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + svelte: 4.2.5 + vite: 5.0.0(@types/node@18.18.6)(sass@1.69.5) transitivePeerDependencies: - supports-color dev: false - /@sveltejs/vite-plugin-svelte@2.5.2(svelte@4.2.2)(vite@4.5.0): - resolution: {integrity: sha512-Dfy0Rbl+IctOVfJvWGxrX/3m6vxPLH8o0x+8FA5QEyMUQMo4kGOVIojjryU7YomBAexOTAuYf1RT7809yDziaA==} - engines: {node: ^14.18.0 || >= 16} + /@sveltejs/vite-plugin-svelte@3.0.0(svelte@4.2.5)(vite@5.0.0): + resolution: {integrity: sha512-Th0nupxk8hl5Rcg9jm+1xWylwco4bSUAvutWxM4W4bjOAollpXLmrYqSSnYo9pPbZOO6ZGRm6sSqYa/v1d/Saw==} + engines: {node: ^18.0.0 || >=20} peerDependencies: - svelte: ^3.54.0 || ^4.0.0 || ^5.0.0-next.0 - vite: ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 peerDependenciesMeta: vite: optional: true dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 1.0.4(@sveltejs/vite-plugin-svelte@2.5.2)(svelte@4.2.2)(vite@4.5.0) + '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@4.2.5)(vite@5.0.0) debug: 4.3.4(supports-color@8.1.1) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.5 - svelte: 4.2.2 - svelte-hmr: 0.15.3(svelte@4.2.2) - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) - vitefu: 0.2.5(vite@4.5.0) + svelte: 4.2.5 + svelte-hmr: 0.15.3(svelte@4.2.5) + vite: 5.0.0(@types/node@18.18.6)(sass@1.69.5) + vitefu: 0.2.5(vite@5.0.0) transitivePeerDependencies: - supports-color dev: false @@ -8292,7 +7264,7 @@ packages: /@ts-morph/common@0.20.0: resolution: {integrity: sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q==} dependencies: - fast-glob: 3.3.1 + fast-glob: 3.3.2 minimatch: 7.4.6 mkdirp: 2.1.6 path-browserify: 1.0.1 @@ -8301,48 +7273,48 @@ packages: /@types/acorn@4.0.6: resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 dev: false - /@types/alpinejs@3.13.3: - resolution: {integrity: sha512-ZMxJlDxDDqn94gBWOkeGulVw3nUOy/rPGXlyQksnlzwzuipl4kW0E/tFzAiU4uKSu6UXZL94wReRorln+2FStg==} + /@types/alpinejs@3.13.5: + resolution: {integrity: sha512-BSNTroRhmBkNiyd7ELK/5Boja92hnQMST6H4z1BqXKeMVzHjp9o1j5poqd5Tyhjd8oMFwxYC4I00eghfg2xrTA==} dev: false - /@types/babel__core@7.20.3: - resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==} + /@types/babel__core@7.20.4: + resolution: {integrity: sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==} dependencies: - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - '@types/babel__generator': 7.6.6 - '@types/babel__template': 7.4.3 - '@types/babel__traverse': 7.20.3 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 + '@types/babel__generator': 7.6.7 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.4 dev: false - /@types/babel__generator@7.6.6: - resolution: {integrity: sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==} + /@types/babel__generator@7.6.7: + resolution: {integrity: sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 - /@types/babel__template@7.4.3: - resolution: {integrity: sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==} + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 dev: false - /@types/babel__traverse@7.20.3: - resolution: {integrity: sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==} + /@types/babel__traverse@7.20.4: + resolution: {integrity: sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 - /@types/canvas-confetti@1.6.2: - resolution: {integrity: sha512-ozy7d+7AmYnPEgzdGwwAIA0/yLHnT9YBUQAOm5Ucu+P2ptxq2P464SZDVzYp71wD10ZPYckyeC665bPxQM78kw==} + /@types/canvas-confetti@1.6.3: + resolution: {integrity: sha512-yKVMDzWJ6g0s8TDI3VERfLMCOh0oHqZUnfK+o3VVjR2mFsLynUgb2lR+3IRaEJMza3BKbV9pkoirmM23YhKozA==} dev: false - /@types/chai-as-promised@7.1.7: - resolution: {integrity: sha512-APucaP5rlmTRYKtRA6FE5QPP87x76ejw5t5guRJ4y5OgMnwtsvigw7HHhKZlx2MGXLeZd6R/GNZR/IqDHcbtQw==} + /@types/chai-as-promised@7.1.8: + resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} dependencies: - '@types/chai': 4.3.9 + '@types/chai': 4.3.10 dev: true /@types/chai-subset@1.3.4: @@ -8351,73 +7323,70 @@ packages: '@types/chai': 4.3.9 dev: false + /@types/chai@4.3.10: + resolution: {integrity: sha512-of+ICnbqjmFCiixUnqRulbylyXQrPqIGf/B3Jax1wIF3DvSheysQxAWvqHhZiW3IQrycvokcLcFQlveGp+vyNg==} + dev: true + /@types/chai@4.3.9: resolution: {integrity: sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg==} + dev: false - /@types/common-ancestor-path@1.0.1: - resolution: {integrity: sha512-qkUbNjvDLOlW9PuI4k1w9MkHaWM0/qffQCxWLTfulY5jIijvMpI9PIt0pL+aKzQBz8o8B1kRnBAhBiUBS9NdUA==} + /@types/common-ancestor-path@1.0.2: + resolution: {integrity: sha512-8llyULydTb7nM9yfiW78n6id3cet+qnATPV3R44yIywxgBaa8QXFSM9QTMf4OH64QOB45BlgZ3/oL4mmFLztQw==} dev: true - /@types/connect@3.4.37: - resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 18.18.6 + '@types/node': 20.9.1 dev: true - /@types/cookie@0.5.3: - resolution: {integrity: sha512-SLg07AS9z1Ab2LU+QxzU8RCmzsja80ywjf/t5oqw+4NSH20gIGlhLOrBDm1L3PBWzPa4+wkgFQVZAjE6Ioj2ug==} + /@types/cookie@0.5.4: + resolution: {integrity: sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==} dev: true - /@types/debug@4.1.10: - resolution: {integrity: sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==} + /@types/debug@4.1.12: + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} dependencies: - '@types/ms': 0.7.33 + '@types/ms': 0.7.34 - /@types/diff@5.0.7: - resolution: {integrity: sha512-adBosR2GntaQQiuHnfRN9HtxYpoHHJBcdyz7VSXhjpSAmtvIfu/S1fjTqwuIx/Ypba6LCZdfWIqPYx2BR5TneQ==} + /@types/diff@5.0.8: + resolution: {integrity: sha512-kR0gRf0wMwpxQq6ME5s+tWk9zVCfJUl98eRkD05HWWRbhPB/eu4V1IbyZAsvzC1Gn4znBJ0HN01M4DGXdBEV8Q==} dev: true - /@types/dlv@1.1.3: - resolution: {integrity: sha512-u6JdAm9wje4n7vqkK9F6nQI18xSO+MVfXz6RMgN4acJmSZMlV7ZRrEQg4d1wmiQ2txg2xArpc68RS6p4JecVNg==} + /@types/dlv@1.1.4: + resolution: {integrity: sha512-m8KmImw4Jt+4rIgupwfivrWEOnj1LzkmKkqbh075uG13eTQ1ZxHWT6T0vIdSQhLIjQCiR0n0lZdtyDOPO1x2Mw==} dev: true - /@types/dom-view-transitions@1.0.3: - resolution: {integrity: sha512-1X/BUVdo9pKho8SFWVNcIz0fasBAqwcAvWGMt0Z57LUN68I4AtdrgTUXFryZW/OHUSO+9OH9KtSgCTMrzOZdRg==} + /@types/dom-view-transitions@1.0.4: + resolution: {integrity: sha512-oDuagM6G+xPLrLU4KeCKlr1oalMF5mJqV5pDPMDVIEaa8AkUW00i6u+5P02XCjdEEUQJC9dpnxqSLsZeAciSLQ==} dev: true - /@types/estree-jsx@1.0.2: - resolution: {integrity: sha512-GNBWlGBMjiiiL5TSkvPtOteuXsiVitw5MYGY1UYlrAq0SKyczsls6sCD7TZ8fsjRsvCVxml7EbyjJezPb3DrSA==} + /@types/estree-jsx@1.0.3: + resolution: {integrity: sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==} dependencies: - '@types/estree': 1.0.3 - - /@types/estree@0.0.39: - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - dev: false - - /@types/estree@1.0.3: - resolution: {integrity: sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==} + '@types/estree': 1.0.5 - /@types/extend@3.0.3: - resolution: {integrity: sha512-1Hz9SFYIkslmAt4R5WCpJBzCX9Cn+flMDgKbBXV3c47VyhLOOGYo52SIeoW00VBiUCI/dqKbnfM/8IC7Cm0h6g==} - dev: true + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - /@types/hast@2.3.7: - resolution: {integrity: sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw==} + /@types/hast@2.3.8: + resolution: {integrity: sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 + dev: true - /@types/hast@3.0.2: - resolution: {integrity: sha512-B5hZHgHsXvfCoO3xgNJvBnX7N8p86TqQeGKXcokW4XXi+qY4vxxPSFYofytvVmpFxzPv7oxDQzjg5Un5m2/xiw==} + /@types/hast@3.0.3: + resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} dependencies: - '@types/unist': 2.0.9 - dev: false + '@types/unist': 3.0.2 - /@types/html-escaper@3.0.1: - resolution: {integrity: sha512-lVnoTUR09iECkTInzCzFEasZKs11VuCTIdo8hnLXwCU40UUbSl8boPsy6MNJ9+HbJQ/jxju8nSZxSHPVIbmCbg==} + /@types/html-escaper@3.0.2: + resolution: {integrity: sha512-A8vk09eyYzk8J/lFO4OUMKCmRN0rRzfZf4n3Olwapgox/PtTiU8zPYlL1UEkJ/WeHvV6v9Xnj3o/705PKz9r4Q==} dev: true - /@types/http-cache-semantics@4.0.3: - resolution: {integrity: sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==} + /@types/http-cache-semantics@4.0.4: + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} dev: true /@types/is-ci@3.0.3: @@ -8426,100 +7395,94 @@ packages: ci-info: 3.9.0 dev: true - /@types/js-yaml@4.0.8: - resolution: {integrity: sha512-m6jnPk1VhlYRiLFm3f8X9Uep761f+CK8mHyS65LutH2OhmBF0BeMEjHgg05usH8PLZMWWc/BUR9RPmkvpWnyRA==} + /@types/js-yaml@4.0.9: + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} dev: true - /@types/json-schema@7.0.14: - resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==} + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true /@types/json5@0.0.30: resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==} dev: true - /@types/katex@0.16.5: - resolution: {integrity: sha512-DD2Y3xMlTQvAnN6d8803xdgnOeYZ+HwMglb7/9YCf49J9RkJL53azf9qKa40MkEYhqVwxZ1GS2+VlShnz4Z1Bw==} + /@types/katex@0.16.6: + resolution: {integrity: sha512-rZYO1HInM99rAFYNwGqbYPxHZHxu2IwZYKj4bJ4oh6edVrm1UId8mmbHIZLBtG253qU6y3piag0XYe/joNnwzQ==} dev: true - /@types/linkify-it@3.0.4: - resolution: {integrity: sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==} + /@types/linkify-it@3.0.5: + resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} /@types/markdown-it@12.2.3: resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} requiresBuild: true dependencies: - '@types/linkify-it': 3.0.4 - '@types/mdurl': 1.0.4 + '@types/linkify-it': 3.0.5 + '@types/mdurl': 1.0.5 dev: false optional: true - /@types/markdown-it@13.0.4: - resolution: {integrity: sha512-FAIUdEXrCDnQmAAmJC+UeW/3p0eCI4QZ/+W0lX/h83VD3v78IgTFYftjnAeXS8H0g4PFQCgipc51cQDA8tjgLw==} + /@types/markdown-it@13.0.6: + resolution: {integrity: sha512-0VqpvusJn1/lwRegCxcHVdmLfF+wIsprsKMC9xW8UPcTxhFcQtoN/fBU1zMe8pH7D/RuueMh2CaBaNv+GrLqTw==} dependencies: - '@types/linkify-it': 3.0.4 - '@types/mdurl': 1.0.4 + '@types/linkify-it': 3.0.5 + '@types/mdurl': 1.0.5 dev: true /@types/mathjax@0.0.37: resolution: {integrity: sha512-y0WSZBtBNQwcYipTU/BhgeFu1EZNlFvUNCmkMXV9kBQZq7/o5z82dNVyH3yy2Xv5zzeNeQoHSL4Xm06+EQiH+g==} dev: true - /@types/mdast@3.0.14: - resolution: {integrity: sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==} - dependencies: - '@types/unist': 2.0.9 - - /@types/mdast@4.0.2: - resolution: {integrity: sha512-tYR83EignvhYO9iU3kDg8V28M0jqyh9zzp5GV+EO+AYnyUl3P5ltkTeJuTiFZQFz670FSb3EwT/6LQdX+UdKfw==} + /@types/mdast@4.0.3: + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} dependencies: - '@types/unist': 2.0.9 - dev: false + '@types/unist': 3.0.2 - /@types/mdurl@1.0.4: - resolution: {integrity: sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==} + /@types/mdurl@1.0.5: + resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} - /@types/mdx@2.0.9: - resolution: {integrity: sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg==} + /@types/mdx@2.0.10: + resolution: {integrity: sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==} dev: false - /@types/mime@1.3.4: - resolution: {integrity: sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==} + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: true - /@types/mime@3.0.3: - resolution: {integrity: sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==} + /@types/mime@3.0.4: + resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} dev: true /@types/minimist@1.2.4: resolution: {integrity: sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==} dev: true - /@types/mocha@10.0.3: - resolution: {integrity: sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ==} + /@types/mocha@10.0.4: + resolution: {integrity: sha512-xKU7bUjiFTIttpWaIZ9qvgg+22O1nmbA+HRxdlR+u6TWsGfmFdXrheJoK4fFxrHNVIOBDvDNKZG+LYBpMHpX3w==} dev: true - /@types/ms@0.7.33: - resolution: {integrity: sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==} + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - /@types/needle@3.2.2: - resolution: {integrity: sha512-xUKAjFjDcucpgfyTvnbaqN+WBKyM9UehBuVRI/1AoPbaXrCScADqeTgTM1ZBYnS3Ovs9IEQt813IcJNyac7dNQ==} + /@types/needle@3.2.3: + resolution: {integrity: sha512-aUtoZUGROl654rDZlZYPRYaysAOBaVgjnbmYKq3n32afuqFvEts31YGixTebSOCJt7B7qKnHzCzcjbMig5LcQg==} dependencies: - '@types/node': 18.18.6 + '@types/node': 20.9.1 dev: true /@types/nlcst@1.0.3: resolution: {integrity: sha512-cpO6PPMz4E++zxP2Vhp/3KVl2Nbtj+Iksb25rlRinG7mphu2zmCIKWWlqdsx1NwJEISogR2eeZTD7JqLOCzaiw==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 dev: false /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node@16.18.59: - resolution: {integrity: sha512-PJ1w2cNeKUEdey4LiPra0ZuxZFOGvetswE8qHRriV/sUkL5Al4tTmPV9D2+Y/TPIxTHHgxTfRjZVKWhPw/ORhQ==} + /@types/node@16.18.61: + resolution: {integrity: sha512-k0N7BqGhJoJzdh6MuQg1V1ragJiXTh8VUBAZTWjJ9cUq23SG0F0xavOwZbhiP4J3y20xd6jxKx+xNUhkMAi76Q==} dev: false /@types/node@17.0.45: @@ -8529,55 +7492,57 @@ packages: /@types/node@18.18.6: resolution: {integrity: sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==} + /@types/node@18.18.9: + resolution: {integrity: sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/node@20.9.1: + resolution: {integrity: sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/normalize-package-data@2.4.3: resolution: {integrity: sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==} dev: true - /@types/parse5@6.0.3: - resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} - dev: false - - /@types/prismjs@1.26.0: - resolution: {integrity: sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==} + /@types/prismjs@1.26.3: + resolution: {integrity: sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==} dev: true - /@types/probe-image-size@7.2.2: - resolution: {integrity: sha512-rNWbJLj3XdCfiHsaDVTkPgvTtxlVMgNEpGpJYU/d2pVwzIpjumZguQzlnOQPWF7ajPOpX00rmPQGerRlB3tL+g==} + /@types/probe-image-size@7.2.3: + resolution: {integrity: sha512-6OJa/Tj7OjiahwdcfLWvrzGpXLSjLfbfjqdpth2Oy9YKI58A6Ec5YvFcqfVXOSaJPkA3W+nZx6cPheMQrdtz1w==} dependencies: - '@types/needle': 3.2.2 - '@types/node': 18.18.6 + '@types/needle': 3.2.3 + '@types/node': 20.9.1 dev: true - /@types/prompts@2.4.7: - resolution: {integrity: sha512-5zTamE+QQM4nR6Ab3yHK+ovWuhLJXaa2ZLt3mT1en8U3ubWtjVT1vXDaVFC2+cL89uVn7Y+gIq5B3IcVvBl5xQ==} + /@types/prompts@2.4.8: + resolution: {integrity: sha512-fPOEzviubkEVCiLduO45h+zFHB0RZX8tFt3C783sO5cT7fUXf3EEECpD26djtYdh4Isa9Z9tasMQuZnYPtvYzw==} dependencies: - '@types/node': 18.18.6 + '@types/node': 20.9.1 kleur: 3.0.3 dev: true - /@types/prop-types@15.7.9: - resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} + /@types/prop-types@15.7.10: + resolution: {integrity: sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==} - /@types/react-dom@18.2.14: - resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} + /@types/react-dom@18.2.15: + resolution: {integrity: sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==} dependencies: - '@types/react': 18.2.31 + '@types/react': 18.2.37 - /@types/react@18.2.31: - resolution: {integrity: sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==} + /@types/react@18.2.37: + resolution: {integrity: sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==} dependencies: - '@types/prop-types': 15.7.9 - '@types/scheduler': 0.16.5 + '@types/prop-types': 15.7.10 + '@types/scheduler': 0.16.6 csstype: 3.1.2 - /@types/resolve@1.17.1: - resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} - dependencies: - '@types/node': 18.18.6 - dev: false - - /@types/resolve@1.20.4: - resolution: {integrity: sha512-BKGK0T1VgB1zD+PwQR4RRf0ais3NyvH1qjLUrHI5SEiccYaJrhLstLuoXFWJ+2Op9whGizSPUMGPJY/Qtb/A2w==} + /@types/resolve@1.20.5: + resolution: {integrity: sha512-aten5YPFp8G+cMpkTK5MCcUW5GlwZUby+qlt0/3oFgOCooFgzqvZQ9/0tROY49sUYmhEybBBj3jwpkQ/R3rjjw==} dev: true /@types/sax@1.2.6: @@ -8586,30 +7551,34 @@ packages: '@types/node': 18.18.6 dev: false - /@types/scheduler@0.16.5: - resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==} + /@types/scheduler@0.16.6: + resolution: {integrity: sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==} /@types/semver@7.5.4: resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==} dev: true - /@types/send@0.17.3: - resolution: {integrity: sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==} + /@types/semver@7.5.5: + resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==} + dev: true + + /@types/send@0.17.4: + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: - '@types/mime': 1.3.4 - '@types/node': 18.18.6 + '@types/mime': 1.3.5 + '@types/node': 20.9.1 dev: true - /@types/server-destroy@1.0.2: - resolution: {integrity: sha512-Ac4skQzgViPGKqWU89yrtDDfZHvwDxQOzGnd4aS6Tab9IL3VatvfYk2LScKGNS/EML21yvF/9Zy4lMl74tXkPw==} + /@types/server-destroy@1.0.3: + resolution: {integrity: sha512-Qq0fn70C7TLDG1W9FCblKufNWW1OckQ41dVKV2Dku5KdZF7bexezG4e2WBaBKhdwL3HZ+cYCEIKwg2BRgzrWmA==} dependencies: - '@types/node': 18.18.6 + '@types/node': 20.9.1 dev: true - /@types/set-cookie-parser@2.4.5: - resolution: {integrity: sha512-ZPmztaAQ4rbnW/WTUnT1dwSENQo4bjGqxCSeyK+gZxmd+zJl/QAeF6dpEXcS5UEJX22HwiggFSaY8nE1nRmkbg==} + /@types/set-cookie-parser@2.4.6: + resolution: {integrity: sha512-tjIRMxGztGfIbW2/d20MdJmAPZbabtdW051cKfU+nvZXUnKKifHbY2CyL/C0EGabUB8ahIRjanYzTqJUQR8TAQ==} dependencies: - '@types/node': 18.18.6 + '@types/node': 20.9.1 dev: true /@types/strip-bom@3.0.0: @@ -8623,23 +7592,26 @@ packages: /@types/trusted-types@2.0.5: resolution: {integrity: sha512-I3pkr8j/6tmQtKV/ZzHtuaqYSQvyjGRKH4go60Rr0IDLlFxuRT5V32uvB1mecM5G1EVAUyF/4r4QZ1GHgz+mxA==} - /@types/unist@2.0.9: - resolution: {integrity: sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ==} + /@types/ungap__structured-clone@0.3.2: + resolution: {integrity: sha512-a7oBPz4/IurTfw0/+R4F315npapBXlSimrQlmDfr0lo1Pv0BeHNADgbHXdDP8LCjnCiRne4jRSr/5UnQitX2og==} + dev: true - /@types/unist@3.0.1: - resolution: {integrity: sha512-ue/hDUpPjC85m+PM9OQDMZr3LywT+CT6mPsQq8OJtCLiERkGRcQUFvu9XASF5XWqyZFXbf15lvb3JFJ4dRLWPg==} - dev: false + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} - /@types/which-pm-runs@1.0.1: - resolution: {integrity: sha512-RMI8GIL1+Ky7+dRuAfJgOyEWo7ss0lKPwi3VyircV32lUoLjiEDhemt7YuTxbXaxa1XXd+F0xrUaxHdh7gr52A==} + /@types/unist@3.0.2: + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + + /@types/which-pm-runs@1.0.2: + resolution: {integrity: sha512-M0ZefeDApctHbjqtATOiixiwafG7pXD3exxnjku4XmX9+2DmONGghv5Z8Pnm0lNLBZKvDQyuG+4pLkH2UkP5gg==} dev: true - /@types/yargs-parser@21.0.2: - resolution: {integrity: sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==} + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} dev: true - /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.1.6): - resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==} + /@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2): + resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -8649,26 +7621,26 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.9.1 - '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.1.6) - '@typescript-eslint/scope-manager': 6.8.0 - '@typescript-eslint/type-utils': 6.8.0(eslint@8.52.0)(typescript@5.1.6) - '@typescript-eslint/utils': 6.8.0(eslint@8.52.0)(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 6.8.0 + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 6.11.0(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.11.0 + '@typescript-eslint/type-utils': 6.11.0(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.11.0(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.11.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 + eslint: 8.54.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.1.6) - typescript: 5.1.6 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.8.0(eslint@8.52.0)(typescript@5.1.6): - resolution: {integrity: sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==} + /@typescript-eslint/parser@6.11.0(eslint@8.54.0)(typescript@5.2.2): + resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -8677,27 +7649,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.8.0 - '@typescript-eslint/types': 6.8.0 - '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 6.8.0 + '@typescript-eslint/scope-manager': 6.11.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.11.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 - typescript: 5.1.6 + eslint: 8.54.0 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.8.0: - resolution: {integrity: sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==} + /@typescript-eslint/scope-manager@6.11.0: + resolution: {integrity: sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.8.0 - '@typescript-eslint/visitor-keys': 6.8.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/visitor-keys': 6.11.0 dev: true - /@typescript-eslint/type-utils@6.8.0(eslint@8.52.0)(typescript@5.1.6): - resolution: {integrity: sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==} + /@typescript-eslint/type-utils@6.11.0(eslint@8.54.0)(typescript@5.2.2): + resolution: {integrity: sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -8706,23 +7678,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.8.0(eslint@8.52.0)(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.11.0(eslint@8.54.0)(typescript@5.2.2) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 - ts-api-utils: 1.0.3(typescript@5.1.6) - typescript: 5.1.6 + eslint: 8.54.0 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.8.0: - resolution: {integrity: sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==} + /@typescript-eslint/types@6.11.0: + resolution: {integrity: sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.8.0(typescript@5.1.6): - resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==} + /@typescript-eslint/typescript-estree@6.11.0(typescript@5.2.2): + resolution: {integrity: sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -8730,42 +7702,42 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.8.0 - '@typescript-eslint/visitor-keys': 6.8.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/visitor-keys': 6.11.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.1.6) - typescript: 5.1.6 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.8.0(eslint@8.52.0)(typescript@5.1.6): - resolution: {integrity: sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==} + /@typescript-eslint/utils@6.11.0(eslint@8.54.0)(typescript@5.2.2): + resolution: {integrity: sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - '@types/json-schema': 7.0.14 - '@types/semver': 7.5.4 - '@typescript-eslint/scope-manager': 6.8.0 - '@typescript-eslint/types': 6.8.0 - '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.1.6) - eslint: 8.52.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.5 + '@typescript-eslint/scope-manager': 6.11.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) + eslint: 8.54.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.8.0: - resolution: {integrity: sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==} + /@typescript-eslint/visitor-keys@6.11.0: + resolution: {integrity: sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/types': 6.11.0 eslint-visitor-keys: 3.4.3 dev: true @@ -8804,81 +7776,81 @@ packages: server-only: 0.0.1 dev: false - /@vercel/edge@1.1.0: - resolution: {integrity: sha512-84H2EavY5Kul9Ef1DnTH0XEG5vChqcXjyqoRLVPjjZjLWw47sMapzXXQH09pybcshR+8AKqULGvFqPTWuRh3Rw==} + /@vercel/edge@1.1.1: + resolution: {integrity: sha512-NtKiIbn9Cq6HWGy+qRudz28mz5nxfOJWls5Pnckjw1yCfSX8rhXdvY/il3Sy3Zd5n/sKCM2h7VSCCpJF/oaDrQ==} dev: true - /@vercel/nft@0.23.1: - resolution: {integrity: sha512-NE0xSmGWVhgHF1OIoir71XAd0W0C1UE3nzFyhpFiMr3rVhetww7NvM1kc41trBsPG37Bh+dE5FYCTMzM/gBu0w==} - engines: {node: '>=14'} + /@vercel/nft@0.24.3: + resolution: {integrity: sha512-IyBdIxmFAeGZnEfMgt4QrGK7XX4lWazlQj34HEi9dw04/WeDBJ7r1yaOIO5tTf9pbfvwUFodj9b0H+NDGGoOMg==} + engines: {node: '>=16'} hasBin: true dependencies: '@mapbox/node-pre-gyp': 1.0.11 '@rollup/pluginutils': 4.2.1 - acorn: 8.10.0 + acorn: 8.11.2 async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 glob: 7.2.3 graceful-fs: 4.2.11 micromatch: 4.0.5 - node-gyp-build: 4.6.1 + node-gyp-build: 4.7.0 resolve-from: 5.0.0 transitivePeerDependencies: - encoding - supports-color dev: false - /@vitejs/plugin-react@4.1.0(vite@4.5.0): - resolution: {integrity: sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==} + /@vitejs/plugin-react@4.2.0(vite@5.0.0): + resolution: {integrity: sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.2.0 + vite: ^4.2.0 || ^5.0.0 peerDependenciesMeta: vite: optional: true dependencies: - '@babel/core': 7.23.2 - '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.2) - '@types/babel__core': 7.20.3 + '@babel/core': 7.23.3 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.3) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.3) + '@types/babel__core': 7.20.4 react-refresh: 0.14.0 - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + vite: 5.0.0(@types/node@18.18.6)(sass@1.69.5) transitivePeerDependencies: - supports-color dev: false - /@vitejs/plugin-vue-jsx@3.0.2(vite@4.5.0)(vue@3.3.6): - resolution: {integrity: sha512-obF26P2Z4Ogy3cPp07B4VaW6rpiu0ue4OT2Y15UxT5BZZ76haUY9guOsZV3uWh/I6xc+VeiW+ZVabRE82FyzWw==} + /@vitejs/plugin-vue-jsx@3.1.0(vite@5.0.0)(vue@3.3.8): + resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.0.0 + vite: ^4.0.0 || ^5.0.0 vue: ^3.0.0 peerDependenciesMeta: vite: optional: true dependencies: - '@babel/core': 7.23.2 - '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.2) - '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.2) - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) - vue: 3.3.6(typescript@5.1.6) + '@babel/core': 7.23.3 + '@babel/plugin-transform-typescript': 7.23.3(@babel/core@7.23.3) + '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.3) + vite: 5.0.0(@types/node@18.18.6)(sass@1.69.5) + vue: 3.3.8(typescript@5.2.2) transitivePeerDependencies: - supports-color dev: false - /@vitejs/plugin-vue@4.4.0(vite@4.5.0)(vue@3.3.6): - resolution: {integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==} + /@vitejs/plugin-vue@4.5.0(vite@5.0.0)(vue@3.3.8): + resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.0.0 + vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 peerDependenciesMeta: vite: optional: true dependencies: - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) - vue: 3.3.6(typescript@5.1.6) + vite: 5.0.0(@types/node@18.18.6)(sass@1.69.5) + vue: 3.3.8(typescript@5.2.2) dev: false /@vitest/expect@0.34.6: @@ -8919,59 +7891,60 @@ packages: pretty-format: 29.7.0 dev: false - /@volar/kit@1.10.4(typescript@5.1.6): - resolution: {integrity: sha512-ha6xNFwkLoRysR90JqJ05xKhjZ3vUMkxjOBif6MaS1eF4sVip2579fygSPsAXviT81gA+oyWJeKBWD8nhdnxIg==} + /@volar/kit@1.10.10(typescript@5.2.2): + resolution: {integrity: sha512-V2SyUPCPUhueqH8j5t48LJ0QsjExGSXzTv/XOdkUHV7hJ/ekyRGFqKxcfBtMq/nK6Tgu2G1ba+6u0d7e6wKcQw==} peerDependencies: typescript: '*' dependencies: - '@volar/language-service': 1.10.4 + '@volar/language-service': 1.10.10 typesafe-path: 0.2.2 - typescript: 5.1.6 + typescript: 5.2.2 vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 dev: true - /@volar/language-core@1.10.4: - resolution: {integrity: sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==} + /@volar/language-core@1.10.10: + resolution: {integrity: sha512-nsV1o3AZ5n5jaEAObrS3MWLBWaGwUj/vAsc15FVNIv+DbpizQRISg9wzygsHBr56ELRH8r4K75vkYNMtsSNNWw==} dependencies: - '@volar/source-map': 1.10.4 + '@volar/source-map': 1.10.10 dev: true - /@volar/language-server@1.10.4: - resolution: {integrity: sha512-LhCz5GTdA6nRy35GIqCnYRljWC+C+sPT/AF5FNZnSjUn9I/Ug5io2LI2RnMLCKFQM1v9VFePHMiHBl639Rf6Kw==} + /@volar/language-server@1.10.10: + resolution: {integrity: sha512-F2PRBU+CRjT7L9qe8bjof/uz/LbAXVmgwNU2gOSX2y1bUl3E8DHmD0dB6pwIVublvkx+Ivg/0r3Z6oyxfPPruQ==} dependencies: - '@volar/language-core': 1.10.4 - '@volar/language-service': 1.10.4 - '@volar/typescript': 1.10.4 + '@volar/language-core': 1.10.10 + '@volar/language-service': 1.10.10 + '@volar/typescript': 1.10.10 '@vscode/l10n': 0.0.16 + path-browserify: 1.0.1 request-light: 0.7.0 - typesafe-path: 0.2.2 vscode-languageserver: 9.0.1 vscode-languageserver-protocol: 3.17.5 vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 dev: true - /@volar/language-service@1.10.4: - resolution: {integrity: sha512-SGDsmGojVJi7RiHM9WON4O2Ed7PbjU+3gzEn0lODxK5qa+PDGzzSaFWIQeCp8Av+ef5uhZ4gJcTUR3AmD/29HQ==} + /@volar/language-service@1.10.10: + resolution: {integrity: sha512-P4fiPWDI6fLGO6BghlksCVHs1nr9gvWAMDyma3Bca4aowxXusxjUVTsnJq0EVorIN5uIr1Xel4B/tNdXt/IKyw==} dependencies: - '@volar/language-core': 1.10.4 - '@volar/source-map': 1.10.4 + '@volar/language-core': 1.10.10 + '@volar/source-map': 1.10.10 vscode-languageserver-protocol: 3.17.5 vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 dev: true - /@volar/source-map@1.10.4: - resolution: {integrity: sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==} + /@volar/source-map@1.10.10: + resolution: {integrity: sha512-GVKjLnifV4voJ9F0vhP56p4+F3WGf+gXlRtjFZsv6v3WxBTWU3ZVeaRaEHJmWrcv5LXmoYYpk/SC25BKemPRkg==} dependencies: muggle-string: 0.3.1 dev: true - /@volar/typescript@1.10.4: - resolution: {integrity: sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==} + /@volar/typescript@1.10.10: + resolution: {integrity: sha512-4a2r5bdUub2m+mYVnLu2wt59fuoYWe7nf0uXtGHU8QQ5LDNfzAR0wK7NgDiQ9rcl2WT3fxT2AA9AylAwFtj50A==} dependencies: - '@volar/language-core': 1.10.4 + '@volar/language-core': 1.10.10 + path-browserify: 1.0.1 dev: true /@vscode/emmet-helper@2.9.2: @@ -8992,7 +7965,7 @@ packages: resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==} dev: false - /@vue/babel-plugin-jsx@1.1.5(@babel/core@7.23.2): + /@vue/babel-plugin-jsx@1.1.5(@babel/core@7.23.3): resolution: {integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==} peerDependencies: '@babel/core': ^7.0.0-0 @@ -9000,12 +7973,12 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-module-imports': 7.22.15 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.3) '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 '@vue/babel-helper-vue-transform-on': 1.1.5 camelcase: 6.3.0 html-tags: 3.3.1 @@ -9014,46 +7987,46 @@ packages: - supports-color dev: false - /@vue/compiler-core@3.3.6: - resolution: {integrity: sha512-2JNjemwaNwf+MkkatATVZi7oAH1Hx0B04DdPH3ZoZ8vKC1xZVP7nl4HIsk8XYd3r+/52sqqoz9TWzYc3yE9dqA==} + /@vue/compiler-core@3.3.8: + resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} dependencies: - '@babel/parser': 7.23.0 - '@vue/shared': 3.3.6 + '@babel/parser': 7.23.3 + '@vue/shared': 3.3.8 estree-walker: 2.0.2 source-map-js: 1.0.2 - /@vue/compiler-dom@3.3.6: - resolution: {integrity: sha512-1MxXcJYMHiTPexjLAJUkNs/Tw2eDf2tY3a0rL+LfuWyiKN2s6jvSwywH3PWD8bKICjfebX3GWx2Os8jkRDq3Ng==} + /@vue/compiler-dom@3.3.8: + resolution: {integrity: sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==} dependencies: - '@vue/compiler-core': 3.3.6 - '@vue/shared': 3.3.6 + '@vue/compiler-core': 3.3.8 + '@vue/shared': 3.3.8 - /@vue/compiler-sfc@3.3.6: - resolution: {integrity: sha512-/Kms6du2h1VrXFreuZmlvQej8B1zenBqIohP0690IUBkJjsFvJxY0crcvVRJ0UhMgSR9dewB+khdR1DfbpArJA==} + /@vue/compiler-sfc@3.3.8: + resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} dependencies: - '@babel/parser': 7.23.0 - '@vue/compiler-core': 3.3.6 - '@vue/compiler-dom': 3.3.6 - '@vue/compiler-ssr': 3.3.6 - '@vue/reactivity-transform': 3.3.6 - '@vue/shared': 3.3.6 + '@babel/parser': 7.23.3 + '@vue/compiler-core': 3.3.8 + '@vue/compiler-dom': 3.3.8 + '@vue/compiler-ssr': 3.3.8 + '@vue/reactivity-transform': 3.3.8 + '@vue/shared': 3.3.8 estree-walker: 2.0.2 magic-string: 0.30.5 postcss: 8.4.31 source-map-js: 1.0.2 - /@vue/compiler-ssr@3.3.6: - resolution: {integrity: sha512-QTIHAfDCHhjXlYGkUg5KH7YwYtdUM1vcFl/FxFDlD6d0nXAmnjizka3HITp8DGudzHndv2PjKVS44vqqy0vP4w==} + /@vue/compiler-ssr@3.3.8: + resolution: {integrity: sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==} dependencies: - '@vue/compiler-dom': 3.3.6 - '@vue/shared': 3.3.6 + '@vue/compiler-dom': 3.3.8 + '@vue/shared': 3.3.8 - /@vue/reactivity-transform@3.3.6: - resolution: {integrity: sha512-RlJl4dHfeO7EuzU1iJOsrlqWyJfHTkJbvYz/IOJWqu8dlCNWtxWX377WI0VsbAgBizjwD+3ZjdnvSyyFW1YVng==} + /@vue/reactivity-transform@3.3.8: + resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==} dependencies: - '@babel/parser': 7.23.0 - '@vue/compiler-core': 3.3.6 - '@vue/shared': 3.3.6 + '@babel/parser': 7.23.3 + '@vue/compiler-core': 3.3.8 + '@vue/shared': 3.3.8 estree-walker: 2.0.2 magic-string: 0.30.5 @@ -9063,39 +8036,39 @@ packages: '@vue/shared': 3.1.5 dev: false - /@vue/reactivity@3.3.6: - resolution: {integrity: sha512-gtChAumfQz5lSy5jZXfyXbKrIYPf9XEOrIr6rxwVyeWVjFhJwmwPLtV6Yis+M9onzX++I5AVE9j+iPH60U+B8Q==} + /@vue/reactivity@3.3.8: + resolution: {integrity: sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==} dependencies: - '@vue/shared': 3.3.6 + '@vue/shared': 3.3.8 - /@vue/runtime-core@3.3.6: - resolution: {integrity: sha512-qp7HTP1iw1UW2ZGJ8L3zpqlngrBKvLsDAcq5lA6JvEXHmpoEmjKju7ahM9W2p/h51h0OT5F2fGlP/gMhHOmbUA==} + /@vue/runtime-core@3.3.8: + resolution: {integrity: sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==} dependencies: - '@vue/reactivity': 3.3.6 - '@vue/shared': 3.3.6 + '@vue/reactivity': 3.3.8 + '@vue/shared': 3.3.8 - /@vue/runtime-dom@3.3.6: - resolution: {integrity: sha512-AoX3Cp8NqMXjLbIG9YR6n/pPLWE9TiDdk6wTJHFnl2GpHzDFH1HLBC9wlqqQ7RlnvN3bVLpzPGAAH00SAtOxHg==} + /@vue/runtime-dom@3.3.8: + resolution: {integrity: sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==} dependencies: - '@vue/runtime-core': 3.3.6 - '@vue/shared': 3.3.6 + '@vue/runtime-core': 3.3.8 + '@vue/shared': 3.3.8 csstype: 3.1.2 - /@vue/server-renderer@3.3.6(vue@3.3.6): - resolution: {integrity: sha512-kgLoN43W4ERdZ6dpyy+gnk2ZHtcOaIr5Uc/WUP5DRwutgvluzu2pudsZGoD2b7AEJHByUVMa9k6Sho5lLRCykw==} + /@vue/server-renderer@3.3.8(vue@3.3.8): + resolution: {integrity: sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==} peerDependencies: - vue: 3.3.6 + vue: 3.3.8 dependencies: - '@vue/compiler-ssr': 3.3.6 - '@vue/shared': 3.3.6 - vue: 3.3.6(typescript@5.1.6) + '@vue/compiler-ssr': 3.3.8 + '@vue/shared': 3.3.8 + vue: 3.3.8(typescript@5.2.2) /@vue/shared@3.1.5: resolution: {integrity: sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==} dev: false - /@vue/shared@3.3.6: - resolution: {integrity: sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ==} + /@vue/shared@3.3.8: + resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} /@webcomponents/template-shadowroot@0.2.1: resolution: {integrity: sha512-fXL/vIUakyZL62hyvUh+EMwbVoTc0hksublmRz6ai6et8znHkJa6gtqMUZo1oc7dIz46exHSIImml9QTdknMHg==} @@ -9117,28 +8090,28 @@ packages: negotiator: 0.6.3 dev: true - /acorn-globals@7.0.1: - resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} - dependencies: - acorn: 8.10.0 - acorn-walk: 8.2.0 - dev: true - - /acorn-jsx@5.3.2(acorn@8.10.0): + /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.10.0 + acorn: 8.11.2 /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} + dev: false /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true + dev: false + + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + engines: {node: '>=0.4.0'} + hasBin: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -9148,6 +8121,15 @@ packages: transitivePeerDependencies: - supports-color + /agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: false + /aggregate-error@4.0.1: resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} engines: {node: '>=12'} @@ -9165,17 +8147,8 @@ packages: uri-js: 4.4.1 dev: true - /ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: false - - /alpinejs@3.13.2: - resolution: {integrity: sha512-WzojeeN082kLZznGI1HAuP8yFJSWqJ1fGdz2mUjj45H4y0XwToE7fFqtI3mCPRR+BpcSbxT/NL+FyPnYAWSltw==} + /alpinejs@3.13.3: + resolution: {integrity: sha512-WZ6WQjkAOl+WdW/jukzNHq9zHFDNKmkk/x6WF7WdyNDD6woinrfXCVsZXm0galjbco+pEpYmJLtwlZwcOfIVdg==} dependencies: '@vue/reactivity': 3.1.5 dev: false @@ -9281,6 +8254,7 @@ packages: dependencies: call-bind: 1.0.5 is-array-buffer: 3.0.2 + dev: true /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} @@ -9316,6 +8290,7 @@ packages: get-intrinsic: 1.2.2 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 + dev: true /arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} @@ -9330,23 +8305,23 @@ packages: hasBin: true dev: false - /astro-auto-import@0.3.1(astro@packages+astro): - resolution: {integrity: sha512-4kXZMlZFiq3dqT6fcfPbCjHTABQ279eKbIqZAb6qktBhGlmHwpHr1spOUFj/RQFilaWVgfjzOBmuZnoydZb5Vg==} + /astro-auto-import@0.3.2(astro@packages+astro): + resolution: {integrity: sha512-xnr56geVyqJTu5qicJzvxqSnkhktq7SulWIzme1Vs5mrrcMkH/N1s7TEYkgJCN2b5qSeltqqZ7UUSD3xXrXamA==} engines: {node: '>=16.0.0'} peerDependencies: astro: '*' dependencies: - '@types/node': 18.18.6 - acorn: 8.10.0 + '@types/node': 18.18.9 + acorn: 8.11.2 astro: link:packages/astro dev: false - /astro-embed@0.5.1(astro@packages+astro): - resolution: {integrity: sha512-ucrikhD3KwuTLNJUbZmAYddGakf9Tmw4TBr43YseGPfpZrKk1rMOD70d6ehj7Ai3kkTziab1vGXA56dAWf9bVg==} + /astro-embed@0.6.0(astro@packages+astro): + resolution: {integrity: sha512-KE1cBjQvCdqNv1C/oXG5sMfH+bbovu7F88pK1J/iZRaoaRqH2sNe5ZT1G25PDlzvcPYzK6KNB2aUm8jBRNQJfg==} peerDependencies: astro: '*' dependencies: - '@astro-community/astro-embed-integration': 0.5.1(astro@packages+astro) + '@astro-community/astro-embed-integration': 0.6.0(astro@packages+astro) '@astro-community/astro-embed-twitter': 0.5.2(astro@packages+astro) '@astro-community/astro-embed-vimeo': 0.3.1(astro@packages+astro) '@astro-community/astro-embed-youtube': 0.4.1(astro@packages+astro) @@ -9365,18 +8340,9 @@ packages: resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} dev: false - /async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - dev: false - /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - /at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - dev: false - /autocannon@7.12.0: resolution: {integrity: sha512-SZwtwykFZaoz5pKg7WY7gw1Dayqv9buXSjvc99sSzZIfguUc4FmFEFJr3INtfXJ7o9Xyn5bJM093wxipVV59ZA==} hasBin: true @@ -9424,6 +8390,7 @@ packages: /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} + dev: true /axobject-query@3.2.1: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} @@ -9436,7 +8403,7 @@ packages: dev: false optional: true - /babel-plugin-jsx-dom-expressions@0.37.2(@babel/core@7.23.2): + /babel-plugin-jsx-dom-expressions@0.37.2(@babel/core@7.23.3): resolution: {integrity: sha512-u3VKB+On86cYSLAbw9j0m0X8ZejL4MR7oG7TRlrMQ/y1mauR/ZpM2xkiOPZEUlzHLo1GYGlTdP9s5D3XuA6iSQ==} peerDependencies: '@babel/core': ^7.20.12 @@ -9444,59 +8411,14 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) - '@babel/types': 7.23.0 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.3) + '@babel/types': 7.23.3 html-entities: 2.3.3 validate-html-nesting: 1.2.2 dev: false - /babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.23.2): - resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/compat-data': 7.23.2 - '@babel/core': 7.23.2 - '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-polyfill-corejs3@0.8.6(@babel/core@7.23.2): - resolution: {integrity: sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) - core-js-compat: 3.33.1 - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.23.2): - resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) - transitivePeerDependencies: - - supports-color - dev: false - /babel-plugin-transform-hook-names@1.0.2: resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} peerDependencies: @@ -9506,7 +8428,7 @@ packages: optional: true dev: false - /babel-preset-solid@1.8.2(@babel/core@7.23.2): + /babel-preset-solid@1.8.2(@babel/core@7.23.3): resolution: {integrity: sha512-hEIy4K1CGPQwCekFJ9NV3T92fezS4GQV0SQXEGVe9dyo+7iI7Fjuu6OKIdE5z/S4IfMEL6gCU+1AZ3yK6PnGMg==} peerDependencies: '@babel/core': ^7.0.0 @@ -9514,8 +8436,8 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.23.2 - babel-plugin-jsx-dom-expressions: 0.37.2(@babel/core@7.23.2) + '@babel/core': 7.23.3 + babel-plugin-jsx-dom-expressions: 0.37.2(@babel/core@7.23.3) dev: false /bail@2.0.2: @@ -9524,6 +8446,10 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base-64@1.0.0: + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + dev: false + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: false @@ -9630,6 +8556,7 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 + dev: true /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -9657,10 +8584,6 @@ packages: node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: false - /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} requiresBuild: true @@ -9677,11 +8600,6 @@ packages: ieee754: 1.2.1 dev: false - /builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - dev: false - /bundle-name@3.0.0: resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} engines: {node: '>=12'} @@ -9705,6 +8623,7 @@ packages: function-bind: 1.1.2 get-intrinsic: 1.2.2 set-function-length: 1.1.1 + dev: true /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -9748,8 +8667,8 @@ packages: /caniuse-lite@1.0.30001553: resolution: {integrity: sha512-N0ttd6TrFfuqKNi+pMgWJTb9qrdJu4JSpgPFLe/lrD19ugC6fZgF0pUewRowDwzdDnb9V41mFcdlYgl/PyKf4A==} - /canvas-confetti@1.9.0: - resolution: {integrity: sha512-0UGU/T5Un/Cd4Aj4fu/p/oVQm8Il+brK5xcmY+y77u7PXuyNJD4ODUWe01A5o3GUI9Bb8lOBlQ10VdaDsY1FBA==} + /canvas-confetti@1.9.1: + resolution: {integrity: sha512-jieDCn9OnPgFu5q+rbOGUmIGOjzgOnecW1/6KH07kAFAMwOczcTc4clde9pdyUPIAd/2wxZ8C5u7mBAcOpGK8Q==} dev: false /ccount@2.0.1: @@ -9893,6 +8812,12 @@ packages: /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + dev: true + + /ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + dev: false /clean-css@4.2.4: resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} @@ -9977,11 +8902,15 @@ packages: resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - '@types/estree': 1.0.3 - acorn: 8.10.0 + '@types/estree': 1.0.5 + acorn: 8.11.2 estree-walker: 3.0.3 periscopic: 3.1.0 + /collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + dev: false + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -10063,11 +8992,6 @@ packages: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} dev: false - /common-tags@1.8.2: - resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} - engines: {node: '>=4.0.0'} - dev: false - /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -10098,11 +9022,11 @@ packages: /cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + dev: true - /core-js-compat@3.33.1: - resolution: {integrity: sha512-6pYKNOgD/j/bkC5xS5IIg6bncid3rfrI42oBH1SQJbsmYPKF7rhzcFzYCcxYMmNQQ0rCEB8WqpW7QHndOggaeQ==} - dependencies: - browserslist: 4.22.1 + /cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} dev: false /cross-argv@2.0.0: @@ -10144,11 +9068,6 @@ packages: shebang-command: 2.0.0 which: 2.0.2 - /crypto-random-string@2.0.0: - resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} - engines: {node: '>=8'} - dev: false - /css-blank-pseudo@6.0.0(postcss@8.4.31): resolution: {integrity: sha512-VbfLlOWO7sBHBTn6pwDQzc07Z0SDydgDBfNfCE0nvrehdBNv9RKsuupIRa/qal0+fBZhAALyQDPMKz5lnvcchw==} engines: {node: ^14 || ^16 || >=18} @@ -10193,8 +9112,8 @@ packages: resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==} dev: false - /css-selector-parser@2.3.2: - resolution: {integrity: sha512-JjnG6/pdLJh3iqipq7kteNVtbIczsU2A1cNxb+VAiniSuNmrB/NI3us4rSCfArvlwRXYly+jZhUUfEoInSH9Qg==} + /css-selector-parser@3.0.0: + resolution: {integrity: sha512-ITsFspnTOObbNv81tXX+7QK/MtxciSBDAWQCKnmWIuwDSDDvfJD+YSPEpC7TMVhi1N2llzHHMz7xCX8AoC0L6w==} dev: false /css-tree@2.2.1: @@ -10216,8 +9135,8 @@ packages: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} - /cssdb@7.8.0: - resolution: {integrity: sha512-SkeezZOQr5AHt9MgJgSFNyiuJwg1p8AwoVln6JwaQJsyxduRW9QJ+HP/gAQzbsz8SIqINtYvpJKjxTRI67zxLg==} + /cssdb@7.9.0: + resolution: {integrity: sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw==} dev: true /cssesc@3.0.0: @@ -10232,19 +9151,15 @@ packages: css-tree: 2.2.1 dev: false - /cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - dev: true - /cssom@0.5.0: resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} dev: true - /cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} + /cssstyle@3.0.0: + resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} + engines: {node: '>=14'} dependencies: - cssom: 0.3.8 + rrweb-cssom: 0.6.0 dev: true /csstype@3.1.2: @@ -10277,13 +9192,13 @@ packages: engines: {node: '>= 12'} dev: false - /data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} + /data-urls@4.0.0: + resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} + engines: {node: '>=14'} dependencies: abab: 2.0.6 whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 + whatwg-url: 12.0.1 dev: true /dataloader@1.4.0: @@ -10416,6 +9331,7 @@ packages: get-intrinsic: 1.2.2 gopd: 1.0.1 has-property-descriptors: 1.0.1 + dev: true /define-lazy-prop@3.0.0: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} @@ -10429,9 +9345,10 @@ packages: define-data-property: 1.1.1 has-property-descriptors: 1.0.1 object-keys: 1.1.1 + dev: true - /defu@6.1.2: - resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} + /defu@6.1.3: + resolution: {integrity: sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ==} dev: false /del@7.1.0: @@ -10485,10 +9402,14 @@ packages: /detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} + requiresBuild: true dev: false - /deterministic-object-hash@1.3.1: - resolution: {integrity: sha512-kQDIieBUreEgY+akq0N7o4FzZCr27dPG1xr3wq267vPwDlSXQ3UMcBXHqTGUBaM/5WDS1jwTYjxRhUzHeuiAvw==} + /deterministic-object-hash@2.0.1: + resolution: {integrity: sha512-8HuU2kMCPzMwxa86oBoFQ5xwmwRrPAqWdyhS89RSYjsr2b6k7NIMlDwZRzRI/rHAm3Ip8KNy76cWWuprreJSyg==} + engines: {node: '>=18'} + dependencies: + base-64: 1.0.0 dev: false /devalue@4.3.2: @@ -10498,7 +9419,6 @@ packages: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} dependencies: dequal: 2.0.3 - dev: false /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -10521,12 +9441,14 @@ packages: /diff@5.1.0: resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} engines: {node: '>=0.3.1'} + dev: false /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} dependencies: path-type: 4.0.0 + dev: true /direction@2.0.1: resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} @@ -10578,8 +9500,8 @@ packages: engines: {node: '>=10'} dev: true - /dset@3.1.2: - resolution: {integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==} + /dset@3.1.3: + resolution: {integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==} engines: {node: '>=4'} dev: false @@ -10600,14 +9522,6 @@ packages: /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - /ejs@3.1.9: - resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - jake: 10.8.7 - dev: false - /electron-to-chromium@1.4.563: resolution: {integrity: sha512-dg5gj5qOgfZNkPNeyKBZQAQitIQ/xwfIDmEQJHCbXaD9ebTZxwJXUsDYcBlAvZGZLi+/354l35J1wkmP6CqYaw==} @@ -10714,9 +9628,10 @@ packages: typed-array-length: 1.0.4 unbox-primitive: 1.0.2 which-typed-array: 1.1.13 + dev: true - /es-module-lexer@1.3.1: - resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==} + /es-module-lexer@1.4.1: + resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} dev: false /es-set-tostringtag@2.0.2: @@ -10726,6 +9641,7 @@ packages: get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 hasown: 2.0.0 + dev: true /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} @@ -10740,15 +9656,16 @@ packages: is-callable: 1.2.7 is-date-object: 1.0.5 is-symbol: 1.0.4 + dev: true - /esbuild-plugin-copy@2.1.1(esbuild@0.19.5): + /esbuild-plugin-copy@2.1.1(esbuild@0.19.6): resolution: {integrity: sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw==} peerDependencies: esbuild: '>= 0.14.0' dependencies: chalk: 4.1.2 chokidar: 3.5.3 - esbuild: 0.19.5 + esbuild: 0.19.6 fs-extra: 10.1.0 globby: 11.1.0 dev: true @@ -10781,35 +9698,36 @@ packages: '@esbuild/win32-arm64': 0.18.20 '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 + dev: false - /esbuild@0.19.5: - resolution: {integrity: sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==} + /esbuild@0.19.6: + resolution: {integrity: sha512-Xl7dntjA2OEIvpr9j0DVxxnog2fyTGnyVoQXAMQI6eR3mf9zCQds7VIKUDCotDgE/p4ncTgeRqgX8t5d6oP4Gw==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.19.5 - '@esbuild/android-arm64': 0.19.5 - '@esbuild/android-x64': 0.19.5 - '@esbuild/darwin-arm64': 0.19.5 - '@esbuild/darwin-x64': 0.19.5 - '@esbuild/freebsd-arm64': 0.19.5 - '@esbuild/freebsd-x64': 0.19.5 - '@esbuild/linux-arm': 0.19.5 - '@esbuild/linux-arm64': 0.19.5 - '@esbuild/linux-ia32': 0.19.5 - '@esbuild/linux-loong64': 0.19.5 - '@esbuild/linux-mips64el': 0.19.5 - '@esbuild/linux-ppc64': 0.19.5 - '@esbuild/linux-riscv64': 0.19.5 - '@esbuild/linux-s390x': 0.19.5 - '@esbuild/linux-x64': 0.19.5 - '@esbuild/netbsd-x64': 0.19.5 - '@esbuild/openbsd-x64': 0.19.5 - '@esbuild/sunos-x64': 0.19.5 - '@esbuild/win32-arm64': 0.19.5 - '@esbuild/win32-ia32': 0.19.5 - '@esbuild/win32-x64': 0.19.5 + '@esbuild/android-arm': 0.19.6 + '@esbuild/android-arm64': 0.19.6 + '@esbuild/android-x64': 0.19.6 + '@esbuild/darwin-arm64': 0.19.6 + '@esbuild/darwin-x64': 0.19.6 + '@esbuild/freebsd-arm64': 0.19.6 + '@esbuild/freebsd-x64': 0.19.6 + '@esbuild/linux-arm': 0.19.6 + '@esbuild/linux-arm64': 0.19.6 + '@esbuild/linux-ia32': 0.19.6 + '@esbuild/linux-loong64': 0.19.6 + '@esbuild/linux-mips64el': 0.19.6 + '@esbuild/linux-ppc64': 0.19.6 + '@esbuild/linux-riscv64': 0.19.6 + '@esbuild/linux-s390x': 0.19.6 + '@esbuild/linux-x64': 0.19.6 + '@esbuild/netbsd-x64': 0.19.6 + '@esbuild/openbsd-x64': 0.19.6 + '@esbuild/sunos-x64': 0.19.6 + '@esbuild/win32-arm64': 0.19.6 + '@esbuild/win32-ia32': 0.19.6 + '@esbuild/win32-x64': 0.19.6 /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -10831,25 +9749,13 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} - /escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - dev: true - - /eslint-config-prettier@9.0.0(eslint@8.52.0): + /eslint-config-prettier@9.0.0(eslint@8.54.0): resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.54.0 dev: true /eslint-plugin-no-only-tests@3.1.0: @@ -10857,7 +9763,7 @@ packages: engines: {node: '>=5.0.0'} dev: true - /eslint-plugin-prettier@5.0.1(eslint-config-prettier@9.0.0)(eslint@8.52.0)(prettier@3.0.3): + /eslint-plugin-prettier@5.0.1(eslint-config-prettier@9.0.0)(eslint@8.54.0)(prettier@3.1.0): resolution: {integrity: sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -10871,9 +9777,9 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.52.0 - eslint-config-prettier: 9.0.0(eslint@8.52.0) - prettier: 3.0.3 + eslint: 8.54.0 + eslint-config-prettier: 9.0.0(eslint@8.54.0) + prettier: 3.1.0 prettier-linter-helpers: 1.0.0 synckit: 0.8.5 dev: true @@ -10891,15 +9797,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.52.0: - resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} + /eslint@8.54.0: + resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - '@eslint-community/regexpp': 4.9.1 - '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.52.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.3 + '@eslint/js': 8.54.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -10921,7 +9827,7 @@ packages: glob-parent: 6.0.2 globals: 13.23.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -10947,8 +9853,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) eslint-visitor-keys: 3.4.3 dev: true @@ -10976,41 +9882,38 @@ packages: engines: {node: '>=4.0'} dev: true - /estree-util-attach-comments@2.1.1: - resolution: {integrity: sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==} + /estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 dev: false - /estree-util-build-jsx@2.2.2: - resolution: {integrity: sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==} + /estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} dependencies: - '@types/estree-jsx': 1.0.2 - estree-util-is-identifier-name: 2.1.0 + '@types/estree-jsx': 1.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 estree-walker: 3.0.3 dev: false - /estree-util-is-identifier-name@2.1.0: - resolution: {integrity: sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==} + /estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} dev: false - /estree-util-to-js@1.2.0: - resolution: {integrity: sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==} + /estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} dependencies: - '@types/estree-jsx': 1.0.2 + '@types/estree-jsx': 1.0.3 astring: 1.8.6 source-map: 0.7.4 dev: false - /estree-util-visit@1.2.1: - resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==} + /estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} dependencies: - '@types/estree-jsx': 1.0.2 - '@types/unist': 2.0.9 - dev: false - - /estree-walker@1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + '@types/estree-jsx': 1.0.3 + '@types/unist': 3.0.2 dev: false /estree-walker@2.0.2: @@ -11019,11 +9922,12 @@ packages: /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + dev: true /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} @@ -11148,6 +10052,7 @@ packages: /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true /fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} @@ -11159,8 +10064,8 @@ packages: dev: false optional: true - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -11171,6 +10076,7 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -11205,19 +10111,13 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 3.1.1 + flat-cache: 3.2.0 dev: true /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} dev: false - /filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - dependencies: - minimatch: 5.1.6 - dev: false - /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -11259,9 +10159,9 @@ packages: micromatch: 4.0.5 pkg-dir: 4.2.0 - /flat-cache@3.1.1: - resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==} - engines: {node: '>=12.0.0'} + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} dependencies: flatted: 3.2.9 keyv: 4.5.4 @@ -11277,10 +10177,16 @@ packages: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true + /flattie@1.1.0: + resolution: {integrity: sha512-xU99gDEnciIwJdGcBmNHnzTJ/w5AT+VFJOu6sTB6WM8diOYNA3Sa+K1DiEBQ7XH4QikQq3iFW1U+jRVcotQnBw==} + engines: {node: '>=8'} + dev: false + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: is-callable: 1.2.7 + dev: true /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} @@ -11342,16 +10248,6 @@ packages: universalify: 0.1.2 dev: true - /fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: false - /fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -11388,9 +10284,11 @@ packages: define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 + dev: true /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true /gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} @@ -11417,6 +10315,11 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: false + /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -11427,10 +10330,7 @@ packages: has-proto: 1.0.1 has-symbols: 1.0.3 hasown: 2.0.0 - - /get-own-enumerable-property-symbols@3.0.2: - resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} - dev: false + dev: true /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} @@ -11447,16 +10347,17 @@ packages: dependencies: call-bind: 1.0.5 get-intrinsic: 1.2.2 + dev: true - /giget@1.1.2: - resolution: {integrity: sha512-HsLoS07HiQ5oqvObOI+Qb2tyZH4Gj5nYGfF9qQcZNrPw+uEFhdXtgJr01aO2pWadGHucajYDLxxbtQkm97ON2A==} + /giget@1.1.3: + resolution: {integrity: sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q==} hasBin: true dependencies: colorette: 2.0.20 - defu: 6.1.2 - https-proxy-agent: 5.0.1 + defu: 6.1.3 + https-proxy-agent: 7.0.2 mri: 1.2.0 - node-fetch-native: 1.4.0 + node-fetch-native: 1.4.1 pathe: 1.1.1 tar: 6.2.0 transitivePeerDependencies: @@ -11532,6 +10433,7 @@ packages: engines: {node: '>= 0.4'} dependencies: define-properties: 1.2.1 + dev: true /globalyzer@0.1.0: resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} @@ -11543,8 +10445,8 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.0 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -11554,10 +10456,23 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.0 merge2: 1.4.1 slash: 4.0.0 + dev: true + + /globby@14.0.0: + resolution: {integrity: sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==} + engines: {node: '>=18'} + dependencies: + '@sindresorhus/merge-streams': 1.0.0 + fast-glob: 3.3.2 + ignore: 5.3.0 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 + dev: false /globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} @@ -11567,6 +10482,7 @@ packages: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.2 + dev: true /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -11600,6 +10516,7 @@ packages: /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} @@ -11613,20 +10530,24 @@ packages: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: get-intrinsic: 1.2.2 + dev: true /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} + dev: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} + dev: true /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 + dev: true /has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} @@ -11647,90 +10568,82 @@ packages: dependencies: function-bind: 1.1.2 - /hast-util-from-dom@4.2.0: - resolution: {integrity: sha512-t1RJW/OpJbCAJQeKi3Qrj1cAOLA0+av/iPFori112+0X7R3wng+jxLA+kXec8K4szqPRGI8vPxbbpEYvvpwaeQ==} + /hast-util-from-dom@5.0.0: + resolution: {integrity: sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==} dependencies: - hastscript: 7.2.0 + '@types/hast': 3.0.3 + hastscript: 8.0.0 web-namespaces: 2.0.1 dev: true + /hast-util-from-html@2.0.1: + resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==} + dependencies: + '@types/hast': 3.0.3 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.1 + parse5: 7.1.2 + vfile: 6.0.1 + vfile-message: 4.0.2 + dev: false + /hast-util-from-parse5@7.1.2: resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} dependencies: - '@types/hast': 2.3.7 - '@types/unist': 2.0.9 + '@types/hast': 2.3.8 + '@types/unist': 2.0.10 hastscript: 7.2.0 - property-information: 6.3.0 + property-information: 6.4.0 vfile: 5.3.7 vfile-location: 4.1.0 web-namespaces: 2.0.1 - dev: false + dev: true /hast-util-from-parse5@8.0.1: resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} dependencies: - '@types/hast': 3.0.2 - '@types/unist': 3.0.1 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 devlop: 1.1.0 hastscript: 8.0.0 - property-information: 6.3.0 + property-information: 6.4.0 vfile: 6.0.1 vfile-location: 5.0.2 web-namespaces: 2.0.1 dev: false - /hast-util-has-property@2.0.1: - resolution: {integrity: sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==} - /hast-util-has-property@3.0.0: resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} dependencies: - '@types/hast': 3.0.2 + '@types/hast': 3.0.3 dev: false - /hast-util-heading-rank@2.1.1: - resolution: {integrity: sha512-iAuRp+ESgJoRFJbSyaqsfvJDY6zzmFoEnL1gtz1+U8gKtGGj1p0CVlysuUAUjq95qlZESHINLThwJzNGmgGZxA==} + /hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 3.0.3 - /hast-util-is-element@2.1.3: - resolution: {integrity: sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==} + /hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} dependencies: - '@types/hast': 2.3.7 - '@types/unist': 2.0.9 + '@types/hast': 3.0.3 /hast-util-parse-selector@3.1.1: resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 2.3.8 + dev: true /hast-util-parse-selector@4.0.0: resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} dependencies: - '@types/hast': 3.0.2 - dev: false - - /hast-util-raw@7.2.3: - resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==} - dependencies: - '@types/hast': 2.3.7 - '@types/parse5': 6.0.3 - hast-util-from-parse5: 7.1.2 - hast-util-to-parse5: 7.1.0 - html-void-elements: 2.0.1 - parse5: 6.0.1 - unist-util-position: 4.0.4 - unist-util-visit: 4.1.2 - vfile: 5.3.7 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - dev: false + '@types/hast': 3.0.3 /hast-util-raw@9.0.1: resolution: {integrity: sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==} dependencies: - '@types/hast': 3.0.2 - '@types/unist': 3.0.1 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 '@ungap/structured-clone': 1.2.0 hast-util-from-parse5: 8.0.1 hast-util-to-parse5: 8.0.0 @@ -11744,34 +10657,14 @@ packages: zwitch: 2.0.4 dev: false - /hast-util-select@5.0.5: - resolution: {integrity: sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==} - dependencies: - '@types/hast': 2.3.7 - '@types/unist': 2.0.9 - bcp-47-match: 2.0.3 - comma-separated-tokens: 2.0.3 - css-selector-parser: 1.4.1 - direction: 2.0.1 - hast-util-has-property: 2.0.1 - hast-util-to-string: 2.0.0 - hast-util-whitespace: 2.0.1 - not: 0.1.0 - nth-check: 2.1.1 - property-information: 6.3.0 - space-separated-tokens: 2.0.2 - unist-util-visit: 4.1.2 - zwitch: 2.0.4 - dev: false - - /hast-util-select@6.0.1: - resolution: {integrity: sha512-KPNOtLqeJCcFRyxQm9BakO3bdIQfremXraw4mh9jxsJ+L593v/VdP3G9Dfjahacl/bw8PPvIFseaXzElKOYRpA==} + /hast-util-select@6.0.2: + resolution: {integrity: sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==} dependencies: - '@types/hast': 3.0.2 - '@types/unist': 3.0.1 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 bcp-47-match: 2.0.3 comma-separated-tokens: 2.0.3 - css-selector-parser: 2.3.2 + css-selector-parser: 3.0.0 devlop: 1.1.0 direction: 2.0.1 hast-util-has-property: 3.0.0 @@ -11779,85 +10672,73 @@ packages: hast-util-whitespace: 3.0.0 not: 0.1.0 nth-check: 2.1.1 - property-information: 6.3.0 + property-information: 6.4.0 space-separated-tokens: 2.0.2 unist-util-visit: 5.0.0 zwitch: 2.0.4 dev: false - /hast-util-to-estree@2.3.3: - resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==} + /hast-util-to-estree@3.1.0: + resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} dependencies: - '@types/estree': 1.0.3 - '@types/estree-jsx': 1.0.2 - '@types/hast': 2.3.7 - '@types/unist': 2.0.9 + '@types/estree': 1.0.5 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 comma-separated-tokens: 2.0.3 - estree-util-attach-comments: 2.1.1 - estree-util-is-identifier-name: 2.1.0 - hast-util-whitespace: 2.0.1 - mdast-util-mdx-expression: 1.3.2 - mdast-util-mdxjs-esm: 1.3.1 - property-information: 6.3.0 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.4.0 space-separated-tokens: 2.0.2 style-to-object: 0.4.4 - unist-util-position: 4.0.4 + unist-util-position: 5.0.0 zwitch: 2.0.4 transitivePeerDependencies: - supports-color dev: false - /hast-util-to-html@8.0.4: - resolution: {integrity: sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==} - dependencies: - '@types/hast': 2.3.7 - '@types/unist': 2.0.9 - ccount: 2.0.1 - comma-separated-tokens: 2.0.3 - hast-util-raw: 7.2.3 - hast-util-whitespace: 2.0.1 - html-void-elements: 2.0.1 - property-information: 6.3.0 - space-separated-tokens: 2.0.2 - stringify-entities: 4.0.3 - zwitch: 2.0.4 - dev: false - /hast-util-to-html@9.0.0: resolution: {integrity: sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==} dependencies: - '@types/hast': 3.0.2 - '@types/unist': 3.0.1 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 ccount: 2.0.1 comma-separated-tokens: 2.0.3 hast-util-raw: 9.0.1 hast-util-whitespace: 3.0.0 html-void-elements: 3.0.0 mdast-util-to-hast: 13.0.2 - property-information: 6.3.0 + property-information: 6.4.0 space-separated-tokens: 2.0.2 stringify-entities: 4.0.3 zwitch: 2.0.4 dev: false - /hast-util-to-parse5@7.1.0: - resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==} + /hast-util-to-jsx-runtime@2.2.0: + resolution: {integrity: sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 comma-separated-tokens: 2.0.3 - property-information: 6.3.0 + hast-util-whitespace: 3.0.0 + property-information: 6.4.0 space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 + style-to-object: 0.4.4 + unist-util-position: 5.0.0 + vfile-message: 4.0.2 dev: false /hast-util-to-parse5@8.0.0: resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} dependencies: - '@types/hast': 3.0.2 + '@types/hast': 3.0.3 comma-separated-tokens: 2.0.3 devlop: 1.1.0 - property-information: 6.3.0 + property-information: 6.4.0 space-separated-tokens: 2.0.2 web-namespaces: 2.0.1 zwitch: 2.0.4 @@ -11866,51 +10747,47 @@ packages: /hast-util-to-string@2.0.0: resolution: {integrity: sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 2.3.8 + dev: true /hast-util-to-string@3.0.0: resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==} dependencies: - '@types/hast': 3.0.2 - dev: false + '@types/hast': 3.0.3 - /hast-util-to-text@3.1.2: - resolution: {integrity: sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==} + /hast-util-to-text@4.0.0: + resolution: {integrity: sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==} dependencies: - '@types/hast': 2.3.7 - '@types/unist': 2.0.9 - hast-util-is-element: 2.1.3 - unist-util-find-after: 4.0.1 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 dev: true - /hast-util-whitespace@2.0.1: - resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} - dev: false - /hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} dependencies: - '@types/hast': 3.0.2 + '@types/hast': 3.0.3 dev: false /hastscript@7.2.0: resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 2.3.8 comma-separated-tokens: 2.0.3 hast-util-parse-selector: 3.1.1 - property-information: 6.3.0 + property-information: 6.4.0 space-separated-tokens: 2.0.2 + dev: true /hastscript@8.0.0: resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} dependencies: - '@types/hast': 3.0.2 + '@types/hast': 3.0.3 comma-separated-tokens: 2.0.3 hast-util-parse-selector: 4.0.0 - property-information: 6.3.0 + property-information: 6.4.0 space-separated-tokens: 2.0.2 - dev: false /hdr-histogram-js@3.0.0: resolution: {integrity: sha512-/EpvQI2/Z98mNFYEnlqJ8Ogful8OpArLG/6Tf2bPnkutBVLIeMVNHjk1ZDfshF2BUweipzbk+dB1hgSB7SIakw==} @@ -11966,10 +10843,6 @@ packages: engines: {node: '>=8'} dev: false - /html-void-elements@2.0.1: - resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} - dev: false - /html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} dev: false @@ -11990,7 +10863,6 @@ packages: domhandler: 5.0.3 domutils: 3.1.0 entities: 4.5.0 - dev: false /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} @@ -12030,6 +10902,16 @@ packages: transitivePeerDependencies: - supports-color + /https-proxy-agent@7.0.2: + resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: false + /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true @@ -12073,16 +10955,12 @@ packages: safer-buffer: 2.1.2 dev: true - /idb@7.1.1: - resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} - dev: false - /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} /immutable@4.3.4: @@ -12096,8 +10974,8 @@ packages: resolve-from: 4.0.0 dev: true - /import-meta-resolve@3.0.0: - resolution: {integrity: sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==} + /import-meta-resolve@4.0.0: + resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} dev: false /imurmurhash@0.1.4: @@ -12141,6 +11019,7 @@ packages: get-intrinsic: 1.2.2 hasown: 2.0.0 side-channel: 1.0.4 + dev: true /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} @@ -12162,6 +11041,7 @@ packages: call-bind: 1.0.5 get-intrinsic: 1.2.2 is-typed-array: 1.1.12 + dev: true /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -12177,6 +11057,7 @@ packages: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: has-bigints: 1.0.2 + dev: true /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} @@ -12190,6 +11071,7 @@ packages: dependencies: call-bind: 1.0.5 has-tostringtag: 1.0.0 + dev: true /is-buffer@2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} @@ -12198,6 +11080,7 @@ packages: /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + dev: true /is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} @@ -12216,6 +11099,7 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -12270,29 +11154,22 @@ packages: engines: {node: '>=12'} dev: false - /is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - dev: false - /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} + dev: true /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - /is-obj@1.0.1: - resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} - engines: {node: '>=0.10.0'} - dev: false - /is-obj@3.0.0: resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} engines: {node: '>=12'} @@ -12339,7 +11216,7 @@ packages: /is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} @@ -12347,20 +11224,18 @@ packages: dependencies: call-bind: 1.0.5 has-tostringtag: 1.0.0 - - /is-regexp@1.0.0: - resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} - engines: {node: '>=0.10.0'} - dev: false + dev: true /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: call-bind: 1.0.5 + dev: true /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + dev: true /is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} @@ -12371,6 +11246,7 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} @@ -12384,12 +11260,14 @@ packages: engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 + dev: true /is-typed-array@1.1.12: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: which-typed-array: 1.1.13 + dev: true /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} @@ -12405,6 +11283,7 @@ packages: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.5 + dev: true /is-what@4.1.15: resolution: {integrity: sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA==} @@ -12432,21 +11311,11 @@ packages: /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - /jake@10.8.7: - resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} - engines: {node: '>=10'} - hasBin: true - dependencies: - async: 3.2.4 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - dev: false - /jest-diff@21.2.1: resolution: {integrity: sha512-E5fu6r7PvvPr5qAWE1RaUwIh/k6Zx/3OOkZ4rk5dBJkEWRrUuSgbMt2EO8IUTPTd6DOqU3LW6uTIwX5FRvXoFA==} dependencies: @@ -12479,17 +11348,8 @@ packages: pretty-format: 21.2.1 dev: true - /jest-worker@26.6.2: - resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} - engines: {node: '>= 10.13.0'} - dependencies: - '@types/node': 18.18.6 - merge-stream: 2.0.0 - supports-color: 7.2.0 - dev: false - - /jiti@1.20.0: - resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==} + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true /js-tokens@4.0.0: @@ -12508,9 +11368,9 @@ packages: dependencies: argparse: 2.0.1 - /jsdom@20.0.3: - resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} - engines: {node: '>=14'} + /jsdom@22.1.0: + resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==} + engines: {node: '>=16'} peerDependencies: canvas: ^2.5.0 peerDependenciesMeta: @@ -12518,14 +11378,10 @@ packages: optional: true dependencies: abab: 2.0.6 - acorn: 8.10.0 - acorn-globals: 7.0.1 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 + cssstyle: 3.0.0 + data-urls: 4.0.0 decimal.js: 10.4.3 domexception: 4.0.0 - escodegen: 2.1.0 form-data: 4.0.0 html-encoding-sniffer: 3.0.0 http-proxy-agent: 5.0.0 @@ -12533,6 +11389,7 @@ packages: is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.7 parse5: 7.1.2 + rrweb-cssom: 0.6.0 saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 4.1.3 @@ -12540,7 +11397,7 @@ packages: webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 + whatwg-url: 12.0.1 ws: 8.14.2 xml-name-validator: 4.0.0 transitivePeerDependencies: @@ -12549,11 +11406,6 @@ packages: - utf-8-validate dev: true - /jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - dev: false - /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -12572,6 +11424,13 @@ packages: quill-delta: ^5 rxjs: '7' tslib: '2' + peerDependenciesMeta: + quill-delta: + optional: true + rxjs: + optional: true + tslib: + optional: true dependencies: arg: 5.0.2 hyperdyperid: 1.2.0 @@ -12589,14 +11448,6 @@ packages: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: false - - /json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: false - /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true @@ -12625,11 +11476,7 @@ packages: universalify: 2.0.0 optionalDependencies: graceful-fs: 4.2.11 - - /jsonpointer@5.0.1: - resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} - engines: {node: '>=0.10.0'} - dev: false + dev: true /katex@0.16.9: resolution: {integrity: sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==} @@ -12660,11 +11507,6 @@ packages: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} dev: false - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: false - /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -12677,16 +11519,20 @@ packages: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - /linkedom@0.15.6: - resolution: {integrity: sha512-2Vt8fdP5BNWeIiV8B3ZxfY2Z8zB0u2nVP4JPS+cgeqUlNbY26IFdDot4FYM+pZ6dA2fTVrP6bi8Z4VNTlyurvA==} + /linkedom@0.16.4: + resolution: {integrity: sha512-SykvDVh/jAnaO+WiPqH5vX3QpZrIRImuppzYhIHons3RXPhDwqN2dOyfopOVaHleqWtoS+3vWCqen+m8M3HToQ==} dependencies: css-select: 5.1.0 cssom: 0.5.0 html-escaper: 3.0.3 - htmlparser2: 8.0.2 + htmlparser2: 9.0.0 uhyphen: 0.2.0 dev: true @@ -12696,11 +11542,25 @@ packages: '@lit-labs/ssr-dom-shim': 1.1.2 '@lit/reactive-element': 1.6.3 lit-html: 2.8.0 + dev: false + + /lit-element@4.0.2: + resolution: {integrity: sha512-/W6WQZUa5VEXwC7H9tbtDMdSs9aWil3Ou8hU6z2cOKWbsm/tXPAcsoaHVEtrDo0zcOIE5GF6QgU55tlGL2Nihg==} + dependencies: + '@lit-labs/ssr-dom-shim': 1.1.2 + '@lit/reactive-element': 2.0.2 + lit-html: 3.1.0 /lit-html@2.8.0: resolution: {integrity: sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==} dependencies: '@types/trusted-types': 2.0.5 + dev: false + + /lit-html@3.1.0: + resolution: {integrity: sha512-FwAjq3iNsaO6SOZXEIpeROlJLUlrbyMkn4iuv4f4u1H40Jw8wkeR/OUXZUHUoiYabGk8Y4Y0F/rgq+R4MrOLmA==} + dependencies: + '@types/trusted-types': 2.0.5 /lit@2.8.0: resolution: {integrity: sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==} @@ -12708,6 +11568,14 @@ packages: '@lit/reactive-element': 1.6.3 lit-element: 3.3.3 lit-html: 2.8.0 + dev: false + + /lit@3.1.0: + resolution: {integrity: sha512-rzo/hmUqX8zmOdamDAeydfjsGXbbdtAFqMhmocnh2j9aDYqbu0fjXygjCa0T99Od9VQ/2itwaGrjZz/ZELVl7w==} + dependencies: + '@lit/reactive-element': 2.0.2 + lit-element: 4.0.2 + lit-html: 3.1.0 /lite-youtube-embed@0.2.0: resolution: {integrity: sha512-XXXAk5sbvtjjwbie3XG+6HppgTm1HTGL/Uk9z9NkJH53o7puZLur434heHzAjkS60hZB3vT4ls25zl5rMiX4EA==} @@ -12760,10 +11628,6 @@ packages: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} dev: false - /lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: false - /lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: false @@ -12771,10 +11635,6 @@ packages: /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - /lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - dev: false - /lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: true @@ -12783,10 +11643,6 @@ packages: resolution: {integrity: sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==} dev: true - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -12862,12 +11718,6 @@ packages: hasBin: true dev: true - /magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - dependencies: - sourcemap-codec: 1.4.8 - dev: false - /magic-string@0.30.5: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} @@ -12895,9 +11745,9 @@ packages: engines: {node: '>=8'} dev: true - /markdown-extensions@1.1.1: - resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} - engines: {node: '>=0.10.0'} + /markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} dev: false /markdown-table@3.0.3: @@ -12919,227 +11769,223 @@ packages: speech-rule-engine: 4.0.7 dev: true - /mdast-util-definitions@5.1.2: - resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} - dependencies: - '@types/mdast': 3.0.14 - '@types/unist': 2.0.9 - unist-util-visit: 4.1.2 - /mdast-util-definitions@6.0.0: resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} dependencies: - '@types/mdast': 4.0.2 - '@types/unist': 3.0.1 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 unist-util-visit: 5.0.0 dev: false - /mdast-util-find-and-replace@2.2.2: - resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} + /mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} dependencies: - '@types/mdast': 3.0.14 + '@types/mdast': 4.0.3 escape-string-regexp: 5.0.0 - unist-util-is: 5.2.1 - unist-util-visit-parents: 5.1.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 dev: false - /mdast-util-from-markdown@1.3.1: - resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + /mdast-util-from-markdown@2.0.0: + resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} dependencies: - '@types/mdast': 3.0.14 - '@types/unist': 2.0.9 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 decode-named-character-reference: 1.0.2 - mdast-util-to-string: 3.2.0 - micromark: 3.2.0 - micromark-util-decode-numeric-character-reference: 1.1.0 - micromark-util-decode-string: 1.1.0 - micromark-util-normalize-identifier: 1.1.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - unist-util-stringify-position: 3.0.3 - uvu: 0.5.6 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 transitivePeerDependencies: - supports-color - /mdast-util-gfm-autolink-literal@1.0.3: - resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==} + /mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} dependencies: - '@types/mdast': 3.0.14 + '@types/mdast': 4.0.3 ccount: 2.0.1 - mdast-util-find-and-replace: 2.2.2 - micromark-util-character: 1.2.0 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.0.1 dev: false - /mdast-util-gfm-footnote@1.0.2: - resolution: {integrity: sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==} + /mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-to-markdown: 1.5.0 - micromark-util-normalize-identifier: 1.1.0 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + transitivePeerDependencies: + - supports-color dev: false - /mdast-util-gfm-strikethrough@1.0.3: - resolution: {integrity: sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==} + /mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-to-markdown: 1.5.0 + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color dev: false - /mdast-util-gfm-table@1.0.7: - resolution: {integrity: sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==} + /mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} dependencies: - '@types/mdast': 3.0.14 + '@types/mdast': 4.0.3 + devlop: 1.1.0 markdown-table: 3.0.3 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.5.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color dev: false - /mdast-util-gfm-task-list-item@1.0.2: - resolution: {integrity: sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==} + /mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-to-markdown: 1.5.0 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color dev: false - /mdast-util-gfm@2.0.2: - resolution: {integrity: sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==} + /mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} dependencies: - mdast-util-from-markdown: 1.3.1 - mdast-util-gfm-autolink-literal: 1.0.3 - mdast-util-gfm-footnote: 1.0.2 - mdast-util-gfm-strikethrough: 1.0.3 - mdast-util-gfm-table: 1.0.7 - mdast-util-gfm-task-list-item: 1.0.2 - mdast-util-to-markdown: 1.5.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color dev: false - /mdast-util-math@2.0.2: - resolution: {integrity: sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ==} + /mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} dependencies: - '@types/mdast': 3.0.14 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 longest-streak: 3.1.0 - mdast-util-to-markdown: 1.5.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color dev: true - /mdast-util-mdx-expression@1.3.2: - resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==} + /mdast-util-mdx-expression@2.0.0: + resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} dependencies: - '@types/estree-jsx': 1.0.2 - '@types/hast': 2.3.7 - '@types/mdast': 3.0.14 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.5.0 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - /mdast-util-mdx-jsx@2.1.4: - resolution: {integrity: sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==} + /mdast-util-mdx-jsx@3.0.0: + resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==} dependencies: - '@types/estree-jsx': 1.0.2 - '@types/hast': 2.3.7 - '@types/mdast': 3.0.14 - '@types/unist': 2.0.9 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 ccount: 2.0.1 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.5.0 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 parse-entities: 4.0.1 stringify-entities: 4.0.3 - unist-util-remove-position: 4.0.2 - unist-util-stringify-position: 3.0.3 - vfile-message: 3.1.4 + unist-util-remove-position: 5.0.0 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 transitivePeerDependencies: - supports-color - /mdast-util-mdx@2.0.1: - resolution: {integrity: sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==} + /mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} dependencies: - mdast-util-from-markdown: 1.3.1 - mdast-util-mdx-expression: 1.3.2 - mdast-util-mdx-jsx: 2.1.4 - mdast-util-mdxjs-esm: 1.3.1 - mdast-util-to-markdown: 1.5.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - /mdast-util-mdxjs-esm@1.3.1: - resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==} + /mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} dependencies: - '@types/estree-jsx': 1.0.2 - '@types/hast': 2.3.7 - '@types/mdast': 3.0.14 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.5.0 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - /mdast-util-phrasing@3.0.1: - resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} - dependencies: - '@types/mdast': 3.0.14 - unist-util-is: 5.2.1 - - /mdast-util-to-hast@12.3.0: - resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} + /mdast-util-phrasing@4.0.0: + resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} dependencies: - '@types/hast': 2.3.7 - '@types/mdast': 3.0.14 - mdast-util-definitions: 5.1.2 - micromark-util-sanitize-uri: 1.2.0 - trim-lines: 3.0.1 - unist-util-generated: 2.0.1 - unist-util-position: 4.0.4 - unist-util-visit: 4.1.2 + '@types/mdast': 4.0.3 + unist-util-is: 6.0.0 /mdast-util-to-hast@13.0.2: resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} dependencies: - '@types/hast': 3.0.2 - '@types/mdast': 4.0.2 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 '@ungap/structured-clone': 1.2.0 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.0 trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - dev: false - /mdast-util-to-markdown@1.5.0: - resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} + /mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} dependencies: - '@types/mdast': 3.0.14 - '@types/unist': 2.0.9 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 longest-streak: 3.1.0 - mdast-util-phrasing: 3.0.1 - mdast-util-to-string: 3.2.0 - micromark-util-decode-string: 1.1.0 - unist-util-visit: 4.1.2 + mdast-util-phrasing: 4.0.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 zwitch: 2.0.4 - /mdast-util-to-string@3.2.0: - resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} - dependencies: - '@types/mdast': 3.0.14 - /mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} dependencies: - '@types/mdast': 4.0.2 - dev: false + '@types/mdast': 4.0.3 - /mdast-util-toc@6.1.1: - resolution: {integrity: sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==} + /mdast-util-toc@7.0.0: + resolution: {integrity: sha512-C28UcSqjmnWuvgT8d97qpaItHKvySqVPAECUzqQ51xuMyNFFJwcFoKW77KoMjtXrclTidLQFDzLUmTmrshRweA==} dependencies: - '@types/extend': 3.0.3 - '@types/mdast': 3.0.14 - extend: 3.0.2 + '@types/mdast': 4.0.3 + '@types/ungap__structured-clone': 0.3.2 + '@ungap/structured-clone': 1.2.0 github-slugger: 2.0.0 - mdast-util-to-string: 3.2.0 - unist-util-is: 5.2.1 - unist-util-visit: 4.1.2 + mdast-util-to-string: 4.0.0 + unist-util-is: 6.0.0 + unist-util-visit: 5.0.0 dev: true /mdn-data@2.0.28: @@ -13159,6 +12005,9 @@ packages: engines: {node: '>= 4.0.0'} peerDependencies: tslib: '2' + peerDependenciesMeta: + tslib: + optional: true dependencies: json-joy: 9.9.1 thingies: 1.12.0 @@ -13216,304 +12065,286 @@ packages: resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==} dev: true - /micromark-core-commonmark@1.1.0: - resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + /micromark-core-commonmark@2.0.0: + resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} dependencies: decode-named-character-reference: 1.0.2 - micromark-factory-destination: 1.1.0 - micromark-factory-label: 1.1.0 - micromark-factory-space: 1.1.0 - micromark-factory-title: 1.1.0 - micromark-factory-whitespace: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-chunked: 1.1.0 - micromark-util-classify-character: 1.1.0 - micromark-util-html-tag-name: 1.2.0 - micromark-util-normalize-identifier: 1.1.0 - micromark-util-resolve-all: 1.1.0 - micromark-util-subtokenize: 1.1.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - /micromark-extension-gfm-autolink-literal@1.0.5: - resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==} + /micromark-extension-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} dependencies: - micromark-util-character: 1.2.0 - micromark-util-sanitize-uri: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-gfm-footnote@1.1.2: - resolution: {integrity: sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==} + /micromark-extension-gfm-footnote@2.0.0: + resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} dependencies: - micromark-core-commonmark: 1.1.0 - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-normalize-identifier: 1.1.0 - micromark-util-sanitize-uri: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-gfm-strikethrough@1.0.7: - resolution: {integrity: sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==} + /micromark-extension-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} dependencies: - micromark-util-chunked: 1.1.0 - micromark-util-classify-character: 1.1.0 - micromark-util-resolve-all: 1.1.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-gfm-table@1.0.7: - resolution: {integrity: sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==} + /micromark-extension-gfm-table@2.0.0: + resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} dependencies: - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-gfm-tagfilter@1.0.2: - resolution: {integrity: sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==} + /micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} dependencies: - micromark-util-types: 1.1.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-gfm-task-list-item@1.0.5: - resolution: {integrity: sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==} + /micromark-extension-gfm-task-list-item@2.0.1: + resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} dependencies: - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-gfm@2.0.3: - resolution: {integrity: sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==} + /micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} dependencies: - micromark-extension-gfm-autolink-literal: 1.0.5 - micromark-extension-gfm-footnote: 1.1.2 - micromark-extension-gfm-strikethrough: 1.0.7 - micromark-extension-gfm-table: 1.0.7 - micromark-extension-gfm-tagfilter: 1.0.2 - micromark-extension-gfm-task-list-item: 1.0.5 - micromark-util-combine-extensions: 1.1.0 - micromark-util-types: 1.1.0 + micromark-extension-gfm-autolink-literal: 2.0.0 + micromark-extension-gfm-footnote: 2.0.0 + micromark-extension-gfm-strikethrough: 2.0.0 + micromark-extension-gfm-table: 2.0.0 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.0.1 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-math@2.1.2: - resolution: {integrity: sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg==} + /micromark-extension-math@3.0.0: + resolution: {integrity: sha512-iJ2Q28vBoEovLN5o3GO12CpqorQRYDPT+p4zW50tGwTfJB+iv/VnB6Ini+gqa24K97DwptMBBIvVX6Bjk49oyQ==} dependencies: - '@types/katex': 0.16.5 + '@types/katex': 0.16.6 + devlop: 1.1.0 katex: 0.16.9 - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: true - /micromark-extension-mdx-expression@1.0.8: - resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==} + /micromark-extension-mdx-expression@3.0.0: + resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} dependencies: - '@types/estree': 1.0.3 - micromark-factory-mdx-expression: 1.0.9 - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-events-to-acorn: 1.2.3 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + '@types/estree': 1.0.5 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-mdx-jsx@1.0.5: - resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==} + /micromark-extension-mdx-jsx@3.0.0: + resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} dependencies: '@types/acorn': 4.0.6 - '@types/estree': 1.0.3 - estree-util-is-identifier-name: 2.1.0 - micromark-factory-mdx-expression: 1.0.9 - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 - vfile-message: 3.1.4 + '@types/estree': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + vfile-message: 4.0.2 dev: false - /micromark-extension-mdx-md@1.0.1: - resolution: {integrity: sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==} + /micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} dependencies: - micromark-util-types: 1.1.0 + micromark-util-types: 2.0.0 dev: false - /micromark-extension-mdxjs-esm@1.0.5: - resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==} + /micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} dependencies: - '@types/estree': 1.0.3 - micromark-core-commonmark: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-events-to-acorn: 1.2.3 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - unist-util-position-from-estree: 1.1.2 - uvu: 0.5.6 - vfile-message: 3.1.4 + '@types/estree': 1.0.5 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 dev: false - /micromark-extension-mdxjs@1.0.1: - resolution: {integrity: sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==} + /micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) - micromark-extension-mdx-expression: 1.0.8 - micromark-extension-mdx-jsx: 1.0.5 - micromark-extension-mdx-md: 1.0.1 - micromark-extension-mdxjs-esm: 1.0.5 - micromark-util-combine-extensions: 1.1.0 - micromark-util-types: 1.1.0 - dev: false - - /micromark-factory-destination@1.1.0: - resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} - dependencies: - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - - /micromark-factory-label@1.1.0: - resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} - dependencies: - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 - - /micromark-factory-mdx-expression@1.0.9: - resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==} - dependencies: - '@types/estree': 1.0.3 - micromark-util-character: 1.2.0 - micromark-util-events-to-acorn: 1.2.3 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - unist-util-position-from-estree: 1.1.2 - uvu: 0.5.6 - vfile-message: 3.1.4 + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) + micromark-extension-mdx-expression: 3.0.0 + micromark-extension-mdx-jsx: 3.0.0 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 dev: false - /micromark-factory-space@1.1.0: - resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + /micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + /micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} dependencies: - micromark-util-character: 1.2.0 - micromark-util-types: 1.1.0 + devlop: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + /micromark-factory-mdx-expression@2.0.1: + resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} + dependencies: + '@types/estree': 1.0.5 + devlop: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + dev: false - /micromark-factory-title@1.1.0: - resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + /micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} dependencies: - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-types: 2.0.0 - /micromark-factory-whitespace@1.1.0: - resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + /micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} dependencies: - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - /micromark-util-character@1.2.0: - resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + /micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} dependencies: - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 /micromark-util-character@2.0.1: resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} dependencies: micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: false - /micromark-util-chunked@1.1.0: - resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + /micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} dependencies: - micromark-util-symbol: 1.1.0 + micromark-util-symbol: 2.0.0 - /micromark-util-classify-character@1.1.0: - resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + /micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} dependencies: - micromark-util-character: 1.2.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - /micromark-util-combine-extensions@1.1.0: - resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + /micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} dependencies: - micromark-util-chunked: 1.1.0 - micromark-util-types: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 - /micromark-util-decode-numeric-character-reference@1.1.0: - resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + /micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} dependencies: - micromark-util-symbol: 1.1.0 + micromark-util-symbol: 2.0.0 - /micromark-util-decode-string@1.1.0: - resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + /micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} dependencies: decode-named-character-reference: 1.0.2 - micromark-util-character: 1.2.0 - micromark-util-decode-numeric-character-reference: 1.1.0 - micromark-util-symbol: 1.1.0 - - /micromark-util-encode@1.1.0: - resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + micromark-util-character: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 /micromark-util-encode@2.0.0: resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - dev: false - /micromark-util-events-to-acorn@1.2.3: - resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==} + /micromark-util-events-to-acorn@2.0.2: + resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} dependencies: '@types/acorn': 4.0.6 - '@types/estree': 1.0.3 - '@types/unist': 2.0.9 - estree-util-visit: 1.2.1 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 - vfile-message: 3.1.4 + '@types/estree': 1.0.5 + '@types/unist': 3.0.2 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + vfile-message: 4.0.2 dev: false - /micromark-util-html-tag-name@1.2.0: - resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + /micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} - /micromark-util-normalize-identifier@1.1.0: - resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + /micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} dependencies: - micromark-util-symbol: 1.1.0 - - /micromark-util-resolve-all@1.1.0: - resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} - dependencies: - micromark-util-types: 1.1.0 + micromark-util-symbol: 2.0.0 - /micromark-util-sanitize-uri@1.2.0: - resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + /micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} dependencies: - micromark-util-character: 1.2.0 - micromark-util-encode: 1.1.0 - micromark-util-symbol: 1.1.0 + micromark-util-types: 2.0.0 /micromark-util-sanitize-uri@2.0.0: resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} @@ -13521,50 +12352,41 @@ packages: micromark-util-character: 2.0.1 micromark-util-encode: 2.0.0 micromark-util-symbol: 2.0.0 - dev: false - /micromark-util-subtokenize@1.1.0: - resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + /micromark-util-subtokenize@2.0.0: + resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} dependencies: - micromark-util-chunked: 1.1.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 - - /micromark-util-symbol@1.1.0: - resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 /micromark-util-symbol@2.0.0: resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - dev: false - - /micromark-util-types@1.1.0: - resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} /micromark-util-types@2.0.0: resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - dev: false - /micromark@3.2.0: - resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + /micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} dependencies: - '@types/debug': 4.1.10 + '@types/debug': 4.1.12 debug: 4.3.4(supports-color@8.1.1) decode-named-character-reference: 1.0.2 - micromark-core-commonmark: 1.1.0 - micromark-factory-space: 1.1.0 - micromark-util-character: 1.2.0 - micromark-util-chunked: 1.1.0 - micromark-util-combine-extensions: 1.1.0 - micromark-util-decode-numeric-character-reference: 1.1.0 - micromark-util-encode: 1.1.0 - micromark-util-normalize-identifier: 1.1.0 - micromark-util-resolve-all: 1.1.0 - micromark-util-sanitize-uri: 1.2.0 - micromark-util-subtokenize: 1.1.0 - micromark-util-symbol: 1.1.0 - micromark-util-types: 1.1.0 - uvu: 0.5.6 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 transitivePeerDependencies: - supports-color @@ -13628,13 +12450,6 @@ packages: brace-expansion: 2.0.1 dev: true - /minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: false - /minimatch@7.4.6: resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} engines: {node: '>=10'} @@ -13653,6 +12468,7 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + requiresBuild: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -13748,6 +12564,7 @@ packages: /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} + dev: false /mrmime@1.0.1: resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} @@ -13785,8 +12602,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /nanostores@0.9.4: - resolution: {integrity: sha512-BVFzKt6K5P8tYQLL7MItqcev7jpspA5pIjv+Ck3k6wBnUlwCJcpkGTIinj4APvx8SvdP9fXDGoMRCTY6DO/9QA==} + /nanostores@0.9.5: + resolution: {integrity: sha512-Z+p+g8E7yzaWwOe5gEUB2Ox0rCEeXWYIZWmYvw/ajNYX8DlXdMvMDj8DWfM/subqPAcsf8l8Td4iAwO1DeIIRQ==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} dev: false @@ -13860,8 +12677,8 @@ packages: engines: {node: '>=10.5.0'} dev: false - /node-fetch-native@1.4.0: - resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==} + /node-fetch-native@1.4.1: + resolution: {integrity: sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w==} dev: false /node-fetch@2.7.0: @@ -13884,8 +12701,8 @@ packages: formdata-polyfill: 4.0.10 dev: false - /node-gyp-build@4.6.1: - resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + /node-gyp-build@4.7.0: + resolution: {integrity: sha512-PbZERfeFdrHQOOXiAKOY0VPbykZy90ndPKk0d+CFDegTKmWp1VgOTz2xACVbr1BjCWxrQp68CXtvNsveFhqDJg==} hasBin: true dev: false @@ -13994,10 +12811,12 @@ packages: /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + dev: true /object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} @@ -14007,6 +12826,7 @@ packages: define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 + dev: true /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -14125,6 +12945,13 @@ packages: yocto-queue: 1.0.0 dev: false + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + dependencies: + yocto-queue: 1.0.0 + dev: false + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -14186,7 +13013,7 @@ packages: /parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 character-entities: 2.0.2 character-entities-legacy: 3.0.0 character-reference-invalid: 2.0.1 @@ -14238,7 +13065,7 @@ packages: /parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - dev: false + dev: true /parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} @@ -14303,6 +13130,12 @@ packages: /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + dev: true + + /path-type@5.0.0: + resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} + engines: {node: '>=12'} + dev: false /pathe@1.1.1: resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} @@ -14314,7 +13147,7 @@ packages: /periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 estree-walker: 3.0.3 is-reference: 3.0.2 @@ -14362,34 +13195,18 @@ packages: pathe: 1.1.1 dev: false - /playwright-core@1.39.0: - resolution: {integrity: sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==} - engines: {node: '>=16'} - hasBin: true - dev: true - - /playwright-core@1.40.0-alpha-nov-13-2023: - resolution: {integrity: sha512-EVClUNNwgSh7y161ACuTQ6ULzb51dgBVbvLSGBd6lBtcb5DZ3gwG6TZLU6UrE4KNSeMxZTBsXlFlrasR6L6G3w==} - engines: {node: '>=16'} - hasBin: true - dev: true - - /playwright@1.39.0: - resolution: {integrity: sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==} + /playwright-core@1.40.0: + resolution: {integrity: sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==} engines: {node: '>=16'} hasBin: true - dependencies: - playwright-core: 1.39.0 - optionalDependencies: - fsevents: 2.3.2 dev: true - /playwright@1.40.0-alpha-nov-13-2023: - resolution: {integrity: sha512-/jHChcF6JXbFaL1YpZvNlXaFDfCJiXPyzooNo4TTp4yUG0vtq0b7r8jSOwmC1AcByIr4tIYkC0nOjn2TjvPlYw==} + /playwright@1.40.0: + resolution: {integrity: sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==} engines: {node: '>=16'} hasBin: true dependencies: - playwright-core: 1.40.0-alpha-nov-13-2023 + playwright-core: 1.40.0 optionalDependencies: fsevents: 2.3.2 dev: true @@ -14589,8 +13406,8 @@ packages: postcss: 8.4.31 dev: true - /postcss-load-config@4.0.1(postcss@8.4.31): - resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + /postcss-load-config@4.0.2(postcss@8.4.31): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: postcss: '>=8.0.9' @@ -14601,9 +13418,9 @@ packages: ts-node: optional: true dependencies: - lilconfig: 2.1.0 + lilconfig: 3.0.0 postcss: 8.4.31 - yaml: 2.3.3 + yaml: 2.3.4 /postcss-logical@7.0.0(postcss@8.4.31): resolution: {integrity: sha512-zYf3vHkoW82f5UZTEXChTJvH49Yl9X37axTZsJGxrCG2kOUwtaAoz9E7tqYg0lsIoJLybaL8fk/2mOi81zVIUw==} @@ -14672,13 +13489,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-preset-env@9.2.0(postcss@8.4.31): - resolution: {integrity: sha512-Lnr4C5gb7t5Cc8akQMJzNdJkqw7s7s7BHUaQSgsuf+CTY9Lsz5lqQTft5yNZr59JyCLz0aFNSAqSLm/xRtcTpg==} + /postcss-preset-env@9.3.0(postcss@8.4.31): + resolution: {integrity: sha512-ycw6doPrqV6QxDCtgiyGDef61bEfiSc59HGM4gOw/wxQxmKnhuEery61oOC/5ViENz/ycpRsuhTexs1kUBTvVw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-cascade-layers': 4.0.0(postcss@8.4.31) + '@csstools/postcss-cascade-layers': 4.0.1(postcss@8.4.31) '@csstools/postcss-color-function': 3.0.7(postcss@8.4.31) '@csstools/postcss-color-mix-function': 2.0.7(postcss@8.4.31) '@csstools/postcss-exponential-functions': 1.0.1(postcss@8.4.31) @@ -14690,6 +13507,8 @@ packages: '@csstools/postcss-initial': 1.0.0(postcss@8.4.31) '@csstools/postcss-is-pseudo-class': 4.0.3(postcss@8.4.31) '@csstools/postcss-logical-float-and-clear': 2.0.0(postcss@8.4.31) + '@csstools/postcss-logical-overflow': 1.0.0(postcss@8.4.31) + '@csstools/postcss-logical-overscroll-behavior': 1.0.0(postcss@8.4.31) '@csstools/postcss-logical-resize': 2.0.0(postcss@8.4.31) '@csstools/postcss-logical-viewport-units': 2.0.3(postcss@8.4.31) '@csstools/postcss-media-minmax': 1.1.0(postcss@8.4.31) @@ -14709,7 +13528,7 @@ packages: css-blank-pseudo: 6.0.0(postcss@8.4.31) css-has-pseudo: 6.0.0(postcss@8.4.31) css-prefers-color-scheme: 9.0.0(postcss@8.4.31) - cssdb: 7.8.0 + cssdb: 7.9.0 postcss: 8.4.31 postcss-attribute-case-insensitive: 6.0.2(postcss@8.4.31) postcss-clamp: 4.1.0(postcss@8.4.31) @@ -14785,17 +13604,17 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 - /preact-render-to-string@6.2.2(preact@10.18.1): - resolution: {integrity: sha512-YDfXQiVeYZutFR8/DpxLSbW3W6b7GgjBExRBxOOqcjrGq5rA9cziitQdNPMZe4RVMSdfBnf4hYqyeLs/KvtIuA==} + /preact-render-to-string@6.3.1(preact@10.19.2): + resolution: {integrity: sha512-NQ28WrjLtWY6lKDlTxnFpKHZdpjfF+oE6V4tZ0rTrunHrtZp6Dm0oFrcJalt/5PNeqJz4j1DuZDS0Y6rCBoqDA==} peerDependencies: preact: '>=10' dependencies: - preact: 10.18.1 + preact: 10.19.2 pretty-format: 3.8.0 dev: false - /preact@10.18.1: - resolution: {integrity: sha512-mKUD7RRkQQM6s7Rkmi7IFkoEHjuFqRQUaXamO61E6Nn7vqF/bo7EZCmSyrUnp2UWHw0O7XjZ2eeXis+m7tf4lg==} + /preact@10.19.2: + resolution: {integrity: sha512-UA9DX/OJwv6YwP9Vn7Ti/vF80XL+YA5H2l7BpCtUr3ya8LWHFzpiO5R+N7dN16ujpIxhekRFuOOF82bXX7K/lg==} /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} @@ -14839,12 +13658,12 @@ packages: fast-diff: 1.3.0 dev: true - /prettier-plugin-astro@0.12.0: - resolution: {integrity: sha512-8E+9YQR6/5CPZJs8XsfBw579zrwZkc0Wb7x0fRVm/51JC8Iys4lBw4ecV8fHwpbQnzve86TUa4fJ08BJzqfWnA==} + /prettier-plugin-astro@0.12.2: + resolution: {integrity: sha512-1OXSEht27zrnX7rCa0bEpLdspeumFW4hnj4+JzPuG5bRlSOAhD0rbXBNZfRD9q0Qbr00EcCcnjd6k6M8q+GfTA==} engines: {node: ^14.15.0 || >=16.0.0} dependencies: '@astrojs/compiler': 1.8.2 - prettier: 3.0.3 + prettier: 3.1.0 sass-formatter: 0.7.8 dev: true @@ -14854,8 +13673,8 @@ packages: hasBin: true dev: true - /prettier@3.0.3: - resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + /prettier@3.1.0: + resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} engines: {node: '>=14'} hasBin: true dev: true @@ -14918,8 +13737,8 @@ packages: sisteransi: 1.0.5 dev: false - /property-information@6.3.0: - resolution: {integrity: sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==} + /property-information@6.4.0: + resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} @@ -14946,9 +13765,10 @@ packages: dev: false optional: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + dev: true /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} @@ -14979,6 +13799,7 @@ packages: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 + dev: true /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} @@ -15102,29 +13923,13 @@ packages: strip-indent: 3.0.0 dev: true - /regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - dev: false - - /regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - dev: false - /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} dev: true /regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} - - /regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - dependencies: - '@babel/runtime': 7.23.2 - dev: false + dev: true /regexp.prototype.flags@1.5.1: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} @@ -15133,48 +13938,29 @@ packages: call-bind: 1.0.5 define-properties: 1.2.1 set-function-name: 2.0.1 + dev: true - /regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} - dependencies: - '@babel/regjsgen': 0.8.0 - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - dev: false - - /regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - dependencies: - jsesc: 0.5.0 - dev: false - - /rehype-autolink-headings@6.1.1: - resolution: {integrity: sha512-NMYzZIsHM3sA14nC5rAFuUPIOfg+DFmf9EY1YMhaNlB7+3kK/ZlE6kqPfuxr1tsJ1XWkTrMtMoyHosU70d35mA==} + /rehype-autolink-headings@7.1.0: + resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==} dependencies: - '@types/hast': 2.3.7 - extend: 3.0.2 - hast-util-has-property: 2.0.1 - hast-util-heading-rank: 2.1.1 - hast-util-is-element: 2.1.3 - unified: 10.1.2 - unist-util-visit: 4.1.2 + '@types/hast': 3.0.3 + '@ungap/structured-clone': 1.2.0 + hast-util-heading-rank: 3.0.0 + hast-util-is-element: 3.0.0 + unified: 11.0.4 + unist-util-visit: 5.0.0 - /rehype-mathjax@4.0.3: - resolution: {integrity: sha512-QIwWH9U+r54nMQklVkT1qluxhKyzdPWz9dFwgel3BrseQsWZafRTDTUj8VR8/14nFuRIV2ChuCMz4zpACPoYvg==} + /rehype-mathjax@5.0.0: + resolution: {integrity: sha512-IRPgpSpwOq4JNn3efeTrbYDMmzjOKCTJtu1Wyo/+6nenyqwqIvlojYDczRILOeHa1HyCMYmqpdvfOovOVzDIGg==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 3.0.3 '@types/mathjax': 0.0.37 - hast-util-from-dom: 4.2.0 - hast-util-to-text: 3.1.2 - jsdom: 20.0.3 + hast-util-from-dom: 5.0.0 + hast-util-to-text: 4.0.0 + jsdom: 22.1.0 mathjax-full: 3.2.2 - unified: 10.1.2 - unist-util-visit: 4.1.2 + unified: 11.0.4 + unist-util-visit-parents: 6.0.1 transitivePeerDependencies: - bufferutil - canvas @@ -15185,48 +13971,60 @@ packages: /rehype-parse@8.0.5: resolution: {integrity: sha512-Ds3RglaY/+clEX2U2mHflt7NlMA72KspZ0JLUJgBBLpRddBcEw3H8uYZQliQriku22NZpYMfjDdSgHcjxue24A==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 2.3.8 hast-util-from-parse5: 7.1.2 parse5: 6.0.1 unified: 10.1.2 + dev: true + + /rehype-parse@9.0.0: + resolution: {integrity: sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==} + dependencies: + '@types/hast': 3.0.3 + hast-util-from-html: 2.0.1 + unified: 11.0.4 dev: false - /rehype-pretty-code@0.10.1: - resolution: {integrity: sha512-WHjRvGlqPXG8BVRB9mK0255WvIOnzvHivAWhFkA2OG+NTkQWtTbCULZMokOHLf3Yy8q8I8/F8QNjDSQBhjMK5w==} + /rehype-pretty-code@0.10.2: + resolution: {integrity: sha512-yBgk3S4yXtkAWVrkoN1DqDihjsaP0ReuN9Du4Dtkl/wsgwyqGNGuIUGi2etVHAOsi40e2KRHoOulQqnKPuscPA==} engines: {node: '>=16'} peerDependencies: shiki: 0.x + peerDependenciesMeta: + shiki: + optional: true dependencies: - '@types/hast': 2.3.7 hash-obj: 4.0.0 + hast-util-to-string: 2.0.0 parse-numeric-range: 1.3.0 + rehype-parse: 8.0.5 + unified: 10.1.2 + unist-util-visit: 4.1.2 dev: true - /rehype-raw@6.1.1: - resolution: {integrity: sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==} + /rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} dependencies: - '@types/hast': 2.3.7 - hast-util-raw: 7.2.3 - unified: 10.1.2 + '@types/hast': 3.0.3 + hast-util-raw: 9.0.1 + vfile: 6.0.1 dev: false - /rehype-slug@5.1.0: - resolution: {integrity: sha512-Gf91dJoXneiorNEnn+Phx97CO7oRMrpi+6r155tTxzGuLtm+QrI4cTwCa9e1rtePdL4i9tSO58PeSS6HWfgsiw==} + /rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} dependencies: - '@types/hast': 2.3.7 + '@types/hast': 3.0.3 github-slugger: 2.0.0 - hast-util-has-property: 2.0.1 - hast-util-heading-rank: 2.1.1 - hast-util-to-string: 2.0.0 - unified: 10.1.2 - unist-util-visit: 4.1.2 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.0 + unist-util-visit: 5.0.0 - /rehype-stringify@9.0.4: - resolution: {integrity: sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==} + /rehype-stringify@10.0.0: + resolution: {integrity: sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==} dependencies: - '@types/hast': 2.3.7 - hast-util-to-html: 8.0.4 - unified: 10.1.2 + '@types/hast': 3.0.3 + hast-util-to-html: 9.0.0 + unified: 11.0.4 dev: false /rehype-toc@3.0.2: @@ -15235,13 +14033,13 @@ packages: dependencies: '@jsdevtools/rehype-toc': 3.0.2 - /rehype@12.0.1: - resolution: {integrity: sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==} + /rehype@13.0.1: + resolution: {integrity: sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==} dependencies: - '@types/hast': 2.3.7 - rehype-parse: 8.0.5 - rehype-stringify: 9.0.4 - unified: 10.1.2 + '@types/hast': 3.0.3 + rehype-parse: 9.0.0 + rehype-stringify: 10.0.0 + unified: 11.0.4 dev: false /reinterval@1.1.0: @@ -15258,67 +14056,73 @@ packages: dependencies: unist-util-visit: 1.4.1 - /remark-gfm@3.0.1: - resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} + /remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-gfm: 2.0.2 - micromark-extension-gfm: 2.0.3 - unified: 10.1.2 + '@types/mdast': 4.0.3 + mdast-util-gfm: 3.0.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.4 transitivePeerDependencies: - supports-color dev: false - /remark-math@5.1.1: - resolution: {integrity: sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw==} + /remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-math: 2.0.2 - micromark-extension-math: 2.1.2 - unified: 10.1.2 + '@types/mdast': 4.0.3 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color dev: true - /remark-mdx@2.3.0: - resolution: {integrity: sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==} + /remark-mdx@3.0.0: + resolution: {integrity: sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==} dependencies: - mdast-util-mdx: 2.0.1 - micromark-extension-mdxjs: 1.0.1 + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 transitivePeerDependencies: - supports-color dev: false - /remark-parse@10.0.2: - resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + /remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-from-markdown: 1.3.1 - unified: 10.1.2 + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + micromark-util-types: 2.0.0 + unified: 11.0.4 transitivePeerDependencies: - supports-color dev: false - /remark-rehype@10.1.0: - resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} + /remark-rehype@11.0.0: + resolution: {integrity: sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==} dependencies: - '@types/hast': 2.3.7 - '@types/mdast': 3.0.14 - mdast-util-to-hast: 12.3.0 - unified: 10.1.2 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + mdast-util-to-hast: 13.0.2 + unified: 11.0.4 + vfile: 6.0.1 - /remark-shiki-twoslash@3.1.3(typescript@5.1.6): + /remark-shiki-twoslash@3.1.3(typescript@5.2.2): resolution: {integrity: sha512-4e8OH3ySOCw5wUbDcPszokOKjKuebOqlP2WlySvC7ITBOq27BiGsFlq+FNWhxppZ+JzhTWah4gQrnMjX3KDbAQ==} peerDependencies: typescript: '>3' dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 '@typescript/twoslash': 3.1.0 '@typescript/vfs': 1.3.4 fenceparser: 1.1.1 regenerator-runtime: 0.13.11 shiki: 0.10.1 - shiki-twoslash: 3.1.2(typescript@5.1.6) + shiki-twoslash: 3.1.2(typescript@5.2.2) tslib: 2.1.0 - typescript: 5.1.6 + typescript: 5.2.2 unist-util-visit: 2.0.3 transitivePeerDependencies: - supports-color @@ -15333,12 +14137,19 @@ packages: unist-util-visit: 4.1.2 dev: false - /remark-toc@8.0.1: - resolution: {integrity: sha512-7he2VOm/cy13zilnOTZcyAoyoolV26ULlon6XyCFU+vG54Z/LWJnwphj/xKIDLOt66QmJUgTyUvLVHi2aAElyg==} + /remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} dependencies: - '@types/mdast': 3.0.14 - mdast-util-toc: 6.1.1 - unified: 10.1.2 + '@types/mdast': 4.0.3 + mdast-util-to-markdown: 2.1.0 + unified: 11.0.4 + dev: false + + /remark-toc@9.0.0: + resolution: {integrity: sha512-KJ9txbo33GjDAV1baHFze7ij4G8c7SGYoY8Kzsm2gzFpbhL/bSoVpMMzGa3vrNDSWASNd/3ppAqL7cP2zD6JIA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-toc: 7.0.0 dev: true /request-light@0.7.0: @@ -15350,11 +14161,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: false - /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true @@ -15437,37 +14243,37 @@ packages: dependencies: glob: 7.2.3 - /rollup-plugin-terser@7.0.2(rollup@2.79.1): - resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser - peerDependencies: - rollup: ^2.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@babel/code-frame': 7.22.13 - jest-worker: 26.6.2 - rollup: 2.79.1 - serialize-javascript: 4.0.0 - terser: 5.22.0 - dev: false - - /rollup@2.79.1: - resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} - engines: {node: '>=10.0.0'} + /rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: fsevents: 2.3.3 dev: false - /rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + /rollup@4.5.0: + resolution: {integrity: sha512-41xsWhzxqjMDASCxH5ibw1mXk+3c4TNI2UjKbLxe6iEzrSQnqOzmmK8/3mufCPbzHNJ2e04Fc1ddI35hHy+8zg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.5.0 + '@rollup/rollup-android-arm64': 4.5.0 + '@rollup/rollup-darwin-arm64': 4.5.0 + '@rollup/rollup-darwin-x64': 4.5.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.5.0 + '@rollup/rollup-linux-arm64-gnu': 4.5.0 + '@rollup/rollup-linux-arm64-musl': 4.5.0 + '@rollup/rollup-linux-x64-gnu': 4.5.0 + '@rollup/rollup-linux-x64-musl': 4.5.0 + '@rollup/rollup-win32-arm64-msvc': 4.5.0 + '@rollup/rollup-win32-ia32-msvc': 4.5.0 + '@rollup/rollup-win32-x64-msvc': 4.5.0 fsevents: 2.3.3 + /rrweb-cssom@0.6.0: + resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} + dev: true + /run-applescript@5.0.0: resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} engines: {node: '>=12'} @@ -15484,12 +14290,6 @@ packages: resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==} dev: true - /sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} - dependencies: - mri: 1.2.0 - /safe-array-concat@1.0.1: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} @@ -15498,6 +14298,7 @@ packages: get-intrinsic: 1.2.2 has-symbols: 1.0.3 isarray: 2.0.5 + dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -15508,6 +14309,7 @@ packages: call-bind: 1.0.5 get-intrinsic: 1.2.2 is-regex: 1.1.4 + dev: true /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -15518,8 +14320,8 @@ packages: suf-log: 2.5.3 dev: true - /sass@1.69.4: - resolution: {integrity: sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==} + /sass@1.69.5: + resolution: {integrity: sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -15587,20 +14389,14 @@ packages: transitivePeerDependencies: - supports-color - /serialize-javascript@4.0.0: - resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} - dependencies: - randombytes: 2.1.0 - dev: false - /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: randombytes: 2.1.0 dev: true - /seroval@0.11.6: - resolution: {integrity: sha512-Lhy+94CNcNza6d0vM4sQKLsaLaX39q0ELqIBc7DkdiFljI8Q387Yb+xKgLxRWXs7uuHRu/ZcJ64xfVJ0Bj4LPg==} + /seroval@0.12.4: + resolution: {integrity: sha512-JIsZHp98o+okpYN8HEPyI9Blr0gxAUPIGvg3waXrEMFjPz9obiLYMz0uFiUGezKiCK8loosYbn8WsqO8WtAJUA==} engines: {node: '>=10'} /serve-static@1.15.0: @@ -15638,6 +14434,7 @@ packages: get-intrinsic: 1.2.2 gopd: 1.0.1 has-property-descriptors: 1.0.1 + dev: true /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} @@ -15646,6 +14443,7 @@ packages: define-data-property: 1.1.1 functions-have-names: 1.2.3 has-property-descriptors: 1.0.1 + dev: true /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -15692,7 +14490,7 @@ packages: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} dev: true - /shiki-twoslash@3.1.2(typescript@5.1.6): + /shiki-twoslash@3.1.2(typescript@5.2.2): resolution: {integrity: sha512-JBcRIIizi+exIA/OUhYkV6jtyeZco0ykCkIRd5sgwIt1Pm4pz+maoaRZpm6SkhPwvif4fCA7xOtJOykhpIV64Q==} peerDependencies: typescript: '>3' @@ -15701,7 +14499,7 @@ packages: '@typescript/vfs': 1.3.4 fenceparser: 1.1.1 shiki: 0.10.1 - typescript: 5.1.6 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -15714,8 +14512,8 @@ packages: vscode-textmate: 5.2.0 dev: true - /shikiji@0.6.10: - resolution: {integrity: sha512-WE+A5Y2ntM5hL3iJQujk97qr5Uj7PSIRXpQfrZ6h+JWPXZ8KBEDhFXc4lqNriaRq1WGOVPUT83XMOzmHiH3W8A==} + /shikiji@0.6.13: + resolution: {integrity: sha512-4T7X39csvhT0p7GDnq9vysWddf2b6BeioiN3Ymhnt3xcy9tXmDcnsEFVxX18Z4YcQgEE/w48dLJ4pPPUcG9KkA==} dependencies: hast-util-to-html: 9.0.0 dev: false @@ -15726,6 +14524,7 @@ packages: call-bind: 1.0.5 get-intrinsic: 1.2.2 object-inspect: 1.13.1 + dev: true /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -15789,6 +14588,12 @@ packages: /slash@4.0.0: resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} engines: {node: '>=12'} + dev: true + + /slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + dev: false /slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} @@ -15811,21 +14616,21 @@ packages: yargs: 15.4.1 dev: true - /solid-js@1.8.3: - resolution: {integrity: sha512-S7ztgPI6X4tUaWmhZe3aDx0E9F6FGxXVU8NsocrPqqUbxHoFi8eTPlDMcenOlXuo2ITQ97j2URaj0StfJci4KQ==} + /solid-js@1.8.5: + resolution: {integrity: sha512-xvtJvzJzWbsn35oKFhW9kNwaxG1Z/YLMsDp4tLVcYZTMPzvzQ8vEZuyDQ6nt7xDArVgZJ7TUFrJUwrui/oq53A==} dependencies: csstype: 3.1.2 - seroval: 0.11.6 + seroval: 0.12.4 - /solid-refresh@0.5.3(solid-js@1.8.3): + /solid-refresh@0.5.3(solid-js@1.8.5): resolution: {integrity: sha512-Otg5it5sjOdZbQZJnvo99TEBAr6J7PQ5AubZLNU6szZzg3RQQ5MX04oteBIIGDs0y2Qv8aXKm9e44V8z+UnFdw==} peerDependencies: solid-js: ^1.3 dependencies: - '@babel/generator': 7.23.0 + '@babel/generator': 7.23.3 '@babel/helper-module-imports': 7.22.15 - '@babel/types': 7.23.0 - solid-js: 1.8.3 + '@babel/types': 7.23.3 + solid-js: 1.8.5 dev: false /sort-keys@5.0.0: @@ -15839,34 +14644,16 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: false - /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + dev: false /source-map@0.7.4: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} engines: {node: '>= 8'} dev: false - /source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} - dependencies: - whatwg-url: 7.1.0 - dev: false - - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - dev: false - /space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -15983,18 +14770,13 @@ packages: strip-ansi: 7.1.0 dev: false - /string.prototype.matchall@4.0.10: - resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} + /string-width@7.0.0: + resolution: {integrity: sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==} + engines: {node: '>=18'} dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - has-symbols: 1.0.3 - internal-slot: 1.0.6 - regexp.prototype.flags: 1.5.1 - set-function-name: 2.0.1 - side-channel: 1.0.4 + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 dev: false /string.prototype.padend@3.1.5: @@ -16013,6 +14795,7 @@ packages: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + dev: true /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} @@ -16020,6 +14803,7 @@ packages: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + dev: true /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} @@ -16027,9 +14811,11 @@ packages: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + dev: true /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + requiresBuild: true dependencies: safe-buffer: 5.2.1 dev: false @@ -16040,15 +14826,6 @@ packages: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 - /stringify-object@3.3.0: - resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} - engines: {node: '>=4'} - dependencies: - get-own-enumerable-property-symbols: 3.0.2 - is-obj: 1.0.1 - is-regexp: 1.0.0 - dev: false - /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -16075,11 +14852,6 @@ packages: engines: {node: '>=8'} dev: true - /strip-comments@2.0.1: - resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} - engines: {node: '>=10'} - dev: false - /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -16099,6 +14871,7 @@ packages: /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} + requiresBuild: true /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} @@ -16169,23 +14942,31 @@ packages: dependencies: has-flag: 4.0.0 + /supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: false + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte-hmr@0.15.3(svelte@4.2.2): + /svelte-hmr@0.15.3(svelte@4.2.5): resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: ^3.19.0 || ^4.0.0 dependencies: - svelte: 4.2.2 + svelte: 4.2.5 dev: false - /svelte2tsx@0.6.23(svelte@4.2.2)(typescript@5.1.6): - resolution: {integrity: sha512-3bwd1PuWUA3oEXy8+85zrLDnmJOsVpShpKVAehGWeYsz/66zMihTpRpUN97VVAKTZbO5tP4wnchHUXYs0zOwdw==} + /svelte2tsx@0.6.25(svelte@4.2.5)(typescript@5.2.2): + resolution: {integrity: sha512-hhBKL5X9gGvKQAZ9xLoHnbE9Yb00HxEZJlxcj2drxWK+Tpqcs/bnodjSfCGbqEhvNaUXYNbVL7s4dEXT+o0f6w==} peerDependencies: - svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 + svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 peerDependenciesMeta: typescript: @@ -16193,18 +14974,18 @@ packages: dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 4.2.2 - typescript: 5.1.6 + svelte: 4.2.5 + typescript: 5.2.2 dev: false - /svelte@4.2.2: - resolution: {integrity: sha512-My2tytF2e2NnHSpn2M7/3VdXT4JdTglYVUuSuK/mXL2XtulPYbeBfl8Dm1QiaKRn0zoULRnL+EtfZHHP0k4H3A==} + /svelte@4.2.5: + resolution: {integrity: sha512-P9YPKsGkNdw4OJbtpd1uzimQHPj7Ai2sPcOHmmD6VgkFhFDmcYevQi7vE4cQ1g8/Vs64aL2TwMoCNFAzv7TPaQ==} engines: {node: '>=16'} dependencies: '@ampproject/remapping': 2.2.1 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.20 - acorn: 8.10.0 + acorn: 8.11.2 aria-query: 5.3.0 axobject-query: 3.2.1 code-red: 1.0.4 @@ -16219,8 +15000,8 @@ packages: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} dev: false - /svgo@3.0.2: - resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==} + /svgo@3.0.4: + resolution: {integrity: sha512-T+Xul3JwuJ6VGXKo/p2ndqx1ibxNKnLTvRc1ZTWKCfyKS/GgNjRZcYsK84fxTsy/izr91g/Rwx6fGnVgaFSI5g==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -16228,6 +15009,7 @@ packages: commander: 7.2.0 css-select: 5.1.0 css-tree: 2.3.1 + css-what: 6.1.0 csso: 5.0.5 picocolors: 1.0.0 dev: false @@ -16244,8 +15026,8 @@ packages: tslib: 2.6.2 dev: true - /tailwindcss@3.3.3: - resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==} + /tailwindcss@3.3.5: + resolution: {integrity: sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -16254,10 +15036,10 @@ packages: chokidar: 3.5.3 didyoumean: 1.2.2 dlv: 1.1.3 - fast-glob: 3.3.1 + fast-glob: 3.3.2 glob-parent: 6.0.2 is-glob: 4.0.3 - jiti: 1.20.0 + jiti: 1.21.0 lilconfig: 2.1.0 micromatch: 4.0.5 normalize-path: 3.0.0 @@ -16266,7 +15048,7 @@ packages: postcss: 8.4.31 postcss-import: 15.1.0(postcss@8.4.31) postcss-js: 4.0.1(postcss@8.4.31) - postcss-load-config: 4.0.1(postcss@8.4.31) + postcss-load-config: 4.0.2(postcss@8.4.31) postcss-nested: 6.0.1(postcss@8.4.31) postcss-selector-parser: 6.0.13 resolve: 1.22.8 @@ -16335,35 +15117,17 @@ packages: yallist: 4.0.0 dev: false - /temp-dir@2.0.0: - resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} - engines: {node: '>=8'} - dev: false - - /tempy@0.6.0: - resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} - engines: {node: '>=10'} - dependencies: - is-stream: 2.0.1 - temp-dir: 2.0.0 - type-fest: 0.16.0 - unique-string: 2.0.0 - dev: false - /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} dev: true - /terser@5.22.0: - resolution: {integrity: sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==} - engines: {node: '>=10'} - hasBin: true + /terminal-link@3.0.0: + resolution: {integrity: sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg==} + engines: {node: '>=12'} dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.10.0 - commander: 2.20.3 - source-map-support: 0.5.21 + ansi-escapes: 5.0.0 + supports-hyperlinks: 2.3.0 dev: false /text-table@0.2.0: @@ -16386,13 +15150,11 @@ packages: engines: {node: '>=10.18'} peerDependencies: tslib: ^2 + peerDependenciesMeta: + tslib: + optional: true dev: true - /throttles@1.0.1: - resolution: {integrity: sha512-fab7Xg+zELr9KOv4fkaBoe/b3L0GMGLd0IBSCn16GoE/Qx6/OfCr1eGNyEcDU2pUA79qQfZ8kPQWlRuok4YwTw==} - engines: {node: '>=6'} - dev: false - /timestring@6.0.0: resolution: {integrity: sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA==} engines: {node: '>=8'} @@ -16450,7 +15212,7 @@ packages: engines: {node: '>=6'} dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 dev: true @@ -16458,17 +15220,11 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - /tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - dependencies: - punycode: 2.3.0 - dev: false - - /tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} + /tr46@4.1.1: + resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} + engines: {node: '>=14'} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /trim-lines@3.0.1: @@ -16482,13 +15238,13 @@ packages: /trough@2.1.0: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} - /ts-api-utils@1.0.3(typescript@5.1.6): + /ts-api-utils@1.0.3(typescript@5.2.2): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.1.6 + typescript: 5.2.2 dev: true /ts-interface-checker@0.1.13: @@ -16501,7 +15257,7 @@ packages: code-block-writer: 12.0.0 dev: true - /tsconfck@3.0.0(typescript@5.1.6): + /tsconfck@3.0.0(typescript@5.2.2): resolution: {integrity: sha512-w3wnsIrJNi7avf4Zb0VjOoodoO0woEqGgZGQm+LHH9przdUI+XDKsWAXwxHA1DaRTjeuZNcregSzr7RaA8zG9A==} engines: {node: ^18 || >=20} hasBin: true @@ -16511,14 +15267,14 @@ packages: typescript: optional: true dependencies: - typescript: 5.1.6 + typescript: 5.2.2 dev: false /tsconfig-resolver@3.0.1: resolution: {integrity: sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==} dependencies: '@types/json5': 0.0.30 - '@types/resolve': 1.20.4 + '@types/resolve': 1.20.5 json5: 2.2.3 resolve: 1.22.8 strip-bom: 4.0.0 @@ -16639,11 +15395,6 @@ packages: engines: {node: '>=10'} dev: true - /type-fest@0.16.0: - resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} - engines: {node: '>=10'} - dev: false - /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -16688,6 +15439,7 @@ packages: call-bind: 1.0.5 get-intrinsic: 1.2.2 is-typed-array: 1.1.12 + dev: true /typed-array-byte-length@1.0.0: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} @@ -16697,6 +15449,7 @@ packages: for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 + dev: true /typed-array-byte-offset@1.0.0: resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} @@ -16707,6 +15460,7 @@ packages: for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 + dev: true /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} @@ -16714,6 +15468,7 @@ packages: call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 + dev: true /typesafe-path@0.2.2: resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} @@ -16725,8 +15480,8 @@ packages: semver: 7.5.4 dev: true - /typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} hasBin: true @@ -16759,6 +15514,10 @@ packages: has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} /undici@5.26.5: resolution: {integrity: sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==} @@ -16771,33 +15530,15 @@ packages: resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} dev: false - /unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - dev: false - - /unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - dev: false - - /unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - dev: false - - /unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} + /unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} dev: false /unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 bail: 2.0.2 extend: 3.0.2 is-buffer: 2.0.5 @@ -16805,23 +15546,24 @@ packages: trough: 2.1.0 vfile: 5.3.7 - /unique-string@2.0.0: - resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} - engines: {node: '>=8'} + /unified@11.0.4: + resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} dependencies: - crypto-random-string: 2.0.0 - dev: false + '@types/unist': 3.0.2 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 6.0.1 - /unist-util-find-after@4.0.1: - resolution: {integrity: sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==} + /unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} dependencies: - '@types/unist': 2.0.9 - unist-util-is: 5.2.1 + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 dev: true - /unist-util-generated@2.0.1: - resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} - /unist-util-is@3.0.0: resolution: {integrity: sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==} @@ -16832,48 +15574,41 @@ packages: /unist-util-is@5.2.1: resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 /unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} dependencies: - '@types/unist': 3.0.1 - dev: false + '@types/unist': 3.0.2 /unist-util-modify-children@3.1.1: resolution: {integrity: sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 array-iterate: 2.0.1 dev: false - /unist-util-position-from-estree@1.1.2: - resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==} + /unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 3.0.2 dev: false - /unist-util-position@4.0.4: - resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} - dependencies: - '@types/unist': 2.0.9 - /unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} dependencies: - '@types/unist': 3.0.1 - dev: false + '@types/unist': 3.0.2 - /unist-util-remove-position@4.0.2: - resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==} + /unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} dependencies: - '@types/unist': 2.0.9 - unist-util-visit: 4.1.2 + '@types/unist': 3.0.2 + unist-util-visit: 5.0.0 /unist-util-select@4.0.3: resolution: {integrity: sha512-1074+K9VyR3NyUz3lgNtHKm7ln+jSZXtLJM4E22uVuoFn88a/Go2pX8dusrt/W+KWH1ncn8jcd8uCQuvXb/fXA==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 css-selector-parser: 1.4.1 nth-check: 2.1.1 zwitch: 2.0.4 @@ -16882,18 +15617,17 @@ packages: /unist-util-stringify-position@3.0.3: resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 /unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} dependencies: - '@types/unist': 3.0.1 - dev: false + '@types/unist': 3.0.2 /unist-util-visit-children@2.0.2: resolution: {integrity: sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 dev: false /unist-util-visit-parents@2.1.2: @@ -16904,22 +15638,21 @@ packages: /unist-util-visit-parents@3.1.1: resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 unist-util-is: 4.1.0 dev: true /unist-util-visit-parents@5.1.3: resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 unist-util-is: 5.2.1 /unist-util-visit-parents@6.0.1: resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} dependencies: - '@types/unist': 3.0.1 + '@types/unist': 3.0.2 unist-util-is: 6.0.0 - dev: false /unist-util-visit@1.4.1: resolution: {integrity: sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==} @@ -16929,7 +15662,7 @@ packages: /unist-util-visit@2.0.3: resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 unist-util-is: 4.1.0 unist-util-visit-parents: 3.1.1 dev: true @@ -16937,17 +15670,16 @@ packages: /unist-util-visit@4.1.2: resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 unist-util-is: 5.2.1 unist-util-visit-parents: 5.1.3 /unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} dependencies: - '@types/unist': 3.0.1 + '@types/unist': 3.0.2 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - dev: false /universal-user-agent@6.0.0: resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} @@ -16966,6 +15698,7 @@ packages: /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} + dev: true /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} @@ -16977,11 +15710,6 @@ packages: engines: {node: '>=8'} dev: true - /upath@1.2.0: - resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} - engines: {node: '>=4'} - dev: false - /update-browserslist-db@1.0.13(browserslist@4.22.1): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -16999,7 +15727,8 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 + dev: true /url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} @@ -17025,16 +15754,6 @@ packages: hasBin: true dev: false - /uvu@0.5.6: - resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} - engines: {node: '>=8'} - hasBin: true - dependencies: - dequal: 2.0.3 - diff: 5.1.0 - kleur: 4.1.5 - sade: 1.8.1 - /validate-html-nesting@1.2.2: resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} dev: false @@ -17054,34 +15773,33 @@ packages: /vfile-location@4.1.0: resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 vfile: 5.3.7 - dev: false + dev: true /vfile-location@5.0.2: resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} dependencies: - '@types/unist': 3.0.1 + '@types/unist': 3.0.2 vfile: 6.0.1 dev: false /vfile-message@3.1.4: resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 unist-util-stringify-position: 3.0.3 /vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} dependencies: - '@types/unist': 3.0.1 + '@types/unist': 3.0.2 unist-util-stringify-position: 4.0.0 - dev: false /vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} dependencies: - '@types/unist': 2.0.9 + '@types/unist': 2.0.10 is-buffer: 2.0.5 unist-util-stringify-position: 3.0.3 vfile-message: 3.1.4 @@ -17089,10 +15807,9 @@ packages: /vfile@6.0.1: resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} dependencies: - '@types/unist': 3.0.1 + '@types/unist': 3.0.2 unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - dev: false /vite-node@0.34.6(@types/node@18.18.6): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} @@ -17104,7 +15821,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + vite: 4.5.0(@types/node@18.18.6) transitivePeerDependencies: - '@types/node' - less @@ -17116,27 +15833,7 @@ packages: - terser dev: false - /vite-plugin-pwa@0.16.4(workbox-window@7.0.0): - resolution: {integrity: sha512-lmwHFIs9zI2H9bXJld/zVTbCqCQHZ9WrpyDMqosICDV0FVnCJwniX1NMDB79HGTIZzOQkY4gSZaVTJTw6maz/Q==} - engines: {node: '>=16.0.0'} - peerDependencies: - vite: ^3.1.0 || ^4.0.0 - workbox-window: ^7.0.0 - peerDependenciesMeta: - vite: - optional: true - dependencies: - debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.1 - pretty-bytes: 6.1.1 - workbox-build: 7.0.0 - workbox-window: 7.0.0 - transitivePeerDependencies: - - '@types/babel__core' - - supports-color - dev: false - - /vite-plugin-solid@2.7.2(solid-js@1.8.3): + /vite-plugin-solid@2.7.2(solid-js@1.8.5): resolution: {integrity: sha512-GV2SMLAibOoXe76i02AsjAg7sbm/0lngBlERvJKVN67HOrJsHcWgkt0R6sfGLDJuFkv2aBe14Zm4vJcNME+7zw==} peerDependencies: solid-js: ^1.7.2 @@ -17145,26 +15842,42 @@ packages: vite: optional: true dependencies: - '@babel/core': 7.23.2 - '@babel/preset-typescript': 7.23.2(@babel/core@7.23.2) - '@types/babel__core': 7.20.3 - babel-preset-solid: 1.8.2(@babel/core@7.23.2) + '@babel/core': 7.23.3 + '@babel/preset-typescript': 7.23.2(@babel/core@7.23.3) + '@types/babel__core': 7.20.4 + babel-preset-solid: 1.8.2(@babel/core@7.23.3) merge-anything: 5.1.7 - solid-js: 1.8.3 - solid-refresh: 0.5.3(solid-js@1.8.3) - vitefu: 0.2.5(vite@4.5.0) + solid-js: 1.8.5 + solid-refresh: 0.5.3(solid-js@1.8.5) + vitefu: 0.2.5(vite@5.0.0) transitivePeerDependencies: - supports-color dev: false /vite-svg-loader@4.0.0: resolution: {integrity: sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==} + peerDependencies: + vue: '*' + peerDependenciesMeta: + vue: + optional: true + dependencies: + '@vue/compiler-sfc': 3.3.8 + svgo: 3.0.4 + dev: false + + /vite-svg-loader@5.0.1: + resolution: {integrity: sha512-EUfcuqk1NomuacwiuL3mvCfinkm4XN0AHN8BXG737eDlhC0jnp5jxdCxakV+juP/YhhjV5tq/c/bLcm3waWv4Q==} + peerDependencies: + vue: '>=3.2.13' + peerDependenciesMeta: + vue: + optional: true dependencies: - '@vue/compiler-sfc': 3.3.6 - svgo: 3.0.2 + svgo: 3.0.4 dev: false - /vite@4.5.0(@types/node@18.18.6)(sass@1.69.4): + /vite@4.5.0(@types/node@18.18.6): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -17196,11 +15909,47 @@ packages: esbuild: 0.18.20 postcss: 8.4.31 rollup: 3.29.4 - sass: 1.69.4 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /vite@5.0.0(@types/node@18.18.6)(sass@1.69.5): + resolution: {integrity: sha512-ESJVM59mdyGpsiNAeHQOR/0fqNoOyWPYesFto8FFZugfmhdHx8Fzd8sF3Q/xkVhZsyOxHfdM7ieiVAorI9RjFw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.18.6 + esbuild: 0.19.6 + postcss: 8.4.31 + rollup: 4.5.0 + sass: 1.69.5 optionalDependencies: fsevents: 2.3.3 - /vitefu@0.2.5(vite@4.5.0): + /vitefu@0.2.5(vite@5.0.0): resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} peerDependencies: vite: ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -17208,7 +15957,7 @@ packages: vite: optional: true dependencies: - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + vite: 5.0.0(@types/node@18.18.6)(sass@1.69.5) dev: false /vitest@0.34.6: @@ -17263,7 +16012,7 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.1 tinypool: 0.7.0 - vite: 4.5.0(@types/node@18.18.6)(sass@1.69.4) + vite: 4.5.0(@types/node@18.18.6) vite-node: 0.34.6(@types/node@18.18.6) why-is-node-running: 2.2.2 transitivePeerDependencies: @@ -17276,47 +16025,47 @@ packages: - terser dev: false - /volar-service-css@0.0.14(@volar/language-service@1.10.4): - resolution: {integrity: sha512-xmyKoyWpbgM0u7mGA1ogyj5ol7CfQADm5eXNpeJeX3Rp79rFEtz1DuuaIjcgRvhSYsjJfPBOtOvHBwTRf4HaEQ==} + /volar-service-css@0.0.16(@volar/language-service@1.10.10): + resolution: {integrity: sha512-gK/XD35t/P3SQrUuS8LMlCnE2ItIk+kXI6gPvBYl1NZ7O+tLH8rUWXA32YgpwNoITxYrm/G1seaq08zs4aiPvg==} peerDependencies: '@volar/language-service': ~1.10.0 peerDependenciesMeta: '@volar/language-service': optional: true dependencies: - '@volar/language-service': 1.10.4 + '@volar/language-service': 1.10.10 vscode-css-languageservice: 6.2.10 vscode-uri: 3.0.8 dev: true - /volar-service-emmet@0.0.14(@volar/language-service@1.10.4): - resolution: {integrity: sha512-0meSKjQ93j5iSYl6Y+qtARfAYr3J2wNSr6wlKr/V9KULAy+8/me8q9l8wkTQqdRMujZAv2j/LzgQ65Yc9mnA1w==} + /volar-service-emmet@0.0.16(@volar/language-service@1.10.10): + resolution: {integrity: sha512-8sWWywzVJOD+PWDArOXDWbiRlM7+peydFhXJT71i4X1WPW32RyPxn6FypvciO+amqpfZP2rXfB9eibIJ+EofSQ==} peerDependencies: '@volar/language-service': ~1.10.0 peerDependenciesMeta: '@volar/language-service': optional: true dependencies: - '@volar/language-service': 1.10.4 + '@volar/language-service': 1.10.10 '@vscode/emmet-helper': 2.9.2 - volar-service-html: 0.0.14(@volar/language-service@1.10.4) + volar-service-html: 0.0.16(@volar/language-service@1.10.10) dev: true - /volar-service-html@0.0.14(@volar/language-service@1.10.4): - resolution: {integrity: sha512-PQb97QICxXhXD7AJFU/S/Vexd1L4IP2Sa5SzxYyKnApcx0GNdxaIbFHlev9wazrTgtCtSnaVXJBxY05pZzTKPw==} + /volar-service-html@0.0.16(@volar/language-service@1.10.10): + resolution: {integrity: sha512-/oEXXgry++1CnTXQBUNf9B8MZfTlYZuJfZA7Zx9MN7WS4ZPxk3BFOdal/cXH6RNR2ruNEYr5QTW9rsqtoUscag==} peerDependencies: '@volar/language-service': ~1.10.0 peerDependenciesMeta: '@volar/language-service': optional: true dependencies: - '@volar/language-service': 1.10.4 - vscode-html-languageservice: 5.1.0 + '@volar/language-service': 1.10.10 + vscode-html-languageservice: 5.1.1 vscode-uri: 3.0.8 dev: true - /volar-service-prettier@0.0.14(@volar/language-service@1.10.4)(prettier@3.0.3): - resolution: {integrity: sha512-woZLBikvv8u0jUAq10ZTtuo9hmnQ1RHZubMhzyJbWwkr6L7wT7bPZkscdyaCGrzBT3Pz4zbS0bnpAC5GLAILTA==} + /volar-service-prettier@0.0.16(@volar/language-service@1.10.10)(prettier@3.1.0): + resolution: {integrity: sha512-Kj2ZdwJGEvfYbsHW8Sjrew/7EB4PgRoas4f8yAJzUUVxIC/kvhUwLDxQc8+N2IibomN76asJGWe+i6VZZvgIkw==} peerDependencies: '@volar/language-service': ~1.10.0 prettier: ^2.2 || ^3.0 @@ -17326,23 +16075,23 @@ packages: prettier: optional: true dependencies: - '@volar/language-service': 1.10.4 - prettier: 3.0.3 + '@volar/language-service': 1.10.10 + prettier: 3.1.0 dev: true - /volar-service-typescript-twoslash-queries@0.0.14(@volar/language-service@1.10.4): - resolution: {integrity: sha512-Lg/AcacxyBmVbZhHZwnwvt+MEn/5YlbLiJ7DJG6Dt3xiuQmpXwZmM+JE7/ZMvPt4gxW6AL9zHz21M6JSPCkJ+g==} + /volar-service-typescript-twoslash-queries@0.0.16(@volar/language-service@1.10.10): + resolution: {integrity: sha512-0gPrkDTD2bMj2AnSNykOKhfmPnBFE2LS1lF3LWA7qu1ChRnJF0sodwCCbbeNYJ9+yth956ApoU1BVQ8UrMg+yw==} peerDependencies: '@volar/language-service': ~1.10.0 peerDependenciesMeta: '@volar/language-service': optional: true dependencies: - '@volar/language-service': 1.10.4 + '@volar/language-service': 1.10.10 dev: true - /volar-service-typescript@0.0.14(@volar/language-service@1.10.4)(@volar/typescript@1.10.4): - resolution: {integrity: sha512-PGHFUbGPLE6/8ldNPO7FxwZdvRLlWBZ26RnJPCM48DBaGTc7qHGkXMtPQq5YCD10d8VwpZirz0eno8K0z+8bpg==} + /volar-service-typescript@0.0.16(@volar/language-service@1.10.10)(@volar/typescript@1.10.10): + resolution: {integrity: sha512-k/qFKM2oxs/3fhbr/vcBSHnCLZ1HN3Aeh+bGvV9Lc9qIhrNyCVsDFOUJN1Qp4dI72+Y+eFSIDCLHmFEZdsP2EA==} peerDependencies: '@volar/language-service': ~1.10.0 '@volar/typescript': ~1.10.0 @@ -17350,8 +16099,9 @@ packages: '@volar/language-service': optional: true dependencies: - '@volar/language-service': 1.10.4 - '@volar/typescript': 1.10.4 + '@volar/language-service': 1.10.10 + '@volar/typescript': 1.10.10 + path-browserify: 1.0.1 semver: 7.5.4 typescript-auto-import-cache: 0.3.0 vscode-languageserver-textdocument: 1.0.11 @@ -17368,8 +16118,8 @@ packages: vscode-uri: 3.0.8 dev: true - /vscode-html-languageservice@5.1.0: - resolution: {integrity: sha512-cGOu5+lrz+2dDXSGS15y24lDtPaML1T8K/SfqgFbLmCZ1btYOxceFieR+ybTS2es/A67kRc62m2cKFLUQPWG5g==} + /vscode-html-languageservice@5.1.1: + resolution: {integrity: sha512-JenrspIIG/Q+93R6G3L6HdK96itSisMynE0glURqHpQbL3dKAKzdm8L40lAHNkwJeBg+BBPpAshZKv/38onrTQ==} dependencies: '@vscode/l10n': 0.0.16 vscode-languageserver-textdocument: 1.0.11 @@ -17424,20 +16174,20 @@ packages: resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} dev: true - /vue@3.3.6(typescript@5.1.6): - resolution: {integrity: sha512-jJIDETeWJnoY+gfn4ZtMPMS5KtbP4ax+CT4dcQFhTnWEk8xMupFyQ0JxL28nvT/M4+p4a0ptxaV2WY0LiIxvRg==} + /vue@3.3.8(typescript@5.2.2): + resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.3.6 - '@vue/compiler-sfc': 3.3.6 - '@vue/runtime-dom': 3.3.6 - '@vue/server-renderer': 3.3.6(vue@3.3.6) - '@vue/shared': 3.3.6 - typescript: 5.1.6 + '@vue/compiler-dom': 3.3.8 + '@vue/compiler-sfc': 3.3.8 + '@vue/runtime-dom': 3.3.8 + '@vue/server-renderer': 3.3.8(vue@3.3.8) + '@vue/shared': 3.3.8 + typescript: 5.2.2 /w3c-xmlserializer@4.0.0: resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} @@ -17467,10 +16217,6 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - /webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - dev: false - /webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} @@ -17488,11 +16234,11 @@ packages: engines: {node: '>=12'} dev: true - /whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} + /whatwg-url@12.0.1: + resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==} + engines: {node: '>=14'} dependencies: - tr46: 3.0.0 + tr46: 4.1.1 webidl-conversions: 7.0.0 dev: true @@ -17502,14 +16248,6 @@ packages: tr46: 0.0.3 webidl-conversions: 3.0.1 - /whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - dev: false - /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -17518,6 +16256,7 @@ packages: is-number-object: 1.0.7 is-string: 1.0.7 is-symbol: 1.0.4 + dev: true /which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} @@ -17551,6 +16290,7 @@ packages: for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 + dev: true /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} @@ -17592,152 +16332,6 @@ packages: string-width: 5.1.2 dev: false - /workbox-background-sync@7.0.0: - resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==} - dependencies: - idb: 7.1.1 - workbox-core: 7.0.0 - dev: false - - /workbox-broadcast-update@7.0.0: - resolution: {integrity: sha512-oUuh4jzZrLySOo0tC0WoKiSg90bVAcnE98uW7F8GFiSOXnhogfNDGZelPJa+6KpGBO5+Qelv04Hqx2UD+BJqNQ==} - dependencies: - workbox-core: 7.0.0 - dev: false - - /workbox-build@7.0.0: - resolution: {integrity: sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg==} - engines: {node: '>=16.0.0'} - dependencies: - '@apideck/better-ajv-errors': 0.3.6(ajv@8.12.0) - '@babel/core': 7.23.2 - '@babel/preset-env': 7.23.2(@babel/core@7.23.2) - '@babel/runtime': 7.23.2 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.23.2)(rollup@2.79.1) - '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1) - '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) - '@surma/rollup-plugin-off-main-thread': 2.2.3 - ajv: 8.12.0 - common-tags: 1.8.2 - fast-json-stable-stringify: 2.1.0 - fs-extra: 9.1.0 - glob: 7.2.3 - lodash: 4.17.21 - pretty-bytes: 5.6.0 - rollup: 2.79.1 - rollup-plugin-terser: 7.0.2(rollup@2.79.1) - source-map: 0.8.0-beta.0 - stringify-object: 3.3.0 - strip-comments: 2.0.1 - tempy: 0.6.0 - upath: 1.2.0 - workbox-background-sync: 7.0.0 - workbox-broadcast-update: 7.0.0 - workbox-cacheable-response: 7.0.0 - workbox-core: 7.0.0 - workbox-expiration: 7.0.0 - workbox-google-analytics: 7.0.0 - workbox-navigation-preload: 7.0.0 - workbox-precaching: 7.0.0 - workbox-range-requests: 7.0.0 - workbox-recipes: 7.0.0 - workbox-routing: 7.0.0 - workbox-strategies: 7.0.0 - workbox-streams: 7.0.0 - workbox-sw: 7.0.0 - workbox-window: 7.0.0 - transitivePeerDependencies: - - '@types/babel__core' - - supports-color - dev: false - - /workbox-cacheable-response@7.0.0: - resolution: {integrity: sha512-0lrtyGHn/LH8kKAJVOQfSu3/80WDc9Ma8ng0p2i/5HuUndGttH+mGMSvOskjOdFImLs2XZIimErp7tSOPmu/6g==} - dependencies: - workbox-core: 7.0.0 - dev: false - - /workbox-core@7.0.0: - resolution: {integrity: sha512-81JkAAZtfVP8darBpfRTovHg8DGAVrKFgHpOArZbdFd78VqHr5Iw65f2guwjE2NlCFbPFDoez3D3/6ZvhI/rwQ==} - dev: false - - /workbox-expiration@7.0.0: - resolution: {integrity: sha512-MLK+fogW+pC3IWU9SFE+FRStvDVutwJMR5if1g7oBJx3qwmO69BNoJQVaMXq41R0gg3MzxVfwOGKx3i9P6sOLQ==} - dependencies: - idb: 7.1.1 - workbox-core: 7.0.0 - dev: false - - /workbox-google-analytics@7.0.0: - resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} - dependencies: - workbox-background-sync: 7.0.0 - workbox-core: 7.0.0 - workbox-routing: 7.0.0 - workbox-strategies: 7.0.0 - dev: false - - /workbox-navigation-preload@7.0.0: - resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==} - dependencies: - workbox-core: 7.0.0 - dev: false - - /workbox-precaching@7.0.0: - resolution: {integrity: sha512-EC0vol623LJqTJo1mkhD9DZmMP604vHqni3EohhQVwhJlTgyKyOkMrZNy5/QHfOby+39xqC01gv4LjOm4HSfnA==} - dependencies: - workbox-core: 7.0.0 - workbox-routing: 7.0.0 - workbox-strategies: 7.0.0 - dev: false - - /workbox-range-requests@7.0.0: - resolution: {integrity: sha512-SxAzoVl9j/zRU9OT5+IQs7pbJBOUOlriB8Gn9YMvi38BNZRbM+RvkujHMo8FOe9IWrqqwYgDFBfv6sk76I1yaQ==} - dependencies: - workbox-core: 7.0.0 - dev: false - - /workbox-recipes@7.0.0: - resolution: {integrity: sha512-DntcK9wuG3rYQOONWC0PejxYYIDHyWWZB/ueTbOUDQgefaeIj1kJ7pdP3LZV2lfrj8XXXBWt+JDRSw1lLLOnww==} - dependencies: - workbox-cacheable-response: 7.0.0 - workbox-core: 7.0.0 - workbox-expiration: 7.0.0 - workbox-precaching: 7.0.0 - workbox-routing: 7.0.0 - workbox-strategies: 7.0.0 - dev: false - - /workbox-routing@7.0.0: - resolution: {integrity: sha512-8YxLr3xvqidnbVeGyRGkaV4YdlKkn5qZ1LfEePW3dq+ydE73hUUJJuLmGEykW3fMX8x8mNdL0XrWgotcuZjIvA==} - dependencies: - workbox-core: 7.0.0 - dev: false - - /workbox-strategies@7.0.0: - resolution: {integrity: sha512-dg3qJU7tR/Gcd/XXOOo7x9QoCI9nk74JopaJaYAQ+ugLi57gPsXycVdBnYbayVj34m6Y8ppPwIuecrzkpBVwbA==} - dependencies: - workbox-core: 7.0.0 - dev: false - - /workbox-streams@7.0.0: - resolution: {integrity: sha512-moVsh+5to//l6IERWceYKGiftc+prNnqOp2sgALJJFbnNVpTXzKISlTIsrWY+ogMqt+x1oMazIdHj25kBSq/HQ==} - dependencies: - workbox-core: 7.0.0 - workbox-routing: 7.0.0 - dev: false - - /workbox-sw@7.0.0: - resolution: {integrity: sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA==} - dev: false - - /workbox-window@7.0.0: - resolution: {integrity: sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA==} - dependencies: - '@types/trusted-types': 2.0.5 - workbox-core: 7.0.0 - dev: false - /workerpool@6.2.1: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true @@ -17840,8 +16434,8 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - /yaml@2.3.3: - resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} engines: {node: '>= 14'} /yargs-parser@18.1.3: @@ -17954,5 +16548,5 @@ packages: resolution: {directory: packages/astro/test/fixtures/solid-component/deps/solid-jsx-component, type: directory} name: '@test/solid-jsx-component' dependencies: - solid-js: 1.8.3 + solid-js: 1.8.5 dev: false diff --git a/scripts/package.json b/scripts/package.json index 8e89fb97cc86c..2365867f5baca 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -9,11 +9,11 @@ }, "dependencies": { "arg": "^5.0.2", - "esbuild": "^0.19.2", - "globby": "^13.2.2", + "esbuild": "^0.19.6", + "globby": "^14.0.0", "kleur": "^4.1.4", - "p-limit": "^4.0.0", - "svelte": "^4.2.0", + "p-limit": "^5.0.0", + "svelte": "^4.2.5", "tar": "^6.1.15" }, "devDependencies": {