feat: harden storyforge production baseline

This commit is contained in:
kris
2026-03-26 19:33:36 +08:00
parent 38b02a9799
commit a30ed8decd
9 changed files with 1883 additions and 20 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,17 @@
const getCapabilities = typeof options.getCapabilities === "function" ? options.getCapabilities : () => null;
const defaultBackendUrl = normalizeBackendUrl(options.defaultBackendUrl, detectDefaultBackendUrl());
function createApiError(response, payload) {
const detail = typeof payload === "object" && payload
? payload.detail || payload.message || JSON.stringify(payload)
: String(payload || response.statusText);
const error = new Error(detail);
error.status = response.status;
error.statusText = response.statusText;
error.payload = payload;
return error;
}
function resolveBackendUrl(requestOptions = {}) {
return normalizeBackendUrl(
requestOptions.backendUrl || getSession()?.backendUrl || defaultBackendUrl,
@@ -57,10 +68,7 @@
const isJson = (response.headers.get("content-type") || "").includes("application/json");
const payload = isJson ? await response.json() : await response.text();
if (!response.ok) {
const detail = typeof payload === "object" && payload
? payload.detail || payload.message || JSON.stringify(payload)
: String(payload || response.statusText);
throw new Error(detail);
throw createApiError(response, payload);
}
return payload;
}
@@ -71,10 +79,7 @@
const payload = (response.headers.get("content-type") || "").includes("application/json")
? await response.json().catch(() => null)
: await response.text().catch(() => "");
const detail = typeof payload === "object" && payload
? payload.detail || payload.message || JSON.stringify(payload)
: String(payload || response.statusText);
throw new Error(detail);
throw createApiError(response, payload);
}
return response.blob();
}

View File

@@ -716,6 +716,30 @@ select {
cursor: pointer;
}
.quota-notice {
margin-top: 14px;
border-color: rgba(228, 103, 103, 0.18);
background:
linear-gradient(180deg, rgba(255, 245, 245, 0.98) 0%, rgba(255, 255, 255, 0.96) 100%);
}
.quota-notice .task-item {
border-color: rgba(228, 103, 103, 0.14);
background: linear-gradient(180deg, rgba(255, 251, 251, 0.98) 0%, rgba(255, 255, 255, 0.98) 100%);
}
.quota-notice .mini-card {
background: rgba(255, 255, 255, 0.92);
}
.quota-notice .mini-card strong {
font-size: 15px;
}
.quota-notice .tag.red {
background: rgba(228, 103, 103, 0.14);
}
.integration-panel {
display: grid;
gap: 14px;