astro 7.2.3 → 7.2.5
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/bin/astro.mjs +15 -0
- package/client.d.ts +8 -4
- package/dist/assets/consts.d.ts +1 -1
- package/dist/assets/consts.js +1 -0
- package/dist/assets/fonts/infra/remote-runtime-font-file-url-resolver.d.ts +6 -4
- package/dist/assets/fonts/infra/remote-runtime-font-file-url-resolver.js +14 -7
- package/dist/assets/utils/node.js +3 -0
- package/dist/assets/utils/vendor/image-size/types/heif.js +8 -3
- package/dist/assets/utils/vendor/image-size/types/icns.js +10 -2
- package/dist/assets/utils/vendor/image-size/types/jp2.js +2 -2
- package/dist/assets/utils/vendor/image-size/types/jxl.js +5 -2
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +1 -1
- package/dist/assets/utils/vendor/image-size/types/utils.js +20 -6
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/cli/server.js +13 -0
- package/dist/container/index.js +8 -5
- package/dist/content/config.d.ts +2 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/loaders/glob.js +3 -3
- package/dist/content/mutable-data-store.js +49 -2
- package/dist/core/app/base.js +3 -7
- package/dist/core/build/plugins/plugin-incremental.js +8 -2
- package/dist/core/build/vite-build-config.js +15 -6
- package/dist/core/cache/memory-provider.js +6 -1
- package/dist/core/compile/compile.js +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/lockfile.js +3 -0
- package/dist/core/errors/dev/utils.js +3 -3
- package/dist/core/fetch/fetch-state.js +11 -14
- package/dist/core/i18n/domain.js +4 -11
- package/dist/core/i18n/handler.js +5 -1
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/routing/match-request.js +2 -13
- package/dist/core/session/runtime.js +4 -2
- package/dist/core/session/types.d.ts +5 -5
- package/dist/core/util/normalized-url.d.ts +8 -0
- package/dist/core/util/normalized-url.js +10 -4
- package/dist/i18n/utils.js +3 -4
- package/dist/runtime/server/astro-global.js +2 -2
- package/dist/runtime/server/render/csp.js +13 -5
- package/dist/transitions/swap-functions.js +4 -2
- package/dist/types/public/config.d.ts +1 -1
- package/dist/vite-plugin-routes/index.js +1 -1
- package/package.json +7 -7
- package/templates/content/module.mjs +3 -3
- package/types/content.d.ts +2 -2
package/bin/astro.mjs
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
import module from 'node:module';
|
|
5
|
+
|
|
6
|
+
// In CI writing the cache is (most of the time) harmful, as it'll never get re-used and just slows down the CLI.
|
|
7
|
+
if (!process.env.CI) {
|
|
8
|
+
try {
|
|
9
|
+
module.enableCompileCache?.();
|
|
10
|
+
// Long-running commands like `astro dev` never reach the flush that happens on process exit.
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
try {
|
|
13
|
+
module.flushCompileCache?.();
|
|
14
|
+
} catch {}
|
|
15
|
+
}, 10_000).unref();
|
|
16
|
+
} catch {}
|
|
17
|
+
}
|
|
18
|
+
|
|
4
19
|
const CI_INSTRUCTIONS = {
|
|
5
20
|
NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript',
|
|
6
21
|
GITHUB_ACTIONS:
|
package/client.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/// <reference path="./types/transitions.d.ts" />
|
|
8
8
|
|
|
9
9
|
interface ImportMetaEnv {
|
|
10
|
-
// TODO: remove in Astro
|
|
10
|
+
// TODO: remove in Astro 8
|
|
11
11
|
/**
|
|
12
12
|
* The prefix for Astro-generated asset links if the build.assetsPrefix config option is set. This can be used to create asset links not handled by Astro.
|
|
13
13
|
* @deprecated This will be removed in a future major version of Astro. Use `build.assetsPrefix` from `astro:config/server` instead.
|
|
@@ -98,6 +98,10 @@ declare module '*.png' {
|
|
|
98
98
|
const metadata: ImageMetadata;
|
|
99
99
|
export default metadata;
|
|
100
100
|
}
|
|
101
|
+
declare module '*.apng' {
|
|
102
|
+
const metadata: ImageMetadata;
|
|
103
|
+
export default metadata;
|
|
104
|
+
}
|
|
101
105
|
declare module '*.tiff' {
|
|
102
106
|
const metadata: ImageMetadata;
|
|
103
107
|
export default metadata;
|
|
@@ -149,11 +153,11 @@ declare module 'astro:components' {
|
|
|
149
153
|
export * from 'astro/components';
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
// TODO: remove in Astro
|
|
156
|
+
// TODO: remove in Astro 8
|
|
153
157
|
/**
|
|
154
158
|
* @deprecated
|
|
155
159
|
* `import { z } from 'astro:schema'` is deprecated and will be removed
|
|
156
|
-
* in Astro
|
|
160
|
+
* in Astro 8. Use `import { z } from 'astro/zod'` instead.
|
|
157
161
|
*/
|
|
158
162
|
declare module 'astro:schema' {
|
|
159
163
|
export * from 'astro/zod';
|
|
@@ -162,7 +166,7 @@ declare module 'astro:schema' {
|
|
|
162
166
|
/**
|
|
163
167
|
* @deprecated
|
|
164
168
|
* `import { z } from 'astro:schema'` is deprecated and will be removed
|
|
165
|
-
* in Astro
|
|
169
|
+
* in Astro 8. Use `import { z } from 'astro/zod'` instead.
|
|
166
170
|
*/
|
|
167
171
|
export const z = zod.z;
|
|
168
172
|
}
|
package/dist/assets/consts.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const VIRTUAL_GET_IMAGE_ID = "virtual:astro:get-image";
|
|
|
5
5
|
export declare const RESOLVED_VIRTUAL_GET_IMAGE_ID: string;
|
|
6
6
|
export declare const VIRTUAL_IMAGE_STYLES_ID = "virtual:astro:image-styles.css";
|
|
7
7
|
export declare const RESOLVED_VIRTUAL_IMAGE_STYLES_ID: string;
|
|
8
|
-
export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg", "avif"];
|
|
8
|
+
export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "apng", "tiff", "webp", "gif", "svg", "avif"];
|
|
9
9
|
/**
|
|
10
10
|
* Valid formats that our base services support.
|
|
11
11
|
* Certain formats can be imported (namely SVGs) but will not be processed.
|
package/dist/assets/consts.js
CHANGED
|
@@ -5,9 +5,11 @@ import type { RuntimeFontFileUrlResolver } from '../definitions.js';
|
|
|
5
5
|
* During prerendering, a temporary Node HTTP server is started to
|
|
6
6
|
* serve font files.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* When possible, the resolver uses a statically known server
|
|
9
|
+
* {@link address}. When the address is not yet available (e.g. the
|
|
10
|
+
* virtual module was evaluated before the HTTP server started
|
|
11
|
+
* listening — see #17722), the resolver falls back to deriving the
|
|
12
|
+
* origin from the caller-supplied {@link requestUrl}.
|
|
11
13
|
*/
|
|
12
14
|
export declare class RemoteRuntimeFontFileUrlResolver implements RuntimeFontFileUrlResolver {
|
|
13
15
|
#private;
|
|
@@ -15,5 +17,5 @@ export declare class RemoteRuntimeFontFileUrlResolver implements RuntimeFontFile
|
|
|
15
17
|
urls: Set<string>;
|
|
16
18
|
address: AddressInfo | null;
|
|
17
19
|
});
|
|
18
|
-
resolve(url: string): string | null;
|
|
20
|
+
resolve(url: string, requestUrl: URL | undefined): string | null;
|
|
19
21
|
}
|
|
@@ -8,18 +8,25 @@ class RemoteRuntimeFontFileUrlResolver {
|
|
|
8
8
|
this.#urls = urls;
|
|
9
9
|
this.#address = address;
|
|
10
10
|
}
|
|
11
|
-
resolve(url) {
|
|
11
|
+
resolve(url, requestUrl) {
|
|
12
12
|
if (!this.#urls.has(url)) {
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
|
-
if (!this.#address) {
|
|
16
|
-
throw new Error("Server address unavailable, this should not happen. Open an issue.");
|
|
17
|
-
}
|
|
18
15
|
if (!url.startsWith("/")) {
|
|
19
|
-
|
|
16
|
+
if (this.#address) {
|
|
17
|
+
url = new URL(url).pathname;
|
|
18
|
+
} else {
|
|
19
|
+
return url;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (this.#address) {
|
|
23
|
+
const host = this.#address.family === "IPv6" ? `[${this.#address.address}]` : this.#address.address;
|
|
24
|
+
return `http://${host}:${this.#address.port}${url}`;
|
|
25
|
+
}
|
|
26
|
+
if (requestUrl) {
|
|
27
|
+
return `${requestUrl.origin}${url}`;
|
|
20
28
|
}
|
|
21
|
-
|
|
22
|
-
return `http://${host}:${this.#address.port}${url}`;
|
|
29
|
+
throw new Error("Server address unavailable, this should not happen. Open an issue.");
|
|
23
30
|
}
|
|
24
31
|
}
|
|
25
32
|
export {
|
|
@@ -80,6 +80,9 @@ async function emitImageMetadata(id, fileEmitter) {
|
|
|
80
80
|
throw err;
|
|
81
81
|
}
|
|
82
82
|
const fileMetadata = await imageMetadata(fileData, id);
|
|
83
|
+
if (path.extname(id).toLowerCase() === ".apng") {
|
|
84
|
+
fileMetadata.format = "apng";
|
|
85
|
+
}
|
|
83
86
|
const emittedImage = {
|
|
84
87
|
src: "",
|
|
85
88
|
...fileMetadata
|
|
@@ -46,20 +46,25 @@ const HEIF = {
|
|
|
46
46
|
const type = detectType(input, 8, metaBox.offset);
|
|
47
47
|
const images = [];
|
|
48
48
|
let currentOffset = ipcoBox.offset + 8;
|
|
49
|
-
|
|
49
|
+
const ipcoEnd = ipcoBox.offset + ipcoBox.size;
|
|
50
|
+
while (currentOffset < ipcoEnd) {
|
|
50
51
|
const ispeBox = findBox(input, "ispe", currentOffset);
|
|
51
52
|
if (!ispeBox) break;
|
|
53
|
+
if (ispeBox.size < 8) break;
|
|
54
|
+
if (ispeBox.offset + ispeBox.size > ipcoEnd) break;
|
|
52
55
|
const rawWidth = readUInt32BE(input, ispeBox.offset + 12);
|
|
53
56
|
const rawHeight = readUInt32BE(input, ispeBox.offset + 16);
|
|
54
57
|
const clapBox = findBox(input, "clap", currentOffset);
|
|
55
58
|
let width = rawWidth;
|
|
56
59
|
let height = rawHeight;
|
|
57
|
-
if (clapBox && clapBox.offset <
|
|
60
|
+
if (clapBox && clapBox.offset < ipcoEnd && clapBox.size >= 8) {
|
|
58
61
|
const cropRight = readUInt32BE(input, clapBox.offset + 12);
|
|
59
62
|
width = rawWidth - cropRight;
|
|
60
63
|
}
|
|
61
64
|
images.push({ height, width });
|
|
62
|
-
|
|
65
|
+
const nextOffset = ispeBox.offset + ispeBox.size;
|
|
66
|
+
if (nextOffset <= currentOffset) break;
|
|
67
|
+
currentOffset = nextOffset;
|
|
63
68
|
}
|
|
64
69
|
if (images.length === 0) {
|
|
65
70
|
throw new TypeError("Invalid HEIF, no sizes found");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readUInt32BE, toUTF8String } from "./utils.js";
|
|
2
2
|
const SIZE_HEADER = 4 + 4;
|
|
3
3
|
const FILE_LENGTH_OFFSET = 4;
|
|
4
|
+
const MIN_ENTRY_LENGTH = 8;
|
|
4
5
|
const ENTRY_LENGTH_OFFSET = 4;
|
|
5
6
|
const ICON_TYPE_SIZE = {
|
|
6
7
|
ICON: 32,
|
|
@@ -63,10 +64,17 @@ const ICNS = {
|
|
|
63
64
|
let imageOffset = SIZE_HEADER;
|
|
64
65
|
const images = [];
|
|
65
66
|
while (imageOffset < fileLength && imageOffset < inputLength) {
|
|
67
|
+
if (inputLength - imageOffset < MIN_ENTRY_LENGTH) break;
|
|
66
68
|
const imageHeader = readImageHeader(input, imageOffset);
|
|
69
|
+
const entryLength = imageHeader[1];
|
|
70
|
+
if (entryLength < MIN_ENTRY_LENGTH) break;
|
|
67
71
|
const imageSize = getImageSize(imageHeader[0]);
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
if (imageSize.width && imageSize.height) {
|
|
73
|
+
images.push(imageSize);
|
|
74
|
+
}
|
|
75
|
+
const nextOffset = imageOffset + entryLength;
|
|
76
|
+
if (nextOffset <= imageOffset) break;
|
|
77
|
+
imageOffset = nextOffset;
|
|
70
78
|
}
|
|
71
79
|
if (images.length === 0) {
|
|
72
80
|
throw new TypeError("Invalid ICNS, no sizes found");
|
|
@@ -10,8 +10,8 @@ const JP2 = {
|
|
|
10
10
|
},
|
|
11
11
|
calculate(input) {
|
|
12
12
|
const jp2hBox = findBox(input, "jp2h", 0);
|
|
13
|
-
const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8);
|
|
14
|
-
if (ihdrBox) {
|
|
13
|
+
const ihdrBox = jp2hBox && jp2hBox.size >= 8 && findBox(input, "ihdr", jp2hBox.offset + 8);
|
|
14
|
+
if (ihdrBox && ihdrBox.size >= 8) {
|
|
15
15
|
return {
|
|
16
16
|
height: readUInt32BE(input, ihdrBox.offset + 8),
|
|
17
17
|
width: readUInt32BE(input, ihdrBox.offset + 12)
|
|
@@ -2,7 +2,7 @@ import { JXLStream } from "./jxl-stream.js";
|
|
|
2
2
|
import { findBox, toUTF8String } from "./utils.js";
|
|
3
3
|
function extractCodestream(input) {
|
|
4
4
|
const jxlcBox = findBox(input, "jxlc", 0);
|
|
5
|
-
if (jxlcBox) {
|
|
5
|
+
if (jxlcBox && jxlcBox.size >= 8) {
|
|
6
6
|
return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size);
|
|
7
7
|
}
|
|
8
8
|
const partialStreams = extractPartialStreams(input);
|
|
@@ -17,10 +17,13 @@ function extractPartialStreams(input) {
|
|
|
17
17
|
while (offset < input.length) {
|
|
18
18
|
const jxlpBox = findBox(input, "jxlp", offset);
|
|
19
19
|
if (!jxlpBox) break;
|
|
20
|
+
if (jxlpBox.size < 12) break;
|
|
20
21
|
partialStreams.push(
|
|
21
22
|
input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size)
|
|
22
23
|
);
|
|
23
|
-
|
|
24
|
+
const nextOffset = jxlpBox.offset + jxlpBox.size;
|
|
25
|
+
if (nextOffset <= offset) break;
|
|
26
|
+
offset = nextOffset;
|
|
24
27
|
}
|
|
25
28
|
return partialStreams;
|
|
26
29
|
}
|
|
@@ -9,7 +9,7 @@ export declare const readUInt32BE: (input: Uint8Array, offset?: number) => numbe
|
|
|
9
9
|
export declare const readUInt32LE: (input: Uint8Array, offset?: number) => number;
|
|
10
10
|
export declare const readUInt64: (input: Uint8Array, offset: number, isBigEndian: boolean) => bigint;
|
|
11
11
|
export declare function readUInt(input: Uint8Array, bits: 16 | 32, offset?: number, isBigEndian?: boolean): number;
|
|
12
|
-
export declare function findBox(input: Uint8Array, boxName: string,
|
|
12
|
+
export declare function findBox(input: Uint8Array, boxName: string, startOffset: number): {
|
|
13
13
|
name: string;
|
|
14
14
|
offset: number;
|
|
15
15
|
size: number;
|
|
@@ -24,22 +24,36 @@ function readUInt(input, bits, offset = 0, isBigEndian = false) {
|
|
|
24
24
|
const methodName = `readUInt${bits}${endian}`;
|
|
25
25
|
return methods[methodName](input, offset);
|
|
26
26
|
}
|
|
27
|
+
const MIN_BOX_HEADER = 8;
|
|
27
28
|
function readBox(input, offset) {
|
|
28
|
-
if (input.length - offset <
|
|
29
|
+
if (input.length - offset < MIN_BOX_HEADER) return;
|
|
29
30
|
const boxSize = readUInt32BE(input, offset);
|
|
31
|
+
if (boxSize === 0) {
|
|
32
|
+
return {
|
|
33
|
+
name: toUTF8String(input, offset + 4, offset + 8),
|
|
34
|
+
offset,
|
|
35
|
+
size: input.length - offset
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (boxSize === 1) return;
|
|
39
|
+
if (boxSize < MIN_BOX_HEADER) return;
|
|
30
40
|
if (input.length - offset < boxSize) return;
|
|
31
41
|
return {
|
|
32
|
-
name: toUTF8String(input,
|
|
42
|
+
name: toUTF8String(input, offset + 4, offset + 8),
|
|
33
43
|
offset,
|
|
34
44
|
size: boxSize
|
|
35
45
|
};
|
|
36
46
|
}
|
|
37
|
-
function findBox(input, boxName,
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
function findBox(input, boxName, startOffset) {
|
|
48
|
+
let offset = startOffset;
|
|
49
|
+
while (offset < input.length) {
|
|
50
|
+
const box = readBox(input, offset);
|
|
40
51
|
if (!box) break;
|
|
41
52
|
if (box.name === boxName) return box;
|
|
42
|
-
|
|
53
|
+
if (box.size < MIN_BOX_HEADER) break;
|
|
54
|
+
const nextOffset = offset + box.size;
|
|
55
|
+
if (nextOffset <= offset) break;
|
|
56
|
+
offset = nextOffset;
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
59
|
export {
|
package/dist/cli/server.js
CHANGED
|
@@ -75,6 +75,19 @@ function buildBackgroundArgs(command, flags) {
|
|
|
75
75
|
if (flags.root) args.push("--root", String(flags.root));
|
|
76
76
|
if (flags.allowedHosts) args.push("--allowed-hosts", String(flags.allowedHosts));
|
|
77
77
|
if (flags.json) args.push("--json");
|
|
78
|
+
if (flags.mode) args.push("--mode", String(flags.mode));
|
|
79
|
+
if (flags.site) args.push("--site", String(flags.site));
|
|
80
|
+
if (flags.base) args.push("--base", String(flags.base));
|
|
81
|
+
if (flags.outDir) args.push("--out-dir", String(flags.outDir));
|
|
82
|
+
if (flags.verbose) args.push("--verbose");
|
|
83
|
+
if (flags.silent) args.push("--silent");
|
|
84
|
+
if (flags.open != null) {
|
|
85
|
+
if (typeof flags.open === "string") {
|
|
86
|
+
args.push("--open", flags.open);
|
|
87
|
+
} else if (flags.open) {
|
|
88
|
+
args.push("--open");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
78
91
|
return args;
|
|
79
92
|
}
|
|
80
93
|
async function stopExistingServer(root, command, pid) {
|
package/dist/container/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import { createConsoleLogger } from "../core/logger/impls/console.js";
|
|
|
16
16
|
import { setLogger } from "../core/logger/manifest-logger.js";
|
|
17
17
|
import { peekMiddleware } from "../core/middleware/load.js";
|
|
18
18
|
import { getRouteTable } from "../core/routing/route-table.js";
|
|
19
|
-
function createManifest(manifest, renderers, middleware) {
|
|
19
|
+
function createManifest(manifest, renderers, middleware, site) {
|
|
20
20
|
function middlewareInstance() {
|
|
21
21
|
return {
|
|
22
22
|
onRequest: middleware ?? NOOP_MIDDLEWARE_FN
|
|
@@ -54,6 +54,7 @@ function createManifest(manifest, renderers, middleware) {
|
|
|
54
54
|
componentMetadata: manifest?.componentMetadata ?? /* @__PURE__ */ new Map(),
|
|
55
55
|
inlinedScripts: manifest?.inlinedScripts ?? /* @__PURE__ */ new Map(),
|
|
56
56
|
i18n: manifest?.i18n,
|
|
57
|
+
site: site ?? manifest?.site,
|
|
57
58
|
checkOrigin: false,
|
|
58
59
|
allowedDomains: manifest?.allowedDomains ?? [],
|
|
59
60
|
actionBodySizeLimit: 1024 * 1024,
|
|
@@ -93,9 +94,10 @@ class experimental_AstroContainer {
|
|
|
93
94
|
streaming = false,
|
|
94
95
|
manifest,
|
|
95
96
|
renderers,
|
|
96
|
-
resolve
|
|
97
|
+
resolve,
|
|
98
|
+
site
|
|
97
99
|
}) {
|
|
98
|
-
const ssrManifest = createManifest(manifest, renderers);
|
|
100
|
+
const ssrManifest = createManifest(manifest, renderers, void 0, site);
|
|
99
101
|
const containerRenderers = renderers ?? manifest?.renderers ?? [];
|
|
100
102
|
const containerResolve = async (specifier) => {
|
|
101
103
|
if (this.#withManifest) {
|
|
@@ -133,12 +135,13 @@ class experimental_AstroContainer {
|
|
|
133
135
|
* @param {AstroContainerOptions=} containerOptions
|
|
134
136
|
*/
|
|
135
137
|
static async create(containerOptions = {}) {
|
|
136
|
-
const { streaming = false, manifest, renderers = [], resolve } = containerOptions;
|
|
138
|
+
const { streaming = false, manifest, renderers = [], resolve, astroConfig } = containerOptions;
|
|
137
139
|
return new experimental_AstroContainer({
|
|
138
140
|
streaming,
|
|
139
141
|
manifest,
|
|
140
142
|
renderers,
|
|
141
|
-
resolve
|
|
143
|
+
resolve,
|
|
144
|
+
site: astroConfig?.site ?? manifest?.site
|
|
142
145
|
});
|
|
143
146
|
}
|
|
144
147
|
/**
|
package/dist/content/config.d.ts
CHANGED
|
@@ -13,7 +13,8 @@ type ImageFunction = () => z.ZodObject<{
|
|
|
13
13
|
zCore.$ZodLiteral<'webp'>,
|
|
14
14
|
zCore.$ZodLiteral<'gif'>,
|
|
15
15
|
zCore.$ZodLiteral<'svg'>,
|
|
16
|
-
zCore.$ZodLiteral<'avif'
|
|
16
|
+
zCore.$ZodLiteral<'avif'>,
|
|
17
|
+
zCore.$ZodLiteral<'apng'>
|
|
17
18
|
]>;
|
|
18
19
|
}>;
|
|
19
20
|
export interface DataEntry {
|
|
@@ -196,7 +196,7 @@ ${contentConfig.error.message}`
|
|
|
196
196
|
logger.info("Content config changed");
|
|
197
197
|
shouldClear = true;
|
|
198
198
|
}
|
|
199
|
-
if (previousAstroVersion && previousAstroVersion !== "7.2.
|
|
199
|
+
if (previousAstroVersion && previousAstroVersion !== "7.2.5") {
|
|
200
200
|
logger.info("Astro version changed");
|
|
201
201
|
shouldClear = true;
|
|
202
202
|
}
|
|
@@ -204,8 +204,8 @@ ${contentConfig.error.message}`
|
|
|
204
204
|
logger.info("Clearing content store");
|
|
205
205
|
this.#store.clearAll();
|
|
206
206
|
}
|
|
207
|
-
if ("7.2.
|
|
208
|
-
this.#store.metaStore().set("astro-version", "7.2.
|
|
207
|
+
if ("7.2.5") {
|
|
208
|
+
this.#store.metaStore().set("astro-version", "7.2.5");
|
|
209
209
|
}
|
|
210
210
|
if (currentConfigDigest) {
|
|
211
211
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
|
@@ -12,7 +12,7 @@ function generateIdDefault({ entry, base, data }, isLegacy) {
|
|
|
12
12
|
if (data.slug) {
|
|
13
13
|
return String(data.slug);
|
|
14
14
|
}
|
|
15
|
-
const entryURL = new URL(encodeURI(entry), base);
|
|
15
|
+
const entryURL = new URL("./" + encodeURI(entry), base);
|
|
16
16
|
if (isLegacy) {
|
|
17
17
|
const { id } = getContentEntryIdAndSlug({
|
|
18
18
|
entry: entryURL,
|
|
@@ -69,7 +69,7 @@ function glob(globOptions) {
|
|
|
69
69
|
logger.warn(`No entry type found for ${entry}`);
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
-
const fileUrl = new URL(encodeURI(entry), base);
|
|
72
|
+
const fileUrl = new URL("./" + encodeURI(entry), base);
|
|
73
73
|
const contents = await fs.readFile(fileUrl, "utf-8").catch((err) => {
|
|
74
74
|
logger.error(`Error reading ${entry}: ${err.message}`);
|
|
75
75
|
return;
|
|
@@ -212,7 +212,7 @@ function glob(globOptions) {
|
|
|
212
212
|
["config.js", "config.ts", "config.mjs"].map((file) => new URL(file, contentDir).href)
|
|
213
213
|
);
|
|
214
214
|
function isConfigFile(file) {
|
|
215
|
-
const fileUrl = new URL(file, baseDir);
|
|
215
|
+
const fileUrl = new URL("./" + encodeURI(file), baseDir);
|
|
216
216
|
return configFiles.has(fileUrl.href);
|
|
217
217
|
}
|
|
218
218
|
await Promise.all(
|
|
@@ -42,17 +42,20 @@ class MutableDataStore extends ImmutableDataStore {
|
|
|
42
42
|
collection.delete(String(key));
|
|
43
43
|
this.#saveToDiskDebounced();
|
|
44
44
|
this.#writeAssetsImportsDebounced();
|
|
45
|
+
this.#writeModulesImportsDebounced();
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
clear(collectionName) {
|
|
48
49
|
this._collections.delete(collectionName);
|
|
49
50
|
this.#saveToDiskDebounced();
|
|
50
51
|
this.#writeAssetsImportsDebounced();
|
|
52
|
+
this.#writeModulesImportsDebounced();
|
|
51
53
|
}
|
|
52
54
|
clearAll() {
|
|
53
55
|
this._collections.clear();
|
|
54
56
|
this.#saveToDiskDebounced();
|
|
55
57
|
this.#writeAssetsImportsDebounced();
|
|
58
|
+
this.#writeModulesImportsDebounced();
|
|
56
59
|
}
|
|
57
60
|
addAssetImport(assetImport, filePath) {
|
|
58
61
|
const id = imageSrcToImportId(assetImport, filePath);
|
|
@@ -93,6 +96,26 @@ class MutableDataStore extends ImmutableDataStore {
|
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Rebuilds #moduleImports from the current entries in _collections.
|
|
101
|
+
* This ensures stale module entries are removed when content files are
|
|
102
|
+
* deleted or renamed, preventing Vite from attempting to resolve
|
|
103
|
+
* non-existent files listed in content-modules.mjs.
|
|
104
|
+
*/
|
|
105
|
+
#rebuildModuleImports() {
|
|
106
|
+
this.#moduleImports.clear();
|
|
107
|
+
for (const collection of this._collections.values()) {
|
|
108
|
+
for (const entry of collection.values()) {
|
|
109
|
+
const typedEntry = entry;
|
|
110
|
+
if (typedEntry.deferredRender && typedEntry.filePath) {
|
|
111
|
+
const id = contentModuleToId(typedEntry.filePath);
|
|
112
|
+
if (id) {
|
|
113
|
+
this.#moduleImports.set(typedEntry.filePath, id);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
96
119
|
async writeAssetImports(filePath) {
|
|
97
120
|
this.#assetsFile = filePath;
|
|
98
121
|
this.#rebuildAssetImports();
|
|
@@ -130,12 +153,14 @@ export default new Map([${exports.join(", ")}]);
|
|
|
130
153
|
}
|
|
131
154
|
async writeModuleImports(filePath) {
|
|
132
155
|
this.#modulesFile = filePath;
|
|
156
|
+
this.#rebuildModuleImports();
|
|
133
157
|
if (this.#moduleImports.size === 0) {
|
|
134
158
|
try {
|
|
135
159
|
await this.#writeFileAtomic(filePath, "export default new Map();");
|
|
136
160
|
} catch (err) {
|
|
137
161
|
throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause: err });
|
|
138
162
|
}
|
|
163
|
+
return;
|
|
139
164
|
}
|
|
140
165
|
if (!this.#modulesDirty && existsSync(filePath)) {
|
|
141
166
|
return;
|
|
@@ -264,7 +289,17 @@ ${lines.join(",\n")}]);
|
|
|
264
289
|
entries: () => this.entries(collectionName),
|
|
265
290
|
values: () => this.values(collectionName),
|
|
266
291
|
keys: () => this.keys(collectionName),
|
|
267
|
-
set: ({
|
|
292
|
+
set: ({
|
|
293
|
+
id: key,
|
|
294
|
+
data,
|
|
295
|
+
body,
|
|
296
|
+
filePath,
|
|
297
|
+
deferredRender,
|
|
298
|
+
digest,
|
|
299
|
+
rendered,
|
|
300
|
+
assetImports,
|
|
301
|
+
imageImports: incomingImageImports
|
|
302
|
+
}) => {
|
|
268
303
|
if (!key) {
|
|
269
304
|
throw new Error(`ID must be a non-empty string`);
|
|
270
305
|
}
|
|
@@ -277,11 +312,23 @@ ${lines.join(",\n")}]);
|
|
|
277
312
|
}
|
|
278
313
|
const foundAssets = new Set(assetImports);
|
|
279
314
|
const imageImports = [];
|
|
315
|
+
const seenImageImportPaths = /* @__PURE__ */ new Set();
|
|
316
|
+
const recordImageImport = (imagePath) => {
|
|
317
|
+
const pathKey = JSON.stringify(imagePath);
|
|
318
|
+
if (seenImageImportPaths.has(pathKey)) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
seenImageImportPaths.add(pathKey);
|
|
322
|
+
imageImports.push(imagePath);
|
|
323
|
+
};
|
|
324
|
+
for (const existingImagePath of incomingImageImports ?? []) {
|
|
325
|
+
recordImageImport([...existingImagePath]);
|
|
326
|
+
}
|
|
280
327
|
forEach(data, function(ctx, val) {
|
|
281
328
|
if (typeof val === "string" && val.startsWith(IMAGE_IMPORT_PREFIX)) {
|
|
282
329
|
const src = val.replace(IMAGE_IMPORT_PREFIX, "");
|
|
283
330
|
foundAssets.add(src);
|
|
284
|
-
|
|
331
|
+
recordImageImport(ctx.path.map((segment) => segment));
|
|
285
332
|
ctx.update(src);
|
|
286
333
|
}
|
|
287
334
|
});
|
package/dist/core/app/base.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
collapseDuplicateLeadingSlashes,
|
|
3
2
|
prependForwardSlash,
|
|
4
|
-
removeTrailingForwardSlash
|
|
3
|
+
removeTrailingForwardSlash,
|
|
4
|
+
stripRequestBase
|
|
5
5
|
} from "@astrojs/internal-helpers/path";
|
|
6
6
|
import { matchPattern } from "@astrojs/internal-helpers/remote";
|
|
7
7
|
import { computePathnameFromDomain } from "../i18n/domain.js";
|
|
@@ -146,11 +146,7 @@ class BaseApp {
|
|
|
146
146
|
updateRouteTable(this.manifest, newManifestData.routes);
|
|
147
147
|
}
|
|
148
148
|
removeBase(pathname) {
|
|
149
|
-
|
|
150
|
-
if (pathname.startsWith(this.manifest.base)) {
|
|
151
|
-
return pathname.slice(this.baseWithoutTrailingSlash.length + 1);
|
|
152
|
-
}
|
|
153
|
-
return pathname;
|
|
149
|
+
return stripRequestBase(pathname, this.manifest.base);
|
|
154
150
|
}
|
|
155
151
|
/**
|
|
156
152
|
* Decodes a pathname with `decodeURI`, falling back to the raw pathname when it
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
+
import nodeFs from "node:fs";
|
|
2
3
|
import { FONTS_SERVER_ADDRESS_PLACEHOLDER } from "../../../assets/fonts/constants.js";
|
|
3
4
|
import { PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
|
|
4
5
|
import { hasContentFlag } from "../../../content/utils.js";
|
|
5
6
|
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../../constants.js";
|
|
6
7
|
import { removeQueryString } from "../../path.js";
|
|
7
|
-
import { rootRelativePath } from "../../viteUtils.js";
|
|
8
|
+
import { CSS_LANGS_RE, rootRelativePath } from "../../viteUtils.js";
|
|
8
9
|
import { moduleIsTopLevelPage } from "../graph.js";
|
|
9
10
|
import { isContentDataIncrementalModule } from "../incremental-metadata.js";
|
|
10
11
|
import { getPageDataByViteID } from "../internal.js";
|
|
@@ -38,8 +39,13 @@ function hashModules(graph, sortedIds) {
|
|
|
38
39
|
hasher.update(id);
|
|
39
40
|
hasher.update("\n");
|
|
40
41
|
const code = graph.getModuleInfo(id)?.code;
|
|
41
|
-
if (code != null) {
|
|
42
|
+
if (code != null && code.length > 0) {
|
|
42
43
|
hasher.update(resolveAssetPlaceholders(graph, code));
|
|
44
|
+
} else if (CSS_LANGS_RE.test(id)) {
|
|
45
|
+
try {
|
|
46
|
+
hasher.update(nodeFs.readFileSync(removeQueryString(id), "utf-8"));
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
43
49
|
}
|
|
44
50
|
hasher.update("\n");
|
|
45
51
|
}
|
|
@@ -19,6 +19,12 @@ const PRERENDER_ENTRY_FILENAME_PREFIX = "prerender-entry";
|
|
|
19
19
|
function createViteBuildConfig(opts) {
|
|
20
20
|
const { settings, viteConfig, routes, plugins, builder, isRolldownInput } = opts;
|
|
21
21
|
const legacyAdapter = !settings.adapter || isLegacyAdapter(settings.adapter);
|
|
22
|
+
const {
|
|
23
|
+
[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]: userSsr,
|
|
24
|
+
[ASTRO_VITE_ENVIRONMENT_NAMES.prerender]: userPrerender,
|
|
25
|
+
[ASTRO_VITE_ENVIRONMENT_NAMES.client]: userClient,
|
|
26
|
+
...userEnvironments
|
|
27
|
+
} = viteConfig.environments ?? {};
|
|
22
28
|
return {
|
|
23
29
|
...viteConfig,
|
|
24
30
|
logLevel: viteConfig.logLevel ?? "error",
|
|
@@ -100,8 +106,9 @@ function createViteBuildConfig(opts) {
|
|
|
100
106
|
envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
|
|
101
107
|
base: settings.config.base,
|
|
102
108
|
environments: {
|
|
103
|
-
...
|
|
109
|
+
...userEnvironments,
|
|
104
110
|
[ASTRO_VITE_ENVIRONMENT_NAMES.prerender]: {
|
|
111
|
+
...userPrerender,
|
|
105
112
|
build: {
|
|
106
113
|
emitAssets: true,
|
|
107
114
|
outDir: fileURLToPath(getPrerenderOutputDirectory(settings)),
|
|
@@ -112,20 +119,21 @@ function createViteBuildConfig(opts) {
|
|
|
112
119
|
output: {
|
|
113
120
|
entryFileNames: `${PRERENDER_ENTRY_FILENAME_PREFIX}.[hash].mjs`,
|
|
114
121
|
format: "esm",
|
|
115
|
-
...
|
|
122
|
+
...userPrerender?.build?.rolldownOptions?.output
|
|
116
123
|
}
|
|
117
124
|
},
|
|
118
125
|
ssr: true
|
|
119
126
|
}
|
|
120
127
|
},
|
|
121
128
|
[ASTRO_VITE_ENVIRONMENT_NAMES.client]: {
|
|
129
|
+
...userClient,
|
|
122
130
|
build: {
|
|
123
131
|
emitAssets: true,
|
|
124
132
|
target: "esnext",
|
|
125
133
|
outDir: fileURLToPath(getClientOutputDirectory(settings)),
|
|
126
134
|
copyPublicDir: true,
|
|
127
|
-
sourcemap:
|
|
128
|
-
minify:
|
|
135
|
+
sourcemap: userClient?.build?.sourcemap ?? viteConfig.build?.sourcemap ?? false,
|
|
136
|
+
minify: userClient?.build?.minify ?? viteConfig.build?.minify ?? true,
|
|
129
137
|
rolldownOptions: {
|
|
130
138
|
preserveEntrySignatures: "exports-only",
|
|
131
139
|
output: {
|
|
@@ -148,17 +156,18 @@ function createViteBuildConfig(opts) {
|
|
|
148
156
|
}
|
|
149
157
|
return `${settings.config.build.assets}/[name].[hash][extname]`;
|
|
150
158
|
},
|
|
151
|
-
...
|
|
159
|
+
...userClient?.build?.rolldownOptions?.output
|
|
152
160
|
}
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
},
|
|
156
164
|
[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]: {
|
|
165
|
+
...userSsr,
|
|
157
166
|
build: {
|
|
158
167
|
outDir: fileURLToPath(getServerOutputDirectory(settings)),
|
|
159
168
|
rolldownOptions: {
|
|
160
169
|
output: {
|
|
161
|
-
...
|
|
170
|
+
...userSsr?.build?.rolldownOptions?.output
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
}
|