astro 6.0.8 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.d.ts +30 -40
- package/dist/assets/build/generate.js +17 -19
- package/dist/assets/build/remote.d.ts +4 -4
- package/dist/assets/build/remote.js +12 -10
- package/dist/assets/fonts/infra/dev-font-file-id-generator.js +4 -1
- package/dist/assets/fonts/vite-plugin-fonts.js +8 -0
- package/dist/assets/services/sharp.d.ts +21 -2
- package/dist/assets/services/sharp.js +54 -12
- package/dist/assets/vite-plugin-assets.js +4 -1
- package/dist/cli/add/index.js +54 -0
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/index.d.ts +1 -1
- package/dist/content/index.js +2 -3
- package/dist/content/runtime.d.ts +2 -0
- package/dist/content/runtime.js +2 -1
- package/dist/content/types-generator.js +4 -0
- package/dist/content/utils.d.ts +0 -1
- package/dist/content/utils.js +1 -10
- package/dist/core/app/dev/app.d.ts +5 -0
- package/dist/core/app/dev/app.js +7 -0
- package/dist/core/app/entrypoints/virtual/dev.js +4 -0
- package/dist/core/app/node.js +5 -4
- package/dist/core/app/validate-headers.d.ts +6 -0
- package/dist/core/app/validate-headers.js +4 -0
- package/dist/core/base-pipeline.d.ts +5 -0
- package/dist/core/base-pipeline.js +7 -0
- package/dist/core/build/generate.d.ts +47 -0
- package/dist/core/build/generate.js +43 -25
- package/dist/core/build/plugins/plugin-css.js +8 -4
- package/dist/core/config/schemas/base.d.ts +4 -2
- package/dist/core/config/schemas/base.js +22 -1
- package/dist/core/config/schemas/relative.d.ts +3 -3
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +1 -1
- package/dist/core/dev/dev.js +13 -1
- package/dist/core/head-propagation/boundary.d.ts +8 -0
- package/dist/core/head-propagation/boundary.js +11 -0
- package/dist/core/head-propagation/buffer.d.ts +21 -0
- package/dist/core/head-propagation/buffer.js +18 -0
- package/dist/core/head-propagation/comment.d.ts +7 -0
- package/dist/core/head-propagation/comment.js +7 -0
- package/dist/core/head-propagation/graph.d.ts +18 -0
- package/dist/core/head-propagation/graph.js +32 -0
- package/dist/core/head-propagation/policy.d.ts +22 -0
- package/dist/core/head-propagation/policy.js +14 -0
- package/dist/core/head-propagation/resolver.d.ts +28 -0
- package/dist/core/head-propagation/resolver.js +25 -0
- package/dist/core/messages/runtime.d.ts +3 -0
- package/dist/core/messages/runtime.js +9 -1
- package/dist/core/middleware/vite-plugin.d.ts +1 -1
- package/dist/core/middleware/vite-plugin.js +25 -0
- package/dist/core/redirects/render.d.ts +17 -0
- package/dist/core/redirects/render.js +33 -24
- package/dist/core/routing/create-manifest.d.ts +15 -0
- package/dist/core/routing/create-manifest.js +131 -130
- package/dist/core/routing/prerender.d.ts +5 -0
- package/dist/core/routing/prerender.js +7 -1
- package/dist/core/server-islands/vite-plugin-server-islands.js +18 -6
- package/dist/integrations/hooks.js +4 -1
- package/dist/jsx/rehype.js +1 -1
- package/dist/manifest/serialized.js +5 -0
- package/dist/manifest/virtual-module.d.ts +4 -1
- package/dist/manifest/virtual-module.js +37 -35
- package/dist/runtime/client/dev-toolbar/apps/audit/rules/a11y.js +3 -3
- package/dist/runtime/server/render/astro/factory.js +6 -7
- package/dist/runtime/server/render/astro/instance.js +2 -4
- package/dist/runtime/server/render/astro/render.js +2 -11
- package/dist/runtime/server/render/common.js +3 -2
- package/dist/runtime/server/render/head-propagation/runtime.d.ts +20 -0
- package/dist/runtime/server/render/head-propagation/runtime.js +53 -0
- package/dist/runtime/server/render/page.js +5 -1
- package/dist/runtime/server/transition.d.ts +19 -1
- package/dist/runtime/server/transition.js +6 -1
- package/dist/transitions/events.d.ts +1 -1
- package/dist/transitions/events.js +5 -5
- package/dist/transitions/router.js +23 -19
- package/dist/types/public/config.d.ts +70 -11
- package/dist/types/public/integrations.d.ts +9 -2
- package/dist/vite-plugin-app/app.d.ts +5 -0
- package/dist/vite-plugin-app/app.js +17 -1
- package/dist/vite-plugin-app/createAstroServerApp.js +4 -0
- package/dist/vite-plugin-astro-server/plugin.js +2 -1
- package/dist/vite-plugin-astro-server/vite.js +2 -2
- package/dist/vite-plugin-head/index.js +63 -25
- package/dist/vite-plugin-scripts/index.js +5 -0
- package/package.json +11 -11
package/client.d.ts
CHANGED
|
@@ -30,36 +30,36 @@ interface ImportMeta {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
declare module 'astro:assets' {
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
33
|
+
// getImage's type here is different from the internal function since the Vite module implicitly pass the service config
|
|
34
|
+
/**
|
|
35
|
+
* Get an optimized image and the necessary attributes to render it.
|
|
36
|
+
*
|
|
37
|
+
* **Example**
|
|
38
|
+
* ```astro
|
|
39
|
+
* ---
|
|
40
|
+
* import { getImage } from 'astro:assets';
|
|
41
|
+
* import originalImage from '../assets/image.png';
|
|
42
|
+
*
|
|
43
|
+
* const optimizedImage = await getImage({src: originalImage, width: 1280 });
|
|
44
|
+
* ---
|
|
45
|
+
* <img src={optimizedImage.src} {...optimizedImage.attributes} />
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
|
|
49
|
+
*/
|
|
50
|
+
export const getImage: (
|
|
51
|
+
options: import('./dist/assets/types.js').UnresolvedImageTransform,
|
|
52
|
+
) => Promise<import('./dist/assets/types.js').GetImageResult>;
|
|
53
|
+
export const imageConfig: import('./dist/types/public/config.js').AstroConfig['image'];
|
|
54
|
+
export const getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService;
|
|
55
|
+
export const inferRemoteSize: typeof import('./dist/assets/utils/index.js').inferRemoteSize;
|
|
56
|
+
export const Image: typeof import('./components/Image.astro').default;
|
|
57
|
+
export const Picture: typeof import('./components/Picture.astro').default;
|
|
58
|
+
export const Font: typeof import('./components/Font.astro').default;
|
|
59
|
+
export const fontData: Record<
|
|
60
|
+
import('astro:assets').CssVariable,
|
|
61
|
+
Array<import('astro:assets').FontData>
|
|
62
|
+
>;
|
|
63
63
|
|
|
64
64
|
type ImgAttributes = import('./dist/type-utils.js').WithRequired<
|
|
65
65
|
Omit<import('./types').HTMLAttributes<'img'>, 'src' | 'width' | 'height'>,
|
|
@@ -72,16 +72,6 @@ declare module 'astro:assets' {
|
|
|
72
72
|
export type RemoteImageProps = import('./dist/type-utils.js').Simplify<
|
|
73
73
|
import('./dist/assets/types.js').RemoteImageProps<ImgAttributes>
|
|
74
74
|
>;
|
|
75
|
-
export const {
|
|
76
|
-
getImage,
|
|
77
|
-
getConfiguredImageService,
|
|
78
|
-
imageConfig,
|
|
79
|
-
Image,
|
|
80
|
-
Picture,
|
|
81
|
-
Font,
|
|
82
|
-
inferRemoteSize,
|
|
83
|
-
fontData,
|
|
84
|
-
}: AstroAssets;
|
|
85
75
|
}
|
|
86
76
|
|
|
87
77
|
declare module 'virtual:astro:image-styles.css' {
|
|
@@ -95,12 +95,11 @@ async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
|
|
|
95
95
|
};
|
|
96
96
|
} else {
|
|
97
97
|
const JSONData = JSON.parse(readFileSync(cachedMetaFileURL, "utf-8"));
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await fs.promises.unlink(cachedMetaFileURL);
|
|
98
|
+
if (typeof JSONData.expires !== "number") {
|
|
99
|
+
await Promise.allSettled([
|
|
100
|
+
fs.promises.unlink(cachedFileURL),
|
|
101
|
+
fs.promises.unlink(cachedMetaFileURL)
|
|
102
|
+
]);
|
|
104
103
|
throw new Error(
|
|
105
104
|
`Malformed cache entry for ${filepath}, cache will be regenerated for this file.`
|
|
106
105
|
);
|
|
@@ -114,9 +113,7 @@ async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
|
|
|
114
113
|
}
|
|
115
114
|
if (JSONData.expires > Date.now()) {
|
|
116
115
|
await fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE);
|
|
117
|
-
return {
|
|
118
|
-
cached: "hit"
|
|
119
|
-
};
|
|
116
|
+
return { cached: "hit" };
|
|
120
117
|
}
|
|
121
118
|
if (JSONData.etag || JSONData.lastModified) {
|
|
122
119
|
try {
|
|
@@ -124,15 +121,13 @@ async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
|
|
|
124
121
|
etag: JSONData.etag,
|
|
125
122
|
lastModified: JSONData.lastModified
|
|
126
123
|
});
|
|
127
|
-
if (revalidatedData.data
|
|
124
|
+
if (revalidatedData.data !== null) {
|
|
128
125
|
originalImage = revalidatedData;
|
|
129
126
|
} else {
|
|
130
|
-
await
|
|
131
|
-
|
|
132
|
-
cachedFileURL,
|
|
133
|
-
|
|
134
|
-
fs.constants.COPYFILE_FICLONE
|
|
135
|
-
);
|
|
127
|
+
await Promise.all([
|
|
128
|
+
writeCacheMetaFile(cachedMetaFileURL, revalidatedData, env),
|
|
129
|
+
fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE)
|
|
130
|
+
]);
|
|
136
131
|
return { cached: "revalidated" };
|
|
137
132
|
}
|
|
138
133
|
} catch (e) {
|
|
@@ -144,8 +139,10 @@ async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
|
|
|
144
139
|
return { cached: "hit" };
|
|
145
140
|
}
|
|
146
141
|
}
|
|
147
|
-
await
|
|
148
|
-
|
|
142
|
+
await Promise.allSettled([
|
|
143
|
+
fs.promises.unlink(cachedFileURL),
|
|
144
|
+
fs.promises.unlink(cachedMetaFileURL)
|
|
145
|
+
]);
|
|
149
146
|
}
|
|
150
147
|
} catch (e) {
|
|
151
148
|
if (e.code !== "ENOENT") {
|
|
@@ -219,7 +216,8 @@ async function writeCacheMetaFile(cachedMetaFileURL, resultData, env) {
|
|
|
219
216
|
expires: resultData.expires,
|
|
220
217
|
etag: resultData.etag,
|
|
221
218
|
lastModified: resultData.lastModified
|
|
222
|
-
})
|
|
219
|
+
}),
|
|
220
|
+
"utf-8"
|
|
223
221
|
);
|
|
224
222
|
} catch (e) {
|
|
225
223
|
env.logger.warn(
|
|
@@ -4,7 +4,7 @@ export type RemoteCacheEntry = {
|
|
|
4
4
|
etag?: string;
|
|
5
5
|
lastModified?: string;
|
|
6
6
|
};
|
|
7
|
-
export declare function loadRemoteImage(src: string): Promise<{
|
|
7
|
+
export declare function loadRemoteImage(src: string, fetchFn?: typeof fetch): Promise<{
|
|
8
8
|
data: Buffer<ArrayBuffer>;
|
|
9
9
|
expires: number;
|
|
10
10
|
etag: string | undefined;
|
|
@@ -17,13 +17,13 @@ export declare function loadRemoteImage(src: string): Promise<{
|
|
|
17
17
|
* The remote server may respond that the cached asset is still up-to-date if the entity-tag or modification time matches (304 Not Modified), or respond with an updated asset (200 OK)
|
|
18
18
|
* @param src - url to remote asset
|
|
19
19
|
* @param revalidationData - an object containing the stored Entity-Tag of the cached asset and/or the Last Modified time
|
|
20
|
-
* @returns An
|
|
20
|
+
* @returns An object containing the refreshed expiry time and cache headers. `data` will be a `Buffer` of the new image if the asset was modified (200 OK), or `null` if the cached version is still valid (304 Not Modified).
|
|
21
21
|
*/
|
|
22
22
|
export declare function revalidateRemoteImage(src: string, revalidationData: {
|
|
23
23
|
etag?: string;
|
|
24
24
|
lastModified?: string;
|
|
25
|
-
}): Promise<{
|
|
26
|
-
data: Buffer<ArrayBuffer
|
|
25
|
+
}, fetchFn?: typeof fetch): Promise<{
|
|
26
|
+
data: Buffer<ArrayBuffer> | null;
|
|
27
27
|
expires: number;
|
|
28
28
|
etag: string | undefined;
|
|
29
29
|
lastModified: string | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import CachePolicy from "http-cache-semantics";
|
|
2
|
-
async function loadRemoteImage(src) {
|
|
2
|
+
async function loadRemoteImage(src, fetchFn = globalThis.fetch) {
|
|
3
3
|
const req = new Request(src);
|
|
4
|
-
const res = await
|
|
4
|
+
const res = await fetchFn(req, { redirect: "manual" });
|
|
5
5
|
if (res.status >= 300 && res.status < 400) {
|
|
6
6
|
throw new Error(`Failed to load remote image ${src}. The request was redirected.`);
|
|
7
7
|
}
|
|
@@ -19,35 +19,37 @@ async function loadRemoteImage(src) {
|
|
|
19
19
|
lastModified: res.headers.get("Last-Modified") ?? void 0
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
async function revalidateRemoteImage(src, revalidationData) {
|
|
22
|
+
async function revalidateRemoteImage(src, revalidationData, fetchFn = globalThis.fetch) {
|
|
23
23
|
const headers = {
|
|
24
24
|
...revalidationData.etag && { "If-None-Match": revalidationData.etag },
|
|
25
25
|
...revalidationData.lastModified && { "If-Modified-Since": revalidationData.lastModified }
|
|
26
26
|
};
|
|
27
27
|
const req = new Request(src, { headers, cache: "no-cache" });
|
|
28
|
-
const res = await
|
|
29
|
-
if (res.status >= 300 && res.status < 400) {
|
|
30
|
-
throw new Error(`Failed to revalidate cached remote image ${src}. The request was redirected.`);
|
|
31
|
-
}
|
|
28
|
+
const res = await fetchFn(req, { redirect: "manual" });
|
|
32
29
|
if (!res.ok && res.status !== 304) {
|
|
30
|
+
if (res.status >= 300 && res.status < 400) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Failed to revalidate cached remote image ${src}. The request was redirected.`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
33
35
|
throw new Error(
|
|
34
36
|
`Failed to revalidate cached remote image ${src}. The request did not return a 200 OK / 304 NOT MODIFIED response. (received ${res.status} ${res.statusText})`
|
|
35
37
|
);
|
|
36
38
|
}
|
|
37
39
|
const data = Buffer.from(await res.arrayBuffer());
|
|
38
40
|
if (res.ok && !data.length) {
|
|
39
|
-
return await loadRemoteImage(src);
|
|
41
|
+
return await loadRemoteImage(src, fetchFn);
|
|
40
42
|
}
|
|
41
43
|
const policy = new CachePolicy(
|
|
42
44
|
webToCachePolicyRequest(req),
|
|
43
45
|
webToCachePolicyResponse(
|
|
44
46
|
res.ok ? res : new Response(null, { status: 200, headers: res.headers })
|
|
45
47
|
)
|
|
46
|
-
// 304 responses
|
|
48
|
+
// 304 responses are not cacheable, so just use its headers to get the refreshed TTL
|
|
47
49
|
);
|
|
48
50
|
const expires = policy.storable() ? policy.timeToLive() : 0;
|
|
49
51
|
return {
|
|
50
|
-
data,
|
|
52
|
+
data: res.ok ? data : null,
|
|
51
53
|
expires: Date.now() + expires,
|
|
52
54
|
// While servers should respond with the same headers as a 200 response, if they don't we should reuse the stored value
|
|
53
55
|
etag: res.headers.get("Etag") ?? (res.ok ? void 0 : revalidationData.etag),
|
|
@@ -17,6 +17,9 @@ class DevFontFileIdGenerator {
|
|
|
17
17
|
}
|
|
18
18
|
return weight?.replace(/\s+/g, "-");
|
|
19
19
|
}
|
|
20
|
+
#formatStyle(style) {
|
|
21
|
+
return style?.replace(/\s+/g, "-");
|
|
22
|
+
}
|
|
20
23
|
generate({
|
|
21
24
|
cssVariable,
|
|
22
25
|
originalUrl,
|
|
@@ -26,7 +29,7 @@ class DevFontFileIdGenerator {
|
|
|
26
29
|
return [
|
|
27
30
|
cssVariable.slice(2),
|
|
28
31
|
this.#formatWeight(font.weight),
|
|
29
|
-
font.style,
|
|
32
|
+
this.#formatStyle(font.style),
|
|
30
33
|
font.meta?.subset,
|
|
31
34
|
`${this.#hasher.hashString(this.#contentResolver.resolve(originalUrl))}.${type}`
|
|
32
35
|
].filter(Boolean).join("-");
|
|
@@ -51,6 +51,7 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
51
51
|
let isBuild;
|
|
52
52
|
let fontFetcher = null;
|
|
53
53
|
let fontTypeExtractor = null;
|
|
54
|
+
let built = false;
|
|
54
55
|
const cleanup = () => {
|
|
55
56
|
componentDataByCssVariable = null;
|
|
56
57
|
fontDataByCssVariable = null;
|
|
@@ -63,6 +64,9 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
63
64
|
isBuild = command === "build";
|
|
64
65
|
},
|
|
65
66
|
async buildStart() {
|
|
67
|
+
if (sync) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
66
70
|
const { root } = settings.config;
|
|
67
71
|
const hasher = await XxhashHasher.create();
|
|
68
72
|
const storage = new UnstorageFsStorage({
|
|
@@ -252,6 +256,9 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
252
256
|
}
|
|
253
257
|
},
|
|
254
258
|
async buildEnd() {
|
|
259
|
+
if (built) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
255
262
|
if (sync || !settings.config.fonts?.length || !isBuild) {
|
|
256
263
|
cleanup();
|
|
257
264
|
return;
|
|
@@ -282,6 +289,7 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
282
289
|
}
|
|
283
290
|
} finally {
|
|
284
291
|
cleanup();
|
|
292
|
+
built = true;
|
|
285
293
|
}
|
|
286
294
|
}
|
|
287
295
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ResizeOptions, SharpOptions } from 'sharp';
|
|
2
|
-
import { type LocalImageService } from './service.js';
|
|
1
|
+
import type { AvifOptions, JpegOptions, PngOptions, ResizeOptions, SharpOptions, WebpOptions } from 'sharp';
|
|
2
|
+
import { type BaseServiceTransform, type LocalImageService } from './service.js';
|
|
3
3
|
export interface SharpImageServiceConfig {
|
|
4
4
|
/**
|
|
5
5
|
* The `limitInputPixels` option passed to Sharp. See https://sharp.pixelplumbing.com/api-constructor for more information
|
|
@@ -9,6 +9,25 @@ export interface SharpImageServiceConfig {
|
|
|
9
9
|
* The `kernel` option is passed to resize calls. See https://sharp.pixelplumbing.com/api-resize/ for more information
|
|
10
10
|
*/
|
|
11
11
|
kernel?: ResizeOptions['kernel'];
|
|
12
|
+
/**
|
|
13
|
+
* The default encoder options passed to `sharp().jpeg()`.
|
|
14
|
+
*/
|
|
15
|
+
jpeg?: JpegOptions;
|
|
16
|
+
/**
|
|
17
|
+
* The default encoder options passed to `sharp().png()`.
|
|
18
|
+
*/
|
|
19
|
+
png?: PngOptions;
|
|
20
|
+
/**
|
|
21
|
+
* The default encoder options passed to `sharp().webp()`.
|
|
22
|
+
*/
|
|
23
|
+
webp?: WebpOptions;
|
|
24
|
+
/**
|
|
25
|
+
* The default encoder options passed to `sharp().avif()`.
|
|
26
|
+
*/
|
|
27
|
+
avif?: AvifOptions;
|
|
12
28
|
}
|
|
29
|
+
export declare function resolveSharpEncoderOptions(transform: Pick<BaseServiceTransform, 'format' | 'quality'>, inputFormat: string | undefined, serviceConfig?: SharpImageServiceConfig): JpegOptions | PngOptions | WebpOptions | AvifOptions | {
|
|
30
|
+
quality?: number;
|
|
31
|
+
} | undefined;
|
|
13
32
|
declare const sharpService: LocalImageService<SharpImageServiceConfig>;
|
|
14
33
|
export default sharpService;
|
|
@@ -10,6 +10,47 @@ const qualityTable = {
|
|
|
10
10
|
high: 80,
|
|
11
11
|
max: 100
|
|
12
12
|
};
|
|
13
|
+
function resolveSharpQuality(quality) {
|
|
14
|
+
if (!quality) return void 0;
|
|
15
|
+
const parsedQuality = parseQuality(quality);
|
|
16
|
+
if (typeof parsedQuality === "number") {
|
|
17
|
+
return parsedQuality;
|
|
18
|
+
}
|
|
19
|
+
return quality in qualityTable ? qualityTable[quality] : void 0;
|
|
20
|
+
}
|
|
21
|
+
function resolveSharpEncoderOptions(transform, inputFormat, serviceConfig = {}) {
|
|
22
|
+
const quality = resolveSharpQuality(transform.quality);
|
|
23
|
+
switch (transform.format) {
|
|
24
|
+
case "jpg":
|
|
25
|
+
case "jpeg":
|
|
26
|
+
return {
|
|
27
|
+
...serviceConfig.jpeg,
|
|
28
|
+
...quality === void 0 ? {} : { quality }
|
|
29
|
+
};
|
|
30
|
+
case "png":
|
|
31
|
+
return {
|
|
32
|
+
...serviceConfig.png,
|
|
33
|
+
...quality === void 0 ? {} : { quality }
|
|
34
|
+
};
|
|
35
|
+
case "webp": {
|
|
36
|
+
const webpOptions = {
|
|
37
|
+
...serviceConfig.webp,
|
|
38
|
+
...quality === void 0 ? {} : { quality }
|
|
39
|
+
};
|
|
40
|
+
if (inputFormat === "gif") {
|
|
41
|
+
webpOptions.loop ??= 0;
|
|
42
|
+
}
|
|
43
|
+
return webpOptions;
|
|
44
|
+
}
|
|
45
|
+
case "avif":
|
|
46
|
+
return {
|
|
47
|
+
...serviceConfig.avif,
|
|
48
|
+
...quality === void 0 ? {} : { quality }
|
|
49
|
+
};
|
|
50
|
+
default:
|
|
51
|
+
return quality === void 0 ? void 0 : { quality };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
13
54
|
async function loadSharp() {
|
|
14
55
|
let sharpImport;
|
|
15
56
|
try {
|
|
@@ -75,19 +116,19 @@ const sharpService = {
|
|
|
75
116
|
result.flatten({ background: transform.background });
|
|
76
117
|
}
|
|
77
118
|
if (transform.format) {
|
|
78
|
-
|
|
79
|
-
if (transform.quality) {
|
|
80
|
-
const parsedQuality = parseQuality(transform.quality);
|
|
81
|
-
if (typeof parsedQuality === "number") {
|
|
82
|
-
quality = parsedQuality;
|
|
83
|
-
} else {
|
|
84
|
-
quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
119
|
+
const encoderOptions = resolveSharpEncoderOptions(transform, format, config.service.config);
|
|
87
120
|
if (transform.format === "webp" && format === "gif") {
|
|
88
|
-
result.webp(
|
|
121
|
+
result.webp(encoderOptions);
|
|
122
|
+
} else if (transform.format === "webp") {
|
|
123
|
+
result.webp(encoderOptions);
|
|
124
|
+
} else if (transform.format === "png") {
|
|
125
|
+
result.png(encoderOptions);
|
|
126
|
+
} else if (transform.format === "avif") {
|
|
127
|
+
result.avif(encoderOptions);
|
|
128
|
+
} else if (transform.format === "jpeg" || transform.format === "jpg") {
|
|
129
|
+
result.jpeg(encoderOptions);
|
|
89
130
|
} else {
|
|
90
|
-
result.toFormat(transform.format,
|
|
131
|
+
result.toFormat(transform.format, encoderOptions);
|
|
91
132
|
}
|
|
92
133
|
}
|
|
93
134
|
const { data, info } = await result.toBuffer({ resolveWithObject: true });
|
|
@@ -100,5 +141,6 @@ const sharpService = {
|
|
|
100
141
|
};
|
|
101
142
|
var sharp_default = sharpService;
|
|
102
143
|
export {
|
|
103
|
-
sharp_default as default
|
|
144
|
+
sharp_default as default,
|
|
145
|
+
resolveSharpEncoderOptions
|
|
104
146
|
};
|
|
@@ -122,7 +122,10 @@ function assets({ fs, settings, sync, logger }) {
|
|
|
122
122
|
const getImageExport = isServerEnvironment ? `import { getImage as getImageInternal } from "astro/assets";
|
|
123
123
|
export const getImage = async (options) => await getImageInternal(options, imageConfig);` : `import { AstroError, AstroErrorData } from "astro/errors";
|
|
124
124
|
export const getImage = async () => {
|
|
125
|
-
throw new AstroError(
|
|
125
|
+
throw new AstroError(
|
|
126
|
+
AstroErrorData.GetImageNotUsedOnServer.message,
|
|
127
|
+
AstroErrorData.GetImageNotUsedOnServer.hint,
|
|
128
|
+
);
|
|
126
129
|
};`;
|
|
127
130
|
return {
|
|
128
131
|
code: `
|
package/dist/cli/add/index.js
CHANGED
|
@@ -207,6 +207,12 @@ async function add(names, { flags }) {
|
|
|
207
207
|
logger,
|
|
208
208
|
scripts: { "generate-types": "wrangler types" }
|
|
209
209
|
});
|
|
210
|
+
await updatePackageJsonOverrides({
|
|
211
|
+
configURL,
|
|
212
|
+
flags,
|
|
213
|
+
logger,
|
|
214
|
+
overrides: { vite: "^7" }
|
|
215
|
+
});
|
|
210
216
|
}
|
|
211
217
|
if (integrations.find((integration) => integration.id === "tailwind")) {
|
|
212
218
|
const dir = new URL("./styles/", new URL(userConfig.srcDir ?? "./src/", root));
|
|
@@ -601,6 +607,54 @@ async function updateAstroConfig({
|
|
|
601
607
|
return 2 /* cancelled */;
|
|
602
608
|
}
|
|
603
609
|
}
|
|
610
|
+
async function updatePackageJsonOverrides({
|
|
611
|
+
configURL,
|
|
612
|
+
flags,
|
|
613
|
+
logger,
|
|
614
|
+
overrides
|
|
615
|
+
}) {
|
|
616
|
+
const pkgURL = new URL("./package.json", configURL);
|
|
617
|
+
if (!existsSync(pkgURL)) {
|
|
618
|
+
logger.debug("add", "No package.json found, skipping overrides update");
|
|
619
|
+
return 0 /* none */;
|
|
620
|
+
}
|
|
621
|
+
const pkgPath = fileURLToPath(pkgURL);
|
|
622
|
+
const input = await fs.readFile(pkgPath, { encoding: "utf-8" });
|
|
623
|
+
const pkgJson = JSON.parse(input);
|
|
624
|
+
pkgJson.overrides ??= {};
|
|
625
|
+
let hasChanges = false;
|
|
626
|
+
for (const [name, range] of Object.entries(overrides)) {
|
|
627
|
+
if (!(name in pkgJson.overrides)) {
|
|
628
|
+
pkgJson.overrides[name] = range;
|
|
629
|
+
hasChanges = true;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (!hasChanges) {
|
|
633
|
+
return 0 /* none */;
|
|
634
|
+
}
|
|
635
|
+
const output = JSON.stringify(pkgJson, null, 2);
|
|
636
|
+
const diff = getDiffContent(input, output);
|
|
637
|
+
if (!diff) {
|
|
638
|
+
return 0 /* none */;
|
|
639
|
+
}
|
|
640
|
+
logger.info(
|
|
641
|
+
"SKIP_FORMAT",
|
|
642
|
+
`
|
|
643
|
+
${magenta("Astro will add the following overrides to your package.json:")}`
|
|
644
|
+
);
|
|
645
|
+
clack.box(diff, "package.json", {
|
|
646
|
+
rounded: true,
|
|
647
|
+
withGuide: false,
|
|
648
|
+
width: "auto"
|
|
649
|
+
});
|
|
650
|
+
if (await askToContinue({ flags, logger })) {
|
|
651
|
+
await fs.writeFile(pkgPath, output, { encoding: "utf-8" });
|
|
652
|
+
logger.debug("add", "Updated package.json overrides");
|
|
653
|
+
return 1 /* updated */;
|
|
654
|
+
} else {
|
|
655
|
+
return 2 /* cancelled */;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
604
658
|
async function updatePackageJsonScripts({
|
|
605
659
|
configURL,
|
|
606
660
|
flags,
|
|
@@ -192,7 +192,7 @@ ${contentConfig.error.message}`
|
|
|
192
192
|
logger.info("Content config changed");
|
|
193
193
|
shouldClear = true;
|
|
194
194
|
}
|
|
195
|
-
if (previousAstroVersion && previousAstroVersion !== "6.0
|
|
195
|
+
if (previousAstroVersion && previousAstroVersion !== "6.1.0") {
|
|
196
196
|
logger.info("Astro version changed");
|
|
197
197
|
shouldClear = true;
|
|
198
198
|
}
|
|
@@ -200,8 +200,8 @@ ${contentConfig.error.message}`
|
|
|
200
200
|
logger.info("Clearing content store");
|
|
201
201
|
this.#store.clearAll();
|
|
202
202
|
}
|
|
203
|
-
if ("6.0
|
|
204
|
-
this.#store.metaStore().set("astro-version", "6.0
|
|
203
|
+
if ("6.1.0") {
|
|
204
|
+
this.#store.metaStore().set("astro-version", "6.1.0");
|
|
205
205
|
}
|
|
206
206
|
if (currentConfigDigest) {
|
|
207
207
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
package/dist/content/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { attachContentServerListeners } from './server-listeners.js';
|
|
2
2
|
export { createContentTypesGenerator } from './types-generator.js';
|
|
3
|
-
export { getContentPaths
|
|
3
|
+
export { getContentPaths } from './utils.js';
|
|
4
4
|
export { astroContentAssetPropagationPlugin } from './vite-plugin-content-assets.js';
|
|
5
5
|
export { astroContentImportPlugin } from './vite-plugin-content-imports.js';
|
|
6
6
|
export { astroContentVirtualModPlugin } from './vite-plugin-content-virtual-mod.js';
|
package/dist/content/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { attachContentServerListeners } from "./server-listeners.js";
|
|
2
2
|
import { createContentTypesGenerator } from "./types-generator.js";
|
|
3
|
-
import { getContentPaths
|
|
3
|
+
import { getContentPaths } from "./utils.js";
|
|
4
4
|
import { astroContentAssetPropagationPlugin } from "./vite-plugin-content-assets.js";
|
|
5
5
|
import { astroContentImportPlugin } from "./vite-plugin-content-imports.js";
|
|
6
6
|
import { astroContentVirtualModPlugin } from "./vite-plugin-content-virtual-mod.js";
|
|
@@ -10,6 +10,5 @@ export {
|
|
|
10
10
|
astroContentVirtualModPlugin,
|
|
11
11
|
attachContentServerListeners,
|
|
12
12
|
createContentTypesGenerator,
|
|
13
|
-
getContentPaths
|
|
14
|
-
hasAssetPropagationFlag
|
|
13
|
+
getContentPaths
|
|
15
14
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { MarkdownHeading } from '@astrojs/markdown-remark';
|
|
2
2
|
import * as z from 'zod/v4';
|
|
3
3
|
import type * as zCore from 'zod/v4/core';
|
|
4
|
+
import type { ImageMetadata } from '../assets/types.js';
|
|
4
5
|
import { type AstroComponentFactory } from '../runtime/server/index.js';
|
|
5
6
|
import type { LiveDataCollectionResult, LiveDataEntryResult } from '../types/public/content.js';
|
|
6
7
|
import { type LIVE_CONTENT_TYPE } from './consts.js';
|
|
@@ -67,6 +68,7 @@ type RenderResult = {
|
|
|
67
68
|
headings: MarkdownHeading[];
|
|
68
69
|
remarkPluginFrontmatter: Record<string, any>;
|
|
69
70
|
};
|
|
71
|
+
export declare function updateImageReferencesInData<T extends Record<string, unknown>>(data: T, fileName?: string, imageAssetMap?: Map<string, ImageMetadata>): T;
|
|
70
72
|
export declare function renderEntry(entry: DataEntry): Promise<RenderResult>;
|
|
71
73
|
export declare function createReference(): (collection: string) => z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
72
74
|
id: z.ZodString;
|
package/dist/content/runtime.js
CHANGED
|
@@ -450,9 +450,13 @@ async function generateJSONSchema(fsMod, collectionConfig, collectionKey, collec
|
|
|
450
450
|
zodSchemaForJson = z.object({}).catchall(zodSchemaForJson);
|
|
451
451
|
}
|
|
452
452
|
if (zodSchemaForJson instanceof z.ZodObject) {
|
|
453
|
+
const existingMeta = z.globalRegistry.get(zodSchemaForJson);
|
|
453
454
|
zodSchemaForJson = zodSchemaForJson.extend({
|
|
454
455
|
$schema: z.string().optional()
|
|
455
456
|
});
|
|
457
|
+
if (existingMeta) {
|
|
458
|
+
z.globalRegistry.add(zodSchemaForJson, existingMeta);
|
|
459
|
+
}
|
|
456
460
|
}
|
|
457
461
|
try {
|
|
458
462
|
const schema = z.toJSONSchema(zodSchemaForJson, {
|
package/dist/content/utils.d.ts
CHANGED
|
@@ -187,7 +187,6 @@ export declare function getEntrySlug({ id, collection, generatedSlug, contentEnt
|
|
|
187
187
|
fileUrl: URL;
|
|
188
188
|
contentEntryType: Pick<ContentEntryType, 'getEntryInfo'>;
|
|
189
189
|
}): Promise<string>;
|
|
190
|
-
export declare function hasAssetPropagationFlag(id: string): boolean;
|
|
191
190
|
/**
|
|
192
191
|
* Unlike `path.posix.relative`, this function will accept a platform path and return a posix path.
|
|
193
192
|
*/
|
package/dist/content/utils.js
CHANGED
|
@@ -15,8 +15,7 @@ import {
|
|
|
15
15
|
CONTENT_MODULE_FLAG,
|
|
16
16
|
DEFERRED_MODULE,
|
|
17
17
|
IMAGE_IMPORT_PREFIX,
|
|
18
|
-
LIVE_CONTENT_TYPE
|
|
19
|
-
PROPAGATED_ASSET_FLAG
|
|
18
|
+
LIVE_CONTENT_TYPE
|
|
20
19
|
} from "./consts.js";
|
|
21
20
|
import { glob, secretLegacyFlag } from "./loaders/glob.js";
|
|
22
21
|
import { createImage } from "./runtime-assets.js";
|
|
@@ -620,13 +619,6 @@ function globWithUnderscoresIgnored(relContentDir, exts) {
|
|
|
620
619
|
`!${contentDir}**/_*${extGlob}`
|
|
621
620
|
];
|
|
622
621
|
}
|
|
623
|
-
function hasAssetPropagationFlag(id) {
|
|
624
|
-
try {
|
|
625
|
-
return new URL(id, "file://").searchParams.has(PROPAGATED_ASSET_FLAG);
|
|
626
|
-
} catch {
|
|
627
|
-
return false;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
622
|
function posixifyPath(filePath) {
|
|
631
623
|
return filePath.split(path.sep).join("/");
|
|
632
624
|
}
|
|
@@ -674,7 +666,6 @@ export {
|
|
|
674
666
|
getEntryType,
|
|
675
667
|
getSymlinkedContentCollections,
|
|
676
668
|
globalContentConfigObserver,
|
|
677
|
-
hasAssetPropagationFlag,
|
|
678
669
|
hasContentFlag,
|
|
679
670
|
isDeferredModule,
|
|
680
671
|
loaderReturnSchema,
|
|
@@ -9,6 +9,11 @@ export declare class DevApp extends BaseApp<NonRunnablePipeline> {
|
|
|
9
9
|
constructor(manifest: SSRManifest, streaming: boolean | undefined, logger: Logger);
|
|
10
10
|
createPipeline(streaming: boolean, manifest: SSRManifest, logger: Logger): NonRunnablePipeline;
|
|
11
11
|
isDev(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Clears the cached middleware so it is re-resolved on the next request.
|
|
14
|
+
* Called via HMR when middleware files change.
|
|
15
|
+
*/
|
|
16
|
+
clearMiddleware(): void;
|
|
12
17
|
/**
|
|
13
18
|
* Updates the routes list when files change during development.
|
|
14
19
|
* Called via HMR when new pages are added/removed.
|