mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
feat: pages (#151)
* wip * wip * wip * wwip * wip * wip * fix(util): rmeove checking to existing in slug * wip * chore: handle create page * chore: handle page title untitled
This commit is contained in:
29
web/lib/utils/slug.test.ts
Normal file
29
web/lib/utils/slug.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { generateUniqueSlug } from "./slug"
|
||||
|
||||
describe("generateUniqueSlug", () => {
|
||||
it("should generate a slug with the correct format", () => {
|
||||
const title = "This is a test title"
|
||||
const slug = generateUniqueSlug(title)
|
||||
expect(slug).toMatch(/^this-is-a-test-title-[a-f0-9]{8}$/)
|
||||
})
|
||||
|
||||
it("should respect the maxLength parameter", () => {
|
||||
const title = "This is a very long title that should be truncated"
|
||||
const maxLength = 30
|
||||
const slug = generateUniqueSlug(title, maxLength)
|
||||
expect(slug.length).toBe(maxLength)
|
||||
})
|
||||
|
||||
it("should generate different slugs for the same title", () => {
|
||||
const title = "Same Title"
|
||||
const slug1 = generateUniqueSlug(title)
|
||||
const slug2 = generateUniqueSlug(title)
|
||||
expect(slug1).not.toBe(slug2)
|
||||
})
|
||||
|
||||
it("should handle empty strings", () => {
|
||||
const title = ""
|
||||
const slug = generateUniqueSlug(title)
|
||||
expect(slug).toMatch(/^-[a-f0-9]{8}$/)
|
||||
})
|
||||
})
|
||||
@@ -1,36 +1,14 @@
|
||||
import slugify from "slugify"
|
||||
import crypto from "crypto"
|
||||
|
||||
type SlugLikeProperty = string | undefined
|
||||
export function generateUniqueSlug(title: string, maxLength: number = 60): string {
|
||||
const baseSlug = slugify(title, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
const randomSuffix = crypto.randomBytes(4).toString("hex")
|
||||
|
||||
interface Data {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export function generateUniqueSlug(
|
||||
existingItems: Data[],
|
||||
title: string,
|
||||
slugProperty: string = "slug",
|
||||
maxLength: number = 50
|
||||
): string {
|
||||
const baseSlug = slugify(title, { lower: true, strict: true })
|
||||
let uniqueSlug = baseSlug.slice(0, maxLength)
|
||||
let num = 1
|
||||
|
||||
if (!existingItems || existingItems.length === 0) {
|
||||
return uniqueSlug
|
||||
}
|
||||
|
||||
const isSlugTaken = (slug: string) =>
|
||||
existingItems.some(item => {
|
||||
const itemSlug = item[slugProperty] as SlugLikeProperty
|
||||
return itemSlug === slug
|
||||
})
|
||||
|
||||
while (isSlugTaken(uniqueSlug)) {
|
||||
const suffix = `-${num}`
|
||||
uniqueSlug = `${baseSlug.slice(0, maxLength - suffix.length)}${suffix}`
|
||||
num++
|
||||
}
|
||||
|
||||
return uniqueSlug
|
||||
const truncatedSlug = baseSlug.slice(0, Math.min(maxLength, 75) - 9)
|
||||
|
||||
return `${truncatedSlug}-${randomSuffix}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user