@riebeckite/og-image 0.0.37 → 0.0.38

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/README.md CHANGED
@@ -5,5 +5,5 @@ Static 1200×630 PNG Open Graph image rendering primitives for Riebeckite.
5
5
  [日本語](./README_ja.md)
6
6
 
7
7
  Use `presetLayout("card")`, `presetLayout("minimal")`, or
8
- `presetLayout("editorial")` with `renderOgImage()`. The renderer uses Sharp and
9
- accepts Japanese text through its SVG text pipeline.
8
+ `presetLayout("editorial")` with `renderOgImage()`. The renderer turns Hono JSX
9
+ layouts into SVG with Satori, then encodes PNG with Sharp.
package/README_ja.md CHANGED
@@ -5,4 +5,4 @@ Riebeckite 向けの、1200×630 PNG Open Graph 画像レンダリングプリ
5
5
  [English](./README.md)
6
6
 
7
7
  `presetLayout("card")`、`presetLayout("minimal")`、
8
- `presetLayout("editorial")` を `renderOgImage()` と組み合わせて使います。レンダラーは Sharp を使い、SVG テキスト経由で日本語を扱います。
8
+ `presetLayout("editorial")` を `renderOgImage()` と組み合わせて使います。レンダラーは Hono JSX のレイアウトを Satori で SVG に変換し、Sharp で PNG にエンコードします。
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type ReactNode } from "react";
1
+ import { type Child } from "hono/jsx";
2
2
  export declare const OG_IMAGE_HEIGHT = 630;
3
3
  export declare const OG_IMAGE_WIDTH = 1200;
4
4
  export type OgPalette = Readonly<{
@@ -32,7 +32,7 @@ export type OgLayoutInput = Readonly<{
32
32
  palette: OgPalette;
33
33
  content: OgContent;
34
34
  }>;
35
- export type OgLayoutResult = ReactNode | string;
35
+ export type OgLayoutResult = Child;
36
36
  export type OgLayout = (input: OgLayoutInput) => OgLayoutResult;
37
37
  export type OgPreset = "card" | "minimal" | "editorial";
38
38
  export declare function defineOgLayout(layout: OgLayout): OgLayout;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // index.ts
2
2
  import { readFileSync } from "node:fs";
3
3
  import { fileURLToPath } from "node:url";
4
- import { createElement } from "react";
4
+ import { createElement } from "hono/jsx";
5
5
  import satori from "satori";
6
6
  import sharp from "sharp";
7
7
  var OG_IMAGE_HEIGHT = 630;
@@ -40,7 +40,7 @@ function presetLayout(preset) {
40
40
  "div",
41
41
  { style: { color: palette.accent, fontSize: 28 } },
42
42
  site.title
43
- ) : createElement("div"),
43
+ ) : createElement("div", null),
44
44
  createElement(
45
45
  "div",
46
46
  {
@@ -79,7 +79,7 @@ function presetLayout(preset) {
79
79
  }
80
80
  async function renderOgImage(layout, input) {
81
81
  const result = layout(input);
82
- const svg = typeof result === "string" ? `<svg xmlns="http://www.w3.org/2000/svg" width="${OG_IMAGE_WIDTH}" height="${OG_IMAGE_HEIGHT}"><style>${fontFaceCss}text{font-family:"Noto Sans JP",sans-serif}</style>${result}</svg>` : await satori(toReactNode(result), {
82
+ const svg = typeof result === "string" ? `<svg xmlns="http://www.w3.org/2000/svg" width="${OG_IMAGE_WIDTH}" height="${OG_IMAGE_HEIGHT}"><style>${fontFaceCss}text{font-family:"Noto Sans JP",sans-serif}</style>${result}</svg>` : await satori(toSatoriNode(result), {
83
83
  width: OG_IMAGE_WIDTH,
84
84
  height: OG_IMAGE_HEIGHT,
85
85
  fonts: notoSansJpFonts
@@ -118,17 +118,21 @@ var notoSansJpFonts = notoSansJpFontData.map(([weight, data]) => ({
118
118
  var fontFaceCss = notoSansJpFontData.map(
119
119
  ([weight, data]) => `@font-face{font-family:"Noto Sans JP";font-style:normal;font-weight:${weight};src:url(data:font/woff;base64,${data.toString("base64")}) format("woff")}`
120
120
  ).join("");
121
- function toReactNode(value) {
122
- if (Array.isArray(value)) return value.map(toReactNode);
121
+ function toSatoriNode(value) {
122
+ if (Array.isArray(value)) return value.map(toSatoriNode);
123
123
  if (!value || typeof value !== "object") return value;
124
124
  const node = value;
125
+ if (node.type !== void 0) return value;
125
126
  if (!node.tag) return value;
126
127
  const children = node.children ?? [];
127
128
  const props = { ...node.props };
129
+ if (children.length > 0) {
130
+ props.children = children.length === 1 ? toSatoriNode(children[0]) : children.map(toSatoriNode);
131
+ }
128
132
  if (typeof node.tag === "function") {
129
- return toReactNode(node.tag({ ...props, children }));
133
+ return toSatoriNode(node.tag(props));
130
134
  }
131
- return createElement(node.tag, props, ...children.map(toReactNode));
135
+ return { type: node.tag, props };
132
136
  }
133
137
  export {
134
138
  OG_IMAGE_HEIGHT,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/og-image",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -14,7 +14,7 @@
14
14
  }
15
15
  },
16
16
  "dependencies": {
17
- "react": "^19.3.1",
17
+ "hono": "^4.12.25",
18
18
  "satori": "^0.25.0",
19
19
  "sharp": "^0.35.5"
20
20
  },