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 3 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
1 change: 1 addition & 0 deletions packages/astro/src/assets/fonts/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const BUILTIN_PROVIDERS = ['google', 'local'] 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;
}
16 changes: 16 additions & 0 deletions packages/astro/src/assets/fonts/providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineFontProvider } from './helpers.js';

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

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

export interface FontProvider<TName extends string> {
name: TName;
entrypoint: string;
config?: Record<string, any>;
}

export type FontFamily<TProvider extends string> = {
provider: TProvider;
} & (TProvider extends 'local'
? {
src: any;
}
: // eslint-disable-next-line @typescript-eslint/no-empty-object-type
{});

export type BuiltInProvider = (typeof BUILTIN_PROVIDERS)[number];
16 changes: 15 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 * as _fontProviders from '../assets/fonts/providers.js';

/**
* See the full Astro Configuration API Documentation
Expand All @@ -15,10 +16,23 @@ 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>) {
TFontProvidersName extends string = never,
>(config: AstroUserConfig<TLocales, TDriver, TFontProvidersName>) {
return config;
}

/** TODO: */
export const fontProviders = _fontProviders;

defineConfig({
experimental: {
fonts: {
providers: [fontProviders.adobe({ apiKey: '' }), fontProviders.test()],
families: [{ provider: 'local' }],
},
},
});

/**
* Use Astro to generate a fully resolved Vite 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 @@ -15,6 +15,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 @@ -590,6 +591,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
45 changes: 45 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,7 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
*/ export interface AstroUserConfig<
TLocales extends Locales = never,
TSession extends SessionDriverName = never,
TFontProvidersName extends string = never,
> {
/**
* @docs
Expand Down Expand Up @@ -2059,6 +2061,49 @@ 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:
* TODO: generics
*/
providers?: TFontProvidersName extends never
? FontProvider<string>[]
: FontProvider<TFontProvidersName>[];

/**
*
* @name experimental.fonts.families
* @type {FontFamily[]}
* @version 5.x
* @description
*
* TODO:
* TODO: generics
*/
// proper autocomplete
// families: TFontProvidersName extends never
// works when no providers specified
families: TFontProvidersName extends never
? FontFamily<BuiltInProvider | (string & {})>[]
: FontFamily<BuiltInProvider | NoInfer<TFontProvidersName>>[];
};
};
}

Expand Down
Loading