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:
Aslam
2024-09-09 17:35:15 +07:00
committed by GitHub
parent 66c96efad8
commit 5f537d5618
14 changed files with 420 additions and 39 deletions

View 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}$/)
})
})

View File

@@ -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}`
}