@geekity/cms 0.40.0 → 0.42.0
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/admin/components/blocks.njk +15 -1
- package/admin/pages/appearance/look.njk +135 -0
- package/admin/pages/dashboard/home.njk +9 -3
- package/admin/pages/documents/conflict.njk +35 -10
- package/admin/pages/documents/editor.njk +29 -0
- package/admin/pages/documents/list.njk +44 -1
- package/admin/pages/settings/general.njk +4 -0
- package/admin/pages/settings/reading.njk +14 -0
- package/admin/pages/users/edit.njk +1 -1
- package/admin/pages/users/writing-goals.njk +64 -0
- package/admin/src/admin.css +32 -0
- package/admin/static/admin.css +202 -4
- package/admin/static/dashboard.js +51 -23
- package/admin/static/editor.js +22 -19
- package/dist/access-log.d.ts +3 -0
- package/dist/access-log.d.ts.map +1 -1
- package/dist/access-log.js +13 -9
- package/dist/access-log.js.map +1 -1
- package/dist/admin/autosave-client.d.ts +85 -0
- package/dist/admin/autosave-client.d.ts.map +1 -0
- package/dist/admin/autosave-client.js +218 -0
- package/dist/admin/autosave-client.js.map +1 -0
- package/dist/admin/autosave.d.ts +12 -0
- package/dist/admin/autosave.d.ts.map +1 -0
- package/dist/admin/autosave.js +92 -0
- package/dist/admin/autosave.js.map +1 -0
- package/dist/admin/blocks.d.ts +13 -1
- package/dist/admin/blocks.d.ts.map +1 -1
- package/dist/admin/blocks.js +40 -5
- package/dist/admin/blocks.js.map +1 -1
- package/dist/admin/core-widgets.d.ts.map +1 -1
- package/dist/admin/core-widgets.js +2 -0
- package/dist/admin/core-widgets.js.map +1 -1
- package/dist/admin/dashboard.d.ts +2 -2
- package/dist/admin/dashboard.d.ts.map +1 -1
- package/dist/admin/dashboard.js +23 -15
- package/dist/admin/dashboard.js.map +1 -1
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +223 -16
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/editor-word-counter.d.ts +8 -0
- package/dist/admin/editor-word-counter.d.ts.map +1 -0
- package/dist/admin/editor-word-counter.js +27 -0
- package/dist/admin/editor-word-counter.js.map +1 -0
- package/dist/admin/editor-words.d.ts +7 -0
- package/dist/admin/editor-words.d.ts.map +1 -0
- package/dist/admin/editor-words.js +9 -0
- package/dist/admin/editor-words.js.map +1 -0
- package/dist/admin/flash.d.ts +2 -0
- package/dist/admin/flash.d.ts.map +1 -1
- package/dist/admin/flash.js +12 -0
- package/dist/admin/flash.js.map +1 -1
- package/dist/admin/focus-mode.d.ts +37 -0
- package/dist/admin/focus-mode.d.ts.map +1 -0
- package/dist/admin/focus-mode.js +71 -0
- package/dist/admin/focus-mode.js.map +1 -0
- package/dist/admin/look.d.ts +12 -0
- package/dist/admin/look.d.ts.map +1 -0
- package/dist/admin/look.js +179 -0
- package/dist/admin/look.js.map +1 -0
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +7 -3
- package/dist/admin/menu.js.map +1 -1
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +1 -0
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +8 -4
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/settings-fields.d.ts +1 -1
- package/dist/admin/settings-fields.d.ts.map +1 -1
- package/dist/admin/settings-fields.js +2 -0
- package/dist/admin/settings-fields.js.map +1 -1
- package/dist/admin/settings-general.d.ts.map +1 -1
- package/dist/admin/settings-general.js +1 -0
- package/dist/admin/settings-general.js.map +1 -1
- package/dist/admin/settings-reading.d.ts.map +1 -1
- package/dist/admin/settings-reading.js +7 -1
- package/dist/admin/settings-reading.js.map +1 -1
- package/dist/admin/templates.d.ts +2 -0
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +2 -0
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +4 -0
- package/dist/admin/users.js.map +1 -1
- package/dist/admin/widget-writing.d.ts +3 -0
- package/dist/admin/widget-writing.d.ts.map +1 -0
- package/dist/admin/widget-writing.js +102 -0
- package/dist/admin/widget-writing.js.map +1 -0
- package/dist/admin/widgets.d.ts +4 -1
- package/dist/admin/widgets.d.ts.map +1 -1
- package/dist/admin/widgets.js +19 -8
- package/dist/admin/widgets.js.map +1 -1
- package/dist/admin/writing-goals.d.ts +33 -0
- package/dist/admin/writing-goals.d.ts.map +1 -0
- package/dist/admin/writing-goals.js +149 -0
- package/dist/admin/writing-goals.js.map +1 -0
- package/dist/autosave/index.d.ts +5 -0
- package/dist/autosave/index.d.ts.map +1 -0
- package/dist/autosave/index.js +3 -0
- package/dist/autosave/index.js.map +1 -0
- package/dist/autosave/key.d.ts +13 -0
- package/dist/autosave/key.d.ts.map +1 -0
- package/dist/autosave/key.js +29 -0
- package/dist/autosave/key.js.map +1 -0
- package/dist/autosave/store.d.ts +23 -0
- package/dist/autosave/store.d.ts.map +1 -0
- package/dist/autosave/store.js +114 -0
- package/dist/autosave/store.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +65 -4
- package/dist/cli.js.map +1 -1
- package/dist/cms/app.d.ts.map +1 -1
- package/dist/cms/app.js +1 -0
- package/dist/cms/app.js.map +1 -1
- package/dist/cms/boot.d.ts.map +1 -1
- package/dist/cms/boot.js +2 -0
- package/dist/cms/boot.js.map +1 -1
- package/dist/cms/create.d.ts +11 -2
- package/dist/cms/create.d.ts.map +1 -1
- package/dist/cms/create.js +61 -2
- package/dist/cms/create.js.map +1 -1
- package/dist/cms/server-error.d.ts.map +1 -1
- package/dist/cms/server-error.js +1 -0
- package/dist/cms/server-error.js.map +1 -1
- package/dist/cms/services.d.ts +2 -0
- package/dist/cms/services.d.ts.map +1 -1
- package/dist/cms/services.js +14 -0
- package/dist/cms/services.js.map +1 -1
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -2
- package/dist/config.js.map +1 -1
- package/dist/content/post-type.d.ts +1 -0
- package/dist/content/post-type.d.ts.map +1 -1
- package/dist/content/post-type.js +1 -1
- package/dist/content/post-type.js.map +1 -1
- package/dist/content/words.d.ts +3 -0
- package/dist/content/words.d.ts.map +1 -0
- package/dist/content/words.js +120 -0
- package/dist/content/words.js.map +1 -0
- package/dist/content/write.d.ts +8 -0
- package/dist/content/write.d.ts.map +1 -1
- package/dist/content/write.js +1 -1
- package/dist/content/write.js.map +1 -1
- package/dist/files/data-files.d.ts +5 -0
- package/dist/files/data-files.d.ts.map +1 -1
- package/dist/files/data-files.js +30 -0
- package/dist/files/data-files.js.map +1 -1
- package/dist/fonts/css.d.ts +25 -0
- package/dist/fonts/css.d.ts.map +1 -0
- package/dist/fonts/css.js +88 -0
- package/dist/fonts/css.js.map +1 -0
- package/dist/fonts/family.d.ts +23 -0
- package/dist/fonts/family.d.ts.map +1 -0
- package/dist/fonts/family.js +41 -0
- package/dist/fonts/family.js.map +1 -0
- package/dist/fonts/index.d.ts +10 -0
- package/dist/fonts/index.d.ts.map +1 -0
- package/dist/fonts/index.js +6 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/fonts/job.d.ts +20 -0
- package/dist/fonts/job.d.ts.map +1 -0
- package/dist/fonts/job.js +49 -0
- package/dist/fonts/job.js.map +1 -0
- package/dist/fonts/roles.d.ts +53 -0
- package/dist/fonts/roles.d.ts.map +1 -0
- package/dist/fonts/roles.js +64 -0
- package/dist/fonts/roles.js.map +1 -0
- package/dist/fonts/store.d.ts +69 -0
- package/dist/fonts/store.d.ts.map +1 -0
- package/dist/fonts/store.js +237 -0
- package/dist/fonts/store.js.map +1 -0
- package/dist/gemini/capsule.d.ts +4 -0
- package/dist/gemini/capsule.d.ts.map +1 -0
- package/dist/gemini/capsule.js +9 -0
- package/dist/gemini/capsule.js.map +1 -0
- package/dist/gemini/certificate.d.ts +34 -0
- package/dist/gemini/certificate.d.ts.map +1 -0
- package/dist/gemini/certificate.js +255 -0
- package/dist/gemini/certificate.js.map +1 -0
- package/dist/gemini/site-certificate.d.ts +8 -0
- package/dist/gemini/site-certificate.d.ts.map +1 -0
- package/dist/gemini/site-certificate.js +17 -0
- package/dist/gemini/site-certificate.js.map +1 -0
- package/dist/micropub/endpoint.d.ts.map +1 -1
- package/dist/micropub/endpoint.js +12 -0
- package/dist/micropub/endpoint.js.map +1 -1
- package/dist/plugin.d.ts +15 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/settings/registry.d.ts.map +1 -1
- package/dist/settings/registry.js +5 -1
- package/dist/settings/registry.js.map +1 -1
- package/dist/settings/types.d.ts +1 -1
- package/dist/settings/types.d.ts.map +1 -1
- package/dist/site/dashboard-layout.d.ts +33 -26
- package/dist/site/dashboard-layout.d.ts.map +1 -1
- package/dist/site/dashboard-layout.js +94 -39
- package/dist/site/dashboard-layout.js.map +1 -1
- package/dist/site/namespace.d.ts +6 -0
- package/dist/site/namespace.d.ts.map +1 -1
- package/dist/site/namespace.js +46 -1
- package/dist/site/namespace.js.map +1 -1
- package/dist/site/users.d.ts +7 -0
- package/dist/site/users.d.ts.map +1 -1
- package/dist/site/users.js +7 -0
- package/dist/site/users.js.map +1 -1
- package/dist/site/writing-goals.d.ts +22 -0
- package/dist/site/writing-goals.d.ts.map +1 -0
- package/dist/site/writing-goals.js +42 -0
- package/dist/site/writing-goals.js.map +1 -0
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +4 -0
- package/dist/store/schema.js.map +1 -1
- package/dist/store/sessions.d.ts +2 -1
- package/dist/store/sessions.d.ts.map +1 -1
- package/dist/store/sessions.js +30 -12
- package/dist/store/sessions.js.map +1 -1
- package/dist/theme/font-family.d.ts +13 -0
- package/dist/theme/font-family.d.ts.map +1 -0
- package/dist/theme/font-family.js +21 -0
- package/dist/theme/font-family.js.map +1 -0
- package/dist/theme/scheme-tokens.d.ts +50 -0
- package/dist/theme/scheme-tokens.d.ts.map +1 -0
- package/dist/theme/scheme-tokens.js +240 -0
- package/dist/theme/scheme-tokens.js.map +1 -0
- package/dist/theme/site-data.d.ts +12 -0
- package/dist/theme/site-data.d.ts.map +1 -1
- package/dist/theme/site-data.js +15 -0
- package/dist/theme/site-data.js.map +1 -1
- package/dist/theme/themes.d.ts +74 -0
- package/dist/theme/themes.d.ts.map +1 -1
- package/dist/theme/themes.js +100 -9
- package/dist/theme/themes.js.map +1 -1
- package/dist/util/public-address.d.ts +1 -0
- package/dist/util/public-address.d.ts.map +1 -1
- package/dist/util/public-address.js +38 -30
- package/dist/util/public-address.js.map +1 -1
- package/dist/web/access-line.d.ts +2 -0
- package/dist/web/access-line.d.ts.map +1 -0
- package/dist/web/access-line.js +6 -0
- package/dist/web/access-line.js.map +1 -0
- package/dist/web/document-page.d.ts.map +1 -1
- package/dist/web/document-page.js +3 -4
- package/dist/web/document-page.js.map +1 -1
- package/dist/web/embed.d.ts.map +1 -1
- package/dist/web/embed.js +2 -1
- package/dist/web/embed.js.map +1 -1
- package/dist/web/env.d.ts +2 -0
- package/dist/web/env.d.ts.map +1 -1
- package/dist/web/feed-routes.d.ts.map +1 -1
- package/dist/web/feed-routes.js +4 -4
- package/dist/web/feed-routes.js.map +1 -1
- package/dist/web/feed-source.d.ts +1 -1
- package/dist/web/feed-source.d.ts.map +1 -1
- package/dist/web/feed-source.js +1 -1
- package/dist/web/feed-source.js.map +1 -1
- package/dist/web/font-routes.d.ts +13 -0
- package/dist/web/font-routes.d.ts.map +1 -0
- package/dist/web/font-routes.js +27 -0
- package/dist/web/font-routes.js.map +1 -0
- package/dist/web/gemini-listener.d.ts +30 -0
- package/dist/web/gemini-listener.d.ts.map +1 -0
- package/dist/web/gemini-listener.js +186 -0
- package/dist/web/gemini-listener.js.map +1 -0
- package/dist/web/gemini-request.d.ts +23 -0
- package/dist/web/gemini-request.d.ts.map +1 -0
- package/dist/web/gemini-request.js +127 -0
- package/dist/web/gemini-request.js.map +1 -0
- package/dist/web/listing-pages.d.ts.map +1 -1
- package/dist/web/listing-pages.js +7 -5
- package/dist/web/listing-pages.js.map +1 -1
- package/dist/web/llms.d.ts +1 -0
- package/dist/web/llms.d.ts.map +1 -1
- package/dist/web/llms.js +3 -0
- package/dist/web/llms.js.map +1 -1
- package/dist/web/maintenance.d.ts.map +1 -1
- package/dist/web/maintenance.js +6 -2
- package/dist/web/maintenance.js.map +1 -1
- package/dist/web/manifest.d.ts +8 -5
- package/dist/web/manifest.d.ts.map +1 -1
- package/dist/web/manifest.js +10 -7
- package/dist/web/manifest.js.map +1 -1
- package/dist/web/markdown-representation.d.ts +11 -20
- package/dist/web/markdown-representation.d.ts.map +1 -1
- package/dist/web/markdown-representation.js +57 -58
- package/dist/web/markdown-representation.js.map +1 -1
- package/dist/web/negotiate.d.ts +4 -16
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +23 -18
- package/dist/web/negotiate.js.map +1 -1
- package/dist/web/oembed.d.ts +17 -3
- package/dist/web/oembed.d.ts.map +1 -1
- package/dist/web/oembed.js +68 -26
- package/dist/web/oembed.js.map +1 -1
- package/dist/web/proxy-protocol.d.ts +13 -0
- package/dist/web/proxy-protocol.d.ts.map +1 -0
- package/dist/web/proxy-protocol.js +79 -0
- package/dist/web/proxy-protocol.js.map +1 -0
- package/dist/web/render.d.ts +52 -22
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +94 -30
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +7 -8
- package/dist/web/routes.js.map +1 -1
- package/dist/web/site-index.d.ts.map +1 -1
- package/dist/web/site-index.js +6 -2
- package/dist/web/site-index.js.map +1 -1
- package/dist/web/status-pages.d.ts +2 -3
- package/dist/web/status-pages.d.ts.map +1 -1
- package/dist/web/status-pages.js +14 -11
- package/dist/web/status-pages.js.map +1 -1
- package/dist/web/throttle.d.ts +9 -0
- package/dist/web/throttle.d.ts.map +1 -1
- package/dist/web/throttle.js +17 -0
- package/dist/web/throttle.js.map +1 -1
- package/dist/webmention/fetch-public.d.ts +6 -0
- package/dist/webmention/fetch-public.d.ts.map +1 -1
- package/dist/webmention/fetch-public.js +6 -1
- package/dist/webmention/fetch-public.js.map +1 -1
- package/dist/writing/ledger.d.ts +15 -0
- package/dist/writing/ledger.d.ts.map +1 -0
- package/dist/writing/ledger.js +70 -0
- package/dist/writing/ledger.js.map +1 -0
- package/dist/writing/progress.d.ts +25 -0
- package/dist/writing/progress.d.ts.map +1 -0
- package/dist/writing/progress.js +83 -0
- package/dist/writing/progress.js.map +1 -0
- package/package.json +2 -1
- package/themes/default/layouts/404.gmi.njk +10 -0
- package/themes/default/layouts/410.gmi.njk +8 -0
- package/themes/default/layouts/500.gmi.njk +9 -0
- package/themes/default/layouts/503.gmi.njk +9 -0
- package/themes/default/layouts/base.njk +31 -16
- package/themes/default/layouts/page.njk +4 -8
- package/themes/default/partials/bio.njk +1 -1
- package/themes/default/partials/contact-form.njk +1 -1
- package/themes/default/partials/markdown-footer.md.njk +9 -1
- package/themes/default/src/style.css +326 -15
- package/themes/default/static/style.css +489 -3
- package/themes/default/theme.json +23 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CssFontStack } from '../theme/font-family.ts';
|
|
2
|
+
import type { ThemeFont } from '../theme/themes.ts';
|
|
3
|
+
import type { FontStyle } from './family.ts';
|
|
4
|
+
import type { FontStore } from './store.ts';
|
|
5
|
+
export declare const FONT_ROLES: readonly [{
|
|
6
|
+
readonly role: 'heading';
|
|
7
|
+
readonly setting: 'heading_font';
|
|
8
|
+
readonly fileKey: 'headingFont';
|
|
9
|
+
readonly styles: readonly [{
|
|
10
|
+
readonly weight: 700;
|
|
11
|
+
readonly italic: false;
|
|
12
|
+
}];
|
|
13
|
+
}, {
|
|
14
|
+
readonly role: 'body';
|
|
15
|
+
readonly setting: 'body_font';
|
|
16
|
+
readonly fileKey: 'bodyFont';
|
|
17
|
+
readonly styles: readonly [{
|
|
18
|
+
readonly weight: 400;
|
|
19
|
+
readonly italic: false;
|
|
20
|
+
}, {
|
|
21
|
+
readonly weight: 400;
|
|
22
|
+
readonly italic: true;
|
|
23
|
+
}, {
|
|
24
|
+
readonly weight: 700;
|
|
25
|
+
readonly italic: false;
|
|
26
|
+
}];
|
|
27
|
+
}];
|
|
28
|
+
export type FontRole = (typeof FONT_ROLES)[number];
|
|
29
|
+
export interface PageFont {
|
|
30
|
+
readonly font: ThemeFont;
|
|
31
|
+
readonly family: string;
|
|
32
|
+
/** The hosted `@font-face` stylesheet, same-origin and fingerprinted. */
|
|
33
|
+
readonly href: string;
|
|
34
|
+
/** What the role's custom property is set to: the family, then the theme's stack. */
|
|
35
|
+
readonly value: CssFontStack;
|
|
36
|
+
}
|
|
37
|
+
/** The roles the theme declares that the site can set a font for, in {@link FONT_ROLES} order. */
|
|
38
|
+
export declare function declaredFontRoles(declared: readonly ThemeFont[]): {
|
|
39
|
+
readonly font: ThemeFont;
|
|
40
|
+
readonly role: FontRole;
|
|
41
|
+
}[];
|
|
42
|
+
export interface PageFontsOptions {
|
|
43
|
+
readonly store: FontStore;
|
|
44
|
+
readonly refetch: (family: string, styles: readonly FontStyle[]) => Promise<unknown>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The fonts a page is set in: each role the theme declares whose family the
|
|
48
|
+
* site chose and whose files are here. A family whose files are gone is left
|
|
49
|
+
* out, so the page falls back to the theme's stack, and a fetch of it is
|
|
50
|
+
* queued once until its files are back.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createPageFonts(options: PageFontsOptions): (site: Readonly<Record<string, unknown>>, declared: readonly ThemeFont[]) => PageFont[];
|
|
53
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/fonts/roles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,UAAU;mBAEb,SAAS;sBACN,cAAc;sBACd,aAAa;;yBACH,GAAG;;;;mBAGhB,MAAM;sBACH,WAAW;sBACX,UAAU;;yBAEP,GAAG;;;yBACH,GAAG;;;yBACH,GAAG;;;EAQhB,CAAC;AAEJ,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC9B;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,SAAS,EAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,EAAE,CAKzD;AAYD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACtF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,gBAAgB,GACxB,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,SAAS,EAAE,KAAK,QAAQ,EAAE,CAyBzF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { cssFontStackWith, isFontFamilyName } from '../theme/font-family.js';
|
|
2
|
+
export const FONT_ROLES = [
|
|
3
|
+
{
|
|
4
|
+
role: 'heading',
|
|
5
|
+
setting: 'heading_font',
|
|
6
|
+
fileKey: 'headingFont',
|
|
7
|
+
styles: [{ weight: 700, italic: false }],
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
role: 'body',
|
|
11
|
+
setting: 'body_font',
|
|
12
|
+
fileKey: 'bodyFont',
|
|
13
|
+
styles: [
|
|
14
|
+
{ weight: 400, italic: false },
|
|
15
|
+
{ weight: 400, italic: true },
|
|
16
|
+
{ weight: 700, italic: false },
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
/** The roles the theme declares that the site can set a font for, in {@link FONT_ROLES} order. */
|
|
21
|
+
export function declaredFontRoles(declared) {
|
|
22
|
+
return FONT_ROLES.flatMap((role) => {
|
|
23
|
+
const font = declared.find((each) => each.role === role.role);
|
|
24
|
+
return font === undefined ? [] : [{ font, role }];
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function chosenFonts(site, declared) {
|
|
28
|
+
return declaredFontRoles(declared).map(({ font, role }) => {
|
|
29
|
+
const named = site[role.fileKey];
|
|
30
|
+
return { font, role, family: typeof named === 'string' ? named.trim() : '' };
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The fonts a page is set in: each role the theme declares whose family the
|
|
35
|
+
* site chose and whose files are here. A family whose files are gone is left
|
|
36
|
+
* out, so the page falls back to the theme's stack, and a fetch of it is
|
|
37
|
+
* queued once until its files are back.
|
|
38
|
+
*/
|
|
39
|
+
export function createPageFonts(options) {
|
|
40
|
+
const { store, refetch } = options;
|
|
41
|
+
const queued = new Set();
|
|
42
|
+
return (site, declared) => chosenFonts(site, declared).flatMap(({ font, role, family }) => {
|
|
43
|
+
if (!isFontFamilyName(family))
|
|
44
|
+
return [];
|
|
45
|
+
const key = `${family}\n${role.role}`;
|
|
46
|
+
const stylesheet = store.stylesheet(family, role.styles);
|
|
47
|
+
if (stylesheet === undefined) {
|
|
48
|
+
if (!queued.has(key)) {
|
|
49
|
+
queued.add(key);
|
|
50
|
+
refetch(family, role.styles).catch((thrown) => {
|
|
51
|
+
queued.delete(key);
|
|
52
|
+
console.warn(`No fetch of the font ${family} was queued: ${String(thrown)}`);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
queued.delete(key);
|
|
58
|
+
const value = cssFontStackWith(stylesheet.family, font.fallback);
|
|
59
|
+
return value === undefined
|
|
60
|
+
? []
|
|
61
|
+
: [{ font, family: stylesheet.family, href: stylesheet.href, value }];
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/fonts/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,cAAc;QACvB,OAAO,EAAE,aAAa;QACtB,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;KACzC;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE,UAAU;QACnB,MAAM,EAAE;YACN,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;YAC9B,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;YAC7B,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;SAC/B;KACF;CAMA,CAAC;AAaJ,kGAAkG;AAClG,MAAM,UAAU,iBAAiB,CAC/B,QAA8B;IAE9B,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAClB,IAAuC,EACvC,QAA8B;IAE9B,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC;AAOD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAyB;IAEzB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7D,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,GAAG,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAChB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,MAAe,EAAE,EAAE;oBACrD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,wBAAwB,MAAM,gBAAgB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC/E,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnB,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjE,OAAO,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { StaticAsset } from '../files/static-files.ts';
|
|
2
|
+
import type { HostLookup } from '../util/public-address.ts';
|
|
3
|
+
import type { FontStyle } from './family.ts';
|
|
4
|
+
export declare const FONT_PATH_PREFIX = "/_geekity/fonts/";
|
|
5
|
+
/**
|
|
6
|
+
* The CSS2 API answers each browser with what it can use. A current desktop
|
|
7
|
+
* Chrome is answered with WOFF2 files split into unicode-range subsets.
|
|
8
|
+
*/
|
|
9
|
+
export declare const FONT_FETCH_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
10
|
+
/** How long one request to Google is given, body included. */
|
|
11
|
+
export declare const FONT_FETCH_TIMEOUT_MS = 15000;
|
|
12
|
+
/** Why a family was not fetched. `message` is a sentence for the person who chose it. */
|
|
13
|
+
export type FontRefusal = {
|
|
14
|
+
readonly kind: 'invalid-name';
|
|
15
|
+
readonly family: string;
|
|
16
|
+
readonly message: string;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'unknown-family';
|
|
19
|
+
readonly family: string;
|
|
20
|
+
readonly message: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly kind: 'missing-styles';
|
|
23
|
+
readonly family: string;
|
|
24
|
+
readonly styles: readonly FontStyle[];
|
|
25
|
+
readonly message: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'unavailable';
|
|
28
|
+
readonly family: string;
|
|
29
|
+
readonly message: string;
|
|
30
|
+
};
|
|
31
|
+
export interface FontStylesheet {
|
|
32
|
+
/** Same-origin, with `?v=` the hash of its bytes, so it can be cached for a year. */
|
|
33
|
+
readonly href: string;
|
|
34
|
+
readonly family: string;
|
|
35
|
+
}
|
|
36
|
+
export type FontFetch = {
|
|
37
|
+
readonly ok: true;
|
|
38
|
+
readonly stylesheet: FontStylesheet;
|
|
39
|
+
/** Whether Google was asked: false when every file was already here. */
|
|
40
|
+
readonly fetched: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
readonly ok: false;
|
|
43
|
+
readonly refusal: FontRefusal;
|
|
44
|
+
};
|
|
45
|
+
export interface CreateFontStoreOptions {
|
|
46
|
+
readonly dataDir: string;
|
|
47
|
+
readonly hostLookup: HostLookup;
|
|
48
|
+
}
|
|
49
|
+
export interface FontStore {
|
|
50
|
+
/**
|
|
51
|
+
* Make sure the family is here in these styles: nothing to do when its
|
|
52
|
+
* stylesheet and every file it names are on disk, else fetch it. A family
|
|
53
|
+
* or style Google lacks is a refusal, and nothing is written. Two calls for
|
|
54
|
+
* the same family and styles at once share one fetch.
|
|
55
|
+
*/
|
|
56
|
+
ensure(family: string, styles: readonly FontStyle[], signal?: AbortSignal): Promise<FontFetch>;
|
|
57
|
+
/**
|
|
58
|
+
* The stylesheet to link for the family in these styles, or `undefined`
|
|
59
|
+
* when it has not been fetched or a file it names is gone. Synchronous, for
|
|
60
|
+
* a page render: it costs a `stat` while the stylesheet is unchanged.
|
|
61
|
+
*/
|
|
62
|
+
stylesheet(family: string, styles: readonly FontStyle[]): FontStylesheet | undefined;
|
|
63
|
+
/** A file the store wrote, for the font route, or `undefined` for any other name. */
|
|
64
|
+
file(slug: string, name: string): StaticAsset | undefined;
|
|
65
|
+
/** Resolve once every fetch in flight has finished. */
|
|
66
|
+
settled(): Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
export declare function createFontStore(options: CreateFontStoreOptions): FontStore;
|
|
69
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/fonts/store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAc5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,oHACiF,CAAC;AAEpH,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAY5C,yFAAyF;AACzF,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtF;IACE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExF,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,SAAS,GACjB;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAED,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/F;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,cAAc,GAAG,SAAS,CAAC;IACrF,qFAAqF;IACrF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAC1D,uDAAuD;IACvD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAkI1E"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { writeFileAtomically } from '../files/atomic.js';
|
|
5
|
+
import { FONTS, dataFolder, dataPath } from '../files/data-files.js';
|
|
6
|
+
import { findAsset } from '../files/static-files.js';
|
|
7
|
+
import { assetVersion } from '../theme/assets.js';
|
|
8
|
+
import { fetchPublic } from '../webmention/fetch-public.js';
|
|
9
|
+
import { isFontFamilyName } from '../theme/font-family.js';
|
|
10
|
+
import { faceRule, isFontFileUrl, parseGoogleCss } from './css.js';
|
|
11
|
+
import { CSS2_ORIGIN, canonicalStyles, css2Url, fontFamilySlug, isFontStyle, styleKey, styleLabel, } from './family.js';
|
|
12
|
+
export const FONT_PATH_PREFIX = '/_geekity/fonts/';
|
|
13
|
+
/**
|
|
14
|
+
* The CSS2 API answers each browser with what it can use. A current desktop
|
|
15
|
+
* Chrome is answered with WOFF2 files split into unicode-range subsets.
|
|
16
|
+
*/
|
|
17
|
+
export const FONT_FETCH_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';
|
|
18
|
+
/** How long one request to Google is given, body included. */
|
|
19
|
+
export const FONT_FETCH_TIMEOUT_MS = 15_000;
|
|
20
|
+
const CSS_MAX_BYTES = 1_000_000;
|
|
21
|
+
const FILE_MAX_BYTES = 5_000_000;
|
|
22
|
+
const FAMILY_MAX_BYTES = 64_000_000;
|
|
23
|
+
const MAX_FILES = 1_000;
|
|
24
|
+
const PARALLEL_DOWNLOADS = 6;
|
|
25
|
+
const FILE_NAME = /^[0-9a-f]{12}\.woff2$/;
|
|
26
|
+
const STYLESHEET_NAME = /^\d{3}i?(?:-\d{3}i?)*\.css$/;
|
|
27
|
+
const SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
28
|
+
export function createFontStore(options) {
|
|
29
|
+
const { dataDir, hostLookup } = options;
|
|
30
|
+
const inFlight = new Map();
|
|
31
|
+
const known = new Map();
|
|
32
|
+
function stylesheetName(styles) {
|
|
33
|
+
return `${styles.map(styleKey).join('-')}.css`;
|
|
34
|
+
}
|
|
35
|
+
function folderOf(slug) {
|
|
36
|
+
return path.join(dataFolder(dataDir, FONTS), slug);
|
|
37
|
+
}
|
|
38
|
+
function present(slug, name, fresh) {
|
|
39
|
+
const asset = findAsset(name, [folderOf(slug)]);
|
|
40
|
+
if (asset === undefined)
|
|
41
|
+
return undefined;
|
|
42
|
+
const memo = known.get(asset.file);
|
|
43
|
+
if (!fresh && memo?.etag === asset.etag)
|
|
44
|
+
return memo.stylesheet;
|
|
45
|
+
const css = readFileSync(asset.file, 'utf8');
|
|
46
|
+
const family = /font-family: '([^']*)'/.exec(css)?.[1];
|
|
47
|
+
const prefix = `${FONT_PATH_PREFIX}${slug}/`;
|
|
48
|
+
const files = [...css.matchAll(/url\(([^)]*)\)/g)].map(([, href = '']) => href.startsWith(prefix) ? href.slice(prefix.length) : '');
|
|
49
|
+
const whole = family !== undefined &&
|
|
50
|
+
files.length > 0 &&
|
|
51
|
+
files.every((file) => FILE_NAME.test(file) && existsSync(dataPath(dataDir, FONTS, slug, file)));
|
|
52
|
+
const stylesheet = whole
|
|
53
|
+
? { href: `${prefix}${name}?v=${assetVersion(asset)}`, family }
|
|
54
|
+
: undefined;
|
|
55
|
+
known.set(asset.file, { etag: asset.etag, stylesheet });
|
|
56
|
+
return stylesheet;
|
|
57
|
+
}
|
|
58
|
+
async function fetchFamily(family, styles, signal) {
|
|
59
|
+
const slug = fontFamilySlug(family);
|
|
60
|
+
const name = stylesheetName(styles);
|
|
61
|
+
const held = present(slug, name, true);
|
|
62
|
+
if (held !== undefined)
|
|
63
|
+
return { ok: true, stylesheet: held, fetched: false };
|
|
64
|
+
const refuse = (message) => ({
|
|
65
|
+
ok: false,
|
|
66
|
+
refusal: {
|
|
67
|
+
kind: 'unavailable',
|
|
68
|
+
family,
|
|
69
|
+
message: `${family} could not be fetched from Google Fonts: ${message}.`,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
const css = await fetchCss(css2Url(family, styles), hostLookup, signal);
|
|
73
|
+
if (css.kind === 'missing')
|
|
74
|
+
return { ok: false, refusal: await whatIsMissing(family, styles, hostLookup, signal) };
|
|
75
|
+
if (css.kind === 'unavailable')
|
|
76
|
+
return refuse(css.reason);
|
|
77
|
+
const parsed = parseGoogleCss(css.text);
|
|
78
|
+
if (!parsed.ok)
|
|
79
|
+
return refuse(parsed.reason);
|
|
80
|
+
const lacking = styles.filter((style) => !parsed.faces.some((face) => styleKey(face.style) === styleKey(style)));
|
|
81
|
+
if (lacking.length > 0)
|
|
82
|
+
return { ok: false, refusal: missingStyles(family, lacking) };
|
|
83
|
+
if (parsed.faces.length > MAX_FILES)
|
|
84
|
+
return refuse(`it lists more than ${String(MAX_FILES)} files`);
|
|
85
|
+
const downloaded = await downloadAll(parsed.faces, hostLookup, signal);
|
|
86
|
+
if (!downloaded.ok)
|
|
87
|
+
return refuse(downloaded.reason);
|
|
88
|
+
const rules = [];
|
|
89
|
+
for (const face of parsed.faces) {
|
|
90
|
+
const bytes = downloaded.files.get(face.src);
|
|
91
|
+
if (bytes === undefined)
|
|
92
|
+
return refuse(`${face.src} was not downloaded`);
|
|
93
|
+
const file = `${createHash('sha256').update(bytes).digest('hex').slice(0, 12)}.woff2`;
|
|
94
|
+
const target = dataPath(dataDir, FONTS, slug, file);
|
|
95
|
+
if (!existsSync(target))
|
|
96
|
+
await writeFileAtomically(target, bytes);
|
|
97
|
+
rules.push(faceRule(face, `${FONT_PATH_PREFIX}${slug}/${file}`));
|
|
98
|
+
}
|
|
99
|
+
await writeFileAtomically(dataPath(dataDir, FONTS, slug, name), rules.join('\n'));
|
|
100
|
+
const written = present(slug, name, true);
|
|
101
|
+
if (written === undefined)
|
|
102
|
+
return refuse('its files were not all written');
|
|
103
|
+
return { ok: true, stylesheet: written, fetched: true };
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
ensure(family, styles, signal) {
|
|
107
|
+
if (!isFontFamilyName(family)) {
|
|
108
|
+
return Promise.resolve({
|
|
109
|
+
ok: false,
|
|
110
|
+
refusal: {
|
|
111
|
+
kind: 'invalid-name',
|
|
112
|
+
family,
|
|
113
|
+
message: `${JSON.stringify(family)} is not a Google Fonts family name.`,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const canonical = canonicalStyles(styles);
|
|
118
|
+
if (canonical.length === 0 || !canonical.every(isFontStyle)) {
|
|
119
|
+
throw new Error(`Fetching ${family} needs at least one style of weight 100 to 900.`);
|
|
120
|
+
}
|
|
121
|
+
const key = `${fontFamilySlug(family)}/${stylesheetName(canonical)}`;
|
|
122
|
+
const running = inFlight.get(key);
|
|
123
|
+
if (running !== undefined)
|
|
124
|
+
return running;
|
|
125
|
+
const started = fetchFamily(family, canonical, signal).finally(() => inFlight.delete(key));
|
|
126
|
+
inFlight.set(key, started);
|
|
127
|
+
return started;
|
|
128
|
+
},
|
|
129
|
+
stylesheet(family, styles) {
|
|
130
|
+
if (!isFontFamilyName(family))
|
|
131
|
+
return undefined;
|
|
132
|
+
return present(fontFamilySlug(family), stylesheetName(canonicalStyles(styles)), false);
|
|
133
|
+
},
|
|
134
|
+
file(slug, name) {
|
|
135
|
+
if (!SLUG.test(slug) || !(FILE_NAME.test(name) || STYLESHEET_NAME.test(name))) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
return findAsset(name, [folderOf(slug)]);
|
|
139
|
+
},
|
|
140
|
+
async settled() {
|
|
141
|
+
await Promise.allSettled([...inFlight.values()]);
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function missingStyles(family, styles) {
|
|
146
|
+
return {
|
|
147
|
+
kind: 'missing-styles',
|
|
148
|
+
family,
|
|
149
|
+
styles,
|
|
150
|
+
message: `${family} has no ${styles.map(styleLabel).join(' or ')} on Google Fonts.`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function timeoutSignal(signal) {
|
|
154
|
+
const timeout = AbortSignal.timeout(FONT_FETCH_TIMEOUT_MS);
|
|
155
|
+
return signal === undefined ? timeout : AbortSignal.any([signal, timeout]);
|
|
156
|
+
}
|
|
157
|
+
/** The CSS2 API's answer. Google says 400 for a family or a style it does not have. */
|
|
158
|
+
async function fetchCss(url, lookup, signal) {
|
|
159
|
+
const fetched = await fetchPublic(url, {
|
|
160
|
+
lookup,
|
|
161
|
+
signal: timeoutSignal(signal),
|
|
162
|
+
maxBytes: CSS_MAX_BYTES,
|
|
163
|
+
accept: 'text/css,*/*;q=0.1',
|
|
164
|
+
userAgent: FONT_FETCH_USER_AGENT,
|
|
165
|
+
allowed: (at) => at.origin === CSS2_ORIGIN,
|
|
166
|
+
contentType: { pattern: /^\s*text\/css\s*(;|$)/i, name: 'a stylesheet' },
|
|
167
|
+
});
|
|
168
|
+
if (fetched.ok)
|
|
169
|
+
return { kind: 'css', text: Buffer.from(fetched.body).toString('utf8') };
|
|
170
|
+
if (fetched.status === 400)
|
|
171
|
+
return { kind: 'missing' };
|
|
172
|
+
return { kind: 'unavailable', reason: fetched.reason };
|
|
173
|
+
}
|
|
174
|
+
async function whatIsMissing(family, styles, lookup, signal) {
|
|
175
|
+
const lacking = [];
|
|
176
|
+
for (const style of styles) {
|
|
177
|
+
const answer = await fetchCss(css2Url(family, [style]), lookup, signal);
|
|
178
|
+
if (answer.kind === 'unavailable') {
|
|
179
|
+
return {
|
|
180
|
+
kind: 'unavailable',
|
|
181
|
+
family,
|
|
182
|
+
message: `${family} could not be fetched from Google Fonts: ${answer.reason}.`,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (answer.kind === 'missing')
|
|
186
|
+
lacking.push(style);
|
|
187
|
+
}
|
|
188
|
+
if (lacking.length < styles.length)
|
|
189
|
+
return missingStyles(family, lacking);
|
|
190
|
+
const alone = await fetchCss(css2Url(family, []), lookup, signal);
|
|
191
|
+
if (alone.kind === 'css')
|
|
192
|
+
return missingStyles(family, styles);
|
|
193
|
+
return {
|
|
194
|
+
kind: 'unknown-family',
|
|
195
|
+
family,
|
|
196
|
+
message: `Google Fonts has no family called ${family}.`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
async function downloadAll(faces, lookup, signal) {
|
|
200
|
+
const sources = [...new Set(faces.map((face) => face.src))];
|
|
201
|
+
const files = new Map();
|
|
202
|
+
let total = 0;
|
|
203
|
+
let failure;
|
|
204
|
+
let next = 0;
|
|
205
|
+
async function worker() {
|
|
206
|
+
while (failure === undefined && next < sources.length) {
|
|
207
|
+
const source = sources[next] ?? '';
|
|
208
|
+
next += 1;
|
|
209
|
+
const fetched = await fetchPublic(source, {
|
|
210
|
+
lookup,
|
|
211
|
+
signal: timeoutSignal(signal),
|
|
212
|
+
maxBytes: FILE_MAX_BYTES,
|
|
213
|
+
accept: 'font/woff2',
|
|
214
|
+
userAgent: FONT_FETCH_USER_AGENT,
|
|
215
|
+
allowed: isFontFileUrl,
|
|
216
|
+
contentType: { pattern: /^\s*font\/woff2\s*(;|$)/i, name: 'a WOFF2 font' },
|
|
217
|
+
});
|
|
218
|
+
if (!fetched.ok) {
|
|
219
|
+
failure ??= `${source} ${fetched.reason}`;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (Buffer.from(fetched.body.subarray(0, 4)).toString('latin1') !== 'wOF2') {
|
|
223
|
+
failure ??= `${source} is not a WOFF2 file`;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
total += fetched.body.length;
|
|
227
|
+
if (total > FAMILY_MAX_BYTES) {
|
|
228
|
+
failure ??= `its files come to more than ${String(FAMILY_MAX_BYTES)} bytes`;
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
files.set(source, fetched.body);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
await Promise.all(Array.from({ length: PARALLEL_DOWNLOADS }, worker));
|
|
235
|
+
return failure === undefined ? { ok: true, files } : { ok: false, reason: failure };
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/fonts/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ResolvedConfig } from '../config.ts';
|
|
2
|
+
import type { SiteSettings } from '../site/settings.ts';
|
|
3
|
+
export declare function capsuleUrl(config: Pick<ResolvedConfig, 'baseUrl' | 'baseUrlSource' | 'geminiPort'>, site: SiteSettings, path: string): string | undefined;
|
|
4
|
+
//# sourceMappingURL=capsule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capsule.d.ts","sourceRoot":"","sources":["../../src/gemini/capsule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,wBAAgB,UAAU,CACxB,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,eAAe,GAAG,YAAY,CAAC,EACxE,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAIpB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DEFAULT_GEMINI_PORT } from '../config.js';
|
|
2
|
+
import { geminiHost } from './site-certificate.js';
|
|
3
|
+
export function capsuleUrl(config, site, path) {
|
|
4
|
+
if (!site.gemini)
|
|
5
|
+
return undefined;
|
|
6
|
+
const port = config.geminiPort === DEFAULT_GEMINI_PORT ? '' : `:${String(config.geminiPort)}`;
|
|
7
|
+
return `gemini://${geminiHost(config, site)}${port}${path}`;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=capsule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capsule.js","sourceRoot":"","sources":["../../src/gemini/capsule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,UAAU,UAAU,CACxB,MAAwE,EACxE,IAAkB,EAClB,IAAY;IAEZ,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,KAAK,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;IAC9F,OAAO,YAAY,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ResolvedConfig } from '../config.ts';
|
|
2
|
+
export type GeminiCertificateConfig = Pick<ResolvedConfig, 'dataDir' | 'geminiCert' | 'geminiKey'>;
|
|
3
|
+
export interface GeminiCertificate {
|
|
4
|
+
readonly source: 'generated' | 'operator';
|
|
5
|
+
readonly certFile: string;
|
|
6
|
+
readonly keyFile: string;
|
|
7
|
+
readonly cert: string;
|
|
8
|
+
readonly key: string;
|
|
9
|
+
readonly subject: string;
|
|
10
|
+
readonly validTo: Date;
|
|
11
|
+
readonly fingerprint256: string;
|
|
12
|
+
readonly coversHost: boolean;
|
|
13
|
+
}
|
|
14
|
+
export type GeminiCertificateResult = {
|
|
15
|
+
readonly ok: true;
|
|
16
|
+
readonly certificate: GeminiCertificate;
|
|
17
|
+
} | {
|
|
18
|
+
readonly ok: false;
|
|
19
|
+
readonly problem: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function readGeminiCertificate(config: GeminiCertificateConfig, host: string): Promise<GeminiCertificateResult>;
|
|
22
|
+
export declare function ensureGeminiCertificate(config: GeminiCertificateConfig, host: string, now: Date): Promise<GeminiCertificateResult>;
|
|
23
|
+
export declare function regenerateGeminiCertificate(config: GeminiCertificateConfig, host: string, now: Date): Promise<GeminiCertificateResult>;
|
|
24
|
+
/**
|
|
25
|
+
* An X.509 v3 certificate signed by its own ECDSA P-256 key, naming `host`
|
|
26
|
+
* as its common name and its one subject alternative name. Node can sign but
|
|
27
|
+
* not build a certificate, so the few DER structures it needs are written
|
|
28
|
+
* here rather than taken from a dependency.
|
|
29
|
+
*/
|
|
30
|
+
export declare function selfSignedCertificate(host: string, now: Date): {
|
|
31
|
+
cert: string;
|
|
32
|
+
key: string;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=certificate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificate.d.ts","sourceRoot":"","sources":["../../src/gemini/certificate.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC;AAEnG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAYrD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,uBAAuB,EAC/B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,uBAAuB,CAAC,CAWlC;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,uBAAuB,EAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,uBAAuB,CAAC,CAOlC;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,uBAAuB,EAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,uBAAuB,CAAC,CAWlC;AAgID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAuB5F"}
|