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

Draft
wants to merge 7 commits into
base: feat/fonts
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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',
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',
});
}
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;
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';

/**
* 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>) {
TFontProviders extends FontProvider<string>[] = never,
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}"`,
});
}
}
}),
})
.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
39 changes: 39 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,40 @@ 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;

/**
*
* @name experimental.fonts.families
* @type {FontFamily[]}
* @version 5.x
* @description
*
* TODO:
*/
families: TFontFamilies;
};
};
}

Expand Down
Loading