Comparing version 0.2.1 to 0.3.0
{ | ||
"name": "impro", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "Image processing engine", | ||
@@ -37,2 +37,3 @@ "author": "Andreas Lind <andreaslindpetersen@gmail.com>", | ||
"eslint-plugin-standard": "^4.0.1", | ||
"file-type": "^12.3.0", | ||
"gifsicle-stream": "1.0.0", | ||
@@ -39,0 +40,0 @@ "gm": "1.23.1", |
@@ -0,1 +1,5 @@ | ||
# Impro | ||
An image processing engine integrating multiple conversion libraries. | ||
[![NPM version](https://badge.fury.io/js/impro.svg)](http://badge.fury.io/js/impro) | ||
@@ -5,1 +9,18 @@ [![Build Status](https://travis-ci.org/papandreou/impro.svg?branch=master)](https://travis-ci.org/papandreou/impro) | ||
[![Dependency Status](https://david-dm.org/papandreou/impro.svg)](https://david-dm.org/papandreou/impro) | ||
Impro allows specifyng the operations to aplpy to images and will | ||
itself select the correct conversion library to perform the job. | ||
Support for the following libraries is included: | ||
- Sharp | ||
- Gifsicle | ||
- GraphicsMagick | ||
- JpegTran | ||
- Inkscape | ||
- SvgFilter | ||
- OptiPNG | ||
## License | ||
Impro is licensed under a standard 3-clause BSD license. |
@@ -66,3 +66,3 @@ const requireOr = require('require-or'); | ||
if (gifsicleArgs.length > 0) { | ||
pipeline.add(new Gifsicle(gifsicleArgs)); | ||
pipeline._attach(new Gifsicle(gifsicleArgs)); | ||
seenOperationThatMustComeBeforeExtract = false; | ||
@@ -69,0 +69,0 @@ gifsicleArgs = []; |
@@ -33,3 +33,3 @@ const requireOr = require('require-or'); | ||
inputTypes: ['gif', 'jpeg', 'png', 'ico', 'tga', 'tiff', '*'], | ||
outputTypes: ['gif', 'jpeg', 'png', 'ico', 'tga', 'tiff'], | ||
outputTypes: ['gif', 'jpeg', 'png', 'tga', 'tiff', 'webp'], | ||
validateOperation: function(name, args) { | ||
@@ -188,6 +188,3 @@ switch (name) { | ||
if ( | ||
operation.name === 'webp' || | ||
operation.name === 'png' || | ||
operation.name === 'jpeg' || | ||
operation.name === 'gif' | ||
module.exports.outputTypes.includes(operation.name) | ||
) { | ||
@@ -225,3 +222,3 @@ operation = _.extend({}, operation); | ||
new Error( | ||
'The gm stream ended without emitting any data' | ||
'gm: stream ended without emitting any data' | ||
) | ||
@@ -243,4 +240,4 @@ ); | ||
}; | ||
pipeline.add(readWriteStream); | ||
pipeline._attach(readWriteStream); | ||
} | ||
}; |
@@ -29,4 +29,4 @@ const requireOr = require('require-or'); | ||
} | ||
pipeline.add(new Inkscape(commandLineArgs)); | ||
pipeline._attach(new Inkscape(commandLineArgs)); | ||
} | ||
}; |
@@ -17,2 +17,3 @@ const requireOr = require('require-or'); | ||
'copy', | ||
'crop', | ||
'optimize', | ||
@@ -88,4 +89,7 @@ 'progressive', | ||
}); | ||
pipeline.add(new JpegTran(commandLineArgs)); | ||
pipeline._attach(new JpegTran(commandLineArgs)); | ||
return commandLineArgs; | ||
} | ||
}; |
@@ -124,3 +124,3 @@ const requireOr = require('require-or'); | ||
}); | ||
pipeline.add(duplexStream); | ||
pipeline._attach(duplexStream); | ||
pipeline.targetType = 'json'; | ||
@@ -127,0 +127,0 @@ pipeline.targetContentType = 'application/json; charset=utf-8'; |
@@ -20,4 +20,4 @@ const requireOr = require('require-or'); | ||
}); | ||
pipeline.add(new OptiPng(commandLineArgs)); | ||
pipeline._attach(new OptiPng(commandLineArgs)); | ||
} | ||
}; |
@@ -89,4 +89,4 @@ const requireOr = require('require-or'); | ||
}); | ||
pipeline.add(new PngCrush(commandLineArgs)); | ||
pipeline._attach(new PngCrush(commandLineArgs)); | ||
} | ||
}; |
@@ -43,4 +43,4 @@ const requireOr = require('require-or'); | ||
}); | ||
pipeline.add(new PngQuant(commandLineArgs)); | ||
pipeline._attach(new PngQuant(commandLineArgs)); | ||
} | ||
}; |
@@ -10,3 +10,3 @@ const requireOr = require('require-or'); | ||
function locatePreviousCommand(operations, nameToFind) { | ||
return operations.find(operation => { | ||
return operations.findIndex(operation => { | ||
return operation.name === nameToFind; | ||
@@ -157,2 +157,10 @@ }); | ||
var operationsForExecution = []; | ||
if (pipeline.targetType) { | ||
operationsForExecution.push({ | ||
name: pipeline.targetType, | ||
args: [] | ||
}); | ||
} | ||
operations.forEach(function(operation) { | ||
@@ -181,11 +189,38 @@ var name = operation.name; | ||
const locatedOperation = locatePreviousCommand( | ||
const locatedIndex = locatePreviousCommand( | ||
operationsForExecution, | ||
name | ||
); | ||
if (locatedOperation) { | ||
locatedOperation.args[2] = args[2]; | ||
if (locatedIndex > -1) { | ||
let locatedOperation = operationsForExecution[locatedIndex]; | ||
locatedOperation = { | ||
...locatedOperation, | ||
args: locatedOperation.args.concat(args[2]) | ||
}; | ||
operationsForExecution[locatedIndex] = locatedOperation; | ||
return; | ||
} | ||
} | ||
// in sharp quality is implemented as an option to the target type | ||
if (operation.name === 'quality') { | ||
const locatedIndex = locatePreviousCommand( | ||
operationsForExecution, | ||
pipeline.targetType | ||
); | ||
if (locatedIndex > -1) { | ||
let locatedOperation = operationsForExecution[locatedIndex]; | ||
locatedOperation = { | ||
...locatedOperation, | ||
args: [ | ||
{ ...locatedOperation.args[0], quality: args[0] } | ||
] | ||
}; | ||
operationsForExecution[locatedIndex] = locatedOperation; | ||
return; | ||
} else { | ||
throw new Error( | ||
'sharp: quality() operation must follow output type selection' | ||
); | ||
} | ||
} | ||
// Compensate for https://github.com/lovell/sharp/issues/276 | ||
@@ -210,4 +245,6 @@ if (name === 'extract' && args.length >= 4) { | ||
pipeline.add(sharpInstance); | ||
pipeline._attach(sharpInstance); | ||
return operationsForExecution; | ||
} | ||
}; |
@@ -14,4 +14,4 @@ const requireOr = require('require-or'); | ||
execute: function(pipeline, operations, options) { | ||
pipeline.add(new SvgFilter(options)); | ||
pipeline._attach(new SvgFilter(options)); | ||
} | ||
}; |
@@ -47,2 +47,7 @@ const _ = require('lodash'); | ||
createPipeline(options, operations) { | ||
if (typeof options === 'string' || Array.isArray(options)) { | ||
operations = options; | ||
options = undefined; | ||
} | ||
const pipeline = new this._Pipeline(this, { | ||
@@ -52,5 +57,15 @@ ...options, | ||
}); | ||
if (operations) { | ||
pipeline.add(operations); | ||
if (typeof operations === 'string') { | ||
operations = this.parse(operations).operations; | ||
} else if (!Array.isArray(operations)) { | ||
throw new Error( | ||
'Pipeline creation can only be supplied an operations array or string' | ||
); | ||
} | ||
operations.forEach(operation => pipeline.add(operation)); | ||
} | ||
return pipeline; | ||
@@ -70,4 +85,4 @@ } | ||
add(...rest) { | ||
return this.createPipeline().add(...rest); | ||
add(operation) { | ||
return this.createPipeline().add(operation); | ||
} | ||
@@ -74,0 +89,0 @@ |
@@ -18,3 +18,3 @@ const Stream = require('stream'); | ||
const { type, supportedOptions, ...sourceMetadata } = options || {}; | ||
supportedOptions.forEach(optionName => { | ||
(supportedOptions || []).forEach(optionName => { | ||
this.options[optionName] = | ||
@@ -31,3 +31,3 @@ typeof options[optionName] !== 'undefined' | ||
flush() { | ||
flush(isStream = false) { | ||
if (this._flushed) { | ||
@@ -43,3 +43,7 @@ return this; | ||
var _flush = upToIndex => { | ||
if (startIndex < upToIndex) { | ||
if (startIndex >= upToIndex) { | ||
return; | ||
} | ||
try { | ||
if (this.targetType) { | ||
@@ -86,2 +90,8 @@ candidateEngineNames = candidateEngineNames.filter( | ||
startIndex = upToIndex; | ||
} catch (e) { | ||
if (isStream) { | ||
this._fail(e, this.usedEngines.length + 1); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -182,3 +192,3 @@ }; | ||
_write(chunk, encoding, cb) { | ||
this.flush(); | ||
this.flush(true); | ||
this._streams[0].write(chunk, encoding); | ||
@@ -189,3 +199,3 @@ cb(); | ||
_read(size) { | ||
this.flush(); | ||
this.flush(true); | ||
this._streams[this._streams.length - 1].read(size); | ||
@@ -236,17 +246,14 @@ } | ||
_finish() { | ||
if (this.ended) { | ||
return; | ||
this._streams[0].end(); | ||
} | ||
_attach(stream) { | ||
if (!(stream && typeof stream.pipe === 'function')) { | ||
throw new Error('Cannot attach something that is not a stream'); | ||
} | ||
this.ended = true; | ||
this._streams[0].end(); | ||
this._streams.push(stream); | ||
} | ||
add(operation) { | ||
// FIXME: Make a separate method for this | ||
if (operation && typeof operation.pipe === 'function') { | ||
this._streams.push(operation); | ||
return this; | ||
} | ||
if (this._flushed) { | ||
@@ -257,12 +264,8 @@ throw new Error( | ||
} | ||
if (Array.isArray(operation)) { | ||
operation.forEach(operation => this.add(operation)); | ||
} else if (typeof operation === 'string') { | ||
this.impro | ||
.parse(operation) | ||
.operations.forEach(operation => this.add(operation)); | ||
} else if (operation && typeof operation.name === 'string') { | ||
if (operation && typeof operation.name === 'string') { | ||
this._queuedOperations.push(operation); | ||
} else { | ||
throw new Error('add: Unsupported argument: ' + operation); | ||
throw new Error( | ||
`add: Unsupported argument: ${JSON.stringify(operation)}` | ||
); | ||
} | ||
@@ -269,0 +272,0 @@ return this; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
59184
1457
26
0
30