返回 AiToEarn
configFieldMeta.ts
根目录 / project / aitoearn-web / src / app / layout / ConfigManagerDialog / utils / configFieldMeta.ts
1 import type { ConfigPath, ConfigValue } from '../types'
2 import { formatConfigKey, isRecord, stableStringify } from './configPath'
3
4 const sensitiveKeyPattern = /apiKey|key|secret|password|token|credential|accessKey/i
5
6 export function getLastStringSegment(path: ConfigPath, fallback: string) {
7 const segment = [...path].reverse().find(item => typeof item === 'string')
8 return typeof segment === 'string' ? segment : fallback
9 }
10
11 export function translateWithFallback(t: (key: string) => string, key: string, fallback: string) {
12 const translated = t(key)
13 return translated === key ? fallback : translated
14 }
15
16 export function getConfigFieldLabel(t: (key: string) => string, path: ConfigPath, fieldKey: string) {
17 const key = getLastStringSegment(path, fieldKey)
18 return translateWithFallback(t, `fields.${key}`, formatConfigKey(key))
19 }
20
21 export function isSensitiveConfigPath(path: ConfigPath) {
22 return path.some(segment => typeof segment === 'string' && sensitiveKeyPattern.test(segment))
23 }
24
25 export function isConfigValueModified(value: ConfigValue, originalValue: ConfigValue) {
26 return stableStringify(value) !== stableStringify(originalValue)
27 }
28
29 export function countLeafFields(value: unknown): number {
30 if (Array.isArray(value)) {
31 if (value.length === 0)
32 return 1
33 return value.reduce<number>((count, item) => count + countLeafFields(item), 0)
34 }
35
36 if (isRecord(value)) {
37 const entries = Object.values(value)
38 if (entries.length === 0)
39 return 1
40 return entries.reduce<number>((count, item) => count + countLeafFields(item), 0)
41 }
42
43 return 1
44 }
45
46 export function countModifiedLeafFields(value: unknown, originalValue: unknown): number {
47 if (value === undefined && originalValue !== undefined)
48 return countLeafFields(originalValue)
49
50 if (Array.isArray(value)) {
51 if (!Array.isArray(originalValue))
52 return countLeafFields(value)
53 if (value.length === 0)
54 return isConfigValueModified(value, originalValue) ? 1 : 0
55
56 const maxLength = Math.max(value.length, originalValue.length)
57 let count = 0
58 for (let index = 0; index < maxLength; index += 1)
59 count += countModifiedLeafFields(value[index], originalValue[index])
60 return count
61 }
62
63 if (isRecord(value)) {
64 if (!isRecord(originalValue))
65 return countLeafFields(value)
66
67 const keys = new Set([...Object.keys(value), ...Object.keys(originalValue)])
68 if (keys.size === 0)
69 return isConfigValueModified(value, originalValue) ? 1 : 0
70
71 let count = 0
72 keys.forEach((key) => {
73 count += countModifiedLeafFields(value[key], originalValue[key])
74 })
75 return count
76 }
77
78 return isConfigValueModified(value, originalValue) ? 1 : 0
79 }
80
80 lines TYPESCRIPT