refactor: implement path utilities, add custom date formatting, improve type safety, and unify database imports

This commit is contained in:
diegosouzapw 2026-04-21 19:56:04 -03:00
parent 098639e146
commit 98c5b250b9
6 changed files with 96 additions and 12 deletions

View file

@ -1944,7 +1944,11 @@ async function handleRoundRobinCombo({
// Extract error info
let errorText = result.statusText || "";
let retryAfter = null;
let errorBody: { error?: { code?: string | null; message?: string | null } } | null = null;
let errorBody: {
error?: { code?: string | null; message?: string | null } | string;
message?: string | null;
retryAfter?: number | string | null;
} | null = null;
try {
const cloned = result.clone();
try {

View file

@ -1,9 +1,18 @@
"use client";
import { useState, useEffect } from "react";
import Card from "@/shared/components/Card";
import EmptyState from "@/shared/components/EmptyState";
import { formatDistanceToNow } from "date-fns";
import { Card, EmptyState } from "@/shared/components";
function formatDistanceToNow(timestamp: number) {
const seconds = Math.floor(Date.now() / 1000 - timestamp);
if (seconds < 60) return `${seconds}s ago`;
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
const days = Math.floor(hours / 24);
return `${days}d ago`;
}
export default function BatchPage() {
const [batches, setBatches] = useState([]);
@ -70,7 +79,7 @@ export default function BatchPage() {
</span>
</div>
<span className="text-xs text-text-muted">
{formatDistanceToNow(batch.createdAt, { addSuffix: true })}
{formatDistanceToNow(batch.createdAt)}
</span>
</div>
@ -121,9 +130,7 @@ export default function BatchPage() {
<div className="flex items-center gap-2">
<span className="font-mono text-sm font-semibold">{file.id}</span>
</div>
<span className="text-xs text-text-muted">
{formatDistanceToNow(file.createdAt, { addSuffix: true })}
</span>
<span className="text-xs text-text-muted">{formatDistanceToNow(file.createdAt)}</span>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">

View file

@ -1,12 +1,15 @@
import { NextResponse } from "next/server";
import { getProviderConnectionById } from "@/models";
import {
isClaudeCodeCompatibleProvider,
isOpenAICompatibleProvider,
isAnthropicCompatibleProvider,
} from "@/shared/constants/providers";
import { PROVIDER_MODELS } from "@/shared/constants/models";
import { getModelIsHidden, resolveProxyForProvider } from "@/lib/localDb";
import {
getProviderConnectionById,
getModelIsHidden,
resolveProxyForProvider,
} from "@/lib/localDb";
import {
SAFE_OUTBOUND_FETCH_PRESETS,
getSafeOutboundFetchErrorStatus,

66
src/lib/dataPaths.js Normal file
View file

@ -0,0 +1,66 @@
"use strict";
var __importDefault =
(this && this.__importDefault) ||
function (mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.APP_NAME = void 0;
exports.getLegacyDotDataDir = getLegacyDotDataDir;
exports.getDefaultDataDir = getDefaultDataDir;
exports.resolveDataDir = resolveDataDir;
exports.isSamePath = isSamePath;
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
exports.APP_NAME = "omniroute";
function fallbackHomeDir() {
const envHome = process.env.HOME || process.env.USERPROFILE;
if (typeof envHome === "string" && envHome.trim().length > 0) {
return path_1.default.resolve(envHome);
}
return os_1.default.tmpdir();
}
function safeHomeDir() {
try {
return os_1.default.homedir();
} catch {
return fallbackHomeDir();
}
}
function normalizeConfiguredPath(dir) {
if (typeof dir !== "string") return null;
const trimmed = dir.trim();
if (!trimmed) return null;
return path_1.default.resolve(trimmed);
}
function getLegacyDotDataDir() {
return path_1.default.join(safeHomeDir(), `.${exports.APP_NAME}`);
}
function getDefaultDataDir() {
const homeDir = safeHomeDir();
if (process.platform === "win32") {
const appData = process.env.APPDATA || path_1.default.join(homeDir, "AppData", "Roaming");
return path_1.default.join(appData, exports.APP_NAME);
}
// Support XDG on Linux/macOS when explicitly configured.
const xdgConfigHome = normalizeConfiguredPath(process.env.XDG_CONFIG_HOME);
if (xdgConfigHome) {
return path_1.default.join(xdgConfigHome, exports.APP_NAME);
}
return getLegacyDotDataDir();
}
function resolveDataDir({ isCloud = false } = {}) {
if (isCloud) return "/tmp";
const configured = normalizeConfiguredPath(process.env.DATA_DIR);
if (configured) return configured;
return getDefaultDataDir();
}
function isSamePath(a, b) {
if (!a || !b) return false;
const normalizedA = path_1.default.resolve(a);
const normalizedB = path_1.default.resolve(b);
if (process.platform === "win32") {
return normalizedA.toLowerCase() === normalizedB.toLowerCase();
}
return normalizedA === normalizedB;
}

4
tests/scratch_test.mjs Normal file
View file

@ -0,0 +1,4 @@
import { getDbInstance } from "../src/lib/db/core.ts";
import { runMigrations, getMigrationStatus } from "../src/lib/db/migrationRunner.ts";
const db = getDbInstance();
console.log(getMigrationStatus(db).pending);

View file

@ -6,8 +6,8 @@ import {
withInjectionGuard,
} from "../../src/middleware/promptInjectionGuard.ts";
async function withEnv(overrides, fn) {
const originals = {};
async function withEnv(overrides: Record<string, string | undefined>, fn: any) {
const originals: Record<string, string | undefined> = {};
for (const [key, value] of Object.entries(overrides)) {
originals[key] = process.env[key];