mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-19 13:33:35 +08:00
Keep desktop smoke on the configured backend
Browser-mode startup now respects an explicit Vite desktop server URL before falling back to same-origin H5 serving. This keeps local desktop smoke tests pointed at the real API server while preserving same-origin behavior for packaged H5 access. Constraint: Vite dev smoke serves the web app and API on different loopback ports Rejected: Treat same-origin as always preferred | Vite would answer /api requests with HTML and the chat surface never becomes ready Confidence: high Scope-risk: narrow Tested: cd desktop && bun run test -- src/lib/desktopRuntime.test.ts src/api/client.test.ts --run Tested: bun run check:desktop Tested: bun run quality:gate --mode baseline --allow-live --only 'provider-smoke:*' --only 'desktop-smoke:*' --provider-model codingplan:main:codingplan-main Not-tested: Full bun run quality:pr after this commit; it will run again during push
This commit is contained in:
parent
d37d752310
commit
d1211e4dca
@ -44,6 +44,10 @@ export function getDefaultBaseUrl() {
|
||||
return DEFAULT_BASE_URL
|
||||
}
|
||||
|
||||
export function hasExplicitDefaultBaseUrl() {
|
||||
return Boolean(ENV_BASE_URL)
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
public status: number,
|
||||
|
||||
@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const clientMocks = vi.hoisted(() => ({
|
||||
defaultBaseUrl: 'http://127.0.0.1:3456',
|
||||
explicitDefaultBaseUrl: false,
|
||||
setBaseUrl: vi.fn(),
|
||||
setAuthToken: vi.fn(),
|
||||
postVerify: vi.fn(),
|
||||
@ -12,6 +13,7 @@ vi.mock('../api/client', () => ({
|
||||
post: clientMocks.postVerify,
|
||||
},
|
||||
getDefaultBaseUrl: () => clientMocks.defaultBaseUrl,
|
||||
hasExplicitDefaultBaseUrl: () => clientMocks.explicitDefaultBaseUrl,
|
||||
setAuthToken: clientMocks.setAuthToken,
|
||||
setBaseUrl: clientMocks.setBaseUrl,
|
||||
}))
|
||||
@ -31,6 +33,8 @@ describe('desktopRuntime browser H5 bootstrap', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
clientMocks.defaultBaseUrl = 'http://127.0.0.1:3456'
|
||||
clientMocks.explicitDefaultBaseUrl = false
|
||||
vi.useRealTimers()
|
||||
window.localStorage.clear()
|
||||
window.history.pushState({}, '', '/')
|
||||
@ -111,6 +115,26 @@ describe('desktopRuntime browser H5 bootstrap', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('prefers an explicit Vite desktop server URL over the dev server origin', async () => {
|
||||
clientMocks.defaultBaseUrl = 'http://127.0.0.1:55189'
|
||||
clientMocks.explicitDefaultBaseUrl = true
|
||||
window.history.pushState({}, '', '/')
|
||||
globalThis.fetch = vi.fn().mockResolvedValue(
|
||||
new Response(null, { status: 200 }),
|
||||
) as typeof fetch
|
||||
|
||||
await expect(initializeDesktopServerUrl()).resolves.toBe('http://127.0.0.1:55189')
|
||||
|
||||
expect(clientMocks.setBaseUrl).toHaveBeenLastCalledWith('http://127.0.0.1:55189')
|
||||
expect(clientMocks.setAuthToken).toHaveBeenLastCalledWith(null)
|
||||
expect(globalThis.fetch).toHaveBeenCalledWith('http://127.0.0.1:55189/health', {
|
||||
cache: 'no-store',
|
||||
})
|
||||
expect(globalThis.fetch).toHaveBeenCalledWith('http://127.0.0.1:55189/api/status', {
|
||||
cache: 'no-store',
|
||||
})
|
||||
})
|
||||
|
||||
it('normalizes unreachable remote browser startup into a recoverable H5 error', async () => {
|
||||
vi.useFakeTimers()
|
||||
globalThis.fetch = vi.fn().mockRejectedValue(new TypeError('Failed to fetch')) as typeof fetch
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import { api, getDefaultBaseUrl, setAuthToken, setBaseUrl } from '../api/client'
|
||||
import {
|
||||
api,
|
||||
getDefaultBaseUrl,
|
||||
hasExplicitDefaultBaseUrl,
|
||||
setAuthToken,
|
||||
setBaseUrl,
|
||||
} from '../api/client'
|
||||
|
||||
export const H5_SERVER_URL_STORAGE_KEY = 'cc-haha-h5-server-url'
|
||||
export const H5_TOKEN_STORAGE_KEY = 'cc-haha-h5-token'
|
||||
@ -133,7 +139,7 @@ async function initializeBrowserServerUrl(fallbackUrl: string) {
|
||||
const requestedUrl =
|
||||
normalizeServerUrl(queryUrl) ??
|
||||
stored.serverUrl ??
|
||||
getSameOriginServerUrl() ??
|
||||
getConfiguredBrowserServerUrl(fallbackUrl) ??
|
||||
fallbackUrl
|
||||
const token = stored.token
|
||||
const browserH5Runtime = requiresH5AuthForServerUrl(requestedUrl)
|
||||
@ -249,6 +255,14 @@ function getSameOriginServerUrl() {
|
||||
return normalizeServerUrl(window.location.origin)
|
||||
}
|
||||
|
||||
function getConfiguredBrowserServerUrl(fallbackUrl: string) {
|
||||
if (hasExplicitDefaultBaseUrl()) {
|
||||
return normalizeServerUrl(fallbackUrl)
|
||||
}
|
||||
|
||||
return getSameOriginServerUrl()
|
||||
}
|
||||
|
||||
export function isLoopbackHostname(hostname: string) {
|
||||
const normalized = hostname.trim().replace(/^\[/, '').replace(/\]$/, '').toLowerCase()
|
||||
return normalized === '127.0.0.1' || normalized === 'localhost' || normalized === '::1'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user