diff --git a/packages/url/__tests__/url.test.ts b/packages/url/__tests__/url.test.ts index 7f51e4a..eac14de 100644 --- a/packages/url/__tests__/url.test.ts +++ b/packages/url/__tests__/url.test.ts @@ -209,6 +209,14 @@ describe('Url', () => { it('should return as is', () => { expect(extractPublicId('example')).toEqual('example') }) + + it('should correctly handle filenames with no extension', () => { + expect(extractPublicId('https://res.cloudinary.com/xyz/image/upload/v111111111/Folder/noextension')).toBe('Folder/noextension') + }) + + it('should allow multiple dots in the filename before the extension', () => { + expect(extractPublicId('https://res.cloudinary.com/xyz/image/upload/v111111111/Folder/Name.With.Multiple.Dots.png')).toBe('Folder/Name.With.Multiple.Dots') + }) }) describe('getSubDomain', () => { diff --git a/packages/url/lib/url.ts b/packages/url/lib/url.ts index 6dbd0f3..cb56cad 100644 --- a/packages/url/lib/url.ts +++ b/packages/url/lib/url.ts @@ -6,14 +6,19 @@ import { toTransformationStr, transform } from './transformers' const SHARED_CDNS:string[] = ["cloudinary-a.akamaihd.net", "res.cloudinary.com"] //eslint-disable-next-line -const CLOUDINARY_REGEX = /^.+\.cloudinary\.com\/(?:[^\/]+\/)(?:(image|video|raw)\/)?(?:(upload|fetch|private|authenticated|sprite|facebook|twitter|youtube|vimeo)\/)?(?:(?:[^_/]+_[^,/]+,?)*\/)?(?:v(\d+|\w{1,2})\/)?([^\.^\s]+)(?:\.(.+))?$/ +const CLOUDINARY_REGEX = /^.+\.cloudinary\.com\/(?:[^\/]+\/)(?:(image|video|raw)\/)?(?:(upload|fetch|private|authenticated|sprite|facebook|twitter|youtube|vimeo)\/)?(?:(?:[^_/]+_[^,/]+,?)*\/)?(?:v(\d+|\w{1,2})\/)?(.+)$/ export const extractPublicId = (link: string):string => { if (!link) return '' const parts = CLOUDINARY_REGEX.exec(link) - return parts && parts.length > 2 ? parts[parts.length - 2] : link + if (!parts) { + return link + } + + // Strip extension if present + return parts[parts.length - 1].replace(/\.[^/.]+$/, "") } export const getSignature = (signature?: string) => {