refactor: no slugs util

This commit is contained in:
tdgao
2026-09-03 11:17:43 -06:00
parent 6c7d40fbd9
commit 6e6ca3302c
4 changed files with 38 additions and 40 deletions
@@ -85,7 +85,7 @@ import {
} from '@modrinth/ui'
import { ref } from 'vue'
import { generateUrlSlug } from '~/utils/slugs'
import { generateUrlSlug } from '~/composables/project-slug-suggestions'
import CreateLimitAlert from './CreateLimitAlert.vue'
@@ -160,10 +160,10 @@ import { computed, defineAsyncComponent, h } from 'vue'
import SlugSuggestions from '~/components/ui/SlugSuggestions.vue'
import {
generateUrlSlug,
useProjectSlugSuggestions,
useSlugSuggestionVisibility,
} from '~/composables/project-slug-suggestions'
import { generateUrlSlug } from '~/utils/slugs'
import CreateLimitAlert from './CreateLimitAlert.vue'
@@ -3,10 +3,10 @@ import { injectModrinthClient } from '@modrinth/ui'
import { useQueryClient } from '@tanstack/vue-query'
import { type MaybeRefOrGetter, onScopeDispose, ref, toValue, watch } from 'vue'
import { generateProjectSlugSuggestions } from '~/utils/slugs'
const STALE_TIME = 1000 * 60 * 5
const CHECK_DEBOUNCE = 300
const PROJECT_SLUG_UNSAFE_CHARS = /[^a-zA-Z0-9._-]/g
const PROJECT_SLUG_REGEX = /^[a-zA-Z0-9._-]{3,64}$/
interface ProjectSlugSuggestionOptions {
title: MaybeRefOrGetter<string>
@@ -14,6 +14,40 @@ interface ProjectSlugSuggestionOptions {
currentProjectId?: MaybeRefOrGetter<string | null | undefined>
}
export function generateUrlSlug(value: string) {
return value
.trim()
.toLowerCase()
.replaceAll(' ', '-')
.replaceAll(PROJECT_SLUG_UNSAFE_CHARS, '')
.replaceAll(/--+/gm, '-')
}
function isValidProjectSlug(value: string) {
return PROJECT_SLUG_REGEX.test(value)
}
function generateProjectSlugSuggestions(title: string, username?: string | null) {
const titleSlug = generateUrlSlug(title)
const titleWords = title
.trim()
.split(/\s+/)
.map((word) => generateUrlSlug(word))
.filter(Boolean)
const acronym = titleWords.length > 1 ? titleWords.map((word) => word[0]).join('') : ''
const withoutDashes = titleSlug.replaceAll('-', '')
const usernameSlug = username ? generateUrlSlug(username) : ''
let withUsername = ''
if (titleSlug && usernameSlug) {
const availableTitleLength = 64 - usernameSlug.length - 1
const truncatedTitle = titleSlug.slice(0, availableTitleLength).replace(/-+$/, '')
if (truncatedTitle) withUsername = `${truncatedTitle}-${usernameSlug}`
}
return [...new Set([titleSlug, acronym, withoutDashes, withUsername])].filter(isValidProjectSlug)
}
export function useSlugSuggestionVisibility() {
const visible = ref(false)
-36
View File
@@ -1,36 +0,0 @@
const PROJECT_SLUG_UNSAFE_CHARS = /[^a-zA-Z0-9._-]/g
const PROJECT_SLUG_REGEX = /^[a-zA-Z0-9._-]{3,64}$/
export function generateUrlSlug(value: string) {
return value
.trim()
.toLowerCase()
.replaceAll(' ', '-')
.replaceAll(PROJECT_SLUG_UNSAFE_CHARS, '')
.replaceAll(/--+/gm, '-')
}
export function isValidProjectSlug(value: string) {
return PROJECT_SLUG_REGEX.test(value)
}
export function generateProjectSlugSuggestions(title: string, username?: string | null) {
const titleSlug = generateUrlSlug(title)
const titleWords = title
.trim()
.split(/\s+/)
.map((word) => generateUrlSlug(word))
.filter(Boolean)
const acronym = titleWords.length > 1 ? titleWords.map((word) => word[0]).join('') : ''
const withoutDashes = titleSlug.replaceAll('-', '')
const usernameSlug = username ? generateUrlSlug(username) : ''
let withUsername = ''
if (titleSlug && usernameSlug) {
const availableTitleLength = 64 - usernameSlug.length - 1
const truncatedTitle = titleSlug.slice(0, availableTitleLength).replace(/-+$/, '')
if (truncatedTitle) withUsername = `${truncatedTitle}-${usernameSlug}`
}
return [...new Set([titleSlug, acronym, withoutDashes, withUsername])].filter(isValidProjectSlug)
}