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

express-compiless

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-compiless - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

94

lib/index.js
var Path = require('path'),
less = require('less');
crypto = require('crypto'),
fs = require('fs'),
less = require('less'),
seq = require('seq'),
passError = require('passerror'),
importRegExp = /(@import(?:\s*'.*?'|\s*".*?"|\s+url\((?:[^'"]*?|'[^']*'|"[^"]*")\));)/,
importRegExpWithCaptures = /@import(?:\s*(['"])(.*?)\1|\s+url\((['"]|)(.*?)\3\));/;
require('express-hijackresponse');
// Returns flattened less text, accumulates seen files in the isSeenByFileName object provided by the caller.
function resolveImports(lessText, baseDir, isSeenByFileName, cb) {
seq(lessText.split(importRegExp))
.parMap(function (chunk) {
var cb = this,
matchImport = chunk.match(importRegExpWithCaptures);
if (matchImport) {
var importedFileName = Path.resolve(baseDir.replace(/\/*$/, '/'), matchImport[2] || matchImport[4]);
isSeenByFileName[importedFileName] = true;
fs.readFile(importedFileName, 'utf-8', passError(cb, function (importedLessText) {
resolveImports(importedLessText, Path.dirname(importedFileName), isSeenByFileName, passError(cb, function (lessText) {
cb(null, lessText);
}));
}));
} else {
this(null, chunk);
}
})
.seq(function () {
cb(null, this.stack.join(''));
});
}
module.exports = function compiless(options) {

@@ -32,12 +62,2 @@ if (!options || !options.root) {

// won't reply with a false positive 304 on the same URL after compiless has been enabled or disabled:
var oldETag = res.getHeader('ETag');
if (oldETag) {
var newETag = '"' + oldETag.replace(/^"|"$/g, '') + '-compiless"';
res.setHeader('ETag', newETag);
if (ifNoneMatch && ifNoneMatch.indexOf(newETag) !== -1) {
return res.send(304);
}
}
var chunks = [];

@@ -54,13 +74,45 @@ res.on('error', function () {

var lessText = Buffer.concat(chunks).toString('utf-8'), // No other charsets are really relevant, right?
baseDir = Path.resolve(options.root, req.url.replace(/\/[^\/]*(?:\?.*)?$/, '/').substr(1));
baseDir = Path.resolve(options.root, req.url.replace(/\/[^\/]*(?:\?.*)?$/, '/').substr(1)),
isSeenByFileName = {};
// Unfortunately less.render throws errors in async code instead of passing it to our callback.
// Hopefully the solution for https://github.com/cloudhead/less.js/issues/462 will remedy this.
less.render(lessText, {paths: [baseDir]}, function (err, cssText) {
if (err) {
return res.send(500);
}
res.setHeader('Content-Type', 'text/css');
res.setHeader('Content-Length', Buffer.byteLength(cssText));
res.end(cssText);
resolveImports(lessText, baseDir, isSeenByFileName, function (err, flattenedLessText) {
seq(Object.keys(isSeenByFileName))
.parEach(function (fileName) {
fs.stat(fileName, this.into(fileName));
})
.unflatten()
.seq(function (fileNames) {
var oldETag = res.getHeader('ETag');
if (oldETag) {
var etagFragments = [oldETag.replace(/^"|"$/g, '')];
if (fileNames.length) {
var importedFileStats = [];
fileNames.sort().forEach(function (fileName) {
var stats = this.vars[fileName];
importedFileStats.push(fileName, String(stats.mtime.getTime()), String(stats.size));
}, this);
etagFragments.push(crypto.createHash('md5').update(importedFileStats.join('-')).digest('hex').substr(0, 16));
}
var newETag = '"' + etagFragments.join('-') + '-compiless"';
res.setHeader('ETag', newETag);
if (ifNoneMatch && ifNoneMatch.indexOf(newETag) !== -1) {
return res.send(304);
}
}
// Unfortunately less.render throws errors in async code instead of passing it to our callback.
// Hopefully the solution for https://github.com/cloudhead/less.js/issues/462 will remedy this.
less.render(lessText, {paths: [baseDir]}, function (err, cssText) {
if (err) {
return res.send(500);
}
cssText = fileNames.map(function (fileName) {
return "/*@IMPORTED:" + Path.relative(options.root, fileName) + "*/\n";
}).join("") + cssText;
res.setHeader('Content-Type', 'text/css');
res.setHeader('Content-Length', Buffer.byteLength(cssText));
res.end(cssText);
});
});
});

@@ -67,0 +119,0 @@ });

{
"name": "express-compiless",
"version": "0.0.4",
"version": "0.0.5",
"description": "Express middleware that compiles less files to css on the way out.",

@@ -25,3 +25,4 @@ "main": "lib/index.js",

"less": "=1.3.0",
"passerror": "=0.0.1"
"passerror": "=0.0.1",
"seq": "=0.3.5"
},

@@ -28,0 +29,0 @@ "devDependencies": {

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