2
0
Fork 0

redone with objects

This commit is contained in:
Willem 2015-02-27 01:25:57 +01:00
parent 8bb333ae8d
commit 3f580bbe2d
12 changed files with 725 additions and 400 deletions

1
.jshintignore Normal file
View file

@ -0,0 +1 @@
node_modules

38
.jshintrc Normal file
View file

@ -0,0 +1,38 @@
{
"predef": [
"before",
"after",
"it",
"describe",
"beforeEach",
"afterEach"
],
"asi" : false,
"bitwise" : true,
"boss" : false,
"curly" : true,
"debug": false,
"devel": false,
"eqeqeq": true,
"evil": false,
"expr": true,
"forin": false,
"immed": true,
"latedef" : false,
"laxbreak": false,
"multistr": true,
"newcap": true,
"noarg": true,
"node" : true,
"noempty": false,
"nonew": true,
"onevar": false,
"plusplus": false,
"proto": true,
"regexp": false,
"strict": false,
"sub": false,
"trailing" : true,
"undef": true,
"unused": true
}

397
index.js
View file

@ -1,397 +0,0 @@
var NodeFsExtra = require('fs-extra');
var NodeMinify = require('minify');
var NodeEvents = require('events');
var NodeFetch = require('fetch');
var NodeFs = require('fs');
var DEFAULT_DOWNLOAD_MAX_SIZE = (1024*1024) * 10; // 10mb
var DEFAULT_DOWNLOAD_TIMEOUT = (1000*60) * 1; // 1min
var DEFAULT_OPTIONS = {
downloadStartDelay: null,
downloadForce: false,
downloadOptions: {
timeout: DEFAULT_DOWNLOAD_TIMEOUT,
maxResponseLength: DEFAULT_DOWNLOAD_MAX_SIZE,
agent: 'node-ff-assets asset fetcher'
},
linkTargetSingleResult: true,
linkTarget: null,
linkSources: [],
linkMapping: [],
assetHeader: '\n/* node-ff-assets: begin */\n\n',
assetFooter: '\n/* node-ff-assets: end */\n\n',
assetSeperator: '\n/* node-ff-assets: next */\n',
}
function ResourceBuilder(config, readFile) {
this.config = config;
this.startTime = 0;
this.readFile = readFile || FunctionFactory.Constructor.readFile();
NodeEvents.EventEmitter.call(this);
this.run = function(callback) {
configCheckSync(this.config);
configDefaultsSync(this.config);
runBuildSafe(this, this.readFile, callback);
};
}
ResourceBuilder.prototype.__proto__ = NodeEvents.EventEmitter.prototype;
var FunctionFactory = {
Constructor: {
readFile: function() {
return function(file,callback) {
NodeFs.readFile(file, function(err, data) {
if (err) {
callback(err);
} else {
callback(null, data);
}
});
};
},
readFileMinify: function(options) {
if (options == null) {
options = {};
}
return function(file, callback) {
NodeMinify(file, options, function(err, data) {
if (err) {
callback(err);
} else {
callback(null, data);
}
});
};
},
},
Event: {
log: {
console: function(logType) {
if (logType == null) {
throw Error('no logType');
}
return function(logLevel, logMessage) {
console.log(logLevel+': node-ff-assets-'+logType+' '+logMessage);
};
},
},
result: {
objectFunction: function(object, functionName, resultKey) {
if (object == null) {
throw Error('no object');
}
if (functionName == null) {
throw Error('no functionName');
}
return function(resultValue) {
if (resultKey == null) {
object[functionName](resultValue);
} else {
object[functionName](resultKey, resultValue);
}
};
},
objectAdd: function(object,resultKey) {
return FunctionFactory.Event.result.objectFunction(object,'add',resultKey);
},
objectSet: function(object,resultKey) {
return FunctionFactory.Event.result.objectFunction(object,'set',resultKey);
},
objectPut: function(object,resultKey) {
return FunctionFactory.Event.result.objectFunction(object,'put',resultKey);
},
arrayPush: function(object,resultKey) {
return FunctionFactory.Event.result.objectFunction(object,'push');
},
}
}
}
function configCheckSync(config) {
if (!config) {
throw Error('no config');
}
if (!config.linkTarget) {
throw Error('no config.linkTarget');
}
if (!config.linkSources) {
throw Error('no config.linkSources');
}
if (!config.linkMapping) {
throw Error('no config.linkMapping');
}
}
function configDefaultsSync(config) {
if (config.downloadOptions == null) {
config.downloadOptions = DEFAULT_OPTIONS.downloadOptions;
}
if (config.assetHeader == null) {
config.assetHeader = DEFAULT_OPTIONS.assetHeader;
}
if (config.assetFooter == null) {
config.assetFooter = DEFAULT_OPTIONS.assetFooter;
}
if (config.assetSeperator == null) {
config.assetSeperator = DEFAULT_OPTIONS.assetSeperator;
}
}
function runBuildSafe(builder, readFile, callback) {
runBuild(builder, readFile, function(err) {
// send error
if (err) {
builder.emit('error',err);
}
// finish callback
if (callback != null) {
callback(err);
}
});
}
function runBuild(builder, readFile, callback) {
if (builder.config.downloadStartDelay) {
setTimeout(function() {
buildStart(builder, readFile, callback);
}, builder.config.downloadStartDelay);
} else {
buildStart(builder, readFile, callback);
}
}
function buildStart(builder, readFile, callback) {
builder.startTime = new Date().getTime();
builder.emit('begin');
builder.emit('log','info','build begin for: '+builder.config.linkTarget);
if (builder.config.downloadForce) {
builder.emit('log','info','build using forced downloads.');
}
var targetFile = mapLocalFileSync(builder, builder.config.linkTarget);
NodeFsExtra.ensureFile(targetFile, function (err) {
if (err) {
callback(err);
} else {
builder.emit('file-write-pre',targetFile);
NodeFsExtra.writeFile(targetFile, builder.config.assetHeader, function(err) {
if (err) {
callback(err);
} else {
buildAsset(builder, targetFile, readFile, callback);
}
});
}
});
}
function buildAsset(builder, targetFile, readFile, callback) {
var uriList = builder.config.linkSources;
var localFileList = [];
var resultUriList = [];
var downloadList = [];
for (i = 0; i < uriList.length; i++) {
var assetItem = uriList[i];
var remoteUrl = null;
var remoteForce = null;
var remoteIndex = assetItem.indexOf('@');
if (remoteIndex > 0) {
remoteUrl = assetItem.substring(remoteIndex + 1);
if (remoteUrl.indexOf('@') == 0) {
remoteUrl = assetItem.substring(remoteIndex + 2);
remoteForce = true;
}
assetItem = assetItem.substring(0,remoteIndex);
}
var localFile = mapLocalFileSync(builder, assetItem);
// override force on all files
if (remoteForce==null && builder.config.downloadForce != null) {
remoteForce = builder.config.downloadForce;
}
if (remoteUrl && (remoteForce || !NodeFs.existsSync(localFile))) {
downloadList.push({
remoteUrl: remoteUrl,
localFile: localFile
});
}
localFileList.push(localFile);
resultUriList.push(assetItem);
}
downloadList.reverse();
localFileList.reverse();
downloadFileList(builder, downloadList, function(error) {
if (error) {
callback(err);
} else {
//for(....
//if (!NodeFs.existsSync(localFile)) {
// Log.warn("illegal entry: "+localFile);
// continue;
//}
aggregateFileList(builder, targetFile, localFileList, readFile, function(err) {
if (err) {
callback(err);
} else {
buildEnd(builder, targetFile, resultUriList, callback);
}
});
}
});
}
function mapLocalFileSync(builder, linkSource) {
var uriMapping = builder.config.linkMapping;
if (uriMapping) {
uriMappingKeys = Object.keys(uriMapping);
uriMappingKeys.sort(function(a, b) {
return a.length < b.length; // longest first as we break on first hit
});
for (ii = 0; ii < uriMappingKeys.length; ii++) {
var uriKey = uriMappingKeys[ii];
var localPath = uriMapping[uriKey];
var mapIndex = linkSource.indexOf(uriKey);
if (mapIndex == 0) {
return localPath+linkSource.substring(uriKey.length);
}
}
}
return linkSource;
}
function downloadFileList(builder, downloadList, callback) {
if (downloadList.length == 0) {
callback();
return;
}
var download = downloadList.pop();
downloadFile(builder, download.remoteUrl, download.localFile, function(err) {
if (err) {
callback(err);
} else {
downloadFileList(builder, downloadList, callback);
}
});
}
function downloadFile(builder, remoteUrl, localFile, callback) {
builder.emit('file-download-pre',remoteUrl);
builder.emit('log','debug','downloadFile: '+remoteUrl);
NodeFsExtra.ensureFile(localFile, function(err) {
if (err) {
callback(err);
} else {
var stream = new NodeFetch.FetchStream(remoteUrl);
stream.on('error', function(err) {
callback(err);
});
stream.on('end', function() {
builder.emit('file-download-post',remoteUrl);
callback();
});
stream.pipe(NodeFs.createWriteStream(localFile));
}
});
}
function aggregateFileList(builder, targetFile, aggregateList, readFile, callback) {
if (aggregateList.length == 0) {
callback();
return;
}
var aggregateFile = aggregateList.pop();
builder.emit('file-read-pre',aggregateFile);
readFile(aggregateFile, function(err, data) {
if (err) {
callback(err);
} else {
builder.emit('file-read-post',aggregateFile);
builder.emit('log','debug','readFile: '+aggregateFile+' size: '+data.length);
if (aggregateList.length > 0) {
data = data + builder.config.assetSeperator;
}
NodeFs.appendFile(targetFile, data, function (err) {
if (err) {
callback(err);
} else {
aggregateFileList(builder, targetFile, aggregateList, readFile, callback);
}
});
}
});
}
function buildEnd(builder, targetFile, resultUriList, callback) {
NodeFs.appendFile(targetFile, builder.config.assetFooter, function (err) {
if (err) {
callback(err);
} else {
builder.emit('file-write-post',targetFile);
var buildTime = new Date().getTime() - builder.startTime;
var buildResultSize = +resultUriList.length;
if (builder.config.linkTargetSingleResult) {
resultUriList = [builder.config.linkTarget];
}
var targetStats = NodeFs.statSync(targetFile);
var targetSize = targetStats['size'];
builder.emit('log','debug','target size: '+targetSize);
builder.emit('log','info','build result size: '+resultUriList.length+' from: '+buildResultSize);
builder.emit('log','info','build done in: '+buildTime+' ms.');
builder.emit('result',resultUriList);
builder.emit('end');
callback();
}
});
}
function runBuilderList(builderList,callback) {
if (callback == null) {
callback = function(err) {
if(err) {
throw err; // mm
}
};
}
if (builderList.length == 0) {
callback();
return;
}
var builder = builderList.pop();
builder.run(function(err) {
if (err) {
callback(err);
} else {
runBuilderList(builderList,callback);
}
});
}
function runAll(builderList,callback) {
builderList.reverse();
runBuilderList(builderList,callback);
}
function pushLinkSourcesSync(builder, linkPrefix, fileFolder) {
NodeFs.readdirSync(fileFolder).forEach(function (file) {
if (~file.indexOf('.js') || ~file.indexOf('.css')) {
builder.linkSources.push(linkPrefix+file)
}
});
}
module.exports = {
ResourceBuilder: ResourceBuilder,
FunctionFactory: FunctionFactory,
runAll: runAll,
pushLinkSourcesSync: pushLinkSourcesSync,
}

View file

@ -0,0 +1,63 @@
'use strict';
var name = 'node-ff-assets';
var downloadTimeout = (1000*10) * 6; // 1min
var downloadMaxSize = (1024*1024) * 10; // 10mb
var template = {
downloadStartDelay: null,
downloadForce: false,
downloadOptions: {
timeout: downloadTimeout,
maxResponseLength: downloadMaxSize,
agent: name+' remote fetcher',
},
linkTargetSingleResult: true,
linkTarget: null,
linkSources: [],
linkMapping: [],
assetType: null,
assetHeader: '\n/* '+name+': begin */\n\n',
assetFooter: '\n/* '+name+': end */\n\n',
assetSeperator: '\n/* '+name+': next */\n',
};
function checkConfig(config,callback) {
if (!config) {
callback(new Error('no config'));
}
if (!config.linkTarget) {
callback(new Error('no config.linkTarget'));
}
if (!config.linkSources) {
callback(new Error('no config.linkSources'));
}
if (!config.linkMapping) {
callback(new Error('no config.linkMapping'));
}
callback();
}
function fillDefaults(config,callback) {
if (config.downloadOptions === undefined) {
config.downloadOptions = template.downloadOptions;
}
if (config.assetHeader === undefined) {
config.assetHeader = template.assetHeader;
}
if (config.assetFooter === undefined) {
config.assetFooter = template.assetFooter;
}
if (config.assetSeperator === undefined) {
config.assetSeperator = template.assetSeperator;
}
callback(null,config);
}
module.exports = {
template: template,
checkConfig: checkConfig,
fillDefaults: fillDefaults,
};

252
lib/asset-assembler.js Normal file
View file

@ -0,0 +1,252 @@
'use strict';
var events = require('events');
var fetch = require('fetch');
var fs = require('fs-extra');
var factory = require('./factory');
var config = require('./asset-assembler-config');
function buildEnd(builder, targetFile, resultUriList, callback) {
fs.appendFile(targetFile, builder.config.assetFooter, function (err) {
if (err) {
callback(err);
} else {
var buildTime = new Date().getTime() - builder.startTime,
buildResultSize = resultUriList.length,
targetStats = fs.statSync(targetFile),
targetSize = targetStats.size;
if (builder.config.linkTargetSingleResult) {
resultUriList = [builder.config.linkTarget];
}
builder.emit('file-write-post',targetFile);
builder.emit('log','debug','target size: '+targetSize);
builder.emit('log','info','build result size: '+resultUriList.length+' from: '+buildResultSize);
builder.emit('log','info','build done in: '+buildTime+' ms.');
builder.emit('result',resultUriList);
builder.emit('end');
callback();
}
});
}
function downloadFile(builder, remoteUrl, localFile, callback) {
builder.emit('file-download-pre',remoteUrl);
builder.emit('log','debug','downloadFile: '+remoteUrl);
fs.ensureFile(localFile, function(err) {
if (err) {
callback(err);
} else {
var stream = new fetch.FetchStream(remoteUrl);
stream.on('error', function(err) {
callback(err);
});
stream.on('end', function() {
builder.emit('file-download-post',remoteUrl);
callback();
});
stream.pipe(fs.createWriteStream(localFile));
}
});
}
function downloadFileList(builder, downloadList, callback) {
if (downloadList.length === 0) {
callback();
return;
}
var download = downloadList.pop();
downloadFile(builder, download.remoteUrl, download.localFile, function(err) {
if (err) {
callback(err);
} else {
downloadFileList(builder, downloadList, callback);
}
});
}
function aggregateFileList(builder, targetFile, aggregateList, readFile, callback) {
if (aggregateList.length === 0) {
callback();
return;
}
var aggregateFile = aggregateList.pop();
builder.emit('file-read-pre',aggregateFile);
readFile(aggregateFile, function(err, data) {
if (err) {
callback(err);
} else {
builder.emit('file-read-post',aggregateFile);
builder.emit('log','debug','readFile: '+aggregateFile+' size: '+data.length);
if (aggregateList.length > 0) {
data = data + builder.config.assetSeperator;
}
fs.appendFile(targetFile, data, function (err) {
if (err) {
callback(err);
} else {
aggregateFileList(builder, targetFile, aggregateList, readFile, callback);
}
});
}
});
}
function mapLocalFileSync(assembler, linkSource) {
var uriMapping = assembler.config.linkMapping;
if (uriMapping) {
var uriMappingKeys = Object.keys(uriMapping);
uriMappingKeys.sort(function(a, b) {
return a.length < b.length; // longest first as we break on first hit
});
for (var ii = 0; ii < uriMappingKeys.length; ii++) {
var uriKey = uriMappingKeys[ii];
var localPath = uriMapping[uriKey];
var mapIndex = linkSource.indexOf(uriKey);
if (mapIndex === 0) {
return localPath+linkSource.substring(uriKey.length);
}
}
}
return linkSource;
}
function buildAsset(builder, targetFile, readFile, callback) {
var uriList = builder.config.linkSources;
var localFileList = [];
var resultUriList = [];
var downloadList = [];
for (var i = 0; i < uriList.length; i++) {
var assetItem = uriList[i];
var remoteUrl = null;
var remoteForce = null;
var remoteIndex = assetItem.indexOf('@');
if (remoteIndex > 0) {
remoteUrl = assetItem.substring(remoteIndex + 1);
if (remoteUrl.indexOf('@') === 0) {
remoteUrl = assetItem.substring(remoteIndex + 2);
remoteForce = true;
}
assetItem = assetItem.substring(0,remoteIndex);
}
var localFile = mapLocalFileSync(builder, assetItem);
// override force on all files
if (remoteForce===undefined && builder.config.downloadForce !== undefined) {
remoteForce = builder.config.downloadForce;
}
if (remoteUrl && (remoteForce || !fs.existsSync(localFile))) {
downloadList.push({
remoteUrl: remoteUrl,
localFile: localFile
});
}
localFileList.push(localFile);
resultUriList.push(assetItem);
}
downloadList.reverse();
localFileList.reverse();
downloadFileList(builder, downloadList, function(err) {
if (err) {
callback(err);
} else {
//for(....
//if (!fs.existsSync(localFile)) {
// Log.warn("illegal entry: "+localFile);
// continue;
//}
aggregateFileList(builder, targetFile, localFileList, readFile, function(err) {
if (err) {
callback(err);
} else {
buildEnd(builder, targetFile, resultUriList, callback);
}
});
}
});
}
function buildStart(assembler, readFile, callback) {
assembler.startTime = new Date().getTime();
assembler.emit('begin');
assembler.emit('log','info','build begin for: '+assembler.config.linkTarget);
if (assembler.config.downloadForce) {
assembler.emit('log','info','build using forced downloads.');
}
var targetFile = mapLocalFileSync(assembler, assembler.config.linkTarget);
fs.ensureFile(targetFile, function (err) {
if (err) {
callback(err);
} else {
assembler.emit('file-write-pre',targetFile);
fs.writeFile(targetFile, assembler.config.assetHeader, function(err) {
if (err) {
callback(err);
} else {
buildAsset(assembler, targetFile, readFile, callback);
}
});
}
});
}
function runAssembler(assembler, readFile, callback) {
if (assembler.config.downloadStartDelay) {
setTimeout(function() {
buildStart(assembler, readFile, callback);
}, assembler.config.downloadStartDelay);
} else {
buildStart(assembler, readFile, callback);
}
}
function runAssemblerSafe(assembler, readFile, callback) {
runAssembler(assembler, readFile, function(err) {
// send error
if (err) {
assembler.emit('error',err);
}
// finish callback
if (callback !== undefined) {
callback(err);
}
});
}
function AssetAssembler(config, readFile) {
this.config = config;
this.startTime = 0;
this.readFile = readFile || factory.assembler.constructor.readFile();
events.EventEmitter.call(this);
}
AssetAssembler.prototype.__proto__ = events.EventEmitter.prototype;
AssetAssembler.prototype.run = function(callback) {
if (callback === undefined) {
throw new Error('no callback');
}
var self = this;
config.checkConfig(self.config,function(err) {
if (err) {
callback(err);
} else {
config.fillDefaults(self.config, function (err) {
if (err) {
callback(err);
} else {
runAssemblerSafe(self, self.readFile, callback);
}
});
}
});
};
module.exports = AssetAssembler;

View file

@ -0,0 +1,57 @@
'use strict';
var factory = require('./factory');
var template = {
buildOrder: ['css','js'],
configCreate: null,
configFill: factory.builder.configCreate.nop(),
assemblerCreate: factory.builder.assemblerCreate.readFile(),
assemblerFill: factory.builder.configCreate.nop(),
assets: {
js: {
configCreate: null,
configFill: null,
assemblerCreate: null,
assemblerFill: null,
},
css: {
configCreate: null,
configFill: null,
assemblerCreate: null,
assemblerFill: null,
},
},
};
function checkConfig(config,callback) {
if (!config) {
callback(new Error('no config'));
}
// TODO: add more
callback();
}
function fillDefaults(config,callback) {
if (config.buildOrder === undefined) {
config.buildOrder = Object.keys(config.assets);
}
if (config.configFill === undefined) {
config.configFill = template.configFill;
}
if (config.assemblerCreate === undefined) {
config.assemblerCreate = template.assemblerCreate;
}
if (config.assemblerFill === undefined) {
config.assemblerFill = template.assemblerFill;
}
callback();
}
module.exports = {
template: template,
checkConfig: checkConfig,
fillDefaults: fillDefaults,
};

115
lib/assets-builder.js Normal file
View file

@ -0,0 +1,115 @@
'use strict';
var events = require('events');
var async = require('async');
var config = require('./assets-builder-config');
function buildStepAssemblerRun(builder, buildConfig, assembler, callback) {
assembler.run(callback);
}
function buildStepAssemblerFill(builder, buildConfig, assembler, callback) {
var assemblerFill = buildConfig.assemblerFill || builder.config.assemblerFill;
assemblerFill(assembler, function(err) {
if (err) {
callback(err);
} else {
buildStepAssemblerRun(builder, buildConfig, assembler, callback);
}
});
}
function buildStepAssemblerCreate(builder, buildConfig, assemblerConfig, callback) {
var assemblerCreate = buildConfig.assemblerCreate || builder.config.assemblerCreate;
assemblerCreate(assemblerConfig, function(err, assembler) {
if (err) {
callback(err);
} else {
buildStepAssemblerFill(builder, buildConfig, assembler, callback);
}
});
}
function buildStepConfigFill(builder, buildConfig, assemblerConfig, callback) {
var configFill = buildConfig.configFill || builder.config.configFill;
if (assemblerConfig.assetType === undefined) {
assemblerConfig.assetType = builder.currentAssetType;
}
configFill(assemblerConfig, function(err) {
if (err) {
callback(err);
} else {
buildStepAssemblerCreate(builder, buildConfig, assemblerConfig, callback);
}
});
}
function buildStepConfigCreate(builder, buildConfig, callback) {
var configCreate = buildConfig.configCreate || builder.config.configCreate;
configCreate(function(err, assemblerConfig) {
if (err) {
callback(err);
} else {
buildStepConfigFill(builder, buildConfig, assemblerConfig, callback);
}
});
}
function AssetsBuilder(config) {
this.config = config;
this.startTime = 0;
this.currentAssetType = '';
events.EventEmitter.call(this);
}
AssetsBuilder.prototype.__proto__ = events.EventEmitter.prototype;
AssetsBuilder.prototype.runAll = function(callback) {
var self = this;
config.checkConfig(self.config,function(err) {
if (err) {
callback(err);
} else {
config.fillDefaults(self.config, function (err) {
if (err) {
callback(err);
} else {
var runners = [];
for (var i = 0; i < self.config.buildOrder.length; i++) {
var assetKey = self.config.buildOrder[i];
runners.push(self.runAsset(assetKey));
}
async.series(runners,self.config.buildDone);
}
});
}
});
};
AssetsBuilder.prototype.runAsset = function(name) {
var self = this;
return function(callback) {
if (name === undefined) {
throw new Error('no name');
}
if (callback === undefined) {
throw new Error('no callback');
}
config.checkConfig(self.config,function(err) {
if (err) {
callback(err);
} else {
var buildConfig = self.config.assets[name];
if (buildConfig === undefined) {
throw new Error('no asset config found');
}
self.currentAssetType = name;
buildStepConfigCreate(self,buildConfig,callback);
}
});
};
};
module.exports = AssetsBuilder;

144
lib/factory.js Normal file
View file

@ -0,0 +1,144 @@
'use strict';
var fs = require('fs');
var assemblerConstructors = {
readFile : function() {
return function(file, callback) {
fs.readFile(file, function(err, data) {
if (err) {
callback(err);
} else {
callback(null, data);
}
});
};
},
readFileMinify : function(options) {
if (options === undefined) {
options = {};
}
var minify = require('minify');
return function(file, callback) {
minify(file, options, function(err, data) {
if (err) {
callback(err);
} else {
callback(null, data);
}
});
};
},
};
var assemblerEventLog = {
console : function(logType) {
if (logType === undefined) {
throw new Error('no logType');
}
return function(logLevel, logMessage) {
console.log(logLevel + ': node-ff-assets-' + logType + ' ' + logMessage);
};
},
winston: function(logger, logType) {
if (logger === undefined) {
throw new Error('no logger');
}
if (logType === undefined) {
throw new Error('no logType');
}
return function(logLevel, logMessage) {
logger.log(logLevel, 'node-ff-assets-'+logType+' '+logMessage);
};
},
};
var assemblerEventResult = {
objectFunction : function(object, functionName, resultKey) {
if (object === undefined) {
throw new Error('no object');
}
if (functionName === undefined) {
throw new Error('no functionName');
}
return function(resultValue) {
if (resultKey === undefined) {
object[functionName](resultValue);
} else {
object[functionName](resultKey, resultValue);
}
};
},
objectAdd : function(object, resultKey) {
return assemblerEventResult.objectFunction(object, 'add', resultKey);
},
objectSet : function(object, resultKey) {
return assemblerEventResult.objectFunction(object, 'set', resultKey);
},
objectPut : function(object, resultKey) {
return assemblerEventResult.objectFunction(object, 'put', resultKey);
},
arrayPush : function(object) {
return assemblerEventResult.objectFunction(object, 'push');
},
};
var libAsync = {
pushLinkSources: function (builder, linkPrefix, fileFolder) {
return function(callback) {
fs.readdir(fileFolder, function (err, fileList) {
if (err) {
callback(err);
} else {
fileList.forEach(function (file) {
if (file.indexOf('.js') > 0 || file.indexOf('.css') > 0) {
builder.linkSources.push(linkPrefix+file);
}
});
callback(null,null);
}
});
};
},
runBuilder: function (builder) {
return function(callback) {
builder.run(callback);
};
},
};
var builderAssemblerCreate = {
readFile: function () {
return function (assemblerConfig, callback) {
var AS = require('./asset-assembler');
callback(null,new AS(assemblerConfig,assemblerConstructors.readFile()));
};
},
readFileMinify: function(options) {
return function (assemblerConfig, callback) {
var AS = require('./asset-assembler');
callback(null,new AS(assemblerConfig,assemblerConstructors.readFileMinify(options)));
};
},
};
var builderEmptyCallback = function () {};
module.exports = {
assembler: {
constructor : assemblerConstructors,
event : {
log : assemblerEventLog,
result : assemblerEventResult,
},
},
builder: {
configCreate: { nop: builderEmptyCallback },
configFill: { nop: builderEmptyCallback },
assemblerCreate: builderAssemblerCreate,
assemblerFill: { nop: builderEmptyCallback },
},
lib: {
async: libAsync,
},
};

16
lib/node-ff-assets.js Normal file
View file

@ -0,0 +1,16 @@
'use strict';
var assets = {
factory: require('./factory'),
AssetAssembler: require('./asset-assembler'),
checkAssemblerConfig: require('./asset-assembler-config').checkConfig,
AssetsBuilder: require('./assets-builder'),
checkBuilderConfig: require('./assets-builder-config').checkConfig,
};
assets.build = function (config,callback) {
var builder = new assets.AssetsBuilder(config);
builder.runAll(callback);
};
module.exports = assets;

View file

@ -1,16 +1,24 @@
{
"name": "node-ff-assets",
"version": "0.1.2",
"version": "0.2.0",
"description": "Site assets local/remote aggregation with minify.",
"main": "index.js",
"main": "lib/node-ff-assets.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "node_modules/mocha/bin/mocha"
},
"author": "Willem <willem.git.2015@forwardfire.net> (http://forwardfire.net/)",
"license": "BSD-2-Clause",
"repository": {
"type": "git",
"url": "https://bitbucket.org/im_ik/node-ff-assets.git"
},
"dependencies": {
"fetch": "^0.3.6",
"fs-extra": "^0.16.3",
"minify": "^1.4.8"
},
"devDependencies": {
"mocha": "^2.1.0",
"mocha-jshint": "0.0.9"
}
}

3
test/jshint.spec.js Normal file
View file

@ -0,0 +1,3 @@
'use strict';
require('mocha-jshint')(['lib']);

View file

@ -0,0 +1,25 @@
'use strict';
var assert = require("assert");
var asserts = require("../lib/node-ff-assets");
describe('node-ff-assets', function() {
describe('export.* check undefined', function() {
it('asserts.factory should not be undefined', function() {
assert.equal(false, asserts.factory === undefined);
});
it('asserts.AssetAssembler should not be undefined', function() {
assert.equal(false, asserts.AssetAssembler === undefined);
});
it('asserts.checkAssemblerConfig should not be undefined', function() {
assert.equal(false, asserts.checkAssemblerConfig === undefined);
});
it('asserts.AssetsBuilder should not be undefined', function() {
assert.equal(false, asserts.AssetsBuilder === undefined);
});
it('asserts.checkBuilderConfig should not be undefined', function() {
assert.equal(false, asserts.checkBuilderConfig === undefined);
});
});
});