@astrojs/cloudflare 13.0.2 → 13.1.1
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/dist/entrypoints/image-passthrough-endpoint.d.ts +3 -0
- package/dist/entrypoints/image-passthrough-endpoint.js +49 -0
- package/dist/entrypoints/preview.js +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +61 -25
- package/dist/utils/image-binding-transform.js +10 -3
- package/dist/utils/image-config.d.ts +6 -8
- package/dist/utils/image-config.js +12 -2
- package/dist/vite-plugin-dev-server-prerender-middleware.d.ts +6 -0
- package/dist/vite-plugin-dev-server-prerender-middleware.js +26 -0
- package/package.json +5 -4
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { imageConfig } from "astro:assets";
|
|
2
|
+
import { isRemotePath } from "@astrojs/internal-helpers/path";
|
|
3
|
+
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
|
|
4
|
+
import { env } from "cloudflare:workers";
|
|
5
|
+
const prerender = false;
|
|
6
|
+
const GET = async ({ request }) => {
|
|
7
|
+
try {
|
|
8
|
+
const url = new URL(request.url);
|
|
9
|
+
const href = url.searchParams.get("href");
|
|
10
|
+
if (!href) return new Response("Bad Request", { status: 400 });
|
|
11
|
+
const isRemote = isRemotePath(href);
|
|
12
|
+
let response;
|
|
13
|
+
if (isRemote) {
|
|
14
|
+
if (!isRemoteAllowed(href, imageConfig)) {
|
|
15
|
+
return new Response("Forbidden", { status: 403 });
|
|
16
|
+
}
|
|
17
|
+
response = await fetch(href, { redirect: "manual" });
|
|
18
|
+
} else {
|
|
19
|
+
const sourceUrl = new URL(href, url.origin);
|
|
20
|
+
if (sourceUrl.origin !== url.origin) {
|
|
21
|
+
return new Response("Forbidden", { status: 403 });
|
|
22
|
+
}
|
|
23
|
+
response = await env.ASSETS.fetch(new Request(sourceUrl, { headers: request.headers }));
|
|
24
|
+
}
|
|
25
|
+
if (response.status >= 300 && response.status < 400) {
|
|
26
|
+
return new Response("Not Found", { status: 404 });
|
|
27
|
+
}
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
return new Response("Not Found", { status: 404 });
|
|
30
|
+
}
|
|
31
|
+
const contentType = response.headers.get("Content-Type") ?? "";
|
|
32
|
+
if (!contentType.startsWith("image/")) {
|
|
33
|
+
return new Response("Forbidden", { status: 403 });
|
|
34
|
+
}
|
|
35
|
+
const headers = new Headers();
|
|
36
|
+
headers.set("Content-Type", contentType);
|
|
37
|
+
headers.set("Cache-Control", "public, max-age=31536000");
|
|
38
|
+
headers.set("Date", (/* @__PURE__ */ new Date()).toUTCString());
|
|
39
|
+
const etag = response.headers.get("ETag");
|
|
40
|
+
if (etag) headers.set("ETag", etag);
|
|
41
|
+
return new Response(response.body, { status: 200, headers });
|
|
42
|
+
} catch (_err) {
|
|
43
|
+
return new Response("Internal Server Error", { status: 500 });
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export {
|
|
47
|
+
GET,
|
|
48
|
+
prerender
|
|
49
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve as resolvePath } from "node:path";
|
|
1
3
|
import {
|
|
2
4
|
preview
|
|
3
5
|
} from "vite";
|
|
@@ -14,6 +16,11 @@ const createPreviewServer = async ({
|
|
|
14
16
|
host,
|
|
15
17
|
root
|
|
16
18
|
}) => {
|
|
19
|
+
const wranglerConfigPath = resolvePath(fileURLToPath(root), ".wrangler/deploy/config.json");
|
|
20
|
+
if (!existsSync(wranglerConfigPath)) {
|
|
21
|
+
logger.error("No build output found. Run `astro build` before running `astro preview`.");
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
17
24
|
const startServerTime = performance.now();
|
|
18
25
|
let previewServer;
|
|
19
26
|
try {
|
|
@@ -80,7 +87,7 @@ function serverStart({
|
|
|
80
87
|
host,
|
|
81
88
|
base
|
|
82
89
|
}) {
|
|
83
|
-
const version = "13.
|
|
90
|
+
const version = "13.1.1";
|
|
84
91
|
const localPrefix = `${colors.dim("\u2503")} Local `;
|
|
85
92
|
const networkPrefix = `${colors.dim("\u2503")} Network `;
|
|
86
93
|
const emptyPrefix = " ".repeat(11);
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,13 @@ export interface Options extends Pick<PluginConfig, 'auxiliaryWorkers' | 'config
|
|
|
25
25
|
* See https://developers.cloudflare.com/images/transform-images/bindings/ for more details.
|
|
26
26
|
*/
|
|
27
27
|
imagesBindingName?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Controls which runtime is used for prerendering static pages at build time.
|
|
30
|
+
*
|
|
31
|
+
* - `'workerd'` (default): Uses Cloudflare's workerd runtime.
|
|
32
|
+
* - `'node'`: Uses Astro's default node prerender environment.
|
|
33
|
+
*/
|
|
34
|
+
prerenderEnvironment?: 'workerd' | 'node';
|
|
28
35
|
experimental?: Pick<NonNullable<PluginConfig['experimental']>, 'headersAndRedirectsDevModeSupport'>;
|
|
29
36
|
}
|
|
30
|
-
export default function createIntegration({ imageService, sessionKVBindingName, imagesBindingName, ...cloudflareOptions }?: Options): AstroIntegration;
|
|
37
|
+
export default function createIntegration({ imageService, sessionKVBindingName, imagesBindingName, prerenderEnvironment, ...cloudflareOptions }?: Options): AstroIntegration;
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
setImageConfig
|
|
12
12
|
} from "./utils/image-config.js";
|
|
13
13
|
import { createConfigPlugin } from "./vite-plugin-config.js";
|
|
14
|
+
import { createNodePrerenderPlugin } from "./vite-plugin-dev-server-prerender-middleware.js";
|
|
14
15
|
import {
|
|
15
16
|
cloudflareConfigCustomizer,
|
|
16
17
|
DEFAULT_SESSION_KV_BINDING_NAME,
|
|
@@ -19,7 +20,6 @@ import {
|
|
|
19
20
|
import { parseEnv } from "node:util";
|
|
20
21
|
import { sessionDrivers } from "astro/config";
|
|
21
22
|
import { createCloudflarePrerenderer } from "./prerenderer.js";
|
|
22
|
-
import { createRequire } from "node:module";
|
|
23
23
|
const CLOUDFLARE_KV_SESSION_DRIVER_ENTRYPOINT = sessionDrivers.cloudflareKVBinding().entrypoint;
|
|
24
24
|
function usesCloudflareKVSessionDriver(session) {
|
|
25
25
|
const driver = session?.driver;
|
|
@@ -32,10 +32,28 @@ function usesCloudflareKVSessionDriver(session) {
|
|
|
32
32
|
const entrypoint = typeof driver.entrypoint === "string" ? driver.entrypoint : driver.entrypoint.toString();
|
|
33
33
|
return entrypoint === CLOUDFLARE_KV_SESSION_DRIVER_ENTRYPOINT || entrypoint.endsWith("cloudflare-kv-binding");
|
|
34
34
|
}
|
|
35
|
+
function hasContentCollectionsConfig(srcDir) {
|
|
36
|
+
const contentConfigPaths = [
|
|
37
|
+
"content.config.mjs",
|
|
38
|
+
"content.config.js",
|
|
39
|
+
"content.config.mts",
|
|
40
|
+
"content.config.ts",
|
|
41
|
+
"content/config.mjs",
|
|
42
|
+
"content/config.js",
|
|
43
|
+
"content/config.mts",
|
|
44
|
+
"content/config.ts",
|
|
45
|
+
"live.config.mjs",
|
|
46
|
+
"live.config.js",
|
|
47
|
+
"live.config.mts",
|
|
48
|
+
"live.config.ts"
|
|
49
|
+
];
|
|
50
|
+
return contentConfigPaths.some((configPath) => existsSync(new URL(`./${configPath}`, srcDir)));
|
|
51
|
+
}
|
|
35
52
|
function createIntegration({
|
|
36
53
|
imageService,
|
|
37
54
|
sessionKVBindingName = DEFAULT_SESSION_KV_BINDING_NAME,
|
|
38
55
|
imagesBindingName = DEFAULT_IMAGES_BINDING_NAME,
|
|
56
|
+
prerenderEnvironment = "workerd",
|
|
39
57
|
...cloudflareOptions
|
|
40
58
|
} = {}) {
|
|
41
59
|
let _config;
|
|
@@ -76,22 +94,26 @@ function createIntegration({
|
|
|
76
94
|
}
|
|
77
95
|
const needsSessionKVBinding = usesCloudflareKVSessionDriver(session);
|
|
78
96
|
const needsImagesBindingForDev = isCompile && command === "dev";
|
|
97
|
+
const usesContentCollections = hasContentCollectionsConfig(config.srcDir);
|
|
98
|
+
const prebundleContentRuntime = command === "dev" && usesContentCollections;
|
|
79
99
|
cfPluginConfig = {
|
|
80
100
|
config: cloudflareConfigCustomizer({
|
|
81
101
|
needsSessionKVBinding,
|
|
82
102
|
sessionKVBindingName,
|
|
83
103
|
imagesBindingName: needsImagesBinding || needsImagesBindingForDev ? imagesBindingName : false
|
|
84
104
|
}),
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
105
|
+
...prerenderEnvironment === "workerd" && {
|
|
106
|
+
experimental: {
|
|
107
|
+
prerenderWorker: {
|
|
108
|
+
config(_, { entryWorkerConfig }) {
|
|
109
|
+
return {
|
|
110
|
+
...entryWorkerConfig,
|
|
111
|
+
name: "prerender",
|
|
112
|
+
...needsImagesBinding && !entryWorkerConfig.images && {
|
|
113
|
+
images: { binding: imagesBindingName }
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
95
117
|
}
|
|
96
118
|
}
|
|
97
119
|
}
|
|
@@ -106,7 +128,12 @@ function createIntegration({
|
|
|
106
128
|
session,
|
|
107
129
|
vite: {
|
|
108
130
|
plugins: [
|
|
109
|
-
|
|
131
|
+
...prerenderEnvironment === "node" && command === "dev" ? [createNodePrerenderPlugin()] : [],
|
|
132
|
+
cfVitePlugin({
|
|
133
|
+
...cloudflareOptions,
|
|
134
|
+
...cfPluginConfig,
|
|
135
|
+
viteEnvironment: { name: "ssr" }
|
|
136
|
+
}),
|
|
110
137
|
{
|
|
111
138
|
name: "@astrojs/cloudflare:cf-imports",
|
|
112
139
|
enforce: "pre",
|
|
@@ -129,6 +156,7 @@ function createIntegration({
|
|
|
129
156
|
return {
|
|
130
157
|
optimizeDeps: {
|
|
131
158
|
include: [
|
|
159
|
+
"@astrojs/cloudflare/image-service-workerd",
|
|
132
160
|
"astro",
|
|
133
161
|
"astro/runtime/**",
|
|
134
162
|
"astro > html-escaper",
|
|
@@ -146,8 +174,14 @@ function createIntegration({
|
|
|
146
174
|
"astro > picomatch",
|
|
147
175
|
"astro/app",
|
|
148
176
|
"astro/assets",
|
|
177
|
+
"astro/assets/runtime",
|
|
178
|
+
"astro/assets/utils/inferRemoteSize.js",
|
|
179
|
+
"astro/assets/fonts/runtime.js",
|
|
180
|
+
...prebundleContentRuntime ? ["astro/content/runtime"] : [],
|
|
149
181
|
"astro/compiler-runtime",
|
|
150
|
-
"astro/
|
|
182
|
+
"astro/jsx-runtime",
|
|
183
|
+
"astro/app/entrypoint/dev",
|
|
184
|
+
"astro/virtual-modules/middleware.js"
|
|
151
185
|
],
|
|
152
186
|
exclude: [
|
|
153
187
|
"unstorage/drivers/cloudflare-kv-binding",
|
|
@@ -200,7 +234,7 @@ function createIntegration({
|
|
|
200
234
|
image: setImageConfig(imageService, config.image, command, logger)
|
|
201
235
|
});
|
|
202
236
|
if (cloudflareOptions.configPath) {
|
|
203
|
-
addWatchFile(
|
|
237
|
+
addWatchFile(new URL(cloudflareOptions.configPath, config.root));
|
|
204
238
|
}
|
|
205
239
|
addWatchFile(new URL("./wrangler.toml", config.root));
|
|
206
240
|
addWatchFile(new URL("./wrangler.json", config.root));
|
|
@@ -254,17 +288,19 @@ function createIntegration({
|
|
|
254
288
|
}
|
|
255
289
|
},
|
|
256
290
|
"astro:build:start": ({ setPrerenderer }) => {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
291
|
+
if (prerenderEnvironment === "workerd") {
|
|
292
|
+
setPrerenderer(
|
|
293
|
+
createCloudflarePrerenderer({
|
|
294
|
+
root: _config.root,
|
|
295
|
+
serverDir: _config.build.server,
|
|
296
|
+
clientDir: _config.build.client,
|
|
297
|
+
base: _config.base,
|
|
298
|
+
trailingSlash: _config.trailingSlash,
|
|
299
|
+
cfPluginConfig,
|
|
300
|
+
hasCompileImageService: buildService === "compile"
|
|
301
|
+
})
|
|
302
|
+
);
|
|
303
|
+
}
|
|
268
304
|
},
|
|
269
305
|
"astro:build:setup": ({ vite, target }) => {
|
|
270
306
|
if (target === "server") {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { imageConfig } from "astro:assets";
|
|
2
2
|
import { isRemotePath } from "@astrojs/internal-helpers/path";
|
|
3
3
|
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
|
|
4
|
+
const qualityTable = {
|
|
5
|
+
low: 25,
|
|
6
|
+
mid: 50,
|
|
7
|
+
high: 80,
|
|
8
|
+
max: 100
|
|
9
|
+
};
|
|
4
10
|
async function transform(rawUrl, images, assets) {
|
|
5
11
|
const url = new URL(rawUrl);
|
|
6
12
|
const href = url.searchParams.get("href");
|
|
@@ -28,10 +34,11 @@ async function transform(rawUrl, images, assets) {
|
|
|
28
34
|
return (await input.transform({
|
|
29
35
|
width: url.searchParams.has("w") ? Number.parseInt(url.searchParams.get("w")) : void 0,
|
|
30
36
|
height: url.searchParams.has("h") ? Number.parseInt(url.searchParams.get("h")) : void 0,
|
|
31
|
-
// `quality` is documented, but doesn't appear to work in manual testing...
|
|
32
|
-
// quality: url.searchParams.get('q'),
|
|
33
37
|
fit: url.searchParams.get("fit")
|
|
34
|
-
}).output({
|
|
38
|
+
}).output({
|
|
39
|
+
quality: url.searchParams.get("q") ? qualityTable[url.searchParams.get("q")] ?? Number.parseInt(url.searchParams.get("q")) : void 0,
|
|
40
|
+
format: outputFormat
|
|
41
|
+
})).response();
|
|
35
42
|
}
|
|
36
43
|
export {
|
|
37
44
|
transform
|
|
@@ -10,12 +10,11 @@ export declare function normalizeImageServiceConfig(config: ImageServiceConfig |
|
|
|
10
10
|
runtimeService: ImageServiceMode;
|
|
11
11
|
};
|
|
12
12
|
export declare function setImageConfig(service: ImageServiceConfig | undefined, config: AstroConfig['image'], command: HookParameters<'astro:config:setup'>['command'], logger: AstroIntegrationLogger): {
|
|
13
|
-
service:
|
|
13
|
+
service: {
|
|
14
|
+
entrypoint: string;
|
|
15
|
+
};
|
|
14
16
|
endpoint: {
|
|
15
17
|
entrypoint: string;
|
|
16
|
-
} | {
|
|
17
|
-
route: string;
|
|
18
|
-
entrypoint?: string | undefined;
|
|
19
18
|
};
|
|
20
19
|
domains: string[];
|
|
21
20
|
remotePatterns: {
|
|
@@ -30,11 +29,10 @@ export declare function setImageConfig(service: ImageServiceConfig | undefined,
|
|
|
30
29
|
objectPosition?: string | undefined;
|
|
31
30
|
breakpoints?: number[] | undefined;
|
|
32
31
|
} | {
|
|
33
|
-
service:
|
|
34
|
-
entrypoint: string;
|
|
35
|
-
};
|
|
32
|
+
service: import("astro").ImageServiceConfig<Record<string, any>>;
|
|
36
33
|
endpoint: {
|
|
37
|
-
|
|
34
|
+
route: string;
|
|
35
|
+
entrypoint?: string | undefined;
|
|
38
36
|
};
|
|
39
37
|
domains: string[];
|
|
40
38
|
remotePatterns: {
|
|
@@ -13,6 +13,9 @@ function normalizeImageServiceConfig(config) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
const GENERIC_ENDPOINT = { entrypoint: "astro/assets/endpoint/generic" };
|
|
16
|
+
const CLOUDFLARE_PASSTHROUGH_ENDPOINT = {
|
|
17
|
+
entrypoint: "@astrojs/cloudflare/image-passthrough-endpoint"
|
|
18
|
+
};
|
|
16
19
|
const WORKERD_IMAGE_SERVICE = { entrypoint: "@astrojs/cloudflare/image-service-workerd" };
|
|
17
20
|
function setImageConfig(service, config, command, logger) {
|
|
18
21
|
const { buildService, runtimeService } = normalizeImageServiceConfig(service);
|
|
@@ -21,9 +24,16 @@ function setImageConfig(service, config, command, logger) {
|
|
|
21
24
|
return {
|
|
22
25
|
...config,
|
|
23
26
|
service: passthroughImageService(),
|
|
24
|
-
endpoint: command === "dev" ? GENERIC_ENDPOINT :
|
|
27
|
+
endpoint: command === "dev" ? GENERIC_ENDPOINT : CLOUDFLARE_PASSTHROUGH_ENDPOINT
|
|
25
28
|
};
|
|
26
29
|
case "cloudflare":
|
|
30
|
+
if (command === "dev") {
|
|
31
|
+
return {
|
|
32
|
+
...config,
|
|
33
|
+
service: passthroughImageService(),
|
|
34
|
+
endpoint: GENERIC_ENDPOINT
|
|
35
|
+
};
|
|
36
|
+
}
|
|
27
37
|
return {
|
|
28
38
|
...config,
|
|
29
39
|
service: { entrypoint: "@astrojs/cloudflare/image-service" }
|
|
@@ -42,7 +52,7 @@ function setImageConfig(service, config, command, logger) {
|
|
|
42
52
|
service: WORKERD_IMAGE_SERVICE,
|
|
43
53
|
// Dev: IMAGES binding (via Cloudflare Vite plugin) for real transforms.
|
|
44
54
|
// Build: endpoint depends on runtime - `cloudflare-binding` uses IMAGES, `passthrough` uses generic.
|
|
45
|
-
endpoint: command === "dev" || runtimeService === "cloudflare-binding" ? { entrypoint: "@astrojs/cloudflare/image-transform-endpoint" } :
|
|
55
|
+
endpoint: command === "dev" || runtimeService === "cloudflare-binding" ? { entrypoint: "@astrojs/cloudflare/image-transform-endpoint" } : CLOUDFLARE_PASSTHROUGH_ENDPOINT
|
|
46
56
|
};
|
|
47
57
|
case "custom":
|
|
48
58
|
return { ...config };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const devPrerenderMiddlewareSymbol = /* @__PURE__ */ Symbol.for("astro.devPrerenderMiddleware");
|
|
2
|
+
function createNodePrerenderPlugin() {
|
|
3
|
+
return {
|
|
4
|
+
name: "@astrojs/cloudflare:dev-server-prerender-middleware",
|
|
5
|
+
config() {
|
|
6
|
+
return {
|
|
7
|
+
environments: {
|
|
8
|
+
prerender: { dev: {} }
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
// Disable dep optimization for the `prerender` environment so dependencies
|
|
13
|
+
// are loaded via native import() with correct import.meta.url semantics.
|
|
14
|
+
configEnvironment(environmentName) {
|
|
15
|
+
if (environmentName === "prerender") {
|
|
16
|
+
return { optimizeDeps: { noDiscovery: true, include: [] } };
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
configureServer(server) {
|
|
20
|
+
server[devPrerenderMiddlewareSymbol] = true;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
createNodePrerenderPlugin
|
|
26
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/cloudflare",
|
|
3
3
|
"description": "Deploy your site to Cloudflare Workers",
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.1.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"author": "withastro",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"./entrypoints/server.js": "./dist/entrypoints/server.js",
|
|
26
26
|
"./image-service": "./dist/entrypoints/image-service-external.js",
|
|
27
27
|
"./image-transform-endpoint": "./dist/entrypoints/image-transform-endpoint.js",
|
|
28
|
+
"./image-passthrough-endpoint": "./dist/entrypoints/image-passthrough-endpoint.js",
|
|
28
29
|
"./image-service-workerd": "./dist/entrypoints/image-service-workerd.js",
|
|
29
30
|
"./handler": "./dist/utils/handler.js",
|
|
30
31
|
"./types.d.ts": "./types.d.ts",
|
|
@@ -39,8 +40,8 @@
|
|
|
39
40
|
"piccolore": "^0.1.3",
|
|
40
41
|
"tinyglobby": "^0.2.15",
|
|
41
42
|
"vite": "^7.3.1",
|
|
42
|
-
"@astrojs/
|
|
43
|
-
"@astrojs/
|
|
43
|
+
"@astrojs/internal-helpers": "0.8.0",
|
|
44
|
+
"@astrojs/underscore-redirects": "1.0.1"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
47
|
"astro": "^6.0.0-alpha.0",
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
"@types/node": "^25.2.2",
|
|
52
53
|
"cheerio": "1.2.0",
|
|
53
54
|
"devalue": "^5.6.3",
|
|
54
|
-
"astro": "6.0.
|
|
55
|
+
"astro": "6.0.4",
|
|
55
56
|
"astro-scripts": "0.0.14"
|
|
56
57
|
},
|
|
57
58
|
"publishConfig": {
|