Refactor proxyFetch and enhance MediaProviderDetailPage layout

- Removed the isCloud check from proxyFetch.js, simplifying the fetch patching logic.
- Updated MediaProviderDetailPage to include a new section for API key retrieval, improving user experience with clearer layout and additional notice text.
- Enhanced ConnectionRow to better handle email display names.
- Improved ProviderDetailPage to conditionally render provider notices and API key links.
- Refactored localDb, requestDetailsDb, and usageDb to remove unnecessary isCloud checks, streamlining database interactions.
- Updated OAuthModal to combine waiting and manual input steps for a more cohesive user flow.
- Added API key URLs to several providers in providers.js for better accessibility.
This commit is contained in:
decolua
2026-05-01 17:03:13 +07:00
parent f8d2a9ff76
commit f410061e70
9 changed files with 144 additions and 147 deletions

View File

@@ -7,10 +7,9 @@ import lockfile from "proper-lockfile";
import { DATA_DIR } from "@/lib/dataDir.js";
const DEFAULT_MITM_ROUTER_BASE = "http://localhost:20128";
const isCloud = typeof caches !== 'undefined' || typeof caches === 'object';
const DB_FILE = isCloud ? null : path.join(DATA_DIR, "db.json");
const DB_FILE = path.join(DATA_DIR, "db.json");
if (!isCloud && !fs.existsSync(DATA_DIR)) {
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
}
@@ -57,7 +56,7 @@ function cloneDefaultData() {
};
}
if (!isCloud && DB_FILE && !fs.existsSync(DB_FILE)) {
if (!fs.existsSync(DB_FILE)) {
fs.writeFileSync(DB_FILE, JSON.stringify(cloneDefaultData(), null, 2));
}
@@ -144,11 +143,6 @@ class LocalMutex {
const localMutex = new LocalMutex();
async function withFileLock(db, operation) {
if (isCloud) {
await operation();
return;
}
const releaseLocal = await localMutex.acquire();
let release = null;
try {
@@ -176,15 +170,6 @@ async function safeWrite(db) {
}
export async function getDb() {
if (isCloud) {
if (!dbInstance) {
const data = cloneDefaultData();
dbInstance = new Low({ read: async () => { }, write: async () => { } }, data);
dbInstance.data = data;
}
return dbInstance;
}
if (!dbInstance) {
dbInstance = new Low(new JSONFile(DB_FILE), cloneDefaultData());
}

View File

@@ -4,24 +4,21 @@ import path from "node:path";
import fs from "node:fs";
import { DATA_DIR } from "@/lib/dataDir.js";
const isCloud = typeof caches !== "undefined" && typeof caches === "object";
const DEFAULT_MAX_RECORDS = 200;
const DEFAULT_BATCH_SIZE = 20;
const DEFAULT_FLUSH_INTERVAL_MS = 5000;
const DEFAULT_MAX_JSON_SIZE = 5 * 1024; // 5KB default, configurable via settings
const CONFIG_CACHE_TTL_MS = 5000;
const MAX_TOTAL_DB_SIZE = 50 * 1024 * 1024; // 50MB hard limit for total DB file
const DB_FILE = isCloud ? null : path.join(DATA_DIR, "request-details.json");
const DB_FILE = path.join(DATA_DIR, "request-details.json");
if (!isCloud && !fs.existsSync(DATA_DIR)) {
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
}
let dbInstance = null;
async function getDb() {
if (isCloud) return null;
if (!dbInstance) {
const adapter = new JSONFile(DB_FILE);
const db = new Low(adapter, { records: [] });
@@ -107,7 +104,7 @@ function generateDetailId(model) {
}
async function flushToDatabase() {
if (isCloud || isFlushing || writeBuffer.length === 0) return;
if (isFlushing || writeBuffer.length === 0) return;
isFlushing = true;
try {
@@ -178,8 +175,6 @@ async function flushToDatabase() {
}
export async function saveRequestDetail(detail) {
if (isCloud) return;
const config = await getObservabilityConfig();
if (!config.enabled) return;
@@ -197,10 +192,6 @@ export async function saveRequestDetail(detail) {
}
export async function getRequestDetails(filter = {}) {
if (isCloud) {
return { details: [], pagination: { page: 1, pageSize: 50, totalItems: 0, totalPages: 0, hasNext: false, hasPrev: false } };
}
const db = await getDb();
let records = [...db.data.records];
@@ -228,8 +219,6 @@ export async function getRequestDetails(filter = {}) {
}
export async function getRequestDetailById(id) {
if (isCloud) return null;
const db = await getDb();
return db.data.records.find(r => r.id === id) || null;
}
@@ -241,8 +230,6 @@ const _shutdownHandler = async () => {
};
function ensureShutdownHandler() {
if (isCloud) return;
// Remove any previously registered listeners from this module (hot-reload safety)
process.off("beforeExit", _shutdownHandler);
process.off("SIGINT", _shutdownHandler);

View File

@@ -5,12 +5,11 @@ import path from "path";
import fs from "fs";
import { DATA_DIR } from "@/lib/dataDir.js";
const isCloud = typeof caches !== 'undefined' || typeof caches === 'object';
const DB_FILE = isCloud ? null : path.join(DATA_DIR, "usage.json");
const LOG_FILE = isCloud ? null : path.join(DATA_DIR, "log.txt");
const DB_FILE = path.join(DATA_DIR, "usage.json");
const LOG_FILE = path.join(DATA_DIR, "log.txt");
// Ensure data directory exists
if (!isCloud && fs && typeof fs.existsSync === "function") {
if (fs && typeof fs.existsSync === "function") {
try {
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
@@ -231,15 +230,6 @@ export async function getActiveRequests() {
* Get usage database instance (singleton)
*/
export async function getUsageDb() {
if (isCloud) {
// Return in-memory DB for Workers
if (!dbInstance) {
dbInstance = new Low({ read: async () => {}, write: async () => {} }, defaultData);
dbInstance.data = defaultData;
}
return dbInstance;
}
if (!dbInstance) {
const adapter = new JSONFile(DB_FILE);
dbInstance = new Low(adapter, defaultData);
@@ -279,8 +269,6 @@ export async function getUsageDb() {
* @param {object} entry - Usage entry { provider, model, tokens: { prompt_tokens, completion_tokens, ... }, connectionId?, apiKey? }
*/
export async function saveRequestUsage(entry) {
if (isCloud) return; // Skip saving in Workers
try {
const db = await getUsageDb();
@@ -366,8 +354,6 @@ function formatLogDate(date = new Date()) {
* Format: datetime(dd-mm-yyyy h:m:s) | model | provider | account | tokens sent | tokens received | status
*/
export async function appendRequestLog({ model, provider, connectionId, tokens, status }) {
if (isCloud) return; // Skip logging in Workers
try {
const timestamp = formatLogDate();
const p = provider?.toUpperCase() || "-";
@@ -406,8 +392,6 @@ export async function appendRequestLog({ model, provider, connectionId, tokens,
* Get last N lines of log.txt
*/
export async function getRecentLogs(limit = 200) {
if (isCloud) return []; // Skip in Workers
// Runtime check: ensure fs module is available
if (!fs || typeof fs.existsSync !== "function") {
console.error("[usageDb] fs module not available in this environment");