1import { isValidName } from "../../../shared/mod.ts";2import type { AppInitRequest, AppReservationInfo } from "../../../shared/mod.ts";3import {4 appReservationToInfo,5 getAppReservationByAlias,6 getVaultByName,7 reserveAppOrigin,8} from "../db.ts";9import { type Env, json } from "../env.ts";10import { ApiError, readJson } from "./errors.ts";1112/** Reserve an app hostname permanently before its first build exists. */13export async function handleAppInit(14 request: Request,15 env: Env,16): Promise<Response> {17 const body = await readJson<AppInitRequest>(request);18 const target = body.target;19 if (!target || !isValidName(target.vault) || !isValidName(target.alias)) {20 throw new ApiError(400, "app target must be vault:alias using valid names");21 }22 const vault = await getVaultByName(env, target.vault);23 if (!vault) throw new ApiError(404, `unknown vault: ${target.vault}`);2425 const existed = await getAppReservationByAlias(env, vault.slot, target.alias);26 const reservation = existed ?? await reserveAppOrigin(env, vault, target.alias);27 const info = await appReservationToInfo(env, reservation, vault.name);28 return json<AppReservationInfo>(info, existed ? 200 : 201);29}