diff --git a/packages/api/src/dto/resume.ts b/packages/api/src/dto/resume.ts index 3292bead5..248e245c2 100644 --- a/packages/api/src/dto/resume.ts +++ b/packages/api/src/dto/resume.ts @@ -6,12 +6,12 @@ import { jsonPatchOperationSchema } from "@reactive-resume/utils/resume/patch"; const resumeSchema = createSelectSchema(schema.resume, { id: z.string().describe("The ID of the resume."), - name: z.string().min(1).describe("The name of the resume."), - slug: z.string().min(1).describe("The slug of the resume."), + name: z.string().trim().min(1).describe("The name of the resume."), + slug: z.string().trim().min(1).describe("The slug of the resume."), tags: z.array(z.string()).describe("The tags of the resume."), isPublic: z.boolean().describe("Whether the resume is public."), isLocked: z.boolean().describe("Whether the resume is locked."), - password: z.string().min(6).nullable().describe("The password of the resume, if any."), + password: z.string().trim().min(6).max(64).nullable().describe("The password of the resume, if any."), data: resumeDataSchema, userId: z.string().describe("The ID of the user who owns the resume."), createdAt: z.date().describe("The date and time the resume was created."), diff --git a/packages/utils/src/string.test.ts b/packages/utils/src/string.test.ts index ff8dc0c4b..18a523c6c 100644 --- a/packages/utils/src/string.test.ts +++ b/packages/utils/src/string.test.ts @@ -50,6 +50,10 @@ describe("slugify", () => { it("handles unicode emojis by stripping them", () => { expect(slugify("Hello 🌍 World")).toBe("hello-world"); }); + + it("falls back to a non-empty slug for CJK input", () => { + expect(slugify("ä¸­æ–‡įŽ€åŽ†")).not.toBe(""); + }); }); describe("getInitials", () => { diff --git a/packages/utils/src/string.ts b/packages/utils/src/string.ts index 11af0fd29..6e6dd965b 100644 --- a/packages/utils/src/string.ts +++ b/packages/utils/src/string.ts @@ -16,7 +16,9 @@ export function generateId() { * @returns The slugified value. */ export function slugify(value: string) { - return _slugify(value, { decamelize: false }); + const slug = _slugify(value, { decamelize: false }); + if (slug || !value.trim()) return slug; + return slugify(generateRandomName()); } /**