@ewanc26/og 0.1.5 → 0.1.6
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/{chunk-2I73D34T.js → chunk-CM6746HS.js} +1 -9
- package/dist/chunk-CM6746HS.js.map +1 -0
- package/dist/index.cjs +21 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -11
- package/dist/index.d.ts +7 -11
- package/dist/index.js +22 -114
- package/dist/index.js.map +1 -1
- package/dist/templates/index.js +1 -1
- package/package.json +3 -2
- package/src/fonts-base64.ts +7 -0
- package/src/fonts.ts +29 -107
- package/src/index.ts +1 -1
- package/dist/chunk-2I73D34T.js.map +0 -1
- package/dist/fonts/Inter-Bold.ttf +0 -0
- package/dist/fonts/Inter-Regular.ttf +0 -0
- package/src/fonts-data.ts +0 -61
package/src/fonts.ts
CHANGED
|
@@ -1,73 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @ewanc26/og fonts
|
|
3
3
|
*
|
|
4
|
-
* Font loading utilities.
|
|
4
|
+
* Font loading utilities. Fonts are inlined as base64 at build time so this
|
|
5
|
+
* works in serverless environments (Vercel, Netlify, etc.) without any
|
|
6
|
+
* filesystem access to node_modules.
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
|
-
import {
|
|
8
|
-
import { existsSync } from 'node:fs'
|
|
9
|
-
import { dirname, resolve } from 'node:path'
|
|
10
|
-
import { fileURLToPath } from 'node:url'
|
|
9
|
+
import { INTER_BOLD_B64, INTER_REGULAR_B64 } from './fonts-base64.js'
|
|
11
10
|
import type { OgFontConfig } from './types.js'
|
|
12
|
-
import { loadEmbeddedFonts } from './fonts-data.js'
|
|
13
|
-
|
|
14
|
-
// Declare __dirname for CJS contexts (injected by bundlers)
|
|
15
|
-
declare const __dirname: string | undefined
|
|
16
|
-
|
|
17
|
-
// ─── Paths ────────────────────────────────────────────────────────────────────
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Get the directory of the current module.
|
|
21
|
-
* Works in both ESM and bundled contexts.
|
|
22
|
-
*/
|
|
23
|
-
function getModuleDir(): string {
|
|
24
|
-
// ESM context
|
|
25
|
-
if (typeof import.meta !== 'undefined' && import.meta.url) {
|
|
26
|
-
return dirname(fileURLToPath(import.meta.url))
|
|
27
|
-
}
|
|
28
|
-
// Bundled CJS context - __dirname is injected by bundlers
|
|
29
|
-
if (typeof __dirname !== 'undefined') {
|
|
30
|
-
return __dirname
|
|
31
|
-
}
|
|
32
|
-
// Fallback
|
|
33
|
-
return resolve(process.cwd(), 'node_modules/@ewanc26/og/dist')
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Resolve the fonts directory relative to the installed package.
|
|
38
|
-
* Tries multiple possible locations for serverless compatibility.
|
|
39
|
-
*/
|
|
40
|
-
function getFontsDir(): string {
|
|
41
|
-
const candidates = [
|
|
42
|
-
// Standard: fonts next to dist
|
|
43
|
-
resolve(getModuleDir(), '../fonts'),
|
|
44
|
-
// Vercel serverless: fonts inside dist
|
|
45
|
-
resolve(getModuleDir(), 'fonts'),
|
|
46
|
-
// Fallback: node_modules path
|
|
47
|
-
resolve(process.cwd(), 'node_modules/@ewanc26/og/fonts'),
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
for (const dir of candidates) {
|
|
51
|
-
if (existsSync(dir)) {
|
|
52
|
-
return dir
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Return first candidate as fallback (will fail gracefully)
|
|
57
|
-
return candidates[0]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Resolve bundled font paths. Uses getters to defer resolution until runtime.
|
|
62
|
-
*/
|
|
63
|
-
export const BUNDLED_FONTS = {
|
|
64
|
-
get heading() {
|
|
65
|
-
return resolve(getFontsDir(), 'Inter-Bold.ttf')
|
|
66
|
-
},
|
|
67
|
-
get body() {
|
|
68
|
-
return resolve(getFontsDir(), 'Inter-Regular.ttf')
|
|
69
|
-
},
|
|
70
|
-
} as const
|
|
71
11
|
|
|
72
12
|
// ─── Font Loading ──────────────────────────────────────────────────────────────
|
|
73
13
|
|
|
@@ -76,43 +16,36 @@ export interface LoadedFonts {
|
|
|
76
16
|
body: ArrayBuffer
|
|
77
17
|
}
|
|
78
18
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
*/
|
|
82
|
-
function toArrayBuffer(buf: Buffer): ArrayBuffer {
|
|
19
|
+
function base64ToArrayBuffer(b64: string): ArrayBuffer {
|
|
20
|
+
const buf = Buffer.from(b64, 'base64')
|
|
83
21
|
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer
|
|
84
22
|
}
|
|
85
23
|
|
|
86
24
|
/**
|
|
87
|
-
* Load fonts from config, falling back to bundled
|
|
25
|
+
* Load fonts from config, falling back to the bundled Inter font.
|
|
26
|
+
* If custom paths are provided they are loaded from disk; otherwise the
|
|
27
|
+
* pre-inlined base64 data is used (safe in any serverless runtime).
|
|
88
28
|
*/
|
|
89
29
|
export async function loadFonts(config?: OgFontConfig): Promise<LoadedFonts> {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* Falls back to alternative locations if local file not found.
|
|
104
|
-
*/
|
|
105
|
-
async function loadFontFile(source: string): Promise<ArrayBuffer> {
|
|
106
|
-
try {
|
|
107
|
-
const buffer = await readFile(source)
|
|
108
|
-
return toArrayBuffer(buffer)
|
|
109
|
-
} catch (error) {
|
|
110
|
-
// Try embedded fonts (loaded from alternative locations)
|
|
111
|
-
const embedded = await loadEmbeddedFonts()
|
|
112
|
-
if (embedded) {
|
|
113
|
-
return source.includes('Bold') ? embedded.heading : embedded.body
|
|
30
|
+
if (config?.heading || config?.body) {
|
|
31
|
+
const { readFile } = await import('node:fs/promises')
|
|
32
|
+
const [headingBuf, bodyBuf] = await Promise.all([
|
|
33
|
+
config.heading ? readFile(config.heading) : Buffer.from(INTER_BOLD_B64, 'base64'),
|
|
34
|
+
config.body ? readFile(config.body) : Buffer.from(INTER_REGULAR_B64, 'base64'),
|
|
35
|
+
])
|
|
36
|
+
return {
|
|
37
|
+
heading: headingBuf instanceof Buffer
|
|
38
|
+
? (headingBuf.buffer.slice(headingBuf.byteOffset, headingBuf.byteOffset + headingBuf.byteLength) as ArrayBuffer)
|
|
39
|
+
: headingBuf.buffer,
|
|
40
|
+
body: bodyBuf instanceof Buffer
|
|
41
|
+
? (bodyBuf.buffer.slice(bodyBuf.byteOffset, bodyBuf.byteOffset + bodyBuf.byteLength) as ArrayBuffer)
|
|
42
|
+
: bodyBuf.buffer,
|
|
114
43
|
}
|
|
115
|
-
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
heading: base64ToArrayBuffer(INTER_BOLD_B64),
|
|
48
|
+
body: base64ToArrayBuffer(INTER_REGULAR_B64),
|
|
116
49
|
}
|
|
117
50
|
}
|
|
118
51
|
|
|
@@ -127,21 +60,10 @@ export type SatoriFontConfig = {
|
|
|
127
60
|
|
|
128
61
|
/**
|
|
129
62
|
* Create Satori-compatible font config from loaded fonts.
|
|
130
|
-
* Uses Inter font family with weight 700 for headings and 400 for body.
|
|
131
63
|
*/
|
|
132
64
|
export function createSatoriFonts(fonts: LoadedFonts): SatoriFontConfig[] {
|
|
133
65
|
return [
|
|
134
|
-
{
|
|
135
|
-
|
|
136
|
-
data: fonts.heading,
|
|
137
|
-
weight: 700,
|
|
138
|
-
style: 'normal',
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
name: 'Inter',
|
|
142
|
-
data: fonts.body,
|
|
143
|
-
weight: 400,
|
|
144
|
-
style: 'normal',
|
|
145
|
-
},
|
|
66
|
+
{ name: 'Inter', data: fonts.heading, weight: 700, style: 'normal' },
|
|
67
|
+
{ name: 'Inter', data: fonts.body, weight: 400, style: 'normal' },
|
|
146
68
|
]
|
|
147
69
|
}
|
package/src/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ export { defaultColors } from './types.js'
|
|
|
41
41
|
export { generateNoiseDataUrl, generateCircleNoiseDataUrl } from './noise.js'
|
|
42
42
|
|
|
43
43
|
// Fonts (for advanced customization)
|
|
44
|
-
export { loadFonts, createSatoriFonts
|
|
44
|
+
export { loadFonts, createSatoriFonts } from './fonts.js'
|
|
45
45
|
|
|
46
46
|
// Endpoint helpers
|
|
47
47
|
export { createOgEndpoint } from './endpoint.js'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js","../src/templates/blog.ts","../src/templates/profile.ts","../src/templates/default.ts","../src/templates/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Blog OG template.\n * Clean centered layout.\n */\n\nimport type { OgTemplateProps } from '../types.js'\n\nexport function blogTemplate({\n\ttitle,\n\tdescription,\n\tsiteName,\n\tcolors,\n\tnoiseDataUrl,\n\twidth,\n\theight,\n}: OgTemplateProps) {\n\treturn {\n\t\ttype: 'div',\n\t\tprops: {\n\t\t\tstyle: {\n\t\t\t\tposition: 'relative',\n\t\t\t\tdisplay: 'flex',\n\t\t\t\tflexDirection: 'column',\n\t\t\t\talignItems: 'center',\n\t\t\t\tjustifyContent: 'center',\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tbackgroundColor: colors.background,\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tnoiseDataUrl ? {\n\t\t\t\t\ttype: 'img',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsrc: noiseDataUrl,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} : null,\n\t\t\t\t{\n\t\t\t\t\ttype: 'div',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\t\tdisplay: 'flex',\n\t\t\t\t\t\t\tflexDirection: 'column',\n\t\t\t\t\t\t\talignItems: 'center',\n\t\t\t\t\t\t\tjustifyContent: 'center',\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\tpadding: '0 60px',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'h1',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tfontSize: 64,\n\t\t\t\t\t\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\t\t\t\t\t\tcolor: colors.text,\n\t\t\t\t\t\t\t\t\t\tletterSpacing: '-0.02em',\n\t\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\t\t\tlineHeight: 1.1,\n\t\t\t\t\t\t\t\t\t\tmaxWidth: 1000,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: title,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdescription ? {\n\t\t\t\t\t\t\t\ttype: 'p',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tfontSize: 28,\n\t\t\t\t\t\t\t\t\t\tfontWeight: 400,\n\t\t\t\t\t\t\t\t\t\tcolor: colors.accent,\n\t\t\t\t\t\t\t\t\t\tmarginTop: 28,\n\t\t\t\t\t\t\t\t\t\tmarginBottom: 0,\n\t\t\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\t\t\tlineHeight: 1.4,\n\t\t\t\t\t\t\t\t\t\tmaxWidth: 900,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: description,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t} : null,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'p',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tfontSize: 24,\n\t\t\t\t\t\t\t\t\t\tfontWeight: 400,\n\t\t\t\t\t\t\t\t\t\tcolor: colors.accent,\n\t\t\t\t\t\t\t\t\t\tmarginTop: 56,\n\t\t\t\t\t\t\t\t\t\tmarginBottom: 0,\n\t\t\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\t\t\topacity: 0.7,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: siteName,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t].filter(Boolean),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t].filter(Boolean),\n\t\t},\n\t}\n}\n","/**\n * Profile OG template.\n * Centered layout.\n */\n\nimport type { OgTemplateProps } from '../types.js'\n\nexport function profileTemplate({\n\ttitle,\n\tdescription,\n\tsiteName,\n\timage,\n\tcolors,\n\tnoiseDataUrl,\n\twidth,\n\theight,\n}: OgTemplateProps) {\n\tconst contentChildren: unknown[] = []\n\n\tif (image) {\n\t\tcontentChildren.push({\n\t\t\ttype: 'img',\n\t\t\tprops: {\n\t\t\t\tsrc: image,\n\t\t\t\twidth: 120,\n\t\t\t\theight: 120,\n\t\t\t\tstyle: {\n\t\t\t\t\tborderRadius: '50%',\n\t\t\t\t\tmarginBottom: 32,\n\t\t\t\t\tobjectFit: 'cover',\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t}\n\n\tcontentChildren.push({\n\t\ttype: 'h1',\n\t\tprops: {\n\t\t\tstyle: {\n\t\t\t\tfontSize: 56,\n\t\t\t\tfontWeight: 700,\n\t\t\t\tcolor: colors.text,\n\t\t\t\tletterSpacing: '-0.02em',\n\t\t\t\tmargin: 0,\n\t\t\t\ttextAlign: 'center',\n\t\t\t\tlineHeight: 1.1,\n\t\t\t\tmaxWidth: 900,\n\t\t\t},\n\t\t\tchildren: title,\n\t\t},\n\t})\n\n\tif (description) {\n\t\tcontentChildren.push({\n\t\t\ttype: 'p',\n\t\t\tprops: {\n\t\t\t\tstyle: {\n\t\t\t\t\tfontSize: 26,\n\t\t\t\t\tfontWeight: 400,\n\t\t\t\t\tcolor: colors.accent,\n\t\t\t\t\tmarginTop: 20,\n\t\t\t\t\tmarginBottom: 0,\n\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\tlineHeight: 1.4,\n\t\t\t\t\tmaxWidth: 700,\n\t\t\t\t},\n\t\t\t\tchildren: description,\n\t\t\t},\n\t\t})\n\t}\n\n\tcontentChildren.push({\n\t\ttype: 'p',\n\t\tprops: {\n\t\t\tstyle: {\n\t\t\t\tfontSize: 24,\n\t\t\t\tfontWeight: 400,\n\t\t\t\tcolor: colors.accent,\n\t\t\t\tmarginTop: 48,\n\t\t\t\tmarginBottom: 0,\n\t\t\t\ttextAlign: 'center',\n\t\t\t\topacity: 0.7,\n\t\t\t},\n\t\t\tchildren: siteName,\n\t\t},\n\t})\n\n\treturn {\n\t\ttype: 'div',\n\t\tprops: {\n\t\t\tstyle: {\n\t\t\t\tposition: 'relative',\n\t\t\t\tdisplay: 'flex',\n\t\t\t\tflexDirection: 'column',\n\t\t\t\talignItems: 'center',\n\t\t\t\tjustifyContent: 'center',\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tbackgroundColor: colors.background,\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tnoiseDataUrl ? {\n\t\t\t\t\ttype: 'img',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsrc: noiseDataUrl,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} : null,\n\t\t\t\t{\n\t\t\t\t\ttype: 'div',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\t\tdisplay: 'flex',\n\t\t\t\t\t\t\tflexDirection: 'column',\n\t\t\t\t\t\t\talignItems: 'center',\n\t\t\t\t\t\t\tjustifyContent: 'center',\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\tpadding: '0 60px',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: contentChildren,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t].filter(Boolean),\n\t\t},\n\t}\n}\n","/**\n * Default OG template.\n * Clean, centered layout.\n */\n\nimport type { OgTemplateProps } from '../types.js'\n\nexport function defaultTemplate({\n\ttitle,\n\tdescription,\n\tsiteName,\n\tcolors,\n\tnoiseDataUrl,\n\twidth,\n\theight,\n}: OgTemplateProps) {\n\treturn {\n\t\ttype: 'div',\n\t\tprops: {\n\t\t\tstyle: {\n\t\t\t\tposition: 'relative',\n\t\t\t\tdisplay: 'flex',\n\t\t\t\tflexDirection: 'column',\n\t\t\t\talignItems: 'center',\n\t\t\t\tjustifyContent: 'center',\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tbackgroundColor: colors.background,\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tnoiseDataUrl ? {\n\t\t\t\t\ttype: 'img',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsrc: noiseDataUrl,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} : null,\n\t\t\t\t{\n\t\t\t\t\ttype: 'div',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\t\tdisplay: 'flex',\n\t\t\t\t\t\t\tflexDirection: 'column',\n\t\t\t\t\t\t\talignItems: 'center',\n\t\t\t\t\t\t\tjustifyContent: 'center',\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\tpadding: '0 60px',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'h1',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tfontSize: 72,\n\t\t\t\t\t\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\t\t\t\t\t\tcolor: colors.text,\n\t\t\t\t\t\t\t\t\t\tletterSpacing: '-0.02em',\n\t\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: title,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdescription ? {\n\t\t\t\t\t\t\t\ttype: 'p',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tfontSize: 32,\n\t\t\t\t\t\t\t\t\t\tfontWeight: 400,\n\t\t\t\t\t\t\t\t\t\tcolor: colors.accent,\n\t\t\t\t\t\t\t\t\t\tmarginTop: 24,\n\t\t\t\t\t\t\t\t\t\tmarginBottom: 0,\n\t\t\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\t\t\tmaxWidth: 900,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: description,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t} : null,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'p',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tfontSize: 28,\n\t\t\t\t\t\t\t\t\t\tfontWeight: 400,\n\t\t\t\t\t\t\t\t\t\tcolor: colors.accent,\n\t\t\t\t\t\t\t\t\t\tmarginTop: 64,\n\t\t\t\t\t\t\t\t\t\tmarginBottom: 0,\n\t\t\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\t\t\topacity: 0.7,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: siteName,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t].filter(Boolean),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t].filter(Boolean),\n\t\t},\n\t}\n}\n","/**\n * Built-in OG templates.\n */\n\nexport { blogTemplate } from './blog.js'\nexport { profileTemplate } from './profile.js'\nexport { defaultTemplate } from './default.js'\n\nimport { blogTemplate } from './blog.js'\nimport { profileTemplate } from './profile.js'\nimport { defaultTemplate } from './default.js'\nimport type { OgTemplate } from '../types.js'\n\nexport const templates = {\n\tblog: blogTemplate,\n\tprofile: profileTemplate,\n\tdefault: defaultTemplate,\n} as const\n\nexport type TemplateName = keyof typeof templates\n\nexport function getTemplate(name: TemplateName | OgTemplate): OgTemplate {\n\tif (typeof name === 'function') {\n\t\treturn name\n\t}\n\treturn templates[name]\n}\n"],"mappings":"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","names":[]}
|
|
Binary file
|
|
Binary file
|
package/src/fonts-data.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Font loading helper for serverless environments
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { readFile } from 'node:fs/promises'
|
|
6
|
-
import { dirname, resolve } from 'node:path'
|
|
7
|
-
import { fileURLToPath } from 'node:url'
|
|
8
|
-
|
|
9
|
-
// Declare __dirname for CJS contexts (injected by bundlers)
|
|
10
|
-
declare const __dirname: string | undefined
|
|
11
|
-
|
|
12
|
-
function getModuleDir(): string {
|
|
13
|
-
if (typeof import.meta !== 'undefined' && import.meta.url) {
|
|
14
|
-
return dirname(fileURLToPath(import.meta.url))
|
|
15
|
-
}
|
|
16
|
-
if (typeof __dirname !== 'undefined') {
|
|
17
|
-
return __dirname
|
|
18
|
-
}
|
|
19
|
-
return resolve(process.cwd(), 'node_modules/@ewanc26/og/dist')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface FontData {
|
|
23
|
-
heading: ArrayBuffer
|
|
24
|
-
body: ArrayBuffer
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Try loading fonts from dist/fonts directory
|
|
29
|
-
*/
|
|
30
|
-
export async function loadEmbeddedFonts(): Promise<FontData | null> {
|
|
31
|
-
const moduleDir = getModuleDir()
|
|
32
|
-
|
|
33
|
-
const paths = [
|
|
34
|
-
{
|
|
35
|
-
heading: resolve(moduleDir, 'fonts/Inter-Bold.ttf'),
|
|
36
|
-
body: resolve(moduleDir, 'fonts/Inter-Regular.ttf'),
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
heading: resolve(moduleDir, '../fonts/Inter-Bold.ttf'),
|
|
40
|
-
body: resolve(moduleDir, '../fonts/Inter-Regular.ttf'),
|
|
41
|
-
},
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
for (const p of paths) {
|
|
45
|
-
try {
|
|
46
|
-
const [headingBuf, bodyBuf] = await Promise.all([
|
|
47
|
-
readFile(p.heading),
|
|
48
|
-
readFile(p.body),
|
|
49
|
-
])
|
|
50
|
-
// Convert Buffer to ArrayBuffer
|
|
51
|
-
return {
|
|
52
|
-
heading: headingBuf.buffer.slice(headingBuf.byteOffset, headingBuf.byteOffset + headingBuf.byteLength),
|
|
53
|
-
body: bodyBuf.buffer.slice(bodyBuf.byteOffset, bodyBuf.byteOffset + bodyBuf.byteLength),
|
|
54
|
-
}
|
|
55
|
-
} catch {
|
|
56
|
-
continue
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return null
|
|
61
|
-
}
|