Avatar

karfau

Joined August 11, 2023
Likes
33
saolsen avatar
telemetry
@saolsen
Script
Telemetry For Vals. Telemetry is a library that lets you trace val town executions with opentelemetry. All traces are stored in val.town sqlite and there is an integrated trace viewer to see them. Quickstart Instrument an http val like this. import { init, tracedHandler, } from "https://esm.town/v/saolsen/telemetry"; // Set up tracing by passing in `import.meta.url`. // be sure to await it!!! await init(import.meta.url); async function handler(req: Request): Promise<Response> { // whatever else you do. return } export default tracedHandler(handler); This will instrument the http val and trace every request. Too add additional traces see this widgets example . Then, too see your traces create another http val like this. import { traceViewer } from "https://esm.town/v/saolsen/telemetry"; export default traceViewer; This val will serve a UI that lets you browse traces. For example, you can see my UI here . Tracing By wrapping your http handler in tracedHandler all your val executions will be traced. You can add additional traces by using the helpers. trace lets you trace a block of syncronous code. import { trace } from "https://esm.town/v/saolsen/telemetry"; trace("traced block", () => { // do something }); traceAsync lets you trace a block of async code. import { traceAsync } from "https://esm.town/v/saolsen/telemetry"; await traceAsync("traced block", await () => { // await doSomething(); }); traced wraps an async function in tracing. import { traceAsync } from "https://esm.town/v/saolsen/telemetry"; const myTracedFunction: () => Promise<string> = traced( "myTracedFunction", async () => { // await sleep(100); return "something"; }, ); fetch is a traced version of the builtin fetch function that traces the request. Just import it and use it like you would use fetch . sqlite is a traced version of the val town sqlite client. Just import it and use it like you would use https://www.val.town/v/std/sqlite attribute adds an attribute to the current span, which you can see in the UI. event adds an event to the current span, which you can see in the UI.
nbbaier avatar
shell
@nbbaier
HTTP
Just wanted to see if this works and it does. Try sh <(curl -s https://nbbaier-shell.web.val.run)
rlesser avatar
dependency_graph
@rlesser
HTTP
An interactive, runnable TypeScript val by rlesser
rlesser avatar
getDependencyGraph
@rlesser
Script
Dependency Graph Explorer This val allows for dependency graph exploration. getDependencyGraph Iteratively explores the dependency graph of a val and its children, returning the results. arguments valUrlOrSlug string - the full val url or slug ( author/name ) of the val returns An object containing: dependencyMap Map<string, string[]> - A map of vals (by id) to dependencies (vals or non-val id) moduleMap Map<string, Module> - A map of modules (by val or non-val id) to module information. Module object contains: slug string - the slug of the module, how it should be displayed visually id string - the id of the module, corresponding to how it's displayed in the code, normally as a url. websiteUrl string - the website link for the module, a normally a link to either valtown or npm. category string|null - the category of the module, such as "valtown", "esm.sh", or "npm". Those without a predefined category are in null.
nbbaier avatar
honoZodSwaggerUi
@nbbaier
HTTP
// The OpenAPI documentation will be available at /doc
karfau avatar
aocXX_00
@karfau
Script
Forked from karfau/aoc15_03
pomdtr avatar
lowdb_example
@pomdtr
Script
Lowdb Example This val demonstrates the integration between valtown and lowdb . Read the Lodash section if you want to give superpowers to your DB.
pomdtr avatar
lowdb
@pomdtr
Script
Val Town Adapter for lowdb @std/blob is used as a lowdb sync. See @pomdtr/lowdb_example for example usage.
tmcw avatar
oldfashioned
@tmcw
HTTP (preview)
@jsxImportSource npm:hono/jsx
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>
fil avatar
earthquakes
@fil
HTTP
Earthquake map 🌏 This val loads earthquake data from USGS, a topojson file for the land shape, and supporting libraries. It then creates a map and save it as a SVG string. The result is cached for a day. Note that we must strive to keep it under val.town’s limit of 100kB, hence the heavy simplification of the land shape. (For a simpler example, see becker barley .) | | | |-----|-----| | Web page | https://fil-earthquakes.web.val.run/ | | Observable Plot | https://observablehq.com/plot/ | | linkedom | https://github.com/WebReflection/linkedom | | topojson | https://github.com/topojson/topojson | | earthquakes | https://earthquake.usgs.gov | | world | https://observablehq.com/@visionscarto/world-atlas-topojson | | css | https://milligram.io/ |
karfau avatar
test_getRaw
@karfau
Script
An interactive, runnable TypeScript val by karfau
karfau avatar
getRaw
@karfau
Script
A helper to get the raw data of a val, using the very nice implementation from @pomdtr.raw . Usage: https://www.val.town/v/karfau.test_getRaw Also look at @karfau.rawUrl to just get the raw url of another val inside a val.
karfau avatar
rawUrl
@karfau
Script
A helper for creating the URL to request the raw data of a val, defaulting to use the very nice implementation from @pomdtr.raw . Also look at @karfau.getRaw to get the data of a val inside a val.
zackoverflow avatar
minizod
@zackoverflow
Script
minizod Tiny Zod implementation. Why Zod is a dense library, and its module structure (or lack thereof) makes it difficult for bundlers to tree-shake unused modules . Additionally, using Zod in vals requires the await import syntax which means having to wrap every schema in a Promise and awaiting it. This is extremely annoying. So this is a lil-tiny-smol Zod meant for use in vals. A noteworthy use-case is using minizod to generate tyep-safe API calls to run vals outside of Val Town (such as client-side). Type-safe API call example We can use minizod to create type safe HTTP handlers and generate the corresponding code to call them using Val Town's API, all in a type-safe manner. First, create a schema for a function. The following example defines a schema for a function that takes a { name: string } parameter and returns a Promise<{ text: string }> . const minizodExampleSchema = () => @zackoverflow.minizod().chain((z) => z .func() .args(z.tuple().item(z.object({ name: z.string() }))) .ret(z.promise().return(z.object({ text: z.string() }))) ); With a function schema, you can then create an implementation and export it as a val: const minizodExample = @me.minizodExampleSchema().impl(async ( { name }, ) => ({ text: `Hello, ${name}!` })).json() In the above example, we call .impl() on a function schema and pass in a closure which implements the actual body of the function. Here, we simply return a greeting to the name passed in. We can call this val, and it will automatically parse and validate the args we give it: // Errors at compile time and runtime for us! const response = @me.minizodExample({ name: 420 }) Alternatively, we can use the .json() function to use it as a JSON HTTP handler: const minizodExample = @me.minizodExampleSchema().impl(async ( { name }, ) => ({ text: `Hello, ${name}!` })).json() // <-- this part We can now call minizodExample through Val Town's API. Since we defined a schema for it, we know exactly the types of its arguments and return, which means we can generate type-safe code to call the API: let generatedApiCode = @zackoverflow.minizodFunctionGenerateTypescript( // put your username here "zackoverflow", "minizodExample", // put your auth token here "my auth token", @me.minizodExampleSchema(), ); This generates the following the code: export const fetchMinizodExample = async ( ...args: [{ name: string }] ): Promise<Awaited<Promise<{ text: string }>>> => await fetch(`https://api.val.town/v1/run/zackoverflow.minizodExample`, { method: "POST", body: JSON.stringify({ args: [...args], }), headers: { Authorization: "Bearer ksafajslfkjal;kjf;laksjl;fajsdf", }, }).then((res) => res.json());
karfau avatar
SignatureCheck
@karfau
Script
This val has been created to avoid certain shortcomings of @vtdocs.verifyGithubWebhookSignature . So it was created as a mix/evolution of two sources: The github docs about securing webhook Some code from the @octokit/webhhokmethods package This code is covered by tests which you can copy to run them, see @karfau.test_SignatureCheck This val does not contain any val.town specific code ( @ -imports, console.email ...), so it should be possible to run in Deno as is, potentially even in modern browsers (that support crypto and TextEncoder and modern ES syntax). Usage const myGithubWebhook = (req: Request) => { const {verify} = @karfau.SignatureCheck(); // you have to call it to get the verify function! const body = await req.text(); const signature = req.headers.get("X-Hub-Signature-256"); const verified = await verify( {payload:body, signature}, @me.secrets.myGithubWebhookSecret, // optionally provide fallback secrets (as many as needed) // @me.secrets.myGithubWebhookSecretFallback ); if (!verified) { return new Response(`Not verified`, 401); } const payload = JSON.parse(body); // actually do things in your webhook }; By default the reason for failing verification is logged to console.error , but you can pass it a different handler: const {verify} = @karfau.SignatureCheck((reason) => { throw new Error(reason); }); (be aware that it will silently fail if you don't try catch it in an endpoint and the return code will be 502) Why @vtdocs.verifyGithubWebhookSignature has the following issues: it relies on the verify method of the outdated @octokit/webhooks-methods@3.0.2 which has (at least) two bugs that can make a difference when used in a webhook it can throws errors instead of just returning false , which can be triggered by sending an invalid signature it can be lured into checking a SHA1 signature if the signature header starts with sha1= you need to pass the secret and payload as argument to the val, which makes them appear in the evaluation logs you produce ( they are only visible for the author of the val if you run them as an API , but it still feels odd to see the secret in the evaluation logs.) parameters are all of type string and the order can be confused you can not use fallback secrets for rotating