// prepare.ts: get a val's directory ready to run on this VM. // // deno run -A ~/vals-kit/prepare.ts ~/vals/ // // Adds to the val's deno.json (keeping what's there) the imports that send // Val Town's std/sqlite, std/blob, std/email and std/openai to this kit, // and "vendor": true, so other remote code is saved in the val's vendor/. // Then lists every line that still depends on Val Town, and exits 1 if any. const dir = Deno.args[0]; if (!dir) throw new Error("usage: prepare.ts "); const kit = new URL(".", import.meta.url).pathname; const imports = JSON.parse(await Deno.readTextFile(`${kit}imports.json`)); let config: Record = {}; try { config = JSON.parse(await Deno.readTextFile(`${dir}/deno.json`)); } catch { /* none yet */ } config.imports = { ...(config.imports as object ?? {}), ...imports }; config.vendor = true; await Deno.writeTextFile(`${dir}/deno.json`, JSON.stringify(config, null, 2) + "\n"); console.log(`${dir}/deno.json: std imports mapped to ${kit}`); const mapped = new Set(Object.keys(imports)); const watch = /esm\.town\/v\/|val\.run|valtown\.email|api\.val\.town|Deno\.env\.get\(["'](valtown|VAL_TOWN_API_KEY)["']\)|@valtown\/sdk/; let left = 0; async function scan(d: string) { for await (const e of Deno.readDir(d)) { const p = `${d}/${e.name}`; if (e.isDirectory) { if (![".git", "vendor", "node_modules", "data", ".vt"].includes(e.name)) await scan(p); } else if (/\.(ts|tsx|js|jsx|mjs|html)$/.test(e.name)) { (await Deno.readTextFile(p)).split("\n").forEach((line, i) => { const url = line.match(/["'](https:\/\/esm\.town\/v\/[^"']+)["']/)?.[1]; if (watch.test(line) && !(url && mapped.has(url))) { left++; console.log(`${p.slice(dir.length + 1)}:${i + 1}: ${line.trim().slice(0, 120)}`); } }); } } } await scan(dir); console.log(left ? `\n${left} lines still use Val Town (see above)` : "nothing left that uses Val Town"); Deno.exit(left ? 1 : 0);