nap-cli
Version:
a new package cli
289 lines (268 loc) • 8.84 kB
JavaScript
var express = require('express');
var path = require('path');
var fs = require('fs');
var fse = require('fs-extra');
var bodyParser = require('body-parser');
var clip = require('./clipboard');
var _port = 9000, _ip = '0.0.0.0';
var configs = {
exts: [".js", ".css", ".md", ".json", ".asp", ".jpg", ".bmp", ".gif", ".png", ".svg", ".html", ".htm"]
}
module.exports = function(options){
new service(options);
}
function service(options){
this.app = express();
this.options = options;
this.dir = path.resolve(__dirname, '../codeditor');
this.init();
}
service.prototype.init = function(){
this.app.use(express.static(this.dir));
this.app.use(bodyParser.urlencoded({ extended: true }));
this.projects();
this.tree();
this.read();
this.save();
this.create();
this.clean();
this.paste();
var port = this.options.port || _port;
var ip = this.options.ip || _ip;
this.app.listen(port, ip);
var __ip = ip === '0.0.0.0' ? '127.0.0.1' : ip;
var __port = port === 80 ? '' : ':' + port;
var url = 'http://' + __ip + __port + '/html/index.html';
clip(url);
console.log('\n➜ open ' + url + ' on browser...');
}
service.prototype.projects = function(){
this.app.get('/codeditor/projects', function(req, res){
var cwd = process.cwd();
var projects = fs.readdirSync(cwd);
var result = [];
for ( var i = 0 ; i < projects.length ; i++ ){
if ( !/^\./.test(projects[i]) ){
var project = path.resolve(cwd, projects[i]);
var fo = fs.statSync(project);
if ( fo.isDirectory() ){
result.push(projects[i]);
}
}
}
res.json({
success: true,
result: result
});
});
}
service.prototype.tree = function(){
this.app.get('/codeditor/tree', function(req, res){
var cwd = process.cwd();
var project = path.resolve(cwd, req.query.project);
res.json(fsReadAll(project));
}) ;
}
service.prototype.read = function(){
this.app.post('/codeditor/read', function(req, res){
var cwd = process.cwd();
var file = path.resolve(cwd, req.body.file);
if ( fs.existsSync(file) ){
res.json({
success: true,
content: fs.readFileSync(file, 'utf8') || ''
});
}else{
res.json({
success: false,
message: 'can not find the file.'
});
}
});
}
service.prototype.save = function(){
this.app.post('/codeditor/save', function(req, res){
var cwd = process.cwd();
var file = path.resolve(cwd, req.body.file);
var content = req.body.content || '';
fs.writeFile(file, content, 'utf8', function(err){
if ( err ){
return res.json({
success: false,
message: err.message
});
}
return res.json({ success: true });
});
});
}
service.prototype.create = function(){
this.app.post('/codeditor/create/:type', function(req, res){
var cwd = process.cwd();
var file = path.resolve(cwd, req.body.file);
var name = req.body.name;
if ( !name ){
return res.json({
success: false,
message: 'need name'
});
}
var pather = path.resolve(file, name);
switch (req.params.type){
case 'folder':
if ( !fs.existsSync(pather) ){
fs.mkdir(pather, function(err){
if ( err ){
return res.json({
success: false,
message: err.message
});
}
res.json({ success: true });
})
}else{
res.json({ success: true });
}
break;
case 'file':
if ( !fs.existsSync(pather) ){
fs.writeFile(pather, ' ', 'utf8', function(err){
if ( err ){
return res.json({
success: false,
message: err.message
});
}
res.json({ success: true });
})
}else{
res.json({ success: true });
}
break;
}
});
}
service.prototype.clean = function(){
this.app.post('/codeditor/clean', function(req, res){
var cwd = process.cwd();
var file = path.resolve(cwd, req.body.file);
var fo = fs.statSync(file);
if ( fo.isDirectory() ){
rmdirSync(file, function(err){
if ( err ){
return res.json({
success: false,
message: err.message
});
}
res.json({ success: true });
});
}else if ( fo.isFile() ){
fs.unlink(file, function(err){
if ( err ){
return res.json({
success: false,
message: err.message
});
}
res.json({ success: true });
});
}else{
res.json({ success: false, message: 'error clean type.' });
}
});
}
service.prototype.paste = function(){
this.app.post('/codeditor/paste', function(req, res){
var cwd = process.cwd();
var from = path.resolve(cwd, req.body.from);
var to = path.resolve(cwd, req.body.to);
var over = 1 == req.body.over;
if ( !fs.existsSync(from) ){
return res.json({ success: false, message: "无法找到复制源" });
}
if ( !fs.existsSync(to) ){
return res.json({ success: false, message: "无法找到复制目标" });
}
var name = path.basename(from);
var _to = path.resolve(to, name);
if ( !over && fs.existsSync(_to) ){
return res.json({ success: false, message: "文件或文件夹已存在,是否覆盖?", over: true });
}
fse.copy(from, _to, { clobber: over }, function(err){
if ( err ){
return res.json({
success: false,
message: err.message
});
}
res.json({ success: true });
});
});
}
function fsReadAll(dir){
var result = {};
if ( fs.existsSync(dir) ){
result.dir = path.basename(dir);
result.files = [];
result.folders = [];
result.status = false;
var items = fs.readdirSync(dir);
for ( var i = 0 ; i < items.length ; i++ ){
var item = path.resolve(dir, items[i]);
var fo = fs.statSync(item);
if ( fo.isDirectory() ){
if ( !/^\./.test(items[i]) ){
var ret = fsReadAll(item);
if ( ret.success ){
result.folders.push(ret.result);
}
}
}else if ( fo.isFile() ){
var ext = path.extname(items[i]).toLowerCase();
if ( configs.exts.indexOf(ext) > -1 ){
result.files.push(items[i]);
}
}
}
return {
success: true,
result: result
}
}else{
return {
success: false,
message: 'can not find the project'
}
}
}
var rmdirSync = (function(){
function iterator(url,dirs){
var stat = fs.statSync(url);
if(stat.isDirectory()){
dirs.unshift(url);//收集目录
inner(url,dirs);
}else if(stat.isFile()){
fs.unlinkSync(url);//直接删除文件
}
}
function inner(path,dirs){
var arr = fs.readdirSync(path);
for(var i = 0, el ; el = arr[i++];){
iterator(path+"/"+el,dirs);
}
}
return function(dir,cb){
cb = cb || function(){};
var dirs = [];
try{
iterator(dir,dirs);
for(var i = 0, el ; el = dirs[i++];){
fs.rmdirSync(el);//一次性删除所有收集到的目录
}
cb()
}catch(e){//如果文件或目录本来就不存在,fs.statSync会报错,不过我们还是当成没有异常发生
e.code === "ENOENT" ? cb() : cb(e);
}
}
})();