@ethercorps/sveltekit-og 4.0.0 → 4.2.0-next.1
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/dist/fonts.d.ts +54 -0
- package/dist/fonts.js +112 -0
- package/dist/helpers/cache.d.ts +1 -0
- package/dist/helpers/cache.js +1 -0
- package/dist/helpers/emoji.js +1 -1
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +14 -0
- package/dist/types.d.ts +12 -1
- package/package.json +73 -66
package/dist/fonts.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { FinalFontOptions, FontStyle, FontWeight, MayBePromise } from './types.js';
|
|
2
|
+
interface BaseFontOptions {
|
|
3
|
+
weight?: FontWeight;
|
|
4
|
+
style?: FontStyle;
|
|
5
|
+
}
|
|
6
|
+
/** * Base font class defining the structure required by Satori.
|
|
7
|
+
* All font types inherit from this class.
|
|
8
|
+
*/
|
|
9
|
+
export declare class BaseFont {
|
|
10
|
+
protected input: any;
|
|
11
|
+
name: string;
|
|
12
|
+
style: FontStyle;
|
|
13
|
+
weight: FontWeight;
|
|
14
|
+
constructor(name: string, input: any, { weight, style }?: BaseFontOptions);
|
|
15
|
+
/** * Abstract getter that returns the promised ArrayBuffer.
|
|
16
|
+
* Overridden by CustomFont and GoogleFont for lazy loading.
|
|
17
|
+
*/
|
|
18
|
+
get data(): MayBePromise<Buffer | ArrayBuffer>;
|
|
19
|
+
}
|
|
20
|
+
/** * A helper class to load Custom fonts, typically from local files.
|
|
21
|
+
* The input must be a function provided by the user (e.g., using $app/server/read).
|
|
22
|
+
*/
|
|
23
|
+
export declare class CustomFont extends BaseFont {
|
|
24
|
+
private promise?;
|
|
25
|
+
/**
|
|
26
|
+
* Creates an instance of CustomFont.
|
|
27
|
+
* @param name The name of the font (for CSS font-family).
|
|
28
|
+
* @param input Font data as ArrayBuffer or a function that resolves to ArrayBuffer (user must provide the loading logic).
|
|
29
|
+
*/
|
|
30
|
+
constructor(name: string, input: MayBePromise<Buffer | ArrayBuffer> | (() => MayBePromise<Buffer | ArrayBuffer>), options?: BaseFontOptions);
|
|
31
|
+
/** A promise which resolves to font data as `ArrayBuffer` (Lazy load) */
|
|
32
|
+
get data(): Promise<Buffer | ArrayBuffer>;
|
|
33
|
+
}
|
|
34
|
+
/** Loads Google font ArrayBuffer with caching. */
|
|
35
|
+
export declare const loadGoogleFont: (family: string, { text, weight, style, display }?: {
|
|
36
|
+
text?: string;
|
|
37
|
+
weight?: string | number;
|
|
38
|
+
style?: FontStyle;
|
|
39
|
+
display?: FontDisplay;
|
|
40
|
+
}) => Promise<ArrayBuffer>;
|
|
41
|
+
export declare class GoogleFont extends BaseFont {
|
|
42
|
+
family: string;
|
|
43
|
+
text: string | undefined;
|
|
44
|
+
private promise?;
|
|
45
|
+
constructor(family: string, options?: {
|
|
46
|
+
name?: string;
|
|
47
|
+
text?: string;
|
|
48
|
+
weight?: FontWeight;
|
|
49
|
+
style?: FontStyle;
|
|
50
|
+
});
|
|
51
|
+
get data(): Promise<ArrayBuffer>;
|
|
52
|
+
}
|
|
53
|
+
export declare function resolveFonts(fontClasses: Array<CustomFont | GoogleFont>): Promise<FinalFontOptions>;
|
|
54
|
+
export {};
|
package/dist/fonts.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { FONT_CACHE_MAP } from './helpers/cache.js';
|
|
2
|
+
/** * Base font class defining the structure required by Satori.
|
|
3
|
+
* All font types inherit from this class.
|
|
4
|
+
*/
|
|
5
|
+
export class BaseFont {
|
|
6
|
+
input;
|
|
7
|
+
name;
|
|
8
|
+
style;
|
|
9
|
+
weight;
|
|
10
|
+
constructor(name, input, { weight = 400, style = 'normal' } = {}) {
|
|
11
|
+
this.input = input;
|
|
12
|
+
this.name = name;
|
|
13
|
+
this.style = style;
|
|
14
|
+
this.weight = weight;
|
|
15
|
+
}
|
|
16
|
+
/** * Abstract getter that returns the promised ArrayBuffer.
|
|
17
|
+
* Overridden by CustomFont and GoogleFont for lazy loading.
|
|
18
|
+
*/
|
|
19
|
+
get data() {
|
|
20
|
+
return this.input;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** * A helper class to load Custom fonts, typically from local files.
|
|
24
|
+
* The input must be a function provided by the user (e.g., using $app/server/read).
|
|
25
|
+
*/
|
|
26
|
+
export class CustomFont extends BaseFont {
|
|
27
|
+
promise;
|
|
28
|
+
/**
|
|
29
|
+
* Creates an instance of CustomFont.
|
|
30
|
+
* @param name The name of the font (for CSS font-family).
|
|
31
|
+
* @param input Font data as ArrayBuffer or a function that resolves to ArrayBuffer (user must provide the loading logic).
|
|
32
|
+
*/
|
|
33
|
+
constructor(name, input, options) {
|
|
34
|
+
super(name, input, options);
|
|
35
|
+
}
|
|
36
|
+
/** A promise which resolves to font data as `ArrayBuffer` (Lazy load) */
|
|
37
|
+
get data() {
|
|
38
|
+
// Defines the loading mechanism: execute the input function or resolve the promise/buffer.
|
|
39
|
+
const fallback = async () => (typeof this.input === 'function' ? this.input() : this.input);
|
|
40
|
+
// Memoization: ensures the input function is executed only once.
|
|
41
|
+
this.promise = this.promise?.then(null, fallback) ?? fallback();
|
|
42
|
+
return this.promise;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Constructs Google font css url */
|
|
46
|
+
const constructGoogleFontCssUrl = (family, { text, weight = 400, style = 'normal', display } = {}) => {
|
|
47
|
+
// Logic to build the URL (e.g., https://fonts.googleapis.com/css2?family=...wght@...)
|
|
48
|
+
const params = {
|
|
49
|
+
family: `${family.replaceAll(' ', '+')}:${style === 'italic' ? 'ital,' : ''}wght@${style === 'italic' ? '1,' : ''}${weight}`,
|
|
50
|
+
};
|
|
51
|
+
if (text)
|
|
52
|
+
params.text = encodeURIComponent(text);
|
|
53
|
+
return `https://fonts.googleapis.com/css2?${Object.keys(params).map((key) => `${key}=${params[key]}`).join('&')}`;
|
|
54
|
+
};
|
|
55
|
+
/** Loads Google font ArrayBuffer with caching. */
|
|
56
|
+
export const loadGoogleFont = async (family, { text, weight = 400, style = 'normal', display } = {}) => {
|
|
57
|
+
const cssUrl = constructGoogleFontCssUrl(family, { text, weight, display, style });
|
|
58
|
+
const fromMap = FONT_CACHE_MAP.get(cssUrl);
|
|
59
|
+
if (fromMap) {
|
|
60
|
+
return fromMap;
|
|
61
|
+
}
|
|
62
|
+
const cssResponse = await fetch(cssUrl);
|
|
63
|
+
if (!cssResponse.ok) {
|
|
64
|
+
throw new Error(`Failed to fetch Google Font CSS for ${family}. Status: ${cssResponse.status}`);
|
|
65
|
+
}
|
|
66
|
+
const css = await cssResponse.text();
|
|
67
|
+
// 3. Extract the font file URL (the actual TTF/OTF file)
|
|
68
|
+
const fontUrl = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/)?.[1];
|
|
69
|
+
if (!fontUrl) {
|
|
70
|
+
throw new Error(`Could not find a compatible truetype font source in the CSS for ${family}.`);
|
|
71
|
+
}
|
|
72
|
+
// 4. Fetch the font buffer
|
|
73
|
+
const fontResponse = await fetch(fontUrl);
|
|
74
|
+
if (!fontResponse.ok) {
|
|
75
|
+
throw new Error(`Failed to fetch font file from URL. Status: ${fontResponse.status}`);
|
|
76
|
+
}
|
|
77
|
+
const buffer = await fontResponse.arrayBuffer();
|
|
78
|
+
// 5. CACHE AND RETURN: Store the resolved ArrayBuffer in the Map, keyed by the CSS URL.
|
|
79
|
+
FONT_CACHE_MAP.set(cssUrl, buffer);
|
|
80
|
+
return buffer;
|
|
81
|
+
};
|
|
82
|
+
export class GoogleFont extends BaseFont {
|
|
83
|
+
family;
|
|
84
|
+
text;
|
|
85
|
+
promise;
|
|
86
|
+
constructor(family, options = {}) {
|
|
87
|
+
super(options.name || family, undefined, options);
|
|
88
|
+
this.family = family;
|
|
89
|
+
this.text = options.text;
|
|
90
|
+
}
|
|
91
|
+
get data() {
|
|
92
|
+
const fallback = async () => loadGoogleFont(this.family, {
|
|
93
|
+
weight: this.weight,
|
|
94
|
+
style: this.style,
|
|
95
|
+
text: this.text,
|
|
96
|
+
});
|
|
97
|
+
this.promise = this.promise?.then(null, fallback) ?? fallback();
|
|
98
|
+
return this.promise;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function resolveFonts(fontClasses) {
|
|
102
|
+
const resolvedFonts = await Promise.all(fontClasses.map(async (fontClass) => {
|
|
103
|
+
const dataBuffer = await fontClass.data;
|
|
104
|
+
return {
|
|
105
|
+
name: fontClass.name,
|
|
106
|
+
data: dataBuffer, // The resolved ArrayBuffer/Buffer
|
|
107
|
+
weight: fontClass.weight,
|
|
108
|
+
style: fontClass.style,
|
|
109
|
+
};
|
|
110
|
+
}));
|
|
111
|
+
return resolvedFonts.filter(font => font !== null);
|
|
112
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FONT_CACHE_MAP: Map<string, ArrayBuffer>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const FONT_CACHE_MAP = new Map();
|
package/dist/helpers/emoji.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_EMOJI_PROVIDER } from '../helpers/defaults.js';
|
|
2
|
-
// Code stolen from @vercel/og
|
|
2
|
+
// Code stolen from @vercel/og and https://github.com/fineshopdesign/cf-wasm
|
|
3
3
|
const U200D = String.fromCharCode(8205);
|
|
4
4
|
const UFE0Fg = /\uFE0F/g;
|
|
5
5
|
function getIconCode(char) {
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { unwasm, type UnwasmPluginOptions } from "unwasm/plugin";
|
|
2
|
+
import type { Plugin as VitePlugin } from "vite";
|
|
2
3
|
type Plugin = ReturnType<typeof unwasm>;
|
|
3
4
|
export declare function rollupWasm(options?: UnwasmPluginOptions): Plugin;
|
|
5
|
+
export declare function sveltekitOG(options?: UnwasmPluginOptions): VitePlugin;
|
|
4
6
|
export {};
|
package/dist/plugin.js
CHANGED
|
@@ -6,3 +6,17 @@ export function rollupWasm(options) {
|
|
|
6
6
|
...options
|
|
7
7
|
});
|
|
8
8
|
}
|
|
9
|
+
export function sveltekitOG(options) {
|
|
10
|
+
return {
|
|
11
|
+
name: 'vite-plugin-sveltekit-og',
|
|
12
|
+
config() {
|
|
13
|
+
return {
|
|
14
|
+
build: {
|
|
15
|
+
rollupOptions: {
|
|
16
|
+
plugins: [rollupWasm(options)]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { SatoriOptions } from 'satori/wasm';
|
|
2
2
|
import type { EmojiType } from './helpers/emoji.js';
|
|
3
|
+
export type Font = SatoriOptions['fonts'][number];
|
|
4
|
+
export type Fonts = Font[];
|
|
5
|
+
export type FontStyle = Font['style'];
|
|
6
|
+
export type FontWeight = Font['weight'];
|
|
7
|
+
export type FinalFontOptions = NonNullable<Fonts>;
|
|
3
8
|
export type ImageOptions = {
|
|
4
9
|
/**
|
|
5
10
|
* Width of the image
|
|
@@ -20,7 +25,7 @@ export type ImageOptions = {
|
|
|
20
25
|
* Fonts used for your text
|
|
21
26
|
* @default `helpers/defaults.js`
|
|
22
27
|
* */
|
|
23
|
-
fonts?:
|
|
28
|
+
fonts?: Fonts;
|
|
24
29
|
/**
|
|
25
30
|
* Tailwind config
|
|
26
31
|
* @default provided by satori
|
|
@@ -78,3 +83,9 @@ export interface VNode {
|
|
|
78
83
|
[prop: string]: any;
|
|
79
84
|
};
|
|
80
85
|
}
|
|
86
|
+
/** utils types */
|
|
87
|
+
export type MayBePromise<T> = T | Promise<T>;
|
|
88
|
+
export type OnlyProps<T, P> = {
|
|
89
|
+
[K in keyof T as K extends P ? K : never]: T[K];
|
|
90
|
+
};
|
|
91
|
+
export type StringWithSuggestions<S extends string> = (string & Record<never, never>) | S;
|
package/package.json
CHANGED
|
@@ -1,68 +1,75 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
2
|
+
"name": "@ethercorps/sveltekit-og",
|
|
3
|
+
"version": "4.2.0-next.1",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"dev": "vite dev",
|
|
6
|
+
"build": "vite build && npm run package",
|
|
7
|
+
"preview": "vite preview",
|
|
8
|
+
"package": "svelte-kit sync && svelte-package && publint",
|
|
9
|
+
"prepublishOnly": "npm run package",
|
|
10
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
11
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
|
14
|
+
"format": "prettier --plugin-search-dir . --write .",
|
|
15
|
+
"publishBeta": "npm publish --tag beta"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"svelte": "./dist/index.js",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./plugin": {
|
|
24
|
+
"types": "./dist/fonts.d.ts",
|
|
25
|
+
"import": "./dist/fonts.js"
|
|
26
|
+
},
|
|
27
|
+
"./plugin": {
|
|
28
|
+
"types": "./dist/plugin.d.ts",
|
|
29
|
+
"import": "./dist/plugin.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"!dist/**/*.test.*",
|
|
35
|
+
"!dist/**/*.spec.*"
|
|
36
|
+
],
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@sveltejs/adapter-vercel": "^5.10.2",
|
|
39
|
+
"@sveltejs/kit": "^2.48.5",
|
|
40
|
+
"@sveltejs/package": "^2.5.4",
|
|
41
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
|
42
|
+
"@types/node": "^24.7.1",
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
44
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
45
|
+
"css-tree": "^2.3.1",
|
|
46
|
+
"eslint": "^8.57.1",
|
|
47
|
+
"eslint-config-prettier": "^8.10.0",
|
|
48
|
+
"eslint-plugin-svelte": "^2.46.1",
|
|
49
|
+
"prettier": "^3.6.2",
|
|
50
|
+
"prettier-plugin-svelte": "^3.4.0",
|
|
51
|
+
"publint": "^0.1.16",
|
|
52
|
+
"rollup-plugin-visualizer": "^5.14.0",
|
|
53
|
+
"svelte": "^5.43.12",
|
|
54
|
+
"svelte-check": "^4.3.2",
|
|
55
|
+
"tslib": "^2.8.1",
|
|
56
|
+
"typescript": "^5.9.3",
|
|
57
|
+
"vite": "^5.4.19",
|
|
58
|
+
"vitest": "^1.6.1"
|
|
59
|
+
},
|
|
60
|
+
"main": "./dist/index.js",
|
|
61
|
+
"svelte": "./dist/index.js",
|
|
62
|
+
"types": "./dist/index.d.ts",
|
|
63
|
+
"type": "module",
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@resvg/resvg-wasm": "^2.6.2",
|
|
66
|
+
"satori": "^0.10.14",
|
|
67
|
+
"satori-html": "0.3.2",
|
|
68
|
+
"std-env": "^3.9.0",
|
|
69
|
+
"unwasm": "^0.5.0"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"@sveltejs/kit": ">=2.0.0"
|
|
73
|
+
},
|
|
74
|
+
"packageManager": "pnpm@10.12.1"
|
|
68
75
|
}
|