Merge branch 'main' of github.com:withastro/astro into add-Minification

# Conflicts:
#	pnpm-lock.yaml
This commit is contained in:
wuls 2023-04-18 18:25:07 +08:00
commit cbc2b2fd55
319 changed files with 3560 additions and 1471 deletions

View file

@ -1,5 +0,0 @@
---
'astro': patch
---
Fix: avoid calling `astro:server:setup` integration hook in production

View file

@ -1,5 +0,0 @@
---
'astro': patch
---
Fix next and previous links for index routes when using pagination

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix Astro.params does not contain path parameter from URL with non-English characters.

View file

@ -1,5 +0,0 @@
---
'@astrojs/react': patch
---
Update React README to reference the [new React docs](https://react.dev)

View file

@ -1,8 +0,0 @@
---
'@astrojs/lit': major
---
Update to use `@lit-labs/ssr@^3`
**[BREAKING]** DOM shim required for Lit SSR has been greatly reduced. `window`, `document`, and other objects are no longer available in global. Most SSR-ready component code should not be affected but, if so, they can be fixed with optional chaining or by using the `isServer` environment checker from the `lit` package. See [lit.dev docs on authoring components for SSR].(https://lit.dev/docs/ssr/authoring/#browser-only-code)
**[BREAKING]** Adds compatibility with `lit@2.7.0` hydration behavior. Do not update if you're using `lit@2.6.1` or lower.
Includes support for template[shadowrootmode] support.

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixes bug with assetsPrefix not being prepended to component-url and renderer-url in astro islands when using SSR mode.

View file

@ -1,5 +0,0 @@
---
'astro': patch
---
Improve error handling when using `astro:assets`

View file

@ -1,5 +0,0 @@
---
'@astrojs/react': patch
---
Add use-immer as a noExternal module

View file

@ -57,7 +57,7 @@ body:
id: bug-reproduction id: bug-reproduction
attributes: attributes:
label: Link to Minimal Reproducible Example label: Link to Minimal Reproducible Example
description: 'Use [astro.new](https://astro.new) to create a minimal reproduction of the problem. **A minimal reproduction is required** so that others can help debug your issue. If a report is vague (e.g. just a generic error message) and has no reproduction, it may be auto-closed.' description: 'Use [astro.new](https://astro.new) to create a minimal reproduction of the problem. **A minimal reproduction is required** so that others can help debug your issue. If a report is vague (e.g. just a generic error message) and has no reproduction, it may be auto-closed. Not sure how to create a minimal example? [Read our guide](https://docs.astro.build/en/guides/troubleshooting/#creating-minimal-reproductions)'
placeholder: 'https://stackblitz.com/abcd1234' placeholder: 'https://stackblitz.com/abcd1234'
validations: validations:
required: true required: true

View file

@ -62,12 +62,30 @@ jobs:
--header 'content-type: application/json' \ --header 'content-type: application/json' \
-d '["semver minor"]' -d '["semver minor"]'
- name: Find Comment
uses: peter-evans/find-comment@v2
id: fc
with:
issue-number: ${{ github.event.number }}
comment-author: 'github-actions[bot]'
- name: Send PR review - name: Send PR review
if: steps.find-blockers.outputs.found == 'true' if: steps.find-blockers.outputs.found == 'true'
uses: peter-evans/create-or-update-comment@v2 uses: peter-evans/create-or-update-comment@v3
continue-on-error: true continue-on-error: true
with: with:
issue-number: ${{ github.event.issue.number }} comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.number }}
body: | body: |
This PR is blocked because it contains a `minor` changeset. A reviewer will merge this at the next release if approved. This PR is blocked because it contains a `minor` changeset. A reviewer will merge this at the next release if approved.
edit-mode: replace edit-mode: replace
- name: Change PR status
if: steps.find-blockers.outputs.found == 'true'
run: |
curl --request POST \
--url https://api.github.com/repos/${{github.repository}}/pulls/${{github.event.number}}/reviews \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
-d '{"event":"REQUEST_CHANGES"}'

1
.gitignore vendored
View file

@ -30,3 +30,4 @@ packages/integrations/**/.netlify/
# ignore content collection generated files # ignore content collection generated files
packages/**/test/**/fixtures/**/.astro/ packages/**/test/**/fixtures/**/.astro/
packages/**/test/**/fixtures/**/env.d.ts packages/**/test/**/fixtures/**/env.d.ts
packages/**/e2e/**/fixtures/**/env.d.ts

View file

@ -42,13 +42,13 @@ Any static assets, like images, can be placed in the `public/` directory.
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -52,13 +52,13 @@ Any static assets, like images, can be placed in the `public/` directory.
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"@astrojs/mdx": "^0.18.2", "@astrojs/mdx": "^0.19.0",
"@astrojs/rss": "^2.3.1", "@astrojs/rss": "^2.3.2",
"@astrojs/sitemap": "^1.2.1" "@astrojs/sitemap": "^1.2.2"
} }
} }

View file

@ -15,7 +15,7 @@
], ],
"scripts": {}, "scripts": {},
"devDependencies": { "devDependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "^2.0.0-beta.0" "astro": "^2.0.0-beta.0"

View file

@ -41,14 +41,14 @@ Any static assets, like images, can be placed in the `public/` directory.
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| | (preview uses Deno CLI) | | | (preview uses Deno CLI) |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/deno": "^4.1.0" "@astrojs/deno": "^4.1.0"

View file

@ -28,13 +28,13 @@ npm create astro@latest -- --template docs
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
To deploy your site to production, check out our [Deploy an Astro Website](https://docs.astro.build/guides/deploy) guide. To deploy your site to production, check out our [Deploy an Astro Website](https://docs.astro.build/guides/deploy) guide.

View file

@ -11,11 +11,11 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"preact": "^10.7.3", "preact": "^10.7.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"@astrojs/react": "^2.1.0", "@astrojs/react": "^2.1.1",
"@astrojs/preact": "^2.1.0", "@astrojs/preact": "^2.1.0",
"@algolia/client-search": "^4.13.1", "@algolia/client-search": "^4.13.1",
"@docsearch/css": "^3.1.0", "@docsearch/css": "^3.1.0",

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"alpinejs": "^3.10.2", "alpinejs": "^3.10.2",
"@astrojs/alpinejs": "^0.2.1", "@astrojs/alpinejs": "^0.2.1",
"@types/alpinejs": "^3.7.0" "@types/alpinejs": "^3.7.0"

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"lit": "^2.7.0", "lit": "^2.7.0",
"@astrojs/lit": "^1.3.0", "@astrojs/lit": "^2.0.1",
"@webcomponents/template-shadowroot": "^0.2.1" "@webcomponents/template-shadowroot": "^0.2.1"
} }
} }

View file

@ -8,6 +8,6 @@ npm create astro@latest -- --template framework-multiple
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/framework-multiple) [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/framework-multiple)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/framework-multiple/devcontainer.json) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/framework-multiple/devcontainer.json)
This example showcases Astro's built-in support for multiple frameworks ([React](https://reactjs.org), [Preact](https://preactjs.com), [Svelte](https://svelte.dev), and [Vue (`v3.x`)](https://v3.vuejs.org/)). This example showcases Astro's built-in support for multiple frameworks ([React](https://react.dev), [Preact](https://preactjs.com), [Svelte](https://svelte.dev), and [Vue (`v3.x`)](https://v3.vuejs.org/)).
No configuration is needed to enable these frameworks—just start writing components in `src/components`. No configuration is needed to enable these frameworks—just start writing components in `src/components`.

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"preact": "^10.7.3", "preact": "^10.7.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
@ -19,9 +19,9 @@
"svelte": "^3.48.0", "svelte": "^3.48.0",
"vue": "^3.2.37", "vue": "^3.2.37",
"@astrojs/preact": "^2.1.0", "@astrojs/preact": "^2.1.0",
"@astrojs/react": "^2.1.0", "@astrojs/react": "^2.1.1",
"@astrojs/solid-js": "^2.1.0", "@astrojs/solid-js": "^2.1.0",
"@astrojs/svelte": "^2.1.0", "@astrojs/svelte": "^2.1.0",
"@astrojs/vue": "^2.1.0" "@astrojs/vue": "^2.1.1"
} }
} }

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"preact": "^10.7.3", "preact": "^10.7.3",
"@astrojs/preact": "^2.1.0", "@astrojs/preact": "^2.1.0",
"@preact/signals": "^1.1.0" "@preact/signals": "^1.1.0"

View file

@ -8,6 +8,6 @@ npm create astro@latest -- --template framework-react
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/framework-react) [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/framework-react)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/framework-react/devcontainer.json) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/framework-react/devcontainer.json)
This example showcases Astro working with [React](https://reactjs.org/). This example showcases Astro working with [React](https://react.dev).
Write your React components as `.jsx` or `.tsx` files in your project. Write your React components as `.jsx` or `.tsx` files in your project.

View file

@ -11,10 +11,10 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"@astrojs/react": "^2.1.0", "@astrojs/react": "^2.1.1",
"@types/react": "^18.0.10", "@types/react": "^18.0.10",
"@types/react-dom": "^18.0.5" "@types/react-dom": "^18.0.5"
} }

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"solid-js": "^1.4.3", "solid-js": "^1.4.3",
"@astrojs/solid-js": "^2.1.0" "@astrojs/solid-js": "^2.1.0"
} }

View file

@ -13,6 +13,6 @@
"dependencies": { "dependencies": {
"svelte": "^3.48.0", "svelte": "^3.48.0",
"@astrojs/svelte": "^2.1.0", "@astrojs/svelte": "^2.1.0",
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"vue": "^3.2.37", "vue": "^3.2.37",
"@astrojs/vue": "^2.1.0" "@astrojs/vue": "^2.1.1"
} }
} }

View file

@ -46,13 +46,13 @@ This project uses the [`@astrojs/node`](https://docs.astro.build/en/guides/integ
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^5.1.0", "@astrojs/node": "^5.1.1",
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -15,7 +15,7 @@
], ],
"scripts": {}, "scripts": {},
"devDependencies": { "devDependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "^2.0.0-beta.0" "astro": "^2.0.0-beta.0"

View file

@ -34,13 +34,13 @@ Any static assets, like images, can be placed in the `public/` directory.
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -39,13 +39,13 @@ Any static assets, like images, can be placed in the `public/` directory.
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -18,13 +18,13 @@ npm create astro@latest -- --template portfolio
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -12,10 +12,10 @@
"server": "node dist/server/entry.mjs" "server": "node dist/server/entry.mjs"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"svelte": "^3.48.0", "svelte": "^3.48.0",
"@astrojs/svelte": "^2.1.0", "@astrojs/svelte": "^2.1.0",
"@astrojs/node": "^5.1.0", "@astrojs/node": "^5.1.1",
"concurrently": "^7.2.1", "concurrently": "^7.2.1",
"unocss": "^0.15.6", "unocss": "^0.15.6",
"vite-imagetools": "^4.0.4" "vite-imagetools": "^4.0.4"

View file

@ -43,13 +43,13 @@ You can also render Astro components from your Markdoc files using [tags](https:
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/markdoc": "^0.1.0", "@astrojs/markdoc": "^0.1.1",
"astro": "^2.1.8", "astro": "^2.3.0",
"kleur": "^4.1.5" "kleur": "^4.1.5"
} }
} }

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"@astrojs/markdown-remark": "^2.1.2", "@astrojs/markdown-remark": "^2.1.4",
"hast-util-select": "5.0.1", "hast-util-select": "5.0.1",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.0.1", "rehype-slug": "^5.0.1",

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8" "astro": "^2.3.0"
} }
} }

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"preact": "^10.6.5", "preact": "^10.6.5",
"@astrojs/preact": "^2.1.0", "@astrojs/preact": "^2.1.0",
"@astrojs/mdx": "^0.18.2" "@astrojs/mdx": "^0.19.0"
} }
} }

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"preact": "^10.7.3", "preact": "^10.7.3",
"@astrojs/preact": "^2.1.0", "@astrojs/preact": "^2.1.0",
"nanostores": "^0.5.12", "nanostores": "^0.5.12",

View file

@ -11,10 +11,10 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^0.18.2", "@astrojs/mdx": "^0.19.0",
"@astrojs/tailwind": "^3.1.1", "@astrojs/tailwind": "^3.1.1",
"@types/canvas-confetti": "^1.4.3", "@types/canvas-confetti": "^1.4.3",
"astro": "^2.1.8", "astro": "^2.3.0",
"autoprefixer": "^10.4.7", "autoprefixer": "^10.4.7",
"canvas-confetti": "^1.5.1", "canvas-confetti": "^1.5.1",
"postcss": "^8.4.14", "postcss": "^8.4.14",

View file

@ -34,13 +34,13 @@ Any static assets, like images, can be placed in the `public/` directory.
All commands are run from the root of the project, from a terminal: All commands are run from the root of the project, from a terminal:
| Command | Action | | Command | Action |
| :--------------------- | :----------------------------------------------- | | :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies | | `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` | | `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` | | `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying | | `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI | | `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ## 👀 Want to learn more?

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"vite-plugin-pwa": "0.11.11", "vite-plugin-pwa": "0.11.11",
"workbox-window": "^6.5.3" "workbox-window": "^6.5.3"
} }

View file

@ -12,7 +12,7 @@
"test": "vitest" "test": "vitest"
}, },
"dependencies": { "dependencies": {
"astro": "^2.1.8", "astro": "^2.3.0",
"vitest": "^0.20.3" "vitest": "^0.20.3"
} }
} }

View file

@ -41,9 +41,9 @@
], ],
"engines": { "engines": {
"node": ">=16.12.0", "node": ">=16.12.0",
"pnpm": ">=7.9.5" "pnpm": ">=8.2.0"
}, },
"packageManager": "pnpm@7.12.2", "packageManager": "pnpm@8.2.0",
"pnpm": { "pnpm": {
"packageExtensions": { "packageExtensions": {
"svelte2tsx": { "svelte2tsx": {
@ -84,19 +84,19 @@
"@changesets/cli": "2.23.0", "@changesets/cli": "2.23.0",
"@octokit/action": "^3.18.1", "@octokit/action": "^3.18.1",
"@types/node": "^18.7.21", "@types/node": "^18.7.21",
"@typescript-eslint/eslint-plugin": "^5.55.0", "@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.55.0", "@typescript-eslint/parser": "^5.58.0",
"del": "^7.0.0", "del": "^7.0.0",
"esbuild": "^0.17.12", "esbuild": "^0.17.12",
"eslint": "^8.17.0", "eslint": "^8.38.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.8.0",
"eslint-plugin-no-only-tests": "^2.6.0", "eslint-plugin-no-only-tests": "^2.6.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.2.1",
"execa": "^6.1.0", "execa": "^6.1.0",
"only-allow": "^1.1.1", "only-allow": "^1.1.1",
"organize-imports-cli": "^0.10.0", "organize-imports-cli": "^0.10.0",
"prettier": "^2.7.0", "prettier": "^2.8.7",
"prettier-plugin-astro": "^0.7.0", "prettier-plugin-astro": "^0.8.0",
"pretty-bytes": "^6.0.0", "pretty-bytes": "^6.0.0",
"tiny-glob": "^0.2.9", "tiny-glob": "^0.2.9",
"turbo": "1.2.5", "turbo": "1.2.5",

View file

@ -1,5 +1,11 @@
# @astrojs/rss # @astrojs/rss
## 2.3.2
### Patch Changes
- [#6614](https://github.com/withastro/astro/pull/6614) [`b1b9b1390`](https://github.com/withastro/astro/commit/b1b9b1390f95c6ae91389eba55f7563b911bccc7) Thanks [@aivarsliepa](https://github.com/aivarsliepa)! - Fixes `RSSOptions` type error when using `strictest` Typescript tsconfig
## 2.3.1 ## 2.3.1
### Patch Changes ### Patch Changes

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/rss", "name": "@astrojs/rss",
"description": "Add RSS feeds to your Astro projects", "description": "Add RSS feeds to your Astro projects",
"version": "2.3.1", "version": "2.3.2",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",

View file

@ -36,7 +36,7 @@ type RSSFeedItem = {
/** Link to item */ /** Link to item */
link: string; link: string;
/** Full content of the item. Should be valid HTML */ /** Full content of the item. Should be valid HTML */
content?: string; content?: string | undefined;
/** Title of item */ /** Title of item */
title: z.infer<typeof rssSchema>['title']; title: z.infer<typeof rssSchema>['title'];
/** Publication date of item */ /** Publication date of item */

View file

@ -1,5 +1,129 @@
# astro # astro
## 2.3.0
### Minor Changes
- [#6816](https://github.com/withastro/astro/pull/6816) [`8539eb164`](https://github.com/withastro/astro/commit/8539eb1643864ae7e0f5a080915cd75535f7101b) Thanks [@bluwy](https://github.com/bluwy)! - Support tsconfig aliases in CSS `@import`
### Patch Changes
- [#6544](https://github.com/withastro/astro/pull/6544) [`a9c22994e`](https://github.com/withastro/astro/commit/a9c22994e41f92a586d8946988d29e3c62148778) Thanks [@wulinsheng123](https://github.com/wulinsheng123)! - Correctly generate directories for assets when users customise the output via rollup options.
- [#6825](https://github.com/withastro/astro/pull/6825) [`948a6d7be`](https://github.com/withastro/astro/commit/948a6d7be0c76fd1dd8550270bd29821075f799c) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix unnecessary warning when using images inside the `src/content` folder with `experimental.assets`
- Updated dependencies [[`2511d58d5`](https://github.com/withastro/astro/commit/2511d58d586af080a78e5ef8a63020b3e17770db)]:
- @astrojs/markdown-remark@2.1.4
## 2.2.3
### Patch Changes
- [#6765](https://github.com/withastro/astro/pull/6765) [`6c09ac03b`](https://github.com/withastro/astro/commit/6c09ac03bf8f77ca9c1279dce570e0dcf3d439e3) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Properly include the needed WASM files for the Squoosh service for Netlify and Vercel in SSR
- [#6817](https://github.com/withastro/astro/pull/6817) [`f882bc163`](https://github.com/withastro/astro/commit/f882bc1636d5ce1c3b8faae47df36b4dc758045a) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix sourcemap warnings when using Content Collections and MDX with the `vite.build.sourcemap` option
- [#6819](https://github.com/withastro/astro/pull/6819) [`76dd53e3f`](https://github.com/withastro/astro/commit/76dd53e3f69d596754795710a457a1e570a3bad4) Thanks [@MoustaphaDev](https://github.com/MoustaphaDev)! - Fix fallback content showing unexpectedly in some cases
- [#6582](https://github.com/withastro/astro/pull/6582) [`7653cf9e9`](https://github.com/withastro/astro/commit/7653cf9e9fedc6edc6038603248351e276191c3a) Thanks [@bluwy](https://github.com/bluwy)! - Fix CSS chunking and deduping between multiple Astro files and framework components
## 2.2.2
### Patch Changes
- [#6811](https://github.com/withastro/astro/pull/6811) [`60c16db6f`](https://github.com/withastro/astro/commit/60c16db6ff583b0656bc1937814c8bbf06831294) Thanks [@bluwy](https://github.com/bluwy)! - Fix check CLI fs load fallback behaviour
- [#6782](https://github.com/withastro/astro/pull/6782) [`c12ca5ece`](https://github.com/withastro/astro/commit/c12ca5ece34beef0fb53f911515a7c752cc2f3ad) Thanks [@amirhhashemi](https://github.com/amirhhashemi)! - Force error overlay direction to be LTR
## 2.2.1
### Patch Changes
- [#6766](https://github.com/withastro/astro/pull/6766) [`72fed684a`](https://github.com/withastro/astro/commit/72fed684a35f00d80c69bcf6e8af297fed0294fe) Thanks [@Xetera](https://github.com/Xetera)! - Exporting the ImageFunction in astro:content and grouping it under a SchemaContext
- [#6772](https://github.com/withastro/astro/pull/6772) [`45bff6fcc`](https://github.com/withastro/astro/commit/45bff6fccb3f5c71ff24c1ceb48cd532196c90f6) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Allow `import.meta.env` values of `0`, `1`, `true`, and `false` to be used for `export const prerender` statements
- [#6770](https://github.com/withastro/astro/pull/6770) [`52d7a4a01`](https://github.com/withastro/astro/commit/52d7a4a011a3bb722b522fffd88c5fe9a519a196) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Updated types to match newer Vite versions
- [#6774](https://github.com/withastro/astro/pull/6774) [`9e88e0f23`](https://github.com/withastro/astro/commit/9e88e0f23c5913c07f7e3e96fa0555219ef710dc) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix: remove old `slug()` type from `defineCollection()` helper
- [#6775](https://github.com/withastro/astro/pull/6775) [`fa84f1a7d`](https://github.com/withastro/astro/commit/fa84f1a7d2c290479c75199f16e8de489036d7ea) Thanks [@matthewp](https://github.com/matthewp)! - Support streaming inside of slots
- [#6779](https://github.com/withastro/astro/pull/6779) [`a98f6f418`](https://github.com/withastro/astro/commit/a98f6f418c92261a06ef79624a8c86e288c21eab) Thanks [@matthewp](https://github.com/matthewp)! - Prevent body head content injection in MDX when using layout
- [#6781](https://github.com/withastro/astro/pull/6781) [`7f74326b7`](https://github.com/withastro/astro/commit/7f74326b762bfc174ebe8e37ae03733563e4214f) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix `astro:server:setup` middlewares not applying. This resolves an issue with the Partytown integration in dev.
## 2.2.0
### Minor Changes
- [#6703](https://github.com/withastro/astro/pull/6703) [`a1108e037`](https://github.com/withastro/astro/commit/a1108e037115cdb67d03505286c7d3a4fc2a1ff5) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Move `image()` to come from `schema` instead to fix it not working with refine and inside complex types
**Migration**:
Remove the `image` import from `astro:content`, and instead use a function to generate your schema, like such:
```ts
import { defineCollection, z } from 'astro:content';
defineCollection({
schema: ({ image }) =>
z.object({
image: image().refine((img) => img.width >= 200, {
message: 'image too small',
}),
}),
});
```
- [#6714](https://github.com/withastro/astro/pull/6714) [`ff0430786`](https://github.com/withastro/astro/commit/ff043078630e678348ae4f4757b3015b3b862c16) Thanks [@bluwy](https://github.com/bluwy)! - Add `build.assetsPrefix` option for CDN support. If set, all Astro-generated asset links will be prefixed with it. For example, setting it to `https://cdn.example.com` would generate `https://cdn.example.com/_astro/penguin.123456.png` links.
Also adds `import.meta.env.ASSETS_PREFIX` environment variable that can be used to manually create asset links not handled by Astro.
### Patch Changes
- [#6753](https://github.com/withastro/astro/pull/6753) [`489dd8d69`](https://github.com/withastro/astro/commit/489dd8d69cdd9d7c243cf8bec96051a914984b9c) Thanks [@bluwy](https://github.com/bluwy)! - Fix `getViteConfig` return type
- [#6744](https://github.com/withastro/astro/pull/6744) [`a1a4f45b5`](https://github.com/withastro/astro/commit/a1a4f45b51a80215fa7598da83bd0d9c5acd20d2) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix remote images in Markdown throwing errors when using `experimental.assets`
- [#6762](https://github.com/withastro/astro/pull/6762) [`8b88e4cf1`](https://github.com/withastro/astro/commit/8b88e4cf15c8bea7942b3985380164e0edf7250b) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Improved error message when an error was encountered while generating types
- [#6719](https://github.com/withastro/astro/pull/6719) [`d54cbe413`](https://github.com/withastro/astro/commit/d54cbe41349e55f8544212ad9320705f07325920) Thanks [@matthewp](https://github.com/matthewp)! - Better errors for when response is already sent
This adds clearer error messaging when a Response has already been sent to the browser and the developer attempts to use:
- Astro.cookies.set
- Astro.redirect
- [#6741](https://github.com/withastro/astro/pull/6741) [`4c347ab51`](https://github.com/withastro/astro/commit/4c347ab51e46f2319d614f8577fe502e3dc816e2) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix content-type header being wrong in dev on images from `astro:assets`
- [#6739](https://github.com/withastro/astro/pull/6739) [`2f2e572e9`](https://github.com/withastro/astro/commit/2f2e572e937fd25451bbc78a05d55b7caa1ca3ec) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Added more types and utilities exports related to `astro:assets` to help building custom image components and image services
- [#6759](https://github.com/withastro/astro/pull/6759) [`7116c021a`](https://github.com/withastro/astro/commit/7116c021a39eac15a6e1264dfbd11bef0f5d618a) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4.2
- Updated dependencies [[`a1a4f45b5`](https://github.com/withastro/astro/commit/a1a4f45b51a80215fa7598da83bd0d9c5acd20d2)]:
- @astrojs/markdown-remark@2.1.3
## 2.1.9
### Patch Changes
- [#6693](https://github.com/withastro/astro/pull/6693) [`c0b7864a4`](https://github.com/withastro/astro/commit/c0b7864a41dd9f31e5a588208d1ff806d4edf047) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix: avoid calling `astro:server:setup` integration hook in production
- [#6676](https://github.com/withastro/astro/pull/6676) [`5e33c51a9`](https://github.com/withastro/astro/commit/5e33c51a9c3c3b731a33f2c4a020a36d1471b78b) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix next and previous links for index routes when using pagination
- [#6717](https://github.com/withastro/astro/pull/6717) [`c2d4ae1cb`](https://github.com/withastro/astro/commit/c2d4ae1cbed622b2fadeb1fe8cc8bbed5f5adc8f) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Dynamically import check command to improve startup speed and prevent Astro from crashing due to language-server stuff
- [#6679](https://github.com/withastro/astro/pull/6679) [`08e92f4f8`](https://github.com/withastro/astro/commit/08e92f4f8ece50e377af5b0caca4ad789e0f23c1) Thanks [@fcFn](https://github.com/fcFn)! - Fix incorrect path to file in error overlay on Win
- [#6649](https://github.com/withastro/astro/pull/6649) [`f0b732d32`](https://github.com/withastro/astro/commit/f0b732d326c609208f30485b9805a84a321a870e) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Improve error handling when using `astro:assets`
- [#6710](https://github.com/withastro/astro/pull/6710) [`a0bdf4ce2`](https://github.com/withastro/astro/commit/a0bdf4ce2f36a0ce7045dc9f96c15dc7d9204c47) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix multiple Image / getImage calls with the same image causing multiple duplicate images to be generated
- [#6711](https://github.com/withastro/astro/pull/6711) [`c04ea0d43`](https://github.com/withastro/astro/commit/c04ea0d43cc2aa8ebe520a1def19dd89828cf662) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix InferGetStaticParamsType and InferGetStaticPropsType not working when getStaticPaths wasn't async
- [#6701](https://github.com/withastro/astro/pull/6701) [`46ecf4662`](https://github.com/withastro/astro/commit/46ecf466281450caedff5915cecde7a9fe3fdde0) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Remove unnecessary `.wasm` files inside build output when possible
## 2.1.8 ## 2.1.8
### Patch Changes ### Patch Changes

View file

@ -178,6 +178,10 @@ declare module '*.module.pcss' {
const classes: CSSModuleClasses; const classes: CSSModuleClasses;
export default classes; export default classes;
} }
declare module '*.module.sss' {
const classes: CSSModuleClasses;
export default classes;
}
// CSS // CSS
declare module '*.css' { declare module '*.css' {
@ -208,9 +212,31 @@ declare module '*.pcss' {
const css: string; const css: string;
export default css; export default css;
} }
declare module '*.sss' {
const css: string;
export default css;
}
// Built-in asset types // Built-in asset types
// see `src/constants.ts` // see `src/node/constants.ts`
// images
declare module '*.jfif' {
const src: string;
export default src;
}
declare module '*.pjpeg' {
const src: string;
export default src;
}
declare module '*.pjp' {
const src: string;
export default src;
}
declare module '*.ico' {
const src: string;
export default src;
}
// media // media
declare module '*.mp4' { declare module '*.mp4' {
@ -242,6 +268,11 @@ declare module '*.aac' {
export default src; export default src;
} }
declare module '*.opus' {
const src: string;
export default src;
}
// fonts // fonts
declare module '*.woff' { declare module '*.woff' {
const src: string; const src: string;
@ -265,10 +296,6 @@ declare module '*.otf' {
} }
// other // other
declare module '*.wasm' {
const initWasm: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports>;
export default initWasm;
}
declare module '*.webmanifest' { declare module '*.webmanifest' {
const src: string; const src: string;
export default src; export default src;
@ -282,6 +309,12 @@ declare module '*.txt' {
export default src; export default src;
} }
// wasm?init
declare module '*.wasm?init' {
const initWasm: (options: WebAssembly.Imports) => Promise<WebAssembly.Instance>;
export default initWasm;
}
// web worker // web worker
declare module '*?worker' { declare module '*?worker' {
const workerConstructor: { const workerConstructor: {
@ -297,6 +330,11 @@ declare module '*?worker&inline' {
export default workerConstructor; export default workerConstructor;
} }
declare module '*?worker&url' {
const src: string;
export default src;
}
declare module '*?sharedworker' { declare module '*?sharedworker' {
const sharedWorkerConstructor: { const sharedWorkerConstructor: {
new (): SharedWorker; new (): SharedWorker;
@ -304,6 +342,18 @@ declare module '*?sharedworker' {
export default sharedWorkerConstructor; export default sharedWorkerConstructor;
} }
declare module '*?sharedworker&inline' {
const sharedWorkerConstructor: {
new (): SharedWorker;
};
export default sharedWorkerConstructor;
}
declare module '*?sharedworker&url' {
const src: string;
export default src;
}
declare module '*?raw' { declare module '*?raw' {
const src: string; const src: string;
export default src; export default src;

View file

@ -1,4 +1,5 @@
type ViteUserConfig = import('vite').UserConfig; type ViteUserConfig = import('vite').UserConfig;
type ViteUserConfigFn = import('vite').UserConfigFn;
type AstroUserConfig = import('./dist/@types/astro.js').AstroUserConfig; type AstroUserConfig = import('./dist/@types/astro.js').AstroUserConfig;
/** /**
@ -10,4 +11,4 @@ export function defineConfig(config: AstroUserConfig): AstroUserConfig;
/** /**
* Use Astro to generate a fully resolved Vite config * Use Astro to generate a fully resolved Vite config
*/ */
export function getViteConfig(config: ViteUserConfig): ViteUserConfig; export function getViteConfig(config: ViteUserConfig): ViteUserConfigFn;

View file

@ -52,6 +52,28 @@ test.describe('Error display', () => {
expect(await page.locator('vite-error-overlay').count()).toEqual(0); expect(await page.locator('vite-error-overlay').count()).toEqual(0);
}); });
test('shows correct file path when a page has an error', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/import-not-found'));
const { fileLocation, absoluteFileLocation } = await getErrorOverlayContent(page);
const absoluteFileUrl = 'file://' + absoluteFileLocation.replace(/:\d+:\d+$/, '');
const fileExists = astro.pathExists(absoluteFileUrl);
expect(fileExists).toBeTruthy();
expect(fileLocation).toMatch(/^pages\/import-not-found\.astro/);
});
test('shows correct file path when a component has an error', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/preact-runtime-error'));
const { fileLocation, absoluteFileLocation } = await getErrorOverlayContent(page);
const absoluteFileUrl = 'file://' + absoluteFileLocation.replace(/:\d+:\d+$/, '');
const fileExists = astro.pathExists(absoluteFileUrl);
expect(fileExists).toBeTruthy();
expect(fileLocation).toMatch(/^components\/PreactRuntimeError.jsx/);
});
test('framework errors recover when fixed', async ({ page, astro }) => { test('framework errors recover when fixed', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/svelte-syntax-error')); await page.goto(astro.resolveUrl('/svelte-syntax-error'));

View file

@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "workspace:*",
"@e2e/astro-linked-lib": "link:../_deps/astro-linked-lib", "@e2e/astro-linked-lib": "link:../_deps/astro-linked-lib",
"astro": "workspace:*", "astro": "workspace:*",
"preact": "^10.11.0" "preact": "^10.11.0"

View file

@ -1,5 +1,5 @@
{ {
"name": "@test/astro-envs", "name": "@e2e/astro-envs",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {

View file

@ -1,5 +1,5 @@
{ {
"name": "@e2e/preact-component", "name": "@e2e/preact-compat-component",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {

View file

@ -1,5 +1,5 @@
{ {
"name": "@test/vue-component", "name": "@e2e/vue-component",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {

View file

@ -0,0 +1,19 @@
<script setup lang="ts">
import {onMounted, ref} from 'vue'
const props = defineProps(['id'])
/** The top-level await causes event handling to not work (button click) */
await new Promise((resolve) => setTimeout(resolve, 10));
const a = ref(1);
onMounted(()=>{
a.value = 2
})
</script>
<template>
<div :id="props.id">
{{ a }}
</div>
</template>

View file

@ -1,6 +1,7 @@
--- ---
import Counter from '../components/Counter.vue'; import Counter from '../components/Counter.vue';
import VueComponent from '../components/VueComponent.vue'; import VueComponent from '../components/VueComponent.vue';
import AsyncTest from '../components/Test.vue'
const someProps = { const someProps = {
count: 0, count: 0,
@ -33,5 +34,6 @@ const someProps = {
</Counter> </Counter>
<VueComponent id="client-only" client:only="vue" /> <VueComponent id="client-only" client:only="vue" />
<AsyncTest id="client-test" client:only="vue" />
</body> </body>
</html> </html>

View file

@ -1,6 +1,7 @@
export { default } from '../components/Layout.astro'; export { default } from '../components/Layout.astro';
import Counter from '../components/Counter.vue'; import Counter from '../components/Counter.vue';
import VueComponent from '../components/VueComponent.vue'; import VueComponent from '../components/VueComponent.vue';
import AsyncTest from '../components/Test.vue';
export const someProps = { export const someProps = {
count: 0, count: 0,
@ -27,3 +28,5 @@ export const someProps = {
</Counter> </Counter>
<VueComponent id="client-only" client:only="vue" /> <VueComponent id="client-only" client:only="vue" />
<AsyncTest id="client-test" client:only="vue" />

View file

@ -35,7 +35,7 @@ export function testFactory(inlineConfig) {
/** /**
* *
* @param {string} page * @param {string} page
* @returns {Promise<{message: string, hint: string}>} * @returns {Promise<{message: string, hint: string, absoluteFileLocation: string, fileLocation: string}>}
*/ */
export async function getErrorOverlayContent(page) { export async function getErrorOverlayContent(page) {
const overlay = await page.waitForSelector('vite-error-overlay', { const overlay = await page.waitForSelector('vite-error-overlay', {
@ -47,8 +47,11 @@ export async function getErrorOverlayContent(page) {
const message = await overlay.$$eval('#message-content', (m) => m[0].textContent); const message = await overlay.$$eval('#message-content', (m) => m[0].textContent);
const hint = await overlay.$$eval('#hint-content', (m) => m[0].textContent); const hint = await overlay.$$eval('#hint-content', (m) => m[0].textContent);
const [absoluteFileLocation, fileLocation] = await overlay.$$eval('#code header h2', (m) => [
return { message, hint }; m[0].title,
m[0].textContent,
]);
return { message, hint, absoluteFileLocation, fileLocation };
} }
/** /**

View file

@ -1,5 +1,5 @@
import { prepareTestFactory } from './shared-component-tests.js'; import { prepareTestFactory } from './shared-component-tests.js';
import { expect } from '@playwright/test';
const { test, createTests } = prepareTestFactory({ root: './fixtures/vue-component/' }); const { test, createTests } = prepareTestFactory({ root: './fixtures/vue-component/' });
const config = { const config = {
@ -23,3 +23,19 @@ test.describe('Vue components in MDX files', () => {
pageSourceFilePath: './src/pages/mdx.mdx', pageSourceFilePath: './src/pages/mdx.mdx',
}); });
}); });
test('test the async vue component in astro', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));
const label = page.locator('#client-test');
await expect(label, 'component not hydrated').toHaveText('2');
});
test('test the async vue component in mdx', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/mdx/'));
const label = page.locator('#client-test');
await expect(label, 'component not hydrated').toHaveText('2');
});

View file

@ -1,6 +1,6 @@
{ {
"name": "astro", "name": "astro",
"version": "2.1.8", "version": "2.3.0",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
"type": "module", "type": "module",
"author": "withastro", "author": "withastro",
@ -107,9 +107,9 @@
"test:e2e:match": "playwright test -g" "test:e2e:match": "playwright test -g"
}, },
"dependencies": { "dependencies": {
"@astrojs/compiler": "^1.3.0", "@astrojs/compiler": "^1.3.1",
"@astrojs/language-server": "^0.28.3", "@astrojs/language-server": "^0.28.3",
"@astrojs/markdown-remark": "^2.1.2", "@astrojs/markdown-remark": "^2.1.4",
"@astrojs/telemetry": "^2.1.0", "@astrojs/telemetry": "^2.1.0",
"@astrojs/webapi": "^2.1.0", "@astrojs/webapi": "^2.1.0",
"@babel/core": "^7.18.2", "@babel/core": "^7.18.2",
@ -156,10 +156,10 @@
"typescript": "*", "typescript": "*",
"unist-util-visit": "^4.1.0", "unist-util-visit": "^4.1.0",
"vfile": "^5.3.2", "vfile": "^5.3.2",
"vite": "^4.1.2", "vite": "^4.2.1",
"vitefu": "^0.2.4", "vitefu": "^0.2.4",
"yargs-parser": "^21.0.1", "yargs-parser": "^21.0.1",
"zod": "^3.17.3" "zod": "^3.20.6"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.29.2", "@playwright/test": "^1.29.2",

View file

@ -14,11 +14,11 @@
"author": "", "author": "",
"license": "unlicensed", "license": "unlicensed",
"dependencies": { "dependencies": {
"@astrojs/react": "^2.0.2", "@astrojs/react": "workspace:*",
"@performance/utils": "^0.0.0", "@performance/utils": "workspace:*",
"@types/react": "^18.0.21", "@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"astro": "^2.0.12", "astro": "workspace:*",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0" "react-dom": "^18.0.0"
} }

View file

@ -14,12 +14,12 @@
"author": "", "author": "",
"license": "unlicensed", "license": "unlicensed",
"dependencies": { "dependencies": {
"@astrojs/markdoc": "^0.0.0-markdoc-20230302210326", "@astrojs/markdoc": "workspace:*",
"@astrojs/react": "^2.0.2", "@astrojs/react": "workspace:*",
"@performance/utils": "^0.0.0", "@performance/utils": "workspace:*",
"@types/react": "^18.0.21", "@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"astro": "^2.0.12", "astro": "workspace:*",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0" "react-dom": "^18.0.0"
} }

View file

@ -14,12 +14,12 @@
"author": "", "author": "",
"license": "unlicensed", "license": "unlicensed",
"dependencies": { "dependencies": {
"@astrojs/mdx": "^0.17.2", "@astrojs/mdx": "workspace:*",
"@astrojs/react": "^2.0.2", "@astrojs/react": "workspace:*",
"@performance/utils": "^0.0.0", "@performance/utils": "workspace:*",
"@types/react": "^18.0.21", "@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"astro": "^2.0.12", "astro": "workspace:*",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0" "react-dom": "^18.0.0"
} }

View file

@ -9,7 +9,7 @@
"author": "", "author": "",
"license": "unlicensed", "license": "unlicensed",
"devDependencies": { "devDependencies": {
"astro": "^2.0.12", "astro": "workspace:*",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0"
}, },

View file

@ -30,8 +30,20 @@ export type {
RemarkPlugins, RemarkPlugins,
ShikiConfig, ShikiConfig,
} from '@astrojs/markdown-remark'; } from '@astrojs/markdown-remark';
export type { ExternalImageService, LocalImageService } from '../assets/services/service'; export type {
export type { ImageMetadata, ImageTransform } from '../assets/types'; ExternalImageService,
ImageService,
LocalImageService,
} from '../assets/services/service';
export type {
GetImageResult,
ImageInputFormat,
ImageMetadata,
ImageOutputFormat,
ImageQuality,
ImageQualityPreset,
ImageTransform,
} from '../assets/types';
export type { SSRManifest } from '../core/app/types'; export type { SSRManifest } from '../core/app/types';
export type { AstroCookies } from '../core/cookies'; export type { AstroCookies } from '../core/cookies';
@ -629,6 +641,29 @@ export interface AstroUserConfig {
* ``` * ```
*/ */
assets?: string; assets?: string;
/**
* @docs
* @name build.assetsPrefix
* @type {string}
* @default `undefined`
* @version 2.2.0
* @description
* Specifies the prefix for Astro-generated asset links. This can be used if assets are served from a different domain than the current site.
*
* For example, if this is set to `https://cdn.example.com`, assets will be fetched from `https://cdn.example.com/_astro/...` (regardless of the `base` option).
* You would need to upload the files in `./dist/_astro/` to `https://cdn.example.com/_astro/` to serve the assets.
* The process varies depending on how the third-party domain is hosted.
* To rename the `_astro` path, specify a new directory in `build.assets`.
*
* ```js
* {
* build: {
* assetsPrefix: 'https://cdn.example.com'
* }
* }
* ```
*/
assetsPrefix?: string;
/** /**
* @docs * @docs
* @name build.serverEntry * @name build.serverEntry
@ -1214,11 +1249,13 @@ export type GetStaticPaths = (
* *
* @example * @example
* ```ts * ```ts
* export async function getStaticPaths() { * import type { GetStaticPaths } from 'astro';
*
* export const getStaticPaths = (() => {
* return results.map((entry) => ({ * return results.map((entry) => ({
* params: { slug: entry.slug }, * params: { slug: entry.slug },
* })); * }));
* } * }) satisfies GetStaticPaths;
* *
* type Params = InferGetStaticParamsType<typeof getStaticPaths>; * type Params = InferGetStaticParamsType<typeof getStaticPaths>;
* // ^? { slug: string; } * // ^? { slug: string; }
@ -1226,7 +1263,7 @@ export type GetStaticPaths = (
* const { slug } = Astro.params as Params; * const { slug } = Astro.params as Params;
* ``` * ```
*/ */
export type InferGetStaticParamsType<T> = T extends () => Promise<infer R> export type InferGetStaticParamsType<T> = T extends () => infer R | Promise<infer R>
? R extends Array<infer U> ? R extends Array<infer U>
? U extends { params: infer P } ? U extends { params: infer P }
? P ? P
@ -1239,7 +1276,9 @@ export type InferGetStaticParamsType<T> = T extends () => Promise<infer R>
* *
* @example * @example
* ```ts * ```ts
* export async function getStaticPaths() { * import type { GetStaticPaths } from 'astro';
*
* export const getStaticPaths = (() => {
* return results.map((entry) => ({ * return results.map((entry) => ({
* params: { slug: entry.slug }, * params: { slug: entry.slug },
* props: { * props: {
@ -1247,15 +1286,15 @@ export type InferGetStaticParamsType<T> = T extends () => Promise<infer R>
* propB: 42 * propB: 42
* }, * },
* })); * }));
* } * }) satisfies GetStaticPaths;
* *
* type Props = InferGetStaticPropsType<typeof getStaticPaths>; * type Props = InferGetStaticPropsType<typeof getStaticPaths>;
* // ^? { propA: boolean; propB: number; } * // ^? { propA: boolean; propB: number; }
* *
* const { propA, propB } = Astro.props as Props; * const { propA, propB } = Astro.props;
* ``` * ```
*/ */
export type InferGetStaticPropsType<T> = T extends () => Promise<infer R> export type InferGetStaticPropsType<T> = T extends () => infer R | Promise<infer R>
? R extends Array<infer U> ? R extends Array<infer U>
? U extends { props: infer P } ? U extends { props: infer P }
? P ? P

View file

@ -1,9 +1,5 @@
export const VIRTUAL_MODULE_ID = 'astro:assets'; export const VIRTUAL_MODULE_ID = 'astro:assets';
export const VIRTUAL_SERVICE_ID = 'virtual:image-service'; export const VIRTUAL_SERVICE_ID = 'virtual:image-service';
/**
* Valid formats for optimizations in our base services.
* Certain formats can be imported (namely SVGs) but not optimized, so they are excluded from this list.
*/
export const VALID_INPUT_FORMATS = [ export const VALID_INPUT_FORMATS = [
// TODO: `image-size` does not support the following formats, so users can't import them. // TODO: `image-size` does not support the following formats, so users can't import them.
// However, it would be immensely useful to add, for three reasons: // However, it would be immensely useful to add, for three reasons:
@ -19,5 +15,11 @@ export const VALID_INPUT_FORMATS = [
'tiff', 'tiff',
'webp', 'webp',
'gif', 'gif',
'svg',
] as const; ] as const;
/**
* Valid formats for optimizations in our base services.
* Certain formats can be imported (namely SVGs) but not processed, so they are excluded from this list.
*/
export const VALID_OPTIMIZABLE_FORMATS = ['jpeg', 'jpg', 'png', 'tiff', 'webp', 'gif'] as const;
export const VALID_OUTPUT_FORMATS = ['avif', 'png', 'webp', 'jpeg', 'jpg'] as const; export const VALID_OUTPUT_FORMATS = ['avif', 'png', 'webp', 'jpeg', 'jpg'] as const;

View file

@ -1,4 +1,4 @@
import mime from 'mime'; import mime from 'mime/lite.js';
import type { APIRoute } from '../@types/astro.js'; import type { APIRoute } from '../@types/astro.js';
import { isRemotePath } from '../core/path.js'; import { isRemotePath } from '../core/path.js';
import { getConfiguredImageService } from './internal.js'; import { getConfiguredImageService } from './internal.js';
@ -54,7 +54,7 @@ export const get: APIRoute = async ({ request }) => {
return new Response(data, { return new Response(data, {
status: 200, status: 200,
headers: { headers: {
'Content-Type': mime.getType(format) || '', 'Content-Type': mime.getType(format) ?? `image/${format}`,
'Cache-Control': 'public, max-age=31536000', 'Cache-Control': 'public, max-age=31536000',
ETag: etag(data.toString()), ETag: etag(data.toString()),
Date: new Date().toUTCString(), Date: new Date().toUTCString(),

View file

@ -1,5 +1,5 @@
export { getConfiguredImageService, getImage } from './internal.js'; export { getConfiguredImageService, getImage } from './internal.js';
export { baseService } from './services/service.js'; export { baseService, isLocalService } from './services/service.js';
export { type LocalImageProps, type RemoteImageProps } from './types.js'; export { type LocalImageProps, type RemoteImageProps } from './types.js';
export { emitESMImage } from './utils/emitAsset.js'; export { emitESMImage } from './utils/emitAsset.js';
export { imageMetadata } from './utils/metadata.js'; export { imageMetadata } from './utils/metadata.js';

View file

@ -4,7 +4,7 @@ import type { StaticBuildOptions } from '../core/build/types.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js';
import { prependForwardSlash } from '../core/path.js'; import { prependForwardSlash } from '../core/path.js';
import { isLocalService, type ImageService, type LocalImageService } from './services/service.js'; import { isLocalService, type ImageService, type LocalImageService } from './services/service.js';
import type { ImageMetadata, ImageTransform } from './types.js'; import type { GetImageResult, ImageMetadata, ImageTransform } from './types.js';
export function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata { export function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata {
return typeof src === 'object'; return typeof src === 'object';
@ -29,13 +29,6 @@ export async function getConfiguredImageService(): Promise<ImageService> {
return globalThis.astroAsset.imageService; return globalThis.astroAsset.imageService;
} }
interface GetImageResult {
rawOptions: ImageTransform;
options: ImageTransform;
src: string;
attributes: Record<string, any>;
}
/** /**
* Get an optimized image and the necessary attributes to render it. * Get an optimized image and the necessary attributes to render it.
* *
@ -45,7 +38,7 @@ interface GetImageResult {
* import { getImage } from 'astro:assets'; * import { getImage } from 'astro:assets';
* import originalImage from '../assets/image.png'; * import originalImage from '../assets/image.png';
* *
* const optimizedImage = await getImage({src: originalImage, width: 1280 }) * const optimizedImage = await getImage({src: originalImage, width: 1280 });
* --- * ---
* <img src={optimizedImage.src} {...optimizedImage.attributes} /> * <img src={optimizedImage.src} {...optimizedImage.attributes} />
* ``` * ```
@ -79,7 +72,9 @@ export async function getImage(options: ImageTransform): Promise<GetImageResult>
}; };
} }
export function getStaticImageList(): Iterable<[ImageTransform, string]> { export function getStaticImageList(): Iterable<
[string, { path: string; options: ImageTransform }]
> {
if (!globalThis?.astroAsset?.staticImages) { if (!globalThis?.astroAsset?.staticImages) {
return []; return [];
} }

View file

@ -1,7 +1,7 @@
import { AstroError, AstroErrorData } from '../../core/errors/index.js'; import { AstroError, AstroErrorData } from '../../core/errors/index.js';
import { VALID_INPUT_FORMATS } from '../consts.js'; import { VALID_OPTIMIZABLE_FORMATS } from '../consts.js';
import { isESMImportedImage } from '../internal.js'; import { isESMImportedImage } from '../internal.js';
import type { ImageTransform, OutputFormat } from '../types.js'; import type { ImageOutputFormat, ImageTransform } from '../types.js';
export type ImageService = LocalImageService | ExternalImageService; export type ImageService = LocalImageService | ExternalImageService;
@ -71,7 +71,7 @@ export interface LocalImageService extends SharedServiceProps {
transform: ( transform: (
inputBuffer: Buffer, inputBuffer: Buffer,
transform: LocalImageTransform transform: LocalImageTransform
) => Promise<{ data: Buffer; format: OutputFormat }>; ) => Promise<{ data: Buffer; format: ImageOutputFormat }>;
} }
export type BaseServiceTransform = { export type BaseServiceTransform = {
@ -129,13 +129,13 @@ export const baseService: Omit<LocalImageService, 'transform'> = {
}); });
} }
} else { } else {
if (!VALID_INPUT_FORMATS.includes(options.src.format as any)) { if (!VALID_OPTIMIZABLE_FORMATS.includes(options.src.format as any)) {
throw new AstroError({ throw new AstroError({
...AstroErrorData.UnsupportedImageFormat, ...AstroErrorData.UnsupportedImageFormat,
message: AstroErrorData.UnsupportedImageFormat.message( message: AstroErrorData.UnsupportedImageFormat.message(
options.src.format, options.src.format,
options.src.src, options.src.src,
VALID_INPUT_FORMATS VALID_OPTIMIZABLE_FORMATS
), ),
}); });
} }
@ -204,7 +204,7 @@ export const baseService: Omit<LocalImageService, 'transform'> = {
src: params.get('href')!, src: params.get('href')!,
width: params.has('w') ? parseInt(params.get('w')!) : undefined, width: params.has('w') ? parseInt(params.get('w')!) : undefined,
height: params.has('h') ? parseInt(params.get('h')!) : undefined, height: params.has('h') ? parseInt(params.get('h')!) : undefined,
format: params.get('f') as OutputFormat, format: params.get('f') as ImageOutputFormat,
quality: params.get('q'), quality: params.get('q'),
}; };

View file

@ -1,5 +1,5 @@
import type { FormatEnum } from 'sharp'; import type { FormatEnum } from 'sharp';
import type { ImageQualityPreset, OutputFormat } from '../types.js'; import type { ImageOutputFormat, ImageQualityPreset } from '../types.js';
import { import {
baseService, baseService,
parseQuality, parseQuality,
@ -64,7 +64,7 @@ const sharpService: LocalImageService = {
return { return {
data: data, data: data,
format: info.format as OutputFormat, format: info.format as ImageOutputFormat,
}; };
}, },
}; };

View file

@ -1,6 +1,6 @@
// TODO: Investigate removing this service once sharp lands WASM support, as libsquoosh is deprecated // TODO: Investigate removing this service once sharp lands WASM support, as libsquoosh is deprecated
import type { ImageQualityPreset, OutputFormat } from '../types.js'; import type { ImageOutputFormat, ImageQualityPreset } from '../types.js';
import { import {
baseService, baseService,
parseQuality, parseQuality,
@ -11,7 +11,10 @@ import { processBuffer } from './vendor/squoosh/image-pool.js';
import type { Operation } from './vendor/squoosh/image.js'; import type { Operation } from './vendor/squoosh/image.js';
const baseQuality = { low: 25, mid: 50, high: 80, max: 100 }; const baseQuality = { low: 25, mid: 50, high: 80, max: 100 };
const qualityTable: Record<Exclude<OutputFormat, 'png'>, Record<ImageQualityPreset, number>> = { const qualityTable: Record<
Exclude<ImageOutputFormat, 'png'>,
Record<ImageQualityPreset, number>
> = {
avif: { avif: {
// Squoosh's AVIF encoder has a bit of a weird behavior where `62` is technically the maximum, and anything over is overkill // Squoosh's AVIF encoder has a bit of a weird behavior where `62` is technically the maximum, and anything over is overkill
max: 62, max: 62,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,4 @@
import { promises as fsp } from 'node:fs' import { instantiateEmscriptenWasm } from './emscripten-utils.js'
import { getModuleURL, instantiateEmscriptenWasm, pathify } from './emscripten-utils.js'
interface DecodeModule extends EmscriptenWasm.Module { interface DecodeModule extends EmscriptenWasm.Module {
decode: (data: Uint8Array) => ImageData decode: (data: Uint8Array) => ImageData
@ -35,52 +34,47 @@ export interface RotateOptions {
// MozJPEG // MozJPEG
import type { MozJPEGModule as MozJPEGEncodeModule } from './mozjpeg/mozjpeg_enc' import type { MozJPEGModule as MozJPEGEncodeModule } from './mozjpeg/mozjpeg_enc'
// @ts-ignore
import mozEnc from './mozjpeg/mozjpeg_node_enc.js'
const mozEncWasm = new URL('./mozjpeg/mozjpeg_node_enc.wasm', getModuleURL(import.meta.url))
// @ts-ignore
import mozDec from './mozjpeg/mozjpeg_node_dec.js' import mozDec from './mozjpeg/mozjpeg_node_dec.js'
const mozDecWasm = new URL('./mozjpeg/mozjpeg_node_dec.wasm', getModuleURL(import.meta.url)) import mozDecWasm from './mozjpeg/mozjpeg_node_dec.wasm.js'
import mozEnc from './mozjpeg/mozjpeg_node_enc.js'
import mozEncWasm from './mozjpeg/mozjpeg_node_enc.wasm.js'
// WebP // WebP
import type { WebPModule as WebPEncodeModule } from './webp/webp_enc' import type { WebPModule as WebPEncodeModule } from './webp/webp_enc'
// @ts-ignore
import webpEnc from './webp/webp_node_enc.js'
const webpEncWasm = new URL('./webp/webp_node_enc.wasm', getModuleURL(import.meta.url))
// @ts-ignore
import webpDec from './webp/webp_node_dec.js' import webpDec from './webp/webp_node_dec.js'
const webpDecWasm = new URL('./webp/webp_node_dec.wasm', getModuleURL(import.meta.url)) import webpDecWasm from './webp/webp_node_dec.wasm.js'
import webpEnc from './webp/webp_node_enc.js'
import webpEncWasm from './webp/webp_node_enc.wasm.js'
// AVIF // AVIF
import type { AVIFModule as AVIFEncodeModule } from './avif/avif_enc' import type { AVIFModule as AVIFEncodeModule } from './avif/avif_enc'
// @ts-ignore
import avifEnc from './avif/avif_node_enc.js'
const avifEncWasm = new URL('./avif/avif_node_enc.wasm', getModuleURL(import.meta.url))
// @ts-ignore
import avifDec from './avif/avif_node_dec.js' import avifDec from './avif/avif_node_dec.js'
const avifDecWasm = new URL('./avif/avif_node_dec.wasm', getModuleURL(import.meta.url)) import avifDecWasm from './avif/avif_node_dec.wasm.js'
import avifEnc from './avif/avif_node_enc.js'
import avifEncWasm from './avif/avif_node_enc.wasm.js'
// PNG // PNG
// @ts-ignore
import * as pngEncDec from './png/squoosh_png.js' import * as pngEncDec from './png/squoosh_png.js'
const pngEncDecWasm = new URL('./png/squoosh_png_bg.wasm', getModuleURL(import.meta.url)) import pngEncDecWasm from './png/squoosh_png_bg.wasm.js'
const pngEncDecInit = () => const pngEncDecInit = () =>
pngEncDec.default(fsp.readFile(pathify(pngEncDecWasm.toString()))) pngEncDec.default(pngEncDecWasm)
// OxiPNG // OxiPNG
// @ts-ignore
import * as oxipng from './png/squoosh_oxipng.js' import * as oxipng from './png/squoosh_oxipng.js'
const oxipngWasm = new URL('./png/squoosh_oxipng_bg.wasm', getModuleURL(import.meta.url)) import oxipngWasm from './png/squoosh_oxipng_bg.wasm.js'
const oxipngInit = () => oxipng.default(fsp.readFile(pathify(oxipngWasm.toString()))) const oxipngInit = () => oxipng.default(oxipngWasm)
// Resize // Resize
// @ts-ignore
import * as resize from './resize/squoosh_resize.js' import * as resize from './resize/squoosh_resize.js'
const resizeWasm = new URL('./resize/squoosh_resize_bg.wasm', getModuleURL(import.meta.url)) import resizeWasm from './resize/squoosh_resize_bg.wasm.js'
const resizeInit = () => resize.default(fsp.readFile(pathify(resizeWasm.toString()))) const resizeInit = () => resize.default(resizeWasm)
// rotate // rotate
const rotateWasm = new URL('./rotate/rotate.wasm', getModuleURL(import.meta.url)) import rotateWasm from './rotate/rotate.wasm.js'
// Our decoders currently rely on a `ImageData` global. // Our decoders currently rely on a `ImageData` global.
import ImageData from './image_data.js' import ImageData from './image_data.js'
@ -187,7 +181,7 @@ export const preprocessors = {
const sameDimensions = degrees === 0 || degrees === 180 const sameDimensions = degrees === 0 || degrees === 180
const size = width * height * 4 const size = width * height * 4
const instance = ( const instance = (
await WebAssembly.instantiate(await fsp.readFile(pathify(rotateWasm.toString()))) await WebAssembly.instantiate(rotateWasm)
).instance as RotateModuleInstance ).instance as RotateModuleInstance
const { memory } = instance.exports const { memory } = instance.exports
const additionalPagesNeeded = Math.ceil( const additionalPagesNeeded = Math.ceil(
@ -218,11 +212,11 @@ export const codecs = {
extension: 'jpg', extension: 'jpg',
detectors: [/^\xFF\xD8\xFF/], detectors: [/^\xFF\xD8\xFF/],
dec: () => dec: () =>
instantiateEmscriptenWasm(mozDec as DecodeModuleFactory, mozDecWasm.toString()), instantiateEmscriptenWasm(mozDec as DecodeModuleFactory, mozDecWasm),
enc: () => enc: () =>
instantiateEmscriptenWasm( instantiateEmscriptenWasm(
mozEnc as EmscriptenWasm.ModuleFactory<MozJPEGEncodeModule>, mozEnc as EmscriptenWasm.ModuleFactory<MozJPEGEncodeModule>,
mozEncWasm.toString() mozEncWasm
), ),
defaultEncoderOptions: { defaultEncoderOptions: {
quality: 75, quality: 75,
@ -253,11 +247,11 @@ export const codecs = {
extension: 'webp', extension: 'webp',
detectors: [/^RIFF....WEBPVP8[LX ]/s], detectors: [/^RIFF....WEBPVP8[LX ]/s],
dec: () => dec: () =>
instantiateEmscriptenWasm(webpDec as DecodeModuleFactory, webpDecWasm.toString()), instantiateEmscriptenWasm(webpDec as DecodeModuleFactory, webpDecWasm),
enc: () => enc: () =>
instantiateEmscriptenWasm( instantiateEmscriptenWasm(
webpEnc as EmscriptenWasm.ModuleFactory<WebPEncodeModule>, webpEnc as EmscriptenWasm.ModuleFactory<WebPEncodeModule>,
webpEncWasm.toString() webpEncWasm
), ),
defaultEncoderOptions: { defaultEncoderOptions: {
quality: 75, quality: 75,
@ -300,11 +294,11 @@ export const codecs = {
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
detectors: [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/], detectors: [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/],
dec: () => dec: () =>
instantiateEmscriptenWasm(avifDec as DecodeModuleFactory, avifDecWasm.toString()), instantiateEmscriptenWasm(avifDec as DecodeModuleFactory, avifDecWasm),
enc: async () => { enc: async () => {
return instantiateEmscriptenWasm( return instantiateEmscriptenWasm(
avifEnc as EmscriptenWasm.ModuleFactory<AVIFEncodeModule>, avifEnc as EmscriptenWasm.ModuleFactory<AVIFEncodeModule>,
avifEncWasm.toString() avifEncWasm
) )
}, },
defaultEncoderOptions: { defaultEncoderOptions: {

View file

@ -1,24 +0,0 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
export async function copyWasmFiles(dir: URL) {
const src = new URL('./', import.meta.url);
await copyDir(fileURLToPath(src), fileURLToPath(dir));
}
async function copyDir(src: string, dest: string) {
const itemNames = await fs.readdir(src);
await Promise.all(itemNames.map(async (srcName) => {
const srcPath = path.join(src, srcName);
const destPath = path.join(dest, srcName);
const s = await fs.stat(srcPath);
if (s.isFile() && /.wasm$/.test(srcPath)) {
await fs.mkdir(path.dirname(destPath), { recursive: true });
await fs.copyFile(srcPath, destPath);
}
else if (s.isDirectory()) {
await copyDir(srcPath, destPath);
}
}));
}

View file

@ -10,19 +10,14 @@ export function pathify(path: string): string {
export function instantiateEmscriptenWasm<T extends EmscriptenWasm.Module>( export function instantiateEmscriptenWasm<T extends EmscriptenWasm.Module>(
factory: EmscriptenWasm.ModuleFactory<T>, factory: EmscriptenWasm.ModuleFactory<T>,
path: string, bytes: Uint8Array,
workerJS = ''
): Promise<T> { ): Promise<T> {
return factory({ return factory({
locateFile(requestPath) { // @ts-expect-error This is a valid Emscripten option, but the type definitions don't know about it
// The glue code generated by emscripten uses the original wasmBinary: bytes,
// file names of the worker file and the wasm binary. locateFile(file: string) {
// These will have changed in the bundling process and return file
// we need to inject them here. }
if (requestPath.endsWith('.wasm')) return pathify(path)
if (requestPath.endsWith('.worker.js')) return pathify(workerJS)
return requestPath
},
}) })
} }
@ -32,12 +27,12 @@ export function dirname(url: string) {
/** /**
* On certain serverless hosts, our ESM bundle is transpiled to CJS before being run, which means * On certain serverless hosts, our ESM bundle is transpiled to CJS before being run, which means
* import.meta.url is undefined, so we'll fall back to __dirname in those cases * import.meta.url is undefined, so we'll fall back to __filename in those cases
* We should be able to remove this once https://github.com/netlify/zip-it-and-ship-it/issues/750 is fixed * We should be able to remove this once https://github.com/netlify/zip-it-and-ship-it/issues/750 is fixed
*/ */
export function getModuleURL(url: string | undefined): string { export function getModuleURL(url: string | undefined): string {
if (!url) { if (!url) {
return pathToFileURL(__dirname).toString(); return pathToFileURL(__filename).toString();
} }
return url return url

View file

@ -1,7 +1,7 @@
import { isMainThread } from 'node:worker_threads'; import { isMainThread } from 'node:worker_threads';
import { cpus } from 'os'; import { cpus } from 'os';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import type { OutputFormat } from '../../../types.js'; import type { ImageOutputFormat } from '../../../types.js';
import { getModuleURL } from './emscripten-utils.js'; import { getModuleURL } from './emscripten-utils.js';
import type { Operation } from './image.js'; import type { Operation } from './image.js';
import * as impl from './impl.js'; import * as impl from './impl.js';
@ -88,7 +88,7 @@ function handleJob(params: JobMessage) {
export async function processBuffer( export async function processBuffer(
buffer: Buffer, buffer: Buffer,
operations: Operation[], operations: Operation[],
encoding: OutputFormat, encoding: ImageOutputFormat,
quality?: number quality?: number
): Promise<Uint8Array> { ): Promise<Uint8Array> {
// @ts-ignore // @ts-ignore

View file

@ -1,4 +1,4 @@
import type { OutputFormat } from '../../../types.js'; import type { ImageOutputFormat } from '../../../types.js';
import * as impl from './impl.js'; import * as impl from './impl.js';
type RotateOperation = { type RotateOperation = {
@ -15,7 +15,7 @@ export type Operation = RotateOperation | ResizeOperation
export async function processBuffer( export async function processBuffer(
buffer: Buffer, buffer: Buffer,
operations: Operation[], operations: Operation[],
encoding: OutputFormat, encoding: ImageOutputFormat,
quality?: number quality?: number
): Promise<Uint8Array> { ): Promise<Uint8Array> {
let imageData = await impl.decodeBuffer(buffer) let imageData = await impl.decodeBuffer(buffer)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
export default Buffer.from("AGFzbQEAAAABDAJgAn9/AGADf39/AAMGBQAAAAABBQMBABAGEQJ/AEGAgMAAC38AQYCAwAALBy4EBm1lbW9yeQIABnJvdGF0ZQAECl9fZGF0YV9lbmQDAAtfX2hlYXBfYmFzZQMBCpsJBUkBAX8gACABbCIAQf////8DcSICBEBBCCEBIABBAnRBCGohAANAIAAgASgCADYCACABQQRqIQEgAEEEaiEAIAJBf2oiAg0ACwsLzQMBFH8gAUECdCERIAAgAWwiDEECdEEEaiESA0ACQAJAAkACQCAEQQFxRQRAIAMgAU8NAiADQQFqIQgMAQsgA0EPaiICIANJIggNASACIAFJIgVFDQEgASADQRBqIAgbIAEgBRshCCACIQMLIAEgA0EQaiICIAIgAUsbIQ0gA0F/cyETIBIgA0ECdGshFEEAIQVBACEOA0ACQAJAIA5FBEAgBSAASQ0BQQEhBAwGCyAAIAVBEGogBUEPaiICIAVJIgcbIAAgAiAASRshBUEBIQQgByACIABPcg0FDAELIAUiAkEBaiEFC0EBIQ4gAyANTw0AIAAgAkEQaiIPIAAgD0kbQQJ0IAJBAnRrIRUgEyABIAJsaiEHIBQgASACQQFqbEECdGohCSADIQoDQCAAIApsIgYgAmoiBEEQaiAAIAZqIA8gAEkbIgYgBEkgDCAGSXINAyAEIAZHBEAgBEECdEEIaiELIBUhBiAHIRAgCSEEA0AgDCABIBBqIhBNDQUgBCALKAIANgIAIAQgEWohBCALQQRqIQsgBkF8aiIGDQALCyAHQX9qIQcgCUF8aiEJIA0gCkEBaiIKRw0ACwwACwALDwsACyAIIQMMAAsAC1MBAX8CQCAAIAFsQQJ0IgJBCGoiAEEIRg0AIAAgAmpBfGohAEEAIQEDQCABIAJGDQEgACABQQhqKAIANgIAIABBfGohACACIAFBBGoiAUcNAAsLC9oDARN/IABBf2ohEEEAIAFBAnRrIREgACABbCIMQQJ0QQhqIRIDQAJAAkACQAJAIARBAXFFBEAgAyABTw0CIANBAWohCQwBCyADQQ9qIgIgA0kiCQ0BIAIgAUkiBUUNASABIANBEGogCRsgASAFGyEJIAIhAwsgASADQRBqIgIgAiABSxshDSASIANBAnRqIRNBACEFQQAhBgNAAkACQCAGQQFxRQRAIAUgAEkNAUEBIQQMBgsgACAFQRBqIAVBD2oiAiAFSSIIGyAAIAIgAEkbIQVBASEEIAggAiAAT3INBQwBCyAFIgJBAWohBQtBASEGIAMgDU8NACAAIAJBEGoiDiAAIA5JG0ECdCACQQJ0ayEUIAMgASAAIAJrbGohCCATIAEgECACa2xBAnRqIQogAyELA0AgACALbCIHIAJqIgRBEGogACAHaiAOIABJGyIHIARJIAwgB0lyDQMgBCAHRwRAIARBAnRBCGohBiAUIQcgCCEPIAohBANAIAwgDyABayIPTQ0FIAQgBigCADYCACAEIBFqIQQgBkEEaiEGIAdBfGoiBw0ACwtBASEGIAhBAWohCCAKQQRqIQogDSALQQFqIgtHDQALDAALAAsPCwALIAkhAwwACwALUAACQAJAAkACQCACQbMBTARAIAJFDQIgAkHaAEcNASAAIAEQAQ8LIAJBtAFGDQIgAkGOAkYNAwsACyAAIAEQAA8LIAAgARACDwsgACABEAMLAE0JcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AQVydXN0Yx0xLjQ3LjAgKDE4YmY2YjRmMCAyMDIwLTEwLTA3KQ==", 'base64');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,15 +4,15 @@ import type { ImageService } from './services/service.js';
export type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max' | (string & {}); export type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max' | (string & {});
export type ImageQuality = ImageQualityPreset | number; export type ImageQuality = ImageQualityPreset | number;
export type InputFormat = (typeof VALID_INPUT_FORMATS)[number] | 'svg'; export type ImageInputFormat = (typeof VALID_INPUT_FORMATS)[number];
export type OutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {}); export type ImageOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {});
declare global { declare global {
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
var astroAsset: { var astroAsset: {
imageService?: ImageService; imageService?: ImageService;
addStaticImage?: ((options: ImageTransform) => string) | undefined; addStaticImage?: ((options: ImageTransform) => string) | undefined;
staticImages?: Map<ImageTransform, string>; staticImages?: Map<string, { path: string; options: ImageTransform }>;
}; };
} }
@ -23,7 +23,7 @@ export interface ImageMetadata {
src: string; src: string;
width: number; width: number;
height: number; height: number;
format: InputFormat; format: ImageInputFormat;
} }
/** /**
@ -31,13 +31,20 @@ export interface ImageMetadata {
*/ */
export type ImageTransform = { export type ImageTransform = {
src: ImageMetadata | string; src: ImageMetadata | string;
width?: number; width?: number | undefined;
height?: number; height?: number | undefined;
quality?: ImageQuality; quality?: ImageQuality | undefined;
format?: OutputFormat; format?: ImageOutputFormat | undefined;
[key: string]: any; [key: string]: any;
}; };
export interface GetImageResult {
rawOptions: ImageTransform;
options: ImageTransform;
src: string;
attributes: Record<string, any>;
}
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }; type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
type ImageSharedProps<T> = T & { type ImageSharedProps<T> = T & {
/** /**
@ -94,11 +101,11 @@ export type LocalImageProps<T> = ImageSharedProps<T> & {
* <Image src={...} format="avif" alt="..." /> * <Image src={...} format="avif" alt="..." />
* ``` * ```
*/ */
format?: OutputFormat; format?: ImageOutputFormat;
/** /**
* Desired quality for the image. Value can either be a preset such as `low` or `high`, or a numeric value from 0 to 100. * Desired quality for the image. Value can either be a preset such as `low` or `high`, or a numeric value from 0 to 100.
* *
* The perceptual quality of the output image is loader-specific. * The perceptual quality of the output image is service-specific.
* For instance, a certain service might decide that `high` results in a very beautiful image, but another could choose for it to be at best passable. * For instance, a certain service might decide that `high` results in a very beautiful image, but another could choose for it to be at best passable.
* *
* **Example**: * **Example**:

View file

@ -3,19 +3,23 @@ import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url'; import { fileURLToPath, pathToFileURL } from 'node:url';
import slash from 'slash'; import slash from 'slash';
import type { AstroConfig, AstroSettings } from '../../@types/astro'; import type { AstroConfig, AstroSettings } from '../../@types/astro';
import { imageMetadata } from './metadata.js'; import { imageMetadata, type Metadata } from './metadata.js';
export async function emitESMImage( export async function emitESMImage(
id: string, id: string | undefined,
watchMode: boolean, watchMode: boolean,
fileEmitter: any, fileEmitter: any,
settings: Pick<AstroSettings, 'config'> settings: Pick<AstroSettings, 'config'>
) { ): Promise<Metadata | undefined> {
if (!id) {
return undefined;
}
const url = pathToFileURL(id); const url = pathToFileURL(id);
const meta = await imageMetadata(url); const meta = await imageMetadata(url);
if (!meta) { if (!meta) {
return; return undefined;
} }
// Build // Build
@ -48,13 +52,13 @@ export async function emitESMImage(
* due to Vite dependencies in core. * due to Vite dependencies in core.
*/ */
function rootRelativePath(config: Pick<AstroConfig, 'root'>, url: URL) { function rootRelativePath(config: Pick<AstroConfig, 'root'>, url: URL): string {
const basePath = fileURLToNormalizedPath(url); const basePath = fileURLToNormalizedPath(url);
const rootPath = fileURLToNormalizedPath(config.root); const rootPath = fileURLToNormalizedPath(config.root);
return prependForwardSlash(basePath.slice(rootPath.length)); return prependForwardSlash(basePath.slice(rootPath.length));
} }
function prependForwardSlash(filePath: string) { function prependForwardSlash(filePath: string): string {
return filePath[0] === '/' ? filePath : '/' + filePath; return filePath[0] === '/' ? filePath : '/' + filePath;
} }
@ -64,6 +68,6 @@ function fileURLToNormalizedPath(filePath: URL): string {
return slash(fileURLToPath(filePath) + filePath.search).replace(/\\/g, '/'); return slash(fileURLToPath(filePath) + filePath.search).replace(/\\/g, '/');
} }
export function emoji(char: string, fallback: string) { export function emoji(char: string, fallback: string): string {
return process.platform !== 'win32' ? char : fallback; return process.platform !== 'win32' ? char : fallback;
} }

View file

@ -1,6 +1,6 @@
import fs from 'node:fs/promises'; import fs from 'node:fs/promises';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import type { ImageMetadata, InputFormat } from '../types.js'; import type { ImageInputFormat, ImageMetadata } from '../types.js';
import imageSize from '../vendor/image-size/index.js'; import imageSize from '../vendor/image-size/index.js';
export interface Metadata extends ImageMetadata { export interface Metadata extends ImageMetadata {
@ -31,7 +31,7 @@ export async function imageMetadata(
src: fileURLToPath(src), src: fileURLToPath(src),
width: isPortrait ? height : width, width: isPortrait ? height : width,
height: isPortrait ? width : height, height: isPortrait ? width : height,
format: type as InputFormat, format: type as ImageInputFormat,
orientation, orientation,
}; };
} }

View file

@ -1,4 +1,4 @@
import type { ImageMetadata, InputFormat } from '../types.js'; import type { ImageInputFormat, ImageMetadata } from '../types.js';
export function getOrigQueryParams( export function getOrigQueryParams(
params: URLSearchParams params: URLSearchParams
@ -14,6 +14,6 @@ export function getOrigQueryParams(
return { return {
width: parseInt(width), width: parseInt(width),
height: parseInt(height), height: parseInt(height),
format: format as InputFormat, format: format as ImageInputFormat,
}; };
} }

View file

@ -4,7 +4,7 @@ import { shorthash } from '../../runtime/server/shorthash.js';
import { isESMImportedImage } from '../internal.js'; import { isESMImportedImage } from '../internal.js';
import type { ImageTransform } from '../types.js'; import type { ImageTransform } from '../types.js';
export function propsToFilename(transform: ImageTransform, imageService: string) { export function propsToFilename(transform: ImageTransform, hash: string) {
if (!isESMImportedImage(transform.src)) { if (!isESMImportedImage(transform.src)) {
return transform.src; return transform.src;
} }
@ -12,9 +12,13 @@ export function propsToFilename(transform: ImageTransform, imageService: string)
let filename = removeQueryString(transform.src.src); let filename = removeQueryString(transform.src.src);
const ext = extname(filename); const ext = extname(filename);
filename = basename(filename, ext); filename = basename(filename, ext);
const outputExt = transform.format ? `.${transform.format}` : ext;
return `/${filename}_${hash}${outputExt}`;
}
export function hashTransform(transform: ImageTransform, imageService: string) {
// take everything from transform except alt, which is not used in the hash // take everything from transform except alt, which is not used in the hash
const { alt, ...rest } = transform; const { alt, ...rest } = transform;
const hashFields = { ...rest, imageService }; const hashFields = { ...rest, imageService };
const outputExt = transform.format ? `.${transform.format}` : ext; return shorthash(JSON.stringify(hashFields));
return `/${filename}_${shorthash(JSON.stringify(hashFields))}${outputExt}`;
} }

Some files were not shown because too many files have changed in this diff Show more