@json-render/image 0.1.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/LICENSE +201 -0
- package/README.md +167 -0
- package/dist/catalog.d.mts +265 -0
- package/dist/catalog.d.ts +265 -0
- package/dist/catalog.js +207 -0
- package/dist/catalog.js.map +1 -0
- package/dist/catalog.mjs +7 -0
- package/dist/catalog.mjs.map +1 -0
- package/dist/chunk-A67OT34V.mjs +41 -0
- package/dist/chunk-A67OT34V.mjs.map +1 -0
- package/dist/chunk-KQSKKHJA.mjs +348 -0
- package/dist/chunk-KQSKKHJA.mjs.map +1 -0
- package/dist/chunk-PMEELRVP.mjs +183 -0
- package/dist/chunk-PMEELRVP.mjs.map +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +600 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +19 -0
- package/dist/index.mjs.map +1 -0
- package/dist/render-DyXCSaYW.d.mts +40 -0
- package/dist/render-DyXCSaYW.d.ts +40 -0
- package/dist/render.d.mts +4 -0
- package/dist/render.d.ts +4 -0
- package/dist/render.js +380 -0
- package/dist/render.js.map +1 -0
- package/dist/render.mjs +11 -0
- package/dist/render.mjs.map +1 -0
- package/dist/server.d.mts +53 -0
- package/dist/server.d.ts +53 -0
- package/dist/server.js +248 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +11 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +85 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderToPng,
|
|
3
|
+
renderToSvg,
|
|
4
|
+
standardComponents
|
|
5
|
+
} from "./chunk-KQSKKHJA.mjs";
|
|
6
|
+
import {
|
|
7
|
+
schema
|
|
8
|
+
} from "./chunk-A67OT34V.mjs";
|
|
9
|
+
import {
|
|
10
|
+
standardComponentDefinitions
|
|
11
|
+
} from "./chunk-PMEELRVP.mjs";
|
|
12
|
+
export {
|
|
13
|
+
renderToPng,
|
|
14
|
+
renderToSvg,
|
|
15
|
+
schema,
|
|
16
|
+
standardComponentDefinitions,
|
|
17
|
+
standardComponents
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SatoriOptions } from 'satori';
|
|
2
|
+
import { UIElement, Spec } from '@json-render/core';
|
|
3
|
+
import { ReactNode, ComponentType } from 'react';
|
|
4
|
+
|
|
5
|
+
interface ComponentRenderProps<P = Record<string, unknown>> {
|
|
6
|
+
element: UIElement<string, P>;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
emit: (event: string) => void;
|
|
9
|
+
}
|
|
10
|
+
type ComponentRenderer<P = Record<string, unknown>> = ComponentType<ComponentRenderProps<P>>;
|
|
11
|
+
type ComponentRegistry = Record<string, ComponentRenderer<any>>;
|
|
12
|
+
|
|
13
|
+
declare const standardComponents: ComponentRegistry;
|
|
14
|
+
|
|
15
|
+
interface RenderOptions {
|
|
16
|
+
registry?: ComponentRegistry;
|
|
17
|
+
includeStandard?: boolean;
|
|
18
|
+
state?: Record<string, unknown>;
|
|
19
|
+
fonts?: SatoriOptions["fonts"];
|
|
20
|
+
/** Override the Frame width. When omitted, uses the Frame component's width prop. */
|
|
21
|
+
width?: number;
|
|
22
|
+
/** Override the Frame height. When omitted, uses the Frame component's height prop. */
|
|
23
|
+
height?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Render a json-render spec to an SVG string.
|
|
27
|
+
*
|
|
28
|
+
* Uses Satori to convert the spec's component tree into SVG.
|
|
29
|
+
* No additional dependencies are needed beyond satori.
|
|
30
|
+
*/
|
|
31
|
+
declare function renderToSvg(spec: Spec, options?: RenderOptions): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Render a json-render spec to a PNG buffer.
|
|
34
|
+
*
|
|
35
|
+
* Requires `@resvg/resvg-js` to be installed as a peer dependency.
|
|
36
|
+
* The SVG is first generated via Satori, then rasterized to PNG.
|
|
37
|
+
*/
|
|
38
|
+
declare function renderToPng(spec: Spec, options?: RenderOptions): Promise<Uint8Array>;
|
|
39
|
+
|
|
40
|
+
export { type ComponentRenderProps as C, type RenderOptions as R, type ComponentRenderer as a, type ComponentRegistry as b, renderToPng as c, renderToSvg as r, standardComponents as s };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SatoriOptions } from 'satori';
|
|
2
|
+
import { UIElement, Spec } from '@json-render/core';
|
|
3
|
+
import { ReactNode, ComponentType } from 'react';
|
|
4
|
+
|
|
5
|
+
interface ComponentRenderProps<P = Record<string, unknown>> {
|
|
6
|
+
element: UIElement<string, P>;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
emit: (event: string) => void;
|
|
9
|
+
}
|
|
10
|
+
type ComponentRenderer<P = Record<string, unknown>> = ComponentType<ComponentRenderProps<P>>;
|
|
11
|
+
type ComponentRegistry = Record<string, ComponentRenderer<any>>;
|
|
12
|
+
|
|
13
|
+
declare const standardComponents: ComponentRegistry;
|
|
14
|
+
|
|
15
|
+
interface RenderOptions {
|
|
16
|
+
registry?: ComponentRegistry;
|
|
17
|
+
includeStandard?: boolean;
|
|
18
|
+
state?: Record<string, unknown>;
|
|
19
|
+
fonts?: SatoriOptions["fonts"];
|
|
20
|
+
/** Override the Frame width. When omitted, uses the Frame component's width prop. */
|
|
21
|
+
width?: number;
|
|
22
|
+
/** Override the Frame height. When omitted, uses the Frame component's height prop. */
|
|
23
|
+
height?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Render a json-render spec to an SVG string.
|
|
27
|
+
*
|
|
28
|
+
* Uses Satori to convert the spec's component tree into SVG.
|
|
29
|
+
* No additional dependencies are needed beyond satori.
|
|
30
|
+
*/
|
|
31
|
+
declare function renderToSvg(spec: Spec, options?: RenderOptions): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Render a json-render spec to a PNG buffer.
|
|
34
|
+
*
|
|
35
|
+
* Requires `@resvg/resvg-js` to be installed as a peer dependency.
|
|
36
|
+
* The SVG is first generated via Satori, then rasterized to PNG.
|
|
37
|
+
*/
|
|
38
|
+
declare function renderToPng(spec: Spec, options?: RenderOptions): Promise<Uint8Array>;
|
|
39
|
+
|
|
40
|
+
export { type ComponentRenderProps as C, type RenderOptions as R, type ComponentRenderer as a, type ComponentRegistry as b, renderToPng as c, renderToSvg as r, standardComponents as s };
|
package/dist/render.d.ts
ADDED
package/dist/render.js
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/render.tsx
|
|
31
|
+
var render_exports = {};
|
|
32
|
+
__export(render_exports, {
|
|
33
|
+
renderToPng: () => renderToPng,
|
|
34
|
+
renderToSvg: () => renderToSvg,
|
|
35
|
+
standardComponents: () => standardComponents
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(render_exports);
|
|
38
|
+
var import_satori = __toESM(require("satori"));
|
|
39
|
+
var import_core = require("@json-render/core");
|
|
40
|
+
|
|
41
|
+
// src/components/standard.tsx
|
|
42
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
43
|
+
var headingSizes = {
|
|
44
|
+
h1: 48,
|
|
45
|
+
h2: 36,
|
|
46
|
+
h3: 28,
|
|
47
|
+
h4: 22
|
|
48
|
+
};
|
|
49
|
+
var headingWeights = {
|
|
50
|
+
h1: 700,
|
|
51
|
+
h2: 700,
|
|
52
|
+
h3: 600,
|
|
53
|
+
h4: 600
|
|
54
|
+
};
|
|
55
|
+
function cleanStyle(raw) {
|
|
56
|
+
const out = {};
|
|
57
|
+
for (const k in raw) {
|
|
58
|
+
if (raw[k] !== void 0 && raw[k] !== null) {
|
|
59
|
+
out[k] = raw[k];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
function FrameComponent({
|
|
65
|
+
element,
|
|
66
|
+
children
|
|
67
|
+
}) {
|
|
68
|
+
const p = element.props;
|
|
69
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
70
|
+
"div",
|
|
71
|
+
{
|
|
72
|
+
style: cleanStyle({
|
|
73
|
+
display: p.display ?? "flex",
|
|
74
|
+
flexDirection: p.flexDirection ?? "column",
|
|
75
|
+
width: p.width,
|
|
76
|
+
height: p.height,
|
|
77
|
+
backgroundColor: p.backgroundColor ?? "white",
|
|
78
|
+
padding: p.padding,
|
|
79
|
+
alignItems: p.alignItems,
|
|
80
|
+
justifyContent: p.justifyContent
|
|
81
|
+
}),
|
|
82
|
+
children
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
function BoxComponent({
|
|
87
|
+
element,
|
|
88
|
+
children
|
|
89
|
+
}) {
|
|
90
|
+
const p = element.props;
|
|
91
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
style: cleanStyle({
|
|
95
|
+
display: "flex",
|
|
96
|
+
flexDirection: p.flexDirection ?? "column",
|
|
97
|
+
padding: p.padding,
|
|
98
|
+
paddingTop: p.paddingTop,
|
|
99
|
+
paddingBottom: p.paddingBottom,
|
|
100
|
+
paddingLeft: p.paddingLeft,
|
|
101
|
+
paddingRight: p.paddingRight,
|
|
102
|
+
margin: p.margin,
|
|
103
|
+
backgroundColor: p.backgroundColor,
|
|
104
|
+
borderWidth: p.borderWidth,
|
|
105
|
+
borderColor: p.borderColor,
|
|
106
|
+
borderRadius: p.borderRadius,
|
|
107
|
+
borderStyle: p.borderWidth ? "solid" : void 0,
|
|
108
|
+
flex: p.flex,
|
|
109
|
+
width: p.width,
|
|
110
|
+
height: p.height,
|
|
111
|
+
alignItems: p.alignItems,
|
|
112
|
+
justifyContent: p.justifyContent,
|
|
113
|
+
position: p.position,
|
|
114
|
+
top: p.top,
|
|
115
|
+
left: p.left,
|
|
116
|
+
right: p.right,
|
|
117
|
+
bottom: p.bottom,
|
|
118
|
+
overflow: p.overflow
|
|
119
|
+
}),
|
|
120
|
+
children
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
function RowComponent({
|
|
125
|
+
element,
|
|
126
|
+
children
|
|
127
|
+
}) {
|
|
128
|
+
const p = element.props;
|
|
129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
style: cleanStyle({
|
|
133
|
+
display: "flex",
|
|
134
|
+
flexDirection: "row",
|
|
135
|
+
gap: p.gap,
|
|
136
|
+
alignItems: p.alignItems,
|
|
137
|
+
justifyContent: p.justifyContent,
|
|
138
|
+
padding: p.padding,
|
|
139
|
+
flex: p.flex,
|
|
140
|
+
flexWrap: p.wrap ? "wrap" : void 0
|
|
141
|
+
}),
|
|
142
|
+
children
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
function ColumnComponent({
|
|
147
|
+
element,
|
|
148
|
+
children
|
|
149
|
+
}) {
|
|
150
|
+
const p = element.props;
|
|
151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
152
|
+
"div",
|
|
153
|
+
{
|
|
154
|
+
style: cleanStyle({
|
|
155
|
+
display: "flex",
|
|
156
|
+
flexDirection: "column",
|
|
157
|
+
gap: p.gap,
|
|
158
|
+
alignItems: p.alignItems,
|
|
159
|
+
justifyContent: p.justifyContent,
|
|
160
|
+
padding: p.padding,
|
|
161
|
+
flex: p.flex
|
|
162
|
+
}),
|
|
163
|
+
children
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
function HeadingComponent({
|
|
168
|
+
element
|
|
169
|
+
}) {
|
|
170
|
+
const p = element.props;
|
|
171
|
+
const level = p.level ?? "h2";
|
|
172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
173
|
+
"div",
|
|
174
|
+
{
|
|
175
|
+
style: cleanStyle({
|
|
176
|
+
display: "flex",
|
|
177
|
+
fontSize: headingSizes[level] ?? 36,
|
|
178
|
+
fontWeight: headingWeights[level] ?? 700,
|
|
179
|
+
color: p.color ?? "black",
|
|
180
|
+
textAlign: p.align ?? "left",
|
|
181
|
+
letterSpacing: p.letterSpacing,
|
|
182
|
+
lineHeight: p.lineHeight ?? 1.2
|
|
183
|
+
}),
|
|
184
|
+
children: p.text
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
function TextComponent({
|
|
189
|
+
element
|
|
190
|
+
}) {
|
|
191
|
+
const p = element.props;
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
193
|
+
"div",
|
|
194
|
+
{
|
|
195
|
+
style: cleanStyle({
|
|
196
|
+
display: "flex",
|
|
197
|
+
fontSize: p.fontSize ?? 16,
|
|
198
|
+
color: p.color ?? "black",
|
|
199
|
+
textAlign: p.align ?? "left",
|
|
200
|
+
fontWeight: p.fontWeight === "bold" ? 700 : 400,
|
|
201
|
+
fontStyle: p.fontStyle ?? "normal",
|
|
202
|
+
lineHeight: p.lineHeight ?? 1.4,
|
|
203
|
+
letterSpacing: p.letterSpacing,
|
|
204
|
+
textDecoration: p.textDecoration
|
|
205
|
+
}),
|
|
206
|
+
children: p.text
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
function ImageComponent({
|
|
211
|
+
element
|
|
212
|
+
}) {
|
|
213
|
+
const p = element.props;
|
|
214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
215
|
+
"img",
|
|
216
|
+
{
|
|
217
|
+
src: p.src,
|
|
218
|
+
width: p.width ?? void 0,
|
|
219
|
+
height: p.height ?? void 0,
|
|
220
|
+
style: cleanStyle({
|
|
221
|
+
borderRadius: p.borderRadius,
|
|
222
|
+
objectFit: p.objectFit ?? "contain"
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
function DividerComponent({
|
|
228
|
+
element
|
|
229
|
+
}) {
|
|
230
|
+
const p = element.props;
|
|
231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
232
|
+
"div",
|
|
233
|
+
{
|
|
234
|
+
style: {
|
|
235
|
+
display: "flex",
|
|
236
|
+
width: "100%",
|
|
237
|
+
borderBottom: `${p.thickness ?? 1}px solid ${p.color ?? "#e5e7eb"}`,
|
|
238
|
+
marginTop: p.marginTop ?? 8,
|
|
239
|
+
marginBottom: p.marginBottom ?? 8
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
function SpacerComponent({
|
|
245
|
+
element
|
|
246
|
+
}) {
|
|
247
|
+
const p = element.props;
|
|
248
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", height: p.height ?? 20 } });
|
|
249
|
+
}
|
|
250
|
+
var standardComponents = {
|
|
251
|
+
Frame: FrameComponent,
|
|
252
|
+
Box: BoxComponent,
|
|
253
|
+
Row: RowComponent,
|
|
254
|
+
Column: ColumnComponent,
|
|
255
|
+
Heading: HeadingComponent,
|
|
256
|
+
Text: TextComponent,
|
|
257
|
+
Image: ImageComponent,
|
|
258
|
+
Divider: DividerComponent,
|
|
259
|
+
Spacer: SpacerComponent
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/render.tsx
|
|
263
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
264
|
+
var noopEmit = () => {
|
|
265
|
+
};
|
|
266
|
+
function renderElement(elementKey, spec, registry, stateModel, repeatItem, repeatIndex, repeatBasePath) {
|
|
267
|
+
const element = spec.elements[elementKey];
|
|
268
|
+
if (!element) return null;
|
|
269
|
+
const ctx = {
|
|
270
|
+
stateModel,
|
|
271
|
+
repeatItem,
|
|
272
|
+
repeatIndex,
|
|
273
|
+
repeatBasePath
|
|
274
|
+
};
|
|
275
|
+
if (element.visible !== void 0) {
|
|
276
|
+
if (!(0, import_core.evaluateVisibility)(element.visible, ctx)) {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const resolvedProps = (0, import_core.resolveElementProps)(
|
|
281
|
+
element.props,
|
|
282
|
+
ctx
|
|
283
|
+
);
|
|
284
|
+
const resolvedElement = { ...element, props: resolvedProps };
|
|
285
|
+
const Component = registry[resolvedElement.type];
|
|
286
|
+
if (!Component) return null;
|
|
287
|
+
if (resolvedElement.repeat) {
|
|
288
|
+
const items = (0, import_core.getByPath)(stateModel, resolvedElement.repeat.statePath) ?? [];
|
|
289
|
+
const fragments = items.map((item, index) => {
|
|
290
|
+
const key = resolvedElement.repeat.key && typeof item === "object" && item !== null ? String(
|
|
291
|
+
item[resolvedElement.repeat.key] ?? index
|
|
292
|
+
) : String(index);
|
|
293
|
+
const childPath = `${resolvedElement.repeat.statePath}/${index}`;
|
|
294
|
+
const children2 = resolvedElement.children?.map(
|
|
295
|
+
(childKey) => renderElement(
|
|
296
|
+
childKey,
|
|
297
|
+
spec,
|
|
298
|
+
registry,
|
|
299
|
+
stateModel,
|
|
300
|
+
item,
|
|
301
|
+
index,
|
|
302
|
+
childPath
|
|
303
|
+
)
|
|
304
|
+
);
|
|
305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, { element: resolvedElement, emit: noopEmit, children: children2 }, key);
|
|
306
|
+
});
|
|
307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: fragments });
|
|
308
|
+
}
|
|
309
|
+
const children = resolvedElement.children?.map(
|
|
310
|
+
(childKey) => renderElement(
|
|
311
|
+
childKey,
|
|
312
|
+
spec,
|
|
313
|
+
registry,
|
|
314
|
+
stateModel,
|
|
315
|
+
repeatItem,
|
|
316
|
+
repeatIndex,
|
|
317
|
+
repeatBasePath
|
|
318
|
+
)
|
|
319
|
+
);
|
|
320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, { element: resolvedElement, emit: noopEmit, children: children && children.length > 0 ? children : void 0 }, elementKey);
|
|
321
|
+
}
|
|
322
|
+
function getDimensions(spec, options = {}) {
|
|
323
|
+
if (options.width && options.height) {
|
|
324
|
+
return { width: options.width, height: options.height };
|
|
325
|
+
}
|
|
326
|
+
const rootElement = spec.elements[spec.root];
|
|
327
|
+
const props = rootElement?.props;
|
|
328
|
+
return {
|
|
329
|
+
width: options.width ?? props?.width ?? 1200,
|
|
330
|
+
height: options.height ?? props?.height ?? 630
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function buildTree(spec, options = {}) {
|
|
334
|
+
const {
|
|
335
|
+
registry: customRegistry,
|
|
336
|
+
includeStandard = true,
|
|
337
|
+
state = {}
|
|
338
|
+
} = options;
|
|
339
|
+
const mergedState = {
|
|
340
|
+
...spec.state,
|
|
341
|
+
...state
|
|
342
|
+
};
|
|
343
|
+
const registry = {
|
|
344
|
+
...includeStandard ? standardComponents : {},
|
|
345
|
+
...customRegistry
|
|
346
|
+
};
|
|
347
|
+
const root = renderElement(spec.root, spec, registry, mergedState);
|
|
348
|
+
return root ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, {});
|
|
349
|
+
}
|
|
350
|
+
async function renderToSvg(spec, options = {}) {
|
|
351
|
+
const tree = buildTree(spec, options);
|
|
352
|
+
const { width, height } = getDimensions(spec, options);
|
|
353
|
+
return (0, import_satori.default)(tree, {
|
|
354
|
+
width,
|
|
355
|
+
height,
|
|
356
|
+
fonts: options.fonts ?? []
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
async function renderToPng(spec, options = {}) {
|
|
360
|
+
const svg = await renderToSvg(spec, options);
|
|
361
|
+
let Resvg;
|
|
362
|
+
try {
|
|
363
|
+
const mod = await import("@resvg/resvg-js");
|
|
364
|
+
Resvg = mod.Resvg;
|
|
365
|
+
} catch {
|
|
366
|
+
throw new Error(
|
|
367
|
+
"@resvg/resvg-js is required for PNG output. Install it with: npm install @resvg/resvg-js"
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
const resvg = new Resvg(svg);
|
|
371
|
+
const pngData = resvg.render();
|
|
372
|
+
return pngData.asPng();
|
|
373
|
+
}
|
|
374
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
375
|
+
0 && (module.exports = {
|
|
376
|
+
renderToPng,
|
|
377
|
+
renderToSvg,
|
|
378
|
+
standardComponents
|
|
379
|
+
});
|
|
380
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/render.tsx","../src/components/standard.tsx"],"sourcesContent":["import React from \"react\";\nimport satori, { type SatoriOptions } from \"satori\";\nimport type { Spec, UIElement } from \"@json-render/core\";\nimport {\n resolveElementProps,\n evaluateVisibility,\n getByPath,\n type PropResolutionContext,\n} from \"@json-render/core\";\nimport { standardComponents } from \"./components/standard\";\nimport type { ComponentRegistry } from \"./types\";\n\nexport { standardComponents };\n\nexport interface RenderOptions {\n registry?: ComponentRegistry;\n includeStandard?: boolean;\n state?: Record<string, unknown>;\n fonts?: SatoriOptions[\"fonts\"];\n /** Override the Frame width. When omitted, uses the Frame component's width prop. */\n width?: number;\n /** Override the Frame height. When omitted, uses the Frame component's height prop. */\n height?: number;\n}\n\nconst noopEmit = () => {};\n\nfunction renderElement(\n elementKey: string,\n spec: Spec,\n registry: ComponentRegistry,\n stateModel: Record<string, unknown>,\n repeatItem?: unknown,\n repeatIndex?: number,\n repeatBasePath?: string,\n): React.ReactElement | null {\n const element = spec.elements[elementKey];\n if (!element) return null;\n\n const ctx: PropResolutionContext = {\n stateModel,\n repeatItem,\n repeatIndex,\n repeatBasePath,\n };\n\n if (element.visible !== undefined) {\n if (!evaluateVisibility(element.visible, ctx)) {\n return null;\n }\n }\n\n const resolvedProps = resolveElementProps(\n element.props as Record<string, unknown>,\n ctx,\n );\n const resolvedElement: UIElement = { ...element, props: resolvedProps };\n\n const Component = registry[resolvedElement.type];\n if (!Component) return null;\n\n if (resolvedElement.repeat) {\n const items =\n (getByPath(stateModel, resolvedElement.repeat.statePath) as\n | unknown[]\n | undefined) ?? [];\n\n const fragments = items.map((item, index) => {\n const key =\n resolvedElement.repeat!.key && typeof item === \"object\" && item !== null\n ? String(\n (item as Record<string, unknown>)[resolvedElement.repeat!.key!] ??\n index,\n )\n : String(index);\n\n const childPath = `${resolvedElement.repeat!.statePath}/${index}`;\n const children = resolvedElement.children?.map((childKey) =>\n renderElement(\n childKey,\n spec,\n registry,\n stateModel,\n item,\n index,\n childPath,\n ),\n );\n\n return (\n <Component key={key} element={resolvedElement} emit={noopEmit}>\n {children}\n </Component>\n );\n });\n\n return <>{fragments}</>;\n }\n\n const children = resolvedElement.children?.map((childKey) =>\n renderElement(\n childKey,\n spec,\n registry,\n stateModel,\n repeatItem,\n repeatIndex,\n repeatBasePath,\n ),\n );\n\n return (\n <Component key={elementKey} element={resolvedElement} emit={noopEmit}>\n {children && children.length > 0 ? children : undefined}\n </Component>\n );\n}\n\ninterface ImageDimensions {\n width: number;\n height: number;\n}\n\nfunction getDimensions(\n spec: Spec,\n options: RenderOptions = {},\n): ImageDimensions {\n if (options.width && options.height) {\n return { width: options.width, height: options.height };\n }\n\n const rootElement = spec.elements[spec.root];\n const props = rootElement?.props as Record<string, unknown> | undefined;\n\n return {\n width: options.width ?? (props?.width as number) ?? 1200,\n height: options.height ?? (props?.height as number) ?? 630,\n };\n}\n\nfunction buildTree(\n spec: Spec,\n options: RenderOptions = {},\n): React.ReactElement {\n const {\n registry: customRegistry,\n includeStandard = true,\n state = {},\n } = options;\n\n const mergedState: Record<string, unknown> = {\n ...spec.state,\n ...state,\n };\n\n const registry: ComponentRegistry = {\n ...(includeStandard ? standardComponents : {}),\n ...customRegistry,\n };\n\n const root = renderElement(spec.root, spec, registry, mergedState);\n return root ?? <></>;\n}\n\n/**\n * Render a json-render spec to an SVG string.\n *\n * Uses Satori to convert the spec's component tree into SVG.\n * No additional dependencies are needed beyond satori.\n */\nexport async function renderToSvg(\n spec: Spec,\n options: RenderOptions = {},\n): Promise<string> {\n const tree = buildTree(spec, options);\n const { width, height } = getDimensions(spec, options);\n\n return satori(tree as React.ReactNode, {\n width,\n height,\n fonts: options.fonts ?? [],\n });\n}\n\n/**\n * Render a json-render spec to a PNG buffer.\n *\n * Requires `@resvg/resvg-js` to be installed as a peer dependency.\n * The SVG is first generated via Satori, then rasterized to PNG.\n */\nexport async function renderToPng(\n spec: Spec,\n options: RenderOptions = {},\n): Promise<Uint8Array> {\n const svg = await renderToSvg(spec, options);\n\n let Resvg: typeof import(\"@resvg/resvg-js\").Resvg;\n try {\n const mod = await import(\"@resvg/resvg-js\");\n Resvg = mod.Resvg;\n } catch {\n throw new Error(\n \"@resvg/resvg-js is required for PNG output. Install it with: npm install @resvg/resvg-js\",\n );\n }\n\n const resvg = new Resvg(svg);\n const pngData = resvg.render();\n return pngData.asPng();\n}\n","import React from \"react\";\nimport type { ComponentRenderProps, ComponentRegistry } from \"../types\";\nimport type { StandardComponentProps } from \"../catalog\";\n\nconst headingSizes: Record<string, number> = {\n h1: 48,\n h2: 36,\n h3: 28,\n h4: 22,\n};\n\nconst headingWeights: Record<string, number> = {\n h1: 700,\n h2: 700,\n h3: 600,\n h4: 600,\n};\n\n/**\n * Satori crashes on explicit `undefined` style values (e.g. `padding: undefined`).\n * Strip them so only defined properties are passed.\n */\nfunction cleanStyle(raw: Record<string, unknown>): React.CSSProperties {\n const out: Record<string, unknown> = {};\n for (const k in raw) {\n if (raw[k] !== undefined && raw[k] !== null) {\n out[k] = raw[k];\n }\n }\n return out as React.CSSProperties;\n}\n\n// =============================================================================\n// Root\n// =============================================================================\n\nfunction FrameComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Frame\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: p.display ?? \"flex\",\n flexDirection: p.flexDirection ?? \"column\",\n width: p.width,\n height: p.height,\n backgroundColor: p.backgroundColor ?? \"white\",\n padding: p.padding,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n })}\n >\n {children}\n </div>\n );\n}\n\n// =============================================================================\n// Layout Components\n// =============================================================================\n\nfunction BoxComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Box\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n flexDirection: p.flexDirection ?? \"column\",\n padding: p.padding,\n paddingTop: p.paddingTop,\n paddingBottom: p.paddingBottom,\n paddingLeft: p.paddingLeft,\n paddingRight: p.paddingRight,\n margin: p.margin,\n backgroundColor: p.backgroundColor,\n borderWidth: p.borderWidth,\n borderColor: p.borderColor,\n borderRadius: p.borderRadius,\n borderStyle: p.borderWidth ? \"solid\" : undefined,\n flex: p.flex,\n width: p.width,\n height: p.height,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n position: p.position,\n top: p.top,\n left: p.left,\n right: p.right,\n bottom: p.bottom,\n overflow: p.overflow,\n })}\n >\n {children}\n </div>\n );\n}\n\nfunction RowComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Row\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n flexDirection: \"row\",\n gap: p.gap,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n padding: p.padding,\n flex: p.flex,\n flexWrap: p.wrap ? \"wrap\" : undefined,\n })}\n >\n {children}\n </div>\n );\n}\n\nfunction ColumnComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Column\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n flexDirection: \"column\",\n gap: p.gap,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n padding: p.padding,\n flex: p.flex,\n })}\n >\n {children}\n </div>\n );\n}\n\n// =============================================================================\n// Content Components\n// =============================================================================\n\nfunction HeadingComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Heading\">>) {\n const p = element.props;\n const level = p.level ?? \"h2\";\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n fontSize: headingSizes[level] ?? 36,\n fontWeight: headingWeights[level] ?? 700,\n color: p.color ?? \"black\",\n textAlign: p.align ?? \"left\",\n letterSpacing: p.letterSpacing,\n lineHeight: p.lineHeight ?? 1.2,\n })}\n >\n {p.text}\n </div>\n );\n}\n\nfunction TextComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Text\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n fontSize: p.fontSize ?? 16,\n color: p.color ?? \"black\",\n textAlign: p.align ?? \"left\",\n fontWeight: p.fontWeight === \"bold\" ? 700 : 400,\n fontStyle: p.fontStyle ?? \"normal\",\n lineHeight: p.lineHeight ?? 1.4,\n letterSpacing: p.letterSpacing,\n textDecoration: p.textDecoration,\n })}\n >\n {p.text}\n </div>\n );\n}\n\nfunction ImageComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Image\">>) {\n const p = element.props;\n\n return (\n <img\n src={p.src}\n width={p.width ?? undefined}\n height={p.height ?? undefined}\n style={cleanStyle({\n borderRadius: p.borderRadius,\n objectFit: p.objectFit ?? \"contain\",\n })}\n />\n );\n}\n\n// =============================================================================\n// Decorative Components\n// =============================================================================\n\nfunction DividerComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Divider\">>) {\n const p = element.props;\n\n return (\n <div\n style={{\n display: \"flex\",\n width: \"100%\",\n borderBottom: `${p.thickness ?? 1}px solid ${p.color ?? \"#e5e7eb\"}`,\n marginTop: p.marginTop ?? 8,\n marginBottom: p.marginBottom ?? 8,\n }}\n />\n );\n}\n\nfunction SpacerComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Spacer\">>) {\n const p = element.props;\n\n return <div style={{ display: \"flex\", height: p.height ?? 20 }} />;\n}\n\n// =============================================================================\n// Registry\n// =============================================================================\n\nexport const standardComponents: ComponentRegistry = {\n Frame: FrameComponent,\n Box: BoxComponent,\n Row: RowComponent,\n Column: ColumnComponent,\n Heading: HeadingComponent,\n Text: TextComponent,\n Image: ImageComponent,\n Divider: DividerComponent,\n Spacer: SpacerComponent,\n};\n"],"mappings":"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","names":["import_jsx_runtime","children","satori"]}
|
package/dist/render.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as _json_render_core from '@json-render/core';
|
|
2
|
+
import { Catalog, InferCatalogComponents, InferComponentProps } from '@json-render/core';
|
|
3
|
+
export { Spec, StateModel } from '@json-render/core';
|
|
4
|
+
export { StandardComponentDefinitions, StandardComponentProps, standardComponentDefinitions } from './catalog.mjs';
|
|
5
|
+
import 'zod';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The schema for @json-render/image
|
|
9
|
+
*
|
|
10
|
+
* Defines:
|
|
11
|
+
* - Spec: A flat tree of elements with keys, types, props, and children references
|
|
12
|
+
* - Catalog: Components with props schemas
|
|
13
|
+
*
|
|
14
|
+
* Reuses the same { root, elements } spec format as the React and React PDF renderers.
|
|
15
|
+
*/
|
|
16
|
+
declare const schema: _json_render_core.Schema<{
|
|
17
|
+
spec: _json_render_core.SchemaType<"object", {
|
|
18
|
+
root: _json_render_core.SchemaType<"string", unknown>;
|
|
19
|
+
elements: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
20
|
+
type: _json_render_core.SchemaType<"ref", string>;
|
|
21
|
+
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
22
|
+
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
23
|
+
visible: _json_render_core.SchemaType<"any", unknown>;
|
|
24
|
+
}>>;
|
|
25
|
+
}>;
|
|
26
|
+
catalog: _json_render_core.SchemaType<"object", {
|
|
27
|
+
components: _json_render_core.SchemaType<"map", {
|
|
28
|
+
props: _json_render_core.SchemaType<"zod", unknown>;
|
|
29
|
+
slots: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
30
|
+
description: _json_render_core.SchemaType<"string", unknown>;
|
|
31
|
+
example: _json_render_core.SchemaType<"any", unknown>;
|
|
32
|
+
}>;
|
|
33
|
+
}>;
|
|
34
|
+
}>;
|
|
35
|
+
type ImageSchema = typeof schema;
|
|
36
|
+
type ImageSpec<TCatalog> = typeof schema extends {
|
|
37
|
+
createCatalog: (catalog: TCatalog) => {
|
|
38
|
+
_specType: infer S;
|
|
39
|
+
};
|
|
40
|
+
} ? S : never;
|
|
41
|
+
|
|
42
|
+
type SetState = (updater: (prev: Record<string, unknown>) => Record<string, unknown>) => void;
|
|
43
|
+
interface ComponentContext<C extends Catalog, K extends keyof InferCatalogComponents<C>> {
|
|
44
|
+
props: InferComponentProps<C, K>;
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
emit: (event: string) => void;
|
|
47
|
+
}
|
|
48
|
+
type ComponentFn<C extends Catalog, K extends keyof InferCatalogComponents<C>> = (ctx: ComponentContext<C, K>) => React.ReactNode;
|
|
49
|
+
type Components<C extends Catalog> = {
|
|
50
|
+
[K in keyof InferCatalogComponents<C>]: ComponentFn<C, K>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { type ComponentContext, type ComponentFn, type Components, type ImageSchema, type ImageSpec, type SetState, schema };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as _json_render_core from '@json-render/core';
|
|
2
|
+
import { Catalog, InferCatalogComponents, InferComponentProps } from '@json-render/core';
|
|
3
|
+
export { Spec, StateModel } from '@json-render/core';
|
|
4
|
+
export { StandardComponentDefinitions, StandardComponentProps, standardComponentDefinitions } from './catalog.js';
|
|
5
|
+
import 'zod';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The schema for @json-render/image
|
|
9
|
+
*
|
|
10
|
+
* Defines:
|
|
11
|
+
* - Spec: A flat tree of elements with keys, types, props, and children references
|
|
12
|
+
* - Catalog: Components with props schemas
|
|
13
|
+
*
|
|
14
|
+
* Reuses the same { root, elements } spec format as the React and React PDF renderers.
|
|
15
|
+
*/
|
|
16
|
+
declare const schema: _json_render_core.Schema<{
|
|
17
|
+
spec: _json_render_core.SchemaType<"object", {
|
|
18
|
+
root: _json_render_core.SchemaType<"string", unknown>;
|
|
19
|
+
elements: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
20
|
+
type: _json_render_core.SchemaType<"ref", string>;
|
|
21
|
+
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
22
|
+
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
23
|
+
visible: _json_render_core.SchemaType<"any", unknown>;
|
|
24
|
+
}>>;
|
|
25
|
+
}>;
|
|
26
|
+
catalog: _json_render_core.SchemaType<"object", {
|
|
27
|
+
components: _json_render_core.SchemaType<"map", {
|
|
28
|
+
props: _json_render_core.SchemaType<"zod", unknown>;
|
|
29
|
+
slots: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
30
|
+
description: _json_render_core.SchemaType<"string", unknown>;
|
|
31
|
+
example: _json_render_core.SchemaType<"any", unknown>;
|
|
32
|
+
}>;
|
|
33
|
+
}>;
|
|
34
|
+
}>;
|
|
35
|
+
type ImageSchema = typeof schema;
|
|
36
|
+
type ImageSpec<TCatalog> = typeof schema extends {
|
|
37
|
+
createCatalog: (catalog: TCatalog) => {
|
|
38
|
+
_specType: infer S;
|
|
39
|
+
};
|
|
40
|
+
} ? S : never;
|
|
41
|
+
|
|
42
|
+
type SetState = (updater: (prev: Record<string, unknown>) => Record<string, unknown>) => void;
|
|
43
|
+
interface ComponentContext<C extends Catalog, K extends keyof InferCatalogComponents<C>> {
|
|
44
|
+
props: InferComponentProps<C, K>;
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
emit: (event: string) => void;
|
|
47
|
+
}
|
|
48
|
+
type ComponentFn<C extends Catalog, K extends keyof InferCatalogComponents<C>> = (ctx: ComponentContext<C, K>) => React.ReactNode;
|
|
49
|
+
type Components<C extends Catalog> = {
|
|
50
|
+
[K in keyof InferCatalogComponents<C>]: ComponentFn<C, K>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { type ComponentContext, type ComponentFn, type Components, type ImageSchema, type ImageSpec, type SetState, schema };
|