diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index abeae136..7263c90c 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -23,6 +23,6 @@ jobs: yarn install yarn test yarn test-e2e - yarn report-coverage + # yarn report-coverage env: CI: true diff --git a/libs/url/builder.ts b/libs/url/builder.ts index 68cb5368..87319978 100644 --- a/libs/url/builder.ts +++ b/libs/url/builder.ts @@ -1,7 +1,7 @@ /* Helper Modules */ -import url, { UrlWithStringQuery, URLSearchParams } from "url"; +import { URLSearchParams, URL } from "url"; import path from "path"; import crypto from "crypto"; @@ -38,32 +38,21 @@ export const encodeStringIfRequired = (str: string) => { } const buildURL = function (opts: FinalUrlOptions): string { - //Create correct query parameters - var parsedURL: UrlWithStringQuery; - var parsedHost: UrlWithStringQuery; var isSrcParameterUsedForURL: boolean = false; - var urlObject: { [key: string]: string | null } = { host: "", pathname: "", search: "" }; + var urlObject: URL; if (opts.path) { - parsedURL = url.parse(opts.path); - parsedHost = url.parse(opts.urlEndpoint); - - urlObject.protocol = parsedHost.protocol; - urlObject.host = opts.urlEndpoint.replace(urlObject.protocol + "//", ""); + urlObject = new URL(opts.urlEndpoint) } else if (opts.src) { - parsedURL = url.parse(opts.src); isSrcParameterUsedForURL = true; - - urlObject.host = [parsedURL.auth, parsedURL.auth ? "@" : "", parsedURL.host].join(""); - urlObject.protocol = parsedURL.protocol; + urlObject = new URL(opts.src) } else { return ""; } - urlObject.pathname = parsedURL.pathname ? parsedURL.pathname : ""; - var queryParameters = new URLSearchParams(parsedURL.query || ""); + var queryParameters = new URLSearchParams(urlObject.search || ""); for (var i in opts.queryParameters) { queryParameters.set(i, opts.queryParameters[i]); } @@ -75,13 +64,18 @@ const buildURL = function (opts: FinalUrlOptions): string { //string should be added only as a query parameter if (transformationUtils.addAsQueryParameter(opts) || isSrcParameterUsedForURL) { queryParameters.set(TRANSFORMATION_PARAMETER, transformationString); + urlObject.pathname= `${urlObject.pathname}${opts.path||''}`; } else { urlObject.pathname = path.posix.join( - [TRANSFORMATION_PARAMETER, transformationString].join(transformationUtils.getChainTransformDelimiter()), urlObject.pathname, + [TRANSFORMATION_PARAMETER, transformationString].join(transformationUtils.getChainTransformDelimiter()), + opts.path || '', ); } } + else{ + urlObject.pathname= `${urlObject.pathname}${opts.path||''}`; + } urlObject.host = urlFormatter.removeTrailingSlash(urlObject.host); urlObject.pathname = urlFormatter.addLeadingSlash(urlObject.pathname); @@ -107,7 +101,7 @@ const buildURL = function (opts: FinalUrlOptions): string { expiryTimestamp = DEFAULT_TIMESTAMP; } - var intermediateURL = url.format(urlObject); + var intermediateURL = urlObject.href; var urlSignature = getSignature({ privateKey: opts.privateKey, @@ -122,8 +116,7 @@ const buildURL = function (opts: FinalUrlOptions): string { queryParameters.set(SIGNATURE_PARAMETER, urlSignature); urlObject.search = queryParameters.toString(); } - - return url.format(urlObject); + return urlObject.href; }; function constructTransformationString(inputTransformation: Array | undefined) { diff --git a/package.json b/package.json index 38d0f722..520e35e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "imagekit", - "version": "5.2.0", + "version": "5.2.1", "description": "Offical NodeJS SDK for ImageKit.io integration", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/tests/url-generation.js b/tests/url-generation.js index 4e946a48..689e234e 100644 --- a/tests/url-generation.js +++ b/tests/url-generation.js @@ -74,7 +74,7 @@ describe("URL generation", function () { path: "/test_é_path_alt.jpg", signed: true, }); - expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/test_é_path_alt.jpg?ik-s=${signature}`); + expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/test_%C3%A9_path_alt.jpg?ik-s=${signature}`); }); it("Signed URL with é in filename and path", function () { @@ -91,7 +91,7 @@ describe("URL generation", function () { path: "/aéb/test_é_path_alt.jpg", signed: true, }); - expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/aéb/test_é_path_alt.jpg?ik-s=${signature}`); + expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/a%C3%A9b/test_%C3%A9_path_alt.jpg?ik-s=${signature}`); }); it("Signed URL with é in filename, path and transformation as path", function () { @@ -112,7 +112,7 @@ describe("URL generation", function () { transformationPosition: "path", }); expect(url).equal( - `https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekité,fs-50,l-end/aéb/test_é_path_alt.jpg?ik-s=${signature}` + `https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekit%C3%A9,fs-50,l-end/a%C3%A9b/test_%C3%A9_path_alt.jpg?ik-s=${signature}` ); }); @@ -133,7 +133,7 @@ describe("URL generation", function () { transformationPosition: "query", }); expect(url).equal( - `https://ik.imagekit.io/test_url_endpoint/aéb/test_é_path_alt.jpg?tr=l-text%2Ci-Imagekit%C3%A9%2Cfs-50%2Cl-end&ik-s=${signature}` + `https://ik.imagekit.io/test_url_endpoint/a%C3%A9b/test_%C3%A9_path_alt.jpg?tr=l-text%2Ci-Imagekit%C3%A9%2Cfs-50%2Cl-end&ik-s=${signature}` ); }); @@ -333,6 +333,76 @@ describe("URL generation", function () { expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/tr:di-test_path.jpg/test_path1.jpg`); }); + it("Signed URL with ' in filename", function () { + const testURL = "https://ik.imagekit.io/test_url_endpoint/test_'_path_alt.jpg"; + const signature = getSignature({ + privateKey: "test_private_key", + url: testURL, + urlEndpoint: "https://ik.imagekit.io/test_url_endpoint", + expiryTimestamp: "9999999999", + }); + const url = imagekit.url({ + path: "/test_'_path_alt.jpg", + signed: true, + }); + expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/test_'_path_alt.jpg?ik-s=${signature}`); + }); + + it("Signed URL with ' in filename and path", function () { + const testURL = "https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg"; + const signature = getSignature({ + privateKey: "test_private_key", + url: testURL, + urlEndpoint: "https://ik.imagekit.io/test_url_endpoint", + expiryTimestamp: "9999999999", + }); + const url = imagekit.url({ + path: "/a'b/test_'_path_alt.jpg", + signed: true, + }); + expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg?ik-s=${signature}`); + }); + + it("Signed URL with ' in filename, path and transformation as path", function () { + const testURL = "https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekit',fs-50,l-end/a'b/test_'_path_alt.jpg"; + const signature = getSignature({ + privateKey: "test_private_key", + url: testURL, + urlEndpoint: "https://ik.imagekit.io/test_url_endpoint", + expiryTimestamp: "9999999999", + }); + + const url = imagekit.url({ + path: "/a'b/test_'_path_alt.jpg", + signed: true, + transformation: [{ raw: "l-text,i-Imagekit',fs-50,l-end" }], + transformationPosition: "path", + }); + expect(url).equal( + `https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekit',fs-50,l-end/a'b/test_'_path_alt.jpg?ik-s=${signature}` + ); + }); + + it("Signed URL with ' in filename, path and transformation as query", function () { + const testURL = "https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg?tr=l-text%2Ci-Imagekit%27%2Cfs-50%2Cl-end"; + const signature = getSignature({ + privateKey: "test_private_key", + url: testURL, + urlEndpoint: "https://ik.imagekit.io/test_url_endpoint", + expiryTimestamp: "9999999999", + }); + const url = imagekit.url({ + path: "/a'b/test_'_path_alt.jpg", + signed: true, + transformation: [{ raw: "l-text,i-Imagekit',fs-50,l-end" }], + transformationPosition: "query", + }); + expect(url).equal( + `https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg?tr=l-text%2Ci-Imagekit%27%2Cfs-50%2Cl-end&ik-s=${signature}` + ); + }); + + it('All combined', function () { const url = imagekit.url({ path: "/test_path.jpg",