Skip to content

Commit

Permalink
switch to esm, node:test, xo
Browse files Browse the repository at this point in the history
  • Loading branch information
kotarac committed Jan 12, 2024
1 parent eb09763 commit 59de3d3
Show file tree
Hide file tree
Showing 6 changed files with 3,605 additions and 1,143 deletions.
17 changes: 0 additions & 17 deletions .eslintrc

This file was deleted.

9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Intended for usage behind a proxy cache (e.g. nginx, varnish) or a CDN (e.g. Clo
## Install

```sh
npm i -S slicica
npm add slicica
```

Installing this module will automatically fetch and build libvips and its dependencies on Linux, MacOS and Windows x64.
Expand All @@ -20,12 +20,15 @@ For more information read [sharp's documentation](https://sharp.pixelplumbing.co
## Usage

```js
app.use(require('slicica')(options))
import slicica from 'slicica'
app.use(slicica(options))
```

```js
import express from 'express'
import slicica from 'slicica'

const app = express()
const slicica = require('slicica')

app.use(slicica(
// default options below
Expand Down
131 changes: 66 additions & 65 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
const etag = require('etag')
const fs = require('fs')
const fresh = require('fresh')
const mime = require('mime')
const ms = require('ms')
const sharp = require('sharp')

const imageTypes = [
'image/jpeg',
'image/png',
'image/webp',
'image/tiff',
]

function setHeaders (res, headers) {
import fs from 'node:fs'
import etag from 'etag'
import fresh from 'fresh'
import mime from 'mime'
import ms from 'ms'
import sharp from 'sharp'

const imageTypes = new Set(['image/jpeg', 'image/png', 'image/webp', 'image/tiff'])

function setHeaders(res, headers) {
for (const k of Object.keys(headers)) {
res.setHeader(k, headers[k])
}
}

module.exports = function (opts) {
opts = Object.assign({}, {
export default function slicica(options) {
options = {
prefix: '/',
root: '',
maxAge: 0,
Expand All @@ -30,81 +25,83 @@ module.exports = function (opts) {
lastModified: true,
cache: false,
concurrency: 0,
contentTypes: [
'image/jpeg',
'image/png',
'image/webp',
'image/tiff',
],
}, opts)
if (opts.prefix[0] !== '/') {
opts.prefix = `/${opts.prefix}`
contentTypes: ['image/jpeg', 'image/png', 'image/webp', 'image/tiff'],
...options,
}
if (typeof opts.magxAge === 'string') {
opts.maxAge = ms(opts.maxAge) / 1000
if (options.prefix[0] !== '/') {
options.prefix = `/${options.prefix}`
}

if (typeof options.magxAge === 'string') {
options.maxAge = ms(options.maxAge) / 1000
}

sharp.cache(opts.cache)
sharp.concurrency(opts.concurrency)
sharp.cache(options.cache)
sharp.concurrency(options.concurrency)

return function (req, res, next) {
const method = req.method.toUpperCase()
return function (request, res, next) {
const method = request.method.toUpperCase()

if (!['GET', 'HEAD'].includes(method)) {
next()
return
}
if (!req.path.startsWith(opts.prefix)) {

if (!request.path.startsWith(options.prefix)) {
next()
return
}

const { g, max } = req.query
const w = parseInt(req.query.w, 10) || null
const h = parseInt(req.query.h, 10) || null
const path = decodeURI(`${opts.root}${req.path.slice(opts.prefix.length)}`)
const {g, max} = request.query
const w = Number.parseInt(request.query.w, 10) || null
const h = Number.parseInt(request.query.h, 10) || null
const path = decodeURI(`${options.root}${request.path.slice(options.prefix.length)}`)
const type = mime.getType(path)
if (!opts.contentTypes.includes(type)) {
if (!options.contentTypes.includes(type)) {
next()
return
}

req.route = {
path: `${opts.prefix}/:slicica`,
request.route = {
path: `${options.prefix}/:slicica`,
methods: {
[`${method.toLowerCase()}`]: true,
},
}

fs.stat(path, function (err, stats) {
if (err) {
fs.stat(path, (error, stats) => {
if (error) {
next()
return
}

const reqHeaders = req.headers
const requestHeaders = request.headers
const resHeaders = {}
resHeaders['content-type'] = type
if (opts.maxAge !== false) {
resHeaders['cache-control'] = `public, max-age=${opts.maxAge}`
if (options.maxAge !== false) {
resHeaders['cache-control'] = `public, max-age=${options.maxAge}`
}
if (opts.lastModified) {

if (options.lastModified) {
resHeaders['last-modified'] = stats.mtime.toUTCString()
}
if (opts.etag) {
resHeaders['etag'] = etag(`${etag(stats)}p${path}w${w}h${h}g${g}max${max}`)

if (options.etag) {
resHeaders.etag = etag(`${etag(stats)}p${path}w${w}h${h}g${g}max${max}`)
}

if (!imageTypes.includes(type)) {
if (!imageTypes.has(type)) {
next()
return
}
if (fresh(reqHeaders, resHeaders)) {

if (fresh(requestHeaders, resHeaders)) {
setHeaders(res, resHeaders)
res.statusCode = 304
res.end()
return
}

if (method === 'HEAD') {
setHeaders(res, resHeaders)
res.statusCode = 200
Expand All @@ -113,45 +110,49 @@ module.exports = function (opts) {
}

const s = sharp(path)
const gravity = sharp.gravity[g] != null ? sharp.gravity[g] : 'center'
const gravity = sharp.gravity[g] ?? 'center'
if (w || h || max) {
const opts = {}
const options = {}
if (gravity) {
opts.position = gravity
options.position = gravity
}

if (max) {
opts.withoutEnlargement = true
options.withoutEnlargement = true
}
s.resize(w, h, opts)

s.resize(w, h, options)
}

s.jpeg({
force: false,
quality: opts.quality,
progressive: opts.progressive,
compressionLevel: opts.compression,
quality: options.quality,
progressive: options.progressive,
compressionLevel: options.compression,
})
s.png({
force: false,
quality: opts.quality,
progressive: opts.progressive,
compressionLevel: opts.compression,
quality: options.quality,
progressive: options.progressive,
compressionLevel: options.compression,
})
s.webp({
force: false,
quality: opts.quality,
quality: options.quality,
})
s.tiff({
force: false,
quality: opts.quality,
quality: options.quality,
})

setHeaders(res, resHeaders)
s.toBuffer(function (err, buf, info) {
if (err) {
s.toBuffer((error, buf, _info) => {
if (error) {
res.statusCode = 500
res.end()
return
}

res.statusCode = 200
res.write(buf)
res.end()
Expand Down
Loading

0 comments on commit 59de3d3

Please sign in to comment.