test
This commit is contained in:
@@ -12,79 +12,40 @@ const isUsernameTaken = async (UserModel, userName, excludeUserId) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const splitBaseAndSuffix = (value) => {
|
||||
const match = value.match(/^(.*?)(\d+)$/)
|
||||
if (!match || !match[1]) {
|
||||
return { core: value, suffix: null }
|
||||
}
|
||||
return { core: match[1], suffix: Number.parseInt(match[2], 10) }
|
||||
const buildCandidates = (base, attempt) => {
|
||||
const random2 = () => String(Math.floor(Math.random() * 90 + 10))
|
||||
const random3 = () => String(Math.floor(Math.random() * 900 + 100))
|
||||
const random4 = () => String(Math.floor(Math.random() * 9000 + 1000))
|
||||
|
||||
const builders = [
|
||||
() => `${base}_${random2()}`,
|
||||
() => `${base}.${random2()}`,
|
||||
() => `${base}${random3()}`,
|
||||
() => `${base}-${random2()}`,
|
||||
() => `${base}_${random3()}`,
|
||||
() => `${base}${random4()}`,
|
||||
]
|
||||
|
||||
return builders[attempt % builders.length]()
|
||||
}
|
||||
|
||||
const trimToMax = (value) =>
|
||||
value.length > USERNAME_MAX_LENGTH ? value.slice(0, USERNAME_MAX_LENGTH) : value
|
||||
|
||||
/** پیشنهادهای مشابه: amiri2 → amiri3, amiri5, amiiri3, amiri334 */
|
||||
const buildCandidates = (base) => {
|
||||
const { core, suffix } = splitBaseAndSuffix(base)
|
||||
const candidates = []
|
||||
|
||||
if (suffix !== null && !Number.isNaN(suffix)) {
|
||||
candidates.push(`${core}${suffix + 1}`)
|
||||
candidates.push(`${core}${suffix + 3}`)
|
||||
candidates.push(`${core}${suffix}${Math.floor(Math.random() * 9 + 1)}`)
|
||||
}
|
||||
|
||||
const numericSuffixes = [3, 5, 7, 12, 21, 34, 99, 334, 567]
|
||||
numericSuffixes.forEach((num) => {
|
||||
candidates.push(`${core}${num}`)
|
||||
})
|
||||
|
||||
for (let i = 1; i < Math.min(core.length, 5); i += 1) {
|
||||
const ch = core[i]
|
||||
if (!ch) continue
|
||||
const doubled = `${core.slice(0, i)}${ch}${core.slice(i)}`
|
||||
candidates.push(`${doubled}${suffix !== null ? suffix + 1 : 3}`)
|
||||
candidates.push(`${doubled}${Math.floor(Math.random() * 90 + 10)}`)
|
||||
}
|
||||
|
||||
candidates.push(`${core}_${suffix !== null ? suffix + 1 : 1}`)
|
||||
candidates.push(`${core}.${Math.floor(Math.random() * 900 + 100)}`)
|
||||
candidates.push(`${core}-${Math.floor(Math.random() * 90 + 10)}`)
|
||||
|
||||
return [...new Set(candidates.map(trimToMax))]
|
||||
}
|
||||
|
||||
const generateUsernameSuggestions = async (
|
||||
UserModel,
|
||||
baseUsername,
|
||||
excludeUserId,
|
||||
count = 3
|
||||
) => {
|
||||
const base = baseUsername.trim().toLowerCase()
|
||||
const generateUsernameSuggestions = async (UserModel, baseUserName, excludeUserId) => {
|
||||
const base = trimToMax(baseUserName.trim().toLowerCase())
|
||||
const suggestions = []
|
||||
const tried = new Set([base])
|
||||
let attempt = 0
|
||||
|
||||
for (let attempt = 0; attempt < 80 && suggestions.length < count; attempt += 1) {
|
||||
const candidates = buildCandidates(base)
|
||||
while (suggestions.length < 3 && attempt < 30) {
|
||||
const candidate = trimToMax(buildCandidates(base, attempt))
|
||||
attempt += 1
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (suggestions.length >= count) break
|
||||
if (tried.has(candidate)) continue
|
||||
tried.add(candidate)
|
||||
if (validateUsername(candidate)) continue
|
||||
if (validateUsername(candidate)) continue
|
||||
if (suggestions.includes(candidate)) continue
|
||||
if (await isUsernameTaken(UserModel, candidate, excludeUserId)) continue
|
||||
|
||||
const taken = await isUsernameTaken(UserModel, candidate, excludeUserId)
|
||||
if (!taken) suggestions.push(candidate)
|
||||
}
|
||||
|
||||
if (suggestions.length < count) {
|
||||
const fallback = trimToMax(`${base}${Math.floor(Math.random() * 9000 + 1000)}`)
|
||||
if (!tried.has(fallback) && !validateUsername(fallback)) {
|
||||
tried.add(fallback)
|
||||
const taken = await isUsernameTaken(UserModel, fallback, excludeUserId)
|
||||
if (!taken) suggestions.push(fallback)
|
||||
}
|
||||
}
|
||||
suggestions.push(candidate)
|
||||
}
|
||||
|
||||
return suggestions
|
||||
@@ -92,5 +53,4 @@ const generateUsernameSuggestions = async (
|
||||
|
||||
module.exports = {
|
||||
generateUsernameSuggestions,
|
||||
isUsernameTaken
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user