mirror of
https://github.com/langgenius/dify.git
synced 2026-08-29 19:54:46 +08:00
Signed-off-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: 起岚 <155608604+xiaoyaoqilan@users.noreply.github.com> Co-authored-by: Parman Mohammadalizadeh <prmma23@gmail.com> Co-authored-by: Escape0707 <tothesong@gmail.com> Co-authored-by: Xin Zhang <zhangxin@dify.ai> Co-authored-by: iridescentWen <66297467+iridescentWen@users.noreply.github.com> Co-authored-by: Bond Zhu <37842169+MRZHUH@users.noreply.github.com> Co-authored-by: KVOJJJin <jzongcode@gmail.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Chester <superdiao6@gmail.com> Co-authored-by: WH-2099 <wh2099@pm.me> Co-authored-by: Jony <619963502@qq.com> Co-authored-by: Jony <13896935+zyz619963502zyz@users.noreply.github.com> Co-authored-by: Harsh Kashyap <harsh.kashyap2001@gmail.com> Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com> Co-authored-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: csurong <csurong1@gmail.com> Co-authored-by: caosurong <surong.cao@thinkingdata.cn> Co-authored-by: Taranum Wasu <81034301+Taranum01@users.noreply.github.com> Co-authored-by: Taranum01 <50813317+Taranum01@users.noreply.github.com> Co-authored-by: Pranav Agarwal <agarwalpranav0711@gmail.com> Co-authored-by: Stephen Zhou <hi@hyoban.cc> Co-authored-by: zl86790 <marshal_li_b@163.com> Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com> Co-authored-by: yunlu.wen <yunlu.wen@dify.ai> Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
70 lines
2.8 KiB
TypeScript
70 lines
2.8 KiB
TypeScript
type QueryArrayCompatibilityRule = {
|
|
path: RegExp
|
|
fields: readonly string[]
|
|
}
|
|
|
|
// Keep oRPC query-array compatibility at the console OpenAPI transport boundary instead of
|
|
// making backend handlers accept multiple serialized forms. oRPC v2 supports custom query
|
|
// parameter serialization, so this bridge can be removed once we configure repeated keys there.
|
|
const repeatedQueryArrayRules: readonly QueryArrayCompatibilityRule[] = [
|
|
{ path: /\/agent$/, fields: ['tag_ids', 'creator_ids'] },
|
|
{ path: /\/agent\/[^/]+\/logs$/, fields: ['sources', 'statuses'] },
|
|
{ path: /\/agent\/[^/]+\/logs\/[^/]+\/messages$/, fields: ['sources', 'statuses'] },
|
|
{ path: /\/apps$/, fields: ['tag_ids', 'creator_ids'] },
|
|
{ path: /\/apps\/starred$/, fields: ['tag_ids', 'creator_ids'] },
|
|
{ path: /\/datasets$/, fields: ['ids', 'tag_ids'] },
|
|
{ path: /\/datasets\/[^/]+\/documents\/[^/]+\/segment\/[^/]+$/, fields: ['segment_id'] },
|
|
{ path: /\/datasets\/[^/]+\/documents\/[^/]+\/segments$/, fields: ['segment_id', 'status'] },
|
|
{ path: /\/trial-apps\/[^/]+\/datasets$/, fields: ['ids'] },
|
|
{ path: /\/workspaces\/current\/customized-snippets$/, fields: ['tag_ids', 'creators'] },
|
|
{ path: /\/workspaces\/current\/skills$/, fields: ['tag'] },
|
|
{ path: /\/workspaces\/current\/plugin\/[^/]+\/list$/, fields: ['tags'] },
|
|
{
|
|
path: /\/workspaces\/current\/tool-provider\/builtin\/[^/]+\/credential\/info$/,
|
|
fields: ['include_credential_ids'],
|
|
},
|
|
{
|
|
path: /\/workspaces\/current\/tool-provider\/builtin\/[^/]+\/credentials$/,
|
|
fields: ['include_credential_ids'],
|
|
},
|
|
]
|
|
|
|
const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
|
|
const getRepeatedQueryArrayFields = (pathname: string) =>
|
|
repeatedQueryArrayRules.find((rule) => rule.path.test(pathname))?.fields ?? []
|
|
|
|
const rewriteIndexedQueryArrayParam = (url: URL, field: string) => {
|
|
const indexedParamPattern = new RegExp(`^${escapeRegExp(field)}\\[(\\d+)\\]$`)
|
|
const values: Array<{ index: number; value: string }> = []
|
|
const indexedKeys = new Set<string>()
|
|
|
|
url.searchParams.forEach((value, key) => {
|
|
const match = indexedParamPattern.exec(key)
|
|
if (!match) return
|
|
|
|
indexedKeys.add(key)
|
|
values.push({ index: Number(match[1]), value })
|
|
})
|
|
|
|
if (!values.length) return false
|
|
|
|
indexedKeys.forEach((key) => url.searchParams.delete(key))
|
|
values
|
|
.sort((a, b) => a.index - b.index)
|
|
.forEach(({ value }) => url.searchParams.append(field, value))
|
|
|
|
return true
|
|
}
|
|
|
|
export function normalizeConsoleOpenAPIURL(url: string | URL) {
|
|
const normalizedUrl = new URL(url)
|
|
const repeatedQueryArrayFields = getRepeatedQueryArrayFields(normalizedUrl.pathname)
|
|
|
|
if (!repeatedQueryArrayFields.length) return normalizedUrl.href
|
|
|
|
repeatedQueryArrayFields.forEach((field) => rewriteIndexedQueryArrayParam(normalizedUrl, field))
|
|
|
|
return normalizedUrl.href
|
|
}
|