astro 5.6.2 → 5.7.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.
Files changed (80) hide show
  1. package/client.d.ts +3 -0
  2. package/components/Font.astro +32 -0
  3. package/dist/actions/plugins.js +2 -2
  4. package/dist/assets/fonts/config.d.ts +378 -0
  5. package/dist/assets/fonts/config.js +157 -0
  6. package/dist/assets/fonts/constants.d.ts +15 -0
  7. package/dist/assets/fonts/constants.js +41 -0
  8. package/dist/assets/fonts/load.d.ts +20 -0
  9. package/dist/assets/fonts/load.js +135 -0
  10. package/dist/assets/fonts/metrics.d.ts +9 -0
  11. package/dist/assets/fonts/metrics.js +61 -0
  12. package/dist/assets/fonts/providers/entrypoints/adobe.d.ts +2 -0
  13. package/dist/assets/fonts/providers/entrypoints/adobe.js +5 -0
  14. package/dist/assets/fonts/providers/entrypoints/bunny.d.ts +1 -0
  15. package/dist/assets/fonts/providers/entrypoints/bunny.js +5 -0
  16. package/dist/assets/fonts/providers/entrypoints/fontshare.d.ts +1 -0
  17. package/dist/assets/fonts/providers/entrypoints/fontshare.js +5 -0
  18. package/dist/assets/fonts/providers/entrypoints/fontsource.d.ts +1 -0
  19. package/dist/assets/fonts/providers/entrypoints/fontsource.js +5 -0
  20. package/dist/assets/fonts/providers/entrypoints/google.d.ts +2 -0
  21. package/dist/assets/fonts/providers/entrypoints/google.js +5 -0
  22. package/dist/assets/fonts/providers/index.d.ts +48 -0
  23. package/dist/assets/fonts/providers/index.js +40 -0
  24. package/dist/assets/fonts/providers/local.d.ts +10 -0
  25. package/dist/assets/fonts/providers/local.js +30 -0
  26. package/dist/assets/fonts/providers/utils.d.ts +9 -0
  27. package/dist/assets/fonts/providers/utils.js +37 -0
  28. package/dist/assets/fonts/sync.d.ts +2 -0
  29. package/dist/assets/fonts/sync.js +17 -0
  30. package/dist/assets/fonts/types.d.ts +45 -0
  31. package/dist/assets/fonts/types.js +0 -0
  32. package/dist/assets/fonts/utils.d.ts +92 -0
  33. package/dist/assets/fonts/utils.js +215 -0
  34. package/dist/assets/fonts/vite-plugin-fonts.d.ts +10 -0
  35. package/dist/assets/fonts/vite-plugin-fonts.js +212 -0
  36. package/dist/assets/utils/node/emitAsset.d.ts +4 -2
  37. package/dist/assets/utils/node/emitAsset.js +1 -1
  38. package/dist/assets/utils/vendor/image-size/types/index.d.ts +2 -2
  39. package/dist/assets/vite-plugin-assets.d.ts +8 -3
  40. package/dist/assets/vite-plugin-assets.js +7 -7
  41. package/dist/config/entrypoint.d.ts +2 -0
  42. package/dist/config/entrypoint.js +3 -0
  43. package/dist/config/index.d.ts +2 -1
  44. package/dist/content/content-layer.js +5 -4
  45. package/dist/content/runtime-assets.js +1 -0
  46. package/dist/content/vite-plugin-content-imports.js +4 -2
  47. package/dist/core/build/generate.js +2 -2
  48. package/dist/core/build/pipeline.js +2 -2
  49. package/dist/core/build/static-build.js +2 -2
  50. package/dist/core/config/schemas/base.d.ts +436 -39
  51. package/dist/core/config/schemas/base.js +3 -7
  52. package/dist/core/config/schemas/refined.js +12 -0
  53. package/dist/core/config/schemas/relative.d.ts +567 -63
  54. package/dist/core/config/schemas/relative.js +1 -2
  55. package/dist/core/constants.js +1 -1
  56. package/dist/core/create-vite.js +2 -2
  57. package/dist/core/dev/dev.js +1 -1
  58. package/dist/core/errors/errors-data.d.ts +82 -26
  59. package/dist/core/errors/errors-data.js +45 -16
  60. package/dist/core/logger/core.d.ts +1 -1
  61. package/dist/core/messages.js +2 -2
  62. package/dist/core/middleware/vite-plugin.js +2 -2
  63. package/dist/core/render-context.js +38 -5
  64. package/dist/core/routing/rewrite.js +14 -5
  65. package/dist/core/session.d.ts +4 -6
  66. package/dist/core/session.js +4 -29
  67. package/dist/core/sync/index.js +2 -0
  68. package/dist/integrations/hooks.js +2 -3
  69. package/dist/manifest/virtual-module.d.ts +1 -5
  70. package/dist/manifest/virtual-module.js +1 -18
  71. package/dist/prerender/utils.d.ts +5 -1
  72. package/dist/prerender/utils.js +8 -8
  73. package/dist/runtime/client/dev-toolbar/apps/audit/annotations.d.ts +6 -0
  74. package/dist/runtime/client/dev-toolbar/apps/audit/annotations.js +27 -0
  75. package/dist/runtime/client/dev-toolbar/apps/audit/index.js +10 -4
  76. package/dist/runtime/client/dev-toolbar/apps/audit/ui/audit-ui.js +2 -2
  77. package/dist/types/public/config.d.ts +155 -98
  78. package/dist/vite-plugin-astro-server/plugin.js +1 -1
  79. package/package.json +7 -4
  80. package/types/fonts.d.ts +4 -0
@@ -0,0 +1,215 @@
1
+ import { createRequire } from "node:module";
2
+ import { extname } from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { AstroError, AstroErrorData } from "../../core/errors/index.js";
5
+ import { DEFAULT_FALLBACKS, FONT_TYPES, LOCAL_PROVIDER_NAME } from "./constants.js";
6
+ import { resolveProvider } from "./providers/utils.js";
7
+ function generateFontFace(family, font) {
8
+ return [
9
+ "@font-face {",
10
+ ` font-family: ${family};`,
11
+ ` src: ${renderFontSrc(font.src)};`,
12
+ ` font-display: ${font.display ?? "swap"};`,
13
+ font.unicodeRange && ` unicode-range: ${font.unicodeRange};`,
14
+ font.weight && ` font-weight: ${Array.isArray(font.weight) ? font.weight.join(" ") : font.weight};`,
15
+ font.style && ` font-style: ${font.style};`,
16
+ font.stretch && ` font-stretch: ${font.stretch};`,
17
+ font.featureSettings && ` font-feature-settings: ${font.featureSettings};`,
18
+ font.variationSettings && ` font-variation-settings: ${font.variationSettings};`,
19
+ `}`
20
+ ].filter(Boolean).join("\n");
21
+ }
22
+ function renderFontSrc(sources) {
23
+ return sources.map((src) => {
24
+ if ("url" in src) {
25
+ let rendered = `url("${src.url}")`;
26
+ for (const key of ["format", "tech"]) {
27
+ if (key in src) {
28
+ rendered += ` ${key}(${src[key]})`;
29
+ }
30
+ }
31
+ return rendered;
32
+ }
33
+ return `local("${src.name}")`;
34
+ }).join(", ");
35
+ }
36
+ function extractFontType(str) {
37
+ const extension = extname(str).slice(1);
38
+ if (!isFontType(extension)) {
39
+ throw new AstroError(
40
+ {
41
+ ...AstroErrorData.CannotExtractFontType,
42
+ message: AstroErrorData.CannotExtractFontType.message(str)
43
+ },
44
+ {
45
+ cause: `Unexpected extension, got "${extension}"`
46
+ }
47
+ );
48
+ }
49
+ return extension;
50
+ }
51
+ function isFontType(str) {
52
+ return FONT_TYPES.includes(str);
53
+ }
54
+ async function cache(storage, key, cb) {
55
+ const existing = await storage.getItemRaw(key);
56
+ if (existing) {
57
+ return existing;
58
+ }
59
+ const data = await cb();
60
+ await storage.setItemRaw(key, data);
61
+ return data;
62
+ }
63
+ function proxyURL({ value, hashString, collect }) {
64
+ const type = extractFontType(value);
65
+ const hash = `${hashString(value)}.${type}`;
66
+ const url = collect({ hash, type, value });
67
+ return url;
68
+ }
69
+ function isGenericFontFamily(str) {
70
+ return Object.keys(DEFAULT_FALLBACKS).includes(str);
71
+ }
72
+ async function generateFallbacksCSS({
73
+ family,
74
+ fallbacks: _fallbacks,
75
+ font: fontData,
76
+ metrics
77
+ }) {
78
+ let fallbacks = [..._fallbacks];
79
+ if (fallbacks.length === 0) {
80
+ return null;
81
+ }
82
+ let css = "";
83
+ if (!fontData || !metrics) {
84
+ return { css, fallbacks };
85
+ }
86
+ const lastFallback = fallbacks[fallbacks.length - 1];
87
+ if (!isGenericFontFamily(lastFallback)) {
88
+ return { css, fallbacks };
89
+ }
90
+ const localFonts = DEFAULT_FALLBACKS[lastFallback];
91
+ if (localFonts.length === 0) {
92
+ return { css, fallbacks };
93
+ }
94
+ const foundMetrics = await metrics.getMetricsForFamily(family.name, fontData);
95
+ if (!foundMetrics) {
96
+ return { css, fallbacks };
97
+ }
98
+ const localFontsMappings = localFonts.map((font) => ({
99
+ font,
100
+ name: `"${family.nameWithHash} fallback: ${font}"`
101
+ }));
102
+ fallbacks = [.../* @__PURE__ */ new Set([...localFontsMappings.map((m) => m.name), ...fallbacks])];
103
+ for (const { font, name } of localFontsMappings) {
104
+ css += metrics.generateFontFace(foundMetrics, { font, name });
105
+ }
106
+ return { css, fallbacks };
107
+ }
108
+ function dedupe(arr) {
109
+ return [...new Set(arr)];
110
+ }
111
+ function resolveVariants({
112
+ variants,
113
+ root
114
+ }) {
115
+ return variants.map((variant) => ({
116
+ ...variant,
117
+ weight: variant.weight.toString(),
118
+ src: variant.src.map((value) => {
119
+ const isValue = typeof value === "string" || value instanceof URL;
120
+ const url = (isValue ? value : value.url).toString();
121
+ const tech = isValue ? void 0 : value.tech;
122
+ return {
123
+ url: fileURLToPath(resolveEntrypoint(root, url)),
124
+ tech
125
+ };
126
+ })
127
+ }));
128
+ }
129
+ async function resolveFontFamily({
130
+ family,
131
+ generateNameWithHash,
132
+ root,
133
+ resolveMod
134
+ }) {
135
+ const nameWithHash = generateNameWithHash(family);
136
+ if (family.provider === LOCAL_PROVIDER_NAME) {
137
+ return {
138
+ ...family,
139
+ nameWithHash,
140
+ variants: resolveVariants({ variants: family.variants, root }),
141
+ fallbacks: family.fallbacks ? dedupe(family.fallbacks) : void 0
142
+ };
143
+ }
144
+ return {
145
+ ...family,
146
+ nameWithHash,
147
+ provider: await resolveProvider({
148
+ root,
149
+ resolveMod,
150
+ provider: family.provider
151
+ }),
152
+ weights: family.weights ? dedupe(family.weights.map((weight) => weight.toString())) : void 0,
153
+ styles: family.styles ? dedupe(family.styles) : void 0,
154
+ subsets: family.subsets ? dedupe(family.subsets) : void 0,
155
+ fallbacks: family.fallbacks ? dedupe(family.fallbacks) : void 0,
156
+ unicodeRange: family.unicodeRange ? dedupe(family.unicodeRange) : void 0
157
+ };
158
+ }
159
+ function sortObjectByKey(unordered) {
160
+ const ordered = Object.keys(unordered).sort().reduce((obj, key) => {
161
+ obj[key] = unordered[key];
162
+ return obj;
163
+ }, {});
164
+ return ordered;
165
+ }
166
+ function familiesToUnifontProviders({
167
+ families,
168
+ hashString
169
+ }) {
170
+ const hashes = /* @__PURE__ */ new Set();
171
+ const providers = [];
172
+ for (const { provider } of families) {
173
+ if (provider === LOCAL_PROVIDER_NAME) {
174
+ continue;
175
+ }
176
+ const unifontProvider = provider.provider(provider.config);
177
+ const hash = hashString(
178
+ JSON.stringify(
179
+ sortObjectByKey({
180
+ name: unifontProvider._name,
181
+ ...provider.config
182
+ })
183
+ )
184
+ );
185
+ if (hashes.has(hash)) {
186
+ continue;
187
+ }
188
+ unifontProvider._name += `-${hash}`;
189
+ provider.name = unifontProvider._name;
190
+ hashes.add(hash);
191
+ providers.push(unifontProvider);
192
+ }
193
+ return { families, providers };
194
+ }
195
+ function resolveEntrypoint(root, entrypoint) {
196
+ const require2 = createRequire(root);
197
+ try {
198
+ return pathToFileURL(require2.resolve(entrypoint));
199
+ } catch {
200
+ return new URL(entrypoint, root);
201
+ }
202
+ }
203
+ export {
204
+ cache,
205
+ extractFontType,
206
+ familiesToUnifontProviders,
207
+ generateFallbacksCSS,
208
+ generateFontFace,
209
+ isFontType,
210
+ isGenericFontFamily,
211
+ proxyURL,
212
+ resolveEntrypoint,
213
+ resolveFontFamily,
214
+ sortObjectByKey
215
+ };
@@ -0,0 +1,10 @@
1
+ import type { Plugin } from 'vite';
2
+ import type { Logger } from '../../core/logger/core.js';
3
+ import type { AstroSettings } from '../../types/astro.js';
4
+ interface Options {
5
+ settings: AstroSettings;
6
+ sync: boolean;
7
+ logger: Logger;
8
+ }
9
+ export declare function fontsPlugin({ settings, sync, logger }: Options): Plugin;
10
+ export {};
@@ -0,0 +1,212 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { isAbsolute } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { removeTrailingForwardSlash } from "@astrojs/internal-helpers/path";
6
+ import { createStorage } from "unstorage";
7
+ import fsLiteDriver from "unstorage/drivers/fs-lite";
8
+ import xxhash from "xxhash-wasm";
9
+ import { collectErrorMetadata } from "../../core/errors/dev/utils.js";
10
+ import { AstroError, AstroErrorData, isAstroError } from "../../core/errors/index.js";
11
+ import { formatErrorMessage } from "../../core/messages.js";
12
+ import { getClientOutputDirectory } from "../../prerender/utils.js";
13
+ import {
14
+ CACHE_DIR,
15
+ RESOLVED_VIRTUAL_MODULE_ID,
16
+ URL_PREFIX,
17
+ VIRTUAL_MODULE_ID
18
+ } from "./constants.js";
19
+ import { loadFonts } from "./load.js";
20
+ import { generateFallbackFontFace, readMetrics } from "./metrics.js";
21
+ import { cache, extractFontType, resolveFontFamily, sortObjectByKey } from "./utils.js";
22
+ async function fetchFont(url) {
23
+ try {
24
+ if (isAbsolute(url)) {
25
+ return await readFile(url);
26
+ }
27
+ const response = await fetch(url);
28
+ if (!response.ok) {
29
+ throw new Error(`Response was not successful, received status code ${response.status}`);
30
+ }
31
+ return Buffer.from(await response.arrayBuffer());
32
+ } catch (cause) {
33
+ throw new AstroError(
34
+ {
35
+ ...AstroErrorData.CannotFetchFontFile,
36
+ message: AstroErrorData.CannotFetchFontFile.message(url)
37
+ },
38
+ { cause }
39
+ );
40
+ }
41
+ }
42
+ function fontsPlugin({ settings, sync, logger }) {
43
+ if (!settings.config.experimental.fonts) {
44
+ return {
45
+ name: "astro:fonts:fallback",
46
+ config() {
47
+ return {
48
+ build: {
49
+ rollupOptions: {
50
+ external: [VIRTUAL_MODULE_ID]
51
+ }
52
+ }
53
+ };
54
+ }
55
+ };
56
+ }
57
+ const baseUrl = removeTrailingForwardSlash(settings.config.base) + URL_PREFIX;
58
+ let resolvedMap = null;
59
+ let hashToUrlMap = null;
60
+ let isBuild;
61
+ let storage = null;
62
+ const cleanup = () => {
63
+ resolvedMap = null;
64
+ hashToUrlMap = null;
65
+ storage = null;
66
+ };
67
+ async function initialize({ resolveMod, base }) {
68
+ const { h64ToString } = await xxhash();
69
+ storage = createStorage({
70
+ // Types are weirly exported
71
+ driver: fsLiteDriver({
72
+ base: fileURLToPath(base)
73
+ })
74
+ });
75
+ hashToUrlMap = /* @__PURE__ */ new Map();
76
+ resolvedMap = /* @__PURE__ */ new Map();
77
+ const families = [];
78
+ for (const family of settings.config.experimental.fonts) {
79
+ families.push(
80
+ await resolveFontFamily({
81
+ family,
82
+ root: settings.config.root,
83
+ resolveMod,
84
+ generateNameWithHash: (_family) => `${_family.name}-${h64ToString(JSON.stringify(sortObjectByKey(_family)))}`
85
+ })
86
+ );
87
+ }
88
+ await loadFonts({
89
+ base: baseUrl,
90
+ families,
91
+ storage,
92
+ hashToUrlMap,
93
+ resolvedMap,
94
+ hashString: h64ToString,
95
+ generateFallbackFontFace,
96
+ getMetricsForFamily: async (name, font) => {
97
+ return await readMetrics(name, await cache(storage, font.hash, () => fetchFont(font.url)));
98
+ },
99
+ log: (message) => logger.info("assets", message)
100
+ });
101
+ }
102
+ return {
103
+ name: "astro:fonts",
104
+ config(_, { command }) {
105
+ isBuild = command === "build";
106
+ },
107
+ async buildStart() {
108
+ if (isBuild) {
109
+ await initialize({
110
+ resolveMod: (id) => import(id),
111
+ base: new URL(CACHE_DIR, settings.config.cacheDir)
112
+ });
113
+ }
114
+ },
115
+ async configureServer(server) {
116
+ await initialize({
117
+ resolveMod: (id) => server.ssrLoadModule(id),
118
+ // In dev, we cache fonts data in .astro so it can be easily inspected and cleared
119
+ base: new URL(CACHE_DIR, settings.dotAstroDir)
120
+ });
121
+ const localPaths = [...hashToUrlMap.values()].filter((url) => isAbsolute(url));
122
+ server.watcher.on("change", (path) => {
123
+ if (localPaths.includes(path)) {
124
+ logger.info("assets", "Font file updated");
125
+ server.restart();
126
+ }
127
+ });
128
+ server.watcher.on("unlink", (path) => {
129
+ if (localPaths.includes(path)) {
130
+ logger.warn(
131
+ "assets",
132
+ `The font file ${JSON.stringify(path)} referenced in your config has been deleted. Restore the file or remove this font from your configuration if it is no longer needed.`
133
+ );
134
+ }
135
+ });
136
+ server.middlewares.use(URL_PREFIX, async (req, res, next) => {
137
+ if (!req.url) {
138
+ return next();
139
+ }
140
+ const hash = req.url.slice(1);
141
+ const url = hashToUrlMap?.get(hash);
142
+ if (!url) {
143
+ return next();
144
+ }
145
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
146
+ res.setHeader("Pragma", "no-cache");
147
+ res.setHeader("Expires", 0);
148
+ try {
149
+ const data = await cache(storage, hash, () => fetchFont(url));
150
+ res.setHeader("Content-Length", data.length);
151
+ res.setHeader("Content-Type", `font/${extractFontType(hash)}`);
152
+ res.end(data);
153
+ } catch (err) {
154
+ logger.error("assets", "Cannot download font file");
155
+ if (isAstroError(err)) {
156
+ logger.error(
157
+ "SKIP_FORMAT",
158
+ formatErrorMessage(collectErrorMetadata(err), logger.level() === "debug")
159
+ );
160
+ }
161
+ res.statusCode = 500;
162
+ res.end();
163
+ }
164
+ });
165
+ },
166
+ resolveId(id) {
167
+ if (id === VIRTUAL_MODULE_ID) {
168
+ return RESOLVED_VIRTUAL_MODULE_ID;
169
+ }
170
+ },
171
+ load(id) {
172
+ if (id === RESOLVED_VIRTUAL_MODULE_ID) {
173
+ return {
174
+ code: `export const fontsData = new Map(${JSON.stringify(Array.from(resolvedMap?.entries() ?? []))})`
175
+ };
176
+ }
177
+ },
178
+ async buildEnd() {
179
+ if (sync || settings.config.experimental.fonts.length === 0) {
180
+ cleanup();
181
+ return;
182
+ }
183
+ try {
184
+ const dir = getClientOutputDirectory(settings);
185
+ const fontsDir = new URL("." + baseUrl, dir);
186
+ try {
187
+ mkdirSync(fontsDir, { recursive: true });
188
+ } catch (cause) {
189
+ throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause });
190
+ }
191
+ if (hashToUrlMap) {
192
+ logger.info("assets", "Copying fonts...");
193
+ await Promise.all(
194
+ Array.from(hashToUrlMap.entries()).map(async ([hash, url]) => {
195
+ const data = await cache(storage, hash, () => fetchFont(url));
196
+ try {
197
+ writeFileSync(new URL(hash, fontsDir), data);
198
+ } catch (cause) {
199
+ throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause });
200
+ }
201
+ })
202
+ );
203
+ }
204
+ } finally {
205
+ cleanup();
206
+ }
207
+ }
208
+ };
209
+ }
210
+ export {
211
+ fontsPlugin
212
+ };
@@ -9,13 +9,15 @@ type ImageMetadataWithContents = ImageMetadata & {
9
9
  *
10
10
  * @param {string | undefined} id - The identifier or path of the image file to process. If undefined, the function returns immediately.
11
11
  * @param {boolean} _watchMode - **Deprecated**: Indicates if the method is operating in watch mode. This parameter will be removed or updated in the future.
12
- * @param {boolean} experimentalSvgEnabled - A flag to enable experimental handling of SVG files. Embeds SVG file data if set to true.
12
+ * @param {boolean} _experimentalSvgEnabled - **Deprecated**: A flag to enable experimental handling of SVG files. Embeds SVG file data if set to true.
13
13
  * @param {FileEmitter | undefined} [fileEmitter] - Function for emitting files during the build process. May throw in certain scenarios.
14
14
  * @return {Promise<ImageMetadataWithContents | undefined>} Resolves to metadata with optional image contents or `undefined` if processing fails.
15
15
  */
16
16
  export declare function emitESMImage(id: string | undefined,
17
17
  /** @deprecated */
18
- _watchMode: boolean, experimentalSvgEnabled: boolean, fileEmitter?: FileEmitter): Promise<ImageMetadataWithContents | undefined>;
18
+ _watchMode: boolean,
19
+ /** @deprecated */
20
+ _experimentalSvgEnabled: boolean, fileEmitter?: FileEmitter): Promise<ImageMetadataWithContents | undefined>;
19
21
  /**
20
22
  * Processes an image file and emits its metadata and optionally its contents. This function supports both build and development modes.
21
23
  *
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
  import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import { prependForwardSlash, slash } from "../../../core/path.js";
5
5
  import { imageMetadata } from "../metadata.js";
6
- async function emitESMImage(id, _watchMode, experimentalSvgEnabled, fileEmitter) {
6
+ async function emitESMImage(id, _watchMode, _experimentalSvgEnabled, fileEmitter) {
7
7
  if (!id) {
8
8
  return void 0;
9
9
  }
@@ -1,3 +1,3 @@
1
- export declare const typeHandlers: Map<"svg" | "jpg" | "png" | "tiff" | "webp" | "gif" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga", import("./interface.js").IImage>;
2
- export declare const types: ("svg" | "jpg" | "png" | "tiff" | "webp" | "gif" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga")[];
1
+ export declare const typeHandlers: Map<"jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga", import("./interface.js").IImage>;
2
+ export declare const types: ("jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga")[];
3
3
  export type imageType = typeof types[number];
@@ -1,7 +1,12 @@
1
1
  import type * as fsMod from 'node:fs';
2
2
  import type * as vite from 'vite';
3
+ import type { Logger } from '../core/logger/core.js';
3
4
  import type { AstroSettings } from '../types/astro.js';
4
- export default function assets({ fs, settings, }: {
5
- fs: typeof fsMod;
5
+ interface Options {
6
6
  settings: AstroSettings;
7
- }): vite.Plugin[];
7
+ sync: boolean;
8
+ logger: Logger;
9
+ fs: typeof fsMod;
10
+ }
11
+ export default function assets({ fs, settings, sync, logger }: Options): vite.Plugin[];
12
+ export {};
@@ -10,6 +10,7 @@ import {
10
10
  } from "../core/path.js";
11
11
  import { normalizePath } from "../core/viteUtils.js";
12
12
  import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
13
+ import { fontsPlugin } from "./fonts/vite-plugin-fonts.js";
13
14
  import { getAssetsPrefix } from "./utils/getAssetsPrefix.js";
14
15
  import { isESMImportedImage } from "./utils/imageKind.js";
15
16
  import { emitESMImage } from "./utils/node/emitAsset.js";
@@ -63,10 +64,7 @@ const addStaticImageFactory = (settings) => {
63
64
  }
64
65
  };
65
66
  };
66
- function assets({
67
- fs,
68
- settings
69
- }) {
67
+ function assets({ fs, settings, sync, logger }) {
70
68
  let resolvedConfig;
71
69
  let shouldEmitFile = false;
72
70
  let isBuild = false;
@@ -97,6 +95,7 @@ function assets({
97
95
  import { getImage as getImageInternal } from "astro/assets";
98
96
  export { default as Image } from "astro/components/${imageComponentPrefix}Image.astro";
99
97
  export { default as Picture } from "astro/components/${imageComponentPrefix}Picture.astro";
98
+ export { default as Font } from "astro/components/Font.astro";
100
99
  export { inferRemoteSize } from "astro/assets/utils/inferRemoteSize.js";
101
100
 
102
101
  export const imageConfig = ${JSON.stringify({ ...settings.config.image, experimentalResponsiveImages: settings.config.experimental.responsiveImages })};
@@ -173,7 +172,7 @@ function assets({
173
172
  const imageMetadata = await emitESMImage(
174
173
  id,
175
174
  this.meta.watchMode,
176
- !!settings.config.experimental.svg,
175
+ id.endsWith(".svg"),
177
176
  emitFile
178
177
  );
179
178
  if (!imageMetadata) {
@@ -182,7 +181,7 @@ function assets({
182
181
  message: AstroErrorData.ImageNotFound.message(id)
183
182
  });
184
183
  }
185
- if (settings.config.experimental.svg && /\.svg$/.test(id)) {
184
+ if (id.endsWith(".svg")) {
186
185
  const contents = await fs.promises.readFile(imageMetadata.fsPath, { encoding: "utf8" });
187
186
  return { code: makeSvgComponent(imageMetadata, contents) };
188
187
  }
@@ -201,7 +200,8 @@ function assets({
201
200
  }
202
201
  }
203
202
  }
204
- }
203
+ },
204
+ fontsPlugin({ settings, sync, logger })
205
205
  ];
206
206
  }
207
207
  export {
@@ -4,6 +4,8 @@ export { defineConfig, getViteConfig } from './index.js';
4
4
  export { envField } from '../env/config.js';
5
5
  export { mergeConfig } from '../core/config/merge.js';
6
6
  export { validateConfig } from '../core/config/validate.js';
7
+ export { fontProviders, defineAstroFontProvider } from '../assets/fonts/providers/index.js';
8
+ export type { AstroFontProvider } from '../assets/fonts/types.js';
7
9
  /**
8
10
  * Return the configuration needed to use the Sharp-based image service
9
11
  */
@@ -2,6 +2,7 @@ import { defineConfig, getViteConfig } from "./index.js";
2
2
  import { envField } from "../env/config.js";
3
3
  import { mergeConfig } from "../core/config/merge.js";
4
4
  import { validateConfig } from "../core/config/validate.js";
5
+ import { fontProviders, defineAstroFontProvider } from "../assets/fonts/providers/index.js";
5
6
  function sharpImageService(config = {}) {
6
7
  return {
7
8
  entrypoint: "astro/assets/services/sharp",
@@ -15,8 +16,10 @@ function passthroughImageService() {
15
16
  };
16
17
  }
17
18
  export {
19
+ defineAstroFontProvider,
18
20
  defineConfig,
19
21
  envField,
22
+ fontProviders,
20
23
  getViteConfig,
21
24
  mergeConfig,
22
25
  passthroughImageService,
@@ -1,10 +1,11 @@
1
1
  import type { UserConfig as ViteUserConfig, UserConfigFn as ViteUserConfigFn } from 'vite';
2
+ import type { FontFamily } from '../assets/fonts/types.js';
2
3
  import type { AstroInlineConfig, AstroUserConfig, Locales, SessionDriverName } from '../types/public/config.js';
3
4
  /**
4
5
  * See the full Astro Configuration API Documentation
5
6
  * https://astro.build/config
6
7
  */
7
- export declare function defineConfig<const TLocales extends Locales = never, const TDriver extends SessionDriverName = never>(config: AstroUserConfig<TLocales, TDriver>): AstroUserConfig<TLocales, TDriver>;
8
+ export declare function defineConfig<const TLocales extends Locales = never, const TDriver extends SessionDriverName = never, const TFontFamilies extends FontFamily[] = never>(config: AstroUserConfig<TLocales, TDriver, TFontFamilies>): AstroUserConfig<TLocales, TDriver, TFontFamilies>;
8
9
  /**
9
10
  * Use Astro to generate a fully resolved Vite config
10
11
  */
@@ -153,7 +153,7 @@ ${contentConfig.error.message}`);
153
153
  logger.info("Content config changed");
154
154
  shouldClear = true;
155
155
  }
156
- if (previousAstroVersion && previousAstroVersion !== "5.6.2") {
156
+ if (previousAstroVersion && previousAstroVersion !== "5.7.1") {
157
157
  logger.info("Astro version changed");
158
158
  shouldClear = true;
159
159
  }
@@ -161,8 +161,8 @@ ${contentConfig.error.message}`);
161
161
  logger.info("Clearing content store");
162
162
  this.#store.clearAll();
163
163
  }
164
- if ("5.6.2") {
165
- await this.#store.metaStore().set("astro-version", "5.6.2");
164
+ if ("5.7.1") {
165
+ await this.#store.metaStore().set("astro-version", "5.7.1");
166
166
  }
167
167
  if (currentConfigDigest) {
168
168
  await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -202,7 +202,8 @@ ${contentConfig.error.message}`);
202
202
  },
203
203
  collectionWithResolvedSchema,
204
204
  false,
205
- !!this.#settings.config.experimental.svg
205
+ // FUTURE: Remove in this in v6
206
+ id.endsWith(".svg")
206
207
  );
207
208
  return parsedData;
208
209
  };
@@ -7,6 +7,7 @@ function createImage(pluginContext, shouldEmitFile, entryFilePath, experimentalS
7
7
  const metadata = await emitESMImage(
8
8
  resolvedFilePath,
9
9
  pluginContext.meta.watchMode,
10
+ // FUTURE: Remove in this in v6
10
11
  experimentalSvgEnabled,
11
12
  shouldEmitFile ? pluginContext.emitFile : void 0
12
13
  );
@@ -171,7 +171,8 @@ async function getContentEntryModule(params) {
171
171
  { id, collection, _internal, unvalidatedData },
172
172
  collectionConfig,
173
173
  params.shouldEmitFile,
174
- !!params.config.experimental.svg,
174
+ // FUTURE: Remove in this in v6
175
+ id.endsWith(".svg"),
175
176
  pluginContext
176
177
  ) : unvalidatedData;
177
178
  const contentEntryModule = {
@@ -197,7 +198,8 @@ async function getDataEntryModule(params) {
197
198
  { id, collection, _internal, unvalidatedData },
198
199
  collectionConfig,
199
200
  params.shouldEmitFile,
200
- !!params.config.experimental.svg,
201
+ // FUTURE: Remove in this in v6
202
+ id.endsWith(".svg"),
201
203
  pluginContext
202
204
  ) : unvalidatedData;
203
205
  const dataEntryModule = {
@@ -18,7 +18,7 @@ import {
18
18
  } from "../../core/path.js";
19
19
  import { toFallbackType, toRoutingStrategy } from "../../i18n/utils.js";
20
20
  import { runHookBuildGenerated } from "../../integrations/hooks.js";
21
- import { getOutputDirectory } from "../../prerender/utils.js";
21
+ import { getServerOutputDirectory } from "../../prerender/utils.js";
22
22
  import { NoPrerenderedRoutesWithDomains } from "../errors/errors-data.js";
23
23
  import { AstroError, AstroErrorData } from "../errors/index.js";
24
24
  import { NOOP_MIDDLEWARE_FN } from "../middleware/noop-middleware.js";
@@ -41,7 +41,7 @@ async function generatePages(options, internals) {
41
41
  if (ssr) {
42
42
  manifest = await BuildPipeline.retrieveManifest(options.settings, internals);
43
43
  } else {
44
- const baseDirectory = getOutputDirectory(options.settings);
44
+ const baseDirectory = getServerOutputDirectory(options.settings);
45
45
  const renderersEntryUrl = new URL("renderers.mjs", baseDirectory);
46
46
  const renderers = await import(renderersEntryUrl.toString());
47
47
  const middleware = internals.middlewareEntryPoint ? await import(internals.middlewareEntryPoint.toString()).then((mod) => mod.onRequest) : NOOP_MIDDLEWARE_FN;