funcunit
Version:
<!-- @hide title
244 lines (205 loc) • 5.14 kB
JavaScript
/**
* Naming bundles
*
* for naming rules see .md file
*/
var crypto = require('crypto');
var npmNameExp = /.+@.+#.+/;
/**
* is a npm module name?
* do not support npm scoping!
*
* @param name
* @returns {boolean}
*/
function isNpm(name) {
return npmNameExp.test(name);
}
/**
* get the path of a npm module
* {packagename}@{version}#{path}
*
* @param name
* @returns {{package: string, version: string, path: string}}
*/
function deNpm(name) {
var modulePackage = name.substr(0, name.indexOf("@"));
var moduleVersion = name.substring(name.indexOf("@")+1, name.indexOf("#"));
var modulePath = removeFiletype(name.substr(name.indexOf("#")+1));
return {
'package': modulePackage,
'version': moduleVersion,
'path': modulePath
};
}
/**
* remove the filetype from a
*
* @param modulePath
* @returns {*}
*/
var removeFiletype = function(modulePath) {
if(modulePath.lastIndexOf('.') !== -1) {
modulePath = modulePath.substr(0, modulePath.lastIndexOf('.'));
}
return modulePath;
};
/**
* get the last part of a module path
* if a npm package is provided
* e.g.
* main/bar/foo => foo
* packagename@1.0.0#foo/bar => bar
*
* @param uri
* @returns {string}
*/
var filename = function (uri) {
var lastSlash = uri.lastIndexOf("/");
var sub;
if (lastSlash == -1) {
sub = uri;
} else {
sub = uri.substr(lastSlash + 1);
}
var matches = deNpm(sub.toLowerCase()).path.match(/^[\w-\s\.]+/);
return matches ? matches[0] : "";
};
/**
* return the plugin part
*
* @param name
* @returns {string}
*/
var pluginPart = function (name) {
var bang = name.lastIndexOf("!");
if (bang !== -1) {
return name.substr(bang + 1);
}
};
/**
* return the plugin resource
*
* @param name
* @returns {string}
*/
var pluginResource = function (name) {
var bang = name.lastIndexOf("!");
if (bang !== -1) {
return name.substr(0, bang);
}
};
/**
*
* @param bundle
* @returns {string}
*/
function makeGetName() {
var bundleCounter = 0;
var usedBundleNames = {};
if(arguments.length === 1){
return getName(arguments[0]);
}else{
return getName;
}
/**
* get a unique name, based on bundleCounter
*
* @param dirName
* @param shortened
* @param buildTypeSuffix
* @returns {string}
*/
function getUniqueName(dirName, shortened, buildTypeSuffix) {
if (!usedBundleNames[dirName + shortened + buildTypeSuffix]) {
return dirName + shortened + buildTypeSuffix + "";
}else {
return dirName + shortened + "-" + (bundleCounter++) + buildTypeSuffix + "";
}
}
/**
* get the name of a bundle
*
* @param bundle
* @returns {string}
*/
function getName(bundle) {
/**
* add a prototype method to String
*
* @param whatever
* @returns {string}
*/
if(!String.prototype.removeTrailing) {
String.prototype.removeTrailing = function (whatever) {
var result = this;
if (this.substr((-1 * whatever.length)) === whatever) {
result = this.substr(0, this.length - (1 * whatever.length));
}
return result + "";
};
}
var dirName = "bundles/",
shortened,
bundleName;
// remove trailing and leading parts
var bundleNames = bundle.bundles.map(function(appName){
appName = appName.trim().removeTrailing('/');
return appName;
});
// If this is a "main" bundle
if (bundle.bundles.length === 1) {
// main module
shortened = bundleNames[0];
if(pluginPart(shortened)) {
shortened = pluginResource(shortened);
}
// for the shortened we only want the path of the module
if(isNpm(shortened)) {
var module = deNpm(shortened);
shortened = module.path;
dirName += module.package + "/";
// no npm module !
}else{
shortened = removeFiletype(shortened);
}
// if multiple bundles and very long concatenated name
} else if (bundle.bundles.length > 1) {
// concat multiple bundles into one shortened filename,
// for that use only the last part of each modulepath
shortened = bundleNames.map(function(l){
return filename(l);
}).join('-');
// we dont care about naming rules
// we add the bundles into the bundles config
shortened = shortened.replace(/[^\w\-_]/g, "-").replace(/-{2,}/g, '-');
if(shortened.length > 25) {
var hasher = crypto.createHash("md5");
hasher.update(shortened);
var shortenedHash = hasher.digest('hex');
shortened = shortened.substr(0, 16) + "-" + shortenedHash.substr(0, 8);
}
}
var buildType = bundle.buildType || "js",
buildTypeSuffix = buildType === "js" ? "" : "."+buildType+"!";
// delete the String prototype method
delete String.prototype.removeTrailing;
if(bundle.bundles.length === 1) {
// we dont want do rewrite a main module
bundleName = dirName + shortened + buildTypeSuffix;
} else {
bundleName = getUniqueName(dirName, shortened, buildTypeSuffix);
}
usedBundleNames[bundleName] = true;
return bundleName;
}
}
exports = module.exports = function(bundles) {
var getName = makeGetName();
bundles.forEach(function(bundle){
bundle.name = getName(bundle);
});
};
exports.getName = function(bundle) {
return makeGetName(bundle);
};