@farcaster/snap-hono 1.1.5 → 1.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.
@@ -32,8 +32,6 @@ function renderElement(el, accent) {
32
32
  return renderText(el, accent);
33
33
  case "image":
34
34
  return renderImage(el);
35
- case "video":
36
- return renderVideo(el);
37
35
  case "grid":
38
36
  return renderGrid(el);
39
37
  case "progress":
@@ -85,13 +83,6 @@ function renderImage(el) {
85
83
  const ratio = w && h ? `${w}/${h}` : "16/9";
86
84
  return `<div style="aspect-ratio:${ratio};border-radius:8px;overflow:hidden;background:#F3F4F6"><img src="${url}" alt="${esc(el.alt ?? "")}" style="width:100%;height:100%;object-fit:cover"></div>`;
87
85
  }
88
- function renderVideo(el) {
89
- const url = esc(el.url);
90
- const aspect = el.aspect ?? "16:9";
91
- const [w, h] = aspect.split(":").map(Number);
92
- const ratio = w && h ? `${w}/${h}` : "16/9";
93
- return `<div style="aspect-ratio:${ratio};border-radius:8px;overflow:hidden;background:#000"><video src="${url}" autoplay muted loop playsinline style="width:100%;height:100%;object-fit:cover"></video></div>`;
94
- }
95
86
  function renderGrid(el) {
96
87
  const cols = el.cols;
97
88
  const rows = el.rows;
@@ -131,12 +122,11 @@ function renderProgress(el, accent) {
131
122
  }
132
123
  function renderBarChart(el, accent) {
133
124
  const bars = el.bars;
134
- const max = el.max ??
135
- Math.max(...bars.map((b) => b.value), 1);
125
+ const max = el.max ?? Math.max(...bars.map((b) => b.value), 1);
136
126
  const defaultColor = colorHex(el.color, accent);
137
127
  let html = `<div style="display:flex;align-items:flex-end;gap:12px;height:120px">`;
138
128
  for (const bar of bars) {
139
- const color = bar.color ? (PALETTE[bar.color] ?? defaultColor) : defaultColor;
129
+ const color = bar.color ? PALETTE[bar.color] ?? defaultColor : defaultColor;
140
130
  const pct = max > 0 ? (bar.value / max) * 100 : 0;
141
131
  html += `<div style="flex:1;display:flex;flex-direction:column;align-items:center;height:100%;justify-content:flex-end">`;
142
132
  html += `<div style="font-size:11px;color:#6B7280;margin-bottom:4px">${bar.value}</div>`;
@@ -226,7 +216,11 @@ function renderButtons(buttons, layout, accent) {
226
216
  : layout === "grid"
227
217
  ? "display:grid;grid-template-columns:1fr 1fr"
228
218
  : "flex-direction:column";
229
- const wrap = layout === "row" ? "display:flex;" : layout === "grid" ? "" : "display:flex;";
219
+ const wrap = layout === "row"
220
+ ? "display:flex;"
221
+ : layout === "grid"
222
+ ? ""
223
+ : "display:flex;";
230
224
  let html = `<div style="${wrap}${dir};gap:8px;margin-top:12px">`;
231
225
  for (let i = 0; i < buttons.length; i++) {
232
226
  const btn = buttons[i];
@@ -246,9 +240,7 @@ export function renderSnapPage(snap, snapOrigin) {
246
240
  const accent = accentHex(page.theme?.accent);
247
241
  // Extract title for <title> tag
248
242
  const titleEl = page.elements.children.find((el) => el.type === "text" && el.style === "title");
249
- const pageTitle = titleEl
250
- ? esc(titleEl.content)
251
- : "Farcaster Snap";
243
+ const pageTitle = titleEl ? esc(titleEl.content) : "Farcaster Snap";
252
244
  const snapUrl = encodeURIComponent(snapOrigin + "/");
253
245
  // Render elements
254
246
  let elementsHtml = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farcaster/snap-hono",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "Hono integration for Farcaster Snap servers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
- "@farcaster/snap": "1.3.0"
29
+ "@farcaster/snap": "1.3.1"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "hono": ">=4.0.0"
@@ -39,8 +39,6 @@ function renderElement(el: Record<string, unknown>, accent: string): string {
39
39
  return renderText(el, accent);
40
40
  case "image":
41
41
  return renderImage(el);
42
- case "video":
43
- return renderVideo(el);
44
42
  case "grid":
45
43
  return renderGrid(el);
46
44
  case "progress":
@@ -67,17 +65,16 @@ function renderElement(el: Record<string, unknown>, accent: string): string {
67
65
  medium: "16px",
68
66
  large: "24px",
69
67
  };
70
- return `<div style="height:${sizes[(el.size as string) ?? "medium"] ?? "16px"}"></div>`;
68
+ return `<div style="height:${
69
+ sizes[(el.size as string) ?? "medium"] ?? "16px"
70
+ }"></div>`;
71
71
  }
72
72
  default:
73
73
  return "";
74
74
  }
75
75
  }
76
76
 
77
- function renderText(
78
- el: Record<string, unknown>,
79
- _accent: string,
80
- ): string {
77
+ function renderText(el: Record<string, unknown>, _accent: string): string {
81
78
  const style = el.style as string;
82
79
  const content = esc(el.content as string);
83
80
  const align = (el.align as string) ?? "left";
@@ -85,9 +82,12 @@ function renderText(
85
82
  title: "font-size:20px;font-weight:700;color:#111",
86
83
  body: "font-size:15px;line-height:1.5;color:#374151",
87
84
  caption: "font-size:13px;color:#9CA3AF",
88
- label: "font-size:13px;font-weight:600;color:#6B7280;text-transform:uppercase;letter-spacing:0.5px",
85
+ label:
86
+ "font-size:13px;font-weight:600;color:#6B7280;text-transform:uppercase;letter-spacing:0.5px",
89
87
  };
90
- return `<div style="${styles[style] ?? styles.body};text-align:${align}">${content}</div>`;
88
+ return `<div style="${
89
+ styles[style] ?? styles.body
90
+ };text-align:${align}">${content}</div>`;
91
91
  }
92
92
 
93
93
  function renderImage(el: Record<string, unknown>): string {
@@ -95,15 +95,9 @@ function renderImage(el: Record<string, unknown>): string {
95
95
  const aspect = (el.aspect as string) ?? "16:9";
96
96
  const [w, h] = aspect.split(":").map(Number);
97
97
  const ratio = w && h ? `${w}/${h}` : "16/9";
98
- return `<div style="aspect-ratio:${ratio};border-radius:8px;overflow:hidden;background:#F3F4F6"><img src="${url}" alt="${esc((el.alt as string) ?? "")}" style="width:100%;height:100%;object-fit:cover"></div>`;
99
- }
100
-
101
- function renderVideo(el: Record<string, unknown>): string {
102
- const url = esc(el.url as string);
103
- const aspect = (el.aspect as string) ?? "16:9";
104
- const [w, h] = aspect.split(":").map(Number);
105
- const ratio = w && h ? `${w}/${h}` : "16/9";
106
- return `<div style="aspect-ratio:${ratio};border-radius:8px;overflow:hidden;background:#000"><video src="${url}" autoplay muted loop playsinline style="width:100%;height:100%;object-fit:cover"></video></div>`;
98
+ return `<div style="aspect-ratio:${ratio};border-radius:8px;overflow:hidden;background:#F3F4F6"><img src="${url}" alt="${esc(
99
+ (el.alt as string) ?? "",
100
+ )}" style="width:100%;height:100%;object-fit:cover"></div>`;
107
101
  }
108
102
 
109
103
  function renderGrid(el: Record<string, unknown>): string {
@@ -136,46 +130,45 @@ function renderGrid(el: Record<string, unknown>): string {
136
130
  }
137
131
  }
138
132
 
139
- return `<div style="display:grid;grid-template-columns:repeat(${cols},1fr);gap:${gapPx[gap] ?? "2px"}">${cellsHtml}</div>`;
133
+ return `<div style="display:grid;grid-template-columns:repeat(${cols},1fr);gap:${
134
+ gapPx[gap] ?? "2px"
135
+ }">${cellsHtml}</div>`;
140
136
  }
141
137
 
142
- function renderProgress(
143
- el: Record<string, unknown>,
144
- accent: string,
145
- ): string {
138
+ function renderProgress(el: Record<string, unknown>, accent: string): string {
146
139
  const value = el.value as number;
147
140
  const max = el.max as number;
148
141
  const label = el.label as string | undefined;
149
142
  const color = colorHex(el.color as string | undefined, accent);
150
143
  const pct = max > 0 ? Math.min(100, (value / max) * 100) : 0;
151
144
  const labelHtml = label
152
- ? `<div style="font-size:13px;color:#6B7280;margin-bottom:4px">${esc(label)}</div>`
145
+ ? `<div style="font-size:13px;color:#6B7280;margin-bottom:4px">${esc(
146
+ label,
147
+ )}</div>`
153
148
  : "";
154
149
  return `<div>${labelHtml}<div style="height:8px;background:#E5E7EB;border-radius:4px;overflow:hidden"><div style="height:100%;width:${pct}%;background:${color};border-radius:4px"></div></div></div>`;
155
150
  }
156
151
 
157
- function renderBarChart(
158
- el: Record<string, unknown>,
159
- accent: string,
160
- ): string {
152
+ function renderBarChart(el: Record<string, unknown>, accent: string): string {
161
153
  const bars = el.bars as Array<{
162
154
  label: string;
163
155
  value: number;
164
156
  color?: string;
165
157
  }>;
166
158
  const max =
167
- (el.max as number | undefined) ??
168
- Math.max(...bars.map((b) => b.value), 1);
159
+ (el.max as number | undefined) ?? Math.max(...bars.map((b) => b.value), 1);
169
160
  const defaultColor = colorHex(el.color as string | undefined, accent);
170
161
 
171
162
  let html = `<div style="display:flex;align-items:flex-end;gap:12px;height:120px">`;
172
163
  for (const bar of bars) {
173
- const color = bar.color ? (PALETTE[bar.color] ?? defaultColor) : defaultColor;
164
+ const color = bar.color ? PALETTE[bar.color] ?? defaultColor : defaultColor;
174
165
  const pct = max > 0 ? (bar.value / max) * 100 : 0;
175
166
  html += `<div style="flex:1;display:flex;flex-direction:column;align-items:center;height:100%;justify-content:flex-end">`;
176
167
  html += `<div style="font-size:11px;color:#6B7280;margin-bottom:4px">${bar.value}</div>`;
177
168
  html += `<div style="width:100%;height:${pct}%;background:${color};border-radius:4px 4px 0 0;min-height:4px"></div>`;
178
- html += `<div style="font-size:11px;color:#9CA3AF;margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%">${esc(bar.label)}</div>`;
169
+ html += `<div style="font-size:11px;color:#9CA3AF;margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%">${esc(
170
+ bar.label,
171
+ )}</div>`;
179
172
  html += `</div>`;
180
173
  }
181
174
  html += `</div>`;
@@ -196,12 +189,16 @@ function renderList(el: Record<string, unknown>): string {
196
189
  style === "ordered"
197
190
  ? `<span style="color:#9CA3AF;min-width:20px">${i + 1}.</span>`
198
191
  : style === "unordered"
199
- ? `<span style="color:#9CA3AF;min-width:20px">&bull;</span>`
200
- : "";
192
+ ? `<span style="color:#9CA3AF;min-width:20px">&bull;</span>`
193
+ : "";
201
194
  const trailing = item.trailing
202
- ? `<span style="color:#9CA3AF;font-size:13px;white-space:nowrap">${esc(item.trailing)}</span>`
195
+ ? `<span style="color:#9CA3AF;font-size:13px;white-space:nowrap">${esc(
196
+ item.trailing,
197
+ )}</span>`
203
198
  : "";
204
- html += `<div style="display:flex;align-items:center;gap:8px;padding:6px 0">${prefix}<span style="flex:1;font-size:14px;color:#374151">${esc(item.content)}</span>${trailing}</div>`;
199
+ html += `<div style="display:flex;align-items:center;gap:8px;padding:6px 0">${prefix}<span style="flex:1;font-size:14px;color:#374151">${esc(
200
+ item.content,
201
+ )}</span>${trailing}</div>`;
205
202
  }
206
203
  return `<div>${html}</div>`;
207
204
  }
@@ -215,16 +212,15 @@ function renderButtonGroup(
215
212
  const dir = layout === "stack" ? "column" : "row";
216
213
  let html = `<div style="display:flex;flex-direction:${dir};gap:8px">`;
217
214
  for (const opt of options) {
218
- html += `<button onclick="showModal()" style="flex:1;padding:10px 12px;border-radius:8px;border:1px solid #E5E7EB;background:#fff;font-size:14px;color:#374151;cursor:pointer;font-family:inherit">${esc(opt)}</button>`;
215
+ html += `<button onclick="showModal()" style="flex:1;padding:10px 12px;border-radius:8px;border:1px solid #E5E7EB;background:#fff;font-size:14px;color:#374151;cursor:pointer;font-family:inherit">${esc(
216
+ opt,
217
+ )}</button>`;
219
218
  }
220
219
  html += `</div>`;
221
220
  return html;
222
221
  }
223
222
 
224
- function renderSlider(
225
- el: Record<string, unknown>,
226
- accent: string,
227
- ): string {
223
+ function renderSlider(el: Record<string, unknown>, accent: string): string {
228
224
  const label = el.label as string | undefined;
229
225
  const min = el.min as number;
230
226
  const max = el.max as number;
@@ -233,7 +229,9 @@ function renderSlider(
233
229
  const maxLabel = el.maxLabel as string | undefined;
234
230
 
235
231
  const labelHtml = label
236
- ? `<div style="font-size:13px;color:#6B7280;margin-bottom:4px">${esc(label)}</div>`
232
+ ? `<div style="font-size:13px;color:#6B7280;margin-bottom:4px">${esc(
233
+ label,
234
+ )}</div>`
237
235
  : "";
238
236
  const minL = minLabel
239
237
  ? `<span style="font-size:11px;color:#9CA3AF">${esc(minLabel)}</span>`
@@ -250,10 +248,7 @@ function renderTextInput(el: Record<string, unknown>): string {
250
248
  return `<input type="text" placeholder="${placeholder}" disabled style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #E5E7EB;background:#F9FAFB;font-size:14px;color:#9CA3AF;font-family:inherit;box-sizing:border-box">`;
251
249
  }
252
250
 
253
- function renderToggle(
254
- el: Record<string, unknown>,
255
- accent: string,
256
- ): string {
251
+ function renderToggle(el: Record<string, unknown>, accent: string): string {
257
252
  const label = esc(el.label as string);
258
253
  const value = el.value as boolean;
259
254
  const bg = value ? accent : "#D1D5DB";
@@ -264,10 +259,7 @@ function renderToggle(
264
259
  </div>`;
265
260
  }
266
261
 
267
- function renderGroup(
268
- el: Record<string, unknown>,
269
- accent: string,
270
- ): string {
262
+ function renderGroup(el: Record<string, unknown>, accent: string): string {
271
263
  const children = el.children as Array<Record<string, unknown>>;
272
264
  let html = `<div style="display:flex;gap:12px">`;
273
265
  for (const child of children) {
@@ -290,9 +282,14 @@ function renderButtons(
290
282
  layout === "row"
291
283
  ? "flex-direction:row"
292
284
  : layout === "grid"
293
- ? "display:grid;grid-template-columns:1fr 1fr"
294
- : "flex-direction:column";
295
- const wrap = layout === "row" ? "display:flex;" : layout === "grid" ? "" : "display:flex;";
285
+ ? "display:grid;grid-template-columns:1fr 1fr"
286
+ : "flex-direction:column";
287
+ const wrap =
288
+ layout === "row"
289
+ ? "display:flex;"
290
+ : layout === "grid"
291
+ ? ""
292
+ : "display:flex;";
296
293
 
297
294
  let html = `<div style="${wrap}${dir};gap:8px;margin-top:12px">`;
298
295
  for (let i = 0; i < buttons.length; i++) {
@@ -301,8 +298,7 @@ function renderButtons(
301
298
  const style = (btn.style as string) ?? (i === 0 ? "primary" : "secondary");
302
299
  const bg = style === "primary" ? accent : "transparent";
303
300
  const color = style === "primary" ? "#fff" : accent;
304
- const border =
305
- style === "primary" ? "none" : `2px solid ${accent}`;
301
+ const border = style === "primary" ? "none" : `2px solid ${accent}`;
306
302
  html += `<button onclick="showModal()" style="flex:1;padding:10px 16px;border-radius:10px;background:${bg};color:${color};border:${border};font-size:14px;font-weight:600;cursor:pointer;font-family:inherit">${label}</button>`;
307
303
  }
308
304
  html += `</div>`;
@@ -311,27 +307,26 @@ function renderButtons(
311
307
 
312
308
  // ─── Main renderer ──────────────────────────────────────
313
309
 
314
- export function renderSnapPage(
315
- snap: SnapResponse,
316
- snapOrigin: string,
317
- ): string {
310
+ export function renderSnapPage(snap: SnapResponse, snapOrigin: string): string {
318
311
  const page = snap.page;
319
312
  const accent = accentHex(page.theme?.accent);
320
313
 
321
314
  // Extract title for <title> tag
322
315
  const titleEl = page.elements.children.find(
323
- (el) => el.type === "text" && (el as Record<string, unknown>).style === "title",
316
+ (el) =>
317
+ el.type === "text" && (el as Record<string, unknown>).style === "title",
324
318
  ) as Record<string, unknown> | undefined;
325
- const pageTitle = titleEl
326
- ? esc(titleEl.content as string)
327
- : "Farcaster Snap";
319
+ const pageTitle = titleEl ? esc(titleEl.content as string) : "Farcaster Snap";
328
320
 
329
321
  const snapUrl = encodeURIComponent(snapOrigin + "/");
330
322
 
331
323
  // Render elements
332
324
  let elementsHtml = "";
333
325
  for (const el of page.elements.children) {
334
- elementsHtml += `<div style="margin-bottom:12px">${renderElement(el as Record<string, unknown>, accent)}</div>`;
326
+ elementsHtml += `<div style="margin-bottom:12px">${renderElement(
327
+ el as Record<string, unknown>,
328
+ accent,
329
+ )}</div>`;
335
330
  }
336
331
 
337
332
  // Render buttons