4 * Creates a new project from a list of val URLs
5 */
6export async function createProjectFromVals(apiKey: string, vals: ValInfo[], customProjectName?: string): Promise<ConversionResult> {
7 try {
8 // Validate inputs
9 if (!apiKey) {
10 throw new Error("API key is required");
11 }
12
38
39 // Create a new project
40 const projectResponse = await fetch("https://api.val.town/v1/projects", {
41 method: "POST",
42 headers: {
43 "Authorization": `Bearer ${apiKey}`,
44 "Content-Type": "application/json",
45 },
69 try {
70 // Fetch the val details
71 const valResponse = await fetch(`https://api.val.town/v1/alias/${valInfo.username}/${valInfo.valName}`, {
72 headers: { "Authorization": `Bearer ${apiKey}` },
73 });
74
114 const encodedPath = encodeURIComponent(filePath);
115
116 const fileResponse = await fetch(`https://api.val.town/v1/projects/${project.id}/files/${encodedPath}`, {
117 method: "POST",
118 headers: {
119 "Authorization": `Bearer ${apiKey}`,
120 "Content-Type": "application/json",
121 },
139 // Generate and add README.md
140 const readmeContent = generateReadme(project.name, vals, convertedVals);
141 await fetch(`https://api.val.town/v1/projects/${project.id}/files/README.md`, {
142 method: "POST",
143 headers: {
144 "Authorization": `Bearer ${apiKey}`,
145 "Content-Type": "application/json",
146 },
193app.get("/frontend/**/*", c => serveFile(c.req.path, import.meta.url));
194
195// Add your API routes here
196// app.get("/api/data", c => c.json({ hello: "world" }));
197
198// Unwrap and rethrow Hono errors as the original error
4export function App() {
5 const [projectUrl, setProjectUrl] = useState("");
6 const [apiToken, setApiToken] = useState("");
7 const [loading, setLoading] = useState(false);
8 const [message, setMessage] = useState("");
21 }
22
23 if (!apiToken.trim()) {
24 throw new Error("API Token is required");
25 }
26
28 method: "POST",
29 headers: {
30 "Authorization": `Bearer ${apiToken}`,
31 "Content-Type": "application/json",
32 },
63 value={projectUrl}
64 onChange={(e) => setProjectUrl(e.target.value)}
65 placeholder="https://api.val.town/v1/projects/..."
66 className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-purple-500"
67 />
69
70 <div>
71 <label htmlFor="apiToken" className="block text-sm font-medium text-gray-700 mb-1">
72 Val Town API Token (project read + write permissions)
73 </label>
74 <input
75 id="apiToken"
76 type="password"
77 value={apiToken}
78 onChange={(e) => setApiToken(e.target.value)}
79 placeholder="Enter your API token"
80 className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-purple-500"
81 />
16});
17
18// Attach Blackjack routes under /api
19app.route("/api", gameRouter);
20
21// Fire up the server. By default, "hono run" listens on port 8787
7 * Optimisitically types the values we expect in our environment and context:
8 *
9 * - `Bindings` determines env vars, accessed via `c.env.NAME_OF_VAR` in api handlers
10 * - `Variables` determines context vars, accessed via `c.get("NAME_OF_VAR")` in api handlers
11 */
12export type AppType = {
3This is a template for a [HONC](https://honc.dev) project inside ValTown. You should just be able to fork it and get going. It uses:
4
5- Hono for the API
6- Drizzle for the ORM
7- ValTown sqlite for the DB
8- ValTown as the Cloud
9- Fiberplane as the API Explorer
10
11There's a list of example HONC apps for inspiration on GitHub: [here](https://github.com/fiberplane/awesome-honc) and [here](https://github.com/fiberplane/create-honc-app/tree/main/examples)
1import { createFiberplane, createOpenAPISpec } from "./deps/fiberplane.ts";
2import { Hono, HTTPException } from "./deps/hono.ts";
3
4import homePage from "./app/home.tsx";
5import type { AppType } from "./app/types.ts";
6import usersApi from "./app/users.ts";
7import { db } from "./db/client.ts";
8import { migrateDatabase } from "./db/migrate.ts";
22});
23
24/** Mount the user management API at `/api/users` */
25app.route("/api/users", usersApi);
26
27/** Render a Home page (example of using Hono with JSX) */
28app.route("/", homePage);
29
30/** Create a simplified openapi spec that just lists the routes in our app */
31app.get("/openapi.json", async c => {
32 return c.json(
33 createOpenAPISpec(app, {
34 openapi: "3.0.0",
35 info: {
36 title: "Honc D1 App",
42
43/**
44 * Mount the Fiberplane api playground
45 * Visit /fp to view the UI
46 */
48 "/fp/*",
49 createFiberplane({
50 openapi: { url: "/openapi.json" },
51 }),
52);
63/**
64 * Wrap the incoming request, inject the Deno env vars into the Hono app,
65 * and then call the Hono api entrypoint (`app.fetch`)
66 */
67export default async function(req: Request): Promise<Response> {
68 const env = Deno.env.toObject();
69 // NOTE - Adding the entire env object will also expose the following values to your api handlers:
70 //
71 // * `valtown`
72 // * `VAL_TOWN_API_KEY`
73 // * `VALTOWN_API_URL`
74 //
75 // If you don't want those values, remove them from the env object
37 </head>
38 <body class={bodyStyles}>
39 <h1>🪿 Welcome to my HONC API! 🪿</h1>
40 <p>
41 Visit <a href="/fp" class={linkStyles}>/fp</a> to view the Fiberplane API explorer.
42 </p>
43 </body>
1import { createFiberplane, createOpenAPISpec } from "https://esm.sh/@fiberplane/hono@0.4.4";
2
3export { createFiberplane, createOpenAPISpec };
12app.get("/frontend/**/*", c => serveFile(c.req.path, import.meta.url));
13
14// Add your API routes here
15// app.get("/api/data", c => c.json({ hello: "world" }));
16
17// Unwrap and rethrow Hono errors as the original error