diff --git a/apps/sim/lib/workflows/operations/import-export.test.ts b/apps/sim/lib/workflows/operations/import-export.test.ts new file mode 100644 index 00000000000..7d913327274 --- /dev/null +++ b/apps/sim/lib/workflows/operations/import-export.test.ts @@ -0,0 +1,33 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it } from 'vitest' +import { sanitizePathSegment } from '@/lib/workflows/operations/import-export' + +describe('sanitizePathSegment', () => { + it('should preserve ASCII alphanumeric characters', () => { + expect(sanitizePathSegment('workflow-123_abc')).toBe('workflow-123_abc') + }) + + it('should replace spaces with dashes', () => { + expect(sanitizePathSegment('my workflow')).toBe('my-workflow') + }) + + it('should replace special characters with dashes', () => { + expect(sanitizePathSegment('workflow!@#')).toBe('workflow-') + }) + + it('should preserve Korean characters (BUG REPRODUCTION)', () => { + expect(sanitizePathSegment('한글')).toBe('한글') + }) + + it('should preserve other Unicode characters', () => { + expect(sanitizePathSegment('日本語')).toBe('日本語') + }) + + it('should remove filesystem unsafe characters', () => { + expect(sanitizePathSegment('work/flow?name*')).not.toContain('/') + expect(sanitizePathSegment('work/flow?name*')).not.toContain('?') + expect(sanitizePathSegment('work/flow?name*')).not.toContain('*') + }) +}) diff --git a/apps/sim/lib/workflows/operations/import-export.ts b/apps/sim/lib/workflows/operations/import-export.ts index fdac248f134..093f3617a9f 100644 --- a/apps/sim/lib/workflows/operations/import-export.ts +++ b/apps/sim/lib/workflows/operations/import-export.ts @@ -48,7 +48,7 @@ export interface WorkspaceExportStructure { * Sanitizes a string for use as a path segment in a ZIP file. */ export function sanitizePathSegment(name: string): string { - return name.replace(/[^a-z0-9-_]/gi, '-') + return name.replace(/[^\p{L}\p{N}\-_]/gu, '-').replace(/-+/g, '-') } /**