Avatar

shawnbasquiat

Previously an Amazon Software Engineer, Building Open-Source Communities for Tech Professionals Site: https://ShawnCharles.com CV: https://ShawnCharles.com/resume
Likes
39
jxnblk avatar
vimarkdown
@jxnblk
HTTP
vimarkdown Try it now A VIM-mode markdown editor built with Val Town . Features Write markdown in the browser with VIM keybindings Minimal, focused UI Saves to localStorage Multiple color modes Markdown -> HTML preview (โŒ˜+P) NOT mobile-friendly Fork this editor on Val Town to make it your own Inspired by iA Writer Made by Jxnblk TODO [ ] Add syntax highlighting to frontmatter block [ ] Support multiple fonts
stevekrouse avatar
sqlite
@stevekrouse
Script
Forked from std/sqlite
maxm avatar
multiplayerCircles
@maxm
HTTP (deprecated)
Multiplayer Circles Move circles around. State is synced with the server. Open a window in another tab and watch the circles update as you move them .
pomdtr avatar
lastlogin
@pomdtr
Script
Lastlogin Authentication for val.town Looking for an hono integration ? See @pomdtr/lastloginHono Support login in trough: Email Link QR Code Google Oauth Github Oauth Gitlab Oauth Facebook Oauth Demo You can try a demo at https://pomdtr-lastloginhonoexample.web.val.run (see @pomdtr/lastLoginHonoExample for code) Usage Wrap your http handlers in a lastlogin middleware (sessions will be persisted in the lastlogin_session table on your sqlite account). If you want to be the only one able to access your val, you can use @pomdtr/verifyUserEmail. import { lastlogin } from "https://esm.town/v/pomdtr/lastlogin"; import { verifyUserEmail } from "https://esm.town/v/pomdtr/verifyUserEmail"; export default lastlogin((req) => { return new Response(`You are logged in as ${req.headers.get("X-LastLogin-Email")}`); }, { // check that the user email match your val town email verifyEmail: verifyUserEmail }); If you want to customize how is allowed to signup, you can set the verifyEmail option: import { lastlogin } from "https://esm.town/v/pomdtr/lastlogin"; export default lastlogin((req) => { return new Response(`You are logged in as ${req.headers.get("X-LastLogin-Email")}`); }, { verifyEmail: (email) => { email == "steve@valtown" } }); You can allow anyone to signup by returning a boolean from the verifyEmail function: import { lastlogin } from "https://esm.town/v/pomdtr/lastlogin"; export default lastlogin((req) => { return new Response(`You are logged in as ${req.headers.get("X-LastLogin-Email")}`); }, { verifyEmail: (_email) => true }); Public Routes import { lastlogin } from "https://esm.town/v/pomdtr/lastlogin"; import { verifyUserEmail } from "https://esm.town/v/pomdtr/verifyUserEmail"; export default lastlogin(() => { return new Response("Hi!"); }, { verifyEmail: verifyUserEmail, public_routes: ["/", "/public/*"], }); See the URLPattern API for reference. Logout Just redirect the user to /auth/logout
stevekrouse avatar
reloadOnSave
@stevekrouse
Script
Forked from stevekrouse/ReloadScript
andreterron avatar
isMyWebsiteDown
@andreterron
Cron
Forked from thierryc/isMyWebsiteDown
andreterron avatar
renderFormAndSaveData
@andreterron
HTTP (deprecated)
Render form and save data This val provides a web-based interface for collecting email addresses. It features a dual-functionality approach: when accessed via a web browser using a GET request, it serves an HTML form where users can submit their email address. If the script receives a POST request, it implies that the form has been submitted, and it proceeds to handle the incoming data. Fork this val to customize it and use it on your account.
stevekrouse avatar
dailyStandupBot
@stevekrouse
Cron
Daily Standup Bot Every weekday at 9am EDT send a message to our team's #engineering Discord channel to start a thread to remind us to do our standup. Slack version: @mikker/dailySlackRoundup Note : We started doing in-person standups at Val Town, so this val was unscheduled. To get it working for you, you'll need to: Fork it Change its type from Script to Cron and set a schedule like 0 13 * * 1-5
pomdtr avatar
password_auth
@pomdtr
Script
Password Auth Middleware Protect your vals behind a password. Use session cookies to persist authentication. Demo See @pomdtr/password_auth_test Usage import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=84"; export default passwordAuth(() => { return new Response("OK"); }, { verifyPassword: (password) => password == Deno.env.get("VAL_PASSWORD") }); If you want to use an api token to authenticate: import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=84"; import { verifyToken } from "https://esm.town/v/pomdtr/verifyToken"; export default passwordAuth(() => { return new Response("OK"); }, { verifyPassword: verifyToken }); TODO [x] allow to authenticate using a val town token [ ] add a way to send an email to ask a password from the val owner [ ] automatically extend the session [ ] automatically remove expired sessions FAQ How to sign out ? Navigate to <your-site>/signout .
andreterron avatar
codeOnValTown
@andreterron
Script
Code on Val Town Adds a "Code on Val Town" ribbon to your page. This lets your website visitors navigate to the code behind it. This uses github-fork-ribbon-css under the hood. Usage Here are 2 different ways to add the "Code on Val Town" ribbon: 1. Wrap your fetch handler (recommended) import { modifyFetchHandler } from "https://esm.town/v/andreterron/codeOnValTown?v=50"; import { html } from "https://esm.town/v/stevekrouse/html?v=5"; export default modifyFetchHandler(async (req: Request): Promise<Response> => { return html(`<h2>Hello world!</h2>`); }); Example: @andreterron/openable_handler 2. Wrap your HTML string import { modifyHtmlString } from "https://esm.town/v/andreterron/codeOnValTown?v=50"; import { html } from "https://esm.town/v/stevekrouse/html?v=5"; export default async (req: Request): Promise<Response> => { return html(modifyHtmlString(`<h2>Hello world!</h2>`)); }; Example: @andreterron/openable_html Other ways We made sure this was very modular, so you can also add the ribbon using these methods: Get the element string directly: @andreterron/codeOnVT_ribbonElement Modify an HTTP Response: @andreterron/codeOnVT_modifyResponse Use .pipeThrough to append to a stream: @andreterron/InjectCodeOnValTownStream Customization Linking to the val These functions infer the val using the call stack or the request URL. If the inference isn't working, or if you want to ensure it links to a specific val, pass the val argument: modifyFetchHandler(handler, {val: { handle: "andre", name: "foo" }}) modifyHtmlString("<html>...", {val: { handle: "andre", name: "foo" }}) Styling You can set the style parameter to a css string to customize the ribbon. Check out github-fork-ribbon-css to learn more about how to style the element. modifyFetchHandler(handler, {style: ".github-fork-ribbon:before { background-color: #333; }"}) modifyHtmlString("<html>...", {style: ".github-fork-ribbon:before { background-color: #333; }"}) Here's how you can hide the ribbon on small screens: modifyFetchHandler(handler, {style: `@media (max-width: 768px) { .github-fork-ribbon { display: none !important; } }`}) To-dos [ ] Let users customize the ribbon. Some ideas are the text, color or placement.
nbbaier avatar
sqliteExplorerApp
@nbbaier
HTTP (deprecated)
SQLite Explorer View and interact with your Val Town SQLite data. It's based off Steve's excellent SQLite Admin val, adding the ability to run SQLite queries directly in the interface. This new version has a revised UI and that's heavily inspired by LibSQL Studio by invisal . This is now more an SPA, with tables, queries and results showing up on the same page. Install Install the latest stable version (v86) by forking this val: Authentication Login to your SQLite Explorer with password authentication with your Val Town API Token as the password. Todos / Plans [ ] improve error handling [ ] improve table formatting [ ] sticky table headers [x] add codemirror [ ] add loading indication to the run button (initial version shipped) [ ] add ability to favorite queries [ ] add saving of last query run for a table (started) [ ] add visible output for non-query statements [ ] add schema viewing [ ] add refresh to table list sidebar after CREATE/DROP/ALTER statements [ ] add automatic execution of initial select query on double click [x] add views to the sidebar [ ] add triggers to sidebar [ ] add upload from SQL, CSV and JSON [ ] add ability to connect to a non-val town Turso database [x] fix wonky sidebar separator height problem (thanks to @stevekrouse) [x] make result tables scrollable [x] add export to CSV, and JSON (CSV and JSON helper functions written in this val . Thanks to @pomdtr for merging the initial version!) [x] add listener for cmd+enter to submit query
stevekrouse avatar
blob_admin
@stevekrouse
HTTP (deprecated)
Forked from stevekrouse/sqlite_admin
pomdtr avatar
extractValInfo
@pomdtr
Script
Extract vals infos (author, name, version) from a val url (either from esm.town or val.town ). Example usage: const {author, name} = extractValInfo(import.meta.url) Also returns a unique slug for the val: <author>/<name>
std avatar
blob
@std
Script
Blob Storage - Docs โ†— Val Town comes with blob storage built-in. It allows for storing any data, like text, JSON, or images. You can access it via std/blob . Blob storage is scoped globally to your account. If you set a blob in one val, you can retrieve it by the same key in another val. It's backed by Cloudflare R2. You may find this admin viewer helpful for viewing and editing your blobs. Get JSON import { blob } from "https://esm.town/v/std/blob"; let blobDemo = await blob.getJSON("myKey"); console.log(blobDemo); // returns `undefined` if not found Set JSON import { blob } from "https://esm.town/v/std/blob"; await blob.setJSON("myKey", { hello: "world" }); List keys import { blob } from "https://esm.town/v/std/blob"; let allKeys = await blob.list(); console.log(allKeys); const appKeys = await blob.list("app_"); console.log(appKeys); // all keys that begin with `app_` Delete by key import { blob } from "https://esm.town/v/std/blob"; await blob.delete("myKey"); Examples Counter RSS Notifications (saving the last run time) Picture: Save & Read Error Handling blob.get can throw ValTownBlobNotFoundError Any method can throw ValTownBlobError for unexpected errors. Utilities Our Blob SDK also includes some utility functions to make working with blobs easier. Copy import { blob } from "https://esm.town/v/std/blob"; await blob.copy("myKey", "myKeyCopy"); Move import { blob } from "https://esm.town/v/std/blob"; await blob.move("myKey", "myKeyNew"); Lower-level API We provide access to the lower-level getter and setters, which are useful if you are storing non-JSON or binary data, need to stream in your response or request data, or do anything else lower-level. async get(key: string) : Retrieves a blob for a given key. async set(key: string, value: string | BodyInit) : Sets the blob value for a given key. See BodyInit . Limitations Blob-stored data counts towards your total Val Town storage โ€“ 10mb on the free plan and 1gb on pro. Check our pricing page to learn more. Keys for blobs can be up to 512 characters long. ๐Ÿ“ Edit docs
stevekrouse avatar
umbrellaReminder
@stevekrouse
Cron
โ˜”๏ธ Umbrella reminder if there's rain today Setup Fork this val ๐Ÿ‘‰ https://val.town/v/stevekrouse.umbrellaReminder/fork Customize the location (line 8). You can supply any free-form description of a location. โš ๏ธ Only works for US-based locations (where weather.gov covers). How it works Geocodes an free-form description of a location to latitude and longitude โ€“ @stevekrouse.nominatimSearch Converts a latitude and longitude to weather.gov grid โ€“ @stevekrouse.weatherGovGrid Gets the hourly forecast for that grid Filters the forecast for periods that are today and >30% chance of rain If there are any, it formats them appropriately, and sends me an email
stevekrouse avatar
getWeather
@stevekrouse
Script
Forked from sdan/getWeather