forked from boos/BoosAPI
fix connection and release regressions
This commit is contained in:
@@ -358,7 +358,9 @@ export default function Accounts() {
|
||||
skipModelFetch: tokenForm.skipModelFetch,
|
||||
});
|
||||
closeAddPanel();
|
||||
if (result.tokenType === 'apikey') {
|
||||
if (result.queued) {
|
||||
toast.info(result.message || '账号已添加,后台正在同步初始化信息。');
|
||||
} else if (result.tokenType === 'apikey') {
|
||||
toast.success('已添加为 API Key 账号(可用于代理转发)');
|
||||
} else {
|
||||
const parts: string[] = [];
|
||||
|
||||
@@ -162,7 +162,7 @@ function isExactModelPattern(modelPattern: string): boolean {
|
||||
const normalized = modelPattern.trim();
|
||||
if (!normalized) return false;
|
||||
if (normalized.toLowerCase().startsWith('re:')) return false;
|
||||
return !/[\*\?\[]/.test(normalized);
|
||||
return !/[\*\?]/.test(normalized);
|
||||
}
|
||||
|
||||
function routeTitle(route: RouteSelectorItem): string {
|
||||
|
||||
@@ -159,7 +159,7 @@ function isExactModelPattern(modelPattern: string): boolean {
|
||||
const normalized = modelPattern.trim();
|
||||
if (!normalized) return false;
|
||||
if (isRegexModelPattern(normalized)) return false;
|
||||
return !/[\*\?\[]/.test(normalized);
|
||||
return !/[\*\?]/.test(normalized);
|
||||
}
|
||||
|
||||
function routeTitle(route: RouteSelectorItem): string {
|
||||
|
||||
@@ -226,7 +226,7 @@ const isExactModelPattern = (modelPattern: string): boolean => {
|
||||
const normalized = modelPattern.trim();
|
||||
if (!normalized) return false;
|
||||
if (normalized.toLowerCase().startsWith('re:')) return false;
|
||||
return !/[\*\?\[]/.test(normalized);
|
||||
return !/[\*\?]/.test(normalized);
|
||||
};
|
||||
|
||||
const splitCommaSeparated = (value: string): string[] =>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { isExactModelPattern } from './utils.js';
|
||||
|
||||
describe('isExactModelPattern', () => {
|
||||
it('treats bracket-prefixed literal model names as exact patterns', () => {
|
||||
expect(isExactModelPattern('[NV]deepseek-v3.1-terminus')).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -45,7 +45,7 @@ export function isExactModelPattern(modelPattern: string): boolean {
|
||||
const normalized = modelPattern.trim();
|
||||
if (!normalized) return false;
|
||||
if (isRegexModelPattern(normalized)) return false;
|
||||
return !/[\*\?\[]/.test(normalized);
|
||||
return !/[\*\?]/.test(normalized);
|
||||
}
|
||||
|
||||
export function parseRegexModelPattern(modelPattern: string): { regex: RegExp | null; error: string | null } {
|
||||
|
||||
@@ -79,6 +79,54 @@ describe('TokenRoutes grouped source models', () => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('does not treat bracket-prefixed exact model routes as group filters', async () => {
|
||||
apiMock.getRoutesSummary.mockResolvedValue([
|
||||
{
|
||||
id: 4386, modelPattern: '[NV]deepseek-v3.1-terminus', displayName: null,
|
||||
displayIcon: null, modelMapping: null, enabled: true,
|
||||
channelCount: 1, enabledChannelCount: 1, siteNames: ['test'],
|
||||
decisionSnapshot: null, decisionRefreshedAt: null,
|
||||
},
|
||||
{
|
||||
id: 3383, modelPattern: 're:^claude-(opus|sonnet)-4-5$', displayName: 'claude-opus-4-6',
|
||||
displayIcon: null, modelMapping: null, enabled: true,
|
||||
channelCount: 4, enabledChannelCount: 4, siteNames: ['site-a', 'site-b'],
|
||||
decisionSnapshot: null, decisionRefreshedAt: null,
|
||||
},
|
||||
]);
|
||||
|
||||
let root: ReturnType<typeof create> | null = null;
|
||||
try {
|
||||
await act(async () => {
|
||||
root = create(
|
||||
<MemoryRouter initialEntries={['/routes']}>
|
||||
<ToastProvider>
|
||||
<TokenRoutes />
|
||||
</ToastProvider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
const filterToggle = findButtonByText(root.root, '筛选');
|
||||
await act(async () => {
|
||||
filterToggle.props.onClick();
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
const text = collectText(root.root);
|
||||
expect(text).toContain('全部群组1');
|
||||
|
||||
const bracketGroupButtons = root.root.findAll((node) => (
|
||||
node.type === 'button'
|
||||
&& collectText(node).includes('[NV]deepseek-v3.1-terminus')
|
||||
));
|
||||
expect(bracketGroupButtons).toHaveLength(0);
|
||||
} finally {
|
||||
root?.unmount();
|
||||
}
|
||||
});
|
||||
|
||||
it('collapses source-model groups by default for wildcard routes', async () => {
|
||||
const channels = [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user