Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fonts): config #12777

Merged
merged 13 commits into from
Jan 21, 2025
2 changes: 1 addition & 1 deletion packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"test:e2e:match": "playwright test -g",
"test:e2e:chrome": "playwright test",
"test:e2e:firefox": "playwright test --config playwright.firefox.config.js",
"test:types": "tsc --project tsconfig.tests.json",
"test:types": "tsc --project test/types/tsconfig.json",
"test:unit": "astro-scripts test \"test/units/**/*.test.js\" --teardown ./test/units/teardown.js",
"test:integration": "astro-scripts test \"test/*.test.js\""
},
Expand Down
4 changes: 4 additions & 0 deletions packages/astro/src/assets/fonts/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { GOOGLE_PROVIDER_NAME } from "./providers/google.js";
import { LOCAL_PROVIDER_NAME } from "./providers/local.js";

export const BUILTIN_PROVIDERS = [GOOGLE_PROVIDER_NAME, LOCAL_PROVIDER_NAME] as const;
5 changes: 5 additions & 0 deletions packages/astro/src/assets/fonts/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { FontProvider } from './types.js';

export function defineFontProvider<TName extends string>(provider: FontProvider<TName>) {
return provider;
}
6 changes: 6 additions & 0 deletions packages/astro/src/assets/fonts/providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { adobe } from './providers/adobe.js';

/** TODO: */
export const fontProviders = {
adobe,
};
9 changes: 9 additions & 0 deletions packages/astro/src/assets/fonts/providers/adobe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineFontProvider } from '../helpers.js';

export function adobe(config: { apiKey: string }) {
return defineFontProvider({
name: 'adobe',
entrypoint: 'astro/assets/fonts/providers/adobe',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entrypoints should have the file extension. E.g. astro/assets/fonts/providers/adobe.js

config,
});
}
10 changes: 10 additions & 0 deletions packages/astro/src/assets/fonts/providers/google.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineFontProvider } from '../helpers.js';

export const GOOGLE_PROVIDER_NAME = 'google';

export function google() {
return defineFontProvider({
name: GOOGLE_PROVIDER_NAME,
entrypoint: 'astro/assets/fonts/providers/google',
ematipico marked this conversation as resolved.
Show resolved Hide resolved
});
}
10 changes: 10 additions & 0 deletions packages/astro/src/assets/fonts/providers/local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineFontProvider } from '../helpers.js';

export const LOCAL_PROVIDER_NAME = 'local';

export function local() {
return defineFontProvider({
name: LOCAL_PROVIDER_NAME,
entrypoint: 'astro/assets/fonts/providers/google',
});
}
27 changes: 27 additions & 0 deletions packages/astro/src/assets/fonts/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { BUILTIN_PROVIDERS } from './constants.js';
import type { GOOGLE_PROVIDER_NAME } from './providers/google.js';
import type { LOCAL_PROVIDER_NAME } from './providers/local.js';

export interface FontProvider<TName extends string> {
name: TName;
entrypoint: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entrypoint should be a string or a URL. Since v5, all entry points now accept URL too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll address this in the next PR

config?: Record<string, any>;
}

type LocalFontFamily = {
provider: LocalProviderName;
// TODO: refine type
src: string;
};

type StandardFontFamily<TProvider extends string> = {
provider: TProvider;
};

export type FontFamily<TProvider extends string> = TProvider extends LocalProviderName
? LocalFontFamily
: StandardFontFamily<TProvider>;

export type LocalProviderName = typeof LOCAL_PROVIDER_NAME;
export type GoogleProviderName = typeof GOOGLE_PROVIDER_NAME;
export type BuiltInProvider = (typeof BUILTIN_PROVIDERS)[number];
1 change: 1 addition & 0 deletions packages/astro/src/config/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ImageServiceConfig } from '../types/public/index.js';

export { defineConfig, getViteConfig } from './index.js';
export { envField } from '../env/config.js';
export { fontProviders } from '../assets/fonts/providers.js';

/**
* Return the configuration needed to use the Sharp-based image service
Expand Down
7 changes: 6 additions & 1 deletion packages/astro/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
SessionDriverName,
} from '../types/public/config.js';
import { createDevelopmentManifest } from '../vite-plugin-astro-server/plugin.js';
import type { BuiltInProvider, FontFamily, FontProvider } from '../assets/fonts/types.js';

florian-lefebvre marked this conversation as resolved.
Show resolved Hide resolved
/**
* See the full Astro Configuration API Documentation
Expand All @@ -15,7 +16,11 @@ import { createDevelopmentManifest } from '../vite-plugin-astro-server/plugin.js
export function defineConfig<
const TLocales extends Locales = never,
const TDriver extends SessionDriverName = never,
>(config: AstroUserConfig<TLocales, TDriver>) {
const TFontProviders extends FontProvider<string>[] = never,
const TFontFamilies extends FontFamily<
(TFontProviders extends never ? [] : TFontProviders)[number]['name'] | BuiltInProvider
>[] = never,
>(config: AstroUserConfig<TLocales, TDriver, TFontProviders, TFontFamilies>) {
return config;
}

Expand Down
48 changes: 48 additions & 0 deletions packages/astro/src/core/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { SvgRenderMode } from '../../assets/utils/svg.js';
import { EnvSchema } from '../../env/schema.js';
import type { AstroUserConfig, ViteUserConfig } from '../../types/public/config.js';
import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from '../path.js';
import { BUILTIN_PROVIDERS } from '../../assets/fonts/constants.js';

// The below types are required boilerplate to workaround a Zod issue since v3.21.2. Since that version,
// Zod's compiled TypeScript would "simplify" certain values to their base representation, causing references
Expand Down Expand Up @@ -589,6 +590,53 @@ export const AstroConfigSchema = z.object({
}
return svgConfig;
}),
fonts: z
.object({
providers: z
.array(
z
.object({
name: z.string().superRefine((name, ctx) => {
if (BUILTIN_PROVIDERS.includes(name as any)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `"${name}" is a reserved provider name`,
});
}
}),
entrypoint: z.string(),
config: z.record(z.string(), z.any()).optional(),
})
.strict(),
)
.optional(),
families: z.array(
z
.object({
provider: z.string(),
})
.strict(),
),
})
.strict()
.optional()
.superRefine((fonts, ctx) => {
if (!fonts) {
return;
}
const providersNames = [
...BUILTIN_PROVIDERS,
...(fonts.providers ?? []).map((provider) => provider.name),
];
for (const family of fonts.families) {
if (!providersNames.includes(family.provider)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Invalid provider "${family.provider}". Please use of the following: ${providersNames.map((name) => `"${name}"`).join(', ')}`,
});
}
}
}),
})
.strict(
`Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/experimental-flags/ for a list of all current experiments.`,
Expand Down
44 changes: 44 additions & 0 deletions packages/astro/src/types/public/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type { AstroCookieSetOptions } from '../../core/cookies/cookies.js';
import type { Logger, LoggerLevel } from '../../core/logger/core.js';
import type { EnvSchema } from '../../env/schema.js';
import type { AstroIntegration } from './integrations.js';
import type { BuiltInProvider, FontFamily, FontProvider } from '../../assets/fonts/types.js';
export type Locales = (string | { codes: string[]; path: string })[];

type NormalizeLocales<T extends Locales> = {
Expand Down Expand Up @@ -164,6 +165,10 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
*/ export interface AstroUserConfig<
TLocales extends Locales = never,
TSession extends SessionDriverName = never,
TFontProviders extends FontProvider<string>[] = never,
TFontFamilies extends FontFamily<
(TFontProviders extends never ? [] : TFontProviders)[number]['name'] | BuiltInProvider
>[] = never,
> {
/**
* @docs
Expand Down Expand Up @@ -2059,6 +2064,45 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
*/
mode: SvgRenderMode;
};

/**
*
* @name experimental.fonts
* @type {object}
* @default `undefined`
* @version 5.x
* @description
*
* TODO:
*/
fonts?: {
/**
*
* @name experimental.fonts.providers
* @type {FontProvider[]}
* @version 5.x
* @description
*
* TODO:
*/
providers?: [TFontProviders] extends [never] ? FontProvider<string>[] : TFontProviders;

/**
*
* @name experimental.fonts.families
* @type {FontFamily[]}
* @version 5.x
* @description
*
* TODO:
*/
families: [TFontFamilies] extends [never]
? FontFamily<
| ([TFontProviders] extends [never] ? [] : TFontProviders)[number]['name']
| BuiltInProvider
>[]
: TFontFamilies;
};
};
}

Expand Down
Loading
Loading