3const NEWSLETTER_URL = "https://bytes.dev/archives";
4
5function normalizeURL(url: string) {
6 return url.startsWith("http://") || url.startsWith("https://")
7 ? url
9}
10
11async function fetchText(url: string, options?: any) {
12 const response = await fetch(normalizeURL(url), {
13 redirect: "follow",
2
3// Fetches a random joke.
4async function fetchRandomJoke() {
5 const response = await fetch(
6 "https://official-joke-api.appspot.com/random_joke",
9};
10
11export function authMiddleware(
12 handler: (Request) => Promise<Response>,
13 options: Options,
56}
57
58export default async function(req: Request): Promise<Response> {
59 return new Response("This is middleware only");
60}
15 */
16
17export default async function(req: Request): Promise<Response> {
18 // HANDLE GET REQUEST FOR 'VERIFICATION REQUESTS'
19 if (req.method === "GET") {
10export const blobStore = createStore();
11
12export function createStore<T>(options?: KeyvBlobOptions): Store<T> {
13 const key = options?.key ?? "keyv";
14 return new KeyvLow<T>({
5import ky from "npm:ky";
6
7export default async function(req: Request, options?: {
8 transformReadme: HtmlProcessor;
9}): Promise<Response> {
39}
40
41async function fetchValtownExample(scope: string, name: string, version: string) {
42 const pkgConfig = await getConfig(scope, name, version);
43 version = pkgConfig.version;
8export type HtmlProcessor = (html: string, author: string, name: string) => Promise<string>;
9
10export function serveReadme(
11 valUrl: string | URL,
12 transformHtml: HtmlProcessor = decorateHtml,
25
26export { decorateHtml as transformHtml };
27async function decorateHtml(html: string, author: string, name: string) {
28 html = await appendCodeOnValTownRibbon(html, author, name);
29 html = await appendPersonalizedFooter(html);
31}
32
33export async function appendCodeOnValTownRibbon(html: string, author: string, name: string) {
34 const { ribbonElement } = await import("https://esm.town/v/andreterron/codeOnVT_ribbonElement?v=7");
35 const fragment = ribbonElement({ val: { handle: author, name } });
37}
38
39export async function appendPersonalizedFooter(html: string) {
40 const { MyFooter: createMyFooter } = await import("https://esm.town/v/vladimyr/MyFooter");
41 const style = `<style>
54}
55
56async function readmeToHtml(readme: string, author: string, name: string) {
57 return linkifyReadme(
58 await gfm(readme, {
15export const sqliteStore = createStore();
16
17export function createStore<T>(options?: KeyvSqliteOptions): Store<T> {
18 return new KeyvSql({
19 ...options,
23}
24
25async function connect() {
26 return async function query(sql: string): Promise<Record<string, any>[]> {
27 const { columns, rows } = await sqlite.execute(sql);
28 return rows.map(row => {
36 tables: string[];
37};
38function parseOptions(params: URLSearchParams): GenerateOptions {
39 const camelCase = params.has("camelCase") ? params.get("camelCase") === "true" : undefined;
40 const excludePattern = params.get("excludePattern") ?? undefined;
54 };
55}
56export default async function(req: Request): Promise<Response> {
57 const url = new URL(req.url);
58 if (url.pathname !== "/") return new Response(null, { status: 404 });
39});
40
41export async function getLatestVersion(scope: string, name: string) {
42 scope = normalizeScope(scope);
43 const data = await client.get(`@${scope}/${name}/meta.json`).json();
45}
46
47export async function getManifest(scope: string, name: string, version = "latest") {
48 scope = normalizeScope(scope);
49 if (version === "latest") {
54}
55
56export async function getConfig(scope: string, name: string, version: string) {
57 scope = normalizeScope(scope);
58 const manifest = await getManifest(scope, name, version);
64}
65
66function normalizeScope(input: string) {
67 if (!input.startsWith("@")) return input;
68 return input.slice(1);