flnxi-Wu/scripts/cleanup-category-options.js
WuYongJie d1c6efc79d
Some checks failed
CI Check / check (push) Has been cancelled
feat: NAS 部署与 Harbor 推送流程
2025-12-03 14:39:06 +08:00

186 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
function isArrayString(str) {
const trimmed = (str || '').trim()
if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) return false
try {
const parsed = JSON.parse(trimmed)
return Array.isArray(parsed)
} catch {
return false
}
}
function normalizeOptionValue(option) {
let cleaned = (option || '').trim()
if (!cleaned) return ''
try {
if (
(cleaned.startsWith('"') && cleaned.endsWith('"')) ||
(cleaned.startsWith("'") && cleaned.endsWith("'"))
) {
const parsed = JSON.parse(cleaned)
if (typeof parsed === 'string') {
cleaned = parsed.trim()
}
}
} catch {
// ignore parse errors
}
cleaned = cleaned.replace(/\\+"/g, '"').replace(/\\'/g, "'")
cleaned = cleaned.replace(/["'`“”]/g, '')
cleaned = cleaned.trim()
if (cleaned.startsWith('\\') && cleaned.endsWith('\\')) {
cleaned = cleaned.slice(1, -1).trim()
}
return cleaned.trim()
}
function stripLooseBrackets(value) {
let result = (value || '').trim()
let guard = 0
while (result.startsWith('[') && result.endsWith(']') && guard < 5) {
const inner = result.slice(1, -1).trim()
if (!inner || inner === result) {
break
}
result = inner
guard += 1
}
return result
}
function extractLooseArrayOptions(option) {
let trimmed = (option || '').trim()
if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) return null
let inner = trimmed
let safeGuard = 0
while (inner.startsWith('[') && inner.endsWith(']') && safeGuard < 5) {
const next = inner.slice(1, -1).trim()
if (!next || next === inner) {
break
}
inner = next
safeGuard += 1
}
if (!inner) return []
const segments = inner.split(/[,,]/).map(seg => normalizeOptionValue(seg)).filter(Boolean)
if (segments.length > 1) {
return segments
}
const single = normalizeOptionValue(inner)
return single ? [single] : null
}
function sanitizeOptions(optionsStatic) {
if (!optionsStatic) return []
const result = new Set()
const pushOption = (value) => {
const normalized = stripLooseBrackets(normalizeOptionValue(value))
if (normalized && !isArrayString(normalized)) {
result.add(normalized)
}
}
try {
const parsed = JSON.parse(optionsStatic)
if (Array.isArray(parsed)) {
parsed.forEach(opt => {
const optStr = String(opt || '').trim()
if (!optStr) return
const loose = extractLooseArrayOptions(optStr)
if (loose && loose.length) {
loose.forEach(pushOption)
return
}
if (isArrayString(optStr)) {
try {
const nested = JSON.parse(optStr)
if (Array.isArray(nested)) {
nested.forEach(item => pushOption(String(item)))
return
}
} catch {
// ignore
}
}
pushOption(optStr)
})
return Array.from(result)
}
} catch {
// ignored
}
optionsStatic
.split('\n')
.map(line => line.trim())
.filter(Boolean)
.forEach(line => {
const loose = extractLooseArrayOptions(line)
if (loose && loose.length) {
loose.forEach(pushOption)
} else {
pushOption(line)
}
})
return Array.from(result)
}
async function main() {
const fields = await prisma.uploadField.findMany({
where: {
optionsStatic: {
not: null,
},
},
select: {
id: true,
key: true,
label: true,
optionsStatic: true,
},
})
let updated = 0
for (const field of fields) {
const sanitized = sanitizeOptions(field.optionsStatic)
const sanitizedJson = JSON.stringify(sanitized)
const currentTrimmed = (field.optionsStatic || '').trim()
if (sanitizedJson && sanitizedJson !== currentTrimmed) {
await prisma.uploadField.update({
where: { id: field.id },
data: { optionsStatic: sanitizedJson },
})
updated += 1
console.log(`[Cleanup] Updated ${field.key} (${field.label}) -> ${sanitizedJson}`)
}
}
console.log(`Cleanup finished. Updated ${updated} field(s).`)
}
main()
.catch((error) => {
console.error('Cleanup failed:', error)
process.exitCode = 1
})
.finally(async () => {
await prisma.$disconnect()
})