Skip to content

Commit

Permalink
feat: enable custom paramter and url encoding function
Browse files Browse the repository at this point in the history
Co-authored-by: Filipe Pfluck <[email protected]>
  • Loading branch information
luqven and FilipePfluck committed Oct 31, 2022
1 parent 8dd5d5a commit 1f5649a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 13 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ The following options can be used when creating an instance of `ImgixClient`:
- **`params`:** Object. Any number of imgix rendering API [parameters](https://docs.imgix.com/apis/url).
- **`options`:** Object. Any number of modifiers, described below:
- [**`disablePathEncoding`**](#disable-path-encoding)
- [**`customEncoder`**](#custom-encoder)

Construct a single image URL by passing in the image `path` and any rendering API parameters.

Expand Down Expand Up @@ -429,6 +430,28 @@ console.log(srcset);

Normally this would output a src of `https://testing.imgix.net/file%2Bwith%2520some%2Bcrazy%3Fthings.jpg`, but since path encoding is disabled, it will output a src of `https://testing.imgix.net/file+with%20some+crazy?things.jpg`.

### Custom URL encoding

This library will encode by default using the `encodeURI()` or `encodeURIComponent()`. If you want to use another form of encoding you can pass it in the optionss.

```js
const ImgixClient = require("@imgix/js-core");
const client = new ImgixClient({
domain: 'test.imgix.com',
secureURLToken: 'xxxxxxxx',
});

client.buildURL(
"https://imgix-proxy.n8s.jp/img_nikkei-sum.jpg",
{
"txt": "test!()*"
},
{
customEncoder: (path) => encodeURI(path).replace("'", "%27")
}
)
```

### Web Proxy Sources

If you are using a [Web Proxy Source](https://docs.imgix.com/setup/creating-sources/web-proxy), all you need to do is pass the full image URL you would like to proxy to `@imgix/js-core` as the path, and include a `secureURLToken` when creating the client. `@imgix/js-core` will then encode this full URL into a format that imgix will understand, thus creating a proxy URL for you.
Expand Down
49 changes: 36 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
DEFAULT_OPTIONS,
DOMAIN_REGEX,
DPR_QUALITIES,
VERSION,
VERSION
} from './constants.js';
import { extractUrl } from './helpers';
import {
Expand All @@ -16,7 +16,7 @@ import {
validateVariableQualities,
validateVariableQuality,
validateWidths,
validateWidthTolerance,
validateWidthTolerance
} from './validators.js';

export default class ImgixClient {
Expand Down Expand Up @@ -50,9 +50,10 @@ export default class ImgixClient {
buildURL(rawPath = '', params = {}, options = {}) {
const path = this._sanitizePath(rawPath, {
encode: !options.disablePathEncoding,
customEncoder: options.customEncoder
});

let finalParams = this._buildParams(params);
let finalParams = this._buildParams(params, options);
if (!!this.settings.secureURLToken) {
finalParams = this._signParams(path, finalParams);
}
Expand Down Expand Up @@ -104,7 +105,11 @@ export default class ImgixClient {
return client.buildURL(pathname, combinedParams);
}

_buildParams(params = {}) {
_buildParams(params = {}, options = {}) {
// If a custom encoder is present, use it
// Otherwise just use the encodeURIComponent
const encode = options.customEncoder || encodeURIComponent

const queryParams = [
// Set the libraryParam if applicable.
...(this.settings.libraryParam
Expand All @@ -116,12 +121,17 @@ export default class ImgixClient {
if (value == null) {
return prev;
}
const encodedKey = encodeURIComponent(key);
const encodedKey = encode(key);
const encodedValue =
key.substr(-2) === '64'
? Base64.encodeURI(value)
: encodeURIComponent(value);
: encode(value);
prev.push(`${encodedKey}=${encodedValue}`);

if(value === "test!(')"){
console.log('#######################',encodedKey, encodedValue)
}

return prev;
}, []),
];
Expand Down Expand Up @@ -154,13 +164,17 @@ export default class ImgixClient {

if (!(options.encode === false)) {
if (/^https?:\/\//.test(_path)) {
// Use de/encodeURIComponent to ensure *all* characters are handled,
// If a custom encoder is passed, use it
// otherwise use de/encodeURIComponent to ensure *all* characters are handled,
// since it's being used as a path
_path = encodeURIComponent(_path);
const encode = options.customEncoder || encodeURIComponent
_path = encode(_path);
} else {
// Use de/encodeURI if we think the path is just a path,
// If a custom encoder is passed, use it
// Otherwise use de/encodeURI if we think the path is just a path,
// so it leaves legal characters like '/' and '@' alone
_path = encodeURI(_path).replace(/[#?:+]/g, encodeURIComponent);
const encode = options.customEncoder || encodeURI
_path = encode(_path).replace(/[#?:+]/g, encodeURIComponent);
}
}

Expand Down Expand Up @@ -286,7 +300,10 @@ export default class ImgixClient {
`${this.buildURL(
path,
{ ...params, w },
{ disablePathEncoding: options.disablePathEncoding },
{
disablePathEncoding: options.disablePathEncoding,
customEncoder: options.customEncoder
},
)} ${w}w`,
);

Expand Down Expand Up @@ -320,7 +337,10 @@ export default class ImgixClient {
dpr: dpr,
q: params.q || qualities[dpr] || qualities[Math.floor(dpr)],
},
{ disablePathEncoding: options.disablePathEncoding },
{
disablePathEncoding: options.disablePathEncoding,
customEncoder: options.customEncoder
},
)} ${dpr}x`;
};

Expand All @@ -330,7 +350,10 @@ export default class ImgixClient {
`${this.buildURL(
path,
{ ...params, dpr },
{ disablePathEncoding: options.disablePathEncoding },
{
disablePathEncoding: options.disablePathEncoding,
customEncoder: options.customEncoder
},
)} ${dpr}x`,
)
: targetRatios.map((dpr) => withQuality(path, params, dpr));
Expand Down
21 changes: 21 additions & 0 deletions test/test-buildURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,5 +354,26 @@ describe('URL Builder:', function describeSuite() {
assert(!actual.includes('txt=undefined'));
assert(!actual.includes('txt=null'));
});

it('should be able to use a custom encoder', function testSpec() {
const actual = client.buildURL(
"unsplash/walrus.jpg",
{
txt: "test!(')",
"txt-color": "000",
"txt-size": 400,
"txt-font": "Avenir-Black",
"txt-x": 800,
"txt-y": 600
},
{
customEncoder: (path) => encodeURI(path).replace("'", "%27")
}
)

const expected = 'https://test.imgix.net/unsplash/walrus.jpg?txt=test!(%27)&txt-color=000&txt-size=400&txt-font=Avenir-Black&txt-x=800&txt-y=600'

assert.strictEqual(actual, expected)
})
});
});

0 comments on commit 1f5649a

Please sign in to comment.