Compare commits

..

2 Commits

Author SHA1 Message Date
QuantumGhost
f943f1e39b chore: bump version to 1.13.1 (#33505) 2026-03-17 18:31:12 +08:00
-LAN-
239e09473e fix(web): preserve public workflow SSE reconnect after pause (#33552) 2026-03-17 16:41:08 +08:00
17 changed files with 71 additions and 178 deletions

View File

@@ -1,6 +1,6 @@
[project]
name = "dify-api"
version = "1.13.0"
version = "1.13.1"
requires-python = ">=3.11,<3.13"
dependencies = [

2
api/uv.lock generated
View File

@@ -1533,7 +1533,7 @@ wheels = [
[[package]]
name = "dify-api"
version = "1.13.0"
version = "1.13.1"
source = { virtual = "." }
dependencies = [
{ name = "aliyun-log-python-sdk" },

View File

@@ -21,7 +21,7 @@ services:
# API service
api:
image: langgenius/dify-api:1.13.0
image: langgenius/dify-api:1.13.1
restart: always
environment:
# Use the shared environment variables.
@@ -63,7 +63,7 @@ services:
# worker service
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
worker:
image: langgenius/dify-api:1.13.0
image: langgenius/dify-api:1.13.1
restart: always
environment:
# Use the shared environment variables.
@@ -102,7 +102,7 @@ services:
# worker_beat service
# Celery beat for scheduling periodic tasks.
worker_beat:
image: langgenius/dify-api:1.13.0
image: langgenius/dify-api:1.13.1
restart: always
environment:
# Use the shared environment variables.
@@ -132,7 +132,7 @@ services:
# Frontend web application.
web:
image: langgenius/dify-web:1.13.0
image: langgenius/dify-web:1.13.1
restart: always
environment:
CONSOLE_API_URL: ${CONSOLE_API_URL:-}

View File

@@ -728,7 +728,7 @@ services:
# API service
api:
image: langgenius/dify-api:1.13.0
image: langgenius/dify-api:1.13.1
restart: always
environment:
# Use the shared environment variables.
@@ -770,7 +770,7 @@ services:
# worker service
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
worker:
image: langgenius/dify-api:1.13.0
image: langgenius/dify-api:1.13.1
restart: always
environment:
# Use the shared environment variables.
@@ -809,7 +809,7 @@ services:
# worker_beat service
# Celery beat for scheduling periodic tasks.
worker_beat:
image: langgenius/dify-api:1.13.0
image: langgenius/dify-api:1.13.1
restart: always
environment:
# Use the shared environment variables.
@@ -839,7 +839,7 @@ services:
# Frontend web application.
web:
image: langgenius/dify-web:1.13.0
image: langgenius/dify-web:1.13.1
restart: always
environment:
CONSOLE_API_URL: ${CONSOLE_API_URL:-}

View File

@@ -12,7 +12,7 @@ NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# Dev-only Hono proxy targets. Set the api prefixes above to https://localhost:5001/... to start the proxy with HTTPS.
# Dev-only Hono proxy targets. The frontend keeps requesting http://localhost:5001 directly.
HONO_PROXY_HOST=127.0.0.1
HONO_PROXY_PORT=5001
HONO_CONSOLE_API_PROXY_TARGET=

View File

@@ -328,7 +328,7 @@ describe('createWorkflowStreamHandlers', () => {
vi.clearAllMocks()
})
const setupHandlers = (overrides: { isTimedOut?: () => boolean } = {}) => {
const setupHandlers = (overrides: { isPublicAPI?: boolean, isTimedOut?: () => boolean } = {}) => {
let completionRes = ''
let currentTaskId: string | null = null
let isStopping = false
@@ -359,6 +359,7 @@ describe('createWorkflowStreamHandlers', () => {
const handlers = createWorkflowStreamHandlers({
getCompletionRes: () => completionRes,
getWorkflowProcessData: () => workflowProcessData,
isPublicAPI: overrides.isPublicAPI ?? false,
isTimedOut: overrides.isTimedOut ?? (() => false),
markEnded,
notify,
@@ -391,7 +392,7 @@ describe('createWorkflowStreamHandlers', () => {
}
it('should process workflow success and paused events', () => {
const setup = setupHandlers()
const setup = setupHandlers({ isPublicAPI: true })
const handlers = setup.handlers as Required<Pick<IOtherOptions, 'onWorkflowStarted' | 'onTextChunk' | 'onHumanInputRequired' | 'onHumanInputFormFilled' | 'onHumanInputFormTimeout' | 'onWorkflowPaused' | 'onWorkflowFinished' | 'onNodeStarted' | 'onNodeFinished' | 'onIterationStart' | 'onIterationNext' | 'onIterationFinish' | 'onLoopStart' | 'onLoopNext' | 'onLoopFinish'>>
act(() => {
@@ -546,7 +547,11 @@ describe('createWorkflowStreamHandlers', () => {
resultText: 'Hello',
status: WorkflowRunningStatus.Succeeded,
}))
expect(sseGetMock).toHaveBeenCalledWith('/workflow/run-1/events', {}, expect.any(Object))
expect(sseGetMock).toHaveBeenCalledWith(
'/workflow/run-1/events',
{},
expect.objectContaining({ isPublicAPI: true }),
)
expect(setup.messageId()).toBe('run-1')
expect(setup.onCompleted).toHaveBeenCalledWith('{"answer":"Hello"}', 3, true)
expect(setup.setRespondingFalse).toHaveBeenCalled()
@@ -647,6 +652,7 @@ describe('createWorkflowStreamHandlers', () => {
const handlers = createWorkflowStreamHandlers({
getCompletionRes: () => '',
getWorkflowProcessData: () => existingProcess,
isPublicAPI: false,
isTimedOut: () => false,
markEnded: vi.fn(),
notify: setup.notify,

View File

@@ -351,6 +351,7 @@ describe('useResultSender', () => {
await waitFor(() => {
expect(createWorkflowStreamHandlersMock).toHaveBeenCalledWith(expect.objectContaining({
getCompletionRes: harness.runState.getCompletionRes,
isPublicAPI: true,
resetRunState: harness.runState.resetRunState,
setWorkflowProcessData: harness.runState.setWorkflowProcessData,
}))
@@ -373,6 +374,30 @@ describe('useResultSender', () => {
expect(harness.runState.clearMoreLikeThis).not.toHaveBeenCalled()
})
it('should configure workflow handlers for installed apps as non-public', async () => {
const harness = createRunStateHarness()
const { result } = renderSender({
appSourceType: AppSourceTypeEnum.installedApp,
isWorkflow: true,
runState: harness.runState,
})
await act(async () => {
expect(await result.current.handleSend()).toBe(true)
})
expect(createWorkflowStreamHandlersMock).toHaveBeenCalledWith(expect.objectContaining({
isPublicAPI: false,
}))
expect(sendWorkflowMessageMock).toHaveBeenCalledWith(
{ inputs: { name: 'Alice' } },
expect.any(Object),
AppSourceTypeEnum.installedApp,
'app-1',
)
})
it('should stringify non-Error workflow failures', async () => {
const harness = createRunStateHarness()
sendWorkflowMessageMock.mockRejectedValue('workflow failed')

View File

@@ -1,11 +1,11 @@
import type { ResultInputValue } from '../result-request'
import type { ResultRunStateController } from './use-result-run-state'
import type { PromptConfig } from '@/models/debug'
import type { AppSourceType } from '@/service/share'
import type { VisionFile, VisionSettings } from '@/types/app'
import { useCallback, useEffect, useRef } from 'react'
import { TEXT_GENERATION_TIMEOUT_MS } from '@/config'
import {
AppSourceType,
sendCompletionMessage,
sendWorkflowMessage,
} from '@/service/share'
@@ -117,6 +117,7 @@ export const useResultSender = ({
const otherOptions = createWorkflowStreamHandlers({
getCompletionRes: runState.getCompletionRes,
getWorkflowProcessData: runState.getWorkflowProcessData,
isPublicAPI: appSourceType === AppSourceType.webApp,
isTimedOut: () => isTimeout,
markEnded: () => {
isEnd = true

View File

@@ -13,6 +13,7 @@ type Translate = (key: string, options?: Record<string, unknown>) => string
type CreateWorkflowStreamHandlersParams = {
getCompletionRes: () => string
getWorkflowProcessData: () => WorkflowProcess | undefined
isPublicAPI: boolean
isTimedOut: () => boolean
markEnded: () => void
notify: Notify
@@ -255,6 +256,7 @@ const serializeWorkflowOutputs = (outputs: WorkflowFinishedResponse['data']['out
export const createWorkflowStreamHandlers = ({
getCompletionRes,
getWorkflowProcessData,
isPublicAPI,
isTimedOut,
markEnded,
notify,
@@ -287,6 +289,7 @@ export const createWorkflowStreamHandlers = ({
}
const otherOptions: IOtherOptions = {
isPublicAPI,
onWorkflowStarted: ({ workflow_run_id, task_id }) => {
const workflowProcessData = getWorkflowProcessData()
if (workflowProcessData?.tracing.length) {
@@ -378,6 +381,7 @@ export const createWorkflowStreamHandlers = ({
},
onWorkflowPaused: ({ data }) => {
tempMessageId = data.workflow_run_id
// WebApp workflows must keep using the public API namespace after pause/resume.
void sseGet(`/workflow/${data.workflow_run_id}/events`, {}, otherOptions)
setWorkflowProcessData(applyWorkflowPaused(getWorkflowProcessData()))
},

View File

@@ -1,7 +1,7 @@
{
"name": "dify-web",
"type": "module",
"version": "1.13.0",
"version": "1.13.1",
"private": true,
"packageManager": "pnpm@10.32.1",
"imports": {
@@ -210,7 +210,6 @@
"@types/sortablejs": "1.15.9",
"@typescript-eslint/parser": "8.57.0",
"@typescript/native-preview": "7.0.0-dev.20260312.1",
"@vitejs/plugin-basic-ssl": "2.2.0",
"@vitejs/plugin-react": "6.0.0",
"@vitejs/plugin-rsc": "0.5.21",
"@vitest/coverage-v8": "4.1.0",

View File

@@ -34,16 +34,7 @@ const toUpstreamCookieName = (cookieName: string) => {
return `__Host-${cookieName}`
}
const toLocalCookieName = (cookieName: string, options: LocalCookieRewriteOptions) => {
if (options.localSecure)
return cookieName
return cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '')
}
type LocalCookieRewriteOptions = {
localSecure: boolean
}
const toLocalCookieName = (cookieName: string) => cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '')
export const rewriteCookieHeaderForUpstream = (cookieHeader?: string) => {
if (!cookieHeader)
@@ -64,10 +55,7 @@ export const rewriteCookieHeaderForUpstream = (cookieHeader?: string) => {
.join('; ')
}
const rewriteSetCookieValueForLocal = (
setCookieValue: string,
options: LocalCookieRewriteOptions,
) => {
const rewriteSetCookieValueForLocal = (setCookieValue: string) => {
const [rawCookiePair, ...rawAttributes] = setCookieValue.split(';')
const separatorIndex = rawCookiePair.indexOf('=')
@@ -80,11 +68,11 @@ const rewriteSetCookieValueForLocal = (
.map(attribute => attribute.trim())
.filter(attribute =>
!COOKIE_DOMAIN_PATTERN.test(attribute)
&& (options.localSecure || !COOKIE_SECURE_PATTERN.test(attribute))
&& (options.localSecure || !COOKIE_PARTITIONED_PATTERN.test(attribute)),
&& !COOKIE_SECURE_PATTERN.test(attribute)
&& !COOKIE_PARTITIONED_PATTERN.test(attribute),
)
.map((attribute) => {
if (!options.localSecure && SAME_SITE_NONE_PATTERN.test(attribute))
if (SAME_SITE_NONE_PATTERN.test(attribute))
return 'SameSite=Lax'
if (COOKIE_PATH_PATTERN.test(attribute))
@@ -93,13 +81,10 @@ const rewriteSetCookieValueForLocal = (
return attribute
})
return [`${toLocalCookieName(cookieName, options)}=${cookieValue}`, ...rewrittenAttributes].join('; ')
return [`${toLocalCookieName(cookieName)}=${cookieValue}`, ...rewrittenAttributes].join('; ')
}
export const rewriteSetCookieHeadersForLocal = (
setCookieHeaders: string | string[] | undefined,
options: LocalCookieRewriteOptions,
): string[] | undefined => {
export const rewriteSetCookieHeadersForLocal = (setCookieHeaders?: string | string[]): string[] | undefined => {
if (!setCookieHeaders)
return undefined
@@ -107,7 +92,7 @@ export const rewriteSetCookieHeadersForLocal = (
? setCookieHeaders
: [setCookieHeaders]
return normalizedHeaders.map(setCookieValue => rewriteSetCookieValueForLocal(setCookieValue, options))
return normalizedHeaders.map(rewriteSetCookieValueForLocal)
}
export { DEFAULT_PROXY_TARGET }

View File

@@ -1,21 +0,0 @@
export type DevProxyProtocolEnv = Partial<Record<
| 'NEXT_PUBLIC_API_PREFIX'
| 'NEXT_PUBLIC_PUBLIC_API_PREFIX',
string
>>
const isHttpsUrl = (value?: string) => {
if (!value)
return false
try {
return new URL(value).protocol === 'https:'
}
catch {
return false
}
}
export const shouldUseHttpsForDevProxy = (env: DevProxyProtocolEnv = {}) => {
return isHttpsUrl(env.NEXT_PUBLIC_API_PREFIX) || isHttpsUrl(env.NEXT_PUBLIC_PUBLIC_API_PREFIX)
}

View File

@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { buildUpstreamUrl, createDevProxyApp, isAllowedDevOrigin, resolveDevProxyTargets, shouldUseHttpsForDevProxy } from './server'
import { buildUpstreamUrl, createDevProxyApp, isAllowedDevOrigin, resolveDevProxyTargets } from './server'
describe('dev proxy server', () => {
beforeEach(() => {
@@ -19,21 +19,6 @@ describe('dev proxy server', () => {
expect(targets.publicApiTarget).toBe('https://public.example.com')
})
// Scenario: the local dev proxy should switch to https when api prefixes are configured with https.
it('should enable https for the local dev proxy when api prefixes use https', () => {
// Assert
expect(shouldUseHttpsForDevProxy({
NEXT_PUBLIC_API_PREFIX: 'https://localhost:5001/console/api',
})).toBe(true)
expect(shouldUseHttpsForDevProxy({
NEXT_PUBLIC_PUBLIC_API_PREFIX: 'https://localhost:5001/api',
})).toBe(true)
expect(shouldUseHttpsForDevProxy({
NEXT_PUBLIC_API_PREFIX: 'http://localhost:5001/console/api',
NEXT_PUBLIC_PUBLIC_API_PREFIX: 'http://localhost:5001/api',
})).toBe(false)
})
// Scenario: target paths should not be duplicated when the incoming route already includes them.
it('should preserve prefixed targets when building upstream URLs', () => {
// Act
@@ -47,7 +32,6 @@ describe('dev proxy server', () => {
it('should only allow local development origins', () => {
// Assert
expect(isAllowedDevOrigin('http://localhost:3000')).toBe(true)
expect(isAllowedDevOrigin('https://localhost:3000')).toBe(true)
expect(isAllowedDevOrigin('http://127.0.0.1:3000')).toBe(true)
expect(isAllowedDevOrigin('https://example.com')).toBe(false)
})
@@ -102,39 +86,6 @@ describe('dev proxy server', () => {
])
})
// Scenario: secure local proxy responses should keep secure cross-site cookie attributes intact.
it('should preserve secure cookie attributes when the local proxy is https', async () => {
// Arrange
const fetchImpl = vi.fn<typeof fetch>().mockResolvedValue(new Response('ok', {
status: 200,
headers: [
['set-cookie', '__Host-access_token=abc; Path=/console/api; Domain=cloud.dify.ai; Secure; SameSite=None; Partitioned'],
['set-cookie', '__Host-csrf_token=csrf; Path=/console/api; Domain=cloud.dify.ai; Secure; SameSite=None'],
],
}))
const app = createDevProxyApp({
consoleApiTarget: 'https://cloud.dify.ai',
publicApiTarget: 'https://public.dify.ai',
fetchImpl,
})
// Act
const response = await app.request('https://127.0.0.1:5001/console/api/apps?page=1', {
headers: {
Origin: 'https://localhost:3000',
Cookie: 'access_token=abc',
},
})
// Assert
expect(response.headers.getSetCookie()).toEqual([
'__Host-access_token=abc; Path=/; Secure; SameSite=None; Partitioned',
'__Host-csrf_token=csrf; Path=/; Secure; SameSite=None',
])
expect(response.headers.get('access-control-allow-origin')).toBe('https://localhost:3000')
expect(response.headers.get('access-control-allow-credentials')).toBe('true')
})
// Scenario: preflight requests should advertise allowed headers for credentialed cross-origin calls.
it('should answer CORS preflight requests', async () => {
// Arrange

View File

@@ -2,16 +2,10 @@ import type { Context, Hono } from 'hono'
import { Hono as HonoApp } from 'hono'
import { DEFAULT_PROXY_TARGET, rewriteCookieHeaderForUpstream, rewriteSetCookieHeadersForLocal } from './cookies'
export { shouldUseHttpsForDevProxy } from './protocol'
type DevProxyEnv = Partial<Record<
| 'HONO_CONSOLE_API_PROXY_TARGET'
| 'HONO_PUBLIC_API_PROXY_TARGET',
string
> & Record<
| 'NEXT_PUBLIC_API_PREFIX'
| 'NEXT_PUBLIC_PUBLIC_API_PREFIX',
string | undefined
>>
export type DevProxyTargets = {
@@ -99,15 +93,11 @@ const createProxyRequestHeaders = (request: Request, targetUrl: URL) => {
return headers
}
const createUpstreamResponseHeaders = (
response: Response,
requestOrigin: string | null | undefined,
localSecure: boolean,
) => {
const createUpstreamResponseHeaders = (response: Response, requestOrigin?: string | null) => {
const headers = new Headers(response.headers)
RESPONSE_HEADERS_TO_DROP.forEach(header => headers.delete(header))
const rewrittenSetCookies = rewriteSetCookieHeadersForLocal(response.headers.getSetCookie(), { localSecure })
const rewrittenSetCookies = rewriteSetCookieHeadersForLocal(response.headers.getSetCookie())
rewrittenSetCookies?.forEach((cookie) => {
headers.append('set-cookie', cookie)
})
@@ -136,11 +126,7 @@ const proxyRequest = async (
}
const upstreamResponse = await fetchImpl(targetUrl, requestInit)
const responseHeaders = createUpstreamResponseHeaders(
upstreamResponse,
context.req.header('origin'),
requestUrl.protocol === 'https:',
)
const responseHeaders = createUpstreamResponseHeaders(upstreamResponse, context.req.header('origin'))
return new Response(upstreamResponse.body, {
status: upstreamResponse.status,

13
web/pnpm-lock.yaml generated
View File

@@ -512,9 +512,6 @@ importers:
'@typescript/native-preview':
specifier: 7.0.0-dev.20260312.1
version: 7.0.0-dev.20260312.1
'@vitejs/plugin-basic-ssl':
specifier: 2.2.0
version: 2.2.0(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))
'@vitejs/plugin-react':
specifier: 6.0.0
version: 6.0.0(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))
@@ -3606,12 +3603,6 @@ packages:
resolution: {integrity: sha512-hBcWIOppZV14bi+eAmCZj8Elj8hVSUZJTpf1lgGBhVD85pervzQ1poM/qYfFUlPraYSZYP+ASg6To5BwYmUSGQ==}
engines: {node: '>=16'}
'@vitejs/plugin-basic-ssl@2.2.0':
resolution: {integrity: sha512-nmyQ1HGRkfUxjsv3jw0+hMhEdZdrtkvMTdkzRUaRWfiO6PCWw2V2Pz3gldCq96Tn9S8htcgdTxw/gmbLLEbfYw==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
peerDependencies:
vite: ^6.0.0 || ^7.0.0 || ^8.0.0
'@vitejs/plugin-react@5.2.0':
resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -11039,10 +11030,6 @@ snapshots:
'@resvg/resvg-wasm': 2.4.0
satori: 0.16.0
'@vitejs/plugin-basic-ssl@2.2.0(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))':
dependencies:
vite: '@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)'
'@vitejs/plugin-react@5.2.0(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))':
dependencies:
'@babel/core': 7.29.0

View File

@@ -1,10 +1,8 @@
import { createSecureServer } from 'node:http2'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { serve } from '@hono/node-server'
import { getCertificate } from '@vitejs/plugin-basic-ssl'
import { loadEnv } from 'vite'
import { createDevProxyApp, resolveDevProxyTargets, shouldUseHttpsForDevProxy } from '../plugins/dev-proxy/server'
import { createDevProxyApp, resolveDevProxyTargets } from '../plugins/dev-proxy/server'
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
const mode = process.env.MODE || process.env.NODE_ENV || 'development'
@@ -13,33 +11,11 @@ const env = loadEnv(mode, projectRoot, '')
const host = env.HONO_PROXY_HOST || '127.0.0.1'
const port = Number(env.HONO_PROXY_PORT || 5001)
const app = createDevProxyApp(resolveDevProxyTargets(env))
const useHttps = shouldUseHttpsForDevProxy(env)
if (useHttps) {
const certificate = await getCertificate(
path.join(projectRoot, 'node_modules/.vite/basic-ssl'),
'localhost',
Array.from(new Set(['localhost', '127.0.0.1', host])),
)
serve({
fetch: app.fetch,
hostname: host,
port,
})
serve({
fetch: app.fetch,
hostname: host,
port,
createServer: createSecureServer,
serverOptions: {
allowHTTP1: true,
cert: certificate,
key: certificate,
},
})
}
else {
serve({
fetch: app.fetch,
hostname: host,
port,
})
}
console.log(`[dev-hono-proxy] listening on ${useHttps ? 'https' : 'http'}://${host}:${port}`)
console.log(`[dev-hono-proxy] listening on http://${host}:${port}`)

View File

@@ -1,12 +1,9 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import basicSsl from '@vitejs/plugin-basic-ssl'
import react from '@vitejs/plugin-react'
import vinext from 'vinext'
import { loadEnv } from 'vite'
import Inspect from 'vite-plugin-inspect'
import { defineConfig } from 'vite-plus'
import { shouldUseHttpsForDevProxy } from './plugins/dev-proxy/protocol'
import { createCodeInspectorPlugin, createForceInspectorClientInjectionPlugin } from './plugins/vite/code-inspector'
import { customI18nHmrPlugin } from './plugins/vite/custom-i18n-hmr'
import { nextStaticImageTestPlugin } from './plugins/vite/next-static-image-test'
@@ -24,8 +21,6 @@ export default defineConfig(({ mode }) => {
const isTest = mode === 'test'
const isStorybook = process.env.STORYBOOK === 'true'
|| process.argv.some(arg => arg.toLowerCase().includes('storybook'))
const env = loadEnv(mode, projectRoot, '')
const useHttpsForDevServer = shouldUseHttpsForDevProxy(env)
const isAppComponentsCoverage = coverageScope === 'app-components'
const excludedComponentCoverageFiles = isAppComponentsCoverage
? collectComponentCoverageExcludedFiles(path.join(projectRoot, 'app/components'), { pathPrefix: 'app/components' })
@@ -62,7 +57,6 @@ export default defineConfig(({ mode }) => {
react(),
vinext({ react: false }),
customI18nHmrPlugin({ injectTarget: browserInitializerInjectTarget }),
...(useHttpsForDevServer ? [basicSsl()] : []),
// reactGrabOpenFilePlugin({
// injectTarget: browserInitializerInjectTarget,
// projectRoot,