Socket
Socket
Sign inDemoInstall

ipx

Package Overview
Dependencies
Maintainers
2
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ipx - npm Package Compare versions

Comparing version 0.3.1 to 0.3.2

LICENSE

4

bin/ipx.js

@@ -7,3 +7,3 @@ #!/usr/bin/env node

async function main () {
function main () {
// Create IPX instance

@@ -26,2 +26,2 @@ const ipx = new IPX()

main().catch(consola.error)
main()

@@ -6,2 +6,10 @@ # Change Log

## [0.3.2](https://github.com/nuxt-contrib/ipx/compare/ipx@0.3.1...ipx@0.3.2) (2020-09-23)
**Note:** Version bump only for package ipx
## [0.3.1](https://github.com/jsless/ipx/compare/ipx@0.3.0...ipx@0.3.1) (2019-01-27)

@@ -8,0 +16,0 @@

@@ -8,223 +8,140 @@ 'use strict';

var consola = _interopDefault(require('consola'));
var path = require('path');
var isValidPath = _interopDefault(require('is-valid-path'));
var path = require('path');
var fsExtra = require('fs-extra');
var recursiveReadDir = _interopDefault(require('recursive-readdir'));
var Sharp = _interopDefault(require('sharp'));
var defu = _interopDefault(require('defu'));
var cron = require('cron');
var getEtag = _interopDefault(require('etag'));
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
const MAX_SIZE = 2048;
const numRegex = /^[1-9][0-9]*$/;
class HttpError extends Error {
constructor() {
super(...arguments);
this.statusCode = 500;
}
}
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;
}
function _toArray(arr) {
return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
var MAX_SIZE = 2048;
var numRegex = /^[1-9][0-9]*$/;
function checkConditionalHeaders(req, lastModified, etag) {
// If-None-Match header
var ifNoneMatch = req.headers['if-none-match'];
if (ifNoneMatch === etag) {
return true;
} // If-Modified-Since header
var ifModifiedSince = req.headers['if-modified-since'];
if (ifModifiedSince) {
if (new Date(ifModifiedSince) >= lastModified) {
return true;
// If-None-Match header
const ifNoneMatch = req.headers['if-none-match'];
if (ifNoneMatch === etag) {
return true;
}
}
return false;
// If-Modified-Since header
const ifModifiedSince = req.headers['if-modified-since'];
if (ifModifiedSince) {
if (new Date(ifModifiedSince) >= lastModified) {
return true;
}
}
return false;
}
function badRequest(msg) {
var err = new Error('Bad Request: ' + msg);
err.statusCode = 400;
return err;
const err = new HttpError('Bad Request: ' + msg);
err.statusCode = 400;
return err;
}
function notFound() {
var err = new Error('Not Found');
err.statusCode = 404;
return err;
const err = new HttpError('Not Found');
err.statusCode = 404;
return err;
}
var VMax = function VMax(max) {
return function (num) {
const VMax = (max) => (num) => {
if (!numRegex.test(num)) {
throw badRequest('Invalid numeric argument: ' + num);
throw badRequest('Invalid numeric argument: ' + num);
}
return Math.min(parseInt(num), max) || null;
};
};
var VSize = VMax(MAX_SIZE);
var consola$1 = consola.withTag('ipx');
const VSize = VMax(MAX_SIZE);
const consola$1 = consola.withTag('ipx');
var OPERATIONS = {
s: {
name: 'resize',
args: [VSize, VSize],
handler: function handler(context, pipe, width, height) {
return pipe.resize(width, height);
s: {
name: 'resize',
args: [VSize, VSize],
handler: (_context, pipe, width, height, fit) => pipe.resize(width, height, {
fit,
background: { r: 0, g: 0, b: 0, alpha: 0 }
})
},
w: {
name: 'width',
args: [VSize],
handler: (_context, pipe, width) => pipe.resize(width, null)
},
h: {
name: 'height',
args: [VSize],
handler: (_context, pipe, height) => pipe.resize(null, height)
},
embed: {
name: 'embed',
args: [],
handler: (_context, pipe) => pipe.embed()
},
max: {
name: 'max',
args: [],
handler: (_context, pipe) => pipe.max()
},
min: {
name: 'min',
args: [],
handler: (_context, pipe) => pipe.min()
}
},
w: {
name: 'width',
args: [VSize],
handler: function handler(context, pipe, width) {
return pipe.resize(width, null);
}
},
h: {
name: 'height',
args: [VSize],
handler: function handler(context, pipe, height) {
return pipe.resize(null, height);
}
},
embed: {
name: 'embed',
handler: function handler(context, pipe) {
return pipe.embed();
}
},
max: {
name: 'max',
handler: function handler(context, pipe) {
return pipe.max();
}
},
min: {
name: 'min',
handler: function handler(context, pipe) {
return pipe.min();
}
}
};
function env(name, defaultValue) {
return process.env[name] || defaultValue;
return process.env[name] || defaultValue;
}
function getConfig() {
return {
port: env('IPX_PORT', env('PORT', 3000)),
input: {
adapter: env('IPX_INPUT_ADAPTER', 'fs'),
dir: env('IPX_INPUT_DIR', 'storage')
},
cache: {
adapter: env('IPX_CACHE_ADAPTER', 'fs'),
dir: env('IPX_CACHE_DIR', 'cache'),
cleanCron: env('IPX_CACHE_CLEAN_CRON', '0 0 3 * * *'),
maxUnusedMinutes: env('IPX_CACHE_CLEAN_MINUTES', 24 * 60)
}
};
}
function getConfig() {
return {
port: env('IPX_PORT', env('PORT', 3000)),
input: {
adapter: env('IPX_INPUT_ADAPTER', 'fs'),
dir: env('IPX_INPUT_DIR', 'storage')
},
cache: {
adapter: env('IPX_CACHE_ADAPTER', 'fs'),
dir: env('IPX_CACHE_DIR', 'cache'),
cleanCron: env('IPX_CACHE_CLEAN_CRON', '0 0 3 * * *'),
maxUnusedMinutes: env('IPX_CACHE_CLEAN_MINUTES', 24 * 60)
class BaseInputAdapter {
constructor(ipx) {
this.ipx = ipx;
this.options = ipx.options;
this.init();
}
};
init() { }
}
var isAbsolute = require('path').posix.isAbsolute;
var FSAdapter =
/*#__PURE__*/
function () {
function FSAdapter(ipx) {
_classCallCheck(this, FSAdapter);
this.options = ipx.options;
}
_createClass(FSAdapter, [{
key: "_resolve",
value: function _resolve(src) {
return path.resolve(this.dir, src);
class FSAdapter extends BaseInputAdapter {
get dir() {
return this.options.input.dir;
}
}, {
key: "stats",
value: function stats(src) {
return new Promise(function ($return, $error) {
var _src, stats;
if (isAbsolute(src) || !isValidPath(src)) {
return $return(false);
_resolve(src) {
return path.resolve(this.dir, src);
}
async stats(src) {
if (path.posix.isAbsolute(src) || !isValidPath(src)) {
return false;
}
_src = this._resolve(src);
const _src = await this._resolve(src);
if (path.relative(this.dir, _src).includes('..')) {
return $return(false);
return false;
}
var $Try_1_Catch = function (e) {
try {
// TODO: check for permission errors
return $return(false);
} catch ($boundEx) {
return $error($boundEx);
}
};
try {
return Promise.resolve(fsExtra.stat(_src)).then(function ($await_2) {
try {
stats = $await_2;
return $return(stats);
} catch ($boundEx) {
return $Try_1_Catch($boundEx);
}
}, $Try_1_Catch);
} catch (e) {
$Try_1_Catch(e);
const stats = await fsExtra.stat(_src);
return stats;
}
}.bind(this));
catch (e) {
// TODO: check for permission errors
return false;
}
}

@@ -235,23 +152,11 @@ /**

*/
}, {
key: "get",
value: function get(src) {
var _src = this._resolve(src);
var buff = fsExtra.readFile(_src);
return buff;
async get(src) {
const _src = await this._resolve(src);
const buff = fsExtra.readFile(_src);
return buff;
}
}, {
key: "dir",
get: function get() {
return this.options.input.dir;
}
}]);
}
return FSAdapter;
}();
var InputAdapters = /*#__PURE__*/Object.freeze({

@@ -261,134 +166,60 @@ fs: FSAdapter

var FSCache =
/*#__PURE__*/
function () {
function FSCache(ipx) {
_classCallCheck(this, FSCache);
class BaseCacheAdapter {
constructor(ipx) {
this.ipx = ipx;
this.options = ipx.options;
this.init();
}
init() { }
}
this.ipx = ipx;
this.options = ipx.options;
this.init();
}
_createClass(FSCache, [{
key: "init",
value: function init() {
// Ensure cacheDir exists
if (this.options.cache.dir) {
fsExtra.mkdirpSync(this.options.cache.dir);
}
class FSCache extends BaseCacheAdapter {
init() {
// Ensure cacheDir exists
if (this.options.cache.dir) {
fsExtra.mkdirpSync(this.options.cache.dir);
}
}
}, {
key: "resolve",
value: function resolve(key) {
return path.resolve(this.options.cache.dir, key);
resolve(key) {
return path.resolve(this.options.cache.dir, key);
}
}, {
key: "clean",
value: function clean() {
return new Promise(function ($return, $error) {
var now, diffMins, files, items, maxUnusedMinutes;
now = new Date();
diffMins = function diffMins(t) {
return (now - t) / (1000 * 60);
};
return Promise.resolve(recursiveReadDir(this.options.cache.dir)).then(function ($await_1) {
try {
files = $await_1;
return Promise.resolve(Promise.all(files.map(function (file) {
return new Promise(function ($return, $error) {
var stats;
return Promise.resolve(fsExtra.stat(file)).then(function ($await_2) {
try {
stats = $await_2;
return $return({
file: file,
lastAccessAgo: diffMins(stats.atime)
});
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
});
}))).then(function ($await_3) {
try {
items = $await_3;
maxUnusedMinutes = parseInt(this.options.cache.maxUnusedMinutes);
items = items.filter(function (item) {
return item.lastAccessAgo >= maxUnusedMinutes;
});
return Promise.resolve(Promise.all(items.map(function (item) {
return new Promise(function ($return, $error) {
consola.debug('[DELETE] ' + item.file);
return Promise.resolve(fsExtra.remove(item.file)).then(function ($await_4) {
try {
return $return();
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
});
}))).then(function ($await_5) {
try {
return $return();
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
}.bind(this));
async clean() {
const now = new Date();
const diffMins = (t) => ((+now - +t) / (1000 * 60));
// Scan all files
const files = await recursiveReadDir(this.options.cache.dir);
// Stat all files
let items = await Promise.all(files.map(async (file) => {
const stats = await fsExtra.stat(file);
return {
file,
lastAccessAgo: diffMins(stats.atime)
};
}));
// Filter items to be invalidated from cache
const maxUnusedMinutes = +this.options.cache.maxUnusedMinutes;
items = items.filter(item => item.lastAccessAgo >= maxUnusedMinutes);
await Promise.all(items.map(async (item) => {
consola.debug('[DELETE] ' + item.file);
await fsExtra.remove(item.file);
}));
}
}, {
key: "get",
value: function get(key) {
return new Promise(function ($return, $error) {
var _path;
_path = this.resolve(key);
return Promise.resolve(fsExtra.exists(_path)).then(function ($await_6) {
try {
if (!$await_6) {
return $return(null);
}
consola.debug('[HIT] ' + key);
return $return(fsExtra.readFile(_path));
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
}.bind(this));
async get(key) {
const _path = await this.resolve(key);
// @ts-ignore
if (!(await fsExtra.exists(_path))) {
return null;
}
consola.debug('[HIT] ' + key);
return fsExtra.readFile(_path);
}
}, {
key: "set",
value: function set(key, data) {
return new Promise(function ($return, $error) {
var _path;
_path = this.resolve(key);
return Promise.resolve(fsExtra.mkdirp(path.dirname(_path))).then(function ($await_7) {
try {
return $return(fsExtra.writeFile(_path, data));
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
}.bind(this));
async set(key, data) {
const _path = await this.resolve(key);
await fsExtra.mkdirp(path.dirname(_path));
return fsExtra.writeFile(_path, data);
}
}]);
}
return FSCache;
}();
var CacheAdapters = /*#__PURE__*/Object.freeze({

@@ -398,72 +229,59 @@ fs: FSCache

var operationSeparator = ',';
var argSeparator = '_';
var IPX =
/*#__PURE__*/
function () {
function IPX(options) {
_classCallCheck(this, IPX);
this.options = Object.assign({}, getConfig(), options);
this.operations = {};
this.adapter = null;
this.init();
}
_createClass(IPX, [{
key: "init",
value: function init() {
var _this = this;
// Merge and normalize operations
var _operations = Object.assign({}, OPERATIONS, this.options.operations);
Object.keys(_operations).filter(function (_key) {
return _operations[_key];
}).forEach(function (_key) {
var operation = _operations[_key];
var key = _key || operation.key;
_this.operations[key] = {
name: operation.name || key,
handler: operation.handler || operation,
multiply: Boolean(operation.multiply),
order: Boolean(operation.order),
args: operation.args || []
};
}); // Create instance of input
var InputCtor = this.options.input.adapter;
if (typeof InputCtor === 'string') {
InputCtor = InputAdapters[InputCtor] || require(path.resolve(InputCtor));
}
this.input = new InputCtor(this);
if (typeof this.input.init === 'function') {
this.input.init();
} // Create instance of cache
var CacheCtor = this.options.cache.adapter;
if (typeof CacheCtor === 'string') {
CacheCtor = CacheAdapters[CacheCtor] || require(path.resolve(CacheCtor));
}
this.cache = new CacheCtor(this);
if (typeof this.cache.init === 'function') {
this.cache.init();
} // Start cache cleaning cron
if (this.options.cache.cleanCron) {
this.cacheCleanCron = new cron.CronJob(this.options.cache.cleanCron, function () {
return _this.cleanCache().catch(consola$1.error);
const operationSeparator = ',';
const argSeparator = '_';
class IPX {
constructor(options) {
this.options = defu(options, getConfig());
this.operations = {};
this.adapter = null;
this.init();
}
init() {
// Merge and normalize operations
const _operations = Object.assign({}, OPERATIONS, this.options.operations);
Object.keys(_operations)
.filter(_key => _operations[_key])
.forEach((_key) => {
const operation = _operations[_key];
const key = _key || operation.key;
this.operations[key] = {
name: operation.name || key,
handler: operation.handler || operation,
multiply: Boolean(operation.multiply),
order: Boolean(operation.order),
args: operation.args || []
};
});
consola$1.info('Starting cache clean cron ' + this.options.cache.cleanCron);
this.cacheCleanCron.start();
}
// Create instance of input
let InputCtor;
if (typeof this.options.input.adapter === 'string') {
const adapter = this.options.input.adapter;
InputCtor = InputAdapters[adapter] || require(path.resolve(adapter));
}
else {
InputCtor = this.options.input.adapter;
}
this.input = new InputCtor(this);
if (typeof this.input.init === 'function') {
this.input.init();
}
// Create instance of cache
let CacheCtor;
if (typeof this.options.cache.adapter === 'string') {
const adapter = this.options.cache.adapter;
CacheCtor = CacheAdapters[adapter] || require(path.resolve(adapter));
}
else {
CacheCtor = this.options.cache.adapter;
}
this.cache = new CacheCtor(this);
if (typeof this.cache.init === 'function') {
this.cache.init();
}
// Start cache cleaning cron
if (this.options.cache.cleanCron) {
this.cacheCleanCron = new cron.CronJob(this.options.cache.cleanCron, () => this.cleanCache().catch(consola$1.error));
consola$1.info('Starting cache clean cron ' + this.options.cache.cleanCron);
this.cacheCleanCron.start();
}
}

@@ -474,295 +292,161 @@ /**

*/
}, {
key: "parseOperations",
value: function parseOperations(operations) {
var _this2 = this;
var ops = {};
if (operations === '_') {
return [];
}
return operations.split(operationSeparator).map(function (_o) {
var _o$split = _o.split(argSeparator),
_o$split2 = _toArray(_o$split),
key = _o$split2[0],
args = _o$split2.slice(1);
var operation = _this2.operations[key];
if (!operation) {
throw badRequest('Invalid operation: ' + key);
parseOperations(operations) {
const ops = {};
if (operations === '_') {
return [];
}
if (operation.args.length !== args.length) {
throw badRequest('Invalid number of args for ' + key + '. Expected ' + operation.args.length + ' got ' + args.length);
return operations.split(operationSeparator).map((_o) => {
const [key, ...args] = _o.split(argSeparator);
const operation = this.operations[key];
if (!operation) {
throw badRequest('Invalid operation: ' + key);
}
/**
* allow optional arguments for operations
*/
if (operation.args.length > args.length) {
throw badRequest('Invalid number of args for ' + key + '. Expected ' + operation.args.length + ' got ' + args.length);
}
for (let i = 0; i < operation.args.length; i++) {
args[i] = operation.args[i](args[i]);
}
if (!operation.multiply) {
if (ops[operation.name]) {
throw badRequest(key + ' can be only used once');
}
ops[operation.name] = true;
}
return {
operation,
args,
cacheKey: key + argSeparator + args.join(argSeparator)
};
});
}
async getInfo({ format, operations, src }) {
// Validate format
if (format === '_') {
format = path.extname(src).substr(1);
}
for (var i = 0; i < operation.args.length; i++) {
args[i] = operation.args[i](args[i]);
if (format === 'jpg') {
format = 'jpeg';
}
if (!operation.multiply) {
if (ops[operation.name]) {
throw badRequest(key + ' can be only used once');
}
ops[operation.name] = true;
if (!['jpeg', 'webp', 'png'].includes(format)) {
throw badRequest(`Unkown image format ${format}`);
}
// Validate src
if (!src || src.includes('..')) {
throw notFound();
}
// Get src stat
const stats = await this.input.stats(src);
if (!stats) {
throw notFound();
}
// Parse and validate operations
let _operations = this.parseOperations(operations);
// Reorder operations
_operations = [
..._operations.filter(o => o.operation.order !== true).sort(),
..._operations.filter(o => o.operation.order === true)
];
// Compute unique hash key
const operationsKey = _operations.length ? _operations.map(o => o.cacheKey).join(argSeparator) : '_';
const statsKey = stats.mtime.getTime().toString(16) + '-' + stats.size.toString(16);
const cacheKey = src + '/' + statsKey + '/' + operationsKey + '.' + format;
// Return info
return {
operation: operation,
args: args,
cacheKey: key + argSeparator + args.join(argSeparator)
operations: _operations,
stats,
cacheKey,
format,
src
};
});
}
}, {
key: "getInfo",
value: function getInfo(_ref) {
return new Promise(function ($return, $error) {
var format, operations, src, stats, _operations, operationsKey, statsKey, cacheKey;
format = _ref.format, operations = _ref.operations, src = _ref.src;
// Validate format
if (format === '_') {
format = path.extname(src).substr(1);
async getData({ cacheKey, operations, format, src }) {
// Check cache existence
const cache = await this.cache.get(cacheKey);
if (cache) {
return cache;
}
if (format === 'jpg') {
format = 'jpeg';
// Read buffer from input
const srcBuff = await this.input.get(src);
// Process using Sharp
let sharp = Sharp(srcBuff);
if (format !== '_') {
sharp = sharp.toFormat(format);
}
if (['jpeg', 'webp', 'png'].indexOf(format) === -1) {
return $error(badRequest("Unkown image format ".concat(format)));
} // Validate src
if (!src || src.indexOf('..') >= 0) {
return $error(notFound());
} // Get src stat
return Promise.resolve(this.input.stats(src)).then(function ($await_3) {
try {
stats = $await_3;
if (!stats) {
return $error(notFound());
} // Parse and validate operations
_operations = this.parseOperations(operations);
// Reorder operations
_operations = [].concat(_operations.filter(function (o) {
return o.operation.order !== true;
}).sort(), _operations.filter(function (o) {
return o.operation.order === true;
})); // Compute unique hash key
operationsKey = _operations.length ? _operations.map(function (o) {
return o.cacheKey;
}).join(argSeparator) : '_';
statsKey = stats.mtime.getTime().toString(16) + '-' + stats.size.toString(16);
cacheKey = src + '/' + statsKey + '/' + operationsKey + '.' + format;
// Return info
return $return({
operations: _operations,
stats: stats,
cacheKey: cacheKey,
format: format,
src: src
});
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
}.bind(this));
operations.forEach(({ operation, args }) => {
sharp = operation.handler(this, sharp, ...args);
});
const data = await sharp.toBuffer();
// Put data into cache
try {
await this.cache.set(cacheKey, data);
}
catch (e) {
consola$1.error(e);
}
return data;
}
}, {
key: "getData",
value: function getData(_ref2) {
return new Promise(function ($return, $error) {
var _this3, cacheKey, stats, operations, format, src, cache, srcBuff, sharp, data;
_this3 = this;
cacheKey = _ref2.cacheKey, stats = _ref2.stats, operations = _ref2.operations, format = _ref2.format, src = _ref2.src;
return Promise.resolve(this.cache.get(cacheKey)).then(function ($await_4) {
try {
cache = $await_4;
if (cache) {
return $return(cache);
} // Read buffer from input
return Promise.resolve(this.input.get(src)).then(function ($await_5) {
try {
srcBuff = $await_5;
sharp = new Sharp(srcBuff);
if (format !== '_') {
sharp = sharp.toFormat(format);
}
operations.forEach(function (_ref3) {
var operation = _ref3.operation,
args = _ref3.args;
sharp = operation.handler.apply(operation, [_this3, sharp].concat(_toConsumableArray(args)));
});
return Promise.resolve(sharp.toBuffer()).then(function ($await_6) {
try {
data = $await_6;
var $Try_1_Post = function () {
try {
return $return(data);
} catch ($boundEx) {
return $error($boundEx);
}
};
var $Try_1_Catch = function (e) {
try {
consola$1.error(e);
return $Try_1_Post();
} catch ($boundEx) {
return $error($boundEx);
}
};
// Put data into cache
try {
return Promise.resolve(this.cache.set(cacheKey, data)).then(function ($await_7) {
try {
return $Try_1_Post();
} catch ($boundEx) {
return $Try_1_Catch($boundEx);
}
}, $Try_1_Catch);
} catch (e) {
$Try_1_Catch(e);
}
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
}.bind(this));
}
}, {
key: "cleanCache",
value: function cleanCache() {
return new Promise(function ($return, $error) {
async cleanCache() {
if (this.cache) {
return Promise.resolve(this.cache.clean()).then(function ($await_8) {
try {
return $If_2.call(this);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
await this.cache.clean();
}
function $If_2() {
return $return();
}
return $If_2.call(this);
}.bind(this));
}
}]);
}
return IPX;
}();
function IPXReqHandler(req, res, ipx) {
return new Promise(function ($return, $error) {
var urlArgs, format, operations, src, info, lastModified, etag, data;
urlArgs = req.url.substr(1).split('/');
format = decodeURIComponent(urlArgs.shift());
operations = decodeURIComponent(urlArgs.shift());
src = urlArgs.map(function (c) {
return decodeURIComponent(c);
}).join('/');
async function IPXReqHandler(req, res, ipx) {
// Parse URL
const url = req.url || '/';
const urlArgs = url.substr(1).split('/');
const format = decodeURIComponent(urlArgs.shift() || '');
const operations = decodeURIComponent(urlArgs.shift() || '');
const src = urlArgs.map(c => decodeURIComponent(c)).join('/');
// Validate params
if (!format) {
return $error(badRequest('Missing format'));
throw badRequest('Missing format');
}
if (!operations) {
return $error(badRequest('Missing operations'));
throw badRequest('Missing operations');
}
if (!src) {
return $error(badRequest('Missing src'));
} // Get basic info about request
return Promise.resolve(ipx.getInfo({
format: format,
operations: operations,
src: src
})).then(function ($await_1) {
try {
info = $await_1;
// Set Content-Type header
if (info.format) {
res.setHeader('Content-Type', 'image/' + info.format);
} else {
res.setHeader('Content-Type', 'image');
} // Set Last-Modified Header
lastModified = info.stats.mtime || new Date();
res.setHeader('Last-Modified', lastModified); // Set Etag header
etag = getEtag(info.cacheKey);
res.setHeader('Etag', etag); // Check conditional headers for 304
throw badRequest('Missing src');
}
// Get basic info about request
const info = await ipx.getInfo({ format, operations, src });
// Set Content-Type header
if (info.format) {
res.setHeader('Content-Type', 'image/' + info.format);
}
else {
res.setHeader('Content-Type', 'image');
}
// Set Etag header
const etag = getEtag(info.cacheKey);
res.setHeader('Etag', etag);
if (info.stats) {
// Set Last-Modified Header
const lastModified = info.stats.mtime || new Date();
res.setHeader('Last-Modified', +lastModified);
// Check conditional headers for 304
if (checkConditionalHeaders(req, lastModified, etag)) {
res.statusCode = 304;
return $return(res.end());
} // Process request to get image
return Promise.resolve(ipx.getData(info)).then(function ($await_2) {
try {
data = $await_2;
// Send image
res.end(data);
return $return();
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
});
res.statusCode = 304;
return res.end();
}
}
// Process request to get image
const data = await ipx.getData(info);
// Send image
res.end(data);
}
function IPXMiddleware(ipx) {
return function IPXMiddleware(req, res) {
IPXReqHandler(req, res, ipx).catch(function (err) {
if (err.statusCode) {
res.statusCode = err.statusCode;
}
res.end('IPX Error: ' + err);
});
};
return function IPXMiddleware(req, res) {
IPXReqHandler(req, res, ipx).catch((err) => {
if (err.statusCode) {
res.statusCode = err.statusCode;
}
res.end('IPX Error: ' + err);
});
};
}

@@ -769,0 +453,0 @@

{
"name": "ipx",
"version": "0.3.1",
"version": "0.3.2",
"repository": "nuxt-contrib/ipx",
"license": "MIT",
"contributors": [
{
"name": "Pooya Parsa",
"email": "pooya@pi0.ir"
}
],
"main": "dist/ipx.cjs.js",
"bin": "bin/ipx.js",
"files": [

@@ -15,19 +12,17 @@ "dist",

],
"main": "dist/ipx.cjs.js",
"module": "dist/ipx.es.js",
"bin": "bin/ipx.js",
"scripts": {
"build": "bili --format cjs,es src/index.js"
"build": "bili --format cjs src/index.ts"
},
"dependencies": {
"connect": "^3.6.6",
"consola": "^2.3.2",
"cron": "^1.3.0",
"connect": "^3.7.0",
"consola": "^2.15.0",
"cron": "^1.8.2",
"defu": "^3.1.0",
"etag": "^1.8.1",
"fs-extra": "^7.0.1",
"fs-extra": "^9.0.1",
"is-valid-path": "^0.1.1",
"recursive-readdir": "^2.2.2",
"sharp": "^0.21.3"
"sharp": "^0.26.0"
},
"gitHead": "8c5b9447bd7532dc23f72b0ad8308a5de44a907c"
"gitHead": "eaa62032f71e4f369141efacdb99d88b75faffb5"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc