chore: upgrade Vite+ to 0.2.5 (#39181)

This commit is contained in:
yyh 2026-07-17 13:39:02 +08:00 committed by GitHub
parent f962c9e47a
commit 2a008423d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 1153 additions and 1075 deletions

View File

@ -83,7 +83,7 @@ export default class MyCommand extends DifyCommand {
process.stdout.write( process.stdout.write(
await runMyThing( await runMyThing(
{ {
/* args */ // args
}, },
{ bundle: ctx.bundle, http: ctx.http, io: ctx.io }, { bundle: ctx.bundle, http: ctx.http, io: ctx.io },
), ),

View File

@ -6061,9 +6061,6 @@
}, },
"jsx_a11y/no-static-element-interactions": { "jsx_a11y/no-static-element-interactions": {
"count": 2 "count": 2
},
"no-useless-return": {
"count": 1
} }
}, },
"web/app/components/workflow/panel/version-history-panel/version-history-item.tsx": { "web/app/components/workflow/panel/version-history-panel/version-history-item.tsx": {

View File

@ -3,7 +3,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"check": "vp fmt --check && vp lint --quiet && pnpm lint:eslint", "check": "vp check && pnpm lint:eslint",
"check:fix": "pnpm lint:eslint:fix && vp check --fix", "check:fix": "pnpm lint:eslint:fix && vp check --fix",
"dev": "concurrently -k -n vinext,proxy \"vp run dify-web#dev:vinext\" \"vp run dify-web#dev:proxy\"", "dev": "concurrently -k -n vinext,proxy \"vp run dify-web#dev:vinext\" \"vp run dify-web#dev:proxy\"",
"prepare": "vp config", "prepare": "vp config",

2039
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,7 @@ overrides:
solid-js: 1.9.13 solid-js: 1.9.13
string-width: ~8.2.1 string-width: ~8.2.1
tar@<=7.5.15: ^7.5.16 tar@<=7.5.15: ^7.5.16
vite: npm:@voidzero-dev/vite-plus-core@0.2.4 vite: npm:@voidzero-dev/vite-plus-core@0.2.5
ws@>=8.0.0 <8.20.1: ^8.21.0 ws@>=8.0.0 <8.20.1: ^8.21.0
yaml@>=2.0.0 <2.8.3: 2.9.0 yaml@>=2.0.0 <2.8.3: 2.9.0
yauzl@<3.2.1: 3.2.1 yauzl@<3.2.1: 3.2.1
@ -251,9 +251,9 @@ catalog:
use-context-selector: 2.0.0 use-context-selector: 2.0.0
uuid: 14.0.1 uuid: 14.0.1
vinext: 1.0.0-beta.1 vinext: 1.0.0-beta.1
vite: npm:@voidzero-dev/vite-plus-core@0.2.4 vite: npm:@voidzero-dev/vite-plus-core@0.2.5
vite-plugin-inspect: 12.0.0-beta.3 vite-plugin-inspect: 12.0.0-beta.3
vite-plus: 0.2.4 vite-plus: 0.2.5
vitest: 4.1.10 vitest: 4.1.10
vitest-browser-react: 2.2.0 vitest-browser-react: 2.2.0
vitest-canvas-mock: 1.1.4 vitest-canvas-mock: 1.1.4

View File

@ -9,6 +9,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
*/ */
let mockPostMarketplaceShouldFail = false let mockPostMarketplaceShouldFail = false
const mockPostMarketplace = vi.hoisted(() => vi.fn())
const mockPostMarketplaceResponse = { const mockPostMarketplaceResponse = {
data: { data: {
plugins: [{ type: 'plugin', org: 'test', name: 'plugin1', tags: [] }], plugins: [{ type: 'plugin', org: 'test', name: 'plugin1', tags: [] }],
@ -16,12 +17,12 @@ const mockPostMarketplaceResponse = {
}, },
} }
vi.mock('@/service/base', () => ({ mockPostMarketplace.mockImplementation(async () => {
postMarketplace: vi.fn(async () => { if (mockPostMarketplaceShouldFail) throw new Error('Mock API error')
if (mockPostMarketplaceShouldFail) throw new Error('Mock API error') return mockPostMarketplaceResponse
return mockPostMarketplaceResponse })
}),
})) vi.mock('@/service/base', () => ({ postMarketplace: mockPostMarketplace }))
vi.mock('@/config', () => ({ vi.mock('@/config', () => ({
API_PREFIX: '/api', API_PREFIX: '/api',
@ -169,8 +170,7 @@ describe('useMarketplacePlugins (integration)', () => {
it('should show isLoading during initial fetch', async () => { it('should show isLoading during initial fetch', async () => {
// Delay the response so we can observe the loading state // Delay the response so we can observe the loading state
const { postMarketplace } = await import('@/service/base') mockPostMarketplace.mockImplementationOnce(
vi.mocked(postMarketplace).mockImplementationOnce(
() => () =>
new Promise((resolve) => { new Promise((resolve) => {
setTimeout( setTimeout(
@ -234,8 +234,7 @@ describe('useMarketplacePlugins (integration)', () => {
total: 1, total: 1,
}, },
} }
const { postMarketplace } = await import('@/service/base') mockPostMarketplace.mockResolvedValueOnce(bundleResponse)
vi.mocked(postMarketplace).mockResolvedValueOnce(bundleResponse)
const { useMarketplacePlugins } = await import('../hooks') const { useMarketplacePlugins } = await import('../hooks')
const { Wrapper } = createWrapper() const { Wrapper } = createWrapper()
@ -323,8 +322,7 @@ describe('useMarketplacePlugins (integration)', () => {
}) })
it('should handle response with bundles field (bundles || plugins fallback)', async () => { it('should handle response with bundles field (bundles || plugins fallback)', async () => {
const { postMarketplace } = await import('@/service/base') mockPostMarketplace.mockResolvedValueOnce({
vi.mocked(postMarketplace).mockResolvedValueOnce({
data: { data: {
bundles: [ bundles: [
{ type: 'bundle', org: 'test', name: 'b1', tags: [], description: 'desc', labels: {} }, { type: 'bundle', org: 'test', name: 'b1', tags: [], description: 'desc', labels: {} },
@ -352,8 +350,7 @@ describe('useMarketplacePlugins (integration)', () => {
}) })
it('should handle response with no bundles and no plugins (empty fallback)', async () => { it('should handle response with no bundles and no plugins (empty fallback)', async () => {
const { postMarketplace } = await import('@/service/base') mockPostMarketplace.mockResolvedValueOnce({
vi.mocked(postMarketplace).mockResolvedValueOnce({
data: { data: {
total: 0, total: 0,
}, },

View File

@ -34,6 +34,7 @@ function createWrapper() {
} }
let mockPostMarketplaceShouldFail = false let mockPostMarketplaceShouldFail = false
const mockPostMarketplace = vi.hoisted(() => vi.fn())
const mockPostMarketplaceResponse = { const mockPostMarketplaceResponse = {
data: { data: {
plugins: [ plugins: [
@ -45,12 +46,12 @@ const mockPostMarketplaceResponse = {
}, },
} }
vi.mock('@/service/base', () => ({ mockPostMarketplace.mockImplementation(() => {
postMarketplace: vi.fn(() => { if (mockPostMarketplaceShouldFail) return Promise.reject(new Error('Mock API error'))
if (mockPostMarketplaceShouldFail) return Promise.reject(new Error('Mock API error')) return Promise.resolve(mockPostMarketplaceResponse)
return Promise.resolve(mockPostMarketplaceResponse) })
}),
})) vi.mock('@/service/base', () => ({ postMarketplace: mockPostMarketplace }))
vi.mock('@/config', () => ({ vi.mock('@/config', () => ({
API_PREFIX: '/api', API_PREFIX: '/api',
@ -308,8 +309,7 @@ describe('Hooks queryFn Coverage', () => {
}) })
it('should expose page and total from infinite query data', async () => { it('should expose page and total from infinite query data', async () => {
const { postMarketplace } = await import('@/service/base') mockPostMarketplace
vi.mocked(postMarketplace)
.mockResolvedValueOnce({ .mockResolvedValueOnce({
data: { data: {
plugins: [ plugins: [
@ -420,8 +420,7 @@ describe('Hooks queryFn Coverage', () => {
}) })
it('should test getNextPageParam via fetchNextPage behavior', async () => { it('should test getNextPageParam via fetchNextPage behavior', async () => {
const { postMarketplace } = await import('@/service/base') mockPostMarketplace
vi.mocked(postMarketplace)
.mockResolvedValueOnce({ .mockResolvedValueOnce({
data: { plugins: [], total: 100 }, data: { plugins: [], total: 100 },
}) })

View File

@ -1,4 +1,40 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
// oxlint-disable-next-line no-restricted-imports -- This spec directly tests the legacy request owner.
import { request } from '../base'
const mocks = vi.hoisted(() => ({
isClient: true,
baseFetch: vi.fn(),
refreshAccessTokenOrReLogin: vi.fn(),
}))
vi.mock('@/utils/client', () => ({
get isClient() {
return mocks.isClient
},
get isServer() {
return !mocks.isClient
},
}))
vi.mock('@/utils/var', () => ({
basePath: '/app',
}))
vi.mock('../fetch', () => ({
base: mocks.baseFetch,
ContentType: {
audio: 'audio/mpeg',
download: 'application/octet-stream',
downloadZip: 'application/zip',
json: 'application/json',
},
getBaseOptions: vi.fn(() => ({})),
}))
vi.mock('../refresh-token', () => ({
refreshAccessTokenOrReLogin: mocks.refreshAccessTokenOrReLogin,
}))
const createUnauthorizedResponse = () => const createUnauthorizedResponse = () =>
new Response( new Response(
@ -15,89 +51,23 @@ const createUnauthorizedResponse = () =>
}, },
) )
async function loadServerRequest() {
vi.resetModules()
const mockBaseFetch = vi.fn(async () => {
throw createUnauthorizedResponse()
})
const mockRefreshAccessTokenOrReLogin = vi.fn()
vi.doMock('@/utils/client', () => ({
isClient: false,
isServer: true,
}))
vi.doMock('../fetch', () => ({
base: mockBaseFetch,
ContentType: {
audio: 'audio/mpeg',
download: 'application/octet-stream',
downloadZip: 'application/zip',
json: 'application/json',
},
getBaseOptions: vi.fn(() => ({})),
}))
vi.doMock('../refresh-token', () => ({
refreshAccessTokenOrReLogin: mockRefreshAccessTokenOrReLogin,
}))
const { request } = await import('../base')
return {
request,
mockRefreshAccessTokenOrReLogin,
}
}
type ClientRequestOptions = { type ClientRequestOptions = {
response: Response response: Response
refreshError?: Error refreshError?: Error
} }
async function loadClientRequest({ response, refreshError }: ClientRequestOptions) { function arrangeClientRequest({ response, refreshError }: ClientRequestOptions) {
vi.resetModules() mocks.baseFetch.mockRejectedValue(response)
if (refreshError) mocks.refreshAccessTokenOrReLogin.mockRejectedValue(refreshError)
const mockBaseFetch = vi.fn(async () => {
throw response
})
const mockRefreshAccessTokenOrReLogin = refreshError
? vi.fn().mockRejectedValue(refreshError)
: vi.fn()
vi.doMock('@/utils/client', () => ({
isClient: true,
isServer: false,
}))
vi.doMock('@/utils/var', () => ({
basePath: '/app',
}))
vi.doMock('../fetch', () => ({
base: mockBaseFetch,
ContentType: {
audio: 'audio/mpeg',
download: 'application/octet-stream',
downloadZip: 'application/zip',
json: 'application/json',
},
getBaseOptions: vi.fn(() => ({})),
}))
vi.doMock('../refresh-token', () => ({
refreshAccessTokenOrReLogin: mockRefreshAccessTokenOrReLogin,
}))
const { request } = await import('../base')
return {
request,
mockRefreshAccessTokenOrReLogin,
}
} }
describe('request 401 handling', () => { describe('request 401 handling', () => {
const originalLocation = globalThis.location const originalLocation = globalThis.location
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks() mocks.isClient = true
mocks.baseFetch.mockReset()
mocks.refreshAccessTokenOrReLogin.mockReset()
Object.defineProperty(globalThis, 'location', { Object.defineProperty(globalThis, 'location', {
value: { value: {
origin: 'https://example.com', origin: 'https://example.com',
@ -118,40 +88,40 @@ describe('request 401 handling', () => {
writable: true, writable: true,
configurable: true, configurable: true,
}) })
vi.resetModules()
vi.restoreAllMocks()
}) })
it('should not run browser auth recovery when handling 401 on the server', async () => { it('should not run browser auth recovery when handling 401 on the server', async () => {
const { request, mockRefreshAccessTokenOrReLogin } = await loadServerRequest() const response = createUnauthorizedResponse()
mocks.isClient = false
mocks.baseFetch.mockRejectedValue(response)
await expect(request('/account/profile')).rejects.toMatchObject({ status: 401 }) await expect(request('/account/profile')).rejects.toBe(response)
expect(mockRefreshAccessTokenOrReLogin).not.toHaveBeenCalled() expect(mocks.refreshAccessTokenOrReLogin).not.toHaveBeenCalled()
}) })
it('should preserve the current URL when a 401 response cannot be parsed', async () => { it('should preserve the current URL when a 401 response cannot be parsed', async () => {
const response = new Response('not-json', { status: 401 }) const response = new Response('not-json', { status: 401 })
const { request, mockRefreshAccessTokenOrReLogin } = await loadClientRequest({ response }) arrangeClientRequest({ response })
await expect(request('/account/profile')).rejects.toBe(response) await expect(request('/account/profile')).rejects.toBe(response)
expect(globalThis.location.href).toBe( expect(globalThis.location.href).toBe(
`https://example.com/app/signin?redirect_url=${encodeURIComponent('/app/apps?category=agent#recent')}`, `https://example.com/app/signin?redirect_url=${encodeURIComponent('/app/apps?category=agent#recent')}`,
) )
expect(mockRefreshAccessTokenOrReLogin).not.toHaveBeenCalled() expect(mocks.refreshAccessTokenOrReLogin).not.toHaveBeenCalled()
}) })
it('should preserve the current URL when token refresh fails', async () => { it('should preserve the current URL when token refresh fails', async () => {
const response = createUnauthorizedResponse() const response = createUnauthorizedResponse()
const { request, mockRefreshAccessTokenOrReLogin } = await loadClientRequest({ arrangeClientRequest({
response, response,
refreshError: new Error('refresh failed'), refreshError: new Error('refresh failed'),
}) })
await expect(request('/account/profile')).rejects.toBe(response) await expect(request('/account/profile')).rejects.toBe(response)
expect(mockRefreshAccessTokenOrReLogin).toHaveBeenCalledOnce() expect(mocks.refreshAccessTokenOrReLogin).toHaveBeenCalledOnce()
expect(globalThis.location.href).toBe( expect(globalThis.location.href).toBe(
`https://example.com/app/signin?redirect_url=${encodeURIComponent('/app/apps?category=agent#recent')}`, `https://example.com/app/signin?redirect_url=${encodeURIComponent('/app/apps?category=agent#recent')}`,
) )