Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit a7eb8bcf6dfea4f178faa942e7e0a7cf63fcde83 @azer azer committed Oct 1, 2011
@@ -0,0 +1 @@
+node_modules
13 COPYING
@@ -0,0 +1,13 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2011 Azer Koculu <azer@kodfabrik.com>
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1,3 @@
+.PHONY: test
+test:
+ node test/run.js
11 README
@@ -0,0 +1,11 @@
+Summary: Transform CommonJS packages into single, stand-alone JavaScript files.
+Status: Being Tested
+
+Known Problems:
+ - Doesn't support "directories" field of package manifests.
+
+Todo:
+ - Write Manual
+ - Build Website
+
+vim: tw=100
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+
+var one = require('../lib/one'),
+ opts = require('opts'),
+ puts = require('sys').puts,
+ options,
+ REV;
+
+REV = '1.0.0';
+
+opts.parse([{
+ 'short':'v',
+ 'long':'version',
+ 'description':'Show version and exit',
+ 'callback':version
+ }
+]);
+
+function run(){
+ var args = opts.args();
+ args.length == 0 && args.push('./');
+
+ one.build(args[0], function(error, sc){
+ if(error) throw error;
+ puts(sc);
+ });
+}
+
+function version(){
+ puts(REV);
+ process.exit(0);
+}
+
+run();
@@ -0,0 +1,3 @@
+module.exports = {
+ 'TEMPLATES_DIR':'templates'
+}
No changes.
@@ -0,0 +1,287 @@
+var templating = require('./templating'),
+ render = templating.render,
+ compose = require('functools').compose,
+ map = require('functools').map,
+ combiner = require('combiner'),
+ path = require('path'),
+ readFile = require('fs').readFile;
+
+function build(wd, callback){
+ loadPackage(wd, function(error, pkg){
+ if(error) return callback(error);
+
+ var pkgs = flattenPackageTree(pkg),
+ treeName = templating.makeVariableName(pkg.name);
+
+ pkgs = pkgs.map(function(el){
+ return { 'pkg':el, 'treeName':treeName };
+ });
+
+ map.async(renderPackage, pkgs, function(error, renderedPkgs){
+ if(error) return callback(error);
+ renderWrapper({
+ 'treeName':treeName,
+ 'renderedPkgs':renderedPkgs
+ }, callback);
+ });
+
+ });
+}
+
+function collectDeps(pkg, callback){
+
+ var deps = [],
+ declaredDepObj = pkg.manifest.dependencies,
+ declaredDepList = declaredDepObj && Object.keys(declaredDepObj),
+ next;
+
+ if(!declaredDepList || !declaredDepList.length){
+ return callback(undefined, deps);
+ }
+
+ (function _(i){
+ if(i>=declaredDepList.length){
+ return callback(undefined,deps);
+ }
+
+ next = _.bind(null, i+1);
+
+ var dp = declaredDepList[i],
+ path = pkg.workingDir + 'node_modules/' + dp + '/';
+
+ if(pkg.packageDict[dp]){
+ return next();
+ }
+
+ loadPackage(pkg, path, function(error, subpkg){
+ if(error){
+ return callback(error);
+ }
+
+ deps.push(subpkg);
+ next();
+ });
+
+ })(0);
+}
+
+function collectModules(pkg, callback){
+ compose.async(combiner.findFiles,
+ combiner.includeDirectories,
+ combiner.flatten,
+ function(filenames,callback){
+ callback(undefined,filenames.filter(filterFilename));
+ },
+ function(filenames, callback){
+ var modules = [];
+
+ (function _(i){
+ if(i>=filenames.length){
+ return callback(undefined, modules);
+ }
+
+ var next = _.bind(null, i+1);
+
+ loadModule(filenames[i], function(error, module){
+ module.filename = module.filename.replace(pkg.workingDir,'').replace(/^lib\//,'');
+ module.id = module.filename.replace(/\.js$/,'');
+ if(!error) modules.push(module);
+ next();
+ });
+
+ })(0);
+ })([pkg.workingDir + 'lib/'],callback);
+}
+
+function flattenPackageTree(tree){
+ var l = [tree];
+
+ var i = -1;
+ while(tree.dependencies && ++i<tree.dependencies.length){
+ Array.prototype.push.apply(l, flattenPackageTree(tree.dependencies[i]));
+ }
+
+ return l;
+}
+
+function filterFilename(filename,callback){
+ return /\.js$/.test(filename);
+}
+
+var loadModule = (function(){
+
+ var template;
+
+ return function(filename, callback){
+ readFile(filename, function(error, bf){
+ if(error) return callback(error);
+
+ var content = bf.toString(),
+ name = moduleName(filename);
+
+ callback(undefined, {
+ 'name':name,
+ 'filename':filename,
+ 'path':filename,
+ 'content':content
+ });
+ });
+ }
+
+})();
+
+function loadPackage(/*parentPackage, wd, callback*/){
+
+ var argsLen = arguments.length,
+ parentPackage = argsLen == 3 && arguments[0] || undefined,
+ wd = arguments[argsLen-2],
+ callback = arguments[argsLen-1];
+
+ wd[wd.length-1] != '/' && ( wd = wd+'/' );
+ wd = wd.replace(/^\.\//,'');
+
+ var mainModule = undefined,
+ mainModulePath = undefined,
+ manifestPath = wd + 'package.json',
+ manifestSource = undefined,
+ manifest = undefined,
+ dependencies = undefined,
+ modules = undefined,
+ modulesDict = {},
+ pkg = undefined,
+ i = undefined;
+
+ readFile(manifestPath, function(error, bf){
+
+ if(!error){
+ manifestSource = bf.toString();
+ try {
+ manifest = JSON.parse(manifestSource);
+ } catch(exc) {
+ error = exc;
+ }
+ }
+
+ if(error){
+ return callback(error);
+ }
+
+ pkg = {
+ 'id':templating.id(),
+ 'dependencies':dependencies,
+ 'main':mainModule,
+ 'manifest':manifest,
+ 'manifestPath':manifestPath,
+ 'manifestSource':manifestSource,
+ 'modules':modules,
+ 'modulesDict':modulesDict,
+ 'name':manifest.name,
+ 'parent':parentPackage,
+ 'packageDict':parentPackage && parentPackage.packageDict || {},
+ 'workingDir':wd
+ };
+
+ pkg.packageDict[pkg.name] = pkg;
+
+ collectDeps(pkg, function(error, deps){
+ if(error){
+ return callback(error);
+ }
+
+ pkg.dependencies = deps;
+
+ collectModules(pkg, function(error, modules){
+ if(error){
+ return callback(error);
+ }
+ pkg.modules = modules;
+
+ var i = modules.length,
+ m;
+ while(i-->0){
+ m = modules[i];
+ modulesDict[m.path] = m;
+ }
+
+ if(!error && manifest.main){
+ mainModulePath = path.join(wd, manifest.main+'.js');
+ pkg.main = pkg.modulesDict[mainModulePath];
+ }
+
+ callback(error, pkg);
+ });
+ });
+
+ });
+
+}
+
+function moduleName(filename){
+ var m = filename.match(/([^\/\.]+)\.js$/);
+ return !m ? undefined : m[1];
+}
+
+function renderLibrary(callback){
+ render({ 'template':'node/path.js' }, function(error, nodePathSC){
+ render({ 'template':'library.js', 'view':{}, 'partials':{ 'node_path':nodePathSC } }, callback);
+ });
+}
+
+function renderModule(options, callback){
+ var view = {
+ 'treeName':options.treeName,
+ 'parentId':options.pkg.id,
+ 'id':options.module.id
+ };
+ render({ 'template':'module.js', 'view':view, 'partials':{ 'content':options.module.content } }, callback);
+}
+
+function renderPackage(options,callback){
+
+ var view = {
+ 'treeName':options.treeName,
+ 'parentId':!options.pkg.parent && 'undefined' || options.pkg.parent.id,
+ 'id':options.pkg.id,
+ 'main': options.pkg.main && options.pkg.main.id,
+ 'name':options.pkg.name,
+ 'wd':options.pkg.workingDir
+ };
+
+ var modules = options.pkg.modules.map(function(el){
+ return {
+ 'treeName':options.treeName,
+ 'pkg':options.pkg,
+ 'module':el
+ }
+ });
+
+ map.async(renderModule, modules, function(error, renderedModules){
+ if(error) return callback(error);
+ render({ 'template':'package.js', 'view':view, 'partials':{ 'modules':renderedModules.join('\n\n') } }, callback);
+ });
+}
+
+function renderWrapper(options, callback){
+ renderLibrary(function(error, librarySC){
+ render({
+ 'template':'wrapper.js',
+ 'view':{ 'name':options.treeName },
+ 'partials':{
+ 'library':librarySC,
+ 'packages':options.renderedPkgs.join('\n\n\n\n')
+ }
+ }, callback);
+ });
+}
+
+module.exports = {
+ 'build':build,
+ 'collectDeps':collectDeps,
+ 'collectModules':collectModules,
+ 'filterFilename':filterFilename,
+ 'flattenPackageTree':flattenPackageTree,
+ 'loadModule':loadModule,
+ 'loadPackage':loadPackage,
+ 'moduleName':moduleName,
+ 'renderModule':renderModule
+}
@@ -0,0 +1,33 @@
+var mustache = require('mustache'),
+ fs = require('fs'),
+ config = require('./config'),
+ errors = require('./errors');
+
+var id = (function(){
+ var serial = 0;
+ return function id(){
+ return ++serial;
+ }
+})();
+
+function makeVariableName(str){
+ return str.toLowerCase().replace(/[^a-zA-Z0-9]+/g,' ').replace(/^[\d\s]+/g,'').split(' ').reduce(function(a,b){
+ return a + b.charAt(0).toUpperCase() + b.slice(1).toLowerCase();
+ });
+}
+
+function render(options,callback){
+ fs.readFile(config.TEMPLATES_DIR+'/'+options.template, function(error, bf){
+ var result;
+ if(!error){
+ result = mustache.to_html(bf.toString(), options.view, options.partials);
+ }
+ callback(error, result);
+ });
+}
+
+module.exports = {
+ 'id':id,
+ 'makeVariableName':makeVariableName,
+ 'render':render
+}
Oops, something went wrong.

0 comments on commit a7eb8bc

Please sign in to comment.