Search
tom_og
@tomcritchlow
A simplified version of this: https://www.val.town/v/panphora/canvasText to generate open graph images dynamically for my blog
HTTP
A simplified version of this: https://www.val.town/v/panphora/canvasText to generate open graph images dynamically for my blog
export let canvasText = async (req: Request) => {
const query = new URL(req.url).searchParams;
const { loadImage, createCanvas } = await import(
"https://deno.land/x/canvas/mod.ts"
const canvas = createCanvas(1200, 675);
const ctx = canvas.getContext("2d");
let canvasWidth = canvas.width;
let canvasHeight = canvas.height;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ProfilePage
@iamseeley
An interactive, runnable TypeScript val by iamseeley
Script
/** @jsx jsx */
/** @jsxFrag Fragment */
type ProfilePageProps = {
title: string;
username: string;
name: string;
bio: string;
links: any;
export default function ProfilePage({ username, name, bio, links, title }: ProfilePageProps) {
return (
oldstyle
@easrng
oldstyle bring back the old @import.syntax usage: import oldstyle from "https://esm.town/v/easrng/oldstyle";
const fn = await oldstyle`
export default async () => {
// import vals
const fetchFns = [@std.fetch, @easrng.moduleFetch];
console.log(
await Promise.all(
fetchFns.map((fn) =>
fn("https://icanhazip.com").then((res) => res.text()),
),
),
);
// get environment variables with @me.secrets
console.log(@me.secrets.FORCE_COLOR);
// update vals
console.log(@easrng.counter++);
};
// you don't have to have an export btw
`;
fn();
Script
# oldstyle
bring back the old @import.syntax
## usage:
```tsx
const fn = await oldstyle`
export default async () => {
// (c) easrng 2024
// SPDX-License-Identifier: CC-BY-NC-SA
type Token =
| { type: "StringLiteral"; value: string; closed: boolean }
content_addressable_js
@just_be
Content Addressable JavaScript This is a project I'm working on at the Recurse Center for Impossible Day. The aim is to build a module
system that's a little bit similar to how Unison works. Follow along on my site .
Script
# Content Addressable JavaScript
This is a project I'm working on at the [Recurse Center](https://recurse.com) for Impossible Day. The aim is to build a module
system that's a little bit similar to how [Unison](https://www.unison-lang.org/docs/the-big-idea/) works.
Follow along on [my site](https://just-be.dev/rc/impossible-day).
* Can't do content addressability without a good hash function
* String -> SHA256 hash
const hash = (content: string) =>
crypto.subtle
.digest("SHA-256", new TextEncoder().encode(content))
.then((b) => new Uint8Array(b))
discordEventReceiver
@stevekrouse
An interactive, runnable TypeScript val by stevekrouse
HTTP
export default async function handler(req: Request) {
if (req.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
console.log(await req.json());
return Response.json({ ok: true });
valle_tmp_62963168422172378076257133989442
@janpaul123
An interactive, runnable TypeScript val by janpaul123
HTTP
const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hacker News Clone</title>
<style>
body { font-family: Verdana, Geneva, sans-serif; margin: 0; padding: 0; background: #f6f6ef; }
#header { background: #ff6600; padding: 8px; }
docFeedbackForm
@parkerdavis
Val Town Docs Feedback Form & Handler Live form Val Town Docs YouTube tutorial that explains v17 of this val This feedback form is linked on our docs site. This val renders an HTML form, including pre-fills the user's email address if they've submitted the form in the past (via a cookie), and pre-fills the URL by grabbing it out of the query params. It handles form submissions, including parsing the form, saving the data into @stevekrouse.docsFeedback , a private JSON val, and then returns a thank you message, and set's the user's email address as a cookie, to save them some keystrokes the next time they fill out the form. Another val, @stevekrouse.formFeedbackAlert , polls on an interval for new form submissions, and if it finds any, forwards them on a private Val Town discord channel. There are a number of subtleties to the way each of some features are implemented. A user submitted three pieces of feedback in quick succession, so I thought it'd be nice if we remembered user's email addresses after their first form submissions. There are classically two ways to do this, cookies or localstorage. I choose cookies. It requires setting them in the response header and getting them out of the request header. I used a Deno library to parse the cookie but I set it manually because that seemed simpler. You may be wondering about how I'm getting the referrer out of the query params instead of from the HTTP Referrer header. I tried that at first, but it's increasingly difficult to get path data from it due to more restrictive security policies . So instead I decided to include the URL data in a query param. I get it there via this script in my blog's site: function updateFeedback(ref) {
let feedback = [...document.getElementsByTagName('a')].find(e => e.innerText == 'Feedback')
feedback.setAttribute('href', "https://stevekrouse-docfeedbackform.web.val.run/?ref=" + ref)
}
setTimeout(() => updateFeedback(document.location.href), 100);
navigation.addEventListener('navigate', e => updateFeedback(e.destination.url)); Finally, you may be wondering why I queue up feedback in @stevekrouse.docsFeedback , a private JSON val, and then process it via @stevekrouse.formFeedbackAlert instead of sending it along to Discord directly in this val. I tried that originally but it felt too slow to wait for the API call to Discord before returning the "Thanks for your feedback" message. This is where the context.waitUntil method (that Cloudflare workers and Vercel Edge Functions support) would really come in handy – those allow you to return a Response, and then continue to compute. Currently Val Town requires you to stop all compute with the returning of your Response, so the only way to compute afterwards is to queue it up for another val to take over, and that's what I'm doing here.
HTTP
# Val Town Docs Feedback Form & Handler
* [Live form](https://stevekrouse-docFeedbackForm.web.val.run)
* [Val Town Docs](https://docs.val.town)
* [YouTube tutorial](https://www.youtube.com/watch?v=AEaYaWf5B-I) that explains [v17 of this val](https://www.val.town/v/stevekrouse.docFeedbackForm?v=17)
This feedback form is linked on our docs site.
![Screenshot 2023-09-07 at 14.24.25@2x.png](https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/eec56deb-a070-4d34-f040-c9e55e065e00/public)
export let docFeedbackForm = async (req: Request) => {
if (req.method === "POST") {
let formData = await req.formData();
let data = {
misleadingScarletMongoose
@jeffreyyoung
Shows a inline html and then says meow a few times
https://poe.com/inline_html_test_bot
HTTP
Shows a inline html and then says meow a few times
https://poe.com/inline_html_test_bot
* Returns a response to the user's query
async function getResponse(req: Query, send: SendEventFn) {
send("meta", { content_type: "text/markdown" });
send("text", {
text: `hello I render inline html\n`,
send("text", { text: "<html><body>\n<h1>hello world\n" });
await sleep(3000);
send("text", { text: "</h1>\n</body></html>\n" });
valle_tmp_7777989881357556524901586448784
@janpaul123
// This val will respond with a simple HTML form for users to input their name
HTTP
// This val will respond with a simple HTML form for users to input their name
export default async function (req: Request): Promise<Response> {
if (req.method === "POST") {
const formData = new URLSearchParams(await req.text());
const name = formData.get("name") ?? "Stranger"; // Default to "Stranger" if no name provided
return new Response(`<h1>Hello, ${name}!</h1>`, { headers: { "Content-Type": "text/html" } });
return new Response(`
<html>
<head>
<title>Greetings Form</title>
logRequestExpress
@lirenxn
An interactive, runnable TypeScript val by lirenxn
Express (deprecated)
export const logRequestExpress = (req: express.Request, res: express.Response) => {
return res.json({ req });
valle_tmp_53487231682553289664317124512605
@janpaul123
// This val will respond with a simple "Hello World" HTML page
HTTP
// This val will respond with a simple "Hello World" HTML page
export default async function(req: Request): Promise<Response> {
// HTML content to be sent in the response
const htmlContent = `<html><body><h1>Hello World!</h1></body></html>`;
// Send an HTML response
return new Response(htmlContent, {
headers: {
"Content-Type": "text/html",
oddTanRoundworm
@l2046a
An interactive, runnable TypeScript val by l2046a
HTTP
export default async function(req: Request): Promise<Response> {
if (req.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
status: 204,
const openai = new OpenAI();
try {
var body = await req.json();
labLoginBanUser
@todepond
An interactive, runnable TypeScript val by todepond
HTTP
export default async function(req: Request): Promise<Response> {
const TABLE_NAME = "lab_login_users_with_times";
const body = await req.json();
const { username, password, type, target } = body;
const tpUserQuery = await sqlite.execute({
sql: `SELECT * FROM ${TABLE_NAME} WHERE username = ?`,
args: ["TodePond"],
if (tpUserQuery.rows.length === 0) {
return new Response(JSON.stringify({ error: "admin user not found" }), { status: 404 });
const tpUser = tpUserQuery.rows[0];