gatsby-source-sanity
Version:
Gatsby source plugin for building websites using Sanity.io as a backend.
171 lines • 5.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const graphql_1 = require("gatsby/graphql");
var ImageFormat;
(function (ImageFormat) {
ImageFormat["NO_CHANGE"] = "";
ImageFormat["WEBP"] = "webp";
ImageFormat["JPG"] = "jpg";
ImageFormat["PNG"] = "png";
})(ImageFormat || (ImageFormat = {}));
const ImageFormatType = new graphql_1.GraphQLEnumType({
name: 'SanityImageFormat',
values: {
NO_CHANGE: { value: '' },
JPG: { value: 'jpg' },
PNG: { value: 'png' },
WEBP: { value: 'webp' }
}
});
const idPattern = /^image-[A-Za-z0-9]+-\d+x\d+-[a-z]+$/;
const sizeMultipliersFixed = [1, 1.5, 2, 3];
const sizeMultipliersFluid = [0.25, 0.5, 1, 1.5, 2, 3];
function extendImageNode(context, config) {
return extension;
}
exports.extendImageNode = extendImageNode;
function isValidImage(img) {
const hasId = img && typeof img._id === 'string' && idPattern.test(img._id);
if (!hasId) {
return false;
}
return img && img.metadata && img.metadata.dimensions.width;
}
function resolveFixed(image, args) {
if (image === null || !isValidImage(image)) {
return null;
}
const width = args.width || 400;
const height = args.height;
const { dimensions, lqip } = image.metadata;
const widths = sizeMultipliersFixed.map(scale => Math.round(width * scale));
const format = args.toFormat ? `&fm=${args.toFormat}` : '';
const srcSet = widths
.filter(currentWidth => currentWidth < dimensions.width)
.map((currentWidth, i) => {
const resolution = `${sizeMultipliersFixed[i]}x`;
const currentHeight = Math.round(currentWidth / dimensions.aspectRatio);
const url = `${image.url}?w=${currentWidth}&h=${currentHeight}&fit=crop${format}`;
return `${url} ${resolution}`;
})
.join(`,\n`);
return {
base64: lqip,
aspectRatio: dimensions.aspectRatio,
width: Math.round(width),
height: Math.round(height ? height : width / dimensions.aspectRatio),
src: `${image.url}?w=${width}${format}`,
srcSet
};
}
function resolveFluid(image, options) {
if (!isValidImage(image)) {
return null;
}
if (image === null || !isValidImage(image)) {
return null;
}
const { dimensions, lqip } = image.metadata;
const maxWidth = options.maxWidth
? options.maxWidth
: (options.maxHeight || 1) * dimensions.aspectRatio;
const maxHeight = Math.round(maxWidth / dimensions.aspectRatio);
const sizes = options.sizes || `(max-width: ${maxWidth}px) 100vw, ${maxWidth}px`;
const widths = sizeMultipliersFluid
.map(scale => Math.round(maxWidth * scale))
.filter(width => width < dimensions.width)
.concat(dimensions.width);
const format = options.toFormat ? `&fm=${options.toFormat}` : '';
const srcSet = widths
.map(currentWidth => {
const currentHeight = Math.round(currentWidth / dimensions.aspectRatio);
const url = `${image.url}?w=${currentWidth}&h=${currentHeight}&fit=crop${format}`;
return `${url} ${currentWidth}w`;
})
.join(`,\n`);
const src = `${image.url}?w=${maxWidth}&h=${maxHeight}${format}`;
return {
base64: lqip,
aspectRatio: dimensions.aspectRatio,
src,
srcSet,
sizes
};
}
function resolveWebp(image) {
if (image.src.includes('fm=webp')) {
return null;
}
return `${image.src}&fm=webp`;
}
function resolveWebpSrcSet(image) {
if (image.src.includes('fm=webp')) {
return null;
}
return image.srcSet.replace(/(\/[a-f0-9]+-\d+x\d+\.[a-z]+\?)/g, '$1fm=webp&');
}
const fixed = {
type: new graphql_1.GraphQLObjectType({
name: 'SanityImageFixed',
fields: {
base64: { type: graphql_1.GraphQLString },
aspectRatio: { type: graphql_1.GraphQLFloat },
width: { type: graphql_1.GraphQLFloat },
height: { type: graphql_1.GraphQLFloat },
src: { type: graphql_1.GraphQLString },
srcSet: { type: graphql_1.GraphQLString },
srcWebp: { type: graphql_1.GraphQLString, resolve: resolveWebp },
srcSetWebp: { type: graphql_1.GraphQLString, resolve: resolveWebpSrcSet }
}
}),
args: {
width: {
type: graphql_1.GraphQLInt,
defaultValue: 400
},
height: {
type: graphql_1.GraphQLInt
},
toFormat: {
type: ImageFormatType,
defaultValue: ''
}
},
resolve: resolveFixed
};
const fluid = {
type: new graphql_1.GraphQLObjectType({
name: 'SanityImageFluid',
fields: {
base64: { type: graphql_1.GraphQLString },
aspectRatio: { type: graphql_1.GraphQLFloat },
src: { type: graphql_1.GraphQLString },
srcSet: { type: graphql_1.GraphQLString },
srcWebp: { type: graphql_1.GraphQLString, resolve: resolveWebp },
srcSetWebp: { type: graphql_1.GraphQLString, resolve: resolveWebpSrcSet },
sizes: { type: graphql_1.GraphQLString }
}
}),
args: {
maxWidth: {
type: graphql_1.GraphQLInt,
defaultValue: 800
},
maxHeight: {
type: graphql_1.GraphQLInt
},
sizes: {
type: graphql_1.GraphQLString
},
toFormat: {
type: ImageFormatType,
defaultValue: ''
}
},
resolve: resolveFluid
};
const extension = {
fixed,
fluid
};
//# sourceMappingURL=extendImageNode.js.map