Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: esm rewrite #188

Merged
merged 64 commits into from
Jan 14, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
7e98689
feat: rewrite ix-core-js as esm
ericdeansanchez Nov 18, 2020
bb4b36d
feat: pull constants into separate file
ericdeansanchez Nov 18, 2020
a113fea
feat: pull validation into separate module
ericdeansanchez Nov 18, 2020
f62e8db
feat: add rollup config
ericdeansanchez Nov 18, 2020
c8491e0
feat: update package.json
ericdeansanchez Nov 18, 2020
3809a93
feat: add minimal babelrc
ericdeansanchez Nov 18, 2020
1be0281
feat: remove renovate (for now)
ericdeansanchez Nov 18, 2020
5e5d5da
feat: update buildSrcSet test suite
ericdeansanchez Nov 18, 2020
585bb19
feat: update buildURL test suite
ericdeansanchez Nov 18, 2020
e238dc4
feat: update client test suite
ericdeansanchez Nov 18, 2020
91cc39c
feat: add validation tests
ericdeansanchez Nov 18, 2020
d9afcdb
feat: reintro renovate
ericdeansanchez Dec 2, 2020
65c6f3e
fix: update minor or patch prior to release
ericdeansanchez Dec 3, 2020
9d3bb9e
feat: add src, README to files list
ericdeansanchez Dec 3, 2020
6533f68
refactor: use more descriptive DEFAULT_OPTIONS varname
ericdeansanchez Dec 3, 2020
4c2a31d
feat: use const where possible/appropriate
ericdeansanchez Dec 3, 2020
be3ee98
feat: use const in validators
ericdeansanchez Dec 3, 2020
b1a1925
build: update dist
ericdeansanchez Dec 8, 2020
879e235
feat: update @babel/preset-env
ericdeansanchez Dec 8, 2020
a41ef47
feat: use crypto-js
ericdeansanchez Dec 8, 2020
1d8d4a5
feat: test on node version 14
ericdeansanchez Dec 8, 2020
c488e43
feat: require @babel/register
ericdeansanchez Dec 8, 2020
d5c519c
feat: run mocha with babel/register
ericdeansanchez Dec 8, 2020
1266c1a
feat: add babel core for mocha
ericdeansanchez Dec 8, 2020
4c9735d
feat: use --experimental-modules
ericdeansanchez Dec 8, 2020
9b34c53
ci: run against node v12.11
ericdeansanchez Dec 8, 2020
7a5c1e0
feat: remove old interface
ericdeansanchez Dec 9, 2020
9b031f4
ci: test cjs version of test-buildSrcSet
ericdeansanchez Dec 9, 2020
87b967c
ci: transpile tests to cjs
ericdeansanchez Dec 9, 2020
5e254c1
ci: return to original md5 vendor
ericdeansanchez Dec 9, 2020
5d716fc
ci: separate cjs and js tests
ericdeansanchez Dec 9, 2020
d1638bb
ci: remove node_js version 8
ericdeansanchez Dec 9, 2020
cf49986
feat: generalize test-suite transpilation
ericdeansanchez Dec 10, 2020
197e3be
refactor: destructure options into widthTolerance, min/max width
ericdeansanchez Dec 10, 2020
6142e75
feat: use object spread operator
ericdeansanchez Dec 10, 2020
2b1821c
test: dedupe validateWidths test cases
ericdeansanchez Dec 10, 2020
0748d01
refactor: use spread operator and destructure syntax
ericdeansanchez Dec 17, 2020
8e0eb40
refactor: use/reuse finalParams for single return
ericdeansanchez Dec 17, 2020
64e0348
refactor: use functional constructs to build params
ericdeansanchez Dec 17, 2020
ef0d0a9
refactor: remove redundant assignment/copying
ericdeansanchez Dec 17, 2020
238eba8
refactor: use functional constructs to generate srcset array
ericdeansanchez Dec 17, 2020
ef4c5dc
refactor: functionally build dpr srcsets
ericdeansanchez Dec 17, 2020
258c6a9
refactor: remove file extensions from imports
ericdeansanchez Dec 17, 2020
fbcda9a
refactor: remove file extensions from test file imports
ericdeansanchez Dec 17, 2020
aa39bdf
refactor: remove redundant assignment
ericdeansanchez Dec 17, 2020
843f902
refactor: avoid temp variable, spread instead
ericdeansanchez Dec 17, 2020
f949c01
refactor: fix typo
ericdeansanchez Dec 17, 2020
23a09b9
refactor: remove irrelevant assert
ericdeansanchez Dec 18, 2020
30ba159
refactor: prefer let over var
ericdeansanchez Dec 18, 2020
1a1222a
refactor: reorder args and test only for expectations
ericdeansanchez Dec 18, 2020
6f1a594
refactor(test-client): const remaining lets
ericdeansanchez Dec 18, 2020
9bd7c2b
ci: prefer lts and node (stable) over individual versions
ericdeansanchez Jan 8, 2021
70d15cf
test: don't use double negatives
ericdeansanchez Jan 8, 2021
04c22d7
test: strengthen pharsing of descriptions
ericdeansanchez Jan 8, 2021
3d2e12f
test: throws if widthTolerance is < 0
ericdeansanchez Jan 8, 2021
5b0056d
test: remove typeof wording
ericdeansanchez Jan 8, 2021
680ac2c
test: prefer strictEquals
ericdeansanchez Jan 9, 2021
c6d1791
test: use const and consolidate map calls
ericdeansanchez Jan 12, 2021
4dc59c8
test: use map instead of for-loop
ericdeansanchez Jan 12, 2021
6a20e8e
chore: fix merge conflicts
ericdeansanchez Jan 12, 2021
3d3f5be
build: carry old build steps to new, add prettier, uglify with rollup
ericdeansanchez Jan 13, 2021
b00b00e
build: include rollup-plugin-uglify
ericdeansanchez Jan 13, 2021
1022a36
build: omit assert_version script for now
ericdeansanchez Jan 13, 2021
e5a67e7
docs: clarify description
ericdeansanchez Jan 14, 2021
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
10 changes: 10 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"presets": [
["@babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
},
"modules": false
}]
]
}
329 changes: 329 additions & 0 deletions dist/imgix-core-js.cjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var md5 = _interopDefault(require('md5'));
var jsBase64 = require('js-base64');

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}

function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}

// package version used in the ix-lib parameter
var VERSION = '2.3.2'; // regex pattern used to determine if a domain is valid

var DOMAIN_REGEX = /^(?:[a-z\d\-_]{1,62}\.){0,125}(?:[a-z\d](?:\-(?=\-*[a-z\d])|[a-z]|\d){0,62}\.)[a-z\d]{1,63}$/i; // minimum generated srcset width

var MIN_SRCSET_WIDTH = 100; // maximum generated srcset width

var MAX_SRCSET_WIDTH = 8192; // default tolerable percent difference between srcset pair widths

var DEFAULT_SRCSET_WIDTH_TOLERANCE = .08; // default quality parameter values mapped by each dpr srcset entry

var DPR_QUALITIES = {
1: 75,
2: 50,
3: 35,
4: 23,
5: 20
};
var DEFAULTS = {
domain: null,
useHTTPS: true,
includeLibraryParam: true,
urlPrefix: 'https://',
secureURLToken: null
};

function validateAndDestructureOptions(options) {
if (options.widthTolerance !== undefined) {
validateWidthTolerance(options.widthTolerance);
var widthTolerance = options.widthTolerance;
} else {
var widthTolerance = DEFAULT_SRCSET_WIDTH_TOLERANCE;
}

var minWidth = options.minWidth === undefined ? MIN_SRCSET_WIDTH : options.minWidth;
var maxWidth = options.maxWidth === undefined ? MAX_SRCSET_WIDTH : options.maxWidth; // Validate the range unless we're using defaults for both

if (minWidth != MIN_SRCSET_WIDTH || maxWidth != MAX_SRCSET_WIDTH) {
validateRange(minWidth, maxWidth);
}

return [widthTolerance, minWidth, maxWidth];
}
function validateRange(min, max) {
if (!(Number.isInteger(min) && Number.isInteger(max)) || min <= 0 || max <= 0 || min > max) {
throw new Error('The min and max srcset widths can only be passed positive Number values');
}
}
function validateWidthTolerance(widthTolerance) {
if (typeof widthTolerance != 'number' || widthTolerance <= 0) {
throw new Error('The srcset widthTolerance argument can only be passed a positive scalar number');
}
}
function validateWidths(customWidths) {
if (!Array.isArray(customWidths) || !customWidths.length) {
throw new Error('The widths argument can only be passed a valid non-empty array of integers');
} else {
var allPositiveIntegers = customWidths.every(function (width) {
return Number.isInteger(width) && width > 0;
});

if (!allPositiveIntegers) {
throw new Error('A custom widths argument can only contain positive integer values');
}
}
}
function validateVariableQuality(disableVariableQuality) {
if (typeof disableVariableQuality != 'boolean') {
throw new Error('The disableVariableQuality argument can only be passed a Boolean value');
}
}

var ImgixClient = /*#__PURE__*/function () {
function ImgixClient() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

_classCallCheck(this, ImgixClient);

var settings = Object.assign({}, DEFAULTS);
this.settings = Object.assign(settings, opts); // a cache to store memoized srcset width-pairs

this.targetWidthsCache = {};

if (typeof this.settings.domain != "string") {
throw new Error('ImgixClient must be passed a valid string domain');
}

if (DOMAIN_REGEX.exec(this.settings.domain) == null) {
throw new Error('Domain must be passed in as fully-qualified ' + 'domain name and should not include a protocol or any path ' + 'element, i.e. "example.imgix.net".');
}

if (this.settings.includeLibraryParam) {
this.settings.libraryParam = "js-" + VERSION;
}

this.settings.urlPrefix = this.settings.useHTTPS ? 'https://' : 'http://';
}

_createClass(ImgixClient, [{
key: "buildURL",
value: function buildURL() {
var path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

var sanitizedPath = this._sanitizePath(path);

var queryParams = this._buildParams(params);

if (!!this.settings.secureURLToken) {
var securedParams = this._signParams(sanitizedPath, queryParams);

return this.settings.urlPrefix + this.settings.domain + sanitizedPath + securedParams;
}

return this.settings.urlPrefix + this.settings.domain + sanitizedPath + queryParams;
}
}, {
key: "_buildParams",
value: function _buildParams() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var queryParams = [];

if (this.settings.libraryParam) {
queryParams.push('ixlib=' + this.settings.libraryParam);
}

var key, val, encodedKey, encodedVal;

for (key in params) {
val = params[key];
encodedKey = encodeURIComponent(key);

if (key.substr(-2) === '64') {
encodedVal = jsBase64.Base64.encodeURI(val);
} else {
encodedVal = encodeURIComponent(val);
}

queryParams.push(encodedKey + "=" + encodedVal);
}

if (queryParams[0]) {
queryParams[0] = "?" + queryParams[0];
}

return queryParams.join('&');
}
}, {
key: "_signParams",
value: function _signParams(path, queryParams) {
var signatureBase = this.settings.secureURLToken + path + queryParams;
var signature = md5(signatureBase);

if (queryParams.length > 0) {
return queryParams = queryParams + "&s=" + signature;
} else {
return queryParams = "?s=" + signature;
}
}
}, {
key: "_sanitizePath",
value: function _sanitizePath(path) {
// Strip leading slash first (we'll re-add after encoding)
var _path = path.replace(/^\//, '');

if (/^https?:\/\//.test(_path)) {
// Use de/encodeURIComponent to ensure *all* characters are handled,
// since it's being used as a path
_path = encodeURIComponent(_path);
} else {
// 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);
}

return '/' + _path;
}
}, {
key: "buildSrcSet",
value: function buildSrcSet(path, params, options) {
var _options = options || {};

var _params = params || {};

var width = _params.w;
var height = _params.h;
var aspectRatio = _params.ar;

if (width || height && aspectRatio) {
return this._buildDPRSrcSet(path, _params, _options);
} else {
return this._buildSrcSetPairs(path, _params, _options);
}
}
}, {
key: "_buildSrcSetPairs",
value: function _buildSrcSetPairs(path, params, options) {
var srcsetOptions = validateAndDestructureOptions(options);
var srcset = [];
var currentWidth;
var targetWidths;
var customWidths = options.widths;
var widthTolerance = srcsetOptions[0],
minWidth = srcsetOptions[1],
maxWidth = srcsetOptions[2];

if (customWidths) {
validateWidths(customWidths);
targetWidths = customWidths;
} else {
validateRange(minWidth, maxWidth);
validateWidthTolerance(widthTolerance);
targetWidths = this._generateTargetWidths(widthTolerance, minWidth, maxWidth);
}

var key;
var queryParams = {};

for (key in params) {
queryParams[key] = params[key];
}

for (var i = 0; i < targetWidths.length; i++) {
currentWidth = targetWidths[i];
queryParams.w = currentWidth;
srcset.push(this.buildURL(path, queryParams) + ' ' + currentWidth + 'w');
}

return srcset.join(',\n');
}
}, {
key: "_buildDPRSrcSet",
value: function _buildDPRSrcSet(path, params, options) {
var srcset = [];
var targetRatios = [1, 2, 3, 4, 5];
var disableVariableQuality = options.disableVariableQuality || false;
var key;
var queryParams = {};

for (key in params) {
queryParams[key] = params[key];
}

var quality = queryParams.q;

if (!disableVariableQuality) {
validateVariableQuality(disableVariableQuality);
}

for (var i = 0; i < targetRatios.length; i++) {
var currentRatio = targetRatios[i];
queryParams.dpr = currentRatio;

if (!disableVariableQuality) {
queryParams.q = quality || DPR_QUALITIES[currentRatio];
}

srcset.push(this.buildURL(path, queryParams) + ' ' + currentRatio + 'x');
}

return srcset.join(',\n');
}
}, {
key: "_generateTargetWidths",
// returns an array of width values used during scrset generation
value: function _generateTargetWidths(widthTolerance, minWidth, maxWidth) {
var resolutions = [];
var INCREMENT_PERCENTAGE = widthTolerance;

var _minWidth = Math.floor(minWidth);

var _maxWidth = Math.floor(maxWidth);

var cacheKey = INCREMENT_PERCENTAGE + '/' + _minWidth + '/' + _maxWidth;

if (cacheKey in this.targetWidthsCache) {
return this.targetWidthsCache[cacheKey];
}

var ensureEven = function ensureEven(n) {
return 2 * Math.round(n / 2);
};

var prev = _minWidth;

while (prev < _maxWidth) {
resolutions.push(ensureEven(prev));
prev *= 1 + INCREMENT_PERCENTAGE * 2;
}

resolutions.push(_maxWidth);
this.targetWidthsCache[cacheKey] = resolutions;
return resolutions;
}
}]);

return ImgixClient;
}();

module.exports = ImgixClient;
29 changes: 0 additions & 29 deletions dist/imgix-core-js.d.ts

This file was deleted.

Loading