mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
Merge branch 'main' into feat/support-agent-sandbox
This commit is contained in:
@ -1,78 +0,0 @@
|
||||
/**
|
||||
* Tests for Array.prototype.toSpliced polyfill
|
||||
*/
|
||||
|
||||
describe('toSpliced polyfill', () => {
|
||||
let originalToSpliced: typeof Array.prototype.toSpliced
|
||||
|
||||
beforeEach(() => {
|
||||
// Save original method
|
||||
originalToSpliced = Array.prototype.toSpliced
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// Restore original method
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.toSpliced = originalToSpliced
|
||||
})
|
||||
|
||||
const applyPolyfill = () => {
|
||||
// @ts-expect-error - intentionally deleting for test
|
||||
delete Array.prototype.toSpliced
|
||||
|
||||
if (!Array.prototype.toSpliced) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.toSpliced = function <T>(this: T[], start: number, deleteCount?: number, ...items: T[]): T[] {
|
||||
const copy = this.slice()
|
||||
copy.splice(start, deleteCount ?? copy.length - start, ...items)
|
||||
return copy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it('should add toSpliced method when not available', () => {
|
||||
applyPolyfill()
|
||||
expect(typeof Array.prototype.toSpliced).toBe('function')
|
||||
})
|
||||
|
||||
it('should return a new array without modifying the original', () => {
|
||||
applyPolyfill()
|
||||
const arr = [1, 2, 3, 4, 5]
|
||||
const result = arr.toSpliced(1, 2)
|
||||
|
||||
expect(result).toEqual([1, 4, 5])
|
||||
expect(arr).toEqual([1, 2, 3, 4, 5]) // original unchanged
|
||||
})
|
||||
|
||||
it('should insert items at the specified position', () => {
|
||||
applyPolyfill()
|
||||
const arr: (number | string)[] = [1, 2, 3]
|
||||
const result = arr.toSpliced(1, 0, 'a', 'b')
|
||||
|
||||
expect(result).toEqual([1, 'a', 'b', 2, 3])
|
||||
})
|
||||
|
||||
it('should replace items at the specified position', () => {
|
||||
applyPolyfill()
|
||||
const arr: (number | string)[] = [1, 2, 3, 4, 5]
|
||||
const result = arr.toSpliced(1, 2, 'a', 'b')
|
||||
|
||||
expect(result).toEqual([1, 'a', 'b', 4, 5])
|
||||
})
|
||||
|
||||
it('should handle negative start index', () => {
|
||||
applyPolyfill()
|
||||
const arr = [1, 2, 3, 4, 5]
|
||||
const result = arr.toSpliced(-2, 1)
|
||||
|
||||
expect(result).toEqual([1, 2, 3, 5])
|
||||
})
|
||||
|
||||
it('should delete to end when deleteCount is omitted', () => {
|
||||
applyPolyfill()
|
||||
const arr = [1, 2, 3, 4, 5]
|
||||
const result = arr.toSpliced(2)
|
||||
|
||||
expect(result).toEqual([1, 2])
|
||||
})
|
||||
})
|
||||
@ -1,66 +0,0 @@
|
||||
'use client'
|
||||
|
||||
// Polyfill for Array.prototype.toSpliced (ES2023, Chrome 110+)
|
||||
if (!Array.prototype.toSpliced) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.toSpliced = function <T>(this: T[], start: number, deleteCount?: number, ...items: T[]): T[] {
|
||||
const copy = this.slice()
|
||||
// When deleteCount is undefined (omitted), delete to end; otherwise let splice handle coercion
|
||||
if (deleteCount === undefined)
|
||||
copy.splice(start, copy.length - start, ...items)
|
||||
else
|
||||
copy.splice(start, deleteCount, ...items)
|
||||
return copy
|
||||
}
|
||||
}
|
||||
|
||||
class StorageMock {
|
||||
data: Record<string, string>
|
||||
|
||||
constructor() {
|
||||
this.data = {} as Record<string, string>
|
||||
}
|
||||
|
||||
setItem(name: string, value: string) {
|
||||
this.data[name] = value
|
||||
}
|
||||
|
||||
getItem(name: string) {
|
||||
return this.data[name] || null
|
||||
}
|
||||
|
||||
removeItem(name: string) {
|
||||
delete this.data[name]
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.data = {}
|
||||
}
|
||||
}
|
||||
|
||||
let localStorage, sessionStorage
|
||||
|
||||
try {
|
||||
localStorage = globalThis.localStorage
|
||||
sessionStorage = globalThis.sessionStorage
|
||||
}
|
||||
catch {
|
||||
localStorage = new StorageMock()
|
||||
sessionStorage = new StorageMock()
|
||||
}
|
||||
|
||||
Object.defineProperty(globalThis, 'localStorage', {
|
||||
value: localStorage,
|
||||
})
|
||||
|
||||
Object.defineProperty(globalThis, 'sessionStorage', {
|
||||
value: sessionStorage,
|
||||
})
|
||||
|
||||
const BrowserInitializer = ({
|
||||
children,
|
||||
}: { children: React.ReactElement }) => {
|
||||
return children
|
||||
}
|
||||
|
||||
export default BrowserInitializer
|
||||
@ -1,16 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { IS_DEV } from '@/config'
|
||||
import { env } from '@/env'
|
||||
import dynamic from '@/next/dynamic'
|
||||
|
||||
const SentryInitializer = dynamic(() => import('./sentry-initializer'), { ssr: false })
|
||||
|
||||
const LazySentryInitializer = () => {
|
||||
if (IS_DEV || !env.NEXT_PUBLIC_SENTRY_DSN)
|
||||
return null
|
||||
|
||||
return <SentryInitializer />
|
||||
}
|
||||
|
||||
export default LazySentryInitializer
|
||||
@ -1,27 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as Sentry from '@sentry/react'
|
||||
import { useEffect } from 'react'
|
||||
import { IS_DEV } from '@/config'
|
||||
import { env } from '@/env'
|
||||
|
||||
const SentryInitializer = () => {
|
||||
useEffect(() => {
|
||||
const SENTRY_DSN = env.NEXT_PUBLIC_SENTRY_DSN
|
||||
if (!IS_DEV && SENTRY_DSN) {
|
||||
Sentry.init({
|
||||
dsn: SENTRY_DSN,
|
||||
integrations: [
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration(),
|
||||
],
|
||||
tracesSampleRate: 0.1,
|
||||
replaysSessionSampleRate: 0.1,
|
||||
replaysOnErrorSampleRate: 1.0,
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
return null
|
||||
}
|
||||
|
||||
export default SentryInitializer
|
||||
@ -9,14 +9,12 @@ import { getLocaleOnServer } from '@/i18n-config/server'
|
||||
import { ToastProvider } from './components/base/toast'
|
||||
import { ToastHost } from './components/base/ui/toast'
|
||||
import { TooltipProvider } from './components/base/ui/tooltip'
|
||||
import BrowserInitializer from './components/browser-initializer'
|
||||
import { AgentationLoader } from './components/devtools/agentation-loader'
|
||||
import { ReactScanLoader } from './components/devtools/react-scan/loader'
|
||||
import LazySentryInitializer from './components/lazy-sentry-initializer'
|
||||
import { I18nServerProvider } from './components/provider/i18n-server'
|
||||
import RoutePrefixHandle from './routePrefixHandle'
|
||||
import './styles/globals.css'
|
||||
import './styles/markdown.scss'
|
||||
import './styles/markdown.css'
|
||||
|
||||
export const viewport: Viewport = {
|
||||
width: 'device-width',
|
||||
@ -56,7 +54,6 @@ const LocaleLayout = async ({
|
||||
className="h-full select-auto"
|
||||
{...datasetMap}
|
||||
>
|
||||
<LazySentryInitializer />
|
||||
<div className="isolate h-full">
|
||||
<JotaiProvider>
|
||||
<ThemeProvider
|
||||
@ -67,20 +64,18 @@ const LocaleLayout = async ({
|
||||
enableColorScheme={false}
|
||||
>
|
||||
<NuqsAdapter>
|
||||
<BrowserInitializer>
|
||||
<TanstackQueryInitializer>
|
||||
<I18nServerProvider>
|
||||
<ToastHost timeout={5000} limit={3} />
|
||||
<ToastProvider>
|
||||
<GlobalPublicStoreProvider>
|
||||
<TooltipProvider delay={300} closeDelay={200}>
|
||||
{children}
|
||||
</TooltipProvider>
|
||||
</GlobalPublicStoreProvider>
|
||||
</ToastProvider>
|
||||
</I18nServerProvider>
|
||||
</TanstackQueryInitializer>
|
||||
</BrowserInitializer>
|
||||
<TanstackQueryInitializer>
|
||||
<I18nServerProvider>
|
||||
<ToastHost timeout={5000} limit={3} />
|
||||
<ToastProvider>
|
||||
<GlobalPublicStoreProvider>
|
||||
<TooltipProvider delay={300} closeDelay={200}>
|
||||
{children}
|
||||
</TooltipProvider>
|
||||
</GlobalPublicStoreProvider>
|
||||
</ToastProvider>
|
||||
</I18nServerProvider>
|
||||
</TanstackQueryInitializer>
|
||||
</NuqsAdapter>
|
||||
</ThemeProvider>
|
||||
</JotaiProvider>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
@use '../../themes/markdown-light';
|
||||
@use '../../themes/markdown-dark';
|
||||
@import '../../themes/markdown-light.css';
|
||||
@import '../../themes/markdown-dark.css';
|
||||
|
||||
.markdown-body {
|
||||
-ms-text-size-adjust: 100%;
|
||||
Reference in New Issue
Block a user