@escape-game-over/atlas 0.1.47 → 0.1.49
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.
- package/package.json +1 -1
- package/src/astro/Document.astro +11 -1
- package/src/astro/fonts.ts +21 -0
- package/src/astro/index.ts +1 -0
- package/src/astro/site-routes.ts +11 -0
- package/src/config.ts +3 -0
- package/src/fonts.ts +36 -0
- package/src/index.ts +1 -0
- package/src/project.ts +3 -0
- package/src/site/api.ts +3 -0
- package/src/site/create.ts +3 -0
package/package.json
CHANGED
package/src/astro/Document.astro
CHANGED
|
@@ -13,14 +13,19 @@
|
|
|
13
13
|
* A site with a lead form passes `rememberCampaign`, so the `utm_*` tags a
|
|
14
14
|
* visit landed with survive to the page the form is on; see `attribution.ts`.
|
|
15
15
|
*
|
|
16
|
+
* `fonts={site.fonts}` writes the `@font-face` rules and preloads for the
|
|
17
|
+
* faces `siteFonts(site)` registered in the Astro config.
|
|
18
|
+
*
|
|
16
19
|
* ```astro
|
|
17
|
-
* <Document meta={meta} html={{ class: "scroll-smooth" }} body={{ class: "…" }}>
|
|
20
|
+
* <Document meta={meta} fonts={site.fonts} html={{ class: "scroll-smooth" }} body={{ class: "…" }}>
|
|
18
21
|
* <Fragment slot="head"><link rel="preload" … /></Fragment>
|
|
19
22
|
* …page…
|
|
20
23
|
* </Document>
|
|
21
24
|
* ```
|
|
22
25
|
*/
|
|
26
|
+
import { Font } from "astro:assets";
|
|
23
27
|
import type { HTMLAttributes } from "astro/types";
|
|
28
|
+
import type { Fonts } from "../fonts.ts";
|
|
24
29
|
import type { PageMeta } from "../site/index.ts";
|
|
25
30
|
import MetaTags from "./MetaTags.astro";
|
|
26
31
|
import RememberCampaign from "./RememberCampaign.astro";
|
|
@@ -28,6 +33,7 @@ import ScrollRestore from "./ScrollRestore.astro";
|
|
|
28
33
|
|
|
29
34
|
interface Props {
|
|
30
35
|
readonly meta: PageMeta;
|
|
36
|
+
readonly fonts?: Fonts;
|
|
31
37
|
/** `lang` and `dir` are the page's locale's, from `meta`. */
|
|
32
38
|
readonly html?: Omit<HTMLAttributes<"html">, "lang" | "dir">;
|
|
33
39
|
readonly body?: HTMLAttributes<"body">;
|
|
@@ -39,6 +45,7 @@ interface Props {
|
|
|
39
45
|
|
|
40
46
|
const {
|
|
41
47
|
meta,
|
|
48
|
+
fonts = {},
|
|
42
49
|
html,
|
|
43
50
|
body,
|
|
44
51
|
restoreScroll = true,
|
|
@@ -55,6 +62,9 @@ const {
|
|
|
55
62
|
<head>
|
|
56
63
|
<slot name="head-start" />
|
|
57
64
|
<MetaTags tags={meta.tags} />
|
|
65
|
+
{Object.entries(fonts).map(([key, font]) => (
|
|
66
|
+
<Font cssVariable={`--${key}`} preload={font.preload === true} />
|
|
67
|
+
))}
|
|
58
68
|
<slot name="head" />
|
|
59
69
|
</head>
|
|
60
70
|
<body {...body}>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AstroUserConfig } from "astro";
|
|
2
|
+
import { fontProviders } from "astro/config";
|
|
3
|
+
import type { Fonts } from "../fonts.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `site.fonts` as Astro's `fonts` config: `fonts: siteFonts(site)`.
|
|
7
|
+
*
|
|
8
|
+
* `display` defaults to `fallback`, not Astro's `swap`: `swap` paints the
|
|
9
|
+
* fallback for a frame even when the font is cached, so text jumps on reload.
|
|
10
|
+
*/
|
|
11
|
+
export function siteFonts(site: {
|
|
12
|
+
readonly fonts: Fonts;
|
|
13
|
+
}): NonNullable<AstroUserConfig["fonts"]> {
|
|
14
|
+
return Object.entries(site.fonts).map(([key, { preload, ...font }]) => ({
|
|
15
|
+
display: "fallback",
|
|
16
|
+
styles: ["normal"],
|
|
17
|
+
...font,
|
|
18
|
+
provider: fontProviders.google(),
|
|
19
|
+
cssVariable: `--${key}`,
|
|
20
|
+
}));
|
|
21
|
+
}
|
package/src/astro/index.ts
CHANGED
package/src/astro/site-routes.ts
CHANGED
|
@@ -212,6 +212,7 @@ export function siteRoutes(options: SiteRoutesOptions): AstroIntegration {
|
|
|
212
212
|
"astro:config:setup": ({
|
|
213
213
|
config: current,
|
|
214
214
|
updateConfig,
|
|
215
|
+
addWatchFile,
|
|
215
216
|
logger,
|
|
216
217
|
}) => {
|
|
217
218
|
/**
|
|
@@ -290,6 +291,16 @@ export function siteRoutes(options: SiteRoutesOptions): AstroIntegration {
|
|
|
290
291
|
`updated config: ${JSON.stringify(config, null, 2)}`
|
|
291
292
|
);
|
|
292
293
|
reportOrphans();
|
|
294
|
+
|
|
295
|
+
// `atlas use` swaps the project by relinking `config/project`,
|
|
296
|
+
// and nothing Vite watches changes when it does: the files
|
|
297
|
+
// behind the link are new, but every module already loaded
|
|
298
|
+
// through it stays cached, so a running `astro dev` keeps
|
|
299
|
+
// serving the old project — its messages, its routes, a map
|
|
300
|
+
// from one country with the pins of another. Watching the link
|
|
301
|
+
// itself turns the relink into a restart. A project without
|
|
302
|
+
// overlays has no such link, and the watch is simply idle.
|
|
303
|
+
addWatchFile(new URL("config/project", current.root));
|
|
293
304
|
},
|
|
294
305
|
|
|
295
306
|
/**
|
package/src/config.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Fonts } from "./fonts.ts";
|
|
1
2
|
import type { LlmsConfig } from "./llms.ts";
|
|
2
3
|
import type { RobotsConfig } from "./robots.ts";
|
|
3
4
|
import type { SitemapConfig } from "./sitemap.ts";
|
|
@@ -97,6 +98,8 @@ export interface SiteConfigShape {
|
|
|
97
98
|
* reading this file is not enough to know how one deployment's URLs look.
|
|
98
99
|
*/
|
|
99
100
|
readonly defaultRouting: RoutingConfig<string>;
|
|
101
|
+
/** A project's `overrideFonts` adds to these or replaces one by key. */
|
|
102
|
+
readonly defaultFonts?: Fonts;
|
|
100
103
|
readonly sitemap?: SitemapConfig;
|
|
101
104
|
readonly robots?: RobotsConfig;
|
|
102
105
|
/** `false` publishes no `llms.txt`, and no page links to one. */
|
package/src/fonts.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AstroUserConfig } from "astro";
|
|
2
|
+
|
|
3
|
+
type FontFamily = NonNullable<AstroUserConfig["fonts"]>[number];
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* One typeface, self-hosted from Google Fonts. Astro's own family options, less
|
|
7
|
+
* the two atlas fills in: the provider, and the CSS variable (the key).
|
|
8
|
+
*/
|
|
9
|
+
export type Font = Omit<FontFamily, "provider" | "cssVariable"> & {
|
|
10
|
+
/** Preloads its files on every page. */
|
|
11
|
+
readonly preload?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Keyed by the CSS variable the face is exposed as, without the dashes:
|
|
16
|
+
* `raleway` is `--raleway`.
|
|
17
|
+
*/
|
|
18
|
+
export type Fonts = Readonly<Record<string, Font>>;
|
|
19
|
+
|
|
20
|
+
const CSS_IDENT = /^[a-z][a-z0-9-]*$/;
|
|
21
|
+
|
|
22
|
+
/** A project's fonts: new keys are added, a key the site has replaces it. */
|
|
23
|
+
export function mergeFonts(
|
|
24
|
+
base: Fonts | undefined,
|
|
25
|
+
overrides: Fonts | undefined
|
|
26
|
+
): Fonts {
|
|
27
|
+
const merged = { ...base, ...overrides };
|
|
28
|
+
for (const key of Object.keys(merged)) {
|
|
29
|
+
if (!CSS_IDENT.test(key)) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Font key "${key}" must be lowercase kebab-case: it becomes the CSS variable --${key}.`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return merged;
|
|
36
|
+
}
|
package/src/index.ts
CHANGED
package/src/project.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
RoutingConfig,
|
|
7
7
|
SiteConfigShape,
|
|
8
8
|
} from "./config.ts";
|
|
9
|
+
import type { Fonts } from "./fonts.ts";
|
|
9
10
|
import type {
|
|
10
11
|
BaseCatalog,
|
|
11
12
|
OverrideCatalog,
|
|
@@ -108,6 +109,8 @@ export interface ProjectInput<L extends string, Routes> {
|
|
|
108
109
|
readonly overrideLocaleMeta?: Readonly<
|
|
109
110
|
Partial<Record<L, LocaleMetaOverride>>
|
|
110
111
|
>;
|
|
112
|
+
/** Adds to the site's `defaultFonts`, or replaces one by key. */
|
|
113
|
+
readonly overrideFonts?: Fonts;
|
|
111
114
|
/**
|
|
112
115
|
* Copy overrides: any subset of keys, any subset of locales.
|
|
113
116
|
*
|
package/src/site/api.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ResolvedLocaleMeta } from "../config.ts";
|
|
|
2
2
|
import type { PlainTextFor, RichTextFor } from "../content/index.ts";
|
|
3
3
|
import type { GeneratedFile } from "../file.ts";
|
|
4
4
|
import type { PublicFilePath } from "../files.ts";
|
|
5
|
+
import type { Fonts } from "../fonts.ts";
|
|
5
6
|
import type { TranslateFor } from "../i18n/translate.ts";
|
|
6
7
|
import type { LlmsSection } from "../llms.ts";
|
|
7
8
|
import type { ThemeColor } from "../meta/index.ts";
|
|
@@ -151,6 +152,8 @@ export interface Site<
|
|
|
151
152
|
*/
|
|
152
153
|
readonly themeColor: ThemeColor;
|
|
153
154
|
readonly localeMeta: Readonly<Record<L, ResolvedLocaleMeta>>;
|
|
155
|
+
/** The site's `defaultFonts` with this project's `overrideFonts` applied. */
|
|
156
|
+
readonly fonts: Fonts;
|
|
154
157
|
/**
|
|
155
158
|
* Every route this project builds, in the order the base registry declares
|
|
156
159
|
* them. Derived — a project never lists these. Build menus by filtering it.
|
package/src/site/create.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "../content/index.ts";
|
|
12
12
|
import type { GeneratedFile } from "../file.ts";
|
|
13
13
|
import type { PublicFilePath } from "../files.ts";
|
|
14
|
+
import { mergeFonts } from "../fonts.ts";
|
|
14
15
|
import { type BaseCatalog, mergeCatalog } from "../i18n/define.ts";
|
|
15
16
|
import { createTranslateFactory } from "../i18n/translate.ts";
|
|
16
17
|
import type { ImageAsset } from "../image.ts";
|
|
@@ -158,6 +159,7 @@ export function createSite<
|
|
|
158
159
|
project.overrideLocaleMeta,
|
|
159
160
|
locales
|
|
160
161
|
);
|
|
162
|
+
const fonts = mergeFonts(config_.defaultFonts, project.overrideFonts);
|
|
161
163
|
const pathContext: PathContext<L> = {
|
|
162
164
|
defaultLocale,
|
|
163
165
|
prefixDefaultLocale,
|
|
@@ -797,6 +799,7 @@ export function createSite<
|
|
|
797
799
|
siteName: project.siteName,
|
|
798
800
|
themeColor: project.themeColor,
|
|
799
801
|
localeMeta,
|
|
802
|
+
fonts,
|
|
800
803
|
routes: enabledRouteIds,
|
|
801
804
|
|
|
802
805
|
translate: (locale) => translateFactory(catalog, locale),
|