mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
- bin/cli/CONVENTIONS.md: fonte normativa de flags, exit codes, output,
retry/backoff, i18n, secrets, auditoria de ações destrutivas
- bin/cli/api.mjs: apiFetch() com retry/backoff, Retry-After, ApiError,
statusToExitCode, isServerUp; computeBackoff/shouldRetryStatus exportados
- bin/cli/runtime.mjs: withRuntime/withHttp/withDb — server-first / DB-fallback;
ServerOfflineError com exitCode 3
- bin/cli/i18n.mjs: t() com Map achatado (sem bracket em prototype), interpolação
{vars}, setLocale/detectLocale/resetForTests; hardened contra __proto__ traversal
- bin/cli/output.mjs: emit() (table/json/jsonl/csv), EXIT_CODES, maskSecret,
printSuccess/printError/printWarning/exitWith; output → stdout, diagnóstico → stderr
- bin/cli/locales/en.json + pt-BR.json: strings base (setup/doctor/providers/
keys/combo/serve/backup/update/health/mcp/tunnel)
- bin/cli/README.md: mapa da estrutura e guia de uso dos helpers
- tests/unit/cli-exit-codes.test.ts: 10 casos — EXIT_CODES, statusToExitCode,
backoff exponencial, jitter ±25%, t() i18n com pt-BR e anti-__proto__
- .env.example + docs/reference/ENVIRONMENT.md: documentar 4 novas env vars CLI
(OMNIROUTE_LANG, OMNIROUTE_CLI_TOKEN, OMNIROUTE_HTTP_TIMEOUT_MS, OMNIROUTE_VERBOSE)
- scripts/check/check-env-doc-sync.mjs: adicionar LC_MESSAGES ao allowlist de sistema
73 lines
1.5 KiB
JavaScript
73 lines
1.5 KiB
JavaScript
import { apiFetch, isServerUp } from "./api.mjs";
|
|
import { openOmniRouteDb } from "./sqlite.mjs";
|
|
|
|
export class ServerOfflineError extends Error {
|
|
constructor(message = "Server is offline and operation requires HTTP runtime") {
|
|
super(message);
|
|
this.name = "ServerOfflineError";
|
|
this.exitCode = 3;
|
|
}
|
|
}
|
|
|
|
function makeHttpContext(opts) {
|
|
return {
|
|
kind: "http",
|
|
api: (path, fetchOpts = {}) => apiFetch(path, { ...opts, ...fetchOpts }),
|
|
baseUrl: opts.baseUrl,
|
|
};
|
|
}
|
|
|
|
async function makeDbContext() {
|
|
const { db, dataDir, dbPath } = await openOmniRouteDb();
|
|
return {
|
|
kind: "db",
|
|
db,
|
|
dataDir,
|
|
dbPath,
|
|
close: () => {
|
|
try {
|
|
db.close();
|
|
} catch {
|
|
// best-effort
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
export async function withRuntime(fn, opts = {}) {
|
|
const requireServer = opts.requireServer === true;
|
|
const preferDb = opts.preferDb === true;
|
|
|
|
if (!preferDb) {
|
|
const up = await isServerUp(opts);
|
|
if (up) {
|
|
return await fn(makeHttpContext(opts));
|
|
}
|
|
if (requireServer) {
|
|
throw new ServerOfflineError();
|
|
}
|
|
}
|
|
|
|
const ctx = await makeDbContext();
|
|
try {
|
|
return await fn(ctx);
|
|
} finally {
|
|
ctx.close?.();
|
|
}
|
|
}
|
|
|
|
export async function withHttp(fn, opts = {}) {
|
|
const up = await isServerUp(opts);
|
|
if (!up) throw new ServerOfflineError();
|
|
return fn(makeHttpContext(opts));
|
|
}
|
|
|
|
export async function withDb(fn) {
|
|
const ctx = await makeDbContext();
|
|
try {
|
|
return await fn(ctx);
|
|
} finally {
|
|
ctx.close?.();
|
|
}
|
|
}
|