gatsby-source-sanity
Version:
Gatsby source plugin for building websites using Sanity.io as a backend.
222 lines • 9.29 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var parseUrl = require("url-parse");
exports.LOWEST_FLUID_BREAKPOINT_WIDTH = 100;
exports.DEFAULT_FIXED_WIDTH = 400;
exports.DEFAULT_FLUID_MAX_WIDTH = 800;
var ImageFormat;
(function (ImageFormat) {
ImageFormat["NO_CHANGE"] = "";
ImageFormat["WEBP"] = "webp";
ImageFormat["JPG"] = "jpg";
ImageFormat["PNG"] = "png";
})(ImageFormat || (ImageFormat = {}));
var idPattern = /^image-[A-Za-z0-9]+-\d+x\d+-[a-z]+$/;
var sizeMultipliersFixed = [1, 1.5, 2, 3];
var sizeMultipliersFluid = [0.25, 0.5, 1, 1.5, 2, 3];
function buildImageUrl(loc, stub) {
var projectId = loc.projectId, dataset = loc.dataset;
var assetId = stub.assetId, extension = stub.extension, metadata = stub.metadata;
var _a = metadata.dimensions, width = _a.width, height = _a.height;
var base = 'https://cdn.sanity.io/images';
return base + "/" + projectId + "/" + dataset + "/" + assetId + "-" + width + "x" + height + "." + extension;
}
function getBasicImageProps(node, loc) {
if (!node) {
return false;
}
var obj = node;
var ref = node;
var img = node;
var id = '';
if (typeof node === 'string') {
id = node;
}
else if (obj.asset) {
id = obj.asset._ref || obj.asset._id;
}
else {
id = ref._ref || img._id;
}
var hasId = !id || idPattern.test(id);
if (!hasId) {
return false;
}
var _a = id.split('-'), assetId = _a[1], dimensions = _a[2], extension = _a[3];
var _b = dimensions.split('x').map(function (num) { return parseInt(num, 10); }), width = _b[0], height = _b[1];
var aspectRatio = width / height;
var metadata = img.metadata || { dimensions: { width: width, height: height, aspectRatio: aspectRatio } };
var url = img.url || buildImageUrl(loc, { url: '', assetId: assetId, extension: extension, metadata: metadata });
return {
url: url,
assetId: assetId,
extension: extension,
metadata: metadata,
};
}
function convertToFormat(url, toFormat) {
var parsed = parseUrl(url, true);
var filename = parsed.pathname.replace(/.*\//, '');
var extension = filename.replace(/.*\./, '');
var isConvertedToTarget = parsed.query.fm === toFormat;
var isOriginal = extension === toFormat;
// If the original matches the target format, remove any explicit conversions
if (isConvertedToTarget && isOriginal) {
var _a = parsed.query, fm = _a.fm, params = __rest(_a, ["fm"]);
parsed.set('query', params);
return parsed.toString();
}
if (isConvertedToTarget || isOriginal) {
return url;
}
var newQuery = __assign(__assign({}, parsed.query), { fm: toFormat });
parsed.set('query', newQuery);
return parsed.toString();
}
function isWebP(url) {
var isConverted = url.includes('fm=webp');
var isOriginal = /[a-f0-9]+-\d+x\d+\.webp/.test(url);
return isConverted || isOriginal;
}
function getFixedGatsbyImage(image, args, loc) {
var props = getBasicImageProps(image, loc);
if (!props) {
return null;
}
var width = args.width || exports.DEFAULT_FIXED_WIDTH;
var height = args.height;
var url = props.url, metadata = props.metadata, extension = props.extension;
var dimensions = metadata.dimensions, lqip = metadata.lqip;
var isOriginalSize = function (w, h) { return w === dimensions.width && h === dimensions.height; };
var desiredAspectRatio = dimensions.aspectRatio;
// If we're cropping, calculate the specified aspect ratio
if (args.height) {
desiredAspectRatio = width / args.height;
}
var forceConvert = null;
if (args.toFormat) {
forceConvert = args.toFormat;
}
else if (isWebP(props.url)) {
forceConvert = 'jpg';
}
var hasOriginalRatio = desiredAspectRatio === dimensions.aspectRatio;
var outputHeight = Math.round(height ? height : width / desiredAspectRatio);
var imgUrl = isOriginalSize(width, outputHeight) ||
(hasOriginalRatio && width > dimensions.width && outputHeight > dimensions.height)
? url
: url + "?w=" + width + "&h=" + outputHeight + "&fit=crop";
var widths = sizeMultipliersFixed.map(function (scale) { return Math.round(width * scale); });
var initial = { webp: [], base: [] };
var srcSets = widths
.filter(function (currentWidth) { return currentWidth <= dimensions.width; })
.reduce(function (acc, currentWidth, i) {
var resolution = sizeMultipliersFixed[i] + "x";
var currentHeight = Math.round(currentWidth / desiredAspectRatio);
var imgUrl = isOriginalSize(currentWidth, currentHeight)
? url
: url + "?w=" + currentWidth + "&h=" + currentHeight + "&fit=crop";
var webpUrl = convertToFormat(imgUrl, 'webp');
var baseUrl = convertToFormat(imgUrl, forceConvert || props.extension);
acc.webp.push(webpUrl + " " + resolution);
acc.base.push(baseUrl + " " + resolution);
return acc;
}, initial);
var src = convertToFormat(imgUrl, forceConvert || extension);
var srcWebp = convertToFormat(imgUrl, 'webp');
return {
base64: lqip || null,
aspectRatio: desiredAspectRatio,
width: Math.round(width),
height: outputHeight,
src: src,
srcWebp: srcWebp,
srcSet: srcSets.base.join(',\n') || src + " 1x",
srcSetWebp: srcSets.webp.join(',\n') || srcWebp + " 1x",
};
}
exports.getFixedGatsbyImage = getFixedGatsbyImage;
function getFluidGatsbyImage(image, args, loc) {
var props = getBasicImageProps(image, loc);
if (!props) {
return null;
}
var url = props.url, metadata = props.metadata, extension = props.extension;
var dimensions = metadata.dimensions, lqip = metadata.lqip;
var isOriginalSize = function (w, h) { return w === dimensions.width && h === dimensions.height; };
var maxWidth = Math.min(args.maxWidth || exports.DEFAULT_FLUID_MAX_WIDTH, dimensions.width);
var specifiedMaxHeight = args.maxHeight
? Math.min(args.maxHeight, dimensions.height)
: undefined;
var desiredAspectRatio = dimensions.aspectRatio;
// If we're cropping, calculate the specified aspect ratio
if (specifiedMaxHeight) {
desiredAspectRatio = maxWidth / specifiedMaxHeight;
}
var maxHeight = specifiedMaxHeight || Math.round(maxWidth / dimensions.aspectRatio);
var forceConvert = null;
if (args.toFormat) {
forceConvert = args.toFormat;
}
else if (isWebP(props.url)) {
forceConvert = 'jpg';
}
var baseSrc = isOriginalSize(maxWidth, maxHeight) ||
(maxWidth >= dimensions.width && maxHeight >= dimensions.height)
? url
: url + "?w=" + maxWidth + "&h=" + maxHeight + "&fit=crop";
var src = convertToFormat(baseSrc, forceConvert || extension);
var srcWebp = convertToFormat(baseSrc, 'webp');
var sizes = args.sizes || "(max-width: " + maxWidth + "px) 100vw, " + maxWidth + "px";
var widths = sizeMultipliersFluid
.map(function (scale) { return Math.round(maxWidth * scale); })
.filter(function (width) { return width < dimensions.width && width > exports.LOWEST_FLUID_BREAKPOINT_WIDTH; })
.concat(dimensions.width);
var initial = { webp: [], base: [] };
var srcSets = widths
.filter(function (currentWidth) { return currentWidth <= dimensions.width; })
.reduce(function (acc, currentWidth) {
var currentHeight = Math.round(currentWidth / desiredAspectRatio);
var imgUrl = isOriginalSize(currentWidth, currentHeight)
? url
: url + "?w=" + currentWidth + "&h=" + currentHeight + "&fit=crop";
var webpUrl = convertToFormat(imgUrl, 'webp');
var baseUrl = convertToFormat(imgUrl, forceConvert || props.extension);
acc.webp.push(webpUrl + " " + currentWidth + "w");
acc.base.push(baseUrl + " " + currentWidth + "w");
return acc;
}, initial);
return {
base64: lqip || null,
aspectRatio: desiredAspectRatio,
src: src,
srcWebp: srcWebp,
srcSet: srcSets.base.join(',\n'),
srcSetWebp: srcSets.webp.join(',\n'),
sizes: sizes,
};
}
exports.getFluidGatsbyImage = getFluidGatsbyImage;
//# sourceMappingURL=getGatsbyImageProps.js.map