chore: eslint add sonar (#17989)
This commit is contained in:
@@ -241,7 +241,8 @@ const Prompt: FC<ISimplePromptInput> = ({
|
||||
selectable: !hasSetBlockStatus.query,
|
||||
}}
|
||||
onChange={(value) => {
|
||||
handleChange?.(value, [])
|
||||
if (handleChange)
|
||||
handleChange(value, [])
|
||||
}}
|
||||
onBlur={() => {
|
||||
handleChange(promptTemplate, getVars(promptTemplate))
|
||||
|
@@ -151,7 +151,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
|
||||
return
|
||||
}
|
||||
|
||||
if (localeData.variable && !/[a-zA-Z_][a-zA-Z0-9_]{0,29}/g.test(localeData.variable)) {
|
||||
if (localeData.variable && !/[a-zA-Z_]\w{0,29}/g.test(localeData.variable)) {
|
||||
notify({ type: 'error', message: t('appDebug.varKeyError.notValid', { key: t('appDebug.feature.tools.modal.variableName.title') }) })
|
||||
return
|
||||
}
|
||||
|
@@ -39,12 +39,12 @@ const OPTION_MAP = {
|
||||
`<script>
|
||||
window.difyChatbotConfig = {
|
||||
token: '${token}'${isTestEnv
|
||||
? `,
|
||||
? `,
|
||||
isDev: true`
|
||||
: ''}${IS_CE_EDITION
|
||||
? `,
|
||||
: ''}${IS_CE_EDITION
|
||||
? `,
|
||||
baseUrl: '${url}'`
|
||||
: ''},
|
||||
: ''},
|
||||
systemVariables: {
|
||||
// user_id: 'YOU CAN DEFINE USER ID HERE',
|
||||
},
|
||||
@@ -110,7 +110,7 @@ const Embedded = ({ siteInfo, isShow, onClose, appBaseUrl, accessToken, classNam
|
||||
}
|
||||
|
||||
const navigateToChromeUrl = () => {
|
||||
window.open('https://chrome.google.com/webstore/detail/dify-chatbot/ceehdapohffmjmkdcifjofadiaoeggaf', '_blank')
|
||||
window.open('https://chrome.google.com/webstore/detail/dify-chatbot/ceehdapohffmjmkdcifjofadiaoeggaf', '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
@@ -97,7 +97,7 @@ const AudioBtn = ({
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className={`flex h-full w-full items-center justify-center rounded-md ${!isAudition ? 'hover:bg-gray-50' : 'hover:bg-gray-50'}`}>
|
||||
<div className={'flex h-full w-full items-center justify-center rounded-md hover:bg-gray-50'}>
|
||||
<div className={`h-4 w-4 ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
|
||||
</div>
|
||||
)}
|
||||
|
@@ -196,7 +196,8 @@ const Chat: FC<ChatProps> = ({
|
||||
const chatContainer = chatContainerRef.current
|
||||
if (chatContainer) {
|
||||
const setUserScrolled = () => {
|
||||
if (chatContainer)
|
||||
// eslint-disable-next-line sonarjs/no-gratuitous-expressions
|
||||
if (chatContainer) // its in event callback, chatContainer may be null
|
||||
userScrolledRef.current = chatContainer.scrollHeight - chatContainer.scrollTop > chatContainer.clientHeight
|
||||
}
|
||||
chatContainer.addEventListener('scroll', setUserScrolled)
|
||||
|
@@ -245,7 +245,7 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
|
||||
>
|
||||
<div className='flex items-center justify-between'>
|
||||
<div className='title-2xl-semi-bold text-text-primary'>{t('appDebug.feature.moderation.modal.title')}</div>
|
||||
<div className='cursor-pointer p-1' onClick={onCancel}><RiCloseLine className='h-4 w-4 text-text-tertiary'/></div>
|
||||
<div className='cursor-pointer p-1' onClick={onCancel}><RiCloseLine className='h-4 w-4 text-text-tertiary' /></div>
|
||||
</div>
|
||||
<div className='py-2'>
|
||||
<div className='text-sm font-medium leading-9 text-text-primary'>
|
||||
@@ -348,14 +348,14 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
|
||||
config={localeData.config?.inputs_config || { enabled: false, preset_response: '' }}
|
||||
onConfigChange={config => handleDataContentChange('inputs_config', config)}
|
||||
info={(localeData.type === 'api' && t('appDebug.feature.moderation.modal.content.fromApi')) || ''}
|
||||
showPreset={!(localeData.type === 'api')}
|
||||
showPreset={localeData.type !== 'api'}
|
||||
/>
|
||||
<ModerationContent
|
||||
title={t('appDebug.feature.moderation.modal.content.output') || ''}
|
||||
config={localeData.config?.outputs_config || { enabled: false, preset_response: '' }}
|
||||
onConfigChange={config => handleDataContentChange('outputs_config', config)}
|
||||
info={(localeData.type === 'api' && t('appDebug.feature.moderation.modal.content.fromApi')) || ''}
|
||||
showPreset={!(localeData.type === 'api')}
|
||||
showPreset={localeData.type !== 'api'}
|
||||
/>
|
||||
<div className='mb-8 mt-1 text-xs font-medium text-text-tertiary'>{t('appDebug.feature.moderation.modal.content.condition')}</div>
|
||||
<div className='flex items-center justify-end'>
|
||||
|
@@ -50,10 +50,7 @@ jest.mock('@/app/components/plugins/marketplace/utils', () => ({
|
||||
getMarketplacePluginsByCollectionId: jest.fn(),
|
||||
}))
|
||||
|
||||
jest.mock('./provider-added-card', () => {
|
||||
// eslint-disable-next-line no-labels, ts/no-unused-expressions
|
||||
UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST: []
|
||||
})
|
||||
jest.mock('./provider-added-card', () => jest.fn())
|
||||
|
||||
after(() => {
|
||||
jest.resetModules()
|
||||
|
@@ -37,7 +37,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
if (parameterRule.type === 'int' || parameterRule.type === 'float')
|
||||
defaultValue = isNullOrUndefined(parameterRule.default) ? (parameterRule.min || 0) : parameterRule.default
|
||||
else if (parameterRule.type === 'string' || parameterRule.type === 'text')
|
||||
defaultValue = parameterRule.options?.length ? (parameterRule.default || '') : (parameterRule.default || '')
|
||||
defaultValue = parameterRule.default || ''
|
||||
else if (parameterRule.type === 'boolean')
|
||||
defaultValue = !isNullOrUndefined(parameterRule.default) ? parameterRule.default : false
|
||||
else if (parameterRule.type === 'tag')
|
||||
@@ -132,8 +132,6 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
step = 1
|
||||
else if (parameterRule.max < 1000)
|
||||
step = 10
|
||||
else if (parameterRule.max < 10000)
|
||||
step = 100
|
||||
}
|
||||
|
||||
return (
|
||||
|
@@ -46,25 +46,23 @@ const CardWrapper = ({
|
||||
}
|
||||
/>
|
||||
{
|
||||
showInstallButton && (
|
||||
<div className='absolute bottom-0 hidden w-full items-center space-x-2 rounded-b-xl bg-gradient-to-tr from-components-panel-on-panel-item-bg to-background-gradient-mask-transparent px-4 pb-4 pt-8 group-hover:flex'>
|
||||
<div className='absolute bottom-0 hidden w-full items-center space-x-2 rounded-b-xl bg-gradient-to-tr from-components-panel-on-panel-item-bg to-background-gradient-mask-transparent px-4 pb-4 pt-8 group-hover:flex'>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='w-[calc(50%-4px)]'
|
||||
onClick={showInstallFromMarketplace}
|
||||
>
|
||||
{t('plugin.detailPanel.operation.install')}
|
||||
</Button>
|
||||
<a href={`${getPluginLinkInMarketplace(plugin)}?language=${localeFromLocale}`} target='_blank' className='block w-[calc(50%-4px)] flex-1 shrink-0'>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='w-[calc(50%-4px)]'
|
||||
onClick={showInstallFromMarketplace}
|
||||
className='w-full gap-0.5'
|
||||
>
|
||||
{t('plugin.detailPanel.operation.install')}
|
||||
{t('plugin.detailPanel.operation.detail')}
|
||||
<RiArrowRightUpLine className='ml-1 h-4 w-4' />
|
||||
</Button>
|
||||
<a href={`${getPluginLinkInMarketplace(plugin)}?language=${localeFromLocale}`} target='_blank' className='block w-[calc(50%-4px)] flex-1 shrink-0'>
|
||||
<Button
|
||||
className='w-full gap-0.5'
|
||||
>
|
||||
{t('plugin.detailPanel.operation.detail')}
|
||||
<RiArrowRightUpLine className='ml-1 h-4 w-4' />
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
isShowInstallFromMarketplace && (
|
||||
|
@@ -72,7 +72,7 @@ const Empty = () => {
|
||||
<div className='flex w-full flex-col gap-y-1'>
|
||||
{[
|
||||
...(
|
||||
(enable_marketplace && true)
|
||||
(enable_marketplace)
|
||||
? [{ icon: MagicBox, text: t('plugin.list.source.marketplace'), action: 'marketplace' }]
|
||||
: []
|
||||
),
|
||||
|
@@ -86,7 +86,7 @@ const InstallPluginDropdown = ({
|
||||
<div className='w-full'>
|
||||
{[
|
||||
...(
|
||||
(enable_marketplace && true)
|
||||
(enable_marketplace)
|
||||
? [{ icon: MagicBox, text: t('plugin.source.marketplace'), action: 'marketplace' }]
|
||||
: []
|
||||
),
|
||||
|
@@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { RiInformation2Line } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Card from '@/app/components/plugins/card'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
@@ -103,15 +102,7 @@ const UpdatePluginModal: FC<Props> = ({
|
||||
if (uploadStep === UploadStep.installed)
|
||||
onSave()
|
||||
}, [onSave, uploadStep, check, originalPackageInfo.id, handleRefetch, targetPackageInfo.id])
|
||||
const usedInAppInfo = useMemo(() => {
|
||||
return (
|
||||
<div className='flex items-center justify-center gap-0.5 px-0.5'>
|
||||
<div className='system-xs-medium text-text-warning'>{t(`${i18nPrefix}.usedInApps`, { num: 3 })}</div>
|
||||
{/* show the used apps */}
|
||||
<RiInformation2Line className='h-4 w-4 text-text-tertiary' />
|
||||
</div>
|
||||
)
|
||||
}, [t])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isShow={true}
|
||||
@@ -136,7 +127,6 @@ const UpdatePluginModal: FC<Props> = ({
|
||||
<Badge className='mx-1' size="s" state={BadgeState.Warning}>
|
||||
{`${originalPackageInfo.payload.version} -> ${targetPackageInfo.version}`}
|
||||
</Badge>
|
||||
{false && usedInAppInfo}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
@@ -66,7 +66,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
if (name === '')
|
||||
return true
|
||||
|
||||
return /^[a-zA-Z0-9_]+$/.test(name)
|
||||
return /^\w+$/.test(name)
|
||||
}
|
||||
|
||||
const onConfirm = () => {
|
||||
|
@@ -84,7 +84,7 @@ const CodeEditor: FC<Props> = ({
|
||||
|
||||
const getUniqVarName = (varName: string) => {
|
||||
if (varList.find(v => v.variable === varName)) {
|
||||
const match = varName.match(/_([0-9]+)$/)
|
||||
const match = varName.match(/_(\d+)$/)
|
||||
|
||||
const index = (() => {
|
||||
if (match)
|
||||
@@ -92,7 +92,7 @@ const CodeEditor: FC<Props> = ({
|
||||
|
||||
return 1
|
||||
})()
|
||||
return getUniqVarName(`${varName.replace(/_([0-9]+)$/, '')}_${index}`)
|
||||
return getUniqVarName(`${varName.replace(/_(\d+)$/, '')}_${index}`)
|
||||
}
|
||||
return varName
|
||||
}
|
||||
|
@@ -278,6 +278,7 @@ const formatItem = (
|
||||
break
|
||||
}
|
||||
|
||||
// eslint-disable-next-line sonarjs/no-duplicated-branches
|
||||
case BlockEnum.VariableAggregator: {
|
||||
const {
|
||||
output_type,
|
||||
@@ -466,7 +467,7 @@ const formatItem = (
|
||||
res.vars = res.vars.filter((v) => {
|
||||
const isCurrentMatched = filterVar(v, (() => {
|
||||
const variableArr = v.variable.split('.')
|
||||
const [first, ..._other] = variableArr
|
||||
const [first] = variableArr
|
||||
if (first === 'sys' || first === 'env' || first === 'conversation')
|
||||
return variableArr
|
||||
|
||||
@@ -611,6 +612,7 @@ const getLoopItemType = ({
|
||||
}: {
|
||||
valueSelector: ValueSelector
|
||||
beforeNodesOutputVars: NodeOutPutVar[]
|
||||
// eslint-disable-next-line sonarjs/no-identical-functions
|
||||
}): VarType => {
|
||||
const outputVarNodeId = valueSelector[0]
|
||||
const isSystem = isSystemVar(valueSelector)
|
||||
@@ -1243,6 +1245,7 @@ export const updateNodeVars = (oldNode: Node, oldVarSelector: ValueSelector, new
|
||||
}
|
||||
break
|
||||
}
|
||||
// eslint-disable-next-line sonarjs/no-duplicated-branches
|
||||
case BlockEnum.VariableAggregator: {
|
||||
const payload = data as VariableAssignerNodeType
|
||||
if (payload.variables) {
|
||||
|
@@ -64,7 +64,7 @@ const Item: FC<ItemProps> = ({
|
||||
const isChatVar = itemData.variable.startsWith('conversation.')
|
||||
const itemRef = useRef<HTMLDivElement>(null)
|
||||
const [isItemHovering, setIsItemHovering] = useState(false)
|
||||
const _ = useHover(itemRef, {
|
||||
useHover(itemRef, {
|
||||
onChange: (hovering) => {
|
||||
if (hovering) {
|
||||
setIsItemHovering(true)
|
||||
@@ -185,7 +185,7 @@ const ObjectChildren: FC<ObjectChildrenProps> = ({
|
||||
const currObjPath = objPath
|
||||
const itemRef = useRef<HTMLDivElement>(null)
|
||||
const [isItemHovering, setIsItemHovering] = useState(false)
|
||||
const _ = useHover(itemRef, {
|
||||
useHover(itemRef, {
|
||||
onChange: (hovering) => {
|
||||
if (hovering) {
|
||||
setIsItemHovering(true)
|
||||
|
@@ -97,7 +97,7 @@ const nodeDefault: NodeDefault<AgentNodeType> = {
|
||||
}
|
||||
// check form of tools
|
||||
else {
|
||||
let validState = {
|
||||
const validState = {
|
||||
isValid: true,
|
||||
errorMessage: '',
|
||||
}
|
||||
@@ -108,13 +108,13 @@ const nodeDefault: NodeDefault<AgentNodeType> = {
|
||||
schemas.forEach((schema: any) => {
|
||||
if (schema?.required) {
|
||||
if (schema.form === 'form' && !userSettings[schema.name]?.value) {
|
||||
return validState = {
|
||||
return {
|
||||
isValid: false,
|
||||
errorMessage: t('workflow.errorMsg.toolParameterRequired', { field: renderI18nObject(param.label, language), param: renderI18nObject(schema.label, language) }),
|
||||
}
|
||||
}
|
||||
if (schema.form === 'llm' && reasoningConfig[schema.name]?.auto === 0 && !reasoningConfig[schema.name]?.value) {
|
||||
return validState = {
|
||||
return {
|
||||
isValid: false,
|
||||
errorMessage: t('workflow.errorMsg.toolParameterRequired', { field: renderI18nObject(param.label, language), param: renderI18nObject(schema.label, language) }),
|
||||
}
|
||||
|
@@ -102,6 +102,7 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
||||
{t('workflow.nodes.agent.toolbox')}
|
||||
</GroupLabel>}>
|
||||
<div className='grid grid-cols-10 gap-0.5'>
|
||||
{/* eslint-disable-next-line sonarjs/no-uniq-key */}
|
||||
{tools.map(tool => <ToolIcon {...tool} key={Math.random()} />)}
|
||||
</div>
|
||||
</Group>}
|
||||
|
@@ -16,16 +16,10 @@ const nodeDefault: NodeDefault<EndNodeType> = {
|
||||
getAvailableNextNodes() {
|
||||
return []
|
||||
},
|
||||
checkValid(payload: EndNodeType) {
|
||||
let isValid = true
|
||||
let errorMessages = ''
|
||||
if (payload.type) {
|
||||
isValid = true
|
||||
errorMessages = ''
|
||||
}
|
||||
checkValid() {
|
||||
return {
|
||||
isValid,
|
||||
errorMessage: errorMessages,
|
||||
isValid: true,
|
||||
errorMessage: '',
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@@ -62,5 +62,5 @@ export const comparisonOperatorNotRequireValue = (operator?: ComparisonOperator)
|
||||
return [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull, ComparisonOperator.exists, ComparisonOperator.notExists].includes(operator)
|
||||
}
|
||||
|
||||
export const VARIABLE_REGEX = /\{\{(#[a-zA-Z0-9_-]{1,50}(\.[a-zA-Z_][a-zA-Z0-9_]{0,29}){1,10}#)\}\}/gi
|
||||
export const VARIABLE_REGEX = /\{\{(#[a-zA-Z0-9_-]{1,50}(\.[a-zA-Z_]\w{0,29}){1,10}#)\}\}/gi
|
||||
export const COMMON_VARIABLE_REGEX = /\{\{([a-zA-Z0-9_-]{1,50})\}\}/gi
|
||||
|
@@ -36,7 +36,6 @@ export const getSelectedDatasetsMode = (datasets: DataSet[] = []) => {
|
||||
allHighQualityFullTextSearch = false
|
||||
allEconomic = false
|
||||
mixtureHighQualityAndEconomic = false
|
||||
inconsistentEmbeddingModel = false
|
||||
allExternal = false
|
||||
allInternal = false
|
||||
mixtureInternalAndExternal = false
|
||||
|
@@ -18,4 +18,5 @@ export function getSelectedNode(
|
||||
return $isAtNodeEnd(anchor) ? anchorNode : focusNode
|
||||
}
|
||||
|
||||
// eslint-disable-next-line sonarjs/empty-string-repetition
|
||||
export const urlRegExp = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/
|
||||
|
@@ -38,7 +38,7 @@ const ObjectValueItem: FC<Props> = ({
|
||||
const handleKeyChange = useCallback((index: number) => {
|
||||
return (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newList = produce(list, (draft: any[]) => {
|
||||
if (!/^[a-zA-Z0-9_]+$/.test(e.target.value))
|
||||
if (!/^\w+$/.test(e.target.value))
|
||||
return notify({ type: 'error', message: 'key is can only contain letters, numbers and underscores' })
|
||||
draft[index].key = e.target.value
|
||||
})
|
||||
|
@@ -95,7 +95,7 @@ const VariableModal = ({
|
||||
type === 'number' && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg font-medium text-text-primary shadow-xs hover:border-components-option-card-option-selected-border',
|
||||
)} onClick={() => {
|
||||
setType('number')
|
||||
if (!(/^[0-9]$/).test(value))
|
||||
if (!(/^\d$/).test(value))
|
||||
setValue('')
|
||||
}}>Number</div>
|
||||
<div className={cn(
|
||||
|
@@ -1,37 +0,0 @@
|
||||
import graphToLogStruct from '../graph-to-log-struct'
|
||||
|
||||
describe('parallel', () => {
|
||||
const list = graphToLogStruct('(parallel, parallelNode, nodeA, nodeB -> nodeC)')
|
||||
const [parallelNode, ...parallelDetail] = list
|
||||
const parallelI18n = 'PARALLEL'
|
||||
// format will change the list...
|
||||
// const result = format(cloneDeep(list) as any, () => parallelI18n)
|
||||
|
||||
test('parallel should put nodes in details', () => {
|
||||
// expect(result as any).toEqual([
|
||||
// {
|
||||
// ...parallelNode,
|
||||
// parallelDetail: {
|
||||
// isParallelStartNode: true,
|
||||
// parallelTitle: `${parallelI18n}-1`,
|
||||
// children: [
|
||||
// parallelNode,
|
||||
// {
|
||||
// ...parallelDetail[0],
|
||||
// parallelDetail: {
|
||||
// branchTitle: `${parallelI18n}-1-A`,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// ...parallelDetail[1],
|
||||
// parallelDetail: {
|
||||
// branchTitle: `${parallelI18n}-1-B`,
|
||||
// },
|
||||
// },
|
||||
// parallelDetail[2],
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
// ])
|
||||
})
|
||||
})
|
@@ -148,6 +148,7 @@ const format = (list: NodeTracing[], t: any, isPrint?: boolean): NodeTracing[] =
|
||||
return false
|
||||
|
||||
const isParallelStartNode = node.parallelDetail?.isParallelStartNode
|
||||
// eslint-disable-next-line sonarjs/prefer-single-boolean-return
|
||||
if (!isParallelStartNode)
|
||||
return false
|
||||
|
||||
|
@@ -14,8 +14,5 @@ export const variableTransformer = (v: ValueSelector | string) => {
|
||||
}
|
||||
|
||||
export const isExceptionVariable = (variable: string, nodeType?: BlockEnum) => {
|
||||
if ((variable === 'error_message' || variable === 'error_type') && hasErrorHandleNode(nodeType))
|
||||
return true
|
||||
|
||||
return false
|
||||
return (variable === 'error_message' || variable === 'error_type') && hasErrorHandleNode(nodeType)
|
||||
}
|
||||
|
Reference in New Issue
Block a user