0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-17 23:11:29 -05:00

Merge branch 'main' into next

This commit is contained in:
Matt Kane 2024-10-04 13:26:22 +01:00
commit 7a1d54a389
67 changed files with 425 additions and 106 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Support passing the values `Infinity` and `-Infinity` as island props.

View file

@ -0,0 +1,5 @@
---
'@astrojs/vue': patch
---
Fixes a case where IDs generated by `useId()` (introduced in Vue 3.5) would not be unique between islands

View file

@ -1,5 +0,0 @@
---
'astro': patch
---
Fixes error where references in content layer schemas sometimes incorrectly report as missing

View file

@ -0,0 +1,8 @@
---
'create-astro': patch
'@astrojs/upgrade': patch
'astro': patch
'@astrojs/db': patch
---
Removes the `strip-ansi` dependency in favor of the native Node API

View file

@ -0,0 +1,5 @@
---
"astro": patch
---
Updates Vite links to use their new domain

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixes missing `body` property on CollectionEntry types for content layer entries

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Adds a helpful error when attempting to render an undefined collection entry

View file

@ -24,6 +24,7 @@ env:
jobs:
repository-dispatch:
name: Repository dispatch
if: github.repository_owner == 'withastro'
runs-on: ubuntu-latest
steps:
- name: Dispatch event on push - adapters

View file

@ -345,7 +345,7 @@ const blog = defineCollection({
## `pagesGlobToRssItems()`
To create an RSS feed from documents in `src/pages/`, use the `pagesGlobToRssItems()` helper. This accepts an `import.meta.glob` result ([see Vite documentation](https://vitejs.dev/guide/features.html#glob-import)) and outputs an array of valid [`RSSFeedItem`s](#items).
To create an RSS feed from documents in `src/pages/`, use the `pagesGlobToRssItems()` helper. This accepts an `import.meta.glob` result ([see Vite documentation](https://vite.dev/guide/features.html#glob-import)) and outputs an array of valid [`RSSFeedItem`s](#items).
This function assumes, but does not verify, you are globbing for items inside `src/pages/`, and all necessary feed properties are present in each document's frontmatter. If you encounter errors, verify each page frontmatter manually.

View file

@ -365,6 +365,24 @@
- [#11974](https://github.com/withastro/astro/pull/11974) [`60211de`](https://github.com/withastro/astro/commit/60211defbfb2992ba17d1369e71c146d8928b09a) Thanks [@ascorbic](https://github.com/ascorbic)! - Exports the `RenderResult` type
## 4.15.11
### Patch Changes
- [#12097](https://github.com/withastro/astro/pull/12097) [`11d447f`](https://github.com/withastro/astro/commit/11d447f66b1a0f39489c2600139ebfb565336ce7) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes error where references in content layer schemas sometimes incorrectly report as missing
- [#12108](https://github.com/withastro/astro/pull/12108) [`918953b`](https://github.com/withastro/astro/commit/918953bd09f057131dfe029e810019c0909345cf) Thanks [@lameuler](https://github.com/lameuler)! - Fixes a bug where [data URL images](https://developer.mozilla.org/en-US/docs/Web/URI/Schemes/data) were not correctly handled. The bug resulted in an `ENAMETOOLONG` error.
- [#12105](https://github.com/withastro/astro/pull/12105) [`42037f3`](https://github.com/withastro/astro/commit/42037f33e644d5a2bfba71377697fc7336ecb15b) Thanks [@ascorbic](https://github.com/ascorbic)! - Returns custom statusText that has been set in a Response
- [#12109](https://github.com/withastro/astro/pull/12109) [`ea22558`](https://github.com/withastro/astro/commit/ea225585fd12d27006434266163512ca66ad572b) Thanks [@ematipico](https://github.com/ematipico)! - Fixes a regression that was introduced by an internal refactor of how the middleware is loaded by the Astro application. The regression was introduced by [#11550](https://github.com/withastro/astro/pull/11550).
When the edge middleware feature is opted in, Astro removes the middleware function from the SSR manifest, and this wasn't taken into account during the refactor.
- [#12106](https://github.com/withastro/astro/pull/12106) [`d3a74da`](https://github.com/withastro/astro/commit/d3a74da19644477ffc81acf2a3efb26ad3335a5e) Thanks [@ascorbic](https://github.com/ascorbic)! - Handles case where an immutable Response object is returned from an endpoint
- [#12090](https://github.com/withastro/astro/pull/12090) [`d49a537`](https://github.com/withastro/astro/commit/d49a537f2aaccd132154a15f1da4db471272ee90) Thanks [@markjaquith](https://github.com/markjaquith)! - Server islands: changes the server island HTML placeholder comment so that it is much less likely to get removed by HTML minifiers.
## 4.15.10
### Patch Changes
@ -4773,7 +4791,7 @@
To not break existing APIs, aliases for the Toolbar-based names have been created. The previous API names will continue to function but will be deprecated in the future. All documentation has been updated to reflect Toolbar-based names.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9225](https://github.com/withastro/astro/pull/9225) [`c421a3d17`](https://github.com/withastro/astro/commit/c421a3d17911aeda29b5204f6d568ae87e329eaf) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Removes the opt-in `handleForms` property for `<ViewTransitions />`. Form submissions are now handled by default and this property is no longer necessary. This default behavior can be disabled by setting `data-astro-reload` on relevant `<form />` elements.
@ -5109,7 +5127,7 @@
The types for middlewares have also been revised. To type a middleware function, you should now use `MiddlewareHandler` instead of `MiddlewareResponseHandler`. If you used `defineMiddleware()` to type the function, no changes are needed.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9196](https://github.com/withastro/astro/pull/9196) [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6) Thanks [@bluwy](https://github.com/bluwy)! - Removes support for Shiki custom language's `path` property. The language JSON file should be imported and passed to the option instead.
@ -9318,7 +9336,7 @@
<!-- You have an entry! Use it! -->
```
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vitejs.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vite.dev/guide/migration.html) for more information.
- [#5724](https://github.com/withastro/astro/pull/5724) [`16c7d0bfd`](https://github.com/withastro/astro/commit/16c7d0bfd49d2b9bfae45385f506bcd642f9444a) Thanks [@bluwy](https://github.com/bluwy)! - Remove outdated Vue info log. Remove `toString` support for `RenderTemplateResult`.
@ -9875,7 +9893,7 @@
- [#5716](https://github.com/withastro/astro/pull/5716) [`dd56c1941`](https://github.com/withastro/astro/commit/dd56c19411b126439b8bc42d681b6fa8c06e8c61) Thanks [@bluwy](https://github.com/bluwy)! - Remove MDX Fragment hack. This was used by `@astrojs/mdx` to access the `Fragment` component, but isn't require anymore since `@astrojs/mdx` v0.12.1.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vitejs.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vite.dev/guide/migration.html) for more information.
- [#5724](https://github.com/withastro/astro/pull/5724) [`16c7d0bfd`](https://github.com/withastro/astro/commit/16c7d0bfd49d2b9bfae45385f506bcd642f9444a) Thanks [@bluwy](https://github.com/bluwy)! - Remove outdated Vue info log. Remove `toString` support for `RenderTemplateResult`.

View file

@ -19,7 +19,7 @@ interface ImportMeta {
* Astro and Vite expose environment variables through `import.meta.env`. For a complete list of the environment variables available, see the two references below.
*
* - [Astro reference](https://docs.astro.build/en/guides/environment-variables/#default-environment-variables)
* - [Vite reference](https://vitejs.dev/guide/env-and-mode.html#env-variables)
* - [Vite reference](https://vite.dev/guide/env-and-mode.html#env-variables)
*/
readonly env: ImportMetaEnv;
}

View file

@ -11,12 +11,14 @@ interface Props {
array: any[];
map: Map<string, string>;
set: Set<string>;
infinity: number;
negativeInfinity: number;
}
const isNode = typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]';
/** a counter written in React */
export default function Component({ undefined: undefinedProp, null: nullProp, boolean, number, string, bigint, object, array, map, set }: Props) {
export default function Component({ undefined: undefinedProp, null: nullProp, boolean, number, string, bigint, object, array, map, set, infinity, negativeInfinity }: Props) {
// We are testing hydration, so don't return anything in the server.
if(isNode) {
return <div></div>
@ -30,6 +32,10 @@ export default function Component({ undefined: undefinedProp, null: nullProp, bo
<span id="boolean-value">{boolean.toString()}</span>
<span id="number-type">{Object.prototype.toString.call(number)}</span>
<span id="number-value">{number.toString()}</span>
<span id="infinity-type">{Object.prototype.toString.call(infinity)}</span>
<span id="infinity-value">{infinity.toString()}</span>
<span id="negative-infinity-type">{Object.prototype.toString.call(negativeInfinity)}</span>
<span id="negative-infinity-value">{negativeInfinity.toString()}</span>
<span id="string-type">{Object.prototype.toString.call(string)}</span>
<span id="string-value">{string}</span>
<span id="bigint-type">{Object.prototype.toString.call(bigint)}</span>

View file

@ -42,6 +42,8 @@ set.add('test2');
array={[0, "foo"]}
map={map}
set={set}
infinity={Infinity}
negativeInfinity={-Infinity}
/>
</main>
</body>

View file

@ -47,6 +47,22 @@ test.describe('Passing JS into client components', () => {
await expect(numberValue, 'is visible').toBeVisible();
await expect(numberValue).toHaveText('16');
const infinityType = page.locator('#infinity-type');
await expect(infinityType, 'is visible').toBeVisible();
await expect(infinityType).toHaveText('[object Number]');
const negativeInfinityType = page.locator('#negative-infinity-type');
await expect(negativeInfinityType, 'is visible').toBeVisible();
await expect(negativeInfinityType).toHaveText('[object Number]');
const infinityValue = page.locator('#infinity-value');
await expect(infinityValue, 'is visible').toBeVisible();
await expect(infinityValue).toHaveText('Infinity');
const negativeInfinityValue = page.locator('#negative-infinity-value');
await expect(negativeInfinityValue, 'is visible').toBeVisible();
await expect(negativeInfinityValue).toHaveText('-Infinity');
// string
const stringType = page.locator('#string-type');
await expect(stringType, 'is visible').toBeVisible();

View file

@ -169,7 +169,6 @@
"semver": "^7.6.3",
"shiki": "^1.21.0",
"string-width": "^7.2.0",
"strip-ansi": "^7.1.0",
"tinyexec": "^0.3.0",
"tsconfck": "^3.1.3",
"unist-util-visit": "^5.0.0",

View file

@ -8,7 +8,11 @@ import { isESMImportedImage } from './imageKind.js';
export function propsToFilename(filePath: string, transform: ImageTransform, hash: string) {
let filename = decodeURIComponent(removeQueryString(filePath));
const ext = extname(filename);
filename = basename(filename, ext);
if (filePath.startsWith('data:')) {
filename = shorthash(filePath);
} else {
filename = basename(filename, ext);
}
const prefixDirname = isESMImportedImage(transform.src) ? dirname(filePath) : '';
let outputExt = transform.format ? `.${transform.format}` : ext;

View file

@ -435,7 +435,11 @@ function updateImageReferencesInData<T extends Record<string, unknown>>(
export async function renderEntry(
entry: DataEntry | { render: () => Promise<{ Content: AstroComponentFactory }> },
) {
if (entry && 'render' in entry) {
if (!entry) {
throw new AstroError(AstroErrorData.RenderUndefinedEntryError);
}
if ('render' in entry) {
// This is an old content collection entry, so we use its render method
return entry.render();
}

View file

@ -501,7 +501,7 @@ async function writeContentFiles({
contentTypesStr += `};\n`;
break;
case CONTENT_LAYER_TYPE:
dataTypesStr += `${collectionKey}: Record<string, {\n id: string;\n collection: ${collectionKey};\n data: ${dataType};\n rendered?: RenderedContent;\n filePath?: string \n}>;\n`;
dataTypesStr += `${collectionKey}: Record<string, {\n id: string;\n collection: ${collectionKey};\n data: ${dataType};\n rendered?: RenderedContent;\n filePath?: string;\n body?: string \n}>;\n`;
break;
case 'data':
if (collectionEntryKeys.length === 0) {

View file

@ -107,7 +107,8 @@ export class NodeApp extends App {
* @param destination NodeJS ServerResponse
*/
static async writeResponse(source: Response, destination: ServerResponse) {
const { status, headers, body } = source;
const { status, headers, body, statusText } = source;
destination.statusMessage = statusText;
destination.writeHead(status, createOutgoingHttpHeaders(headers));
if (!body) return destination.end();
try {

View file

@ -67,7 +67,7 @@ export type SSRManifest = {
serverIslandNameMap?: Map<string, string>;
key: Promise<CryptoKey>;
i18n: SSRManifestI18n | undefined;
middleware: () => Promise<AstroMiddlewareInstance> | AstroMiddlewareInstance;
middleware?: () => Promise<AstroMiddlewareInstance> | AstroMiddlewareInstance;
checkOrigin: boolean;
envGetSecretEnabled: boolean;
};

View file

@ -108,7 +108,10 @@ export abstract class Pipeline {
async getMiddleware(): Promise<MiddlewareHandler> {
if (this.resolvedMiddleware) {
return this.resolvedMiddleware;
} else {
}
// The middleware can be undefined when using edge middleware.
// This is set to undefined by the plugin-ssr.ts
else if (this.middleware) {
const middlewareInstance = await this.middleware();
const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN;
if (this.manifest.checkOrigin) {
@ -117,6 +120,9 @@ export abstract class Pipeline {
this.resolvedMiddleware = onRequest;
}
return this.resolvedMiddleware;
} else {
this.resolvedMiddleware = NOOP_MIDDLEWARE_FN;
return this.resolvedMiddleware;
}
}
}

View file

@ -1,9 +1,9 @@
import * as fs from 'node:fs';
import { isAbsolute, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { stripVTControlCharacters } from 'node:util';
import { escape } from 'html-escaper';
import { bold, underline } from 'kleur/colors';
import stripAnsi from 'strip-ansi';
import type { ESBuildTransformResult } from 'vite';
import { normalizePath } from 'vite';
import type { SSRError } from '../../../types/public/internal.js';
@ -27,7 +27,7 @@ export function collectErrorMetadata(e: any, rootFolder?: URL): ErrorWithMetadat
if (e.stack) {
const stackInfo = collectInfoFromStacktrace(e);
try {
error.stack = stripAnsi(stackInfo.stack);
error.stack = stripVTControlCharacters(stackInfo.stack);
} catch {}
error.loc = stackInfo.loc;
error.plugin = stackInfo.plugin;
@ -59,7 +59,7 @@ export function collectErrorMetadata(e: any, rootFolder?: URL): ErrorWithMetadat
if (!error.frame) {
const frame = codeFrame(fileContents, error.loc);
error.frame = stripAnsi(frame);
error.frame = stripVTControlCharacters(frame);
}
if (!error.fullCode) {
@ -75,7 +75,7 @@ export function collectErrorMetadata(e: any, rootFolder?: URL): ErrorWithMetadat
// but it will be handled and added below, which is already ANSI-free
if (error.message) {
try {
error.message = stripAnsi(error.message);
error.message = stripVTControlCharacters(error.message);
} catch {
// Setting `error.message` can fail here if the message is read-only, which for the vast majority of cases will never happen, however some somewhat obscure cases can cause this to happen.
}
@ -170,7 +170,7 @@ function collectInfoFromStacktrace(error: SSRError & { stack: string }): StackIn
// normalize error stack line-endings to \n
stackInfo.stack = normalizeLF(error.stack);
const stackText = stripAnsi(error.stack);
const stackText = stripVTControlCharacters(error.stack);
// Try to find possible location from stack if we don't have one
if (!stackInfo.loc || (!stackInfo.loc.column && !stackInfo.loc.line)) {

View file

@ -929,14 +929,14 @@ export const LocalImageUsedWrongly = {
* @see
* - [Astro.glob](https://docs.astro.build/en/reference/api-reference/#astroglob)
* @description
* `Astro.glob()` can only be used in `.astro` files. You can use [`import.meta.glob()`](https://vitejs.dev/guide/features.html#glob-import) instead to achieve the same result.
* `Astro.glob()` can only be used in `.astro` files. You can use [`import.meta.glob()`](https://vite.dev/guide/features.html#glob-import) instead to achieve the same result.
*/
export const AstroGlobUsedOutside = {
name: 'AstroGlobUsedOutside',
title: 'Astro.glob() used outside of an Astro file.',
message: (globStr: string) =>
`\`Astro.glob(${globStr})\` can only be used in \`.astro\` files. \`import.meta.glob(${globStr})\` can be used instead to achieve a similar result.`,
hint: "See Vite's documentation on `import.meta.glob` for more information: https://vitejs.dev/guide/features.html#glob-import",
hint: "See Vite's documentation on `import.meta.glob` for more information: https://vite.dev/guide/features.html#glob-import",
} satisfies ErrorData;
/**
@ -1008,7 +1008,7 @@ export const MissingSharp = {
/**
* @docs
* @see
* - [Vite troubleshooting guide](https://vitejs.dev/guide/troubleshooting.html)
* - [Vite troubleshooting guide](https://vite.dev/guide/troubleshooting.html)
* @description
* Vite encountered an unknown error while rendering your project. We unfortunately do not know what happened (or we would tell you!)
*
@ -1451,6 +1451,17 @@ export const UnknownContentCollectionError = {
title: 'Unknown Content Collection Error.',
} satisfies ErrorData;
/**
* @docs
* @description
* Astro tried to render a content collection entry that was undefined. This can happen if you try to render an entry that does not exist.
*/
export const RenderUndefinedEntryError = {
name: 'RenderUndefinedEntryError',
title: 'Attempted to render an undefined content collection entry.',
hint: 'Check if the entry is undefined before passing it to `render()`',
} satisfies ErrorData;
/**
* @docs
* @description

View file

@ -1,5 +1,5 @@
import { fileURLToPath } from 'node:url';
import stripAnsi from 'strip-ansi';
import { stripVTControlCharacters } from 'node:util';
import type { LogLevel, Rollup, Logger as ViteLogger } from 'vite';
import { isAstroError } from '../errors/errors.js';
import { serverShortcuts as formatServerShortcuts } from '../messages.js';
@ -34,7 +34,7 @@ export function createViteLogger(
info(msg) {
if (!isLogLevelEnabled(viteLogLevel, 'info')) return;
const stripped = stripAnsi(msg);
const stripped = stripVTControlCharacters(msg);
let m;
// Rewrite HMR page reload message
if ((m = vitePageReloadMsg.exec(stripped))) {

View file

@ -29,6 +29,7 @@ declare const Astro: {
8: (value) => new Uint8Array(value),
9: (value) => new Uint16Array(value),
10: (value) => new Uint32Array(value),
11: (value) => Infinity * value,
};
// Not using JSON.parse reviver because it's bottom-up but we want top-down

View file

@ -53,7 +53,7 @@ export async function renderEndpoint(
return new Response(null, { status: 500 });
}
const response = await handler.call(mod, context);
let response = await handler.call(mod, context);
if (!response || response instanceof Response === false) {
throw new AstroError(EndpointDidNotReturnAResponse);
@ -62,10 +62,20 @@ export async function renderEndpoint(
// Endpoints explicitly returning 404 or 500 response status should
// NOT be subject to rerouting to 404.astro or 500.astro.
if (REROUTABLE_STATUS_CODES.includes(response.status)) {
// Only `Response.redirect` headers are immutable, therefore a `try..catch` is not necessary.
// Note: `Response.redirect` can only be called with HTTP status codes: 301, 302, 303, 307, 308.
// Source: https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect_static#parameters
response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no');
try {
response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no');
} catch (err) {
// In some cases the response may have immutable headers
// This is the case if, for example, the user directly returns a `fetch` response
// There's no clean way to check if the headers are immutable, so we just catch the error
// Note that response.clone() still has immutable headers!
if ((err as Error).message?.includes('immutable')) {
response = new Response(response.body, response);
response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no');
} else {
throw err;
}
}
}
return response;

View file

@ -62,7 +62,7 @@ export function renderServerIsland(
}
}
destination.write('<!--server-island-start-->');
destination.write('<!--[if astro]>server-island-start<![endif]-->');
// Render the slots
const renderedSlots: Record<string, string> = {};
@ -126,7 +126,7 @@ if(response.status === 200 && response.headers.get('content-type') === 'text/htm
// Swap!
while(script.previousSibling &&
script.previousSibling.nodeType !== 8 &&
script.previousSibling.data !== 'server-island-start') {
script.previousSibling.data !== '[if astro]>server-island-start<![endif]') {
script.previousSibling.remove();
}
script.previousSibling?.remove();

View file

@ -13,6 +13,7 @@ const PROP_TYPE = {
Uint8Array: 8,
Uint16Array: 9,
Uint32Array: 10,
Infinity: 11,
};
function serializeArray(
@ -93,11 +94,17 @@ function convertToSerializedForm(
default: {
if (value !== null && typeof value === 'object') {
return [PROP_TYPE.Value, serializeObject(value, metadata, parents)];
} else if (value === undefined) {
return [PROP_TYPE.Value];
} else {
return [PROP_TYPE.Value, value];
}
if (value === Infinity) {
return [PROP_TYPE.Infinity, 1];
}
if (value === -Infinity) {
return [PROP_TYPE.Infinity, -1];
}
if (value === undefined) {
return [PROP_TYPE.Value];
}
return [PROP_TYPE.Value, value];
}
}
}

View file

@ -494,7 +494,7 @@ export interface AstroUserConfig {
*
* Pass additional configuration options to Vite. Useful when Astro doesn't support some advanced configuration that you may need.
*
* View the full `vite` configuration object documentation on [vitejs.dev](https://vitejs.dev/config/).
* View the full `vite` configuration object documentation on [vite.dev](https://vite.dev/config/).
*
* #### Examples
*

View file

@ -53,7 +53,7 @@ export function writeHtmlResponse(res: http.ServerResponse, statusCode: number,
}
export async function writeWebResponse(res: http.ServerResponse, webResponse: Response) {
const { status, headers, body } = webResponse;
const { status, headers, body, statusText } = webResponse;
// Attach any set-cookie headers added via Astro.cookies.set()
const setCookieHeaders = Array.from(getSetCookiesFromResponse(webResponse));
@ -67,7 +67,7 @@ export async function writeWebResponse(res: http.ServerResponse, webResponse: Re
if (headers.has('set-cookie')) {
_headers['set-cookie'] = headers.getSetCookie();
}
res.statusMessage = statusText;
res.writeHead(status, _headers);
if (body) {
if (Symbol.for('astro.responseBody') in webResponse) {

View file

@ -1,6 +1,6 @@
# vite-plugin-env
Improves Vite's [Env Variables](https://vitejs.dev/guide/env-and-mode.html#env-files) support to include **private** env variables during Server-Side Rendering (SSR) but never in client-side rendering (CSR).
Improves Vite's [Env Variables](https://vite.dev/guide/env-and-mode.html#env-files) support to include **private** env variables during Server-Side Rendering (SSR) but never in client-side rendering (CSR).
Private env variables can be accessed through `import.meta.env.SECRET` like Vite. Where the env variable is declared changes how it is replaced when transforming it:

View file

@ -5,7 +5,7 @@ import { join } from 'node:path';
import { Writable } from 'node:stream';
import { describe, it } from 'node:test';
import { fileURLToPath } from 'node:url';
import stripAnsi from 'strip-ansi';
import { stripVTControlCharacters } from 'node:util';
import { cli, cliServerLogSetup, loadFixture, parseCliDevStart } from './test-utils.js';
describe('astro cli', () => {
@ -45,7 +45,7 @@ describe('astro cli', () => {
dest: new Writable({
objectMode: true,
write(event, _, callback) {
logs.push({ ...event, message: stripAnsi(event.message) });
logs.push({ ...event, message: stripVTControlCharacters(event.message) });
if (event.message.includes('1 error')) {
messageResolve(logs);
}

View file

@ -414,5 +414,12 @@ describe('Content Layer', () => {
assert.ok(updated.jsonLoader[0].data.temperament.includes('Bouncy'));
await fixture.resetAllFiles();
});
it('returns an error if we render an undefined entry', async () => {
const res = await fixture.fetch('/missing');
const text = await res.text();
assert.equal(res.status, 500);
assert.ok(text.includes('RenderUndefinedEntryError'));
});
});
});

View file

@ -1298,4 +1298,56 @@ describe('astro:image', () => {
await devServer.stop();
});
});
describe('build data url', () => {
before(async () => {
fixture = await loadFixture({
root: './fixtures/core-image-data-url/',
image: {
remotePatterns: [
{
protocol: 'data',
},
],
},
});
await fixture.build();
});
it('uses short hash for data url filename', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
const src1 = $('#data-url img').attr('src');
assert.equal(basename(src1).length < 32, true);
const src2 = $('#data-url-no-size img').attr('src');
assert.equal(basename(src2).length < 32, true);
assert.equal(src1.split('_')[0], src2.split('_')[0]);
});
it('adds file extension for data url images', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
const src = $('#data-url img').attr('src');
assert.equal(src.endsWith('.webp'), true);
});
it('writes data url images to dist', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
const src = $('#data-url img').attr('src');
assert.equal(src.length > 0, true);
const data = await fixture.readFile(src, null);
assert.equal(data instanceof Buffer, true);
});
it('infers size of data url images', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
const img = $('#data-url-no-size img');
const width = img.attr('width');
const height = img.attr('height');
assert.equal(width, '256');
assert.equal(height, '144');
});
});
});

View file

@ -0,0 +1,14 @@
---
import { getEntry, render } from "astro:content"
// Skipping the broken page in production so the build doesn't fail
if(import.meta.env.PROD) {
return new Response(null, { status: 404 })
}
const entry = await getEntry("spacecraft", "missing")
const { Content } = await render(entry)
---
<Content />

View file

@ -0,0 +1,8 @@
{
"name": "@test/core-image-data-url",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}

View file

@ -0,0 +1,17 @@
---
import { Image } from 'astro:assets';
const data = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAACQCAQAAABNan0aAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQflBAsNKgIhYT8HAAAAXklEQVR42u3BMQEAAADCoPVPbQlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4G8gnwABm4i4EAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNC0xMVQxMzo0MjowMiswMDowMNhkaiwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDQtMTFUMTM6NDI6MDIrMDA6MDCpOdKQAAAAAElFTkSuQmCC"
---
<html>
<head>
</head>
<body>
<div id="data-url">
<Image src={data} alt="transparent" width="128" height="72" />
</div>
<div id="data-url-no-size">
<Image src={data} inferSize={true} alt="transparent" />
</div>
</body>
</html>

View file

@ -0,0 +1,3 @@
export async function GET({ request }) {
return fetch("https://http.im/status/500", request)
}

View file

@ -5,14 +5,19 @@ export function GET() {
{ name: 'lettuce' },
{ name: 'broccoli' },
{ name: 'pizza' }
])
]), {
status: 200,
statusText: `tasty`,
}
)
}
export async function POST({ params, request }) {
const body = await request.text();
return new Response(body === `some data` ? `ok` : `not ok`, {
status: 200,
const ok = body === `some data`
return new Response( ok ? `ok` : `not ok`, {
status: ok ? 200 : 400,
statusText: ok ? `ok` : `not ok`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}

View file

@ -89,6 +89,11 @@ describe('serialize', () => {
const output = `{"a":[10,[1,2,3]]}`;
assert.equal(serializeProps(input), output);
});
it('serializes Infinity and -Infinity', () => {
const input = { a: Infinity, b: -Infinity };
const output = `{"a":[11,1],"b":[11,-1]}`;
assert.equal(serializeProps(input), output);
});
it('cannot serialize a cyclic reference', () => {
const a = {};
a.b = a;

View file

@ -33,6 +33,7 @@ describe('API routes in SSR', () => {
const request = new Request('http://example.com/food.json');
const response = await app.render(request);
assert.equal(response.status, 200);
assert.equal(response.statusText, 'tasty');
const body = await response.json();
assert.equal(body.length, 3);
});
@ -78,6 +79,17 @@ describe('API routes in SSR', () => {
assert.equal(text, 'ok');
});
it('Can read custom status text from API routes', async () => {
const response = await fixture.fetch('/food.json', {
method: 'POST',
body: `not some data`,
});
assert.equal(response.status, 400);
assert.equal(response.statusText, 'not ok');
const text = await response.text();
assert.equal(text, 'not ok');
});
it('Can be passed binary data from multipart formdata', async () => {
const formData = new FormData();
const raw = await fs.promises.readFile(
@ -125,23 +137,29 @@ describe('API routes in SSR', () => {
assert.equal(count, 2, 'Found two separate set-cookie response headers');
});
it('can return an immutable response object', async () => {
const response = await fixture.fetch('/fail');
const text = await response.text();
assert.equal(response.status, 500);
assert.equal(text, '');
});
it('Has valid api context', async () => {
const response = await fixture.fetch('/context/any');
assert.equal(response.status, 200);
const data = await response.json();
assert.equal(data.cookiesExist, true);
assert.equal(data.requestExist, true);
assert.equal(data.redirectExist, true);
assert.equal(data.propsExist, true);
assert.ok(data.cookiesExist);
assert.ok(data.requestExist);
assert.ok(data.redirectExist);
assert.ok(data.propsExist);
assert.deepEqual(data.params, { param: 'any' });
assert.match(data.generator, /^Astro v/);
assert.equal(
assert.ok(
['http://[::1]:4321/blog/context/any', 'http://127.0.0.1:4321/blog/context/any'].includes(
data.url,
),
true,
);
assert.equal(['::1', '127.0.0.1'].includes(data.clientAddress), true);
assert.ok(['::1', '127.0.0.1'].includes(data.clientAddress));
assert.equal(data.site, 'https://mysite.dev/subsite/');
});
});

View file

@ -2,9 +2,9 @@ import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { stripVTControlCharacters } from 'node:util';
import { execa } from 'execa';
import fastGlob from 'fast-glob';
import stripAnsi from 'strip-ansi';
import { Agent } from 'undici';
import { check } from '../dist/cli/check/index.js';
import { globalContentLayer } from '../dist/content/content-layer.js';
@ -344,8 +344,8 @@ export async function parseCliDevStart(proc) {
}
proc.kill();
stdout = stripAnsi(stdout);
stderr = stripAnsi(stderr);
stdout = stripVTControlCharacters(stdout);
stderr = stripVTControlCharacters(stderr);
if (stderr) {
throw new Error(stderr);

View file

@ -1,6 +1,6 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import stripAnsi from 'strip-ansi';
import { stripVTControlCharacters } from 'node:util';
import { z } from 'zod';
import { validateConfig } from '../../../dist/core/config/validate.js';
import { formatConfigErrorMessage } from '../../../dist/core/messages.js';
@ -19,7 +19,7 @@ describe('Config Validation', () => {
it('A validation error can be formatted correctly', async () => {
const configError = await validateConfig({ site: 42 }, process.cwd()).catch((err) => err);
assert.equal(configError instanceof z.ZodError, true);
const formattedError = stripAnsi(formatConfigErrorMessage(configError));
const formattedError = stripVTControlCharacters(formatConfigErrorMessage(configError));
assert.equal(
formattedError,
`[config] Astro found issue(s) with your configuration:
@ -34,7 +34,7 @@ describe('Config Validation', () => {
};
const configError = await validateConfig(veryBadConfig, process.cwd()).catch((err) => err);
assert.equal(configError instanceof z.ZodError, true);
const formattedError = stripAnsi(formatConfigErrorMessage(configError));
const formattedError = stripVTControlCharacters(formatConfigErrorMessage(configError));
assert.equal(
formattedError,
`[config] Astro found issue(s) with your configuration:

View file

@ -37,7 +37,6 @@
"devDependencies": {
"arg": "^5.0.2",
"astro-scripts": "workspace:*",
"strip-ansi": "^7.1.0",
"strip-json-comments": "^5.0.1"
},
"engines": {

View file

@ -1,8 +1,8 @@
import { exec } from 'node:child_process';
import { stripVTControlCharacters } from 'node:util';
/* eslint no-console: 'off' */
import { color, say as houston, label, spinner as load } from '@astrojs/cli-kit';
import { align, sleep } from '@astrojs/cli-kit/utils';
import stripAnsi from 'strip-ansi';
import { shell } from './shell.js';
// Users might lack access to the global npm registry, this function
@ -122,7 +122,7 @@ export const nextSteps = async ({ projectDir, devCmd }: { projectDir: string; de
`\n${prefix}Enter your project directory using`,
color.cyan(`cd ${projectDir}`, ''),
];
const len = enter[0].length + stripAnsi(enter[1]).length;
const len = enter[0].length + stripVTControlCharacters(enter[1]).length;
log(enter.join(len > max ? '\n' + prefix : ' '));
}
log(

View file

@ -1,6 +1,6 @@
import fs from 'node:fs';
import { before, beforeEach } from 'node:test';
import stripAnsi from 'strip-ansi';
import { stripVTControlCharacters } from 'node:util';
import { setStdout } from '../dist/index.js';
export function setup() {
@ -9,7 +9,7 @@ export function setup() {
setStdout(
Object.assign({}, process.stdout, {
write(buf) {
ctx.messages.push(stripAnsi(String(buf)).trim());
ctx.messages.push(stripVTControlCharacters(String(buf)).trim());
return true;
},
}),

View file

@ -79,7 +79,6 @@
"nanoid": "^5.0.7",
"open": "^10.1.0",
"prompts": "^2.4.2",
"strip-ansi": "^7.1.0",
"yargs-parser": "^21.1.1",
"yocto-spinner": "^0.1.0",
"zod": "^3.23.8"

View file

@ -1,9 +1,9 @@
import { stripVTControlCharacters } from 'node:util';
import deepDiff from 'deep-diff';
import { sql } from 'drizzle-orm';
import { SQLiteAsyncDialect } from 'drizzle-orm/sqlite-core';
import * as color from 'kleur/colors';
import { customAlphabet } from 'nanoid';
import stripAnsi from 'strip-ansi';
import { hasPrimaryKey } from '../../runtime/index.js';
import { createRemoteDatabaseClient } from '../../runtime/index.js';
import { isSerializedSQL } from '../../runtime/types.js';
@ -521,7 +521,7 @@ export function formatDataLossMessage(confirmations: string[], isColor = true):
);
let finalMessage = messages.join('\n');
if (!isColor) {
finalMessage = stripAnsi(finalMessage);
finalMessage = stripVTControlCharacters(finalMessage);
}
return finalMessage;
}

View file

@ -288,13 +288,13 @@
### Patch Changes
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
## 3.0.7-beta.0
### Patch Changes
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
## 3.0.6

View file

@ -1,5 +1,11 @@
# @astrojs/sitemap
## 3.2.0
### Minor Changes
- [#11485](https://github.com/withastro/astro/pull/11485) [`fbe1bc5`](https://github.com/withastro/astro/commit/fbe1bc51d89994c4919c12768908658604513bd3) Thanks [@sondr3](https://github.com/sondr3)! - Adds new `xslURL` option to enable styling of sitemaps
## 3.1.6
### Patch Changes

View file

@ -1,7 +1,7 @@
{
"name": "@astrojs/sitemap",
"description": "Generate a sitemap for your Astro site",
"version": "3.1.6",
"version": "3.2.0",
"type": "module",
"types": "./dist/index.d.ts",
"author": "withastro",

View file

@ -88,7 +88,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
const { filter, customPages, serialize, entryLimit } = opts;
let finalSiteUrl = new URL(config.base, config.site);
const finalSiteUrl = new URL(config.base, config.site);
const shouldIgnoreStatus = isStatusCodePage(Object.keys(opts.i18n?.locales ?? {}));
let pageUrls = pages
.filter((p) => !shouldIgnoreStatus(p.pathname))
@ -100,7 +100,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
return new URL(fullPath, finalSiteUrl).href;
});
let routeUrls = routes.reduce<string[]>((urls, r) => {
const routeUrls = routes.reduce<string[]>((urls, r) => {
// Only expose pages, not endpoints or redirects
if (r.type !== 'page') return urls;
@ -116,7 +116,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
if (fullPath.endsWith('/')) fullPath += r.generate(r.pathname).substring(1);
else fullPath += r.generate(r.pathname);
let newUrl = new URL(fullPath, finalSiteUrl).href;
const newUrl = new URL(fullPath, finalSiteUrl).href;
if (config.trailingSlash === 'never') {
urls.push(newUrl);
@ -168,6 +168,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
}
}
const destDir = fileURLToPath(dir);
const xslURL = opts.xslURL ? new URL(opts.xslURL, finalSiteUrl).href : undefined;
await writeSitemap(
{
hostname: finalSiteUrl.href,
@ -175,6 +176,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
publicBasePath: config.base,
sourceData: urlData,
limit: entryLimit,
xslURL: xslURL,
},
config,
);

View file

@ -9,6 +9,7 @@ export const SitemapOptionsSchema = z
filter: z.function().args(z.string()).returns(z.boolean()).optional(),
customPages: z.string().url().array().optional(),
canonicalURL: z.string().url().optional(),
xslURL: z.string().optional(),
i18n: z
.object({

View file

@ -17,6 +17,7 @@ type WriteSitemapConfig = {
destinationDir: string;
publicBasePath?: string;
limit?: number;
xslURL?: string;
};
// adapted from sitemap.js/sitemap-simple
@ -28,6 +29,7 @@ export async function writeSitemap(
destinationDir,
limit = 50000,
publicBasePath = './',
xslURL: xslUrl,
}: WriteSitemapConfig,
astroConfig: AstroConfig,
) {
@ -38,6 +40,7 @@ export async function writeSitemap(
getSitemapStream: (i) => {
const sitemapStream = new SitemapStream({
hostname,
xslUrl,
});
const path = `./sitemap-${i}.xml`;
const writePath = resolve(destinationDir, path);
@ -63,7 +66,7 @@ export async function writeSitemap(
},
});
let src = Readable.from(sourceData);
const src = Readable.from(sourceData);
const indexPath = resolve(destinationDir, `./sitemap-index.xml`);
return promisify(pipeline)(src, sitemapAndIndexStream, createWriteStream(indexPath));
}

View file

@ -3,7 +3,7 @@ import { before, describe, it } from 'node:test';
import { sitemap } from './fixtures/static/deps.mjs';
import { loadFixture, readXML } from './test-utils.js';
describe('Filter support', () => {
describe('Config', () => {
/** @type {import('./test-utils.js').Fixture} */
let fixture;
@ -14,17 +14,26 @@ describe('Filter support', () => {
integrations: [
sitemap({
filter: (page) => page === 'http://example.com/one/',
xslURL: '/sitemap.xsl',
}),
],
});
await fixture.build();
});
it('Just one page is added', async () => {
it('filter: Just one page is added', async () => {
const data = await readXML(fixture.readFile('/sitemap-0.xml'));
const urls = data.urlset.url;
assert.equal(urls.length, 1);
});
it('xslURL: Includes xml-stylsheet', async () => {
const xml = await fixture.readFile('/sitemap-0.xml');
assert.ok(
xml.includes('<?xml-stylesheet type="text/xsl" href="http://example.com/sitemap.xsl"?>'),
xml,
);
});
});
describe('SSR', () => {
@ -34,16 +43,25 @@ describe('Filter support', () => {
integrations: [
sitemap({
filter: (page) => page === 'http://example.com/one/',
xslURL: '/sitemap.xsl',
}),
],
});
await fixture.build();
});
it('Just one page is added', async () => {
it('filter: Just one page is added', async () => {
const data = await readXML(fixture.readFile('/client/sitemap-0.xml'));
const urls = data.urlset.url;
assert.equal(urls.length, 1);
});
it('xslURL: Includes xml-stylsheet', async () => {
const xml = await fixture.readFile('/client/sitemap-0.xml');
assert.ok(
xml.includes('<?xml-stylesheet type="text/xsl" href="http://example.com/sitemap.xsl"?>'),
xml,
);
});
});
});

View file

@ -140,7 +140,7 @@
### Major Changes
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Drops support for Svelte 3 as `@sveltejs/vite-plugin-svelte` is updated to `3.0.0` which does not support Svelte 3
@ -148,7 +148,7 @@
### Major Changes
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Drops support for Svelte 3 as `@sveltejs/vite-plugin-svelte` is updated to `3.0.0` which does not support Svelte 3
@ -358,7 +358,7 @@
- [#5782](https://github.com/withastro/astro/pull/5782) [`1f92d64ea`](https://github.com/withastro/astro/commit/1f92d64ea35c03fec43aff64eaf704dc5a9eb30a) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Remove support for Node 14. Minimum supported Node version is now >=16.12.0
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vitejs.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vite.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Simplify Svelte preprocess setup. `<style lang="postcss">` is now required if using PostCSS inside style tags.
@ -442,7 +442,7 @@
### Major Changes
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vitejs.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vite.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Simplify Svelte preprocess setup. `<style lang="postcss">` is now required if using PostCSS inside style tags.

View file

@ -199,13 +199,13 @@
### Patch Changes
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
## 4.0.0-beta.0
### Patch Changes
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- [#9122](https://github.com/withastro/astro/pull/9122) [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721) Thanks [@bluwy](https://github.com/bluwy)! - Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vite.dev/guide/migration.html) for details of the breaking changes from Vite instead.
- Updated dependencies [[`abf601233`](https://github.com/withastro/astro/commit/abf601233f8188d118a8cb063c777478d8d9f1a3), [`6201bbe96`](https://github.com/withastro/astro/commit/6201bbe96c2a083fb201e4a43a9bd88499821a3e), [`cdabf6ef0`](https://github.com/withastro/astro/commit/cdabf6ef02be7220fd2b6bdcef924ceca089381e), [`1c48ed286`](https://github.com/withastro/astro/commit/1c48ed286538ab9e354eca4e4dcd7c6385c96721), [`37697a2c5`](https://github.com/withastro/astro/commit/37697a2c5511572dc29c0a4ea46f90c2f62be8e6), [`bd0c2e9ae`](https://github.com/withastro/astro/commit/bd0c2e9ae3389a9d3085050c1e8134ae98dff299), [`0fe3a7ed5`](https://github.com/withastro/astro/commit/0fe3a7ed5d7bb1a9fce1623e84ba14104b51223c), [`710be505c`](https://github.com/withastro/astro/commit/710be505c9ddf416e77a75343d8cae9c497d72c6), [`153a5abb9`](https://github.com/withastro/astro/commit/153a5abb905042ac68b712514dc9ec387d3e6b17)]:
- astro@4.0.0-beta.0
@ -357,7 +357,7 @@
- [#5782](https://github.com/withastro/astro/pull/5782) [`1f92d64ea`](https://github.com/withastro/astro/commit/1f92d64ea35c03fec43aff64eaf704dc5a9eb30a) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Remove support for Node 14. Minimum supported Node version is now >=16.12.0
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vitejs.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vite.dev/guide/migration.html) for more information.
- [#5806](https://github.com/withastro/astro/pull/5806) [`7572f7402`](https://github.com/withastro/astro/commit/7572f7402238da37de748be58d678fedaf863b53) Thanks [@matthewp](https://github.com/matthewp)! - Make astro a `peerDependency` of integrations
@ -395,7 +395,7 @@
### Major Changes
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vitejs.dev/guide/migration.html) for more information.
- [#5685](https://github.com/withastro/astro/pull/5685) [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb) Thanks [@bluwy](https://github.com/bluwy)! - Upgrade to Vite 4. Please see its [migration guide](https://vite.dev/guide/migration.html) for more information.
</details>

View file

@ -40,6 +40,7 @@ export default (element) =>
return content;
},
});
app.config.idPrefix = element.getAttribute('prefix');
await setup(app);
app.mount(element, isHydrate);
appMap.set(element, appInstance);

View file

@ -0,0 +1,24 @@
const contexts = new WeakMap();
const ID_PREFIX = 'v';
function getContext(rendererContextResult) {
if (contexts.has(rendererContextResult)) {
return contexts.get(rendererContextResult);
}
const ctx = {
currentIndex: 0,
get id() {
return ID_PREFIX + this.currentIndex.toString();
},
};
contexts.set(rendererContextResult, ctx);
return ctx;
}
export function incrementId(rendererContextResult) {
const ctx = getContext(rendererContextResult);
const id = ctx.id;
ctx.currentIndex++;
return id;
}

View file

@ -33,6 +33,7 @@
"files": [
"dist",
"client.js",
"context.js",
"server.js",
"server.d.ts",
"static-html.js"

View file

@ -1,6 +1,7 @@
import { setup } from 'virtual:@astrojs/vue/app';
import { createSSRApp, h } from 'vue';
import { renderToString } from 'vue/server-renderer';
import { incrementId } from './context.js';
import StaticHtml from './static-html.js';
function check(Component) {
@ -8,6 +9,12 @@ function check(Component) {
}
async function renderToStaticMarkup(Component, inputProps, slotted, metadata) {
let prefix;
if (this && this.result) {
prefix = incrementId(this.result);
}
const attrs = { prefix };
const slots = {};
const props = { ...inputProps };
delete props.slot;
@ -21,9 +28,10 @@ async function renderToStaticMarkup(Component, inputProps, slotted, metadata) {
});
}
const app = createSSRApp({ render: () => h(Component, props, slots) });
app.config.idPrefix = prefix;
await setup(app);
const html = await renderToString(app);
return { html };
return { html, attrs };
}
export default {

View file

@ -30,4 +30,13 @@ describe('Basics', () => {
assert.notEqual(img, undefined);
assert.equal(img.getAttribute('src'), '/light_walrus.avif');
});
it('Should generate unique ids when using useId()', async () => {
const data = await fixture.readFile('/index.html');
const { document } = parseHTML(data);
const els = document.querySelectorAll('.vue-use-id');
assert.equal(els.length, 2);
assert.notEqual(els[0].getAttribute('id'), els[1].getAttribute('id'));
});
});

View file

@ -0,0 +1,9 @@
<script setup>
import { useId } from "vue"
const id = useId()
</script>
<template>
<p class="vue-use-id" :id="id">{{ id }}</p>
</template>

View file

@ -1,6 +1,7 @@
---
import Bar from '../components/Foo.vue';
import Parent from '../components/Parent.astro';
import WithId from '../components/WithId.vue';
---
<html>
<head>
@ -10,5 +11,7 @@ import Parent from '../components/Parent.astro';
<Parent>
<Bar slot="footer" />
</Parent>
<WithId client:idle />
<WithId client:idle />
</body>
</html>

View file

@ -30,15 +30,14 @@
"//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES",
"dependencies": {
"@astrojs/cli-kit": "^0.4.1",
"semver": "^7.6.3",
"preferred-pm": "^4.0.0",
"semver": "^7.6.3",
"terminal-link": "^3.0.0"
},
"devDependencies": {
"@types/semver": "^7.5.8",
"arg": "^5.0.2",
"astro-scripts": "workspace:*",
"strip-ansi": "^7.1.0"
"astro-scripts": "workspace:*"
},
"engines": {
"node": "^18.17.1 || ^20.3.0 || >=21.0.0"

View file

@ -1,5 +1,5 @@
import { before, beforeEach } from 'node:test';
import stripAnsi from 'strip-ansi';
import { stripVTControlCharacters } from 'node:util';
import { setStdout } from '../dist/index.js';
export function setup() {
@ -8,7 +8,7 @@ export function setup() {
setStdout(
Object.assign({}, process.stdout, {
write(buf) {
ctx.messages.push(stripAnsi(String(buf)).trim());
ctx.messages.push(stripVTControlCharacters(String(buf)).trim());
return true;
},
}),

18
pnpm-lock.yaml generated
View file

@ -678,9 +678,6 @@ importers:
string-width:
specifier: ^7.2.0
version: 7.2.0
strip-ansi:
specifier: ^7.1.0
version: 7.1.0
tinyexec:
specifier: ^0.3.0
version: 0.3.0
@ -2774,6 +2771,12 @@ importers:
specifier: workspace:*
version: link:../../..
packages/astro/test/fixtures/core-image-data-url:
dependencies:
astro:
specifier: workspace:*
version: link:../../..
packages/astro/test/fixtures/core-image-deletion:
dependencies:
'@astrojs/markdoc':
@ -4242,9 +4245,6 @@ importers:
astro-scripts:
specifier: workspace:*
version: link:../../scripts
strip-ansi:
specifier: ^7.1.0
version: 7.1.0
strip-json-comments:
specifier: ^5.0.1
version: 5.0.1
@ -4283,9 +4283,6 @@ importers:
prompts:
specifier: ^2.4.2
version: 2.4.2
strip-ansi:
specifier: ^7.1.0
version: 7.1.0
yargs-parser:
specifier: ^21.1.1
version: 21.1.1
@ -5546,9 +5543,6 @@ importers:
astro-scripts:
specifier: workspace:*
version: link:../../scripts
strip-ansi:
specifier: ^7.1.0
version: 7.1.0
scripts:
dependencies: