pruno-cli
Version:
A CLI tool for scaffolding projects that use the pruno build tool and a generator for creating components.
311 lines (255 loc) • 10.1 kB
JavaScript
;
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var inquirer = _interopRequire(require("inquirer"));
var inflection = _interopRequire(require("inflection"));
var assign = _interopRequire(require("object-assign"));
var path = _interopRequire(require("path"));
var fs = _interopRequire(require("fs"));
var Handlebars = _interopRequire(require("handlebars"));
var _shelljs = require("shelljs");
var pwd = _shelljs.pwd;
var mkdir = _shelljs.mkdir;
var log = require("../../logger").log;
var ReactGenerator = (function () {
function ReactGenerator() {
_classCallCheck(this, ReactGenerator);
}
_prototypeProperties(ReactGenerator, null, {
create: {
value: function create(classType, name, options) {
try {
this.config = require(path.join(pwd(), ".prunorc"));
} catch (err) {
throw new Error("Pruno has not properly been initialized. Please run " + "`pruno new` in the root of your project.");
}
this.ensurePath(classType);
var CREATE_STRING = "onCreate" + (classType.charAt(0).toUpperCase() + classType.slice(1));
this.options = options || {};
var hasMethod = Object.getOwnPropertyNames(ReactGenerator.prototype).indexOf(CREATE_STRING) > -1;
if (!hasMethod) {
throw new Error("Invalid generator class type " + classType + ", " + ("ReactGenerator has no method " + CREATE_STRING));
}
this[CREATE_STRING](name, options);
},
writable: true,
configurable: true
},
onCreateComponent: {
value: function onCreateComponent(name, options) {
var _this = this;
var componentName = inflection.titleize(name).replace(/\W/g, "");
var className = inflection.transform(componentName, ["underscore", "dasherize"]);
var stores = fs.readdirSync(path.join(pwd(), this.config.src, "stores")).filter(function (file) {
return /\.js$/.exec(file);
}).map(function (file) {
return file.match(/^(.+)\.js$/)[1];
});
try {
var mixins = fs.readdirSync(path.join(pwd(), this.config.src, "mixins")).filter(function (file) {
return /\.js$/.exec(file);
}).map(function (file) {
return file.match(/^(.+)\.js$/)[1];
});
} catch (err) {
var mixins = [];
}
inquirer.prompt([{
name: "stores",
type: "checkbox",
message: "Would you like to listen to any stores?",
choices: stores,
when: function () {
return stores.length > 0;
}
}, {
name: "mixins",
type: "checkbox",
message: "Would you like to listen to any mixins?",
choices: mixins,
when: function () {
return mixins.length > 0;
}
}, {
name: "isRouteHandler",
type: "confirm",
message: "Is this component a route handler?",
"default": false
}], function (params) {
params.stores || (params.stores = []);
params.mixins || (params.mixins = []);
if (params.stores.length > 0) {
params.mixins.push("StoreListenerMixin");
}
if (params.isRouteHandler) {
params.mixins.push("RouterStateMixin");
componentName += "Route";
}
var opts = assign({ componentName: componentName, className: className }, {
stores: params.stores,
mixins: params.mixins.join(", "),
isRouteHandler: params.isRouteHandler
});
var contents = _this.renderData("Component.js.hbs", opts);
if (params.isRouteHandler) {
_this.ensurePath("route");
var componentType = "routes";
} else {
var componentType = "components";
}
var target = path.join(pwd(), _this.config.src, componentType, componentName + ".js");
fs.writeFileSync(target, contents);
log("Created", target.yellow.underline + ".");
});
},
writable: true,
configurable: true
},
onCreateStore: {
value: function onCreateStore(name, options) {
var _this = this;
var storeName = inflection.transform(name.replace(/-/g, "_"), ["classify"]) + "Store";
var actions = fs.readdirSync(path.join(pwd(), this.config.src, "actions")).filter(function (file) {
return /\.js$/.exec(file);
}).map(function (file) {
return file.replace(/\.js$/, "");
});
inquirer.prompt([{
name: "actions",
type: "checkbox",
choices: actions,
message: "Would you like to bind any actions?"
}], function (params) {
params.actions || (params.actions = []);
var opts = {};
var actionList = [];
var actions = params.actions.reduce(function (memo, actionFile) {
var actionData = fs.readFileSync(path.join(pwd(), _this.config.src, "actions", actionFile + ".js")).toString().split(/[\r\n]/);
var searching = false;
while (actionData.length > 0) {
var line = actionData.shift();
if (line.match(/generateActions\(/)) {
searching = true;
}
if (searching && /'(.+)'/.exec(line)) {
actionList.push(/'(.+)'/.exec(line)[1]);
}
if (line.match(/\);/)) {
searching = false;
}
}
}, []);
opts.actions = params.actions;
opts.actionItems = actionList;
opts.storeName = storeName;
var contents = _this.renderData("Store.js.hbs", opts);
var target = path.join(pwd(), _this.config.src, "stores", storeName + ".js");
fs.writeFileSync(target, contents);
log("Created", target.yellow.underline + ".");
});
},
writable: true,
configurable: true
},
onCreateActions: {
value: function onCreateActions(name, options) {
var _this = this;
var actionsName = inflection.transform(name.replace(/-/g, "_"), ["classify"]) + "ActionCreators";
inquirer.prompt([{
name: "actions",
type: "input",
message: "What actions would you like to generate? (Separate with spaces)"
}], function (params) {
var opts = {
actionsName: actionsName,
actions: params.actions ? params.actions.split(" ") : false
};
var contents = _this.renderData("ActionCreator.js.hbs", opts);
var target = path.join(pwd(), _this.config.src, "actions", actionsName + ".js");
fs.writeFileSync(target, contents);
log("Created", target.yellow.underline + ".");
});
},
writable: true,
configurable: true
},
onCreateMixin: {
value: function onCreateMixin(name, options) {
var _this = this;
var mixinName = inflection.transform(name.replace(/\-/g, "_"), ["titleize"]).replace(/\s/g, "") + "Mixin";
inquirer.prompt([{
type: "confirm",
name: "takesParams",
message: "Does this mixin take parameters?",
"default": false
}], function (params) {
var takesParams = params.takesParams;
var opts = { mixinName: mixinName, takesParams: takesParams };
var contents = _this.renderData("Mixin.js.hbs", opts);
var target = path.join(pwd(), _this.config.src, "mixins", "" + mixinName + ".js");
fs.writeFileSync(target, contents);
log("Created", target.yellow.underline + ".");
});
},
writable: true,
configurable: true
},
renderData: {
value: function renderData(tplFile, opts) {
var hbsPath = path.join(__dirname, "generators", tplFile);
var hbs = fs.readFileSync(hbsPath).toString();
var template = Handlebars.compile(hbs);
var contents = template(opts);
return contents;
},
writable: true,
configurable: true
},
ensurePath: {
value: function ensurePath(classType) {
var pathPart = (function () {
switch (classType) {
case "component":
return "components";
case "actions":
return "actions";
case "mixin":
return "mixins";
case "store":
return "stores";
case "route":
return "routes";
}
})();
var target = path.join(pwd(), this.config.src, pathPart);
if (!fs.existsSync(target)) {
log("Creating directory", target.yellow.underline + ".");
mkdir(target);
}
},
writable: true,
configurable: true
}
});
return ReactGenerator;
})();
Handlebars.registerHelper("camelcase", function (str) {
return inflection.camelize(str, true);
});
Handlebars.registerHelper("actionify", function (str) {
return "on" + str.charAt(0).toUpperCase() + str.slice(1);
});
Handlebars.registerHelper("storeState", function (str) {
return (str.charAt(0).toLowerCase() + str.slice(1)).replace(/Store$/, "");
});
Handlebars.registerHelper("formatList", function (arr, indents) {
var tabs = Array(indents).join(0).split(0).map(function (t) {
return "\t";
}).join("");
var list = arr.map(function (item, i) {
return "'" + item + "'";
}).join(",\r\n" + tabs);
return new Handlebars.SafeString(list);
});
module.exports = new ReactGenerator();