Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
test('image size should not more than 1MB', async t => {
const MAX_WIDTH = 1920 // HD
const MAX_SIZE = 1024 * 1024 // 1MB
const fileList = await glob('docs/assets/**/*.{jpg,png,gif}')
t.true(fileList.length > 0, 'should get image file list')
for (const file of fileList) {
const size = fs.statSync(file)['size']
if (size < 1e3) {
// File size less than 1KB, should be a Git LFS (Large File Storage) pointer
continue
}
const dim = await probeImageSize(fs.createReadStream(file))
if (dim.width > MAX_WIDTH || size > MAX_SIZE) {
t.fail(`${file} exceed the max limit: width: ${dim.width}, size: ${size}. use "./scripts/fit-image.sh " to adjust it fit.`)
}
}
})
addNewUrl = () => {
if (isVideo(this.state.newUrl)) {
this.props.onChange((this.props.value || []).concat({
url: this.state.newUrl,
isIcon: false,
}))
this.setState({
newUrl: '',
})
} else if (isImage(this.state.newUrl)) {
probe(this.state.newUrl).then((result) => {
// console.log(result) // =>
/*
{
width: xx,
height: yy,
type: 'jpg',
mime: 'image/jpeg',
wUnits: 'px',
hUnits: 'px',
url: 'http://example.com/image.jpg'
}
*/
this.props.onChange((this.props.value || []).concat({
url: this.state.newUrl,
width: result.width,
height: result.height,
async function getImageMetadata(io, iconPath) {
// Get a non-utf8 input stream by setting encoding to null.
// (only needed for the 'io/directory' module which open the file using the utf-8
// encoding by default).
let encoding = null;
if (iconPath.endsWith('.svg')) {
encoding = 'utf-8';
}
const data = await io.getFileAsStream(iconPath, { encoding });
return probeImageSize(data);
}
}) {
if (meta && meta.asset && data) {
const { asset, dimensions, square, contentTypePattern, contentTypeHuman }: Meta = meta;
// filePath could be an URL
const filePath = path.resolve(this.rootDir, data);
try {
// Assumption: All assets are images. This may change in the future.
// NOTE(nikki): The '4100' below should be enough for most file types, though we
// could probably go shorter....
// http://www.garykessler.net/library/file_sigs.html
// The metadata content for .jpgs might be located a lot farther down the file, so this
// may pose problems in the future.
// This cases on whether filePath is a remote URL or located on the machine
const probeResult = fs.existsSync(filePath)
? imageProbe.sync(await readChunk(filePath, 0, 4100))
: await imageProbe(data, { useElectronNet: false });
const { width, height, type, mime, wUnits, hUnits } = probeResult;
if (contentTypePattern && !mime.match(new RegExp(contentTypePattern))) {
this.manualValidationErrors.push(
new ValidationError({
errorCode: ErrorCodes.INVALID_CONTENT_TYPE,
fieldPath,
message: `field '${fieldPath}' should point to ${meta.contentTypeHuman} but the file at '${data}' has type ${type}`,
data,
meta,
})
);
}
if (dimensions && (dimensions.height !== height || dimensions.width != width)) {
const srcNode = async (cwd, attributes) => {
const { src, alt = '', ...attrs } = attributes
const url = normalizeUrl(normalizeSrc(src, attributes.srcset))
let size = { width: null, height: null }
if (url.startsWith('http')) {
const result = await probe(url)
size = { width: result.width, height: result.height }
} else if (url.startsWith('data:')) {
const buffer = uriToBuffer(url)
const result = probe.sync(buffer)
size = { width: result.width, height: result.height }
} else {
const fileStream = fs.createReadStream(path.join(cwd, url))
const result = await probe(fileStream)
size = { width: result.width, height: result.height }
fileStream.destroy()
}
// remove loading attribute
// https://github.com/tomoyukikashiro/html2amp/issues/80
let { loading, ..._attrs } = attrs
_attrs = { src: url, alt, width: size.width, height: size.height, layout: 'responsive', ..._attrs }
const _attrsStr = Object.keys(_attrs).map(key => `${key}="${_attrs[key]}"`).join(' ')
return ``
}
meta: Meta,
}) {
if (meta && meta.asset && data) {
const { asset, dimensions, square, contentTypePattern, contentTypeHuman }: Meta = meta;
// filePath could be an URL
const filePath = path.resolve(this.rootDir, data);
try {
// Assumption: All assets are images. This may change in the future.
// NOTE(nikki): The '4100' below should be enough for most file types, though we
// could probably go shorter....
// http://www.garykessler.net/library/file_sigs.html
// The metadata content for .jpgs might be located a lot farther down the file, so this
// may pose problems in the future.
// This cases on whether filePath is a remote URL or located on the machine
const probeResult = fs.existsSync(filePath)
? imageProbe.sync(await readChunk(filePath, 0, 4100))
: await imageProbe(data, { useElectronNet: false });
const { width, height, type, mime, wUnits, hUnits } = probeResult;
if (contentTypePattern && !mime.match(new RegExp(contentTypePattern))) {
this.manualValidationErrors.push(
new ValidationError({
errorCode: ErrorCodes.INVALID_CONTENT_TYPE,
fieldPath,
message: `field '${fieldPath}' should point to ${meta.contentTypeHuman} but the file at '${data}' has type ${type}`,
data,
meta,
})
);
}
async _validateImageAsync({ fieldPath, data, meta }: AssetField) {
if (meta && meta.asset && data) {
const { dimensions, square, contentTypePattern }: Meta = meta;
// filePath could be an URL
const filePath = path.resolve(this.rootDir, data);
try {
// NOTE(nikki): The '4100' below should be enough for most file types, though we
// could probably go shorter....
// http://www.garykessler.net/library/file_sigs.html
// The metadata content for .jpgs might be located a lot farther down the file, so this
// may pose problems in the future.
// This cases on whether filePath is a remote URL or located on the machine
const probeResult = fs.existsSync(filePath)
? imageProbe.sync(await readChunk(filePath, 0, 4100))
: await imageProbe(data, { useElectronNet: false });
if (!probeResult) {
return;
}
const { width, height, type, mime } = probeResult;
if (contentTypePattern && !mime.match(new RegExp(contentTypePattern))) {
this.manualValidationErrors.push(
new ValidationError({
errorCode: 'INVALID_CONTENT_TYPE',
fieldPath,
message: `field '${fieldPath}' should point to ${meta.contentTypeHuman} but the file at '${data}' has type ${type}`,
data,
meta,
})
const defaultBlur = this.config.images.defaultBlur
if (!imageExtensions.includes(ext)) {
throw new Error(
`${ext} is not a supported image format. ` +
`Supported extensions are ${imageExtensions.join(', ')}.`
)
}
if (!await fs.exists(filePath)) {
throw new Error(`${filePath} was not found.`)
}
const hash = await md5File(filePath)
const buffer = await fs.readFile(filePath)
const originalSize = imageSize.sync(buffer) || { width: 1, height: 1 }
const { imageWidth, imageHeight } = computeScaledImageSize(originalSize, options, maxImageWidth)
let imageWidths = options.imageWidths || [480, 1024, 1920, 2560]
if (typeof imageWidths === 'string') {
imageWidths = imageWidths.split(',')
}
let imageSizes = imageWidths.filter(size => size <= imageWidth)
const maxWidth = Math.max(...imageSizes, 0)
if (!options.imageWidths) {
if (imageWidth > maxWidth || imageSizes.length === 0) {
imageSizes.push(imageWidth)
}
async function getImageSize(fileName) {
const input = createReadStream(fileName);
try {
const { width, height } = await probe(input);
return { width, height };
} finally {
input.destroy();
}
}
return getSources(rawSource).map(async src => {
if (src.includes('//')) {
const rawSrc = src;
if (!src.includes('http')) {
src = 'http:' + src;
}
let dimensions;
try {
dimensions = await probe(src);
} catch (error) {
printError(`Couldn't resolve image: ${src}`);
printError(error);
dimensions = {};
}
return new Promise(resolve => {
resolve(
`'${rawSrc}': () => Promise.resolve({
default: {
src: { src: '${src}' },
preSrc: '${src}',
height: ${dimensions.height},
width: ${dimensions.width}
}