Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,16 @@ describe("handelize", () => {
});

test("handles unicode characters", () => {
// Pure unicode with no alphanumerics throws error
expect(() => handelize("日本語.md")).toThrow("no valid filename content");
// Mixed unicode/ascii preserves the ascii parts
expect(handelize("café-notes.md")).toBe("caf-notes.md");
expect(handelize("naïve.md")).toBe("na-ve.md");
expect(handelize("日本語-notes.md")).toBe("notes.md");
// Pure unicode filenames are now supported (Unicode letters/numbers preserved)
expect(handelize("日本語.md")).toBe("日本語.md");
expect(handelize("腾讯混元.md")).toBe("腾讯混元.md");
expect(handelize("한국어.md")).toBe("한국어.md");
// Mixed unicode/ascii preserves all letters
expect(handelize("café-notes.md")).toBe("café-notes.md");
expect(handelize("naïve.md")).toBe("naïve.md");
expect(handelize("日本語-notes.md")).toBe("日本語-notes.md");
// Folder paths with unicode
expect(handelize("中文/文档.md")).toBe("中文/文档.md");
});

test("handles dates and times in filenames", () => {
Expand Down
8 changes: 4 additions & 4 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,11 @@ export function handelize(path: string): string {
}

// Check for paths that are just extensions or only dots/special chars
// A valid path must have at least one alphanumeric character before processing
// A valid path must have at least one letter or number (including Unicode) before processing
const segments = path.split('/').filter(Boolean);
const lastSegment = segments[segments.length - 1] || '';
const filenameWithoutExt = lastSegment.replace(/\.[^.]+$/, '');
const hasValidContent = /[a-zA-Z0-9]/.test(filenameWithoutExt);
const hasValidContent = /[\p{L}\p{N}]/u.test(filenameWithoutExt);
if (!hasValidContent) {
throw new Error(`handelize: path "${path}" has no valid filename content`);
}
Expand All @@ -626,14 +626,14 @@ export function handelize(path: string): string {
const nameWithoutExt = ext ? segment.slice(0, -ext.length) : segment;

const cleanedName = nameWithoutExt
.replace(/[\W_]+/g, '-') // Replace non-word chars with dash
.replace(/[^\p{L}\p{N}]+/gu, '-') // Replace non-letter/number chars with dash (Unicode-aware)
.replace(/^-+|-+$/g, ''); // Remove leading/trailing dashes

return cleanedName + ext;
} else {
// For directories, just clean normally
return segment
.replace(/[\W_]+/g, '-')
.replace(/[^\p{L}\p{N}]+/gu, '-') // Unicode-aware
.replace(/^-+|-+$/g, '');
}
})
Expand Down