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

hashly

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hashly - npm Package Compare versions

Comparing version 0.4.4 to 0.4.5

lib/map-processor.js

6

lib/cli.js

@@ -40,4 +40,4 @@ var path = require("path");

var args = minimist(argv.slice(2), {
"boolean": ["verbose", "clean", "ignore-errors", "help", "skip-css", "amend", "quickhash", "ignore-plugin-errors"],
"string": ["exclude", "include", "manifest-format", "manifest-path", "plugins", "clean-old", "base-dir", "passthrough", "disabled-plugins"],
"boolean": ["verbose", "clean", "ignore-errors", "help", "skip-css", "amend", "quickhash", "ignore-plugin-errors", "skip-map"],
"string": ["exclude", "include", "manifest-format", "manifest-path", "plugins", "clean-old", "base-dir", "passthrough", "disabled-plugins", "sourcemap-url-prefix"],
"alias": {

@@ -85,2 +85,3 @@ "verbose": "v",

processCss: !args["skip-css"],
processMap: !args["skip-map"],
quickhash: args["quickhash"],

@@ -90,2 +91,3 @@ amend: args["amend"],

baseDir: args["base-dir"],
sourcemapURLPrefix: args["sourcemap-url-prefix"] || "",
disabledPlugins: args["disabled-plugins"] ? args["disabled-plugins"].split(";") : null

@@ -92,0 +94,0 @@ };

@@ -32,3 +32,2 @@ "use strict";

};
exports.recurseDirSync = recurseDirSync;

@@ -35,0 +34,0 @@

@@ -10,2 +10,3 @@ "use strict";

var cssProcessor = require("./css-processor");
var mapProcessor = require("./map-processor");
var hashcodeGenerator = require("./hashcode-generator");

@@ -16,4 +17,4 @@

var getManifestPath = function (directory, serializer) {
var getManifestPath = function(directory, serializer) {
// If the manifest path is declared explicitly,

@@ -28,3 +29,3 @@ // use it and ignore the rest of the rules.

var compare = function (a, b) {
var compare = function(a, b) {
if (a < b) {

@@ -41,9 +42,9 @@ return -1;

// and returns a structure with this data
var createManifestEntry = function (fullPath, basePath, targetBasePath, data, hashCode) {
var relativePath = path.relative(basePath, fullPath);
var targetPath = path.resolve(targetBasePath, relativePath);
var createManifestEntry = function(fullPath, baseDir, targetBaseDir, data, hashCode) {
var relativePath = path.relative(baseDir, fullPath);
var targetPath = path.resolve(targetBaseDir, relativePath);
var targetDir = path.dirname(targetPath);
var hashCodeCoalesced = hashCode || hashcodeGenerator.generateForFile(fullPath, _options.quickhash);
var hashedPathPhysical = hashpattern.getHashedFileName(fullPath, targetDir, hashCodeCoalesced);
var hashedPath = path.relative(targetBasePath, hashedPathPhysical);
var hashedPath = path.relative(targetBaseDir, hashedPathPhysical);

@@ -62,12 +63,11 @@ var manifestEntry = {

var createManifestEntryCss = function (fullPath, basePath, targetDir, data) {
var processImagePath = function (virtualPath) {
var createManifestEntryCss = function(fullPath, baseDir, targetDir, data) {
var getHashedPath = function(virtualPath) {
var isRootRelative = virtualPath[0] == "/";
var imagePhysicalPath = isRootRelative ?
path.join(basePath, virtualPath) :
var physicalPath = isRootRelative ?
path.join(baseDir, virtualPath) :
path.resolve(path.dirname(fullPath), virtualPath);
var imageEntry = processEntry(imagePhysicalPath, basePath, targetDir, data);
if (!imageEntry) {
var entry = processEntry(physicalPath, baseDir, targetDir, data);
if (!entry) {
return virtualPath;

@@ -77,11 +77,10 @@ }

if (!isRootRelative) {
return path.relative(path.dirname(fullPath), imageEntry.hashedPathPhysical);
return path.relative(path.dirname(fullPath), entry.hashedPathPhysical);
}
return imageEntry.hashedPath;
return entry.hashedPath;
};
var transformedCssText = cssProcessor.processCss(fsutil.readFileSync(fullPath, "utf8"), processImagePath);
var transformedCssText = cssProcessor.processCss(fsutil.readFileSync(fullPath, "utf8"), getHashedPath);
var entry = createManifestEntry(fullPath, basePath, targetDir, data, hashcodeGenerator.generate(transformedCssText));
var entry = createManifestEntry(fullPath, baseDir, targetDir, data, hashcodeGenerator.generate(transformedCssText));

@@ -93,11 +92,11 @@ entry.transformedText = transformedCssText;

var createAndAugmentManifestEntry = function (fullPath, basePath, targetDir, data) {
var createAndAugmentManifestEntry = function(fullPath, baseDir, targetDir, data, hashCode) {
// Special case: image paths in CSS files need to be replaced with their hashed versions
var ext = path.extname(fullPath);
var createManifestEntryMethod = (_options.processCss && ext == ".css") ? createManifestEntryCss : createManifestEntry;
var entry = createManifestEntryMethod(fullPath, basePath, targetDir, data);
var entry = createManifestEntryMethod(fullPath, baseDir, targetDir, data, hashCode);
// If plugins are present, give them a change to add data to the manifest entry
if (_options.plugins) {
_options.plugins.forEach(function (plugin) {
_options.plugins.forEach(function(plugin) {
try {

@@ -120,3 +119,3 @@ var pluginData = plugin.processFile(entry);

}
return entry;

@@ -126,7 +125,11 @@ };

var isDescendent = function (childPath, baseDir) {
// Should be case insensitive on windows
var isDescendent = function(childPath, baseDir) {
// Should be case insensitive on windows
var preprocess = /^win/.test(process.platform) ?
function (p) { return p.toLowerCase(); } :
function (p) { return p; };
function(p) {
return p.toLowerCase();
} :
function(p) {
return p;
};

@@ -136,4 +139,4 @@ return preprocess(childPath).indexOf(preprocess(baseDir)) === 0;

var processEntry = function (fullPath, baseDir, targetDir, data) {
var processEntry = function(fullPath, baseDir, targetDir, data) {
var ext = path.extname(fullPath);
// See if an existing entry exists in the cache

@@ -156,7 +159,5 @@ var existingEntry = data.lookupMap[fullPath];

// Apply filters to exclude files if specified
if (_options.shouldBeExcluded) {
if (_options.shouldBeExcluded(fullPath)) {
return;
}
// Ignore map files, we check each css and js file for accompaning map file
if (ext === ".map") {
return;
}

@@ -166,3 +167,2 @@

if (_options.isPassthrough && _options.isPassthrough(fullPath)) {
// Passthrough means to simply copy file to the destination path, without labeling it with a hashcode or

@@ -174,7 +174,26 @@ // including in the manifest.

return null;
}
else {
var entry = createAndAugmentManifestEntry(fullPath, baseDir, targetDir, data);
} else {
// Improve map files to have the hashed filepath in their source (instead of unhashed filepath) - useful for debugging
// Note: assuming map files are in the same dir as js/css file and they end with .map
var mapFullPath = fullPath + ".map";
var transformedText = null,
hashCode = null;
if (_options.processMap && fsutil.existsSync(mapFullPath)) {
var mapEntry = createAndAugmentManifestEntry(mapFullPath, baseDir, targetDir, data);
fsutil.copySync(mapFullPath, mapEntry.hashedPathPhysical);
if (_options.logger) {
_options.logger(mapFullPath + " > " + mapEntry.hashedPathPhysical);
}
// The sourcemap filename has changed, so update the minified js/css file and replace unhashed filename with hashed one
// This is done to support zero downtime deployment when two different releases are out at once
transformedText = mapProcessor.processMinFile(ext, fsutil.readFileSync(fullPath, "utf8"), mapEntry.hashedPath, _options.sourcemapURLPrefix);
if (transformedText) {
hashCode = hashcodeGenerator.generate(transformedText);
}
}
// use the generated hashcode for the transformed text to create manifest entry
var entry = createAndAugmentManifestEntry(fullPath, baseDir, targetDir, data, hashCode);
if (_options.logger) {

@@ -184,2 +203,3 @@ _options.logger(fullPath + " > " + entry.hashedPathPhysical);

// If the existing entry is already correct, we can skip the rest.

@@ -194,5 +214,5 @@ if (existingEntry && existingEntry.unverified) {

// Copy the original file to the hashed path
if (entry.transformedText) {
fsutil.writeFileSync(entry.hashedPathPhysical, entry.transformedText, "utf8");
delete entry.transformedText;
if (transformedText) {
fsutil.writeFileSync(entry.hashedPathPhysical, transformedText, "utf8");
transformedText = null;
} else {

@@ -209,3 +229,2 @@ fsutil.copySync(entry.pathPhysical, entry.hashedPathPhysical);

data.lookupMap[fullPath] = entry;
return entry;

@@ -224,2 +243,4 @@ }

_options.logError(msg);
_options.logError();
_options.logError(ex);
}

@@ -234,3 +255,3 @@

// to their target locations.
var createManifest = function (files, baseDir, targetDir, existingManifestData) {
var createManifest = function(files, baseDir, targetDir, existingManifestData) {

@@ -247,3 +268,3 @@ var data = {

if (existingManifestData) {
existingManifestData.forEach(function (entry) {
existingManifestData.forEach(function(entry) {
entry.unverified = true;

@@ -256,3 +277,5 @@ // Populate the lookup map so we can find the entry quickly.

files.forEach(function (fullPath) {
files.filter(function(fullPath) {
return (_options.shouldBeExcluded) ? !_options.shouldBeExcluded(fullPath) : true;
}).map(function(fullPath) {
processEntry(fullPath, baseDir, targetDir, data);

@@ -264,7 +287,7 @@ });

var unixifyPath = function (filePath) {
var unixifyPath = function(filePath) {
return filePath.replace(/\\/g, "/");
};
var processFilter = function (filters, baseDir) {
var processFilter = function(filters, baseDir) {
if (!filters) {

@@ -278,3 +301,3 @@ return null;

return function (filePath) {
return function(filePath) {

@@ -292,3 +315,3 @@ var relativeFilePath = path.relative(baseDir, filePath);

var initOptions = function (options, baseDir, targetDir) {
var initOptions = function(options, baseDir, targetDir) {
// Store global options.

@@ -298,3 +321,4 @@ // This is to prevent having to pass around data for cross-cutting concerns (i.e. logging)

_options = options || {};
_options.sourcemapURLPrefix = options.sourcemapURLPrefix || "";
_options.processMap = options.processMap || true;
// If the passthrough option has been specified, add it to the inclusion filter to make sure

@@ -319,5 +343,5 @@ // we have a chance to process the file. This only makes sense if we are writing content

var excludeFilters = processFilter(_options.exclude, baseDir);
_options.shouldBeExcluded = function (filePath) {
_options.shouldBeExcluded = function(filePath) {
if (excludeFilters && excludeFilters(filePath)) {

@@ -339,3 +363,3 @@ return true;

var handleError = function (ex) {
var handleError = function(ex) {
if (!ex.wasLogged) {

@@ -358,3 +382,3 @@ if (_options.logError) {

// location in targetDir. Creates a manifest json file that documents all the transformations.
exports.processFiles = function (files, baseDir, targetDir, options) {
exports.processFiles = function(files, baseDir, targetDir, options) {

@@ -393,3 +417,3 @@ if (!files) {

existingManifestData = serializer.parse(fsutil.readFileSync(manifestPath, "utf8"));
existingManifestData.forEach(function (entry) {
existingManifestData.forEach(function(entry) {
entry.pathPhysical = baseDir + entry.path;

@@ -406,3 +430,3 @@ entry.hashedPathPhysical = targetDir + entry.hashedPath;

// Remove the manifest itself from the list of files to process
files = files.filter(function (f) {
files = files.filter(function(f) {
return f != manifestPath;

@@ -424,3 +448,3 @@ });

// be deployed to a web server at a different physical path.
var trimmedManifest = manifestData.manifest.map(function (entry) {
var trimmedManifest = manifestData.manifest.map(function(entry) {

@@ -436,3 +460,3 @@ var newEntry = util._extend(entry);

trimmedManifest.sort(function (a, b) {
trimmedManifest.sort(function(a, b) {
return compare(a.path, b.path);

@@ -465,21 +489,21 @@ });

// location in targetDir. Creates a manifest json file that documents all the transformations.
exports.processDirectory = function (sourceDir, targetDir, options) {
exports.processDirectory = function(sourceDir, targetDir, options) {
var files = [];
fsutil.recurseDirSync(sourceDir, function (file) {
fsutil.recurseDirSync(sourceDir, function(file) {
files.push(file);
});
if (options.baseDir) {
if (!isDescendent(sourceDir, options.baseDir)) {
throw new Error("The source directory '" + sourceDir + "' is not in the base directory: '" + options.baseDir + "'");
}
// Adjust sourceDir so full paths relative to the base folder will be written to the manifest.
sourceDir = options.baseDir;
}
if (options.baseDir) {
if (!isDescendent(sourceDir, options.baseDir)) {
throw new Error("The source directory '" + sourceDir + "' is not in the base directory: '" + options.baseDir + "'");
}
// Adjust sourceDir so full paths relative to the base folder will be written to the manifest.
sourceDir = options.baseDir;
}
return exports.processFiles(files, sourceDir, targetDir, options);
};
var deleteFileSync = function (filePath) {
var deleteFileSync = function(filePath) {
if (_options.logger) {

@@ -492,3 +516,3 @@ _options.logger("Deleting " + filePath + "...");

exports.clean = function (directory, options) {
exports.clean = function(directory, options) {

@@ -507,3 +531,3 @@ initOptions(options, directory);

fsutil.recurseDirSync(directory, function (filePath) {
fsutil.recurseDirSync(directory, function(filePath) {

@@ -516,3 +540,3 @@ if (hashpattern.isHashedFile(filePath)) {

exports.cleanOld = function (directory, options) {
exports.cleanOld = function(directory, options) {

@@ -533,3 +557,3 @@ initOptions(options, directory);

var entries = serializer.parse(fsutil.readFileSync(manifestPath, "utf8"));
entries.forEach(function (entry) {
entries.forEach(function(entry) {
fileSet[directory + entry.hashedPath] = true;

@@ -542,3 +566,3 @@ });

fsutil.recurseDirSync(directory, function (filePath) {
fsutil.recurseDirSync(directory, function(filePath) {
if (hashpattern.isHashedFile(filePath)) {

@@ -548,3 +572,3 @@ if (fileSet[filePath]) {

}
if (options.cleanOldDays > 0) {

@@ -551,0 +575,0 @@ var stat = fsutil.statSync(filePath);

{
"name": "hashly",
"version": "0.4.4",
"version": "0.4.5",
"description": "Renames static files with a hashcode for cache busting",

@@ -5,0 +5,0 @@ "directories": {

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