astro 7.2.0 → 7.2.2
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/assets/fonts/constants.d.ts +8 -0
- package/dist/assets/fonts/constants.js +2 -0
- package/dist/assets/fonts/vite-plugin-fonts.js +3 -1
- package/dist/assets/utils/node.js +35 -3
- package/dist/assets/utils/resolveImports.d.ts +0 -1
- package/dist/assets/utils/resolveImports.js +1 -4
- package/dist/cli/dev/index.js +2 -2
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/cli/preview/index.js +1 -1
- package/dist/cli/server.js +4 -4
- package/dist/content/content-layer.js +63 -3
- package/dist/content/loaders/file.js +20 -5
- package/dist/content/loaders/glob.js +18 -4
- package/dist/content/mutable-data-store.js +3 -3
- package/dist/content/runtime.d.ts +1 -0
- package/dist/content/runtime.js +6 -2
- package/dist/core/app/types.d.ts +2 -0
- package/dist/core/build/generate.js +10 -1
- package/dist/core/build/plugins/plugin-incremental.js +162 -36
- package/dist/core/build/plugins/plugin-manifest.js +11 -2
- package/dist/core/config/settings.js +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/lockfile.d.ts +19 -2
- package/dist/core/dev/lockfile.js +25 -2
- package/dist/core/fetch/fetch-state.js +1 -0
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/middleware/vite-plugin.d.ts +1 -1
- package/dist/core/middleware/vite-plugin.js +11 -24
- package/dist/core/routing/dev.d.ts +3 -1
- package/dist/core/routing/dev.js +10 -2
- package/dist/core/util.js +2 -2
- package/dist/prefetch/index.js +18 -1
- package/dist/prefetch/speculation-rules.d.ts +6 -0
- package/dist/prefetch/speculation-rules.js +22 -0
- package/dist/runtime/server/render/head.js +10 -0
- package/dist/transitions/swap-functions.js +49 -4
- package/dist/types/public/config.d.ts +22 -7
- package/dist/types/public/internal.d.ts +2 -0
- package/dist/vite-plugin-app/app.d.ts +3 -1
- package/dist/vite-plugin-app/app.js +4 -3
- package/dist/vite-plugin-css/index.js +2 -2
- package/package.json +5 -4
|
@@ -15,3 +15,11 @@ export declare const FONT_FORMATS: Array<{
|
|
|
15
15
|
}>;
|
|
16
16
|
export declare const GENERIC_FALLBACK_NAMES: readonly ["serif", "sans-serif", "monospace", "cursive", "fantasy", "system-ui", "ui-serif", "ui-sans-serif", "ui-monospace", "ui-rounded", "emoji", "math", "fangsong"];
|
|
17
17
|
export declare const FONTS_TYPES_FILE = "fonts.d.ts";
|
|
18
|
+
/**
|
|
19
|
+
* Variable name used in the font-file-url-resolver virtual module to hold
|
|
20
|
+
* the ephemeral font HTTP server address. The incremental build plugin
|
|
21
|
+
* strips the variable declaration (which contains an OS-assigned port that
|
|
22
|
+
* changes every build) from the module source before hashing so that the
|
|
23
|
+
* dependency hash is deterministic across builds.
|
|
24
|
+
*/
|
|
25
|
+
export declare const FONTS_SERVER_ADDRESS_PLACEHOLDER = "__ASTRO_FONTS_SERVER_ADDRESS__";
|
|
@@ -39,10 +39,12 @@ const GENERIC_FALLBACK_NAMES = [
|
|
|
39
39
|
"fangsong"
|
|
40
40
|
];
|
|
41
41
|
const FONTS_TYPES_FILE = "fonts.d.ts";
|
|
42
|
+
const FONTS_SERVER_ADDRESS_PLACEHOLDER = "__ASTRO_FONTS_SERVER_ADDRESS__";
|
|
42
43
|
export {
|
|
43
44
|
ASSETS_DIR,
|
|
44
45
|
CACHE_DIR,
|
|
45
46
|
DEFAULTS,
|
|
47
|
+
FONTS_SERVER_ADDRESS_PLACEHOLDER,
|
|
46
48
|
FONTS_TYPES_FILE,
|
|
47
49
|
FONT_FORMATS,
|
|
48
50
|
FONT_TYPES,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ASSETS_DIR,
|
|
14
14
|
CACHE_DIR,
|
|
15
15
|
DEFAULTS,
|
|
16
|
+
FONTS_SERVER_ADDRESS_PLACEHOLDER,
|
|
16
17
|
RESOLVED_RUNTIME_FONT_FILE_URL_RESOLVER_VIRTUAL_MODULE_ID,
|
|
17
18
|
RESOLVED_RUNTIME_VIRTUAL_MODULE_ID,
|
|
18
19
|
RESOLVED_VIRTUAL_MODULE_ID,
|
|
@@ -285,9 +286,10 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
285
286
|
return {
|
|
286
287
|
code: `
|
|
287
288
|
import { RemoteRuntimeFontFileUrlResolver } from ${JSON.stringify(new URL("./infra/remote-runtime-font-file-url-resolver.js", import.meta.url))};
|
|
289
|
+
const ${FONTS_SERVER_ADDRESS_PLACEHOLDER} = ${JSON.stringify(serverAddress)};
|
|
288
290
|
export const runtimeFontFileUrlResolver = new RemoteRuntimeFontFileUrlResolver({
|
|
289
291
|
urls: new Set(${JSON.stringify(urls)}),
|
|
290
|
-
address: ${
|
|
292
|
+
address: ${FONTS_SERVER_ADDRESS_PLACEHOLDER},
|
|
291
293
|
});
|
|
292
294
|
`
|
|
293
295
|
};
|
|
@@ -36,6 +36,35 @@ async function handleSvgDeduplication(fileData, filename, fileEmitter) {
|
|
|
36
36
|
return handle;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
const TRANSIENT_ERROR_CODES = /* @__PURE__ */ new Set(["EMFILE", "ENFILE", "EAGAIN", "EBUSY"]);
|
|
40
|
+
const MAX_CONCURRENT_READS = 200;
|
|
41
|
+
let activeReads = 0;
|
|
42
|
+
const readQueue = [];
|
|
43
|
+
async function readFileWithRetry(url, maxRetries = 5) {
|
|
44
|
+
if (activeReads >= MAX_CONCURRENT_READS) {
|
|
45
|
+
await new Promise((resolve) => readQueue.push(resolve));
|
|
46
|
+
}
|
|
47
|
+
activeReads++;
|
|
48
|
+
try {
|
|
49
|
+
for (let attempt = 0; ; attempt++) {
|
|
50
|
+
try {
|
|
51
|
+
return await fs.readFile(url);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
const code = err instanceof Error && "code" in err ? err.code : void 0;
|
|
54
|
+
if (code && TRANSIENT_ERROR_CODES.has(code) && attempt < maxRetries) {
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, 50 * 2 ** attempt));
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} finally {
|
|
62
|
+
activeReads--;
|
|
63
|
+
if (readQueue.length > 0) {
|
|
64
|
+
readQueue.shift()();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
39
68
|
async function emitImageMetadata(id, fileEmitter) {
|
|
40
69
|
if (!id) {
|
|
41
70
|
return void 0;
|
|
@@ -43,9 +72,12 @@ async function emitImageMetadata(id, fileEmitter) {
|
|
|
43
72
|
const url = pathToFileURL(id);
|
|
44
73
|
let fileData;
|
|
45
74
|
try {
|
|
46
|
-
fileData = await
|
|
47
|
-
} catch {
|
|
48
|
-
|
|
75
|
+
fileData = await readFileWithRetry(url);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
80
|
+
throw err;
|
|
49
81
|
}
|
|
50
82
|
const fileMetadata = await imageMetadata(fileData, id);
|
|
51
83
|
const emittedImage = {
|
|
@@ -6,4 +6,3 @@
|
|
|
6
6
|
* @returns A module id of the image that can be resolved by Vite, or undefined if it is not a local image
|
|
7
7
|
*/
|
|
8
8
|
export declare function imageSrcToImportId(imageSrc: string, filePath?: string): string | undefined;
|
|
9
|
-
export declare const importIdToSymbolName: (importId: string) => string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isRemotePath, removeBase } from "@astrojs/internal-helpers/path";
|
|
2
2
|
import { CONTENT_IMAGE_FLAG, IMAGE_IMPORT_PREFIX } from "../../content/consts.js";
|
|
3
|
-
import { shorthash } from "../../runtime/server/shorthash.js";
|
|
4
3
|
import { VALID_INPUT_FORMATS } from "../consts.js";
|
|
5
4
|
function imageSrcToImportId(imageSrc, filePath) {
|
|
6
5
|
imageSrc = removeBase(imageSrc, IMAGE_IMPORT_PREFIX);
|
|
@@ -17,8 +16,6 @@ function imageSrcToImportId(imageSrc, filePath) {
|
|
|
17
16
|
}
|
|
18
17
|
return `${imageSrc}?${params.toString()}`;
|
|
19
18
|
}
|
|
20
|
-
const importIdToSymbolName = (importId) => `__ASTRO_IMAGE_IMPORT_${shorthash(importId)}`;
|
|
21
19
|
export {
|
|
22
|
-
imageSrcToImportId
|
|
23
|
-
importIdToSymbolName
|
|
20
|
+
imageSrcToImportId
|
|
24
21
|
};
|
package/dist/cli/dev/index.js
CHANGED
|
@@ -128,7 +128,7 @@ Run \`astro dev --help\` to see available commands.`
|
|
|
128
128
|
}
|
|
129
129
|
const root = pathToFileURL(resolveRoot(flags.root) + "/");
|
|
130
130
|
if (ignoreLock) {
|
|
131
|
-
const existingServer2 = checkExistingServer(root);
|
|
131
|
+
const existingServer2 = await checkExistingServer(root);
|
|
132
132
|
if (existingServer2) {
|
|
133
133
|
logger.info(
|
|
134
134
|
"SKIP_FORMAT",
|
|
@@ -141,7 +141,7 @@ Run \`astro dev --help\` to see available commands.`
|
|
|
141
141
|
const inlineConfig2 = flagsToAstroInlineConfig(flags);
|
|
142
142
|
return await devServer(inlineConfig2);
|
|
143
143
|
}
|
|
144
|
-
const existingServer = checkExistingServer(root);
|
|
144
|
+
const existingServer = await checkExistingServer(root);
|
|
145
145
|
if (existingServer) {
|
|
146
146
|
if (flags.force) {
|
|
147
147
|
await killDevServer(root, existingServer);
|
|
@@ -69,7 +69,7 @@ Run \`astro preview --help\` to see available commands.`
|
|
|
69
69
|
process.exit(1);
|
|
70
70
|
}
|
|
71
71
|
const root = pathToFileURL(resolveRoot(flags.root) + "/");
|
|
72
|
-
const existingServer = checkExistingServer(root, "preview");
|
|
72
|
+
const existingServer = await checkExistingServer(root, "preview");
|
|
73
73
|
if (existingServer) {
|
|
74
74
|
const message = [
|
|
75
75
|
"Another astro preview server is already running.",
|
package/dist/cli/server.js
CHANGED
|
@@ -101,7 +101,7 @@ async function background({
|
|
|
101
101
|
config
|
|
102
102
|
}) {
|
|
103
103
|
const root = getRootURL(flags);
|
|
104
|
-
const existing = checkExistingServer(root, config.command);
|
|
104
|
+
const existing = await checkExistingServer(root, config.command);
|
|
105
105
|
if (existing && !flags.force) {
|
|
106
106
|
logger.info("SKIP_FORMAT", formatServerRunningMessage(existing, config, { existing: true }));
|
|
107
107
|
return;
|
|
@@ -160,7 +160,7 @@ async function stop({
|
|
|
160
160
|
config
|
|
161
161
|
}) {
|
|
162
162
|
const root = getRootURL(flags);
|
|
163
|
-
const existing = checkExistingServer(root, config.command);
|
|
163
|
+
const existing = await checkExistingServer(root, config.command);
|
|
164
164
|
if (!existing) {
|
|
165
165
|
logger.info("SKIP_FORMAT", `No ${config.command} server is running.`);
|
|
166
166
|
return;
|
|
@@ -174,7 +174,7 @@ async function status({
|
|
|
174
174
|
config
|
|
175
175
|
}) {
|
|
176
176
|
const root = getRootURL(flags);
|
|
177
|
-
const existing = checkExistingServer(root, config.command);
|
|
177
|
+
const existing = await checkExistingServer(root, config.command);
|
|
178
178
|
if (!existing) {
|
|
179
179
|
logger.info("SKIP_FORMAT", `No ${config.command} server is running.`);
|
|
180
180
|
return;
|
|
@@ -198,7 +198,7 @@ async function logs({
|
|
|
198
198
|
config
|
|
199
199
|
}) {
|
|
200
200
|
const root = getRootURL(flags);
|
|
201
|
-
const existing = checkExistingServer(root, config.command);
|
|
201
|
+
const existing = await checkExistingServer(root, config.command);
|
|
202
202
|
if (!existing) {
|
|
203
203
|
logger.error("SKIP_FORMAT", `No ${config.command} server is running.`);
|
|
204
204
|
process.exit(1);
|
|
@@ -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.2") {
|
|
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.2") {
|
|
208
|
+
this.#store.metaStore().set("astro-version", "7.2.2");
|
|
209
209
|
}
|
|
210
210
|
if (currentConfigDigest) {
|
|
211
211
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
|
@@ -265,6 +265,7 @@ ${contentConfig.error.message}`
|
|
|
265
265
|
}
|
|
266
266
|
})
|
|
267
267
|
);
|
|
268
|
+
this.#validateReferences(contentConfig.config.collections, logger);
|
|
268
269
|
await fs.mkdir(this.#settings.config.cacheDir, { recursive: true });
|
|
269
270
|
await fs.mkdir(this.#settings.dotAstroDir, { recursive: true });
|
|
270
271
|
const assetImportsFile = new URL(ASSET_IMPORTS_FILE, this.#settings.dotAstroDir);
|
|
@@ -277,6 +278,65 @@ ${contentConfig.error.message}`
|
|
|
277
278
|
await this.regenerateCollectionFileManifest();
|
|
278
279
|
}
|
|
279
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* After all loaders complete, walks every entry's data to find reference objects
|
|
283
|
+
* (`{ id, collection }`) and checks that the referenced entry exists in the store.
|
|
284
|
+
* This replaces the inline Zod validation that was removed in the Zod 4 upgrade.
|
|
285
|
+
*/
|
|
286
|
+
#validateReferences(collections, logger) {
|
|
287
|
+
const collectionNames = new Set(Object.keys(collections));
|
|
288
|
+
for (const collectionName of collectionNames) {
|
|
289
|
+
for (const entry of this.#store.values(collectionName)) {
|
|
290
|
+
if (entry?.data) {
|
|
291
|
+
this.#findInvalidReferences(
|
|
292
|
+
entry.data,
|
|
293
|
+
collectionNames,
|
|
294
|
+
collectionName,
|
|
295
|
+
entry.id,
|
|
296
|
+
logger,
|
|
297
|
+
""
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
#findInvalidReferences(value, collectionNames, ownerCollection, ownerId, logger, path) {
|
|
304
|
+
if (value == null || typeof value !== "object") return;
|
|
305
|
+
if (Array.isArray(value)) {
|
|
306
|
+
for (let i = 0; i < value.length; i++) {
|
|
307
|
+
this.#findInvalidReferences(
|
|
308
|
+
value[i],
|
|
309
|
+
collectionNames,
|
|
310
|
+
ownerCollection,
|
|
311
|
+
ownerId,
|
|
312
|
+
logger,
|
|
313
|
+
`${path}[${i}]`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const obj = value;
|
|
319
|
+
if (typeof obj.collection === "string" && collectionNames.has(obj.collection)) {
|
|
320
|
+
const refId = typeof obj.id === "string" ? obj.id : typeof obj.slug === "string" ? obj.slug : void 0;
|
|
321
|
+
if (refId !== void 0 && !this.#store.has(obj.collection, refId)) {
|
|
322
|
+
const fieldPath = path ? ` (field: ${path})` : "";
|
|
323
|
+
logger.error(
|
|
324
|
+
`Invalid content reference: entry "${ownerId}" in collection "${ownerCollection}"${fieldPath} references "${refId}" in collection "${obj.collection}", but that entry does not exist.`
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
330
|
+
this.#findInvalidReferences(
|
|
331
|
+
val,
|
|
332
|
+
collectionNames,
|
|
333
|
+
ownerCollection,
|
|
334
|
+
ownerId,
|
|
335
|
+
logger,
|
|
336
|
+
path ? `${path}.${key}` : key
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
280
340
|
async regenerateCollectionFileManifest() {
|
|
281
341
|
const collectionsManifest = new URL(COLLECTIONS_MANIFEST_FILE, this.#settings.dotAstroDir);
|
|
282
342
|
this.#logger.debug("content", "Regenerating collection file manifest");
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { existsSync, promises as fs } from "node:fs";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
import yaml from "js-yaml";
|
|
3
|
+
import * as yaml from "js-yaml";
|
|
4
4
|
import * as toml from "smol-toml";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
DuplicateContentEntrySlugError,
|
|
7
|
+
FileGlobNotSupported,
|
|
8
|
+
FileParserNotFound
|
|
9
|
+
} from "../../core/errors/errors-data.js";
|
|
6
10
|
import { AstroError } from "../../core/errors/index.js";
|
|
7
11
|
import { posixRelative } from "../utils.js";
|
|
8
12
|
function file(fileName, options) {
|
|
@@ -27,7 +31,7 @@ function file(fileName, options) {
|
|
|
27
31
|
message: FileParserNotFound.message(fileName)
|
|
28
32
|
});
|
|
29
33
|
}
|
|
30
|
-
async function syncData(filePath, { logger, parseData, store, config }) {
|
|
34
|
+
async function syncData(filePath, { logger, parseData, store, config, collection }) {
|
|
31
35
|
let data;
|
|
32
36
|
try {
|
|
33
37
|
const contents = await fs.readFile(filePath, "utf-8");
|
|
@@ -52,9 +56,20 @@ function file(fileName, options) {
|
|
|
52
56
|
continue;
|
|
53
57
|
}
|
|
54
58
|
if (idList.has(id)) {
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
const message = DuplicateContentEntrySlugError.message(
|
|
60
|
+
collection,
|
|
61
|
+
id,
|
|
62
|
+
fileName,
|
|
63
|
+
fileName
|
|
57
64
|
);
|
|
65
|
+
if (config.prerenderConflictBehavior === "error") {
|
|
66
|
+
throw new AstroError({
|
|
67
|
+
...DuplicateContentEntrySlugError,
|
|
68
|
+
message
|
|
69
|
+
});
|
|
70
|
+
} else if (config.prerenderConflictBehavior !== "ignore") {
|
|
71
|
+
logger.warn(message);
|
|
72
|
+
}
|
|
58
73
|
}
|
|
59
74
|
idList.add(id);
|
|
60
75
|
const parsedData = await parseData({ id, data: rawItem, filePath });
|
|
@@ -5,10 +5,12 @@ import pLimit from "p-limit";
|
|
|
5
5
|
import colors from "piccolore";
|
|
6
6
|
import picomatch from "picomatch";
|
|
7
7
|
import { glob as tinyglobby } from "tinyglobby";
|
|
8
|
+
import * as AstroErrorData from "../../core/errors/errors-data.js";
|
|
9
|
+
import { AstroError } from "../../core/errors/index.js";
|
|
8
10
|
import { getContentEntryIdAndSlug, posixRelative } from "../utils.js";
|
|
9
11
|
function generateIdDefault({ entry, base, data }, isLegacy) {
|
|
10
12
|
if (data.slug) {
|
|
11
|
-
return data.slug;
|
|
13
|
+
return String(data.slug);
|
|
12
14
|
}
|
|
13
15
|
const entryURL = new URL(encodeURI(entry), base);
|
|
14
16
|
if (isLegacy) {
|
|
@@ -45,7 +47,8 @@ function glob(globOptions) {
|
|
|
45
47
|
);
|
|
46
48
|
}
|
|
47
49
|
const isLegacy = !!globOptions[secretLegacyFlag];
|
|
48
|
-
const
|
|
50
|
+
const userGenerateId = globOptions?.generateId ?? ((opts) => generateIdDefault(opts, isLegacy));
|
|
51
|
+
const generateId = (opts) => String(userGenerateId(opts));
|
|
49
52
|
const fileToIdMap = /* @__PURE__ */ new Map();
|
|
50
53
|
return {
|
|
51
54
|
name: "glob-loader",
|
|
@@ -106,9 +109,20 @@ function glob(globOptions) {
|
|
|
106
109
|
if (existingEntry && existingEntry.filePath && existingEntry.filePath !== relativePath2) {
|
|
107
110
|
const oldFilePath = new URL(existingEntry.filePath, config.root);
|
|
108
111
|
if (existsSync(oldFilePath)) {
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
const message = AstroErrorData.DuplicateContentEntrySlugError.message(
|
|
113
|
+
collection,
|
|
114
|
+
id,
|
|
115
|
+
existingEntry.filePath,
|
|
116
|
+
relativePath2
|
|
111
117
|
);
|
|
118
|
+
if (config.prerenderConflictBehavior === "error") {
|
|
119
|
+
throw new AstroError({
|
|
120
|
+
...AstroErrorData.DuplicateContentEntrySlugError,
|
|
121
|
+
message
|
|
122
|
+
});
|
|
123
|
+
} else if (config.prerenderConflictBehavior !== "ignore") {
|
|
124
|
+
logger.warn(message);
|
|
125
|
+
}
|
|
112
126
|
}
|
|
113
127
|
}
|
|
114
128
|
if (entryType.getRenderFunction && !globOptions.deferRender) {
|
|
@@ -2,7 +2,7 @@ import { existsSync, promises as fs } from "node:fs";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import * as devalue from "devalue";
|
|
4
4
|
import { forEach } from "neotraverse";
|
|
5
|
-
import { imageSrcToImportId
|
|
5
|
+
import { imageSrcToImportId } from "../assets/utils/resolveImports.js";
|
|
6
6
|
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
|
7
7
|
import { DATA_STORE_MANIFEST_FILE, IMAGE_IMPORT_PREFIX } from "./consts.js";
|
|
8
8
|
import {
|
|
@@ -109,8 +109,8 @@ class MutableDataStore extends ImmutableDataStore {
|
|
|
109
109
|
const imports = [];
|
|
110
110
|
const exports = [];
|
|
111
111
|
const sortedAssetImports = [...this.#assetImports].sort();
|
|
112
|
-
sortedAssetImports.forEach((id) => {
|
|
113
|
-
const symbol =
|
|
112
|
+
sortedAssetImports.forEach((id, index) => {
|
|
113
|
+
const symbol = `__ASTRO_IMAGE_IMPORT_${index}`;
|
|
114
114
|
imports.push(`import ${symbol} from ${JSON.stringify(id)};`);
|
|
115
115
|
exports.push(`[${JSON.stringify(id)}, ${symbol}]`);
|
|
116
116
|
});
|
|
@@ -71,6 +71,7 @@ type RenderResult = {
|
|
|
71
71
|
remarkPluginFrontmatter: Record<string, any>;
|
|
72
72
|
};
|
|
73
73
|
export declare function updateImageReferencesInData<T extends Record<string, unknown>>(data: T, fileName?: string, imageAssetMap?: Map<string, ImageMetadata>): T;
|
|
74
|
+
export declare function resolveEntryData<T extends Record<string, unknown>>(entry: DataEntry<T>, imageAssetMap?: Map<string, ImageMetadata>): T;
|
|
74
75
|
export declare function renderEntry(entry: DataEntry): Promise<RenderResult>;
|
|
75
76
|
export declare function createReference(): (collection: string) => z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>, z.ZodString, z.ZodObject<{
|
|
76
77
|
id: z.ZodString;
|
package/dist/content/runtime.js
CHANGED
|
@@ -78,7 +78,7 @@ function createGetCollection({
|
|
|
78
78
|
const { default: imageAssetMap } = await import("astro:asset-imports");
|
|
79
79
|
const result = [];
|
|
80
80
|
for (const rawEntry of await store.values(collection)) {
|
|
81
|
-
const data =
|
|
81
|
+
const data = resolveEntryData(rawEntry, imageAssetMap);
|
|
82
82
|
let entry = {
|
|
83
83
|
...rawEntry,
|
|
84
84
|
data,
|
|
@@ -135,7 +135,7 @@ function createGetEntry({ liveCollections }) {
|
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
const { default: imageAssetMap } = await import("astro:asset-imports");
|
|
138
|
-
const data =
|
|
138
|
+
const data = resolveEntryData(entry, imageAssetMap);
|
|
139
139
|
const result = {
|
|
140
140
|
...entry,
|
|
141
141
|
data,
|
|
@@ -382,6 +382,9 @@ function updateImageReferencesInData(data, fileName, imageAssetMap) {
|
|
|
382
382
|
});
|
|
383
383
|
return copy;
|
|
384
384
|
}
|
|
385
|
+
function resolveEntryData(entry, imageAssetMap) {
|
|
386
|
+
return entry.assetImports?.length ? updateImageReferencesInData(entry.data, entry.filePath, imageAssetMap) : structuredClone(entry.data);
|
|
387
|
+
}
|
|
385
388
|
async function renderEntry(entry) {
|
|
386
389
|
if (!entry) {
|
|
387
390
|
throw new AstroError(AstroErrorData.RenderUndefinedEntryError);
|
|
@@ -563,5 +566,6 @@ export {
|
|
|
563
566
|
defineCollection,
|
|
564
567
|
defineLiveCollection,
|
|
565
568
|
renderEntry,
|
|
569
|
+
resolveEntryData,
|
|
566
570
|
updateImageReferencesInData
|
|
567
571
|
};
|
package/dist/core/app/types.d.ts
CHANGED
|
@@ -193,6 +193,8 @@ export type SSRManifestCSP = {
|
|
|
193
193
|
resources: CspResourceEntry[];
|
|
194
194
|
hashes: CspHashEntry[];
|
|
195
195
|
};
|
|
196
|
+
/** Static speculation rules JSON to inject in the head when CSP + clientPrerender are both enabled. */
|
|
197
|
+
speculationRulesContent?: string;
|
|
196
198
|
};
|
|
197
199
|
export interface SSRManifestSession extends BaseSessionConfig {
|
|
198
200
|
driver: string;
|
|
@@ -222,7 +222,16 @@ ${colors.bgGreen(colors.black(` ${verb} static routes `))}`);
|
|
|
222
222
|
if (prerenderer.collectStaticImages) {
|
|
223
223
|
const adapterImages = await prerenderer.collectStaticImages();
|
|
224
224
|
for (const [path, entry] of adapterImages) {
|
|
225
|
-
staticImageList.
|
|
225
|
+
const existing = staticImageList.get(path);
|
|
226
|
+
if (existing) {
|
|
227
|
+
for (const [hash, transform] of entry.transforms) {
|
|
228
|
+
if (!existing.transforms.has(hash)) {
|
|
229
|
+
existing.transforms.set(hash, transform);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
staticImageList.set(path, entry);
|
|
234
|
+
}
|
|
226
235
|
}
|
|
227
236
|
}
|
|
228
237
|
} finally {
|