mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 14:52:09 +03:00
* feat(dashboard): replace free-text model inputs with hidePaid-aware Selects (#6540) Swap RoutingTab.webSearchRouteModel, ComboDefaultsTab.handoffModel, and BackgroundDegradationTab's from/to fields from free-text inputs to a new shared ModelSelectField fed by the already hidePaidModels-aware GET /api/models, with an off-catalog "(custom)" fallback so an existing saved value is never silently dropped. ModelRoutingSection's glob pattern field gets a fail-open "matches only paid models" warning instead, since it's a wildcard matcher rather than a single model id. Adds save-time paid-target rejection (PAID_MODEL_TARGET_BLOCKED, 400) on PATCH /api/settings, PATCH /api/settings/combo-defaults, and PUT /api/settings/background-degradation when hidePaidModels is on, failing open for aliases/combo names/unrecognized providers. globToRegex is extracted from lib/db/modelComboMappings.ts into a new dependency-free shared/utils/globPattern.ts so both the DB module and the new client-side pattern heuristic reuse the same regex-building logic. * refactor(6540): extract paid-target guard in background-degradation PUT The inline hidePaid check nested if>if>for>if inside the PUT handler, pushing its cognitive complexity to 16 (>15) — a NEW violation that broke the check:complexity-ratchets gate (891 > baseline 890). Extracted the check into a module-local hasBlockedPaidTarget() helper; behaviour and response body are unchanged. cognitive-complexity back to 890 = baseline. * fix(i18n): mirror paidModelPatternWarning into pt-BR.json (#6540) The new key landed only in en.json; the i18n pt-BR integrity test (no drift, #6695) requires pt-BR.json to carry every en.json key.
25 lines
994 B
TypeScript
25 lines
994 B
TypeScript
/**
|
|
* Shared glob → RegExp conversion.
|
|
*
|
|
* Extracted from `src/lib/db/modelComboMappings.ts` (#6540) so client-side
|
|
* code (which cannot import that module — it pulls in `getDbInstance` /
|
|
* server-only DB wiring) can reuse the exact same pattern-matching semantics
|
|
* instead of duplicating the regex-building logic (the repo's ReDoS
|
|
* convention warns against duplicated ad-hoc regex construction).
|
|
*/
|
|
|
|
/**
|
|
* Convert a simple glob pattern to a RegExp.
|
|
* Supports `*` (any characters) and `?` (single character).
|
|
* Case-insensitive matching. Bounded, non-catastrophic-backtracking: all
|
|
* regex specials are escaped before the glob wildcards are substituted, so
|
|
* there is no nested-quantifier construction.
|
|
*/
|
|
export function globToRegex(pattern: string): RegExp {
|
|
const escaped = pattern
|
|
.replace(/[.+^${}()|[\]\\]/g, "\\$&") // escape regex specials
|
|
.replace(/\*/g, ".*") // * → .*
|
|
.replace(/\?/g, "."); // ? → .
|
|
return new RegExp(`^${escaped}$`, "i");
|
|
}
|