mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
Merge branch 'withastro:main' into main
This commit is contained in:
commit
3feb8cd977
188 changed files with 1519 additions and 2037 deletions
5
.changeset/curvy-elephants-fry.md
Normal file
5
.changeset/curvy-elephants-fry.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes an issue where Astro didn't throw an error when `Astro.rewrite` was used without providing the experimental flag
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Drop duplicated brackets in data collections schema generation.
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes a case where rewriting `/` would cause an issue, when `trailingSlash` was set to `"never"`.
|
|
@ -1,27 +0,0 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Adds [`ShikiTransformer`](https://shiki.style/packages/transformers#shikijs-transformers) support to the [`<Code />`](https://docs.astro.build/en/reference/api-reference/#code-) component with a new `transformers` prop.
|
||||
|
||||
Note that `transformers` only applies classes and you must provide your own CSS rules to target the elements of your code block.
|
||||
|
||||
```astro
|
||||
---
|
||||
import { transformerNotationFocus } from '@shikijs/transformers'
|
||||
import { Code } from 'astro:components'
|
||||
|
||||
const code = `const foo = 'hello'
|
||||
const bar = ' world'
|
||||
console.log(foo + bar) // [!code focus]
|
||||
`
|
||||
---
|
||||
|
||||
<Code {code} lang="js" transformers={[transformerNotationFocus()]} />
|
||||
|
||||
<style is:global>
|
||||
pre.has-focused .line:not(.focused) {
|
||||
filter: blur(1px);
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Reverts a logic where it wasn't possible to rewrite `/404` in static mode. It's **now possible** again
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes type generation for empty content collections
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Improves type-checking and error handling to catch case where an image import is passed directly to `getImage()`
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
"astro": minor
|
||||
---
|
||||
|
||||
Improves the developer experience of the `500.astro` file by passing it a new `error` prop.
|
||||
|
||||
When an error is thrown, the special `src/pages/500.astro` page now automatically receives the error as a prop. This allows you to display more specific information about the error on a custom 500 page.
|
||||
|
||||
```astro
|
||||
---
|
||||
// src/pages/500.astro
|
||||
interface Props {
|
||||
error: unknown
|
||||
}
|
||||
|
||||
const { error } = Astro.props
|
||||
---
|
||||
|
||||
<div>{error instanceof Error ? error.message : 'Unknown error'}</div>
|
||||
```
|
||||
|
||||
If an error occurs rendering this page, your host's default 500 error page will be shown to your visitor in production, and Astro's default error overlay will be shown in development.
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Corrects an inconsistency in dev where middleware would run for prerendered 404 routes.
|
||||
Middleware is not run for prerendered 404 routes in production, so this was incorrect.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes an issue that would break `Astro.request.url` and `Astro.request.headers` in `astro dev` if HTTP/2 was enabled.
|
||||
|
||||
HTTP/2 is now enabled by default in `astro dev` if `https` is configured in the Vite config.
|
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,5 +1,8 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💁 Support
|
||||
url: https://astro.build/chat
|
||||
about: 'This issue tracker is not for support questions. Join us on Discord for assistance!'
|
||||
- name: 📘 Documentation
|
||||
url: https://github.com/withastro/docs
|
||||
about: File an issue or make an improvement to the docs website.
|
||||
|
@ -9,6 +12,3 @@ contact_links:
|
|||
- name: 👾 Chat
|
||||
url: https://astro.build/chat
|
||||
about: Our Discord server is active, come join us!
|
||||
- name: 💁 Support
|
||||
url: https://astro.build/chat
|
||||
about: 'This issue tracker is not for support questions. Join us on Discord for assistance!'
|
||||
|
|
1
.github/renovate.json5
vendored
1
.github/renovate.json5
vendored
|
@ -15,6 +15,7 @@
|
|||
// manually bumping deps
|
||||
"@biomejs/biome",
|
||||
"@types/node",
|
||||
"@preact/preset-vite", // v2.8.3 starts to use Vite's esbuild for perf, but this conflicts with the react plugin
|
||||
"preact-render-to-string", // https://github.com/withastro/astro/pull/10200
|
||||
"sharp",
|
||||
|
||||
|
|
6
.npmrc
6
.npmrc
|
@ -4,11 +4,11 @@ link-workspace-packages=true
|
|||
save-workspace-protocol=false # This prevents the examples to have the `workspace:` prefix
|
||||
auto-install-peers=false
|
||||
|
||||
# `github-slugger` is used by `vite-plugin-markdown-legacy`.
|
||||
# Temporarily hoist this until we remove the feature.
|
||||
public-hoist-pattern[]=github-slugger
|
||||
# Vite's esbuild optimizer has trouble optimizing `@astrojs/lit/client-shim.js`
|
||||
# which imports this dependency.
|
||||
public-hoist-pattern[]=@webcomponents/template-shadowroot
|
||||
# There's a lit dependency duplication somewhere causing multiple Lit versions error.
|
||||
public-hoist-pattern[]=*lit*
|
||||
# `astro sync` could try to import `@astrojs/db` but could fail due to linked dependencies in the monorepo.
|
||||
# We hoist it here so that it can easily resolve `@astrojs/db` without hardcoded handling.
|
||||
public-hoist-pattern[]=@astrojs/db
|
||||
|
|
15
biome.json
15
biome.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.7.1/schema.json",
|
||||
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
|
||||
"files": {
|
||||
"ignore": [
|
||||
"vendor",
|
||||
|
@ -20,7 +20,6 @@
|
|||
"benchmark/results/",
|
||||
".changeset",
|
||||
"pnpm-lock.yaml",
|
||||
"package.json",
|
||||
"*.astro"
|
||||
]
|
||||
},
|
||||
|
@ -30,7 +29,7 @@
|
|||
"linter": { "enabled": false },
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"trailingComma": "es5",
|
||||
"trailingCommas": "es5",
|
||||
"quoteStyle": "single",
|
||||
"semicolons": "always"
|
||||
}
|
||||
|
@ -44,5 +43,15 @@
|
|||
"indentStyle": "space",
|
||||
"trailingCommas": "none"
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"include": ["package.json"],
|
||||
"json": {
|
||||
"formatter": {
|
||||
"lineWidth": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^3.1.1",
|
||||
"@astrojs/rss": "^4.0.6",
|
||||
"@astrojs/mdx": "^3.1.2",
|
||||
"@astrojs/rss": "^4.0.7",
|
||||
"@astrojs/sitemap": "^3.1.6",
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.0.0"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"@astrojs/react": "^3.6.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/alpinejs": "^0.4.0",
|
||||
"@types/alpinejs": "^3.13.10",
|
||||
"alpinejs": "^3.14.0",
|
||||
"astro": "^4.10.3"
|
||||
"alpinejs": "^3.14.1",
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/lit": "^4.3.0",
|
||||
"@webcomponents/template-shadowroot": "^0.2.1",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"lit": "^3.1.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"@astrojs/vue": "^4.5.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"preact": "^10.22.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.0",
|
||||
"@preact/signals": "^1.2.3",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"preact": "^10.22.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"@astrojs/react": "^3.6.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/solid-js": "^4.4.0",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"solid-js": "^1.8.17"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/svelte": "^5.6.0",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"svelte": "^4.2.18"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/vue": "^4.5.0",
|
||||
"astro": "^4.10.3",
|
||||
"vue": "^3.4.29"
|
||||
"astro": "^4.11.3",
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^8.3.1",
|
||||
"astro": "^4.10.3"
|
||||
"@astrojs/node": "^8.3.2",
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.0.0"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"server": "node dist/server/entry.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^8.3.1",
|
||||
"astro": "^4.10.3",
|
||||
"@astrojs/node": "^8.3.2",
|
||||
"astro": "^4.11.3",
|
||||
"html-minifier": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
"server": "node dist/server/entry.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^8.3.1",
|
||||
"@astrojs/node": "^8.3.2",
|
||||
"@astrojs/svelte": "^5.6.0",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"svelte": "^4.2.18"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3",
|
||||
"sass": "^1.77.5",
|
||||
"astro": "^4.11.3",
|
||||
"sass": "^1.77.6",
|
||||
"sharp": "^0.33.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@
|
|||
"./app": "./dist/app.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@astrojs/node": "^8.3.1",
|
||||
"astro": "^4.10.3"
|
||||
"@astrojs/node": "^8.3.2",
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/markdoc": "^0.11.0",
|
||||
"astro": "^4.10.3"
|
||||
"@astrojs/markdoc": "^0.11.1",
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/markdown-remark": "^5.1.0",
|
||||
"astro": "^4.10.3",
|
||||
"@astrojs/markdown-remark": "^5.1.1",
|
||||
"astro": "^4.11.3",
|
||||
"hast-util-select": "^6.0.2",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3"
|
||||
"astro": "^4.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^3.1.1",
|
||||
"@astrojs/mdx": "^3.1.2",
|
||||
"@astrojs/preact": "^3.5.0",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"preact": "^10.22.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.0",
|
||||
"@nanostores/preact": "^0.5.1",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"nanostores": "^0.10.3",
|
||||
"preact": "^10.22.0"
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^3.1.1",
|
||||
"@astrojs/mdx": "^3.1.2",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@types/canvas-confetti": "^1.6.4",
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"postcss": "^8.4.38",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.10.3",
|
||||
"astro": "^4.11.3",
|
||||
"vitest": "^1.6.0"
|
||||
}
|
||||
}
|
||||
|
|
16
package.json
16
package.json
|
@ -16,10 +16,10 @@
|
|||
"dev": "turbo run dev --concurrency=40 --parallel --filter=astro --filter=create-astro --filter=\"@astrojs/*\" --filter=\"@benchmark/*\"",
|
||||
"format": "pnpm run format:code && pnpm run format:imports",
|
||||
"format:ci": "pnpm run format:code:ci && pnpm run format:imports:ci",
|
||||
"format:code": "biome format ./ --write && prettier -w \"**/*\" --ignore-unknown --cache",
|
||||
"format:code:ci": "biome format ./ && prettier -w \"**/*\" --ignore-unknown --cache --check",
|
||||
"format:imports": "biome check --apply .",
|
||||
"format:imports:ci": "biome ci .",
|
||||
"format:code": "biome format --write && prettier -w \"**/*\" --ignore-unknown --cache",
|
||||
"format:code:ci": "biome format && prettier -w \"**/*\" --ignore-unknown --cache --check",
|
||||
"format:imports": "biome check --formatter-enabled=false --write",
|
||||
"format:imports:ci": "biome ci --formatter-enabled=false",
|
||||
"test": "turbo run test --concurrency=1 --filter=astro --filter=create-astro --filter=\"@astrojs/*\"",
|
||||
"test:citgm": "pnpm -r --filter=astro test",
|
||||
"test:match": "cd packages/astro && pnpm run test:match",
|
||||
|
@ -52,9 +52,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.7.0",
|
||||
"@biomejs/biome": "1.7.1",
|
||||
"@biomejs/biome": "1.8.1",
|
||||
"@changesets/changelog-github": "^0.5.0",
|
||||
"@changesets/cli": "^2.27.5",
|
||||
"@changesets/cli": "^2.27.6",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@types/node": "^18.17.8",
|
||||
"esbuild": "^0.21.5",
|
||||
|
@ -68,8 +68,8 @@
|
|||
"prettier-plugin-astro": "^0.14.0",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"turbo": "^1.13.4",
|
||||
"typescript": "~5.4.5",
|
||||
"typescript-eslint": "^7.13.0"
|
||||
"typescript": "~5.5.2",
|
||||
"typescript-eslint": "^7.13.1"
|
||||
},
|
||||
"pnpm": {
|
||||
"packageExtensions": {
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @astrojs/rss
|
||||
|
||||
## 4.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11299](https://github.com/withastro/astro/pull/11299) [`8ce66f2`](https://github.com/withastro/astro/commit/8ce66f2ef7328546d823f1076f9bab4217a6be7d) Thanks [@ematipico](https://github.com/ematipico)! - Fixes an issue where the `pagesGlobToRssItems` returned an incorrect type for `items`
|
||||
|
||||
## 4.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@astrojs/rss",
|
||||
"description": "Add RSS feeds to your Astro projects",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.7",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
|
|
|
@ -32,13 +32,13 @@ export type RSSOptions = {
|
|||
|
||||
export type RSSFeedItem = {
|
||||
/** Link to item */
|
||||
link: z.infer<typeof rssSchema>['link'];
|
||||
link?: z.infer<typeof rssSchema>['link'];
|
||||
/** Full content of the item. Should be valid HTML */
|
||||
content?: z.infer<typeof rssSchema>['content'];
|
||||
/** Title of item */
|
||||
title: z.infer<typeof rssSchema>['title'];
|
||||
title?: z.infer<typeof rssSchema>['title'];
|
||||
/** Publication date of item */
|
||||
pubDate: z.infer<typeof rssSchema>['pubDate'];
|
||||
pubDate?: z.infer<typeof rssSchema>['pubDate'];
|
||||
/** Item description */
|
||||
description?: z.infer<typeof rssSchema>['description'];
|
||||
/** Append some other XML-valid data to this item */
|
||||
|
|
|
@ -1,5 +1,111 @@
|
|||
# astro
|
||||
|
||||
## 4.11.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11347](https://github.com/withastro/astro/pull/11347) [`33bdc54`](https://github.com/withastro/astro/commit/33bdc5472929f72fa8e39624598bf929c48e60c0) Thanks [@bluwy](https://github.com/bluwy)! - Fixes installed packages detection when running `astro check`
|
||||
|
||||
- [#11327](https://github.com/withastro/astro/pull/11327) [`0df8142`](https://github.com/withastro/astro/commit/0df81422a81c8f8900684d100e9b8f26365fa0b1) Thanks [@ematipico](https://github.com/ematipico)! - Fixes an issue with the container APIs where a runtime error was thrown during the build, when using `pnpm` as package manager.
|
||||
|
||||
## 4.11.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11335](https://github.com/withastro/astro/pull/11335) [`4c4741b`](https://github.com/withastro/astro/commit/4c4741b42dc531403f7b9647bd51951d0cdb8f5b) Thanks [@ematipico](https://github.com/ematipico)! - Reverts [#11292](https://github.com/withastro/astro/pull/11292), which caused a regression to the input type
|
||||
|
||||
- [#11326](https://github.com/withastro/astro/pull/11326) [`41121fb`](https://github.com/withastro/astro/commit/41121fbe00e144d4d93835811e1c4349664d9003) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Fixes a case where running `astro sync` when using the experimental `astro:env` feature would fail if environment variables were missing
|
||||
|
||||
- [#11338](https://github.com/withastro/astro/pull/11338) [`9752a0b`](https://github.com/withastro/astro/commit/9752a0b27526270fd0066f3db7049e9ae6af1ef8) Thanks [@zaaakher](https://github.com/zaaakher)! - Fixes svg icon margin in devtool tooltip title to look coherent in `rtl` and `ltr` layouts
|
||||
|
||||
- [#11331](https://github.com/withastro/astro/pull/11331) [`f1b78a4`](https://github.com/withastro/astro/commit/f1b78a496034d53b0e9dfc276a4a1b1d691772c4) Thanks [@bluwy](https://github.com/bluwy)! - Removes `resolve` package and simplify internal resolve check
|
||||
|
||||
- [#11339](https://github.com/withastro/astro/pull/11339) [`8fdbf0e`](https://github.com/withastro/astro/commit/8fdbf0e45beffdae3da1e7f36797575c92f8a0ba) Thanks [@matthewp](https://github.com/matthewp)! - Remove non-fatal errors from telemetry
|
||||
|
||||
Previously we tracked non-fatal errors in telemetry to get a good idea of the types of errors that occur in `astro dev`. However this has become noisy over time and results in a lot of data that isn't particularly useful. This removes those non-fatal errors from being tracked.
|
||||
|
||||
## 4.11.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11308](https://github.com/withastro/astro/pull/11308) [`44c61dd`](https://github.com/withastro/astro/commit/44c61ddfd85f1c23f8cec8caeaa5e25897121996) Thanks [@ematipico](https://github.com/ematipico)! - Fixes an issue where custom `404.astro` and `500.astro` were not returning the correct status code when rendered inside a rewriting cycle.
|
||||
|
||||
- [#11302](https://github.com/withastro/astro/pull/11302) [`0622567`](https://github.com/withastro/astro/commit/06225673269201044358788f2a81dbe13912adce) Thanks [@martrapp](https://github.com/martrapp)! - Fixes an issue with the view transition router when redirecting to an URL with different origin.
|
||||
|
||||
- Updated dependencies [[`b6afe6a`](https://github.com/withastro/astro/commit/b6afe6a782f68f4a279463a144baaf99cb96b6dc), [`41064ce`](https://github.com/withastro/astro/commit/41064cee78c1cccd428f710a24c483aeb275fd95)]:
|
||||
- @astrojs/markdown-remark@5.1.1
|
||||
- @astrojs/internal-helpers@0.4.1
|
||||
|
||||
## 4.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#11197](https://github.com/withastro/astro/pull/11197) [`4b46bd9`](https://github.com/withastro/astro/commit/4b46bd9bdcbb302f294aa27b8aa07099e104fa17) Thanks [@braebo](https://github.com/braebo)! - Adds [`ShikiTransformer`](https://shiki.style/packages/transformers#shikijs-transformers) support to the [`<Code />`](https://docs.astro.build/en/reference/api-reference/#code-) component with a new `transformers` prop.
|
||||
|
||||
Note that `transformers` only applies classes and you must provide your own CSS rules to target the elements of your code block.
|
||||
|
||||
```astro
|
||||
---
|
||||
import { transformerNotationFocus } from '@shikijs/transformers';
|
||||
import { Code } from 'astro:components';
|
||||
|
||||
const code = `const foo = 'hello'
|
||||
const bar = ' world'
|
||||
console.log(foo + bar) // [!code focus]
|
||||
`;
|
||||
---
|
||||
|
||||
<Code {code} lang="js" transformers={[transformerNotationFocus()]} />
|
||||
|
||||
<style is:global>
|
||||
pre.has-focused .line:not(.focused) {
|
||||
filter: blur(1px);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
- [#11134](https://github.com/withastro/astro/pull/11134) [`9042be0`](https://github.com/withastro/astro/commit/9042be049157ce859355f911565bc0c3d68f0aa1) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Improves the developer experience of the `500.astro` file by passing it a new `error` prop.
|
||||
|
||||
When an error is thrown, the special `src/pages/500.astro` page now automatically receives the error as a prop. This allows you to display more specific information about the error on a custom 500 page.
|
||||
|
||||
```astro
|
||||
---
|
||||
// src/pages/500.astro
|
||||
interface Props {
|
||||
error: unknown;
|
||||
}
|
||||
|
||||
const { error } = Astro.props;
|
||||
---
|
||||
|
||||
<div>{error instanceof Error ? error.message : 'Unknown error'}</div>
|
||||
```
|
||||
|
||||
If an error occurs rendering this page, your host's default 500 error page will be shown to your visitor in production, and Astro's default error overlay will be shown in development.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11280](https://github.com/withastro/astro/pull/11280) [`fd3645f`](https://github.com/withastro/astro/commit/fd3645fe8364ec5e280b6802d1468867890d463c) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes a bug that prevented cookies from being set when using experimental rewrites
|
||||
|
||||
- [#11275](https://github.com/withastro/astro/pull/11275) [`bab700d`](https://github.com/withastro/astro/commit/bab700d69085b1de8f03fc1b0b31651f709cbfe3) Thanks [@syhily](https://github.com/syhily)! - Drop duplicated brackets in data collections schema generation.
|
||||
|
||||
- [#11272](https://github.com/withastro/astro/pull/11272) [`ea987d7`](https://github.com/withastro/astro/commit/ea987d7da589ead9aa4b550f167f5e2f6c939d2e) Thanks [@ematipico](https://github.com/ematipico)! - Fixes a case where rewriting `/` would cause an issue, when `trailingSlash` was set to `"never"`.
|
||||
|
||||
- [#11272](https://github.com/withastro/astro/pull/11272) [`ea987d7`](https://github.com/withastro/astro/commit/ea987d7da589ead9aa4b550f167f5e2f6c939d2e) Thanks [@ematipico](https://github.com/ematipico)! - Reverts a logic where it wasn't possible to rewrite `/404` in static mode. It's **now possible** again
|
||||
|
||||
- [#11264](https://github.com/withastro/astro/pull/11264) [`5a9c9a6`](https://github.com/withastro/astro/commit/5a9c9a60e7c32aa461b86b5bc667cb955e23d4d9) Thanks [@Fryuni](https://github.com/Fryuni)! - Fixes type generation for empty content collections
|
||||
|
||||
- [#11279](https://github.com/withastro/astro/pull/11279) [`9a08d74`](https://github.com/withastro/astro/commit/9a08d74bc00ae2c3bc254f99580a22ce4df1d002) Thanks [@ascorbic](https://github.com/ascorbic)! - Improves type-checking and error handling to catch case where an image import is passed directly to `getImage()`
|
||||
|
||||
- [#11292](https://github.com/withastro/astro/pull/11292) [`7f8f347`](https://github.com/withastro/astro/commit/7f8f34799528ed0b2011e1ea273bd0636f6e767d) Thanks [@jdtjenkins](https://github.com/jdtjenkins)! - Fixes a case where `defineAction` autocomplete for the `accept` prop would not show `"form"` as a possible value
|
||||
|
||||
- [#11273](https://github.com/withastro/astro/pull/11273) [`cb4d078`](https://github.com/withastro/astro/commit/cb4d07819f0dbdfd94bc4f084edf7720ada01323) Thanks [@ascorbic](https://github.com/ascorbic)! - Corrects an inconsistency in dev where middleware would run for prerendered 404 routes.
|
||||
Middleware is not run for prerendered 404 routes in production, so this was incorrect.
|
||||
|
||||
- [#11284](https://github.com/withastro/astro/pull/11284) [`f4b029b`](https://github.com/withastro/astro/commit/f4b029b08264268c68fc81ea25b264e81f47e683) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes an issue that would break `Astro.request.url` and `Astro.request.headers` in `astro dev` if HTTP/2 was enabled.
|
||||
|
||||
HTTP/2 is now enabled by default in `astro dev` if `https` is configured in the Vite config.
|
||||
|
||||
## 4.10.3
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
"astro": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"typescript": "^5.4.5"
|
||||
"typescript": "^5.5.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"astro": "workspace:*",
|
||||
"react": "19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react-dom": "19.0.0-rc-fb9a90fa48-20240614",
|
||||
"typescript": "^5.4.5"
|
||||
"typescript": "^5.5.2"
|
||||
},
|
||||
"overrides": {
|
||||
"@types/react": "npm:types-react",
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"sass": "^1.77.5"
|
||||
"sass": "^1.77.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
"preact": "^10.22.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sass": "^1.77.5",
|
||||
"sass": "^1.77.6",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"private": true,
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"sass": "^1.77.5"
|
||||
"sass": "^1.77.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.17",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "astro dev"
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"svelte": "^4.2.18",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import Layout from '../components/Layout.astro';
|
|||
<a id="click-self" href="">go to top</a>
|
||||
<a id="click-redirect-two" href="/redirect-two">go to redirect 2</a>
|
||||
<a id="click-redirect-external" href="/redirect-external">go to a redirect external</a>
|
||||
<a id="click-redirect" href="/redirect">redirect cross-origin</a>
|
||||
<a id="click-404" href="/undefined-page">go to undefined page</a>
|
||||
<custom-a id="custom-click-two">
|
||||
<template shadowrootmode="open">
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
const myURL = Astro.request.url;
|
||||
const redirectTo = (myURL.startsWith("http://localhost")
|
||||
? myURL.replace("http://localhost","http://127.0.0.1")
|
||||
: myURL.replace("http://127.0.0.1", "http://localhost"))
|
||||
.replace("redirect","two");
|
||||
return Astro.redirect(redirectTo);
|
||||
---
|
||||
|
||||
<h1>Should not see this</h1>
|
|
@ -6,6 +6,6 @@
|
|||
"@astrojs/mdx": "workspace:*",
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.29"
|
||||
"vue": "^3.4.30"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -788,6 +788,25 @@ test.describe('View Transitions', () => {
|
|||
expect(loads.length, 'There should be 2 page loads').toEqual(2);
|
||||
});
|
||||
|
||||
test('Cross origin redirects do not raise errors', async ({ page, astro }) => {
|
||||
let consoleErrors = [];
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
consoleErrors.push(msg.text());
|
||||
}
|
||||
});
|
||||
// Go to page 1
|
||||
await page.goto(astro.resolveUrl('/one'));
|
||||
let p = page.locator('#one');
|
||||
await expect(p, 'should have content').toHaveText('Page 1');
|
||||
|
||||
await page.click('#click-redirect');
|
||||
p = page.locator('#two');
|
||||
await expect(p, 'should have content').toHaveText('Page 2');
|
||||
|
||||
expect(consoleErrors.length, 'There should be no errors').toEqual(0);
|
||||
});
|
||||
|
||||
test('client:only styles are retained on transition (1/2)', async ({ page, astro }) => {
|
||||
const totalExpectedStyles = 9;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "astro",
|
||||
"version": "4.10.3",
|
||||
"version": "4.11.3",
|
||||
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
||||
"type": "module",
|
||||
"author": "withastro",
|
||||
|
@ -123,7 +123,7 @@
|
|||
"test:node": "astro-scripts test \"test/**/*.test.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/compiler": "^2.8.0",
|
||||
"@astrojs/compiler": "^2.8.1",
|
||||
"@astrojs/internal-helpers": "workspace:*",
|
||||
"@astrojs/markdown-remark": "workspace:*",
|
||||
"@astrojs/telemetry": "workspace:*",
|
||||
|
@ -151,7 +151,7 @@
|
|||
"diff": "^5.2.0",
|
||||
"dlv": "^1.1.3",
|
||||
"dset": "^3.1.3",
|
||||
"es-module-lexer": "^1.5.3",
|
||||
"es-module-lexer": "^1.5.4",
|
||||
"esbuild": "^0.21.5",
|
||||
"estree-walker": "^3.0.3",
|
||||
"execa": "^8.0.1",
|
||||
|
@ -172,9 +172,8 @@
|
|||
"preferred-pm": "^3.1.3",
|
||||
"prompts": "^2.4.2",
|
||||
"rehype": "^13.0.1",
|
||||
"resolve": "^1.22.8",
|
||||
"semver": "^7.6.2",
|
||||
"shiki": "^1.6.5",
|
||||
"shiki": "^1.9.0",
|
||||
"string-width": "^7.1.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"tsconfck": "^3.1.0",
|
||||
|
@ -185,7 +184,7 @@
|
|||
"which-pm": "^2.2.0",
|
||||
"yargs-parser": "^21.1.1",
|
||||
"zod": "^3.23.8",
|
||||
"zod-to-json-schema": "^3.23.0"
|
||||
"zod-to-json-schema": "^3.23.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"sharp": "^0.33.3"
|
||||
|
@ -209,7 +208,6 @@
|
|||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/probe-image-size": "^7.2.4",
|
||||
"@types/prompts": "^2.4.9",
|
||||
"@types/resolve": "^1.20.6",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/send": "^0.17.4",
|
||||
"@types/unist": "^3.0.2",
|
||||
|
@ -220,17 +218,17 @@
|
|||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-mdx-jsx": "^3.1.2",
|
||||
"memfs": "^4.9.3",
|
||||
"node-mocks-http": "^1.14.1",
|
||||
"node-mocks-http": "^1.15.0",
|
||||
"parse-srcset": "^1.0.2",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"rehype-toc": "^3.0.2",
|
||||
"remark-code-titles": "^0.1.2",
|
||||
"rollup": "^4.18.0",
|
||||
"sass": "^1.77.5",
|
||||
"sass": "^1.77.6",
|
||||
"srcset-parse": "^1.1.0",
|
||||
"undici": "^6.19.2",
|
||||
"unified": "^11.0.4"
|
||||
"unified": "^11.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=21.0.0",
|
||||
|
|
|
@ -750,8 +750,13 @@ export interface AstroUserConfig {
|
|||
* @type {boolean}
|
||||
* @default `true`
|
||||
* @description
|
||||
* This is an option to minify your HTML output and reduce the size of your HTML files. By default, Astro removes all whitespace from your HTML, including line breaks, from `.astro` components. This occurs both in development mode and in the final build.
|
||||
* To disable HTML compression, set the `compressHTML` flag to `false`.
|
||||
*
|
||||
* This is an option to minify your HTML output and reduce the size of your HTML files.
|
||||
*
|
||||
* By default, Astro removes whitespace from your HTML, including line breaks, from `.astro` components in a lossless manner.
|
||||
* Some whitespace may be kept as needed to preserve the visual rendering of your HTML. This occurs both in development mode and in the final build.
|
||||
*
|
||||
* To disable HTML compression, set `compressHTML` to false.
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { createRequire } from 'node:module';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import boxen from 'boxen';
|
||||
import ci from 'ci-info';
|
||||
import { execa } from 'execa';
|
||||
|
@ -7,9 +6,9 @@ import { bold, cyan, dim, magenta } from 'kleur/colors';
|
|||
import ora from 'ora';
|
||||
import preferredPM from 'preferred-pm';
|
||||
import prompts from 'prompts';
|
||||
import resolvePackage from 'resolve';
|
||||
import whichPm from 'which-pm';
|
||||
import { type Logger } from '../core/logger/core.js';
|
||||
import type { Logger } from '../core/logger/core.js';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
type GetPackageOptions = {
|
||||
|
@ -25,17 +24,9 @@ export async function getPackage<T>(
|
|||
otherDeps: string[] = []
|
||||
): Promise<T | undefined> {
|
||||
try {
|
||||
// Custom resolution logic for @astrojs/db. Since it lives in our monorepo,
|
||||
// the generic tryResolve() method doesn't work.
|
||||
if (packageName === '@astrojs/db') {
|
||||
const packageJsonLoc = require.resolve(packageName + '/package.json', {
|
||||
paths: [options.cwd ?? process.cwd()],
|
||||
});
|
||||
const packageLoc = pathToFileURL(packageJsonLoc.replace(`package.json`, 'dist/index.js'));
|
||||
const packageImport = await import(packageLoc.toString());
|
||||
return packageImport as T;
|
||||
}
|
||||
await tryResolve(packageName, options.cwd ?? process.cwd());
|
||||
// Try to resolve with `createRequire` first to prevent ESM caching of the package
|
||||
// if it errors and fails here
|
||||
require.resolve(packageName, { paths: [options.cwd ?? process.cwd()] });
|
||||
const packageImport = await import(packageName);
|
||||
return packageImport as T;
|
||||
} catch (e) {
|
||||
|
@ -65,24 +56,6 @@ export async function getPackage<T>(
|
|||
}
|
||||
}
|
||||
|
||||
function tryResolve(packageName: string, cwd: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolvePackage(
|
||||
packageName,
|
||||
{
|
||||
basedir: cwd,
|
||||
},
|
||||
(err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(0);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getInstallCommand(packages: string[], packageManager: string) {
|
||||
switch (packageManager) {
|
||||
case 'npm':
|
||||
|
|
|
@ -48,7 +48,7 @@ export function getViteConfig(
|
|||
astroContentListenPlugin({ settings, logger, fs }),
|
||||
],
|
||||
},
|
||||
{ settings, logger, mode }
|
||||
{ settings, logger, mode, sync: false }
|
||||
);
|
||||
await runHookConfigDone({ settings, logger });
|
||||
return mergeConfig(viteConfig, userViteConfig);
|
||||
|
|
|
@ -14,8 +14,8 @@ import type {
|
|||
SSRManifest,
|
||||
SSRResult,
|
||||
} from '../@types/astro.js';
|
||||
import { validateConfig } from '../core/config/config.js';
|
||||
import { ASTRO_CONFIG_DEFAULTS } from '../core/config/schema.js';
|
||||
import { validateConfig } from '../core/config/validate.js';
|
||||
import { Logger } from '../core/logger/core.js';
|
||||
import { nodeLogDestination } from '../core/logger/node.js';
|
||||
import { removeLeadingForwardSlash } from '../core/path.js';
|
||||
|
@ -208,7 +208,7 @@ type AstroContainerConstructor = {
|
|||
renderers?: SSRLoadedRenderer[];
|
||||
manifest?: AstroContainerManifest;
|
||||
resolve?: SSRResult['resolve'];
|
||||
astroConfig: AstroConfig;
|
||||
astroConfig?: AstroConfig;
|
||||
};
|
||||
|
||||
export class experimental_AstroContainer {
|
||||
|
@ -253,10 +253,10 @@ export class experimental_AstroContainer {
|
|||
});
|
||||
}
|
||||
|
||||
async #containerResolve(specifier: string, astroConfig: AstroConfig): Promise<string> {
|
||||
async #containerResolve(specifier: string, astroConfig?: AstroConfig): Promise<string> {
|
||||
const found = this.#pipeline.manifest.entryModules[specifier];
|
||||
if (found) {
|
||||
return new URL(found, astroConfig.build.client).toString();
|
||||
return new URL(found, astroConfig?.build.client).toString();
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,10 @@ import type {
|
|||
} from '../@types/astro.js';
|
||||
import { type HeadElements, Pipeline } from '../core/base-pipeline.js';
|
||||
import type { SinglePageBuiltModule } from '../core/build/types.js';
|
||||
import { RouteNotFound } from '../core/errors/errors-data.js';
|
||||
import { AstroError } from '../core/errors/index.js';
|
||||
import {
|
||||
createModuleScriptElement,
|
||||
createStylesheetElementSet,
|
||||
} from '../core/render/ssr-element.js';
|
||||
import { DEFAULT_404_ROUTE } from '../core/routing/astro-designed-error-pages.js';
|
||||
import { findRouteToRewrite } from '../core/routing/rewrite.js';
|
||||
|
||||
export class ContainerPipeline extends Pipeline {
|
||||
|
|
|
@ -3,12 +3,13 @@ import { extname } from 'node:path';
|
|||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import glob from 'fast-glob';
|
||||
import pLimit from 'p-limit';
|
||||
import { type Plugin } from 'vite';
|
||||
import type { Plugin } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
import { encodeName } from '../core/build/util.js';
|
||||
import { AstroError, AstroErrorData } from '../core/errors/index.js';
|
||||
import { appendForwardSlash, removeFileExtension } from '../core/path.js';
|
||||
import { isServerLikeOutput, rootRelativePath } from '../core/util.js';
|
||||
import { isServerLikeOutput } from '../core/util.js';
|
||||
import { rootRelativePath } from '../core/viteUtils.js';
|
||||
import type { AstroPluginMetadata } from '../vite-plugin-astro/index.js';
|
||||
import {
|
||||
CONTENT_FLAG,
|
||||
|
|
|
@ -139,7 +139,7 @@ class AstroBuilder {
|
|||
middlewareMode: true,
|
||||
},
|
||||
},
|
||||
{ settings: this.settings, logger: this.logger, mode: 'build', command: 'build' }
|
||||
{ settings: this.settings, logger: this.logger, mode: 'build', command: 'build', sync: false }
|
||||
);
|
||||
await runHookConfigDone({ settings: this.settings, logger: logger });
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ export function vitePluginAnalyzer(
|
|||
): VitePlugin {
|
||||
function hoistedScriptScanner() {
|
||||
const uniqueHoistedIds = new Map<string, string>();
|
||||
const pageScripts = new Map<
|
||||
const pageScriptsMap = new Map<
|
||||
string,
|
||||
{
|
||||
hoistedSet: Set<string>;
|
||||
|
@ -54,20 +54,22 @@ export function vitePluginAnalyzer(
|
|||
if (hoistedScripts.size) {
|
||||
for (const parentInfo of getParentModuleInfos(from, this, isPropagatedAsset)) {
|
||||
if (isPropagatedAsset(parentInfo.id)) {
|
||||
for (const hid of hoistedScripts) {
|
||||
if (!internals.propagatedScriptsMap.has(parentInfo.id)) {
|
||||
internals.propagatedScriptsMap.set(parentInfo.id, new Set());
|
||||
}
|
||||
internals.propagatedScriptsMap.get(parentInfo.id)?.add(hid);
|
||||
const propagatedScripts = internals.propagatedScriptsMap.get(parentInfo.id)!;
|
||||
for (const hid of hoistedScripts) {
|
||||
propagatedScripts.add(hid);
|
||||
}
|
||||
} else if (moduleIsTopLevelPage(parentInfo)) {
|
||||
for (const hid of hoistedScripts) {
|
||||
if (!pageScripts.has(parentInfo.id)) {
|
||||
pageScripts.set(parentInfo.id, {
|
||||
if (!pageScriptsMap.has(parentInfo.id)) {
|
||||
pageScriptsMap.set(parentInfo.id, {
|
||||
hoistedSet: new Set(),
|
||||
});
|
||||
}
|
||||
pageScripts.get(parentInfo.id)?.hoistedSet.add(hid);
|
||||
const pageScripts = pageScriptsMap.get(parentInfo.id)!;
|
||||
for (const hid of hoistedScripts) {
|
||||
pageScripts.hoistedSet.add(hid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +85,7 @@ export function vitePluginAnalyzer(
|
|||
}
|
||||
}
|
||||
|
||||
for (const [pageId, { hoistedSet }] of pageScripts) {
|
||||
for (const [pageId, { hoistedSet }] of pageScriptsMap) {
|
||||
const pageData = getPageDataByViteID(internals, pageId);
|
||||
if (!pageData) continue;
|
||||
|
||||
|
|
|
@ -508,11 +508,14 @@ export function pluginContent(
|
|||
return;
|
||||
}
|
||||
// Cache build output of chunks and assets
|
||||
const promises: Promise<void[] | undefined>[] = [];
|
||||
for (const { cached, dist } of cachedBuildOutput) {
|
||||
if (fsMod.existsSync(dist)) {
|
||||
await copyFiles(dist, cached, true);
|
||||
promises.push(copyFiles(dist, cached, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (promises.length) await Promise.all(promises);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import glob from 'fast-glob';
|
||||
import type { OutputChunk } from 'rollup';
|
||||
import { type Plugin as VitePlugin } from 'vite';
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import { getAssetsPrefix } from '../../../assets/utils/getAssetsPrefix.js';
|
||||
import { normalizeTheLocale } from '../../../i18n/index.js';
|
||||
import { toRoutingStrategy } from '../../../i18n/utils.js';
|
||||
|
|
|
@ -9,7 +9,7 @@ import type { AstroPreferences } from '../../preferences/index.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 { resolvePath } from '../viteUtils.js';
|
||||
import { type PartialCompileCssResult, createStylePreprocessor } from './style.js';
|
||||
import type { CompileCssResult } from './types.js';
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import * as colors from 'kleur/colors';
|
||||
import type { Arguments as Flags } from 'yargs-parser';
|
||||
import { ZodError } from 'zod';
|
||||
import type {
|
||||
AstroConfig,
|
||||
AstroInlineConfig,
|
||||
|
@ -6,49 +11,14 @@ import type {
|
|||
AstroUserConfig,
|
||||
CLIFlags,
|
||||
} from '../../@types/astro.js';
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import * as colors from 'kleur/colors';
|
||||
import { ZodError } from 'zod';
|
||||
import { eventConfigError, telemetry } from '../../events/index.js';
|
||||
import { trackAstroConfigZodError } from '../errors/errors.js';
|
||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||
import { formatConfigErrorMessage } from '../messages.js';
|
||||
import { mergeConfig } from './merge.js';
|
||||
import { createRelativeSchema } from './schema.js';
|
||||
import { validateConfig } from './validate.js';
|
||||
import { loadConfigWithVite } from './vite-load.js';
|
||||
|
||||
/** Turn raw config values into normalized values */
|
||||
export async function validateConfig(
|
||||
userConfig: any,
|
||||
root: string,
|
||||
cmd: string
|
||||
): Promise<AstroConfig> {
|
||||
const AstroConfigRelativeSchema = createRelativeSchema(cmd, root);
|
||||
|
||||
// First-Pass Validation
|
||||
let result: AstroConfig;
|
||||
try {
|
||||
result = await AstroConfigRelativeSchema.parseAsync(userConfig);
|
||||
} catch (e) {
|
||||
// Improve config zod error messages
|
||||
if (e instanceof ZodError) {
|
||||
// Mark this error so the callee can decide to suppress Zod's error if needed.
|
||||
// We still want to throw the error to signal an error in validation.
|
||||
trackAstroConfigZodError(e);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(formatConfigErrorMessage(e) + '\n');
|
||||
telemetry.record(eventConfigError({ cmd, err: e, isFatal: true }));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
// If successful, return the result as a verified AstroConfig object.
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Convert the generic "yargs" flag object into our own, custom TypeScript object. */
|
||||
// NOTE: This function will be removed in a later PR. Use `flagsToAstroInlineConfig` instead.
|
||||
// All CLI related flow should be located in the `packages/astro/src/cli` directory.
|
||||
|
@ -197,7 +167,22 @@ export async function resolveConfig(
|
|||
|
||||
const userConfig = await loadConfig(root, inlineOnlyConfig.configFile, fsMod);
|
||||
const mergedConfig = mergeConfig(userConfig, inlineUserConfig);
|
||||
const astroConfig = await validateConfig(mergedConfig, root, command);
|
||||
// First-Pass Validation
|
||||
let astroConfig: AstroConfig;
|
||||
try {
|
||||
astroConfig = await validateConfig(mergedConfig, root, command);
|
||||
} catch (e) {
|
||||
// Improve config zod error messages
|
||||
if (e instanceof ZodError) {
|
||||
// Mark this error so the callee can decide to suppress Zod's error if needed.
|
||||
// We still want to throw the error to signal an error in validation.
|
||||
trackAstroConfigZodError(e);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(formatConfigErrorMessage(e) + '\n');
|
||||
telemetry.record(eventConfigError({ cmd: command, err: e, isFatal: true }));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
return { userConfig: mergedConfig, astroConfig };
|
||||
}
|
||||
|
|
14
packages/astro/src/core/config/validate.ts
Normal file
14
packages/astro/src/core/config/validate.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import type { AstroConfig } from '../../@types/astro.js';
|
||||
import { createRelativeSchema } from './schema.js';
|
||||
|
||||
/** Turn raw config values into normalized values */
|
||||
export async function validateConfig(
|
||||
userConfig: any,
|
||||
root: string,
|
||||
cmd: string
|
||||
): Promise<AstroConfig> {
|
||||
const AstroConfigRelativeSchema = createRelativeSchema(cmd, root);
|
||||
|
||||
// First-Pass Validation
|
||||
return await AstroConfigRelativeSchema.parseAsync(userConfig);
|
||||
}
|
|
@ -191,6 +191,19 @@ class AstroCookies implements AstroCookiesInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a new AstroCookies instance into the current instance. Any new cookies
|
||||
* will be added to the current instance, overwriting any existing cookies with the same name.
|
||||
*/
|
||||
merge(cookies: AstroCookies) {
|
||||
const outgoing = cookies.#outgoing;
|
||||
if (outgoing) {
|
||||
for (const [key, value] of outgoing) {
|
||||
this.#ensureOutgoingMap().set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Astro.cookies.header() returns an iterator for the cookies that have previously
|
||||
* been set by either Astro.cookies.set() or Astro.cookies.delete().
|
||||
|
|
|
@ -10,7 +10,7 @@ export function responseHasCookies(response: Response): boolean {
|
|||
return Reflect.has(response, astroCookiesSymbol);
|
||||
}
|
||||
|
||||
function getFromResponse(response: Response): AstroCookies | undefined {
|
||||
export function getCookiesFromResponse(response: Response): AstroCookies | undefined {
|
||||
let cookies = Reflect.get(response, astroCookiesSymbol);
|
||||
if (cookies != null) {
|
||||
return cookies as AstroCookies;
|
||||
|
@ -20,7 +20,7 @@ function getFromResponse(response: Response): AstroCookies | undefined {
|
|||
}
|
||||
|
||||
export function* getSetCookiesFromResponse(response: Response): Generator<string, string[]> {
|
||||
const cookies = getFromResponse(response);
|
||||
const cookies = getCookiesFromResponse(response);
|
||||
if (!cookies) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ interface CreateViteOptions {
|
|||
// will be undefined when using `getViteConfig`
|
||||
command?: 'dev' | 'build';
|
||||
fs?: typeof nodeFs;
|
||||
sync: boolean;
|
||||
}
|
||||
|
||||
const ALWAYS_NOEXTERNAL = [
|
||||
|
@ -74,7 +75,7 @@ const ONLY_DEV_EXTERNAL = [
|
|||
/** Return a base vite config as a common starting point for all Vite commands. */
|
||||
export async function createVite(
|
||||
commandConfig: vite.InlineConfig,
|
||||
{ settings, logger, mode, command, fs = nodeFs }: CreateViteOptions
|
||||
{ settings, logger, mode, command, fs = nodeFs, sync }: CreateViteOptions
|
||||
): Promise<vite.InlineConfig> {
|
||||
const astroPkgsConfig = await crawlFrameworkPkgs({
|
||||
root: fileURLToPath(settings.config.root),
|
||||
|
@ -137,7 +138,7 @@ export async function createVite(
|
|||
// the build to run very slow as the filewatcher is triggered often.
|
||||
mode !== 'build' && vitePluginAstroServer({ settings, logger, fs }),
|
||||
envVitePlugin({ settings }),
|
||||
astroEnv({ settings, mode, fs }),
|
||||
astroEnv({ settings, mode, fs, sync }),
|
||||
markdownVitePlugin({ settings, logger }),
|
||||
htmlVitePlugin(),
|
||||
mdxVitePlugin(),
|
||||
|
|
|
@ -74,7 +74,7 @@ export async function createContainer({
|
|||
include: rendererClientEntries,
|
||||
},
|
||||
},
|
||||
{ settings, logger, mode: 'dev', command: 'dev', fs }
|
||||
{ settings, logger, mode: 'dev', command: 'dev', fs, sync: false }
|
||||
);
|
||||
await runHookConfigDone({ settings, logger });
|
||||
const viteServer = await vite.createServer(viteConfig);
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
responseSentSymbol,
|
||||
} from './constants.js';
|
||||
import { AstroCookies, attachCookiesToResponse } from './cookies/index.js';
|
||||
import { getCookiesFromResponse } from './cookies/response.js';
|
||||
import { AstroError, AstroErrorData } from './errors/index.js';
|
||||
import { callMiddleware } from './middleware/callMiddleware.js';
|
||||
import { sequence } from './middleware/index.js';
|
||||
|
@ -135,6 +136,7 @@ export class RenderContext {
|
|||
const lastNext = async (ctx: APIContext, payload?: RewritePayload) => {
|
||||
if (payload) {
|
||||
if (this.pipeline.manifest.rewritingEnabled) {
|
||||
pipeline.logger.debug('router', 'Called rewriting to:', payload);
|
||||
// we intentionally let the error bubble up
|
||||
const [routeData, component] = await pipeline.tryRewrite(
|
||||
payload,
|
||||
|
@ -145,20 +147,23 @@ export class RenderContext {
|
|||
componentInstance = component;
|
||||
this.isRewriting = true;
|
||||
} else {
|
||||
this.pipeline.logger.warn(
|
||||
this.pipeline.logger.error(
|
||||
'router',
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.'
|
||||
);
|
||||
}
|
||||
}
|
||||
let response: Response;
|
||||
|
||||
switch (this.routeData.type) {
|
||||
case 'endpoint':
|
||||
return renderEndpoint(componentInstance as any, ctx, serverLike, logger);
|
||||
case 'endpoint': {
|
||||
response = await renderEndpoint(componentInstance as any, ctx, serverLike, logger);
|
||||
break;
|
||||
}
|
||||
case 'redirect':
|
||||
return renderRedirect(this);
|
||||
case 'page': {
|
||||
const result = await this.createResult(componentInstance!);
|
||||
let response: Response;
|
||||
try {
|
||||
response = await renderPage(
|
||||
result,
|
||||
|
@ -185,12 +190,19 @@ export class RenderContext {
|
|||
) {
|
||||
response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no');
|
||||
}
|
||||
return response;
|
||||
break;
|
||||
}
|
||||
case 'fallback': {
|
||||
return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: 'fallback' } });
|
||||
}
|
||||
}
|
||||
// We need to merge the cookies from the response back into this.cookies
|
||||
// because they may need to be passed along from a rewrite.
|
||||
const responseCookies = getCookiesFromResponse(response);
|
||||
if (responseCookies) {
|
||||
cookies.merge(responseCookies);
|
||||
}
|
||||
return response;
|
||||
};
|
||||
|
||||
const response = await callMiddleware(
|
||||
|
@ -227,6 +239,20 @@ export class RenderContext {
|
|||
|
||||
const rewrite = async (reroutePayload: RewritePayload) => {
|
||||
pipeline.logger.debug('router', 'Called rewriting to:', reroutePayload);
|
||||
if (!this.pipeline.manifest.rewritingEnabled) {
|
||||
this.pipeline.logger.error(
|
||||
'router',
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.'
|
||||
);
|
||||
return new Response(
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.',
|
||||
{
|
||||
status: 500,
|
||||
statusText:
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.',
|
||||
}
|
||||
);
|
||||
}
|
||||
const [routeData, component, newURL] = await pipeline.tryRewrite(
|
||||
reroutePayload,
|
||||
this.request,
|
||||
|
@ -421,6 +447,20 @@ export class RenderContext {
|
|||
};
|
||||
|
||||
const rewrite = async (reroutePayload: RewritePayload) => {
|
||||
if (!this.pipeline.manifest.rewritingEnabled) {
|
||||
this.pipeline.logger.error(
|
||||
'router',
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.'
|
||||
);
|
||||
return new Response(
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.',
|
||||
{
|
||||
status: 500,
|
||||
statusText:
|
||||
'The rewrite API is experimental. To use this feature, add the `rewriting` flag to the `experimental` object in your Astro config.',
|
||||
}
|
||||
);
|
||||
}
|
||||
pipeline.logger.debug('router', 'Calling rewrite: ', reroutePayload);
|
||||
const [routeData, component, newURL] = await pipeline.tryRewrite(
|
||||
reroutePayload,
|
||||
|
|
|
@ -7,6 +7,7 @@ import type { AstroConfig, AstroInlineConfig, AstroSettings } from '../../@types
|
|||
import { getPackage } from '../../cli/install-package.js';
|
||||
import { createContentTypesGenerator } from '../../content/index.js';
|
||||
import { globalContentConfigObserver } from '../../content/utils.js';
|
||||
import { syncAstroEnv } from '../../env/sync.js';
|
||||
import { telemetry } from '../../events/index.js';
|
||||
import { eventCliSession } from '../../events/session.js';
|
||||
import { runHookConfigSetup } from '../../integrations/hooks.js';
|
||||
|
@ -83,6 +84,7 @@ export default async function sync(
|
|||
await dbPackage?.typegen?.(astroConfig);
|
||||
const exitCode = await syncContentCollections(settings, { ...options, logger });
|
||||
if (exitCode !== 0) return exitCode;
|
||||
syncAstroEnv(settings, options?.fs);
|
||||
|
||||
logger.info(null, `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`);
|
||||
return 0;
|
||||
|
@ -123,7 +125,7 @@ export async function syncContentCollections(
|
|||
ssr: { external: [] },
|
||||
logLevel: 'silent',
|
||||
},
|
||||
{ settings, logger, mode: 'build', command: 'build', fs }
|
||||
{ settings, logger, mode: 'build', command: 'build', fs, sync: true }
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { normalizePath } from 'vite';
|
||||
import type { AstroConfig, AstroSettings, RouteType } from '../@types/astro.js';
|
||||
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './constants.js';
|
||||
import type { ModuleLoader } from './module-loader/index.js';
|
||||
import { prependForwardSlash, removeTrailingForwardSlash, slash } from './path.js';
|
||||
import { removeTrailingForwardSlash, slash } from './path.js';
|
||||
|
||||
/** Returns true if argument is an object of any prototype/class (but not null). */
|
||||
export function isObject(value: unknown): value is Record<string, any> {
|
||||
|
@ -184,54 +182,10 @@ export function relativeToSrcDir(config: AstroConfig, idOrUrl: URL | string) {
|
|||
return id.slice(slash(fileURLToPath(config.srcDir)).length);
|
||||
}
|
||||
|
||||
export function rootRelativePath(
|
||||
root: URL,
|
||||
idOrUrl: URL | string,
|
||||
shouldPrependForwardSlash = true
|
||||
) {
|
||||
let id: string;
|
||||
if (typeof idOrUrl !== 'string') {
|
||||
id = unwrapId(viteID(idOrUrl));
|
||||
} else {
|
||||
id = idOrUrl;
|
||||
}
|
||||
const normalizedRoot = normalizePath(fileURLToPath(root));
|
||||
if (id.startsWith(normalizedRoot)) {
|
||||
id = id.slice(normalizedRoot.length);
|
||||
}
|
||||
return shouldPrependForwardSlash ? prependForwardSlash(id) : id;
|
||||
}
|
||||
|
||||
export function emoji(char: string, fallback: string) {
|
||||
return process.platform !== 'win32' ? char : fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate Vite's resolve and import analysis so we can import the id as an URL
|
||||
* through a script tag or a dynamic import as-is.
|
||||
*/
|
||||
// NOTE: `/@id/` should only be used when the id is fully resolved
|
||||
export async function resolveIdToUrl(loader: ModuleLoader, id: string, root?: URL) {
|
||||
let resultId = await loader.resolveId(id, undefined);
|
||||
// Try resolve jsx to tsx
|
||||
if (!resultId && id.endsWith('.jsx')) {
|
||||
resultId = await loader.resolveId(id.slice(0, -4), undefined);
|
||||
}
|
||||
if (!resultId) {
|
||||
return VALID_ID_PREFIX + id;
|
||||
}
|
||||
if (path.isAbsolute(resultId)) {
|
||||
const normalizedRoot = root && normalizePath(fileURLToPath(root));
|
||||
// Convert to root-relative path if path is inside root
|
||||
if (normalizedRoot && resultId.startsWith(normalizedRoot)) {
|
||||
return resultId.slice(normalizedRoot.length - 1);
|
||||
} else {
|
||||
return '/@fs' + prependForwardSlash(resultId);
|
||||
}
|
||||
}
|
||||
return VALID_ID_PREFIX + resultId;
|
||||
}
|
||||
|
||||
export function resolveJsToTs(filePath: string) {
|
||||
if (filePath.endsWith('.jsx') && !fs.existsSync(filePath)) {
|
||||
const tryPath = filePath.slice(0, -4) + '.tsx';
|
||||
|
@ -242,18 +196,6 @@ export function resolveJsToTs(filePath: string) {
|
|||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the hydration paths so that it can be imported in the client
|
||||
*/
|
||||
export function resolvePath(specifier: string, importer: string) {
|
||||
if (specifier.startsWith('.')) {
|
||||
const absoluteSpecifier = path.resolve(path.dirname(importer), specifier);
|
||||
return resolveJsToTs(normalizePath(absoluteSpecifier));
|
||||
} else {
|
||||
return specifier;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a default NODE_ENV so Vite doesn't set an incorrect default when loading the Astro config
|
||||
*/
|
||||
|
|
62
packages/astro/src/core/viteUtils.ts
Normal file
62
packages/astro/src/core/viteUtils.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { normalizePath } from 'vite';
|
||||
import { prependForwardSlash } from '../core/path.js';
|
||||
import type { ModuleLoader } from './module-loader/index.js';
|
||||
import { VALID_ID_PREFIX, resolveJsToTs, unwrapId, viteID } from './util.js';
|
||||
|
||||
/**
|
||||
* Resolve the hydration paths so that it can be imported in the client
|
||||
*/
|
||||
export function resolvePath(specifier: string, importer: string) {
|
||||
if (specifier.startsWith('.')) {
|
||||
const absoluteSpecifier = path.resolve(path.dirname(importer), specifier);
|
||||
return resolveJsToTs(normalizePath(absoluteSpecifier));
|
||||
} else {
|
||||
return specifier;
|
||||
}
|
||||
}
|
||||
|
||||
export function rootRelativePath(
|
||||
root: URL,
|
||||
idOrUrl: URL | string,
|
||||
shouldPrependForwardSlash = true
|
||||
) {
|
||||
let id: string;
|
||||
if (typeof idOrUrl !== 'string') {
|
||||
id = unwrapId(viteID(idOrUrl));
|
||||
} else {
|
||||
id = idOrUrl;
|
||||
}
|
||||
const normalizedRoot = normalizePath(fileURLToPath(root));
|
||||
if (id.startsWith(normalizedRoot)) {
|
||||
id = id.slice(normalizedRoot.length);
|
||||
}
|
||||
return shouldPrependForwardSlash ? prependForwardSlash(id) : id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate Vite's resolve and import analysis so we can import the id as an URL
|
||||
* through a script tag or a dynamic import as-is.
|
||||
*/
|
||||
// NOTE: `/@id/` should only be used when the id is fully resolved
|
||||
export async function resolveIdToUrl(loader: ModuleLoader, id: string, root?: URL) {
|
||||
let resultId = await loader.resolveId(id, undefined);
|
||||
// Try resolve jsx to tsx
|
||||
if (!resultId && id.endsWith('.jsx')) {
|
||||
resultId = await loader.resolveId(id.slice(0, -4), undefined);
|
||||
}
|
||||
if (!resultId) {
|
||||
return VALID_ID_PREFIX + id;
|
||||
}
|
||||
if (path.isAbsolute(resultId)) {
|
||||
const normalizedRoot = root && normalizePath(fileURLToPath(root));
|
||||
// Convert to root-relative path if path is inside root
|
||||
if (normalizedRoot && resultId.startsWith(normalizedRoot)) {
|
||||
return resultId.slice(normalizedRoot.length - 1);
|
||||
} else {
|
||||
return '/@fs' + prependForwardSlash(resultId);
|
||||
}
|
||||
}
|
||||
return VALID_ID_PREFIX + resultId;
|
||||
}
|
30
packages/astro/src/env/sync.ts
vendored
Normal file
30
packages/astro/src/env/sync.ts
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
import fsMod from 'node:fs';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
import { ENV_TYPES_FILE, TYPES_TEMPLATE_URL } from './constants.js';
|
||||
import { getEnvFieldType } from './validators.js';
|
||||
|
||||
export function syncAstroEnv(settings: AstroSettings, fs = fsMod) {
|
||||
if (!settings.config.experimental.env) {
|
||||
return;
|
||||
}
|
||||
|
||||
const schema = settings.config.experimental.env.schema ?? {};
|
||||
|
||||
let client = '';
|
||||
let server = '';
|
||||
|
||||
for (const [key, options] of Object.entries(schema)) {
|
||||
const str = `export const ${key}: ${getEnvFieldType(options)}; \n`;
|
||||
if (options.context === 'client') {
|
||||
client += str;
|
||||
} else {
|
||||
server += str;
|
||||
}
|
||||
}
|
||||
|
||||
const template = fs.readFileSync(TYPES_TEMPLATE_URL, 'utf-8');
|
||||
const dts = template.replace('// @@CLIENT@@', client).replace('// @@SERVER@@', server);
|
||||
|
||||
fs.mkdirSync(settings.dotAstroDir, { recursive: true });
|
||||
fs.writeFileSync(new URL(ENV_TYPES_FILE, settings.dotAstroDir), dts, 'utf-8');
|
||||
}
|
106
packages/astro/src/env/vite-plugin-env.ts
vendored
106
packages/astro/src/env/vite-plugin-env.ts
vendored
|
@ -4,14 +4,12 @@ import { type Plugin, loadEnv } from 'vite';
|
|||
import type { AstroSettings } from '../@types/astro.js';
|
||||
import { AstroError, AstroErrorData } from '../core/errors/index.js';
|
||||
import {
|
||||
ENV_TYPES_FILE,
|
||||
MODULE_TEMPLATE_URL,
|
||||
TYPES_TEMPLATE_URL,
|
||||
VIRTUAL_MODULES_IDS,
|
||||
VIRTUAL_MODULES_IDS_VALUES,
|
||||
} from './constants.js';
|
||||
import type { EnvSchema } from './schema.js';
|
||||
import { getEnvFieldType, validateEnvVariable } from './validators.js';
|
||||
import { validateEnvVariable } from './validators.js';
|
||||
|
||||
// TODO: reminders for when astro:env comes out of experimental
|
||||
// Types should always be generated (like in types/content.d.ts). That means the client module will be empty
|
||||
|
@ -23,14 +21,16 @@ interface AstroEnvVirtualModPluginParams {
|
|||
settings: AstroSettings;
|
||||
mode: 'dev' | 'build' | string;
|
||||
fs: typeof fsMod;
|
||||
sync: boolean;
|
||||
}
|
||||
|
||||
export function astroEnv({
|
||||
settings,
|
||||
mode,
|
||||
fs,
|
||||
sync,
|
||||
}: AstroEnvVirtualModPluginParams): Plugin | undefined {
|
||||
if (!settings.config.experimental.env) {
|
||||
if (!settings.config.experimental.env || sync) {
|
||||
return;
|
||||
}
|
||||
const schema = settings.config.experimental.env.schema ?? {};
|
||||
|
@ -54,23 +54,10 @@ export function astroEnv({
|
|||
|
||||
const validatedVariables = validatePublicVariables({ schema, loadedEnv });
|
||||
|
||||
const clientTemplates = getClientTemplates({ validatedVariables });
|
||||
const serverTemplates = getServerTemplates({ validatedVariables, schema, fs });
|
||||
|
||||
templates = {
|
||||
client: clientTemplates.module,
|
||||
server: serverTemplates.module,
|
||||
...getTemplates(schema, fs, validatedVariables),
|
||||
internal: `export const schema = ${JSON.stringify(schema)};`,
|
||||
};
|
||||
generateDts({
|
||||
settings,
|
||||
fs,
|
||||
content: getDts({
|
||||
fs,
|
||||
client: clientTemplates.types,
|
||||
server: serverTemplates.types,
|
||||
}),
|
||||
});
|
||||
},
|
||||
buildEnd() {
|
||||
templates = null;
|
||||
|
@ -104,19 +91,6 @@ function resolveVirtualModuleId<T extends string>(id: T): `\0${T}` {
|
|||
return `\0${id}`;
|
||||
}
|
||||
|
||||
function generateDts({
|
||||
content,
|
||||
settings,
|
||||
fs,
|
||||
}: {
|
||||
content: string;
|
||||
settings: AstroSettings;
|
||||
fs: typeof fsMod;
|
||||
}) {
|
||||
fs.mkdirSync(settings.dotAstroDir, { recursive: true });
|
||||
fs.writeFileSync(new URL(ENV_TYPES_FILE, settings.dotAstroDir), content, 'utf-8');
|
||||
}
|
||||
|
||||
function validatePublicVariables({
|
||||
schema,
|
||||
loadedEnv,
|
||||
|
@ -152,55 +126,22 @@ function validatePublicVariables({
|
|||
return valid;
|
||||
}
|
||||
|
||||
function getDts({
|
||||
client,
|
||||
server,
|
||||
fs,
|
||||
}: {
|
||||
client: string;
|
||||
server: string;
|
||||
fs: typeof fsMod;
|
||||
}) {
|
||||
const template = fs.readFileSync(TYPES_TEMPLATE_URL, 'utf-8');
|
||||
|
||||
return template.replace('// @@CLIENT@@', client).replace('// @@SERVER@@', server);
|
||||
}
|
||||
|
||||
function getClientTemplates({
|
||||
validatedVariables,
|
||||
}: {
|
||||
validatedVariables: ReturnType<typeof validatePublicVariables>;
|
||||
}) {
|
||||
let module = '';
|
||||
let types = '';
|
||||
|
||||
for (const { key, type, value } of validatedVariables.filter((e) => e.context === 'client')) {
|
||||
module += `export const ${key} = ${JSON.stringify(value)};`;
|
||||
types += `export const ${key}: ${type}; \n`;
|
||||
}
|
||||
|
||||
return {
|
||||
module,
|
||||
types,
|
||||
};
|
||||
}
|
||||
|
||||
function getServerTemplates({
|
||||
validatedVariables,
|
||||
schema,
|
||||
fs,
|
||||
}: {
|
||||
validatedVariables: ReturnType<typeof validatePublicVariables>;
|
||||
schema: EnvSchema;
|
||||
fs: typeof fsMod;
|
||||
}) {
|
||||
let module = fs.readFileSync(MODULE_TEMPLATE_URL, 'utf-8');
|
||||
let types = '';
|
||||
function getTemplates(
|
||||
schema: EnvSchema,
|
||||
fs: typeof fsMod,
|
||||
validatedVariables: ReturnType<typeof validatePublicVariables>
|
||||
) {
|
||||
let client = '';
|
||||
let server = fs.readFileSync(MODULE_TEMPLATE_URL, 'utf-8');
|
||||
let onSetGetEnv = '';
|
||||
|
||||
for (const { key, type, value } of validatedVariables.filter((e) => e.context === 'server')) {
|
||||
module += `export const ${key} = ${JSON.stringify(value)};`;
|
||||
types += `export const ${key}: ${type}; \n`;
|
||||
for (const { key, value, context } of validatedVariables) {
|
||||
const str = `export const ${key} = ${JSON.stringify(value)};`;
|
||||
if (context === 'client') {
|
||||
client += str;
|
||||
} else {
|
||||
server += str;
|
||||
}
|
||||
}
|
||||
|
||||
for (const [key, options] of Object.entries(schema)) {
|
||||
|
@ -208,15 +149,14 @@ function getServerTemplates({
|
|||
continue;
|
||||
}
|
||||
|
||||
types += `export const ${key}: ${getEnvFieldType(options)}; \n`;
|
||||
module += `export let ${key} = _internalGetSecret(${JSON.stringify(key)});\n`;
|
||||
server += `export let ${key} = _internalGetSecret(${JSON.stringify(key)});\n`;
|
||||
onSetGetEnv += `${key} = reset ? undefined : _internalGetSecret(${JSON.stringify(key)});\n`;
|
||||
}
|
||||
|
||||
module = module.replace('// @@ON_SET_GET_ENV@@', onSetGetEnv);
|
||||
server = server.replace('// @@ON_SET_GET_ENV@@', onSetGetEnv);
|
||||
|
||||
return {
|
||||
module,
|
||||
types,
|
||||
client,
|
||||
server,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { PluginObj } from '@babel/core';
|
|||
import * as t from '@babel/types';
|
||||
import { AstroError } from '../core/errors/errors.js';
|
||||
import { AstroErrorData } from '../core/errors/index.js';
|
||||
import { resolvePath } from '../core/util.js';
|
||||
import { resolvePath } from '../core/viteUtils.js';
|
||||
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
|
||||
|
||||
const ClientOnlyPlaceholder = 'astro-client-only';
|
||||
|
|
|
@ -9,7 +9,7 @@ import { visit } from 'unist-util-visit';
|
|||
import type { VFile } from 'vfile';
|
||||
import { AstroError } from '../core/errors/errors.js';
|
||||
import { AstroErrorData } from '../core/errors/index.js';
|
||||
import { resolvePath } from '../core/util.js';
|
||||
import { resolvePath } from '../core/viteUtils.js';
|
||||
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
|
||||
|
||||
// This import includes ambient types for hast to include mdx nodes
|
||||
|
|
|
@ -45,7 +45,7 @@ export class DevToolbarTooltip extends HTMLElement {
|
|||
|
||||
svg {
|
||||
vertical-align: bottom;
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
hr {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { RouteData, SSRResult } from '../../../@types/astro.js';
|
||||
import type { AstroConfig, RouteData, SSRResult } from '../../../@types/astro.js';
|
||||
import { type NonAstroPageComponent, renderComponentToString } from './component.js';
|
||||
import type { AstroComponentFactory } from './index.js';
|
||||
|
||||
|
@ -85,6 +85,16 @@ export async function renderPage(
|
|||
if (route?.component.endsWith('.md')) {
|
||||
headers.set('Content-Type', 'text/html; charset=utf-8');
|
||||
}
|
||||
const response = new Response(body, { ...init, headers });
|
||||
return response;
|
||||
let status = init.status;
|
||||
// Custom 404.astro and 500.astro are particular routes that must return a fixed status code
|
||||
if (route?.route === '/404') {
|
||||
status = 404;
|
||||
} else if (route?.route === '/500') {
|
||||
status = 500;
|
||||
}
|
||||
if (status) {
|
||||
return new Response(body, { ...init, headers, status });
|
||||
} else {
|
||||
return new Response(body, { ...init, headers });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -418,7 +418,13 @@ async function transition(
|
|||
}
|
||||
// if there was a redirection, show the final URL in the browser's address bar
|
||||
if (response.redirected) {
|
||||
preparationEvent.to = new URL(response.redirected);
|
||||
const redirectedTo = new URL(response.redirected);
|
||||
// but do not redirect cross origin
|
||||
if (redirectedTo.origin !== preparationEvent.to.origin) {
|
||||
preparationEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
preparationEvent.to = redirectedTo;
|
||||
}
|
||||
|
||||
parser ??= new DOMParser();
|
||||
|
|
|
@ -24,11 +24,6 @@ export function recordServerError(
|
|||
// Our error should already be complete, but let's try to add a bit more through some guesswork
|
||||
const errorWithMetadata = collectErrorMetadata(err, config.root);
|
||||
|
||||
// Ignore unhandled rejection errors as they appear A LOT and we cannot record the amount to telemetry
|
||||
if (errorWithMetadata.name !== AstroErrorData.UnhandledRejection.name) {
|
||||
telemetry.record(eventError({ cmd: 'dev', err: errorWithMetadata, isFatal: false }));
|
||||
}
|
||||
|
||||
logger.error(null, formatErrorMessage(errorWithMetadata, logger.level() === 'debug'));
|
||||
|
||||
return {
|
||||
|
|
|
@ -12,18 +12,16 @@ import type {
|
|||
} from '../@types/astro.js';
|
||||
import { getInfoOutput } from '../cli/info/index.js';
|
||||
import { type HeadElements } from '../core/base-pipeline.js';
|
||||
import { shouldAppendForwardSlash } from '../core/build/util.js';
|
||||
import { ASTRO_VERSION, DEFAULT_404_COMPONENT } from '../core/constants.js';
|
||||
import { enhanceViteSSRError } from '../core/errors/dev/index.js';
|
||||
import { RewriteEncounteredAnError } from '../core/errors/errors-data.js';
|
||||
import { AggregateError, AstroError, CSSError, MarkdownError } from '../core/errors/index.js';
|
||||
import { AggregateError, CSSError, MarkdownError } from '../core/errors/index.js';
|
||||
import type { Logger } from '../core/logger/core.js';
|
||||
import type { ModuleLoader } from '../core/module-loader/index.js';
|
||||
import { prependForwardSlash, removeTrailingForwardSlash } from '../core/path.js';
|
||||
import { Pipeline, loadRenderer } from '../core/render/index.js';
|
||||
import { DEFAULT_404_ROUTE, default404Page } from '../core/routing/astro-designed-error-pages.js';
|
||||
import { default404Page } from '../core/routing/astro-designed-error-pages.js';
|
||||
import { findRouteToRewrite } from '../core/routing/rewrite.js';
|
||||
import { isPage, isServerLikeOutput, resolveIdToUrl, viteID } from '../core/util.js';
|
||||
import { isPage, isServerLikeOutput, viteID } from '../core/util.js';
|
||||
import { resolveIdToUrl } from '../core/viteUtils.js';
|
||||
import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js';
|
||||
import { getStylesForURL } from './css.js';
|
||||
import { getComponentMetadata } from './metadata.js';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { ModuleLoader } from '../core/module-loader/index.js';
|
||||
import { resolveIdToUrl } from '../core/util.js';
|
||||
import { resolveIdToUrl } from '../core/viteUtils.js';
|
||||
|
||||
export function createResolve(loader: ModuleLoader, root: URL) {
|
||||
// Resolves specifiers in the inline hydrated scripts, such as:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import type { SSRElement } from '../@types/astro.js';
|
||||
import type { ModuleInfo, ModuleLoader } from '../core/module-loader/index.js';
|
||||
import { createModuleScriptElementWithSrc } from '../core/render/ssr-element.js';
|
||||
import { rootRelativePath, viteID } from '../core/util.js';
|
||||
import { viteID } from '../core/util.js';
|
||||
import { rootRelativePath } from '../core/viteUtils.js';
|
||||
import type { PluginMetadata as AstroPluginMetadata } from '../vite-plugin-astro/types.js';
|
||||
import { crawlGraph } from './vite.js';
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue