astro 5.16.6 → 5.16.7

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 (77) hide show
  1. package/components/Code.astro +2 -2
  2. package/components/Image.astro +2 -2
  3. package/components/Picture.astro +1 -1
  4. package/dist/assets/build/remote.js +1 -1
  5. package/dist/assets/endpoint/dev.js +44 -16
  6. package/dist/assets/fonts/config.d.ts +3 -0
  7. package/dist/assets/fonts/config.js +3 -2
  8. package/dist/assets/fonts/constants.js +2 -1
  9. package/dist/assets/fonts/core/resolve-families.js +1 -0
  10. package/dist/assets/fonts/definitions.d.ts +10 -2
  11. package/dist/assets/fonts/infra/remote-font-provider-resolver.d.ts +2 -2
  12. package/dist/assets/fonts/infra/unifont-font-resolver.d.ts +24 -0
  13. package/dist/assets/fonts/infra/unifont-font-resolver.js +59 -0
  14. package/dist/assets/fonts/orchestrate.d.ts +6 -4
  15. package/dist/assets/fonts/orchestrate.js +16 -32
  16. package/dist/assets/fonts/providers/entrypoints/bunny.d.ts +1 -1
  17. package/dist/assets/fonts/providers/entrypoints/fontshare.d.ts +1 -1
  18. package/dist/assets/fonts/providers/entrypoints/fontsource.d.ts +1 -1
  19. package/dist/assets/fonts/providers/index.d.ts +6 -8
  20. package/dist/assets/fonts/providers/index.js +10 -14
  21. package/dist/assets/fonts/types.d.ts +17 -4
  22. package/dist/assets/fonts/vite-plugin-fonts.js +6 -1
  23. package/dist/assets/utils/index.d.ts +1 -1
  24. package/dist/assets/utils/index.js +8 -8
  25. package/dist/assets/utils/vendor/image-size/detector.d.ts +1 -1
  26. package/dist/assets/utils/vendor/image-size/detector.js +2 -1
  27. package/dist/assets/utils/vendor/image-size/types/bmp.js +1 -1
  28. package/dist/assets/utils/vendor/image-size/types/gif.js +1 -1
  29. package/dist/assets/utils/vendor/image-size/types/heif.js +51 -29
  30. package/dist/assets/utils/vendor/image-size/types/icns.js +13 -14
  31. package/dist/assets/utils/vendor/image-size/types/ico.js +5 -5
  32. package/dist/assets/utils/vendor/image-size/types/index.d.ts +3 -3
  33. package/dist/assets/utils/vendor/image-size/types/index.js +4 -0
  34. package/dist/assets/utils/vendor/image-size/types/interface.d.ts +6 -6
  35. package/dist/assets/utils/vendor/image-size/types/j2c.js +2 -2
  36. package/dist/assets/utils/vendor/image-size/types/jp2.js +5 -3
  37. package/dist/assets/utils/vendor/image-size/types/jpg.js +4 -4
  38. package/dist/assets/utils/vendor/image-size/types/jxl-stream.d.ts +2 -0
  39. package/dist/assets/utils/vendor/image-size/types/jxl-stream.js +36 -0
  40. package/dist/assets/utils/vendor/image-size/types/jxl.d.ts +2 -0
  41. package/dist/assets/utils/vendor/image-size/types/jxl.js +57 -0
  42. package/dist/assets/utils/vendor/image-size/types/ktx.js +1 -1
  43. package/dist/assets/utils/vendor/image-size/types/png.js +1 -1
  44. package/dist/assets/utils/vendor/image-size/types/pnm.js +5 -7
  45. package/dist/assets/utils/vendor/image-size/types/psd.js +1 -1
  46. package/dist/assets/utils/vendor/image-size/types/tiff.js +93 -40
  47. package/dist/assets/utils/vendor/image-size/types/utils.d.ts +3 -2
  48. package/dist/assets/utils/vendor/image-size/types/utils.js +24 -22
  49. package/dist/assets/utils/vendor/image-size/types/webp.js +5 -6
  50. package/dist/assets/utils/vendor/image-size/utils/bit-reader.d.ts +10 -0
  51. package/dist/assets/utils/vendor/image-size/utils/bit-reader.js +41 -0
  52. package/dist/assets/vite-plugin-assets.js +7 -0
  53. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  54. package/dist/config/entrypoint.d.ts +1 -2
  55. package/dist/config/entrypoint.js +1 -2
  56. package/dist/content/content-layer.js +3 -3
  57. package/dist/content/utils.js +9 -2
  58. package/dist/core/app/index.d.ts +1 -1
  59. package/dist/core/app/index.js +1 -1
  60. package/dist/core/config/schemas/base.d.ts +7 -0
  61. package/dist/core/config/schemas/relative.d.ts +9 -0
  62. package/dist/core/constants.js +1 -1
  63. package/dist/core/dev/dev.js +1 -1
  64. package/dist/core/messages.js +2 -2
  65. package/dist/runtime/server/render/astro/render.js +26 -3
  66. package/dist/runtime/server/render/common.d.ts +1 -0
  67. package/dist/runtime/server/render/common.js +8 -0
  68. package/dist/transitions/router.js +2 -0
  69. package/dist/types/public/config.d.ts +2 -2
  70. package/dist/types/public/context.d.ts +303 -284
  71. package/package.json +18 -18
  72. package/dist/assets/fonts/core/dedupe-font-faces.d.ts +0 -2
  73. package/dist/assets/fonts/core/dedupe-font-faces.js +0 -30
  74. package/dist/assets/fonts/core/extract-unifont-providers.d.ts +0 -10
  75. package/dist/assets/fonts/core/extract-unifont-providers.js +0 -28
  76. package/dist/assets/utils/remotePattern.d.ts +0 -1
  77. package/dist/assets/utils/remotePattern.js +0 -16
@@ -3,8 +3,8 @@ import type { ThemePresets } from '@astrojs/markdown-remark';
3
3
  import type { ShikiTransformer, ThemeRegistration, ThemeRegistrationRaw } from 'shiki';
4
4
  import { bundledLanguages } from 'shiki/langs';
5
5
  import { getCachedHighlighter } from '../dist/core/shiki.js';
6
- import type { CodeLanguage } from '../dist/types/public';
7
- import type { HTMLAttributes } from '../types';
6
+ import type { CodeLanguage } from '../dist/types/public/index.js';
7
+ import type { HTMLAttributes } from '../types.js';
8
8
 
9
9
  interface Props extends Omit<HTMLAttributes<'pre'>, 'lang'> {
10
10
  /** The code to highlight. Required. */
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  import { getImage, imageConfig, type LocalImageProps, type RemoteImageProps } from 'astro:assets';
3
- import type { UnresolvedImageTransform } from '../dist/assets/types';
3
+ import type { UnresolvedImageTransform } from '../dist/assets/types.js';
4
4
  import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
5
- import type { HTMLAttributes } from '../types';
5
+ import type { HTMLAttributes } from '../types.js';
6
6
 
7
7
  // The TypeScript diagnostic for JSX props uses the last member of the union to suggest props, so it would be better for
8
8
  // LocalImageProps to be last. Unfortunately, when we do this the error messages that remote images get are complete nonsense
@@ -8,7 +8,7 @@ import type {
8
8
  ImageOutputFormat,
9
9
  UnresolvedImageTransform,
10
10
  } from '../dist/types/public/index.js';
11
- import type { HTMLAttributes } from '../types';
11
+ import type { HTMLAttributes } from '../types.js';
12
12
 
13
13
  export type Props = (LocalImageProps | RemoteImageProps) & {
14
14
  formats?: ImageOutputFormat[];
@@ -21,7 +21,7 @@ async function revalidateRemoteImage(src, revalidationData) {
21
21
  ...revalidationData.etag && { "If-None-Match": revalidationData.etag },
22
22
  ...revalidationData.lastModified && { "If-Modified-Since": revalidationData.lastModified }
23
23
  };
24
- const req = new Request(src, { headers });
24
+ const req = new Request(src, { headers, cache: "no-cache" });
25
25
  const res = await fetch(req);
26
26
  if (!res.ok && res.status !== 304) {
27
27
  throw new Error(
@@ -1,33 +1,61 @@
1
- import { root } from "astro:config/server";
1
+ import { safeModulePaths, viteFSConfig } from "astro:assets";
2
2
  import { readFile } from "node:fs/promises";
3
- import { fileURLToPath } from "node:url";
4
- import { isParentDirectory } from "@astrojs/internal-helpers/path";
3
+ import os from "node:os";
4
+ import picomatch from "picomatch";
5
+ import { isFileLoadingAllowed } from "vite";
5
6
  import { handleImageRequest, loadRemoteImage } from "./shared.js";
7
+ function replaceFileSystemReferences(src) {
8
+ return os.platform().includes("win32") ? src.replace(/^\/@fs\//, "") : src.replace(/^\/@fs/, "");
9
+ }
6
10
  async function loadLocalImage(src, url) {
11
+ let returnValue;
12
+ let fsPath;
7
13
  if (src.startsWith("/@fs/")) {
8
- try {
9
- const res = await fetch(new URL(src, url));
10
- if (!res.ok) {
11
- return void 0;
12
- }
13
- return Buffer.from(await res.arrayBuffer());
14
- } catch {
15
- return void 0;
16
- }
14
+ fsPath = replaceFileSystemReferences(src);
17
15
  }
18
- if (isParentDirectory(fileURLToPath(root), src)) {
16
+ if (fsPath && isFileLoadingAllowed(
17
+ {
18
+ fsDenyGlob: picomatch(
19
+ // matchBase: true does not work as it's documented
20
+ // https://github.com/micromatch/picomatch/issues/89
21
+ // convert patterns without `/` on our side for now
22
+ viteFSConfig.deny.map(
23
+ (pattern) => pattern.includes("/") ? pattern : `**/${pattern}`
24
+ ),
25
+ {
26
+ matchBase: false,
27
+ nocase: true,
28
+ dot: true
29
+ }
30
+ ),
31
+ server: { fs: viteFSConfig },
32
+ safeModulePaths
33
+ },
34
+ fsPath
35
+ )) {
19
36
  try {
20
- return await readFile(src);
37
+ returnValue = await readFile(fsPath);
21
38
  } catch {
22
- return void 0;
39
+ returnValue = void 0;
40
+ }
41
+ if (!returnValue) {
42
+ try {
43
+ const res = await fetch(new URL(src, url));
44
+ if (res.ok) {
45
+ returnValue = Buffer.from(await res.arrayBuffer());
46
+ }
47
+ } catch {
48
+ returnValue = void 0;
49
+ }
23
50
  }
24
51
  } else {
25
52
  const sourceUrl = new URL(src, url.origin);
26
53
  if (sourceUrl.origin !== url.origin) {
27
- return void 0;
54
+ returnValue = void 0;
28
55
  }
29
56
  return loadRemoteImage(sourceUrl);
30
57
  }
58
+ return returnValue;
31
59
  }
32
60
  const GET = async ({ request }) => {
33
61
  if (!import.meta.env.DEV) {
@@ -146,6 +146,7 @@ export declare const remoteFontFamilySchema: z.ZodObject<{
146
146
  weights: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "atleastone">>;
147
147
  styles: z.ZodOptional<z.ZodArray<z.ZodEnum<["normal", "italic", "oblique"]>, "atleastone">>;
148
148
  subsets: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
149
+ formats: z.ZodOptional<z.ZodArray<z.ZodEnum<["woff2", "woff", "otf", "ttf", "eot"]>, "atleastone">>;
149
150
  display: z.ZodOptional<z.ZodEnum<["auto", "block", "swap", "fallback", "optional"]>>;
150
151
  stretch: z.ZodOptional<z.ZodString>;
151
152
  featureSettings: z.ZodOptional<z.ZodString>;
@@ -167,6 +168,7 @@ export declare const remoteFontFamilySchema: z.ZodObject<{
167
168
  subsets?: [string, ...string[]] | undefined;
168
169
  fallbacks?: string[] | undefined;
169
170
  optimizedFallbacks?: boolean | undefined;
171
+ formats?: ["woff2" | "woff" | "otf" | "ttf" | "eot", ...("woff2" | "woff" | "otf" | "ttf" | "eot")[]] | undefined;
170
172
  display?: "auto" | "block" | "swap" | "fallback" | "optional" | undefined;
171
173
  stretch?: string | undefined;
172
174
  featureSettings?: string | undefined;
@@ -184,6 +186,7 @@ export declare const remoteFontFamilySchema: z.ZodObject<{
184
186
  subsets?: [string, ...string[]] | undefined;
185
187
  fallbacks?: string[] | undefined;
186
188
  optimizedFallbacks?: boolean | undefined;
189
+ formats?: ["woff2" | "woff" | "otf" | "ttf" | "eot", ...("woff2" | "woff" | "otf" | "ttf" | "eot")[]] | undefined;
187
190
  display?: "auto" | "block" | "swap" | "fallback" | "optional" | undefined;
188
191
  stretch?: string | undefined;
189
192
  featureSettings?: string | undefined;
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { LOCAL_PROVIDER_NAME } from "./constants.js";
2
+ import { FONT_TYPES, LOCAL_PROVIDER_NAME } from "./constants.js";
3
3
  const weightSchema = z.union([z.string(), z.number()]);
4
4
  const styleSchema = z.enum(["normal", "italic", "oblique"]);
5
5
  const displaySchema = z.enum(["auto", "block", "swap", "fallback", "optional"]);
@@ -51,7 +51,8 @@ const remoteFontFamilySchema = z.object({
51
51
  }).strict(),
52
52
  weights: z.array(weightSchema).nonempty().optional(),
53
53
  styles: z.array(styleSchema).nonempty().optional(),
54
- subsets: z.array(z.string()).nonempty().optional()
54
+ subsets: z.array(z.string()).nonempty().optional(),
55
+ formats: z.array(z.enum(FONT_TYPES)).nonempty().optional()
55
56
  }).strict();
56
57
  export {
57
58
  displaySchema,
@@ -5,7 +5,8 @@ const DEFAULTS = {
5
5
  subsets: ["latin"],
6
6
  // Technically serif is the browser default but most websites these days use sans-serif
7
7
  fallbacks: ["sans-serif"],
8
- optimizedFallbacks: true
8
+ optimizedFallbacks: true,
9
+ formats: ["woff2"]
9
10
  };
10
11
  const VIRTUAL_MODULE_ID = "virtual:astro:assets/fonts/internal";
11
12
  const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
@@ -42,6 +42,7 @@ async function resolveFamily({
42
42
  weights: family.weights ? dedupe(family.weights.map((weight) => weight.toString())) : void 0,
43
43
  styles: family.styles ? dedupe(family.styles) : void 0,
44
44
  subsets: family.subsets ? dedupe(family.subsets) : void 0,
45
+ formats: family.formats ? dedupe(family.formats) : void 0,
45
46
  fallbacks: family.fallbacks ? dedupe(family.fallbacks) : void 0,
46
47
  unicodeRange: family.unicodeRange ? dedupe(family.unicodeRange) : void 0,
47
48
  // This will be Astro specific eventually
@@ -1,6 +1,6 @@
1
1
  import type * as unifont from 'unifont';
2
2
  import type { CollectedFontForMetrics } from './core/optimize-fallbacks.js';
3
- import type { AstroFontProvider, FontFaceMetrics, FontFileData, FontType, GenericFallbackName, PreloadData, ResolvedFontProvider, Style } from './types.js';
3
+ import type { FontFaceMetrics, FontFileData, FontProvider, FontType, GenericFallbackName, PreloadData, ResolvedFontProvider, ResolveFontOptions, Style } from './types.js';
4
4
  export interface Hasher {
5
5
  hashString: (input: string) => string;
6
6
  hashObject: (input: Record<string, any>) => string;
@@ -9,7 +9,7 @@ export interface RemoteFontProviderModResolver {
9
9
  resolve: (id: string) => Promise<any>;
10
10
  }
11
11
  export interface RemoteFontProviderResolver {
12
- resolve: (provider: AstroFontProvider) => Promise<ResolvedFontProvider>;
12
+ resolve: (provider: FontProvider) => Promise<ResolvedFontProvider>;
13
13
  }
14
14
  export interface LocalProviderUrlResolver {
15
15
  resolve: (input: string) => string;
@@ -90,3 +90,11 @@ export interface Storage {
90
90
  setItem: (key: string, value: any) => Promise<void>;
91
91
  setItemRaw: (key: string, value: any) => Promise<void>;
92
92
  }
93
+ export interface FontResolver {
94
+ resolveFont: (options: ResolveFontOptions & {
95
+ provider: string;
96
+ }) => Promise<Array<unifont.FontFaceData>>;
97
+ listFonts: (options: {
98
+ provider: string;
99
+ }) => Promise<string[] | undefined>;
100
+ }
@@ -1,10 +1,10 @@
1
1
  import type { RemoteFontProviderModResolver, RemoteFontProviderResolver } from '../definitions.js';
2
- import type { AstroFontProvider, ResolvedFontProvider } from '../types.js';
2
+ import type { FontProvider, ResolvedFontProvider } from '../types.js';
3
3
  export declare class RealRemoteFontProviderResolver implements RemoteFontProviderResolver {
4
4
  #private;
5
5
  constructor({ root, modResolver, }: {
6
6
  root: URL;
7
7
  modResolver: RemoteFontProviderModResolver;
8
8
  });
9
- resolve({ entrypoint, config }: AstroFontProvider): Promise<ResolvedFontProvider>;
9
+ resolve({ entrypoint, config }: FontProvider): Promise<ResolvedFontProvider>;
10
10
  }
@@ -0,0 +1,24 @@
1
+ import type { FontFaceData, Provider } from 'unifont';
2
+ import type { FontResolver, Hasher, Storage } from '../definitions.js';
3
+ import type { ResolvedFontFamily, ResolveFontOptions } from '../types.js';
4
+ type NonEmptyProviders = [Provider, ...Array<Provider>];
5
+ export declare class UnifontFontResolver implements FontResolver {
6
+ #private;
7
+ private constructor();
8
+ static extractUnifontProviders({ families, hasher, }: {
9
+ families: Array<ResolvedFontFamily>;
10
+ hasher: Hasher;
11
+ }): NonEmptyProviders;
12
+ static create({ families, hasher, storage, }: {
13
+ families: Array<ResolvedFontFamily>;
14
+ hasher: Hasher;
15
+ storage: Storage;
16
+ }): Promise<UnifontFontResolver>;
17
+ resolveFont({ familyName, provider, ...rest }: ResolveFontOptions & {
18
+ provider: string;
19
+ }): Promise<Array<FontFaceData>>;
20
+ listFonts({ provider }: {
21
+ provider: string;
22
+ }): Promise<string[] | undefined>;
23
+ }
24
+ export {};
@@ -0,0 +1,59 @@
1
+ import { createUnifont } from "unifont";
2
+ import { LOCAL_PROVIDER_NAME } from "../constants.js";
3
+ class UnifontFontResolver {
4
+ #unifont;
5
+ constructor({ unifont }) {
6
+ this.#unifont = unifont;
7
+ }
8
+ static extractUnifontProviders({
9
+ families,
10
+ hasher
11
+ }) {
12
+ const hashes = /* @__PURE__ */ new Set();
13
+ const providers = [];
14
+ for (const { provider } of families) {
15
+ if (provider === LOCAL_PROVIDER_NAME) {
16
+ continue;
17
+ }
18
+ const unifontProvider = provider.provider(provider.config);
19
+ const hash = hasher.hashObject({
20
+ name: unifontProvider._name,
21
+ ...provider.config
22
+ });
23
+ unifontProvider._name += `-${hash}`;
24
+ provider.name = unifontProvider._name;
25
+ if (!hashes.has(hash)) {
26
+ hashes.add(hash);
27
+ providers.push(unifontProvider);
28
+ }
29
+ }
30
+ return providers;
31
+ }
32
+ static async create({
33
+ families,
34
+ hasher,
35
+ storage
36
+ }) {
37
+ return new UnifontFontResolver({
38
+ unifont: await createUnifont(this.extractUnifontProviders({ families, hasher }), {
39
+ storage,
40
+ // TODO: consider enabling, would require new astro errors
41
+ throwOnError: false
42
+ })
43
+ });
44
+ }
45
+ async resolveFont({
46
+ familyName,
47
+ provider,
48
+ ...rest
49
+ }) {
50
+ const { fonts } = await this.#unifont.resolveFont(familyName, rest, [provider]);
51
+ return fonts;
52
+ }
53
+ async listFonts({ provider }) {
54
+ return await this.#unifont.listFonts([provider]);
55
+ }
56
+ }
57
+ export {
58
+ UnifontFontResolver
59
+ };
@@ -1,6 +1,6 @@
1
1
  import type { Logger } from '../../core/logger/core.js';
2
- import type { CssRenderer, FontFileReader, FontMetricsResolver, FontTypeExtractor, Hasher, LocalProviderUrlResolver, RemoteFontProviderResolver, Storage, StringMatcher, SystemFallbacksProvider, UrlProxy } from './definitions.js';
3
- import type { ConsumableMap, CreateUrlProxyParams, Defaults, FontFamily, FontFileDataMap, InternalConsumableMap } from './types.js';
2
+ import type { CssRenderer, FontFileReader, FontMetricsResolver, FontResolver, FontTypeExtractor, Hasher, LocalProviderUrlResolver, RemoteFontProviderResolver, StringMatcher, SystemFallbacksProvider, UrlProxy } from './definitions.js';
3
+ import type { ConsumableMap, CreateUrlProxyParams, Defaults, FontFamily, FontFileDataMap, InternalConsumableMap, ResolvedFontFamily } from './types.js';
4
4
  /**
5
5
  * Manages how fonts are resolved:
6
6
  *
@@ -19,12 +19,11 @@ import type { ConsumableMap, CreateUrlProxyParams, Defaults, FontFamily, FontFil
19
19
  *
20
20
  * Once that's done, the collected data is returned
21
21
  */
22
- export declare function orchestrate({ families, hasher, remoteFontProviderResolver, localProviderUrlResolver, storage, cssRenderer, systemFallbacksProvider, fontMetricsResolver, fontTypeExtractor, fontFileReader, logger, createUrlProxy, defaults, bold, stringMatcher, }: {
22
+ export declare function orchestrate({ families, hasher, remoteFontProviderResolver, localProviderUrlResolver, cssRenderer, systemFallbacksProvider, fontMetricsResolver, fontTypeExtractor, fontFileReader, logger, createUrlProxy, defaults, bold, stringMatcher, createFontResolver, }: {
23
23
  families: Array<FontFamily>;
24
24
  hasher: Hasher;
25
25
  remoteFontProviderResolver: RemoteFontProviderResolver;
26
26
  localProviderUrlResolver: LocalProviderUrlResolver;
27
- storage: Storage;
28
27
  cssRenderer: CssRenderer;
29
28
  systemFallbacksProvider: SystemFallbacksProvider;
30
29
  fontMetricsResolver: FontMetricsResolver;
@@ -35,6 +34,9 @@ export declare function orchestrate({ families, hasher, remoteFontProviderResolv
35
34
  defaults: Defaults;
36
35
  bold: (input: string) => string;
37
36
  stringMatcher: StringMatcher;
37
+ createFontResolver: (params: {
38
+ families: Array<ResolvedFontFamily>;
39
+ }) => Promise<FontResolver>;
38
40
  }): Promise<{
39
41
  fontFileDataMap: FontFileDataMap;
40
42
  internalConsumableMap: InternalConsumableMap;
@@ -1,7 +1,4 @@
1
- import * as unifont from "unifont";
2
1
  import { LOCAL_PROVIDER_NAME } from "./constants.js";
3
- import { dedupeFontFaces } from "./core/dedupe-font-faces.js";
4
- import { extractUnifontProviders } from "./core/extract-unifont-providers.js";
5
2
  import { normalizeRemoteFontFaces } from "./core/normalize-remote-font-faces.js";
6
3
  import { optimizeFallbacks } from "./core/optimize-fallbacks.js";
7
4
  import { resolveFamilies } from "./core/resolve-families.js";
@@ -16,7 +13,6 @@ async function orchestrate({
16
13
  hasher,
17
14
  remoteFontProviderResolver,
18
15
  localProviderUrlResolver,
19
- storage,
20
16
  cssRenderer,
21
17
  systemFallbacksProvider,
22
18
  fontMetricsResolver,
@@ -26,23 +22,16 @@ async function orchestrate({
26
22
  createUrlProxy,
27
23
  defaults,
28
24
  bold,
29
- stringMatcher
25
+ stringMatcher,
26
+ createFontResolver
30
27
  }) {
31
- let resolvedFamilies = await resolveFamilies({
28
+ const resolvedFamilies = await resolveFamilies({
32
29
  families,
33
30
  hasher,
34
31
  remoteFontProviderResolver,
35
32
  localProviderUrlResolver
36
33
  });
37
- const extractedUnifontProvidersResult = extractUnifontProviders({
38
- families: resolvedFamilies,
39
- hasher
40
- });
41
- resolvedFamilies = extractedUnifontProvidersResult.families;
42
- const unifontProviders = extractedUnifontProvidersResult.providers;
43
- const { resolveFont, listFonts } = await unifont.createUnifont(unifontProviders, {
44
- storage
45
- });
34
+ const fontResolver = await createFontResolver({ families: resolvedFamilies });
46
35
  const fontFileDataMap = /* @__PURE__ */ new Map();
47
36
  const internalConsumableMap = /* @__PURE__ */ new Map();
48
37
  const consumableMap = /* @__PURE__ */ new Map();
@@ -99,26 +88,24 @@ async function orchestrate({
99
88
  });
100
89
  resolvedFamily.fonts.push(...result.fonts);
101
90
  } else {
102
- const result = await resolveFont(
103
- family.name,
104
- // We do not merge the defaults, we only provide defaults as a fallback
105
- {
106
- weights: family.weights ?? defaults.weights,
107
- styles: family.styles ?? defaults.styles,
108
- subsets: family.subsets ?? defaults.subsets,
109
- fallbacks: family.fallbacks ?? defaults.fallbacks
110
- },
91
+ const fonts = await fontResolver.resolveFont({
92
+ familyName: family.name,
111
93
  // By default, unifont goes through all providers. We use a different approach where
112
94
  // we specify a provider per font. Name has been set while extracting unifont providers
113
95
  // from families (inside extractUnifontProviders).
114
- [family.provider.name]
115
- );
116
- if (result.fonts.length === 0) {
96
+ provider: family.provider.name,
97
+ // We do not merge the defaults, we only provide defaults as a fallback
98
+ weights: family.weights ?? defaults.weights,
99
+ styles: family.styles ?? defaults.styles,
100
+ subsets: family.subsets ?? defaults.subsets,
101
+ formats: family.formats ?? defaults.formats
102
+ });
103
+ if (fonts.length === 0) {
117
104
  logger.warn(
118
105
  "assets",
119
106
  `No data found for font family ${bold(family.name)}. Review your configuration`
120
107
  );
121
- const availableFamilies = await listFonts([family.provider.name]);
108
+ const availableFamilies = await fontResolver.listFonts({ provider: family.provider.name });
122
109
  if (availableFamilies && availableFamilies.length > 0 && !availableFamilies.includes(family.name)) {
123
110
  logger.warn(
124
111
  "assets",
@@ -126,10 +113,7 @@ async function orchestrate({
126
113
  );
127
114
  }
128
115
  }
129
- resolvedFamily.fonts = dedupeFontFaces(
130
- resolvedFamily.fonts,
131
- normalizeRemoteFontFaces({ fonts: result.fonts, urlProxy, fontTypeExtractor })
132
- );
116
+ resolvedFamily.fonts = normalizeRemoteFontFaces({ fonts, urlProxy, fontTypeExtractor });
133
117
  }
134
118
  }
135
119
  for (const {
@@ -1 +1 @@
1
- export declare const provider: () => import("unifont").Provider;
1
+ export declare const provider: () => import("unifont").Provider<"bunny", never>;
@@ -1 +1 @@
1
- export declare const provider: () => import("unifont").Provider;
1
+ export declare const provider: () => import("unifont").Provider<"fontshare", never>;
@@ -1 +1 @@
1
- export declare const provider: () => import("unifont").Provider;
1
+ export declare const provider: () => import("unifont").Provider<"fontsource", never>;
@@ -1,15 +1,15 @@
1
1
  import type { providers } from 'unifont';
2
- import type { AstroFontProvider } from '../types.js';
2
+ import type { FontProvider } from '../types.js';
3
3
  /** [Adobe](https://fonts.adobe.com/) */
4
- declare function adobe(config: Parameters<typeof providers.adobe>[0]): AstroFontProvider;
4
+ declare function adobe(config: Parameters<typeof providers.adobe>[0]): FontProvider;
5
5
  /** [Bunny](https://fonts.bunny.net/) */
6
- declare function bunny(): AstroFontProvider;
6
+ declare function bunny(): FontProvider;
7
7
  /** [Fontshare](https://www.fontshare.com/) */
8
- declare function fontshare(): AstroFontProvider;
8
+ declare function fontshare(): FontProvider;
9
9
  /** [Fontsource](https://fontsource.org/) */
10
- declare function fontsource(): AstroFontProvider;
10
+ declare function fontsource(): FontProvider;
11
11
  /** [Google](https://fonts.google.com/) */
12
- declare function google(config?: Parameters<typeof providers.google>[0]): AstroFontProvider;
12
+ declare function google(config?: Parameters<typeof providers.google>[0]): FontProvider;
13
13
  /**
14
14
  * Astro re-exports most [unifont](https://github.com/unjs/unifont/) providers:
15
15
  * - [Adobe](https://fonts.adobe.com/)
@@ -25,6 +25,4 @@ export declare const fontProviders: {
25
25
  fontsource: typeof fontsource;
26
26
  google: typeof google;
27
27
  };
28
- /** A type helper for defining Astro font providers config objects */
29
- export declare function defineAstroFontProvider(provider: AstroFontProvider): AstroFontProvider;
30
28
  export {};
@@ -1,29 +1,29 @@
1
1
  function adobe(config) {
2
- return defineAstroFontProvider({
2
+ return {
3
3
  entrypoint: "astro/assets/fonts/providers/adobe",
4
4
  config
5
- });
5
+ };
6
6
  }
7
7
  function bunny() {
8
- return defineAstroFontProvider({
8
+ return {
9
9
  entrypoint: "astro/assets/fonts/providers/bunny"
10
- });
10
+ };
11
11
  }
12
12
  function fontshare() {
13
- return defineAstroFontProvider({
13
+ return {
14
14
  entrypoint: "astro/assets/fonts/providers/fontshare"
15
- });
15
+ };
16
16
  }
17
17
  function fontsource() {
18
- return defineAstroFontProvider({
18
+ return {
19
19
  entrypoint: "astro/assets/fonts/providers/fontsource"
20
- });
20
+ };
21
21
  }
22
22
  function google(config) {
23
- return defineAstroFontProvider({
23
+ return {
24
24
  entrypoint: "astro/assets/fonts/providers/google",
25
25
  config
26
- });
26
+ };
27
27
  }
28
28
  const fontProviders = {
29
29
  adobe,
@@ -32,10 +32,6 @@ const fontProviders = {
32
32
  fontsource,
33
33
  google
34
34
  };
35
- function defineAstroFontProvider(provider) {
36
- return provider;
37
- }
38
35
  export {
39
- defineAstroFontProvider,
40
36
  fontProviders
41
37
  };
@@ -6,7 +6,7 @@ import type { FONT_TYPES, GENERIC_FALLBACK_NAMES, LOCAL_PROVIDER_NAME } from './
6
6
  import type { CollectedFontForMetrics } from './core/optimize-fallbacks.js';
7
7
  type Weight = z.infer<typeof weightSchema>;
8
8
  type Display = z.infer<typeof displaySchema>;
9
- export interface AstroFontProvider {
9
+ export interface FontProvider {
10
10
  /**
11
11
  * URL, path relative to the root or package import.
12
12
  */
@@ -126,11 +126,11 @@ export interface ResolvedLocalFontFamily extends ResolvedFontFamilyAttributes, O
126
126
  }>;
127
127
  }>;
128
128
  }
129
- export interface RemoteFontFamily extends RequiredFamilyAttributes, Omit<FamilyProperties, 'weight' | 'style'>, Fallbacks {
129
+ export interface RemoteFontFamily extends RequiredFamilyAttributes, Omit<FamilyProperties, 'weight' | 'style' | 'subsets' | 'formats'>, Fallbacks {
130
130
  /**
131
131
  * The source of your font files. You can use a built-in provider or write your own custom provider.
132
132
  */
133
- provider: AstroFontProvider;
133
+ provider: FontProvider;
134
134
  /**
135
135
  * @default `[400]`
136
136
  *
@@ -153,6 +153,12 @@ export interface RemoteFontFamily extends RequiredFamilyAttributes, Omit<FamilyP
153
153
  * An array of [font subsets](https://knaap.dev/posts/font-subsetting/):
154
154
  */
155
155
  subsets?: [string, ...Array<string>] | undefined;
156
+ /**
157
+ * @default `["woff2"]`
158
+ *
159
+ * An array of [font formats](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@font-face/src#font_formats).
160
+ */
161
+ formats?: [FontType, ...Array<FontType>] | undefined;
156
162
  }
157
163
  /** @lintignore somehow required by pickFontFaceProperty in utils */
158
164
  export interface ResolvedRemoteFontFamily extends ResolvedFontFamilyAttributes, Omit<RemoteFontFamily, 'provider' | 'weights'> {
@@ -180,7 +186,7 @@ export interface PreloadData {
180
186
  }
181
187
  export type FontFaceMetrics = Pick<Font, 'ascent' | 'descent' | 'lineGap' | 'unitsPerEm' | 'xWidthAvg'>;
182
188
  export type GenericFallbackName = (typeof GENERIC_FALLBACK_NAMES)[number];
183
- export type Defaults = Partial<Pick<ResolvedRemoteFontFamily, 'weights' | 'styles' | 'subsets' | 'fallbacks' | 'optimizedFallbacks'>>;
189
+ export type Defaults = Partial<Pick<ResolvedRemoteFontFamily, 'weights' | 'styles' | 'subsets' | 'fallbacks' | 'optimizedFallbacks' | 'formats'>>;
184
190
  export interface FontFileData {
185
191
  hash: string;
186
192
  url: string;
@@ -225,4 +231,11 @@ export type PreloadFilter = boolean | Array<{
225
231
  style?: string;
226
232
  subset?: string;
227
233
  }>;
234
+ export interface ResolveFontOptions {
235
+ familyName: string;
236
+ weights: string[] | undefined;
237
+ styles: Style[] | undefined;
238
+ subsets: string[] | undefined;
239
+ formats: FontType[] | undefined;
240
+ }
228
241
  export {};
@@ -35,6 +35,7 @@ import { RealRemoteFontProviderResolver } from "./infra/remote-font-provider-res
35
35
  import { RemoteUrlProxyContentResolver } from "./infra/remote-url-proxy-content-resolver.js";
36
36
  import { RequireLocalProviderUrlResolver } from "./infra/require-local-provider-url-resolver.js";
37
37
  import { RealSystemFallbacksProvider } from "./infra/system-fallbacks-provider.js";
38
+ import { UnifontFontResolver } from "./infra/unifont-font-resolver.js";
38
39
  import { UnstorageFsStorage } from "./infra/unstorage-fs-storage.js";
39
40
  import { RealUrlProxy } from "./infra/url-proxy.js";
40
41
  import { XxhashHasher } from "./infra/xxhash-hasher.js";
@@ -114,7 +115,11 @@ function fontsPlugin({ settings, sync, logger }) {
114
115
  hasher,
115
116
  remoteFontProviderResolver,
116
117
  localProviderUrlResolver,
117
- storage,
118
+ createFontResolver: async ({ families }) => await UnifontFontResolver.create({
119
+ families,
120
+ hasher,
121
+ storage
122
+ }),
118
123
  cssRenderer,
119
124
  systemFallbacksProvider,
120
125
  fontMetricsResolver,
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * If some functions don't need to be exposed, just import the file that contains the functions.
6
6
  */
7
+ export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern, } from '@astrojs/internal-helpers/remote';
7
8
  export { isESMImportedImage, isRemoteImage, resolveSrc } from './imageKind.js';
8
9
  export { imageMetadata } from './metadata.js';
9
10
  export {
@@ -12,6 +13,5 @@ export {
12
13
  */
13
14
  emitESMImage, emitImageMetadata, } from './node/emitAsset.js';
14
15
  export { getOrigQueryParams } from './queryParams.js';
15
- export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern, } from './remotePattern.js';
16
16
  export { inferRemoteSize } from './remoteProbe.js';
17
17
  export { hashTransform, propsToFilename } from './transformToPath.js';
@@ -1,10 +1,3 @@
1
- import { isESMImportedImage, isRemoteImage, resolveSrc } from "./imageKind.js";
2
- import { imageMetadata } from "./metadata.js";
3
- import {
4
- emitESMImage,
5
- emitImageMetadata
6
- } from "./node/emitAsset.js";
7
- import { getOrigQueryParams } from "./queryParams.js";
8
1
  import {
9
2
  isRemoteAllowed,
10
3
  matchHostname,
@@ -12,7 +5,14 @@ import {
12
5
  matchPattern,
13
6
  matchPort,
14
7
  matchProtocol
15
- } from "./remotePattern.js";
8
+ } from "@astrojs/internal-helpers/remote";
9
+ import { isESMImportedImage, isRemoteImage, resolveSrc } from "./imageKind.js";
10
+ import { imageMetadata } from "./metadata.js";
11
+ import {
12
+ emitESMImage,
13
+ emitImageMetadata
14
+ } from "./node/emitAsset.js";
15
+ import { getOrigQueryParams } from "./queryParams.js";
16
16
  import { inferRemoteSize } from "./remoteProbe.js";
17
17
  import { hashTransform, propsToFilename } from "./transformToPath.js";
18
18
  export {