mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Modularize validation schemas (#3594). Integrated into release/v3.8.27 after rebase (reconciled the merged hiddenSidebarGroupLabels #3971 + intelligenceSyncRequestSchema into the new modules) + behavior verification (typecheck, 195 schema/settings/validation tests, build 556/556). Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
216 lines
7.4 KiB
TypeScript
216 lines
7.4 KiB
TypeScript
import { z } from "zod";
|
|
import {
|
|
ACCOUNT_FALLBACK_STRATEGY_VALUES,
|
|
ROUTING_STRATEGY_VALUES,
|
|
} from "@/shared/constants/routingStrategies";
|
|
import { SUPPORTED_BATCH_ENDPOINTS } from "@/shared/constants/batchEndpoints";
|
|
import { MAX_REQUEST_BODY_LIMIT_MB, MIN_REQUEST_BODY_LIMIT_MB } from "@/shared/constants/bodySize";
|
|
import { COMBO_CONFIG_MODES } from "@/shared/constants/comboConfigMode";
|
|
import { providerAllowsOptionalApiKey } from "@/shared/constants/providers";
|
|
import { HIDEABLE_SIDEBAR_ITEM_IDS } from "@/shared/constants/sidebarVisibility";
|
|
import {
|
|
isForbiddenUpstreamHeaderName,
|
|
isForbiddenCustomHeaderName,
|
|
} from "@/shared/constants/upstreamHeaders";
|
|
import { MAX_TIMER_TIMEOUT_MS } from "@/shared/utils/runtimeTimeouts";
|
|
|
|
import { confirmedAccountSchema } from "./misc.ts";
|
|
|
|
// ──── Codex Import Schema ────
|
|
|
|
export const importCodexAuthSchema = z.object({
|
|
source: z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("json"), json: z.unknown() }),
|
|
z.object({
|
|
kind: z.literal("text"),
|
|
text: z.string().max(256 * 1024, "Paste content must be under 256 KB"),
|
|
}),
|
|
]),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Codex Import Bulk Schema ────
|
|
|
|
export const importCodexAuthBulkSchema = z.object({
|
|
entries: z
|
|
.array(
|
|
z.object({
|
|
json: z.unknown(),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
})
|
|
)
|
|
.min(1, "At least one entry is required")
|
|
.max(50, "At most 50 entries per bulk import"),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Claude Auth Import Schema ────
|
|
|
|
export const importClaudeAuthSchema = z.object({
|
|
source: z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("json"), json: z.unknown() }),
|
|
z.object({
|
|
kind: z.literal("text"),
|
|
text: z.string().max(256 * 1024, "Paste content must be under 256 KB"),
|
|
}),
|
|
]),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Claude Auth Import Bulk Schema ────
|
|
|
|
export const importClaudeAuthBulkSchema = z.object({
|
|
entries: z
|
|
.array(
|
|
z.object({
|
|
json: z.unknown(),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
})
|
|
)
|
|
.min(1, "At least one entry is required")
|
|
.max(50, "At most 50 entries per bulk import"),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Gemini CLI Auth Import Schema ────
|
|
|
|
export const importGeminiAuthSchema = z.object({
|
|
source: z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("json"), json: z.unknown() }),
|
|
z.object({
|
|
kind: z.literal("text"),
|
|
text: z.string().max(256 * 1024, "oauth_creds.json content exceeds 256KB"),
|
|
}),
|
|
]),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Antigravity CLI (`agy`) Auth Import Schema ────
|
|
// Same source/options shape as gemini-cli; the parser handles the agy-specific token JSON.
|
|
|
|
export const importAgyAuthSchema = z.object({
|
|
source: z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("json"), json: z.unknown() }),
|
|
z.object({
|
|
kind: z.literal("text"),
|
|
text: z.string().max(256 * 1024, "agy token file content exceeds 256KB"),
|
|
}),
|
|
]),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Antigravity CLI (`agy`) auto-detect local login Schema ────
|
|
// No `source`: the route reads the token from the local agy CLI data dir on disk.
|
|
|
|
export const applyLocalAgyAuthSchema = z.object({
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Gemini CLI Auth Import Bulk Schema ────
|
|
|
|
export const importGeminiAuthBulkSchema = z.object({
|
|
entries: z
|
|
.array(
|
|
z.object({
|
|
json: z.unknown(),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
})
|
|
)
|
|
.min(1, "At least one entry is required")
|
|
.max(50, "At most 50 entries per bulk import"),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
// ──── Antigravity CLI (`agy`) Auth Import Bulk Schema ────
|
|
|
|
export const importAgyAuthBulkSchema = z.object({
|
|
entries: z
|
|
.array(
|
|
z.object({
|
|
json: z.unknown(),
|
|
name: z.string().min(1).max(200).optional(),
|
|
email: z.string().email("Must be a valid email").optional(),
|
|
})
|
|
)
|
|
.min(1, "At least one entry is required")
|
|
.max(50, "At most 50 entries per bulk import"),
|
|
overwriteExisting: z.boolean().optional(),
|
|
});
|
|
|
|
export const oauthExchangeSchema = z.object({
|
|
code: z.string().trim().min(1),
|
|
redirectUri: z.string().trim().min(1),
|
|
codeVerifier: z.string().trim().min(1).optional(),
|
|
state: z.string().nullable().optional(),
|
|
});
|
|
|
|
export const oauthPollSchema = z.object({
|
|
deviceCode: z.string().trim().min(1),
|
|
codeVerifier: z.string().optional(),
|
|
extraData: z.unknown().optional(),
|
|
});
|
|
|
|
/** Import a raw API token (e.g. WINDSURF_API_KEY) without going through the browser OAuth flow. */
|
|
export const oauthImportTokenSchema = z.object({
|
|
token: z.string().trim().min(1, "Token is required"),
|
|
connectionId: z.string().optional(),
|
|
});
|
|
|
|
/**
|
|
* Persist tokens obtained out-of-band by the browser-driven Codex device flow.
|
|
* The browser performs the full device authorization + token exchange against
|
|
* auth.openai.com (the server cannot — its datacenter IP is blocked by Cloudflare),
|
|
* then ships the final tokens here for mapping + persistence. Token fields use the
|
|
* snake_case shape returned by the OAuth token endpoint (consumed directly by
|
|
* each provider's mapTokens).
|
|
*/
|
|
export const oauthDeviceCompleteSchema = z.object({
|
|
access_token: z.string().trim().min(1, "access_token is required"),
|
|
refresh_token: z.string().trim().optional(),
|
|
id_token: z.string().trim().optional(),
|
|
expires_in: z.number().int().positive().optional(),
|
|
connectionId: z.string().optional(),
|
|
});
|
|
|
|
export const cursorImportSchema = z.object({
|
|
accessToken: z.string().trim().min(1, "Access token is required"),
|
|
machineId: z.string().trim().optional(),
|
|
});
|
|
|
|
export const traeImportSchema = z.object({
|
|
accessToken: z.string().trim().min(1, "Cloud-IDE-JWT access token is required"),
|
|
webId: z.string().trim().optional(),
|
|
bizUserId: z.string().trim().optional(),
|
|
userUniqueId: z.string().trim().optional(),
|
|
scope: z.string().trim().optional(),
|
|
tenant: z.string().trim().optional(),
|
|
region: z.string().trim().optional(),
|
|
});
|
|
|
|
export const kiroImportSchema = z.object({
|
|
refreshToken: z.string().trim().min(1, "Refresh token is required"),
|
|
region: z.string().trim().default("us-east-1"),
|
|
});
|
|
|
|
export const kiroSocialExchangeSchema = z.object({
|
|
code: z.string().trim().min(1, "Code is required"),
|
|
codeVerifier: z.string().trim().min(1, "Code verifier is required"),
|
|
provider: z.enum(["google", "github"]),
|
|
});
|
|
|
|
export const zedImportSchema = z.object({
|
|
confirmedAccounts: z.array(confirmedAccountSchema),
|
|
}); |