feat: move base URL, API key, and model to server .env

- BASE_URL, API_KEY, MODEL now read from process.env (Bun auto-loads .env)
- requireEnv() fails fast at startup if any is missing
- request body simplifies to { prompt, size, referenceImages? }
- client drops the three fields from form and localStorage
- add .env.example as the variable-name source of truth
- AGENTS.md notes the 0.0.0.0 bind now exposes the upstream quota to
  anyone reachable on the network
This commit is contained in:
2026-05-18 23:28:12 +08:00
parent 4ef2f1ba2b
commit d5bbc14c8d
5 changed files with 64 additions and 62 deletions
+5 -9
View File
@@ -2,13 +2,12 @@ import { fetchEventSource } from "@microsoft/fetch-event-source";
const byId = <T extends HTMLElement>(id: string) =>
document.getElementById(id) as T;
const input = (id: string) => byId<HTMLInputElement>(id);
const select = (id: string) => byId<HTMLSelectElement>(id);
const textarea = (id: string) => byId<HTMLTextAreaElement>(id);
const persistedFields = ["baseURL", "apiKey", "model", "size", "prompt"] as const;
const persistedFields = ["size", "prompt"] as const;
for (const f of persistedFields) {
const el = byId<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>(f);
const el = byId<HTMLSelectElement | HTMLTextAreaElement>(f);
const saved = localStorage.getItem("aip:" + f);
if (saved) el.value = saved;
const save = () => localStorage.setItem("aip:" + f, el.value);
@@ -42,7 +41,7 @@ function renderRefPreview() {
});
}
input("refImages").addEventListener("change", async (e) => {
byId<HTMLInputElement>("refImages").addEventListener("change", async (e) => {
const el = e.target as HTMLInputElement;
const files = Array.from(el.files ?? []);
for (const file of files) {
@@ -67,16 +66,13 @@ byId<HTMLButtonElement>("generate").addEventListener("click", async () => {
const result = byId<HTMLDivElement>("result");
const body = {
baseURL: input("baseURL").value.trim(),
apiKey: input("apiKey").value.trim(),
model: input("model").value.trim(),
size: select("size").value,
prompt: textarea("prompt").value.trim(),
referenceImages: refImages,
};
if (!body.baseURL || !body.apiKey || !body.model || !body.prompt) {
status.textContent = "Please fill in Base URL, API Key, Model and Prompt.";
if (!body.prompt) {
status.textContent = "Please enter a prompt.";
status.className = "status error";
return;
}