Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

baconize

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

baconize - npm Package Compare versions

Comparing version 2.1.4 to 2.2.0

138

lib/index.js

@@ -13,4 +13,4 @@ 'use strict';

var checkDir = require('checkdir');
var eventEmitter = new events.EventEmitter();
var nodefn = require('when/node');
var crypto = require('crypto');
var rimraf = nodefn.lift(require('rimraf'));

@@ -20,7 +20,10 @@ var mkdirp = nodefn.lift(require('mkdirp'));

// TODO: Consider using node-glob module instead of readdirp + through2
// I think that will simplify the code.
var extname = function(filePath) {
var ext = path.extname(filePath);
if (babyTolk.targetExtensionMap[ext]) return ext;
if (babyTolk.targetExtensionMap[ext]) { return ext; }
return pathCompleteExtname(filePath);
}
};

@@ -51,3 +54,3 @@ var replaceExtension = function(filePath, newExtension) {

).map(excl => excl.path)
)
);

@@ -58,5 +61,16 @@ options.directoryFilter = options.directoryFilter.length ? options.directoryFilter : null;

return options;
}
};
var createHash = function(data) {
var shasum = crypto.createHash('sha1');
shasum.update(data);
return shasum.digest('hex');
};
var noop = () => null
module.exports = function(inputDir, outputDir, options) {
var eventEmitter = new events.EventEmitter();
var shasFilename = '.shas.json';
var fileWhitelist = [shasFilename];
var filesCopied = 0;

@@ -66,2 +80,5 @@ options = options || {};

var abortRequested = false;
var shas = [];
var shasPath = path.join(outputDir, shasFilename);
var existingShas;

@@ -72,9 +89,48 @@ // Default compile and minify options to `true`

var babyTolkOptions = {};
babyTolkOptions.minify = options.minify;
babyTolkOptions.sourceMap = options.sourcemaps;
var babyTolkOptions = {
minify: options.minify,
sourceMap: options.sourcemaps,
inputSha: true,
};
if (options.exclusions) { useExclusionsApi(options); }
var compileAndCopy = function() {
var readAndValidateShas = function() {
var getMainFile = sha => {
var files = sha.output;
var mainFile = files[files.length - 1];
return path.join(outputDir, mainFile);
};
var getInputFile = sha => path.join(inputDir, sha.input);
return fsp.readFile(shasPath, 'utf8').then(contents => {
existingShas = JSON.parse(contents);
var matchingCompilerShas = existingShas.filter(sha =>
babyTolk.getTransformId(getInputFile(sha), babyTolkOptions) === sha.type
);
var files = existingShas.map(sha =>
sha && fsp.readFile(getMainFile(sha), 'utf8').then(contents => contents, noop)
);
return when.all(files).then(filesContents =>
matchingCompilerShas.filter(
(sha, i) => filesContents[i] && (sha.outputSha === createHash(filesContents[i]))
)
);
})
.then(filtered => {
if (!Array.isArray(filtered)) { return; }
return {
input: filtered.map(x => x.input),
// Flatten output files to single array
output: [].concat.apply([], filtered.map(x => x.output))
};
}, noop // ignore errors (shas are not required, just good for perf)
);
};
var compileAndCopy = function(reusableFiles) {
return when.promise(function(resolve, reject) {

@@ -93,2 +149,4 @@ options.root = inputDir;

var addFileToWhitelist = filePath => { fileWhitelist.push(filePath); };
var fileDone = function() {

@@ -108,5 +166,19 @@ if (previousDir !== file.parentDir) {

var compile = function() {
if (reusableFiles && Array.isArray(reusableFiles.input)) {
var reuseExistingFile = reusableFiles.input.indexOf(file.path) > -1;
if (reuseExistingFile) {
var previousSha = existingShas.find(sha => sha.input === file.path);
if (previousSha) { shas.push(previousSha); }
eventEmitter.emit('compile-reuse', file);
previousSha.output.forEach(addFileToWhitelist);
return when.resolve(false);
}
}
eventEmitter.emit('compile-start', file);
return babyTolk.read(file.fullPath, babyTolkOptions).then(function(compiled) {
var writeFiles = [];
var relativePath = path.relative(inputDir, compiled.inputPath);
var writeFiles = [], fileNames = [];

@@ -127,3 +199,5 @@ var fileName = file.name;

});
writeFiles.push(fsp.writeFile(compiledOutputFullPath + '.map', JSON.stringify(compiled.sourcemap)));
var srcMapFileName = compiledOutputFullPath + '.map';
writeFiles.push(fsp.writeFile(srcMapFileName, JSON.stringify(compiled.sourcemap)));
fileNames.push(path.relative(outputDir, srcMapFileName));
if (compiled.extension === '.css') {

@@ -139,6 +213,17 @@ /*# sourceMappingURL=screen.css.map */

writeFiles.push(fsp.writeFile(compiledOutputFullPath, compiled.result));
fileNames.push(path.relative(outputDir, compiledOutputFullPath));
shas.push({
type: compiled.transformId,
inputSha: compiled.inputSha,
outputSha: createHash(compiled.result),
input: relativePath,
output: fileNames
});
eventEmitter.emit('compile-done', file);
return when.all(writeFiles);
return when.all(writeFiles).then(() => {
fileNames.forEach(addFileToWhitelist);
});
});
};
}; // End compile Fn

@@ -149,2 +234,3 @@ var copy = function(renameToSrc) {

var ws = fs.createWriteStream(writePath);
addFileToWhitelist(path.relative(outputDir, writePath));
rs.pipe(ws).on('error', reject);

@@ -185,7 +271,23 @@ ws.on('finish', fileDone).on('error', reject);

})).on('error', reject);
}).then(filesCopied => {
eventEmitter.emit('cleaning-up');
return when.promise((resolve, reject) => {
readdirp({
root: outputDir,
fileFilter: file => fileWhitelist.indexOf(file.path) === -1
}).pipe(through.obj((file, _, next) => {
fs.unlink(file.fullPath);
next();
}, (finish) => {resolve(filesCopied); finish();})).on('error', reject);
});
});
};
var promise = rimraf(outputDir)
.then(compileAndCopy)
var promise =
readAndValidateShas()
.then(compileAndCopy)
.then(numFiles =>
fsp.writeFile(shasPath, JSON.stringify(shas, null, 2)).then(() => numFiles)
)
// TODO: Don't delete dir after abort. Leave as is instead.
.catch(function(err) {

@@ -218,4 +320,4 @@ // If there was an error then back out, delete the output dir and forward

{ bowerComponents: bowerComponents.exists }
)
})
}
);
});
};

6

package.json
{
"name": "baconize",
"version": "2.1.4",
"version": "2.2.0",
"description": "Compile static site for production (with sourcemaps), auto-compiles files like `app.coffee -> app.js`",
"main": "lib/index.js",
"scripts": {
"test": "mocha",
"test": "mocha --timeout 5000",
"example": "node examples/compile-site.js"

@@ -31,3 +31,3 @@ },

"dependencies": {
"baby-tolk": "^4.1.1",
"baby-tolk": "^4.5.0",
"checkdir": "^1.0.0",

@@ -34,0 +34,0 @@ "micromatch": "^2.3.11",

@@ -346,3 +346,3 @@ 'use strict';

before(clearDir);
after(clearDir);
// after(clearDir);

@@ -487,2 +487,172 @@ it('should compile compilable files and copy all others', function () {

describe('compile minified with sourcemaps (SHA test)', function() {
//
// before(clearDir);
after(clearDir);
before(() => {
// Mess up the dir a bit to make sure we recompile files as needed.
var styl = fs.readFile(getPathOut('styles/main.css'), 'utf8').then(content =>
fs.writeFile(getPathOut('styles/main.css'), content + ' ')
);
var html = fs.unlink(getPathOut('index.html'));
var randomFile = fs.writeFile(getPathOut('bla.html'), 'SHOULD BE REMOVED');
return when.all([styl, html, randomFile]);
});
it('should compile compilable files and copy all others', function () {
var options = {
blacklist: ['dont-compile/**'],
directoryFilter: ['!dont-copy'],
compile: true,
minify: true,
sourcemaps: true
};
var bacon = baconize(getPathIn(), getPathOut(), options);
var dirs = [];
bacon.events.on('chdir', function(dir) { dirs.push(dir); });
var compiledFiles = [];
var compilationReuseFiles = [];
var lastStartedFile;
bacon.events.on('compile-start', function(file) {
lastStartedFile = file.path;
});
bacon.events.on('compile-done', function(file) {
if (lastStartedFile === file.path) {
compiledFiles.push(file.path);
} else {
expect.fail('Unexpected compile-done event');
}
});
bacon.events.on('compile-reuse', function(file) {
compilationReuseFiles.push(file.path);
});
return bacon.then(function(num) {
return expect.promise.all([
expect(num, 'to be', 9),
expect(dirs, 'to contain', '', 'dont-compile', 'scripts', 'styles').and('to have length', 4),
expect(compiledFiles, 'to contain', 'index.jade', 'styles/main.styl').and('to have length', 2),
expect(compilationReuseFiles, 'to contain',
'about.html','scripts/log.babel.js', 'styles/typography.css',
'scripts/iterate.js', 'scripts/main.coffee').and('to have length', 5),
]);
});
});
describe('after compilation', function() {
it('should have all compiled files', function() {
return when.all([
fs.readFile(getPathOut('index.html')),
fs.readFile(getPathOut('styles/main.css')),
fs.readFile(getPathOut('scripts/main.js')),
fs.readFile(getPathOut('scripts/iterate.js')),
fs.readFile(getPathOut('about.html')),
fs.readFile(getPathOut('dont-compile/foo.coffee')),
fs.readFile(getPathOut('styles/typography.css'))
]).then(function(results) {
return expect.promise.all([
expect(results[0].toString(), 'to contain', 'saying \'hello\'.</p>'),
expect(results[1].toString(), 'to contain', 'body{'),
expect(results[2].toString(), 'to contain', 'console.log("H'),
expect(results[3].toString(), 'to contain', 'for(var stuff=[1,2,3,4,5]'),
expect(results[4].toString(), 'to contain', '<html><head>'),
expect(results[5].toString(), 'to contain', 'console.log "T'),
expect(results[6].toString(), 'to contain', 'font-family:arial}')
]);
});
});
it('should URL link to source maps', function() {
return when.all([
fs.readFile(getPathOut('styles/main.css')),
fs.readFile(getPathOut('scripts/main.js')),
fs.readFile(getPathOut('scripts/iterate.js')),
fs.readFile(getPathOut('styles/typography.css'))
]).then(function(results) {
return expect.promise.all([
expect(results[0].toString(), 'to contain', '/*# sourceMappingURL=main.css.map*/'),
expect(results[1].toString(), 'to contain', '//# sourceMappingURL=main.js.map'),
expect(results[2].toString(), 'to contain', '//# sourceMappingURL=iterate.js.map'),
expect(results[3].toString(), 'to contain', '/*# sourceMappingURL=typography.css.map*/')
]);
});
});
it('should have source maps', function() {
return when.all([
fs.readFile(getPathOut('styles/main.css.map')),
fs.readFile(getPathOut('scripts/main.js.map')),
fs.readFile(getPathOut('scripts/iterate.js.map')),
fs.readFile(getPathOut('styles/typography.css.map'))
]).then(function(results) {
return expect.promise.all([
expect(results[0].toString(), 'to contain', '"file":"main.css"')
.and('to contain', '"sources":["main.styl"]'),
expect(results[1].toString(), 'to contain', '"file":"main.js"')
.and('to contain', '"sources":["main.coffee"]'),
expect(results[2].toString(), 'to contain', '"file":"iterate.js"')
.and('to contain', '"sources":["iterate.src.js"]'),
expect(results[3].toString(), 'to contain', '"file":"typography.css"')
.and('to contain', '"sources":["typography.src.css"]'),
]);
});
});
it('should copy pre-compiled source files', function() {
return when.all([
fs.readFile(getPathOut('index.jade')),
fs.readFile(getPathOut('about.src.html')),
fs.readFile(getPathOut('scripts/iterate.src.js')),
fs.readFile(getPathOut('styles/typography.src.css'))
]).then(function(results) {
return expect.promise.all([
expect(results[0].toString(), 'to contain', 'html(lang="en")'),
expect(results[1].toString(), 'to contain', ' <meta charset="utf-8">'),
expect(results[2].toString(), 'to contain', 'for (var i = 0; i < stuff.length; i++) {'),
expect(results[3].toString(), 'to contain', ' font-family: arial;')
]);
});
});
it('should not compile blacklist matches', function() {
return fs.readFile(getPathOut('dont-compile/foo.js'))
.then(function() {
return expect.fail('`dont-compile/foo.js` should not be copied');
}, function(err) {
return expect(err.code, 'to be', 'ENOENT');
});
});
it('should not copy ignore paths', function() {
return fs.stat(getPathOut('dont-copy'))
.then(function() {
return expect.fail('`dont-copy` directory should not be copied');
}, function(err) {
return expect(err.code, 'to be', 'ENOENT');
});
});
it('should remove files that weren\'t in src dir', function() {
return fs.readFile(getPathOut('bla.html'))
.then(function() {
return expect.fail(
'`bla.html` should *not* be copied because it\'s not in src directory'
);
}, function(err) {
return expect(err.code, 'to be', 'ENOENT');
});
});
});
});
describe('aborted compile', function() {

@@ -489,0 +659,0 @@

Sorry, the diff of this file is not supported yet

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